1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 #include "wmi_unified_api.h" 29 #include "wmi.h" 30 #include "wmi_version.h" 31 #include "wmi_unified_priv.h" 32 #include "wmi_version_whitelist.h" 33 #include <qdf_module.h> 34 #include <wlan_defs.h> 35 #include <htc_services.h> 36 37 #ifdef CONVERGED_P2P_ENABLE 38 #include "wlan_p2p_public_struct.h" 39 #endif 40 #ifdef WLAN_PMO_ENABLE 41 #include "wlan_pmo_hw_filter_public_struct.h" 42 #endif 43 #include <wlan_utility.h> 44 #ifdef WLAN_SUPPORT_GREEN_AP 45 #include "wlan_green_ap_api.h" 46 #endif 47 48 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 49 #include "nan_public_structs.h" 50 #endif 51 52 #ifdef WLAN_POLICY_MGR_ENABLE 53 #include "wlan_policy_mgr_public_struct.h" 54 #endif 55 56 /* HTC service ids for WMI for multi-radio */ 57 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 58 WMI_CONTROL_SVC_WMAC1, 59 WMI_CONTROL_SVC_WMAC2}; 60 61 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 62 * buffer. 63 * @wmi_handle: pointer to wmi_handle 64 * @cmd: pointer target vdev create command buffer 65 * @param: pointer host params for vdev create 66 * 67 * Return: None 68 */ 69 #ifdef CONFIG_MCL 70 static inline void copy_vdev_create_pdev_id( 71 struct wmi_unified *wmi_handle, 72 wmi_vdev_create_cmd_fixed_param * cmd, 73 struct vdev_create_params *param) 74 { 75 cmd->pdev_id = WMI_PDEV_ID_SOC; 76 } 77 #else 78 static inline void copy_vdev_create_pdev_id( 79 struct wmi_unified *wmi_handle, 80 wmi_vdev_create_cmd_fixed_param * cmd, 81 struct vdev_create_params *param) 82 { 83 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 84 param->pdev_id); 85 } 86 #endif 87 88 /** 89 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 90 * @wmi_handle: wmi handle 91 * @param: pointer to hold vdev create parameter 92 * @macaddr: vdev mac address 93 * 94 * Return: QDF_STATUS_SUCCESS for success or error code 95 */ 96 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 97 uint8_t macaddr[IEEE80211_ADDR_LEN], 98 struct vdev_create_params *param) 99 { 100 wmi_vdev_create_cmd_fixed_param *cmd; 101 wmi_buf_t buf; 102 int32_t len = sizeof(*cmd); 103 QDF_STATUS ret; 104 int num_bands = 2; 105 uint8_t *buf_ptr; 106 wmi_vdev_txrx_streams *txrx_streams; 107 108 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 109 buf = wmi_buf_alloc(wmi_handle, len); 110 if (!buf) { 111 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 112 return QDF_STATUS_E_NOMEM; 113 } 114 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 115 WMITLV_SET_HDR(&cmd->tlv_header, 116 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 117 WMITLV_GET_STRUCT_TLVLEN 118 (wmi_vdev_create_cmd_fixed_param)); 119 cmd->vdev_id = param->if_id; 120 cmd->vdev_type = param->type; 121 cmd->vdev_subtype = param->subtype; 122 cmd->num_cfg_txrx_streams = num_bands; 123 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 124 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 125 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 126 __func__, param->if_id, cmd->pdev_id, 127 macaddr[0], macaddr[1], macaddr[2], 128 macaddr[3], macaddr[4], macaddr[5]); 129 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 130 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 131 (num_bands * sizeof(wmi_vdev_txrx_streams))); 132 buf_ptr += WMI_TLV_HDR_SIZE; 133 134 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 135 param->type, param->subtype, 136 param->nss_2g, param->nss_5g); 137 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 138 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 139 txrx_streams->supported_tx_streams = param->nss_2g; 140 txrx_streams->supported_rx_streams = param->nss_2g; 141 WMITLV_SET_HDR(&txrx_streams->tlv_header, 142 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 143 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 144 145 txrx_streams++; 146 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 147 txrx_streams->supported_tx_streams = param->nss_5g; 148 txrx_streams->supported_rx_streams = param->nss_5g; 149 WMITLV_SET_HDR(&txrx_streams->tlv_header, 150 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 151 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 152 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 153 if (QDF_IS_STATUS_ERROR(ret)) { 154 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 155 wmi_buf_free(buf); 156 } 157 158 return ret; 159 } 160 161 /** 162 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 163 * @wmi_handle: wmi handle 164 * @if_id: vdev id 165 * 166 * Return: QDF_STATUS_SUCCESS for success or error code 167 */ 168 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 169 uint8_t if_id) 170 { 171 wmi_vdev_delete_cmd_fixed_param *cmd; 172 wmi_buf_t buf; 173 QDF_STATUS ret; 174 175 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 176 if (!buf) { 177 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 178 return QDF_STATUS_E_NOMEM; 179 } 180 181 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 182 WMITLV_SET_HDR(&cmd->tlv_header, 183 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 184 WMITLV_GET_STRUCT_TLVLEN 185 (wmi_vdev_delete_cmd_fixed_param)); 186 cmd->vdev_id = if_id; 187 ret = wmi_unified_cmd_send(wmi_handle, buf, 188 sizeof(wmi_vdev_delete_cmd_fixed_param), 189 WMI_VDEV_DELETE_CMDID); 190 if (QDF_IS_STATUS_ERROR(ret)) { 191 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 192 wmi_buf_free(buf); 193 } 194 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 195 196 return ret; 197 } 198 199 /** 200 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 201 * @wmi: wmi handle 202 * @vdev_id: vdev id 203 * 204 * Return: QDF_STATUS_SUCCESS for success or erro code 205 */ 206 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 207 uint8_t vdev_id) 208 { 209 wmi_vdev_stop_cmd_fixed_param *cmd; 210 wmi_buf_t buf; 211 int32_t len = sizeof(*cmd); 212 213 buf = wmi_buf_alloc(wmi, len); 214 if (!buf) { 215 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 216 return QDF_STATUS_E_NOMEM; 217 } 218 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 219 WMITLV_SET_HDR(&cmd->tlv_header, 220 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 221 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 222 cmd->vdev_id = vdev_id; 223 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 224 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 225 wmi_buf_free(buf); 226 return QDF_STATUS_E_FAILURE; 227 } 228 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 229 230 return 0; 231 } 232 233 /** 234 * send_vdev_down_cmd_tlv() - send vdev down command to fw 235 * @wmi: wmi handle 236 * @vdev_id: vdev id 237 * 238 * Return: QDF_STATUS_SUCCESS for success or error code 239 */ 240 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 241 { 242 wmi_vdev_down_cmd_fixed_param *cmd; 243 wmi_buf_t buf; 244 int32_t len = sizeof(*cmd); 245 246 buf = wmi_buf_alloc(wmi, len); 247 if (!buf) { 248 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 249 return QDF_STATUS_E_NOMEM; 250 } 251 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 252 WMITLV_SET_HDR(&cmd->tlv_header, 253 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 254 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 255 cmd->vdev_id = vdev_id; 256 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 257 WMI_LOGP("%s: Failed to send vdev down", __func__); 258 wmi_buf_free(buf); 259 return QDF_STATUS_E_FAILURE; 260 } 261 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 262 263 return 0; 264 } 265 266 #ifdef CONFIG_MCL 267 static inline void copy_channel_info( 268 wmi_vdev_start_request_cmd_fixed_param * cmd, 269 wmi_channel *chan, 270 struct vdev_start_params *req) 271 { 272 chan->mhz = req->chan_freq; 273 274 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 275 276 chan->band_center_freq1 = req->band_center_freq1; 277 chan->band_center_freq2 = req->band_center_freq2; 278 279 if (req->is_half_rate) 280 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 281 else if (req->is_quarter_rate) 282 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 283 284 if (req->is_dfs && req->flag_dfs) { 285 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 286 cmd->disable_hw_ack = req->dis_hw_ack; 287 } 288 289 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 290 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 291 292 } 293 #else 294 static inline void copy_channel_info( 295 wmi_vdev_start_request_cmd_fixed_param * cmd, 296 wmi_channel *chan, 297 struct vdev_start_params *req) 298 { 299 chan->mhz = req->channel.mhz; 300 301 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 302 303 chan->band_center_freq1 = req->channel.cfreq1; 304 chan->band_center_freq2 = req->channel.cfreq2; 305 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 306 307 if (req->channel.half_rate) 308 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 309 else if (req->channel.quarter_rate) 310 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 311 312 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 313 314 if (req->channel.dfs_set) { 315 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 316 cmd->disable_hw_ack = req->disable_hw_ack; 317 } 318 319 if (req->channel.dfs_set_cfreq2) 320 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 321 322 /* According to firmware both reg power and max tx power 323 * on set channel power is used and set it to max reg 324 * power from regulatory. 325 */ 326 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 327 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 328 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 329 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 330 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 331 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 332 333 } 334 #endif 335 /** 336 * send_vdev_start_cmd_tlv() - send vdev start request to fw 337 * @wmi_handle: wmi handle 338 * @req: vdev start params 339 * 340 * Return: QDF status 341 */ 342 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 343 struct vdev_start_params *req) 344 { 345 wmi_vdev_start_request_cmd_fixed_param *cmd; 346 wmi_buf_t buf; 347 wmi_channel *chan; 348 int32_t len, ret; 349 uint8_t *buf_ptr; 350 351 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 352 buf = wmi_buf_alloc(wmi_handle, len); 353 if (!buf) { 354 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 355 return QDF_STATUS_E_NOMEM; 356 } 357 buf_ptr = (uint8_t *) wmi_buf_data(buf); 358 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 359 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 360 WMITLV_SET_HDR(&cmd->tlv_header, 361 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 362 WMITLV_GET_STRUCT_TLVLEN 363 (wmi_vdev_start_request_cmd_fixed_param)); 364 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 365 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 366 cmd->vdev_id = req->vdev_id; 367 368 /* Fill channel info */ 369 copy_channel_info(cmd, chan, req); 370 371 cmd->beacon_interval = req->beacon_intval; 372 cmd->dtim_period = req->dtim_period; 373 374 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 375 if (req->bcn_tx_rate_code) 376 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 377 378 if (!req->is_restart) { 379 cmd->beacon_interval = req->beacon_intval; 380 cmd->dtim_period = req->dtim_period; 381 382 /* Copy the SSID */ 383 if (req->ssid.length) { 384 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 385 cmd->ssid.ssid_len = req->ssid.length; 386 else 387 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 388 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 389 cmd->ssid.ssid_len); 390 } 391 392 if (req->hidden_ssid) 393 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 394 395 if (req->pmf_enabled) 396 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 397 } 398 399 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 400 cmd->num_noa_descriptors = req->num_noa_descriptors; 401 cmd->preferred_rx_streams = req->preferred_rx_streams; 402 cmd->preferred_tx_streams = req->preferred_tx_streams; 403 cmd->cac_duration_ms = req->cac_duration_ms; 404 cmd->regdomain = req->regdomain; 405 cmd->he_ops = req->he_ops; 406 407 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 408 sizeof(wmi_channel)); 409 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 410 cmd->num_noa_descriptors * 411 sizeof(wmi_p2p_noa_descriptor)); 412 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 413 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 414 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 415 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 416 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 417 chan->mhz, req->chan_mode, chan->info, 418 req->is_dfs, req->beacon_intval, cmd->dtim_period, 419 chan->band_center_freq1, chan->band_center_freq2, 420 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 421 req->preferred_tx_streams, req->preferred_rx_streams, 422 req->ldpc_rx_enabled, req->cac_duration_ms, 423 req->regdomain, req->he_ops, 424 req->dis_hw_ack); 425 426 if (req->is_restart) 427 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 428 WMI_VDEV_RESTART_REQUEST_CMDID); 429 else 430 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 431 WMI_VDEV_START_REQUEST_CMDID); 432 if (ret) { 433 WMI_LOGP("%s: Failed to send vdev start command", __func__); 434 wmi_buf_free(buf); 435 return QDF_STATUS_E_FAILURE; 436 } 437 438 return QDF_STATUS_SUCCESS; 439 } 440 441 /** 442 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 443 * @wmi_handle: wmi handle 444 * @restart_params: vdev restart params 445 * 446 * Return: QDF_STATUS_SUCCESS for success or error code 447 */ 448 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 449 struct hidden_ssid_vdev_restart_params *restart_params) 450 { 451 wmi_vdev_start_request_cmd_fixed_param *cmd; 452 wmi_buf_t buf; 453 wmi_channel *chan; 454 int32_t len; 455 uint8_t *buf_ptr; 456 QDF_STATUS ret = 0; 457 458 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 459 buf = wmi_buf_alloc(wmi_handle, len); 460 if (!buf) { 461 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 462 return QDF_STATUS_E_NOMEM; 463 } 464 buf_ptr = (uint8_t *) wmi_buf_data(buf); 465 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 466 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 467 468 WMITLV_SET_HDR(&cmd->tlv_header, 469 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 470 WMITLV_GET_STRUCT_TLVLEN 471 (wmi_vdev_start_request_cmd_fixed_param)); 472 473 WMITLV_SET_HDR(&chan->tlv_header, 474 WMITLV_TAG_STRUC_wmi_channel, 475 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 476 477 cmd->vdev_id = restart_params->session_id; 478 cmd->ssid.ssid_len = restart_params->ssid_len; 479 qdf_mem_copy(cmd->ssid.ssid, 480 restart_params->ssid, 481 cmd->ssid.ssid_len); 482 cmd->flags = restart_params->flags; 483 cmd->requestor_id = restart_params->requestor_id; 484 cmd->disable_hw_ack = restart_params->disable_hw_ack; 485 486 chan->mhz = restart_params->mhz; 487 chan->band_center_freq1 = 488 restart_params->band_center_freq1; 489 chan->band_center_freq2 = 490 restart_params->band_center_freq2; 491 chan->info = restart_params->info; 492 chan->reg_info_1 = restart_params->reg_info_1; 493 chan->reg_info_2 = restart_params->reg_info_2; 494 495 cmd->num_noa_descriptors = 0; 496 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 497 sizeof(wmi_channel)); 498 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 499 cmd->num_noa_descriptors * 500 sizeof(wmi_p2p_noa_descriptor)); 501 502 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 503 WMI_VDEV_RESTART_REQUEST_CMDID); 504 if (QDF_IS_STATUS_ERROR(ret)) { 505 wmi_buf_free(buf); 506 return QDF_STATUS_E_FAILURE; 507 } 508 return QDF_STATUS_SUCCESS; 509 } 510 511 512 /** 513 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 514 * @wmi: wmi handle 515 * @peer_addr: peer mac address 516 * @param: pointer to hold peer flush tid parameter 517 * 518 * Return: 0 for success or error code 519 */ 520 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 521 uint8_t peer_addr[IEEE80211_ADDR_LEN], 522 struct peer_flush_params *param) 523 { 524 wmi_peer_flush_tids_cmd_fixed_param *cmd; 525 wmi_buf_t buf; 526 int32_t len = sizeof(*cmd); 527 528 buf = wmi_buf_alloc(wmi, len); 529 if (!buf) { 530 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 531 return QDF_STATUS_E_NOMEM; 532 } 533 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 534 WMITLV_SET_HDR(&cmd->tlv_header, 535 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 536 WMITLV_GET_STRUCT_TLVLEN 537 (wmi_peer_flush_tids_cmd_fixed_param)); 538 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 539 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 540 cmd->vdev_id = param->vdev_id; 541 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 542 peer_addr, param->vdev_id, 543 param->peer_tid_bitmap); 544 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 545 WMI_LOGP("%s: Failed to send flush tid command", __func__); 546 wmi_buf_free(buf); 547 return QDF_STATUS_E_FAILURE; 548 } 549 550 return 0; 551 } 552 553 /** 554 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 555 * @wmi: wmi handle 556 * @peer_addr: peer mac addr 557 * @vdev_id: vdev id 558 * 559 * Return: QDF_STATUS_SUCCESS for success or error code 560 */ 561 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 562 uint8_t peer_addr[IEEE80211_ADDR_LEN], 563 uint8_t vdev_id) 564 { 565 wmi_peer_delete_cmd_fixed_param *cmd; 566 wmi_buf_t buf; 567 int32_t len = sizeof(*cmd); 568 buf = wmi_buf_alloc(wmi, len); 569 if (!buf) { 570 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 571 return QDF_STATUS_E_NOMEM; 572 } 573 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 574 WMITLV_SET_HDR(&cmd->tlv_header, 575 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 576 WMITLV_GET_STRUCT_TLVLEN 577 (wmi_peer_delete_cmd_fixed_param)); 578 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 579 cmd->vdev_id = vdev_id; 580 581 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 582 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 583 WMI_LOGP("%s: Failed to send peer delete command", __func__); 584 wmi_buf_free(buf); 585 return QDF_STATUS_E_FAILURE; 586 } 587 588 return 0; 589 } 590 591 /** 592 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 593 * to target id. 594 * @targ_paramid: Target parameter id to hold the result. 595 * @peer_param_id: host param id. 596 * 597 * Return: QDF_STATUS_SUCCESS for success 598 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 599 */ 600 #ifdef CONFIG_MCL 601 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 602 uint32_t *targ_paramid, 603 uint32_t peer_param_id) 604 { 605 *targ_paramid = peer_param_id; 606 return QDF_STATUS_SUCCESS; 607 } 608 #else 609 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 610 uint32_t *targ_paramid, 611 uint32_t peer_param_id) 612 { 613 switch (peer_param_id) { 614 case WMI_HOST_PEER_MIMO_PS_STATE: 615 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 616 break; 617 case WMI_HOST_PEER_AMPDU: 618 *targ_paramid = WMI_PEER_AMPDU; 619 break; 620 case WMI_HOST_PEER_AUTHORIZE: 621 *targ_paramid = WMI_PEER_AUTHORIZE; 622 break; 623 case WMI_HOST_PEER_CHWIDTH: 624 *targ_paramid = WMI_PEER_CHWIDTH; 625 break; 626 case WMI_HOST_PEER_NSS: 627 *targ_paramid = WMI_PEER_NSS; 628 break; 629 case WMI_HOST_PEER_USE_4ADDR: 630 *targ_paramid = WMI_PEER_USE_4ADDR; 631 break; 632 case WMI_HOST_PEER_MEMBERSHIP: 633 *targ_paramid = WMI_PEER_MEMBERSHIP; 634 break; 635 case WMI_HOST_PEER_USERPOS: 636 *targ_paramid = WMI_PEER_USERPOS; 637 break; 638 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 639 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 640 break; 641 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 642 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 643 break; 644 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 645 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 646 break; 647 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 648 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 649 break; 650 case WMI_HOST_PEER_PHYMODE: 651 *targ_paramid = WMI_PEER_PHYMODE; 652 break; 653 case WMI_HOST_PEER_USE_FIXED_PWR: 654 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 655 break; 656 case WMI_HOST_PEER_PARAM_FIXED_RATE: 657 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 658 break; 659 case WMI_HOST_PEER_SET_MU_WHITELIST: 660 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 661 break; 662 case WMI_HOST_PEER_SET_MAC_TX_RATE: 663 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 664 break; 665 case WMI_HOST_PEER_SET_MIN_TX_RATE: 666 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 667 break; 668 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 669 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 670 break; 671 case WMI_HOST_PEER_NSS_VHT160: 672 *targ_paramid = WMI_PEER_NSS_VHT160; 673 break; 674 case WMI_HOST_PEER_NSS_VHT80_80: 675 *targ_paramid = WMI_PEER_NSS_VHT80_80; 676 break; 677 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 678 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 679 break; 680 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 681 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 682 break; 683 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 684 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 685 break; 686 case WMI_HOST_PEER_PARAM_MU_ENABLE: 687 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 688 break; 689 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 690 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 691 break; 692 default: 693 return QDF_STATUS_E_NOSUPPORT; 694 } 695 696 return QDF_STATUS_SUCCESS; 697 } 698 #endif 699 /** 700 * send_peer_param_cmd_tlv() - set peer parameter in fw 701 * @wmi: wmi handle 702 * @peer_addr: peer mac address 703 * @param : pointer to hold peer set parameter 704 * 705 * Return: QDF_STATUS_SUCCESS for success or error code 706 */ 707 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 708 uint8_t peer_addr[IEEE80211_ADDR_LEN], 709 struct peer_set_params *param) 710 { 711 wmi_peer_set_param_cmd_fixed_param *cmd; 712 wmi_buf_t buf; 713 int32_t err; 714 uint32_t param_id; 715 716 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 717 param->param_id) != QDF_STATUS_SUCCESS) 718 return QDF_STATUS_E_NOSUPPORT; 719 720 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 721 if (!buf) { 722 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 723 return QDF_STATUS_E_NOMEM; 724 } 725 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 726 WMITLV_SET_HDR(&cmd->tlv_header, 727 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 728 WMITLV_GET_STRUCT_TLVLEN 729 (wmi_peer_set_param_cmd_fixed_param)); 730 cmd->vdev_id = param->vdev_id; 731 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 732 cmd->param_id = param_id; 733 cmd->param_value = param->param_value; 734 err = wmi_unified_cmd_send(wmi, buf, 735 sizeof(wmi_peer_set_param_cmd_fixed_param), 736 WMI_PEER_SET_PARAM_CMDID); 737 if (err) { 738 WMI_LOGE("Failed to send set_param cmd"); 739 wmi_buf_free(buf); 740 return QDF_STATUS_E_FAILURE; 741 } 742 743 return 0; 744 } 745 746 /** 747 * send_vdev_up_cmd_tlv() - send vdev up command in fw 748 * @wmi: wmi handle 749 * @bssid: bssid 750 * @vdev_up_params: pointer to hold vdev up parameter 751 * 752 * Return: QDF_STATUS_SUCCESS for success or error code 753 */ 754 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 755 uint8_t bssid[IEEE80211_ADDR_LEN], 756 struct vdev_up_params *params) 757 { 758 wmi_vdev_up_cmd_fixed_param *cmd; 759 wmi_buf_t buf; 760 int32_t len = sizeof(*cmd); 761 762 WMI_LOGD("%s: VDEV_UP", __func__); 763 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 764 params->vdev_id, params->assoc_id, bssid); 765 buf = wmi_buf_alloc(wmi, len); 766 if (!buf) { 767 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 768 return QDF_STATUS_E_NOMEM; 769 } 770 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 771 WMITLV_SET_HDR(&cmd->tlv_header, 772 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 773 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 774 cmd->vdev_id = params->vdev_id; 775 cmd->vdev_assoc_id = params->assoc_id; 776 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 777 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 778 WMI_LOGP("%s: Failed to send vdev up command", __func__); 779 wmi_buf_free(buf); 780 return QDF_STATUS_E_FAILURE; 781 } 782 783 return 0; 784 } 785 786 /** 787 * send_peer_create_cmd_tlv() - send peer create command to fw 788 * @wmi: wmi handle 789 * @peer_addr: peer mac address 790 * @peer_type: peer type 791 * @vdev_id: vdev id 792 * 793 * Return: QDF_STATUS_SUCCESS for success or error code 794 */ 795 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 796 struct peer_create_params *param) 797 { 798 wmi_peer_create_cmd_fixed_param *cmd; 799 wmi_buf_t buf; 800 int32_t len = sizeof(*cmd); 801 802 buf = wmi_buf_alloc(wmi, len); 803 if (!buf) { 804 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 805 return QDF_STATUS_E_NOMEM; 806 } 807 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 808 WMITLV_SET_HDR(&cmd->tlv_header, 809 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 810 WMITLV_GET_STRUCT_TLVLEN 811 (wmi_peer_create_cmd_fixed_param)); 812 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 813 cmd->peer_type = param->peer_type; 814 cmd->vdev_id = param->vdev_id; 815 816 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 817 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 818 wmi_buf_free(buf); 819 return QDF_STATUS_E_FAILURE; 820 } 821 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 822 param->vdev_id); 823 824 return 0; 825 } 826 827 /** 828 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 829 * command to fw 830 * @wmi: wmi handle 831 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 832 * 833 * Return: 0 for success or error code 834 */ 835 static 836 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 837 struct rx_reorder_queue_setup_params *param) 838 { 839 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 840 wmi_buf_t buf; 841 int32_t len = sizeof(*cmd); 842 843 buf = wmi_buf_alloc(wmi, len); 844 if (!buf) { 845 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 846 return QDF_STATUS_E_NOMEM; 847 } 848 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 849 WMITLV_SET_HDR(&cmd->tlv_header, 850 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 851 WMITLV_GET_STRUCT_TLVLEN 852 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 853 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 854 cmd->vdev_id = param->vdev_id; 855 cmd->tid = param->tid; 856 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 857 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 858 cmd->queue_no = param->queue_no; 859 860 if (wmi_unified_cmd_send(wmi, buf, len, 861 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 862 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 863 __func__); 864 qdf_nbuf_free(buf); 865 return QDF_STATUS_E_FAILURE; 866 } 867 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 868 param->peer_macaddr, param->vdev_id, param->tid); 869 870 return QDF_STATUS_SUCCESS; 871 } 872 873 /** 874 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 875 * command to fw 876 * @wmi: wmi handle 877 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 878 * 879 * Return: 0 for success or error code 880 */ 881 static 882 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 883 struct rx_reorder_queue_remove_params *param) 884 { 885 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 886 wmi_buf_t buf; 887 int32_t len = sizeof(*cmd); 888 889 buf = wmi_buf_alloc(wmi, len); 890 if (!buf) { 891 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 892 return QDF_STATUS_E_NOMEM; 893 } 894 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 895 wmi_buf_data(buf); 896 WMITLV_SET_HDR(&cmd->tlv_header, 897 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 898 WMITLV_GET_STRUCT_TLVLEN 899 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 900 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 901 cmd->vdev_id = param->vdev_id; 902 cmd->tid_mask = param->peer_tid_bitmap; 903 904 if (wmi_unified_cmd_send(wmi, buf, len, 905 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 906 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 907 __func__); 908 qdf_nbuf_free(buf); 909 return QDF_STATUS_E_FAILURE; 910 } 911 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 912 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 913 914 return QDF_STATUS_SUCCESS; 915 } 916 917 /** 918 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 919 * @wmi_handle: wmi handle 920 * @param: pointer holding peer details 921 * 922 * Return: 0 for success or error code 923 */ 924 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 925 struct peer_add_wds_entry_params *param) 926 { 927 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 928 wmi_buf_t buf; 929 int len = sizeof(*cmd); 930 931 buf = wmi_buf_alloc(wmi_handle, len); 932 if (!buf) { 933 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 934 return QDF_STATUS_E_FAILURE; 935 } 936 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 937 WMITLV_SET_HDR(&cmd->tlv_header, 938 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 939 WMITLV_GET_STRUCT_TLVLEN 940 (wmi_peer_add_wds_entry_cmd_fixed_param)); 941 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 942 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 943 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 944 cmd->vdev_id = param->vdev_id; 945 946 return wmi_unified_cmd_send(wmi_handle, buf, len, 947 WMI_PEER_ADD_WDS_ENTRY_CMDID); 948 } 949 950 /** 951 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 952 * @wmi_handle: wmi handle 953 * @param: pointer holding peer details 954 * 955 * Return: 0 for success or error code 956 */ 957 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 958 struct peer_del_wds_entry_params *param) 959 { 960 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 961 wmi_buf_t buf; 962 int len = sizeof(*cmd); 963 964 buf = wmi_buf_alloc(wmi_handle, len); 965 if (!buf) { 966 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 967 return QDF_STATUS_E_NOMEM; 968 } 969 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 970 WMITLV_SET_HDR(&cmd->tlv_header, 971 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 972 WMITLV_GET_STRUCT_TLVLEN 973 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 974 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 975 cmd->vdev_id = param->vdev_id; 976 return wmi_unified_cmd_send(wmi_handle, buf, len, 977 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 978 } 979 980 /** 981 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 982 * @wmi_handle: wmi handle 983 * @param: pointer holding peer details 984 * 985 * Return: 0 for success or error code 986 */ 987 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 988 struct peer_update_wds_entry_params *param) 989 { 990 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 991 wmi_buf_t buf; 992 int len = sizeof(*cmd); 993 994 buf = wmi_buf_alloc(wmi_handle, len); 995 if (!buf) { 996 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 997 return QDF_STATUS_E_NOMEM; 998 } 999 1000 /* wmi_buf_alloc returns zeroed command buffer */ 1001 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1002 WMITLV_SET_HDR(&cmd->tlv_header, 1003 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 1004 WMITLV_GET_STRUCT_TLVLEN 1005 (wmi_peer_update_wds_entry_cmd_fixed_param)); 1006 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1007 cmd->vdev_id = param->vdev_id; 1008 if (param->wds_macaddr) 1009 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1010 &cmd->wds_macaddr); 1011 if (param->peer_macaddr) 1012 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1013 &cmd->peer_macaddr); 1014 return wmi_unified_cmd_send(wmi_handle, buf, len, 1015 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1016 } 1017 1018 /** 1019 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1020 * @wmi_handle: wmi handle 1021 * @param: pointer to get tpc config params 1022 * 1023 * Return: 0 for success or error code 1024 */ 1025 static QDF_STATUS 1026 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1027 uint32_t param) 1028 { 1029 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1030 wmi_buf_t buf; 1031 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1032 1033 buf = wmi_buf_alloc(wmi_handle, len); 1034 if (!buf) { 1035 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1036 return QDF_STATUS_E_NOMEM; 1037 } 1038 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1039 WMITLV_SET_HDR(&cmd->tlv_header, 1040 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1041 WMITLV_GET_STRUCT_TLVLEN 1042 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1043 1044 cmd->param = param; 1045 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1046 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1047 WMI_LOGE("Send pdev get tpc config cmd failed"); 1048 wmi_buf_free(buf); 1049 return QDF_STATUS_E_FAILURE; 1050 1051 } 1052 WMI_LOGD("%s:send success", __func__); 1053 1054 return QDF_STATUS_SUCCESS; 1055 } 1056 1057 #ifdef WLAN_SUPPORT_GREEN_AP 1058 /** 1059 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1060 * @wmi_handle: wmi handle 1061 * @value: value 1062 * @pdev_id: pdev id to have radio context 1063 * 1064 * Return: QDF_STATUS_SUCCESS for success or error code 1065 */ 1066 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1067 uint32_t value, uint8_t pdev_id) 1068 { 1069 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1070 wmi_buf_t buf; 1071 int32_t len = sizeof(*cmd); 1072 1073 WMI_LOGD("Set Green AP PS val %d", value); 1074 1075 buf = wmi_buf_alloc(wmi_handle, len); 1076 if (!buf) { 1077 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1078 return QDF_STATUS_E_NOMEM; 1079 } 1080 1081 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1082 WMITLV_SET_HDR(&cmd->tlv_header, 1083 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1084 WMITLV_GET_STRUCT_TLVLEN 1085 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1086 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1087 cmd->enable = value; 1088 1089 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1090 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1091 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1092 wmi_buf_free(buf); 1093 return QDF_STATUS_E_FAILURE; 1094 } 1095 1096 return 0; 1097 } 1098 #endif 1099 1100 /** 1101 * send_pdev_utf_cmd_tlv() - send utf command to fw 1102 * @wmi_handle: wmi handle 1103 * @param: pointer to pdev_utf_params 1104 * @mac_id: mac id to have radio context 1105 * 1106 * Return: QDF_STATUS_SUCCESS for success or error code 1107 */ 1108 static QDF_STATUS 1109 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1110 struct pdev_utf_params *param, 1111 uint8_t mac_id) 1112 { 1113 wmi_buf_t buf; 1114 uint8_t *cmd; 1115 /* if param->len is 0 no data is sent, return error */ 1116 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1117 static uint8_t msgref = 1; 1118 uint8_t segNumber = 0, segInfo, numSegments; 1119 uint16_t chunk_len, total_bytes; 1120 uint8_t *bufpos; 1121 struct seg_hdr_info segHdrInfo; 1122 1123 bufpos = param->utf_payload; 1124 total_bytes = param->len; 1125 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1126 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1127 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1128 1129 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1130 numSegments++; 1131 1132 while (param->len) { 1133 if (param->len > MAX_WMI_UTF_LEN) 1134 chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */ 1135 else 1136 chunk_len = param->len; 1137 1138 buf = wmi_buf_alloc(wmi_handle, 1139 (chunk_len + sizeof(segHdrInfo) + 1140 WMI_TLV_HDR_SIZE)); 1141 if (!buf) { 1142 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1143 return QDF_STATUS_E_NOMEM; 1144 } 1145 1146 cmd = (uint8_t *) wmi_buf_data(buf); 1147 1148 segHdrInfo.len = total_bytes; 1149 segHdrInfo.msgref = msgref; 1150 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1151 segHdrInfo.segmentInfo = segInfo; 1152 segHdrInfo.pad = 0; 1153 1154 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1155 " segHdrInfo.segmentInfo = %d", 1156 __func__, segHdrInfo.len, segHdrInfo.msgref, 1157 segHdrInfo.segmentInfo); 1158 1159 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1160 "chunk len %d", __func__, total_bytes, segNumber, 1161 numSegments, chunk_len); 1162 1163 segNumber++; 1164 1165 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1166 (chunk_len + sizeof(segHdrInfo))); 1167 cmd += WMI_TLV_HDR_SIZE; 1168 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1169 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1170 1171 ret = wmi_unified_cmd_send(wmi_handle, buf, 1172 (chunk_len + sizeof(segHdrInfo) + 1173 WMI_TLV_HDR_SIZE), 1174 WMI_PDEV_UTF_CMDID); 1175 1176 if (QDF_IS_STATUS_ERROR(ret)) { 1177 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1178 wmi_buf_free(buf); 1179 break; 1180 } 1181 1182 param->len -= chunk_len; 1183 bufpos += chunk_len; 1184 } 1185 1186 msgref++; 1187 1188 return ret; 1189 } 1190 #ifdef CONFIG_MCL 1191 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1192 uint32_t host_param) 1193 { 1194 return host_param; 1195 } 1196 #else 1197 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1198 uint32_t host_param) 1199 { 1200 if (host_param < wmi_pdev_param_max) 1201 return wmi_handle->pdev_param[host_param]; 1202 1203 return WMI_UNAVAILABLE_PARAM; 1204 } 1205 #endif 1206 /** 1207 * send_pdev_param_cmd_tlv() - set pdev parameters 1208 * @wmi_handle: wmi handle 1209 * @param: pointer to pdev parameter 1210 * @mac_id: radio context 1211 * 1212 * Return: 0 on success, errno on failure 1213 */ 1214 static QDF_STATUS 1215 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1216 struct pdev_params *param, 1217 uint8_t mac_id) 1218 { 1219 QDF_STATUS ret; 1220 wmi_pdev_set_param_cmd_fixed_param *cmd; 1221 wmi_buf_t buf; 1222 uint16_t len = sizeof(*cmd); 1223 uint32_t pdev_param; 1224 1225 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1226 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1227 WMI_LOGW("%s: Unavailable param %d\n", 1228 __func__, param->param_id); 1229 return QDF_STATUS_E_INVAL; 1230 } 1231 1232 buf = wmi_buf_alloc(wmi_handle, len); 1233 if (!buf) { 1234 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1235 return QDF_STATUS_E_NOMEM; 1236 } 1237 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1238 WMITLV_SET_HDR(&cmd->tlv_header, 1239 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1240 WMITLV_GET_STRUCT_TLVLEN 1241 (wmi_pdev_set_param_cmd_fixed_param)); 1242 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1243 cmd->param_id = pdev_param; 1244 cmd->param_value = param->param_value; 1245 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1246 param->param_value); 1247 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1248 WMI_PDEV_SET_PARAM_CMDID); 1249 if (QDF_IS_STATUS_ERROR(ret)) { 1250 WMI_LOGE("Failed to send set param command ret = %d", ret); 1251 wmi_buf_free(buf); 1252 } 1253 return ret; 1254 } 1255 1256 /** 1257 * send_suspend_cmd_tlv() - WMI suspend function 1258 * @param wmi_handle : handle to WMI. 1259 * @param param : pointer to hold suspend parameter 1260 * @mac_id: radio context 1261 * 1262 * Return 0 on success and -ve on failure. 1263 */ 1264 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1265 struct suspend_params *param, 1266 uint8_t mac_id) 1267 { 1268 wmi_pdev_suspend_cmd_fixed_param *cmd; 1269 wmi_buf_t wmibuf; 1270 uint32_t len = sizeof(*cmd); 1271 int32_t ret; 1272 1273 /* 1274 * send the comand to Target to ignore the 1275 * PCIE reset so as to ensure that Host and target 1276 * states are in sync 1277 */ 1278 wmibuf = wmi_buf_alloc(wmi_handle, len); 1279 if (wmibuf == NULL) 1280 return QDF_STATUS_E_NOMEM; 1281 1282 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1283 WMITLV_SET_HDR(&cmd->tlv_header, 1284 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1285 WMITLV_GET_STRUCT_TLVLEN 1286 (wmi_pdev_suspend_cmd_fixed_param)); 1287 if (param->disable_target_intr) 1288 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1289 else 1290 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1291 1292 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1293 1294 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1295 WMI_PDEV_SUSPEND_CMDID); 1296 if (ret) { 1297 wmi_buf_free(wmibuf); 1298 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1299 } 1300 1301 return ret; 1302 } 1303 1304 /** 1305 * send_resume_cmd_tlv() - WMI resume function 1306 * @param wmi_handle : handle to WMI. 1307 * @mac_id: radio context 1308 * 1309 * Return: 0 on success and -ve on failure. 1310 */ 1311 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1312 uint8_t mac_id) 1313 { 1314 wmi_buf_t wmibuf; 1315 wmi_pdev_resume_cmd_fixed_param *cmd; 1316 QDF_STATUS ret; 1317 1318 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1319 if (wmibuf == NULL) 1320 return QDF_STATUS_E_NOMEM; 1321 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1322 WMITLV_SET_HDR(&cmd->tlv_header, 1323 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1324 WMITLV_GET_STRUCT_TLVLEN 1325 (wmi_pdev_resume_cmd_fixed_param)); 1326 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1327 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1328 WMI_PDEV_RESUME_CMDID); 1329 if (QDF_IS_STATUS_ERROR(ret)) { 1330 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1331 wmi_buf_free(wmibuf); 1332 } 1333 1334 return ret; 1335 } 1336 1337 #ifdef FEATURE_WLAN_D0WOW 1338 /** 1339 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1340 * @param wmi_handle: handle to WMI. 1341 * @mac_id: radio context 1342 * 1343 * Return: 0 on success and error code on failure. 1344 */ 1345 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1346 uint8_t mac_id) 1347 { 1348 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1349 wmi_buf_t buf; 1350 int32_t len; 1351 QDF_STATUS status; 1352 1353 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1354 1355 buf = wmi_buf_alloc(wmi_handle, len); 1356 if (!buf) { 1357 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1358 return QDF_STATUS_E_NOMEM; 1359 } 1360 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1361 WMITLV_SET_HDR(&cmd->tlv_header, 1362 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1363 WMITLV_GET_STRUCT_TLVLEN 1364 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1365 1366 cmd->enable = true; 1367 1368 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1369 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1370 if (QDF_IS_STATUS_ERROR(status)) 1371 wmi_buf_free(buf); 1372 1373 return status; 1374 } 1375 1376 /** 1377 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1378 * @param wmi_handle: handle to WMI. 1379 * @mac_id: radio context 1380 * 1381 * Return: 0 on success and error code on failure. 1382 */ 1383 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1384 uint8_t mac_id) 1385 { 1386 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1387 wmi_buf_t buf; 1388 int32_t len; 1389 QDF_STATUS status; 1390 1391 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1392 1393 buf = wmi_buf_alloc(wmi_handle, len); 1394 if (!buf) { 1395 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1396 return QDF_STATUS_E_NOMEM; 1397 } 1398 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1399 WMITLV_SET_HDR(&cmd->tlv_header, 1400 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1401 WMITLV_GET_STRUCT_TLVLEN 1402 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1403 1404 cmd->enable = false; 1405 1406 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1407 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1408 if (QDF_IS_STATUS_ERROR(status)) 1409 wmi_buf_free(buf); 1410 1411 return status; 1412 } 1413 #endif 1414 1415 /** 1416 * send_wow_enable_cmd_tlv() - WMI wow enable function 1417 * @param wmi_handle : handle to WMI. 1418 * @param param : pointer to hold wow enable parameter 1419 * @mac_id: radio context 1420 * 1421 * Return: 0 on success and -ve on failure. 1422 */ 1423 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1424 struct wow_cmd_params *param, 1425 uint8_t mac_id) 1426 { 1427 wmi_wow_enable_cmd_fixed_param *cmd; 1428 wmi_buf_t buf; 1429 int32_t len; 1430 int32_t ret; 1431 1432 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1433 1434 buf = wmi_buf_alloc(wmi_handle, len); 1435 if (!buf) { 1436 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1437 return QDF_STATUS_E_NOMEM; 1438 } 1439 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1440 WMITLV_SET_HDR(&cmd->tlv_header, 1441 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1442 WMITLV_GET_STRUCT_TLVLEN 1443 (wmi_wow_enable_cmd_fixed_param)); 1444 cmd->enable = param->enable; 1445 if (param->can_suspend_link) 1446 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1447 else 1448 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1449 cmd->flags = param->flags; 1450 1451 WMI_LOGI("suspend type: %s", 1452 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1453 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1454 1455 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1456 WMI_WOW_ENABLE_CMDID); 1457 if (ret) 1458 wmi_buf_free(buf); 1459 1460 return ret; 1461 } 1462 1463 /** 1464 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1465 * @wmi_handle: wmi handle 1466 * @peer_addr: peer mac address 1467 * @param: pointer to ap_ps parameter structure 1468 * 1469 * Return: QDF_STATUS_SUCCESS for success or error code 1470 */ 1471 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1472 uint8_t *peer_addr, 1473 struct ap_ps_params *param) 1474 { 1475 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1476 wmi_buf_t buf; 1477 int32_t err; 1478 1479 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1480 if (!buf) { 1481 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1482 return QDF_STATUS_E_NOMEM; 1483 } 1484 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1485 WMITLV_SET_HDR(&cmd->tlv_header, 1486 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1487 WMITLV_GET_STRUCT_TLVLEN 1488 (wmi_ap_ps_peer_cmd_fixed_param)); 1489 cmd->vdev_id = param->vdev_id; 1490 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1491 cmd->param = param->param; 1492 cmd->value = param->value; 1493 err = wmi_unified_cmd_send(wmi_handle, buf, 1494 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1495 if (err) { 1496 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1497 wmi_buf_free(buf); 1498 return QDF_STATUS_E_FAILURE; 1499 } 1500 1501 return 0; 1502 } 1503 1504 /** 1505 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1506 * @wmi_handle: wmi handle 1507 * @peer_addr: peer mac address 1508 * @param: pointer to sta_ps parameter structure 1509 * 1510 * Return: QDF_STATUS_SUCCESS for success or error code 1511 */ 1512 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1513 struct sta_ps_params *param) 1514 { 1515 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1516 wmi_buf_t buf; 1517 int32_t len = sizeof(*cmd); 1518 1519 buf = wmi_buf_alloc(wmi_handle, len); 1520 if (!buf) { 1521 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1522 return QDF_STATUS_E_NOMEM; 1523 } 1524 1525 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1526 WMITLV_SET_HDR(&cmd->tlv_header, 1527 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1528 WMITLV_GET_STRUCT_TLVLEN 1529 (wmi_sta_powersave_param_cmd_fixed_param)); 1530 cmd->vdev_id = param->vdev_id; 1531 cmd->param = param->param; 1532 cmd->value = param->value; 1533 1534 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1535 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1536 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1537 param->vdev_id, param->param, param->value); 1538 wmi_buf_free(buf); 1539 return QDF_STATUS_E_FAILURE; 1540 } 1541 1542 return 0; 1543 } 1544 1545 /** 1546 * send_crash_inject_cmd_tlv() - inject fw crash 1547 * @wmi_handle: wmi handle 1548 * @param: ponirt to crash inject paramter structure 1549 * 1550 * Return: QDF_STATUS_SUCCESS for success or return error 1551 */ 1552 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1553 struct crash_inject *param) 1554 { 1555 int32_t ret = 0; 1556 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1557 uint16_t len = sizeof(*cmd); 1558 wmi_buf_t buf; 1559 1560 buf = wmi_buf_alloc(wmi_handle, len); 1561 if (!buf) { 1562 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1563 return QDF_STATUS_E_NOMEM; 1564 } 1565 1566 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1567 WMITLV_SET_HDR(&cmd->tlv_header, 1568 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1569 WMITLV_GET_STRUCT_TLVLEN 1570 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1571 cmd->type = param->type; 1572 cmd->delay_time_ms = param->delay_time_ms; 1573 1574 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1575 WMI_FORCE_FW_HANG_CMDID); 1576 if (ret) { 1577 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1578 __func__, ret); 1579 wmi_buf_free(buf); 1580 } 1581 1582 return ret; 1583 } 1584 1585 /** 1586 * send_dbglog_cmd_tlv() - set debug log level 1587 * @param wmi_handle : handle to WMI. 1588 * @param param : pointer to hold dbglog level parameter 1589 * 1590 * Return: 0 on success and -ve on failure. 1591 */ 1592 static QDF_STATUS 1593 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1594 struct dbglog_params *dbglog_param) 1595 { 1596 wmi_buf_t buf; 1597 wmi_debug_log_config_cmd_fixed_param *configmsg; 1598 QDF_STATUS status; 1599 int32_t i; 1600 int32_t len; 1601 int8_t *buf_ptr; 1602 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1603 1604 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1605 1606 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1607 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1608 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1609 buf = wmi_buf_alloc(wmi_handle, len); 1610 if (buf == NULL) 1611 return QDF_STATUS_E_NOMEM; 1612 1613 configmsg = 1614 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1615 buf_ptr = (int8_t *) configmsg; 1616 WMITLV_SET_HDR(&configmsg->tlv_header, 1617 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1618 WMITLV_GET_STRUCT_TLVLEN 1619 (wmi_debug_log_config_cmd_fixed_param)); 1620 configmsg->dbg_log_param = dbglog_param->param; 1621 configmsg->value = dbglog_param->val; 1622 /* Filling in the data part of second tlv -- should 1623 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1624 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1625 sizeof 1626 (wmi_debug_log_config_cmd_fixed_param) 1627 + WMI_TLV_HDR_SIZE); 1628 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1629 WMITLV_TAG_ARRAY_UINT32, 1630 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1631 if (dbglog_param->module_id_bitmap) { 1632 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1633 module_id_bitmap_array[i] = 1634 dbglog_param->module_id_bitmap[i]; 1635 } 1636 } 1637 1638 status = wmi_unified_cmd_send(wmi_handle, buf, 1639 len, WMI_DBGLOG_CFG_CMDID); 1640 1641 if (status != QDF_STATUS_SUCCESS) 1642 wmi_buf_free(buf); 1643 1644 return status; 1645 } 1646 1647 #ifdef CONFIG_MCL 1648 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1649 uint32_t host_param) 1650 { 1651 return host_param; 1652 } 1653 #else 1654 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1655 uint32_t host_param) 1656 { 1657 if (host_param < wmi_vdev_param_max) 1658 return wmi_handle->vdev_param[host_param]; 1659 1660 return WMI_UNAVAILABLE_PARAM; 1661 } 1662 #endif 1663 /** 1664 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1665 * @param wmi_handle : handle to WMI. 1666 * @param macaddr : MAC address 1667 * @param param : pointer to hold vdev set parameter 1668 * 1669 * Return: 0 on success and -ve on failure. 1670 */ 1671 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1672 struct vdev_set_params *param) 1673 { 1674 QDF_STATUS ret; 1675 wmi_vdev_set_param_cmd_fixed_param *cmd; 1676 wmi_buf_t buf; 1677 uint16_t len = sizeof(*cmd); 1678 uint32_t vdev_param; 1679 1680 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1681 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1682 WMI_LOGW("%s:Vdev param %d not available", __func__, 1683 param->param_id); 1684 return QDF_STATUS_E_INVAL; 1685 1686 } 1687 1688 buf = wmi_buf_alloc(wmi_handle, len); 1689 if (!buf) { 1690 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1691 return QDF_STATUS_E_NOMEM; 1692 } 1693 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1694 WMITLV_SET_HDR(&cmd->tlv_header, 1695 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1696 WMITLV_GET_STRUCT_TLVLEN 1697 (wmi_vdev_set_param_cmd_fixed_param)); 1698 cmd->vdev_id = param->if_id; 1699 cmd->param_id = vdev_param; 1700 cmd->param_value = param->param_value; 1701 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1702 cmd->vdev_id, cmd->param_id, cmd->param_value); 1703 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1704 WMI_VDEV_SET_PARAM_CMDID); 1705 if (QDF_IS_STATUS_ERROR(ret)) { 1706 WMI_LOGE("Failed to send set param command ret = %d", ret); 1707 wmi_buf_free(buf); 1708 } 1709 1710 return ret; 1711 } 1712 1713 /** 1714 * send_stats_request_cmd_tlv() - WMI request stats function 1715 * @param wmi_handle : handle to WMI. 1716 * @param macaddr : MAC address 1717 * @param param : pointer to hold stats request parameter 1718 * 1719 * Return: 0 on success and -ve on failure. 1720 */ 1721 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1722 uint8_t macaddr[IEEE80211_ADDR_LEN], 1723 struct stats_request_params *param) 1724 { 1725 int32_t ret; 1726 wmi_request_stats_cmd_fixed_param *cmd; 1727 wmi_buf_t buf; 1728 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1729 1730 buf = wmi_buf_alloc(wmi_handle, len); 1731 if (!buf) { 1732 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1733 return -QDF_STATUS_E_NOMEM; 1734 } 1735 1736 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1737 WMITLV_SET_HDR(&cmd->tlv_header, 1738 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1739 WMITLV_GET_STRUCT_TLVLEN 1740 (wmi_request_stats_cmd_fixed_param)); 1741 cmd->stats_id = param->stats_id; 1742 cmd->vdev_id = param->vdev_id; 1743 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1744 param->pdev_id); 1745 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1746 1747 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1748 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1749 1750 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1751 WMI_REQUEST_STATS_CMDID); 1752 1753 if (ret) { 1754 WMI_LOGE("Failed to send status request to fw =%d", ret); 1755 wmi_buf_free(buf); 1756 } 1757 1758 return ret; 1759 } 1760 1761 #ifdef CONFIG_WIN 1762 /** 1763 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1764 * @param wmi_handle : handle to WMI. 1765 * @param PKTLOG_EVENT : packet log event 1766 * @mac_id: mac id to have radio context 1767 * 1768 * Return: 0 on success and -ve on failure. 1769 */ 1770 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1771 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1772 { 1773 int32_t ret; 1774 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1775 wmi_buf_t buf; 1776 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1777 1778 buf = wmi_buf_alloc(wmi_handle, len); 1779 if (!buf) { 1780 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1781 return -QDF_STATUS_E_NOMEM; 1782 } 1783 1784 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1785 WMITLV_SET_HDR(&cmd->tlv_header, 1786 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1787 WMITLV_GET_STRUCT_TLVLEN 1788 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1789 cmd->evlist = PKTLOG_EVENT; 1790 cmd->pdev_id = mac_id; 1791 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1792 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1793 if (ret) { 1794 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1795 wmi_buf_free(buf); 1796 } 1797 1798 return ret; 1799 } 1800 1801 /** 1802 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1803 * @param wmi_handle : handle to WMI. 1804 * @mac_id: mac id to have radio context 1805 * 1806 * Return: 0 on success and -ve on failure. 1807 */ 1808 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1809 uint8_t mac_id) 1810 { 1811 int32_t ret; 1812 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1813 wmi_buf_t buf; 1814 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1815 1816 buf = wmi_buf_alloc(wmi_handle, len); 1817 if (!buf) { 1818 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1819 return -QDF_STATUS_E_NOMEM; 1820 } 1821 1822 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1823 WMITLV_SET_HDR(&cmd->tlv_header, 1824 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1825 WMITLV_GET_STRUCT_TLVLEN 1826 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1827 cmd->pdev_id = mac_id; 1828 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1829 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1830 if (ret) { 1831 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1832 wmi_buf_free(buf); 1833 } 1834 1835 return ret; 1836 } 1837 #else 1838 /** 1839 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1840 * packet-log 1841 * @param wmi_handle : handle to WMI. 1842 * @param macaddr : MAC address 1843 * @param param : pointer to hold stats request parameter 1844 * 1845 * Return: 0 on success and -ve on failure. 1846 */ 1847 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1848 uint8_t macaddr[IEEE80211_ADDR_LEN], 1849 struct packet_enable_params *param) 1850 { 1851 return 0; 1852 } 1853 /** 1854 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1855 * packet-log 1856 * @param wmi_handle : handle to WMI. 1857 * @mac_id: mac id to have radio context 1858 * 1859 * Return: 0 on success and -ve on failure. 1860 */ 1861 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1862 uint8_t mac_id) 1863 { 1864 return 0; 1865 } 1866 #endif 1867 1868 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1869 /** 1870 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1871 * sync time between bwtween host and firmware 1872 * @param wmi_handle : handle to WMI. 1873 * 1874 * Return: None 1875 */ 1876 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1877 { 1878 wmi_buf_t buf; 1879 QDF_STATUS status = QDF_STATUS_SUCCESS; 1880 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1881 int32_t len; 1882 qdf_time_t time_ms; 1883 1884 len = sizeof(*time_stamp); 1885 buf = wmi_buf_alloc(wmi_handle, len); 1886 1887 if (!buf) { 1888 WMI_LOGP(FL("wmi_buf_alloc failed")); 1889 return; 1890 } 1891 time_stamp = 1892 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1893 (wmi_buf_data(buf)); 1894 WMITLV_SET_HDR(&time_stamp->tlv_header, 1895 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1896 WMITLV_GET_STRUCT_TLVLEN( 1897 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1898 1899 time_ms = qdf_get_time_of_the_day_ms(); 1900 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1901 time_stamp->time_stamp_low = time_ms & 1902 WMI_FW_TIME_STAMP_LOW_MASK; 1903 /* 1904 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1905 * wont exceed 27 bit 1906 */ 1907 time_stamp->time_stamp_high = 0; 1908 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1909 time_stamp->mode, time_stamp->time_stamp_low, 1910 time_stamp->time_stamp_high); 1911 1912 status = wmi_unified_cmd_send(wmi_handle, buf, 1913 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1914 if (status) { 1915 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1916 wmi_buf_free(buf); 1917 } 1918 1919 } 1920 1921 #ifdef WLAN_SUPPORT_FILS 1922 /** 1923 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 1924 * @wmi_handle: wmi handle 1925 * @evt_buf: pointer to event buffer 1926 * @vdev_id: pointer to hold vdev id 1927 * 1928 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 1929 */ 1930 static QDF_STATUS 1931 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 1932 void *evt_buf, uint32_t *vdev_id) 1933 { 1934 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 1935 wmi_host_swfda_event_fixed_param *swfda_event; 1936 1937 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 1938 if (!param_buf) { 1939 WMI_LOGE("Invalid swfda event buffer"); 1940 return QDF_STATUS_E_INVAL; 1941 } 1942 swfda_event = param_buf->fixed_param; 1943 *vdev_id = swfda_event->vdev_id; 1944 1945 return QDF_STATUS_SUCCESS; 1946 } 1947 1948 /** 1949 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 1950 * @wmi_handle: wmi handle 1951 * @param: pointer to hold FILS discovery enable param 1952 * 1953 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 1954 */ 1955 static QDF_STATUS 1956 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 1957 struct config_fils_params *param) 1958 { 1959 wmi_enable_fils_cmd_fixed_param *cmd; 1960 wmi_buf_t buf; 1961 QDF_STATUS status; 1962 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 1963 1964 buf = wmi_buf_alloc(wmi_handle, len); 1965 if (!buf) { 1966 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 1967 return QDF_STATUS_E_NOMEM; 1968 } 1969 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 1970 WMITLV_SET_HDR(&cmd->tlv_header, 1971 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 1972 WMITLV_GET_STRUCT_TLVLEN( 1973 wmi_enable_fils_cmd_fixed_param)); 1974 cmd->vdev_id = param->vdev_id; 1975 cmd->fd_period = param->fd_period; 1976 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 1977 param->fd_period, param->vdev_id); 1978 1979 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1980 WMI_ENABLE_FILS_CMDID); 1981 if (status != QDF_STATUS_SUCCESS) { 1982 wmi_buf_free(buf); 1983 return QDF_STATUS_E_FAILURE; 1984 } 1985 1986 return QDF_STATUS_SUCCESS; 1987 } 1988 1989 /** 1990 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 1991 * @wmi_handle: wmi handle 1992 * @param: pointer to hold FD send cmd parameter 1993 * 1994 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 1995 */ 1996 static QDF_STATUS 1997 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 1998 struct fd_params *param) 1999 { 2000 QDF_STATUS ret; 2001 wmi_fd_send_from_host_cmd_fixed_param *cmd; 2002 wmi_buf_t wmi_buf; 2003 qdf_dma_addr_t dma_addr; 2004 2005 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2006 if (!wmi_buf) { 2007 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2008 return QDF_STATUS_E_NOMEM; 2009 } 2010 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2011 WMITLV_SET_HDR(&cmd->tlv_header, 2012 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2013 WMITLV_GET_STRUCT_TLVLEN( 2014 wmi_fd_send_from_host_cmd_fixed_param)); 2015 cmd->vdev_id = param->vdev_id; 2016 cmd->data_len = qdf_nbuf_len(param->wbuf); 2017 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2018 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2019 cmd->frame_ctrl = param->frame_ctrl; 2020 2021 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2022 WMI_PDEV_SEND_FD_CMDID); 2023 if (ret != QDF_STATUS_SUCCESS) { 2024 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2025 __func__, ret); 2026 wmi_buf_free(wmi_buf); 2027 } 2028 2029 return ret; 2030 } 2031 #endif /* WLAN_SUPPORT_FILS */ 2032 2033 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2034 struct beacon_params *param) 2035 { 2036 QDF_STATUS ret; 2037 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2038 wmi_buf_t wmi_buf; 2039 qdf_dma_addr_t dma_addr; 2040 uint32_t dtim_flag = 0; 2041 2042 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2043 if (!wmi_buf) { 2044 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2045 return QDF_STATUS_E_NOMEM; 2046 } 2047 if (param->is_dtim_count_zero) { 2048 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2049 if (param->is_bitctl_reqd) { 2050 /* deliver CAB traffic in next DTIM beacon */ 2051 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2052 } 2053 } 2054 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2055 WMITLV_SET_HDR(&cmd->tlv_header, 2056 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2057 WMITLV_GET_STRUCT_TLVLEN 2058 (wmi_bcn_send_from_host_cmd_fixed_param)); 2059 cmd->vdev_id = param->vdev_id; 2060 cmd->data_len = qdf_nbuf_len(param->wbuf); 2061 cmd->frame_ctrl = param->frame_ctrl; 2062 cmd->dtim_flag = dtim_flag; 2063 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2064 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2065 #if defined(HTT_PADDR64) 2066 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2067 #endif 2068 cmd->bcn_antenna = param->bcn_txant; 2069 2070 ret = wmi_unified_cmd_send(wmi_handle, 2071 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2072 if (ret != QDF_STATUS_SUCCESS) { 2073 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2074 wmi_buf_free(wmi_buf); 2075 } 2076 2077 return ret; 2078 } 2079 2080 /** 2081 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2082 * @param wmi_handle : handle to WMI. 2083 * @param param : pointer to hold beacon send cmd parameter 2084 * 2085 * Return: 0 on success and -ve on failure. 2086 */ 2087 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2088 struct beacon_tmpl_params *param) 2089 { 2090 int32_t ret; 2091 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2092 wmi_bcn_prb_info *bcn_prb_info; 2093 wmi_buf_t wmi_buf; 2094 uint8_t *buf_ptr; 2095 uint32_t wmi_buf_len; 2096 2097 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2098 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2099 param->tmpl_len_aligned; 2100 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2101 if (!wmi_buf) { 2102 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2103 return QDF_STATUS_E_NOMEM; 2104 } 2105 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2106 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2107 WMITLV_SET_HDR(&cmd->tlv_header, 2108 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2109 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2110 cmd->vdev_id = param->vdev_id; 2111 cmd->tim_ie_offset = param->tim_ie_offset; 2112 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2113 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2114 cmd->buf_len = param->tmpl_len; 2115 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2116 2117 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2118 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2119 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2120 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2121 bcn_prb_info->caps = 0; 2122 bcn_prb_info->erp = 0; 2123 buf_ptr += sizeof(wmi_bcn_prb_info); 2124 2125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2126 buf_ptr += WMI_TLV_HDR_SIZE; 2127 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2128 2129 ret = wmi_unified_cmd_send(wmi_handle, 2130 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2131 if (ret) { 2132 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2133 wmi_buf_free(wmi_buf); 2134 } 2135 2136 return 0; 2137 } 2138 2139 #ifdef CONFIG_MCL 2140 static inline void copy_peer_flags_tlv( 2141 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2142 struct peer_assoc_params *param) 2143 { 2144 cmd->peer_flags = param->peer_flags; 2145 } 2146 #else 2147 static inline void copy_peer_flags_tlv( 2148 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2149 struct peer_assoc_params *param) 2150 { 2151 /* 2152 * The target only needs a subset of the flags maintained in the host. 2153 * Just populate those flags and send it down 2154 */ 2155 cmd->peer_flags = 0; 2156 2157 /* 2158 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2159 */ 2160 if (param->is_wme_set) { 2161 2162 if (param->qos_flag) 2163 cmd->peer_flags |= WMI_PEER_QOS; 2164 if (param->apsd_flag) 2165 cmd->peer_flags |= WMI_PEER_APSD; 2166 if (param->ht_flag) 2167 cmd->peer_flags |= WMI_PEER_HT; 2168 if (param->bw_40) 2169 cmd->peer_flags |= WMI_PEER_40MHZ; 2170 if (param->bw_80) 2171 cmd->peer_flags |= WMI_PEER_80MHZ; 2172 if (param->bw_160) 2173 cmd->peer_flags |= WMI_PEER_160MHZ; 2174 2175 /* Typically if STBC is enabled for VHT it should be enabled 2176 * for HT as well 2177 **/ 2178 if (param->stbc_flag) 2179 cmd->peer_flags |= WMI_PEER_STBC; 2180 2181 /* Typically if LDPC is enabled for VHT it should be enabled 2182 * for HT as well 2183 **/ 2184 if (param->ldpc_flag) 2185 cmd->peer_flags |= WMI_PEER_LDPC; 2186 2187 if (param->static_mimops_flag) 2188 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2189 if (param->dynamic_mimops_flag) 2190 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2191 if (param->spatial_mux_flag) 2192 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2193 if (param->vht_flag) 2194 cmd->peer_flags |= WMI_PEER_VHT; 2195 if (param->he_flag) 2196 cmd->peer_flags |= WMI_PEER_HE; 2197 } 2198 2199 if (param->is_pmf_enabled) 2200 cmd->peer_flags |= WMI_PEER_PMF; 2201 /* 2202 * Suppress authorization for all AUTH modes that need 4-way handshake 2203 * (during re-association). 2204 * Authorization will be done for these modes on key installation. 2205 */ 2206 if (param->auth_flag) 2207 cmd->peer_flags |= WMI_PEER_AUTH; 2208 if (param->need_ptk_4_way) 2209 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2210 else 2211 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2212 if (param->need_gtk_2_way) 2213 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2214 /* safe mode bypass the 4-way handshake */ 2215 if (param->safe_mode_enabled) 2216 cmd->peer_flags &= 2217 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2218 /* Disable AMSDU for station transmit, if user configures it */ 2219 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2220 * it 2221 * if (param->amsdu_disable) Add after FW support 2222 **/ 2223 2224 /* Target asserts if node is marked HT and all MCS is set to 0. 2225 * Mark the node as non-HT if all the mcs rates are disabled through 2226 * iwpriv 2227 **/ 2228 if (param->peer_ht_rates.num_rates == 0) 2229 cmd->peer_flags &= ~WMI_PEER_HT; 2230 } 2231 #endif 2232 2233 #ifdef CONFIG_MCL 2234 static inline void copy_peer_mac_addr_tlv( 2235 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2236 struct peer_assoc_params *param) 2237 { 2238 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2239 sizeof(param->peer_macaddr)); 2240 } 2241 #else 2242 static inline void copy_peer_mac_addr_tlv( 2243 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2244 struct peer_assoc_params *param) 2245 { 2246 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2247 } 2248 #endif 2249 2250 /** 2251 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2252 * @param wmi_handle : handle to WMI. 2253 * @param param : pointer to peer assoc parameter 2254 * 2255 * Return: 0 on success and -ve on failure. 2256 */ 2257 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2258 struct peer_assoc_params *param) 2259 { 2260 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2261 wmi_vht_rate_set *mcs; 2262 wmi_he_rate_set *he_mcs; 2263 wmi_buf_t buf; 2264 int32_t len; 2265 uint8_t *buf_ptr; 2266 QDF_STATUS ret; 2267 uint32_t peer_legacy_rates_align; 2268 uint32_t peer_ht_rates_align; 2269 int32_t i; 2270 2271 2272 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2273 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2274 2275 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2276 (peer_legacy_rates_align * sizeof(uint8_t)) + 2277 WMI_TLV_HDR_SIZE + 2278 (peer_ht_rates_align * sizeof(uint8_t)) + 2279 sizeof(wmi_vht_rate_set) + 2280 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2281 + WMI_TLV_HDR_SIZE); 2282 2283 buf = wmi_buf_alloc(wmi_handle, len); 2284 if (!buf) { 2285 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2286 return QDF_STATUS_E_NOMEM; 2287 } 2288 2289 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2290 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2291 WMITLV_SET_HDR(&cmd->tlv_header, 2292 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2293 WMITLV_GET_STRUCT_TLVLEN 2294 (wmi_peer_assoc_complete_cmd_fixed_param)); 2295 2296 cmd->vdev_id = param->vdev_id; 2297 2298 cmd->peer_new_assoc = param->peer_new_assoc; 2299 cmd->peer_associd = param->peer_associd; 2300 2301 copy_peer_flags_tlv(cmd, param); 2302 copy_peer_mac_addr_tlv(cmd, param); 2303 2304 cmd->peer_rate_caps = param->peer_rate_caps; 2305 cmd->peer_caps = param->peer_caps; 2306 cmd->peer_listen_intval = param->peer_listen_intval; 2307 cmd->peer_ht_caps = param->peer_ht_caps; 2308 cmd->peer_max_mpdu = param->peer_max_mpdu; 2309 cmd->peer_mpdu_density = param->peer_mpdu_density; 2310 cmd->peer_vht_caps = param->peer_vht_caps; 2311 cmd->peer_phymode = param->peer_phymode; 2312 2313 /* Update 11ax capabilities */ 2314 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2315 cmd->peer_he_ops = param->peer_he_ops; 2316 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2317 sizeof(param->peer_he_cap_phyinfo)); 2318 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2319 sizeof(param->peer_ppet)); 2320 2321 /* Update peer legacy rate information */ 2322 buf_ptr += sizeof(*cmd); 2323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2324 peer_legacy_rates_align); 2325 buf_ptr += WMI_TLV_HDR_SIZE; 2326 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2327 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2328 param->peer_legacy_rates.num_rates); 2329 2330 /* Update peer HT rate information */ 2331 buf_ptr += peer_legacy_rates_align; 2332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2333 peer_ht_rates_align); 2334 buf_ptr += WMI_TLV_HDR_SIZE; 2335 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2336 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2337 param->peer_ht_rates.num_rates); 2338 2339 /* VHT Rates */ 2340 buf_ptr += peer_ht_rates_align; 2341 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2342 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2343 2344 cmd->peer_nss = param->peer_nss; 2345 2346 /* Update bandwidth-NSS mapping */ 2347 cmd->peer_bw_rxnss_override = 0; 2348 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2349 2350 mcs = (wmi_vht_rate_set *) buf_ptr; 2351 if (param->vht_capable) { 2352 mcs->rx_max_rate = param->rx_max_rate; 2353 mcs->rx_mcs_set = param->rx_mcs_set; 2354 mcs->tx_max_rate = param->tx_max_rate; 2355 mcs->tx_mcs_set = param->tx_mcs_set; 2356 } 2357 2358 /* HE Rates */ 2359 cmd->peer_he_mcs = param->peer_he_mcs_count; 2360 buf_ptr += sizeof(wmi_vht_rate_set); 2361 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2362 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2363 buf_ptr += WMI_TLV_HDR_SIZE; 2364 2365 /* Loop through the HE rate set */ 2366 for (i = 0; i < param->peer_he_mcs_count; i++) { 2367 he_mcs = (wmi_he_rate_set *) buf_ptr; 2368 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2369 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2370 2371 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2372 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2373 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2374 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2375 buf_ptr += sizeof(wmi_he_rate_set); 2376 } 2377 2378 2379 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2380 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2381 "nss %d phymode %d peer_mpdu_density %d " 2382 "cmd->peer_vht_caps %x " 2383 "HE cap_info %x ops %x " 2384 "HE phy %x %x %x " 2385 "peer_bw_rxnss_override %x", __func__, 2386 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2387 cmd->peer_rate_caps, cmd->peer_caps, 2388 cmd->peer_listen_intval, cmd->peer_ht_caps, 2389 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2390 cmd->peer_mpdu_density, 2391 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2392 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2393 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2394 cmd->peer_bw_rxnss_override); 2395 2396 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2397 WMI_PEER_ASSOC_CMDID); 2398 if (QDF_IS_STATUS_ERROR(ret)) { 2399 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2400 __func__, ret); 2401 wmi_buf_free(buf); 2402 } 2403 2404 return ret; 2405 } 2406 2407 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2408 */ 2409 static inline void copy_scan_event_cntrl_flags( 2410 wmi_start_scan_cmd_fixed_param * cmd, 2411 struct scan_req_params *param) 2412 { 2413 2414 /* Scan events subscription */ 2415 if (param->scan_ev_started) 2416 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2417 if (param->scan_ev_completed) 2418 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2419 if (param->scan_ev_bss_chan) 2420 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2421 if (param->scan_ev_foreign_chan) 2422 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2423 if (param->scan_ev_dequeued) 2424 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2425 if (param->scan_ev_preempted) 2426 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2427 if (param->scan_ev_start_failed) 2428 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2429 if (param->scan_ev_restarted) 2430 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2431 if (param->scan_ev_foreign_chn_exit) 2432 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2433 if (param->scan_ev_suspended) 2434 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2435 if (param->scan_ev_resumed) 2436 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2437 2438 /** Set scan control flags */ 2439 cmd->scan_ctrl_flags = 0; 2440 if (param->scan_f_passive) 2441 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2442 if (param->scan_f_strict_passive_pch) 2443 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2444 if (param->scan_f_promisc_mode) 2445 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2446 if (param->scan_f_capture_phy_err) 2447 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2448 if (param->scan_f_half_rate) 2449 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2450 if (param->scan_f_quarter_rate) 2451 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2452 if (param->scan_f_cck_rates) 2453 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2454 if (param->scan_f_ofdm_rates) 2455 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2456 if (param->scan_f_chan_stat_evnt) 2457 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2458 if (param->scan_f_filter_prb_req) 2459 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2460 if (param->scan_f_bcast_probe) 2461 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2462 if (param->scan_f_offchan_mgmt_tx) 2463 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2464 if (param->scan_f_offchan_data_tx) 2465 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2466 if (param->scan_f_force_active_dfs_chn) 2467 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2468 if (param->scan_f_add_tpc_ie_in_probe) 2469 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2470 if (param->scan_f_add_ds_ie_in_probe) 2471 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2472 if (param->scan_f_add_spoofed_mac_in_probe) 2473 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2474 if (param->scan_f_add_rand_seq_in_probe) 2475 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2476 if (param->scan_f_en_ie_whitelist_in_probe) 2477 cmd->scan_ctrl_flags |= 2478 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2479 2480 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2481 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2482 param->adaptive_dwell_time_mode); 2483 } 2484 2485 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2486 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2487 struct scan_req_params *params) 2488 { 2489 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2490 } 2491 2492 /** 2493 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2494 * @mac: random mac addr 2495 * @mask: random mac mask 2496 * @mac_addr: wmi random mac 2497 * @mac_mask: wmi random mac mask 2498 * 2499 * Return None. 2500 */ 2501 static inline 2502 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2503 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2504 { 2505 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2506 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2507 } 2508 2509 /* 2510 * wmi_fill_vendor_oui() - fill vendor OUIs 2511 * @buf_ptr: pointer to wmi tlv buffer 2512 * @num_vendor_oui: number of vendor OUIs to be filled 2513 * @param_voui: pointer to OUI buffer 2514 * 2515 * This function populates the wmi tlv buffer when vendor specific OUIs are 2516 * present. 2517 * 2518 * Return: None 2519 */ 2520 static inline 2521 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2522 uint32_t *pvoui) 2523 { 2524 wmi_vendor_oui *voui = NULL; 2525 uint32_t i; 2526 2527 voui = (wmi_vendor_oui *)buf_ptr; 2528 2529 for (i = 0; i < num_vendor_oui; i++) { 2530 WMITLV_SET_HDR(&voui[i].tlv_header, 2531 WMITLV_TAG_STRUC_wmi_vendor_oui, 2532 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2533 voui[i].oui_type_subtype = pvoui[i]; 2534 } 2535 } 2536 2537 /* 2538 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2539 * @ie_bitmap: output pointer to ie bit map in cmd 2540 * @num_vendor_oui: output pointer to num vendor OUIs 2541 * @ie_whitelist: input parameter 2542 * 2543 * This function populates the IE whitelist attrs of scan, pno and 2544 * scan oui commands for ie_whitelist parameter. 2545 * 2546 * Return: None 2547 */ 2548 static inline 2549 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2550 uint32_t *num_vendor_oui, 2551 struct probe_req_whitelist_attr *ie_whitelist) 2552 { 2553 uint32_t i = 0; 2554 2555 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2556 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2557 2558 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2559 } 2560 2561 /** 2562 * send_scan_start_cmd_tlv() - WMI scan start function 2563 * @param wmi_handle : handle to WMI. 2564 * @param param : pointer to hold scan start cmd parameter 2565 * 2566 * Return: 0 on success and -ve on failure. 2567 */ 2568 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2569 struct scan_req_params *params) 2570 { 2571 int32_t ret = 0; 2572 int32_t i; 2573 wmi_buf_t wmi_buf; 2574 wmi_start_scan_cmd_fixed_param *cmd; 2575 uint8_t *buf_ptr; 2576 uint32_t *tmp_ptr; 2577 wmi_ssid *ssid = NULL; 2578 wmi_mac_addr *bssid; 2579 int len = sizeof(*cmd); 2580 uint8_t extraie_len_with_pad = 0; 2581 uint8_t phymode_roundup = 0; 2582 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2583 2584 /* Length TLV placeholder for array of uint32_t */ 2585 len += WMI_TLV_HDR_SIZE; 2586 /* calculate the length of buffer required */ 2587 if (params->chan_list.num_chan) 2588 len += params->chan_list.num_chan * sizeof(uint32_t); 2589 2590 /* Length TLV placeholder for array of wmi_ssid structures */ 2591 len += WMI_TLV_HDR_SIZE; 2592 if (params->num_ssids) 2593 len += params->num_ssids * sizeof(wmi_ssid); 2594 2595 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2596 len += WMI_TLV_HDR_SIZE; 2597 if (params->num_bssid) 2598 len += sizeof(wmi_mac_addr) * params->num_bssid; 2599 2600 /* Length TLV placeholder for array of bytes */ 2601 len += WMI_TLV_HDR_SIZE; 2602 if (params->extraie.len) 2603 extraie_len_with_pad = 2604 roundup(params->extraie.len, sizeof(uint32_t)); 2605 len += extraie_len_with_pad; 2606 2607 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2608 if (ie_whitelist->num_vendor_oui) 2609 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2610 2611 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2612 if (params->scan_f_wide_band) 2613 phymode_roundup = 2614 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2615 sizeof(uint32_t)); 2616 len += phymode_roundup; 2617 2618 /* Allocate the memory */ 2619 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2620 if (!wmi_buf) { 2621 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2622 __func__); 2623 return QDF_STATUS_E_FAILURE; 2624 } 2625 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2626 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2627 WMITLV_SET_HDR(&cmd->tlv_header, 2628 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2629 WMITLV_GET_STRUCT_TLVLEN 2630 (wmi_start_scan_cmd_fixed_param)); 2631 2632 cmd->scan_id = params->scan_id; 2633 cmd->scan_req_id = params->scan_req_id; 2634 cmd->vdev_id = params->vdev_id; 2635 cmd->scan_priority = params->scan_priority; 2636 2637 copy_scan_event_cntrl_flags(cmd, params); 2638 2639 cmd->dwell_time_active = params->dwell_time_active; 2640 cmd->dwell_time_passive = params->dwell_time_passive; 2641 cmd->min_rest_time = params->min_rest_time; 2642 cmd->max_rest_time = params->max_rest_time; 2643 cmd->repeat_probe_time = params->repeat_probe_time; 2644 cmd->probe_spacing_time = params->probe_spacing_time; 2645 cmd->idle_time = params->idle_time; 2646 cmd->max_scan_time = params->max_scan_time; 2647 cmd->probe_delay = params->probe_delay; 2648 cmd->burst_duration = params->burst_duration; 2649 cmd->num_chan = params->chan_list.num_chan; 2650 cmd->num_bssid = params->num_bssid; 2651 cmd->num_ssids = params->num_ssids; 2652 cmd->ie_len = params->extraie.len; 2653 cmd->n_probes = params->n_probes; 2654 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2655 2656 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2657 2658 if (params->scan_random.randomize) 2659 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2660 params->scan_random.mac_mask, 2661 &cmd->mac_addr, 2662 &cmd->mac_mask); 2663 2664 if (ie_whitelist->white_list) 2665 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2666 &cmd->num_vendor_oui, 2667 ie_whitelist); 2668 2669 buf_ptr += sizeof(*cmd); 2670 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2671 for (i = 0; i < params->chan_list.num_chan; ++i) 2672 tmp_ptr[i] = params->chan_list.chan[i].freq; 2673 2674 WMITLV_SET_HDR(buf_ptr, 2675 WMITLV_TAG_ARRAY_UINT32, 2676 (params->chan_list.num_chan * sizeof(uint32_t))); 2677 buf_ptr += WMI_TLV_HDR_SIZE + 2678 (params->chan_list.num_chan * sizeof(uint32_t)); 2679 2680 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2681 WMI_LOGE("Invalid value for numSsid"); 2682 goto error; 2683 } 2684 2685 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2686 (params->num_ssids * sizeof(wmi_ssid))); 2687 2688 if (params->num_ssids) { 2689 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2690 for (i = 0; i < params->num_ssids; ++i) { 2691 ssid->ssid_len = params->ssid[i].length; 2692 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2693 params->ssid[i].length); 2694 ssid++; 2695 } 2696 } 2697 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2698 2699 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2700 (params->num_bssid * sizeof(wmi_mac_addr))); 2701 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2702 2703 if (params->num_bssid) { 2704 for (i = 0; i < params->num_bssid; ++i) { 2705 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2706 ¶ms->bssid_list[i].bytes[0], bssid); 2707 bssid++; 2708 } 2709 } 2710 2711 buf_ptr += WMI_TLV_HDR_SIZE + 2712 (params->num_bssid * sizeof(wmi_mac_addr)); 2713 2714 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2715 if (params->extraie.len) 2716 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2717 params); 2718 2719 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2720 2721 /* probe req ie whitelisting */ 2722 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2723 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2724 2725 buf_ptr += WMI_TLV_HDR_SIZE; 2726 2727 if (cmd->num_vendor_oui) { 2728 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2729 ie_whitelist->voui); 2730 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2731 } 2732 2733 /* Add phy mode TLV if it's a wide band scan */ 2734 if (params->scan_f_wide_band) { 2735 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2736 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2737 for (i = 0; i < params->chan_list.num_chan; ++i) 2738 buf_ptr[i] = 2739 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2740 buf_ptr += phymode_roundup; 2741 } else { 2742 /* Add ZERO legth phy mode TLV */ 2743 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2744 } 2745 2746 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2747 len, WMI_START_SCAN_CMDID); 2748 if (ret) { 2749 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2750 wmi_buf_free(wmi_buf); 2751 } 2752 return ret; 2753 error: 2754 wmi_buf_free(wmi_buf); 2755 return QDF_STATUS_E_FAILURE; 2756 } 2757 2758 /** 2759 * send_scan_stop_cmd_tlv() - WMI scan start function 2760 * @param wmi_handle : handle to WMI. 2761 * @param param : pointer to hold scan cancel cmd parameter 2762 * 2763 * Return: 0 on success and -ve on failure. 2764 */ 2765 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2766 struct scan_cancel_param *param) 2767 { 2768 wmi_stop_scan_cmd_fixed_param *cmd; 2769 int ret; 2770 int len = sizeof(*cmd); 2771 wmi_buf_t wmi_buf; 2772 2773 /* Allocate the memory */ 2774 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2775 if (!wmi_buf) { 2776 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2777 __func__); 2778 ret = QDF_STATUS_E_NOMEM; 2779 goto error; 2780 } 2781 2782 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2783 WMITLV_SET_HDR(&cmd->tlv_header, 2784 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2785 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2786 cmd->vdev_id = param->vdev_id; 2787 cmd->requestor = param->requester; 2788 cmd->scan_id = param->scan_id; 2789 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2790 param->pdev_id); 2791 /* stop the scan with the corresponding scan_id */ 2792 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2793 /* Cancelling all scans */ 2794 cmd->req_type = WMI_SCAN_STOP_ALL; 2795 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2796 /* Cancelling VAP scans */ 2797 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2798 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2799 /* Cancelling specific scan */ 2800 cmd->req_type = WMI_SCAN_STOP_ONE; 2801 } else { 2802 WMI_LOGE("%s: Invalid Command : ", __func__); 2803 wmi_buf_free(wmi_buf); 2804 return QDF_STATUS_E_INVAL; 2805 } 2806 2807 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2808 len, WMI_STOP_SCAN_CMDID); 2809 if (ret) { 2810 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2811 wmi_buf_free(wmi_buf); 2812 } 2813 2814 error: 2815 return ret; 2816 } 2817 2818 #ifdef CONFIG_MCL 2819 /** 2820 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2821 * @param wmi_handle : handle to WMI. 2822 * @param param : pointer to hold scan channel list parameter 2823 * 2824 * Return: 0 on success and -ve on failure. 2825 */ 2826 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2827 struct scan_chan_list_params *chan_list) 2828 { 2829 wmi_buf_t buf; 2830 QDF_STATUS qdf_status; 2831 wmi_scan_chan_list_cmd_fixed_param *cmd; 2832 int i; 2833 uint8_t *buf_ptr; 2834 wmi_channel_param *chan_info, *tchan_info; 2835 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2836 2837 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2838 buf = wmi_buf_alloc(wmi_handle, len); 2839 if (!buf) { 2840 WMI_LOGE("Failed to allocate memory"); 2841 qdf_status = QDF_STATUS_E_NOMEM; 2842 goto end; 2843 } 2844 2845 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2846 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2847 WMITLV_SET_HDR(&cmd->tlv_header, 2848 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2849 WMITLV_GET_STRUCT_TLVLEN 2850 (wmi_scan_chan_list_cmd_fixed_param)); 2851 2852 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2853 2854 cmd->num_scan_chans = chan_list->num_scan_chans; 2855 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2856 WMITLV_TAG_ARRAY_STRUC, 2857 sizeof(wmi_channel) * chan_list->num_scan_chans); 2858 chan_info = (wmi_channel_param *) 2859 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2860 tchan_info = chan_list->chan_info; 2861 2862 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2863 WMITLV_SET_HDR(&chan_info->tlv_header, 2864 WMITLV_TAG_STRUC_wmi_channel, 2865 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2866 chan_info->mhz = tchan_info->mhz; 2867 chan_info->band_center_freq1 = 2868 tchan_info->band_center_freq1; 2869 chan_info->band_center_freq2 = 2870 tchan_info->band_center_freq2; 2871 chan_info->info = tchan_info->info; 2872 chan_info->reg_info_1 = tchan_info->reg_info_1; 2873 chan_info->reg_info_2 = tchan_info->reg_info_2; 2874 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2875 2876 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2877 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2878 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2879 tchan_info++; 2880 chan_info++; 2881 } 2882 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2883 chan_list->pdev_id); 2884 2885 qdf_status = wmi_unified_cmd_send(wmi_handle, 2886 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2887 2888 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2889 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2890 wmi_buf_free(buf); 2891 } 2892 2893 end: 2894 return qdf_status; 2895 } 2896 #else 2897 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2898 struct scan_chan_list_params *chan_list) 2899 { 2900 wmi_buf_t buf; 2901 QDF_STATUS qdf_status; 2902 wmi_scan_chan_list_cmd_fixed_param *cmd; 2903 int i; 2904 uint8_t *buf_ptr; 2905 wmi_channel *chan_info; 2906 struct channel_param *tchan_info; 2907 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2908 2909 len += sizeof(wmi_channel) * chan_list->nallchans; 2910 buf = wmi_buf_alloc(wmi_handle, len); 2911 if (!buf) { 2912 WMI_LOGE("Failed to allocate memory"); 2913 qdf_status = QDF_STATUS_E_NOMEM; 2914 goto end; 2915 } 2916 2917 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2918 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2919 WMITLV_SET_HDR(&cmd->tlv_header, 2920 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2921 WMITLV_GET_STRUCT_TLVLEN 2922 (wmi_scan_chan_list_cmd_fixed_param)); 2923 2924 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2925 2926 if (chan_list->append) 2927 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2928 2929 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2930 chan_list->pdev_id); 2931 cmd->num_scan_chans = chan_list->nallchans; 2932 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2933 WMITLV_TAG_ARRAY_STRUC, 2934 sizeof(wmi_channel) * chan_list->nallchans); 2935 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2936 tchan_info = &(chan_list->ch_param[0]); 2937 2938 for (i = 0; i < chan_list->nallchans; ++i) { 2939 WMITLV_SET_HDR(&chan_info->tlv_header, 2940 WMITLV_TAG_STRUC_wmi_channel, 2941 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2942 chan_info->mhz = tchan_info->mhz; 2943 chan_info->band_center_freq1 = 2944 tchan_info->cfreq1; 2945 chan_info->band_center_freq2 = 2946 tchan_info->cfreq2; 2947 2948 if (tchan_info->is_chan_passive) 2949 WMI_SET_CHANNEL_FLAG(chan_info, 2950 WMI_CHAN_FLAG_PASSIVE); 2951 2952 if (tchan_info->allow_vht) 2953 WMI_SET_CHANNEL_FLAG(chan_info, 2954 WMI_CHAN_FLAG_ALLOW_VHT); 2955 else if (tchan_info->allow_ht) 2956 WMI_SET_CHANNEL_FLAG(chan_info, 2957 WMI_CHAN_FLAG_ALLOW_HT); 2958 WMI_SET_CHANNEL_MODE(chan_info, 2959 tchan_info->phy_mode); 2960 2961 if (tchan_info->half_rate) 2962 WMI_SET_CHANNEL_FLAG(chan_info, 2963 WMI_CHAN_FLAG_HALF_RATE); 2964 2965 if (tchan_info->quarter_rate) 2966 WMI_SET_CHANNEL_FLAG(chan_info, 2967 WMI_CHAN_FLAG_QUARTER_RATE); 2968 2969 /* also fill in power information */ 2970 WMI_SET_CHANNEL_MIN_POWER(chan_info, 2971 tchan_info->minpower); 2972 WMI_SET_CHANNEL_MAX_POWER(chan_info, 2973 tchan_info->maxpower); 2974 WMI_SET_CHANNEL_REG_POWER(chan_info, 2975 tchan_info->maxregpower); 2976 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 2977 tchan_info->antennamax); 2978 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 2979 tchan_info->reg_class_id); 2980 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 2981 tchan_info->maxregpower); 2982 2983 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2984 2985 tchan_info++; 2986 chan_info++; 2987 } 2988 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2989 chan_list->pdev_id); 2990 2991 qdf_status = wmi_unified_cmd_send( 2992 wmi_handle, 2993 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2994 2995 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2996 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2997 wmi_buf_free(buf); 2998 } 2999 3000 end: 3001 return qdf_status; 3002 } 3003 #endif 3004 3005 /** 3006 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3007 * 3008 * @bufp: Pointer to buffer 3009 * @param: Pointer to tx param 3010 * 3011 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3012 */ 3013 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3014 struct tx_send_params param) 3015 { 3016 wmi_tx_send_params *tx_param; 3017 QDF_STATUS status = QDF_STATUS_SUCCESS; 3018 3019 if (!bufp) { 3020 status = QDF_STATUS_E_FAILURE; 3021 return status; 3022 } 3023 tx_param = (wmi_tx_send_params *)bufp; 3024 WMITLV_SET_HDR(&tx_param->tlv_header, 3025 WMITLV_TAG_STRUC_wmi_tx_send_params, 3026 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3027 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3028 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3029 param.mcs_mask); 3030 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3031 param.nss_mask); 3032 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3033 param.retry_limit); 3034 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3035 param.chain_mask); 3036 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3037 param.bw_mask); 3038 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3039 param.preamble_type); 3040 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3041 param.frame_type); 3042 3043 return status; 3044 } 3045 3046 /** 3047 * send_mgmt_cmd_tlv() - WMI scan start function 3048 * @wmi_handle : handle to WMI. 3049 * @param : pointer to hold mgmt cmd parameter 3050 * 3051 * Return: 0 on success and -ve on failure. 3052 */ 3053 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3054 struct wmi_mgmt_params *param) 3055 { 3056 wmi_buf_t buf; 3057 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3058 int32_t cmd_len; 3059 uint64_t dma_addr; 3060 void *qdf_ctx = param->qdf_ctx; 3061 uint8_t *bufp; 3062 QDF_STATUS status = QDF_STATUS_SUCCESS; 3063 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3064 mgmt_tx_dl_frm_len; 3065 3066 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3067 WMI_TLV_HDR_SIZE + 3068 roundup(bufp_len, sizeof(uint32_t)); 3069 3070 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3071 if (!buf) { 3072 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3073 return QDF_STATUS_E_NOMEM; 3074 } 3075 3076 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3077 bufp = (uint8_t *) cmd; 3078 WMITLV_SET_HDR(&cmd->tlv_header, 3079 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3080 WMITLV_GET_STRUCT_TLVLEN 3081 (wmi_mgmt_tx_send_cmd_fixed_param)); 3082 3083 cmd->vdev_id = param->vdev_id; 3084 3085 cmd->desc_id = param->desc_id; 3086 cmd->chanfreq = param->chanfreq; 3087 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3088 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3089 sizeof(uint32_t))); 3090 bufp += WMI_TLV_HDR_SIZE; 3091 qdf_mem_copy(bufp, param->pdata, bufp_len); 3092 3093 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3094 QDF_DMA_TO_DEVICE); 3095 if (status != QDF_STATUS_SUCCESS) { 3096 WMI_LOGE("%s: wmi buf map failed", __func__); 3097 goto free_buf; 3098 } 3099 3100 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3101 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3102 #if defined(HTT_PADDR64) 3103 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3104 #endif 3105 cmd->frame_len = param->frm_len; 3106 cmd->buf_len = bufp_len; 3107 cmd->tx_params_valid = param->tx_params_valid; 3108 3109 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3110 bufp, cmd->vdev_id, cmd->chanfreq); 3111 3112 bufp += roundup(bufp_len, sizeof(uint32_t)); 3113 if (param->tx_params_valid) { 3114 status = populate_tx_send_params(bufp, param->tx_param); 3115 if (status != QDF_STATUS_SUCCESS) { 3116 WMI_LOGE("%s: Populate TX send params failed", 3117 __func__); 3118 goto unmap_tx_frame; 3119 } 3120 cmd_len += sizeof(wmi_tx_send_params); 3121 } 3122 3123 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3124 WMI_MGMT_TX_SEND_CMDID)) { 3125 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3126 goto unmap_tx_frame; 3127 } 3128 return QDF_STATUS_SUCCESS; 3129 3130 unmap_tx_frame: 3131 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3132 QDF_DMA_TO_DEVICE); 3133 free_buf: 3134 wmi_buf_free(buf); 3135 return QDF_STATUS_E_FAILURE; 3136 } 3137 3138 /** 3139 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3140 * @wmi_handle : handle to WMI. 3141 * @param : pointer to offchan data tx cmd parameter 3142 * 3143 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3144 */ 3145 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3146 struct wmi_offchan_data_tx_params *param) 3147 { 3148 wmi_buf_t buf; 3149 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3150 int32_t cmd_len; 3151 uint64_t dma_addr; 3152 void *qdf_ctx = param->qdf_ctx; 3153 uint8_t *bufp; 3154 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3155 param->frm_len : mgmt_tx_dl_frm_len; 3156 QDF_STATUS status = QDF_STATUS_SUCCESS; 3157 3158 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3159 WMI_TLV_HDR_SIZE + 3160 roundup(bufp_len, sizeof(uint32_t)); 3161 3162 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3163 if (!buf) { 3164 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3165 return QDF_STATUS_E_NOMEM; 3166 } 3167 3168 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3169 bufp = (uint8_t *) cmd; 3170 WMITLV_SET_HDR(&cmd->tlv_header, 3171 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3172 WMITLV_GET_STRUCT_TLVLEN 3173 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3174 3175 cmd->vdev_id = param->vdev_id; 3176 3177 cmd->desc_id = param->desc_id; 3178 cmd->chanfreq = param->chanfreq; 3179 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3180 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3181 sizeof(uint32_t))); 3182 bufp += WMI_TLV_HDR_SIZE; 3183 qdf_mem_copy(bufp, param->pdata, bufp_len); 3184 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3185 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3186 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3187 #if defined(HTT_PADDR64) 3188 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3189 #endif 3190 cmd->frame_len = param->frm_len; 3191 cmd->buf_len = bufp_len; 3192 cmd->tx_params_valid = param->tx_params_valid; 3193 3194 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3195 bufp, cmd->vdev_id, cmd->chanfreq); 3196 3197 bufp += roundup(bufp_len, sizeof(uint32_t)); 3198 if (param->tx_params_valid) { 3199 status = populate_tx_send_params(bufp, param->tx_param); 3200 if (status != QDF_STATUS_SUCCESS) { 3201 WMI_LOGE("%s: Populate TX send params failed", 3202 __func__); 3203 goto err1; 3204 } 3205 cmd_len += sizeof(wmi_tx_send_params); 3206 } 3207 3208 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3209 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3210 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3211 goto err1; 3212 } 3213 3214 return QDF_STATUS_SUCCESS; 3215 3216 err1: 3217 wmi_buf_free(buf); 3218 return QDF_STATUS_E_FAILURE; 3219 } 3220 3221 /** 3222 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3223 * @wmi_handle: wmi handle 3224 * @param_value: parameter value 3225 * 3226 * Return: QDF_STATUS_SUCCESS for success or error code 3227 */ 3228 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3229 uint32_t param_value) 3230 { 3231 QDF_STATUS ret; 3232 wmi_modem_power_state_cmd_param *cmd; 3233 wmi_buf_t buf; 3234 uint16_t len = sizeof(*cmd); 3235 3236 buf = wmi_buf_alloc(wmi_handle, len); 3237 if (!buf) { 3238 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3239 return QDF_STATUS_E_NOMEM; 3240 } 3241 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3242 WMITLV_SET_HDR(&cmd->tlv_header, 3243 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3244 WMITLV_GET_STRUCT_TLVLEN 3245 (wmi_modem_power_state_cmd_param)); 3246 cmd->modem_power_state = param_value; 3247 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3248 param_value); 3249 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3250 WMI_MODEM_POWER_STATE_CMDID); 3251 if (QDF_IS_STATUS_ERROR(ret)) { 3252 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3253 wmi_buf_free(buf); 3254 } 3255 3256 return ret; 3257 } 3258 3259 /** 3260 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3261 * @wmi_handle: wmi handle 3262 * @vdev_id: vdev id 3263 * @val: value 3264 * 3265 * Return: QDF_STATUS_SUCCESS for success or error code. 3266 */ 3267 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3268 uint32_t vdev_id, uint8_t val) 3269 { 3270 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3271 wmi_buf_t buf; 3272 int32_t len = sizeof(*cmd); 3273 3274 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3275 3276 buf = wmi_buf_alloc(wmi_handle, len); 3277 if (!buf) { 3278 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3279 return QDF_STATUS_E_NOMEM; 3280 } 3281 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3282 WMITLV_SET_HDR(&cmd->tlv_header, 3283 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3284 WMITLV_GET_STRUCT_TLVLEN 3285 (wmi_sta_powersave_mode_cmd_fixed_param)); 3286 cmd->vdev_id = vdev_id; 3287 if (val) 3288 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3289 else 3290 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3291 3292 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3293 WMI_STA_POWERSAVE_MODE_CMDID)) { 3294 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3295 vdev_id, val); 3296 wmi_buf_free(buf); 3297 return QDF_STATUS_E_FAILURE; 3298 } 3299 return 0; 3300 } 3301 3302 /** 3303 * send_set_mimops_cmd_tlv() - set MIMO powersave 3304 * @wmi_handle: wmi handle 3305 * @vdev_id: vdev id 3306 * @value: value 3307 * 3308 * Return: QDF_STATUS_SUCCESS for success or error code. 3309 */ 3310 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3311 uint8_t vdev_id, int value) 3312 { 3313 QDF_STATUS ret; 3314 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3315 wmi_buf_t buf; 3316 uint16_t len = sizeof(*cmd); 3317 3318 buf = wmi_buf_alloc(wmi_handle, len); 3319 if (!buf) { 3320 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3321 return QDF_STATUS_E_NOMEM; 3322 } 3323 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3324 WMITLV_SET_HDR(&cmd->tlv_header, 3325 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3326 WMITLV_GET_STRUCT_TLVLEN 3327 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3328 3329 cmd->vdev_id = vdev_id; 3330 3331 /* WMI_SMPS_FORCED_MODE values do not directly map 3332 * to SM power save values defined in the specification. 3333 * Make sure to send the right mapping. 3334 */ 3335 switch (value) { 3336 case 0: 3337 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3338 break; 3339 case 1: 3340 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3341 break; 3342 case 2: 3343 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3344 break; 3345 case 3: 3346 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3347 break; 3348 default: 3349 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3350 wmi_buf_free(buf); 3351 return QDF_STATUS_E_FAILURE; 3352 } 3353 3354 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3355 3356 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3357 WMI_STA_SMPS_FORCE_MODE_CMDID); 3358 if (QDF_IS_STATUS_ERROR(ret)) { 3359 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3360 wmi_buf_free(buf); 3361 } 3362 3363 return ret; 3364 } 3365 3366 /** 3367 * send_set_smps_params_cmd_tlv() - set smps params 3368 * @wmi_handle: wmi handle 3369 * @vdev_id: vdev id 3370 * @value: value 3371 * 3372 * Return: QDF_STATUS_SUCCESS for success or error code. 3373 */ 3374 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3375 int value) 3376 { 3377 QDF_STATUS ret; 3378 wmi_sta_smps_param_cmd_fixed_param *cmd; 3379 wmi_buf_t buf; 3380 uint16_t len = sizeof(*cmd); 3381 3382 buf = wmi_buf_alloc(wmi_handle, len); 3383 if (!buf) { 3384 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3385 return QDF_STATUS_E_NOMEM; 3386 } 3387 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3388 WMITLV_SET_HDR(&cmd->tlv_header, 3389 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3390 WMITLV_GET_STRUCT_TLVLEN 3391 (wmi_sta_smps_param_cmd_fixed_param)); 3392 3393 cmd->vdev_id = vdev_id; 3394 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3395 cmd->param = 3396 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3397 3398 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3399 cmd->param); 3400 3401 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3402 WMI_STA_SMPS_PARAM_CMDID); 3403 if (QDF_IS_STATUS_ERROR(ret)) { 3404 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3405 wmi_buf_free(buf); 3406 } 3407 3408 return ret; 3409 } 3410 3411 /** 3412 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3413 * @wmi_handle: wmi handle 3414 * @noa: p2p power save parameters 3415 * 3416 * Return: CDF status 3417 */ 3418 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3419 struct p2p_ps_params *noa) 3420 { 3421 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3422 wmi_p2p_noa_descriptor *noa_discriptor; 3423 wmi_buf_t buf; 3424 uint8_t *buf_ptr; 3425 uint16_t len; 3426 QDF_STATUS status; 3427 uint32_t duration; 3428 3429 WMI_LOGD("%s: Enter", __func__); 3430 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3431 buf = wmi_buf_alloc(wmi_handle, len); 3432 if (!buf) { 3433 WMI_LOGE("Failed to allocate memory"); 3434 status = QDF_STATUS_E_FAILURE; 3435 goto end; 3436 } 3437 3438 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3439 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3440 WMITLV_SET_HDR(&cmd->tlv_header, 3441 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3442 WMITLV_GET_STRUCT_TLVLEN 3443 (wmi_p2p_set_noa_cmd_fixed_param)); 3444 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3445 cmd->vdev_id = noa->session_id; 3446 cmd->enable = (duration) ? true : false; 3447 cmd->num_noa = 1; 3448 3449 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3450 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3451 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3452 sizeof 3453 (wmi_p2p_set_noa_cmd_fixed_param) 3454 + WMI_TLV_HDR_SIZE); 3455 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3456 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3457 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3458 noa_discriptor->type_count = noa->count; 3459 noa_discriptor->duration = duration; 3460 noa_discriptor->interval = noa->interval; 3461 noa_discriptor->start_time = 0; 3462 3463 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3464 cmd->vdev_id, noa->count, noa_discriptor->duration, 3465 noa->interval); 3466 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3467 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3468 if (QDF_IS_STATUS_ERROR(status)) { 3469 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3470 wmi_buf_free(buf); 3471 } 3472 3473 end: 3474 WMI_LOGD("%s: Exit", __func__); 3475 return status; 3476 } 3477 3478 3479 /** 3480 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3481 * @wmi_handle: wmi handle 3482 * @noa: p2p opp power save parameters 3483 * 3484 * Return: CDF status 3485 */ 3486 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3487 struct p2p_ps_params *oppps) 3488 { 3489 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3490 wmi_buf_t buf; 3491 QDF_STATUS status; 3492 3493 WMI_LOGD("%s: Enter", __func__); 3494 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3495 if (!buf) { 3496 WMI_LOGE("Failed to allocate memory"); 3497 status = QDF_STATUS_E_FAILURE; 3498 goto end; 3499 } 3500 3501 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3502 WMITLV_SET_HDR(&cmd->tlv_header, 3503 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3504 WMITLV_GET_STRUCT_TLVLEN 3505 (wmi_p2p_set_oppps_cmd_fixed_param)); 3506 cmd->vdev_id = oppps->session_id; 3507 if (oppps->ctwindow) 3508 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3509 3510 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3511 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3512 cmd->vdev_id, oppps->ctwindow); 3513 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3514 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3515 if (QDF_IS_STATUS_ERROR(status)) { 3516 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3517 wmi_buf_free(buf); 3518 } 3519 3520 end: 3521 WMI_LOGD("%s: Exit", __func__); 3522 return status; 3523 } 3524 3525 #ifdef CONVERGED_P2P_ENABLE 3526 /** 3527 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3528 * @wmi_handle: wmi handle 3529 * @param: p2p listen offload start parameters 3530 * 3531 * Return: QDF status 3532 */ 3533 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3534 struct p2p_lo_start *param) 3535 { 3536 wmi_buf_t buf; 3537 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3538 int32_t len = sizeof(*cmd); 3539 uint8_t *buf_ptr; 3540 QDF_STATUS status; 3541 int device_types_len_aligned; 3542 int probe_resp_len_aligned; 3543 3544 if (!param) { 3545 WMI_LOGE("lo start param is null"); 3546 return QDF_STATUS_E_INVAL; 3547 } 3548 3549 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3550 3551 device_types_len_aligned = 3552 qdf_roundup(param->dev_types_len, 3553 sizeof(uint32_t)); 3554 probe_resp_len_aligned = 3555 qdf_roundup(param->probe_resp_len, 3556 sizeof(uint32_t)); 3557 3558 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3559 probe_resp_len_aligned; 3560 3561 buf = wmi_buf_alloc(wmi_handle, len); 3562 if (!buf) { 3563 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3564 __func__); 3565 return QDF_STATUS_E_NOMEM; 3566 } 3567 3568 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3569 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3570 3571 WMITLV_SET_HDR(&cmd->tlv_header, 3572 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3573 WMITLV_GET_STRUCT_TLVLEN( 3574 wmi_p2p_lo_start_cmd_fixed_param)); 3575 3576 cmd->vdev_id = param->vdev_id; 3577 cmd->ctl_flags = param->ctl_flags; 3578 cmd->channel = param->freq; 3579 cmd->period = param->period; 3580 cmd->interval = param->interval; 3581 cmd->count = param->count; 3582 cmd->device_types_len = param->dev_types_len; 3583 cmd->prob_resp_len = param->probe_resp_len; 3584 3585 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3586 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3587 device_types_len_aligned); 3588 buf_ptr += WMI_TLV_HDR_SIZE; 3589 qdf_mem_copy(buf_ptr, param->device_types, 3590 param->dev_types_len); 3591 3592 buf_ptr += device_types_len_aligned; 3593 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3594 probe_resp_len_aligned); 3595 buf_ptr += WMI_TLV_HDR_SIZE; 3596 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3597 param->probe_resp_len); 3598 3599 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3600 cmd->channel, cmd->period, cmd->interval, cmd->count); 3601 3602 status = wmi_unified_cmd_send(wmi_handle, 3603 buf, len, 3604 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3605 if (status != QDF_STATUS_SUCCESS) { 3606 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3607 __func__, status); 3608 wmi_buf_free(buf); 3609 return status; 3610 } 3611 3612 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3613 3614 return QDF_STATUS_SUCCESS; 3615 } 3616 3617 /** 3618 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3619 * @wmi_handle: wmi handle 3620 * @param: p2p listen offload stop parameters 3621 * 3622 * Return: QDF status 3623 */ 3624 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3625 uint8_t vdev_id) 3626 { 3627 wmi_buf_t buf; 3628 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3629 int32_t len; 3630 QDF_STATUS status; 3631 3632 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3633 3634 len = sizeof(*cmd); 3635 buf = wmi_buf_alloc(wmi_handle, len); 3636 if (!buf) { 3637 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3638 __func__); 3639 return QDF_STATUS_E_NOMEM; 3640 } 3641 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3642 3643 WMITLV_SET_HDR(&cmd->tlv_header, 3644 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3645 WMITLV_GET_STRUCT_TLVLEN( 3646 wmi_p2p_lo_stop_cmd_fixed_param)); 3647 3648 cmd->vdev_id = vdev_id; 3649 3650 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3651 3652 status = wmi_unified_cmd_send(wmi_handle, 3653 buf, len, 3654 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3655 if (status != QDF_STATUS_SUCCESS) { 3656 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3657 __func__, status); 3658 wmi_buf_free(buf); 3659 return status; 3660 } 3661 3662 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3663 3664 return QDF_STATUS_SUCCESS; 3665 } 3666 #endif /* End of CONVERGED_P2P_ENABLE */ 3667 3668 /** 3669 * send_get_temperature_cmd_tlv() - get pdev temperature req 3670 * @wmi_handle: wmi handle 3671 * 3672 * Return: QDF_STATUS_SUCCESS for success or error code. 3673 */ 3674 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3675 { 3676 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3677 wmi_buf_t wmi_buf; 3678 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3679 uint8_t *buf_ptr; 3680 3681 if (!wmi_handle) { 3682 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3683 return QDF_STATUS_E_INVAL; 3684 } 3685 3686 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3687 if (!wmi_buf) { 3688 WMI_LOGE(FL("wmi_buf_alloc failed")); 3689 return QDF_STATUS_E_NOMEM; 3690 } 3691 3692 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3693 3694 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3695 WMITLV_SET_HDR(&cmd->tlv_header, 3696 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3697 WMITLV_GET_STRUCT_TLVLEN 3698 (wmi_pdev_get_temperature_cmd_fixed_param)); 3699 3700 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3701 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3702 WMI_LOGE(FL("failed to send get temperature command")); 3703 wmi_buf_free(wmi_buf); 3704 return QDF_STATUS_E_FAILURE; 3705 } 3706 3707 return QDF_STATUS_SUCCESS; 3708 } 3709 3710 /** 3711 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3712 * @wmi_handle: wmi handle 3713 * @vdevid: vdev id 3714 * @peer_addr: peer mac address 3715 * @auto_triggerparam: auto trigger parameters 3716 * @num_ac: number of access category 3717 * 3718 * This function sets the trigger 3719 * uapsd params such as service interval, delay interval 3720 * and suspend interval which will be used by the firmware 3721 * to send trigger frames periodically when there is no 3722 * traffic on the transmit side. 3723 * 3724 * Return: QDF_STATUS_SUCCESS for success or error code. 3725 */ 3726 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3727 struct sta_uapsd_trig_params *param) 3728 { 3729 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3730 QDF_STATUS ret; 3731 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3732 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3733 uint32_t i; 3734 wmi_buf_t buf; 3735 uint8_t *buf_ptr; 3736 struct sta_uapsd_params *uapsd_param; 3737 wmi_sta_uapsd_auto_trig_param *trig_param; 3738 3739 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3740 if (!buf) { 3741 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3742 return QDF_STATUS_E_NOMEM; 3743 } 3744 3745 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3746 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3747 WMITLV_SET_HDR(&cmd->tlv_header, 3748 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3749 WMITLV_GET_STRUCT_TLVLEN 3750 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3751 cmd->vdev_id = param->vdevid; 3752 cmd->num_ac = param->num_ac; 3753 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3754 3755 /* TLV indicating array of structures to follow */ 3756 buf_ptr += sizeof(*cmd); 3757 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3758 3759 buf_ptr += WMI_TLV_HDR_SIZE; 3760 3761 /* 3762 * Update tag and length for uapsd auto trigger params (this will take 3763 * care of updating tag and length if it is not pre-filled by caller). 3764 */ 3765 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3766 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3767 for (i = 0; i < param->num_ac; i++) { 3768 WMITLV_SET_HDR((buf_ptr + 3769 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3770 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3771 WMITLV_GET_STRUCT_TLVLEN 3772 (wmi_sta_uapsd_auto_trig_param)); 3773 trig_param->wmm_ac = uapsd_param->wmm_ac; 3774 trig_param->user_priority = uapsd_param->user_priority; 3775 trig_param->service_interval = uapsd_param->service_interval; 3776 trig_param->suspend_interval = uapsd_param->suspend_interval; 3777 trig_param->delay_interval = uapsd_param->delay_interval; 3778 trig_param++; 3779 uapsd_param++; 3780 } 3781 3782 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3783 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3784 if (QDF_IS_STATUS_ERROR(ret)) { 3785 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3786 wmi_buf_free(buf); 3787 } 3788 3789 return ret; 3790 } 3791 3792 #ifdef WLAN_FEATURE_DSRC 3793 /** 3794 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3795 * @wmi_handle: pointer to the wmi handle 3796 * @utc: pointer to the UTC time struct 3797 * 3798 * Return: 0 on succes 3799 */ 3800 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3801 struct ocb_utc_param *utc) 3802 { 3803 QDF_STATUS ret; 3804 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3805 uint8_t *buf_ptr; 3806 uint32_t len, i; 3807 wmi_buf_t buf; 3808 3809 len = sizeof(*cmd); 3810 buf = wmi_buf_alloc(wmi_handle, len); 3811 if (!buf) { 3812 WMI_LOGE(FL("wmi_buf_alloc failed")); 3813 return QDF_STATUS_E_NOMEM; 3814 } 3815 3816 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3817 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3818 WMITLV_SET_HDR(&cmd->tlv_header, 3819 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3820 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3821 cmd->vdev_id = utc->vdev_id; 3822 3823 for (i = 0; i < SIZE_UTC_TIME; i++) 3824 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 3825 3826 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 3827 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 3828 3829 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3830 WMI_OCB_SET_UTC_TIME_CMDID); 3831 if (QDF_IS_STATUS_ERROR(ret)) { 3832 WMI_LOGE(FL("Failed to set OCB UTC time")); 3833 wmi_buf_free(buf); 3834 } 3835 3836 return ret; 3837 } 3838 3839 /** 3840 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 3841 * frames on a channel 3842 * @wmi_handle: pointer to the wmi handle 3843 * @timing_advert: pointer to the timing advertisement struct 3844 * 3845 * Return: 0 on succes 3846 */ 3847 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3848 struct ocb_timing_advert_param *timing_advert) 3849 { 3850 QDF_STATUS ret; 3851 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 3852 uint8_t *buf_ptr; 3853 uint32_t len, len_template; 3854 wmi_buf_t buf; 3855 3856 len = sizeof(*cmd) + 3857 WMI_TLV_HDR_SIZE; 3858 3859 len_template = timing_advert->template_length; 3860 /* Add padding to the template if needed */ 3861 if (len_template % 4 != 0) 3862 len_template += 4 - (len_template % 4); 3863 len += len_template; 3864 3865 buf = wmi_buf_alloc(wmi_handle, len); 3866 if (!buf) { 3867 WMI_LOGE(FL("wmi_buf_alloc failed")); 3868 return QDF_STATUS_E_NOMEM; 3869 } 3870 3871 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3872 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 3873 WMITLV_SET_HDR(&cmd->tlv_header, 3874 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 3875 WMITLV_GET_STRUCT_TLVLEN( 3876 wmi_ocb_start_timing_advert_cmd_fixed_param)); 3877 cmd->vdev_id = timing_advert->vdev_id; 3878 cmd->repeat_rate = timing_advert->repeat_rate; 3879 cmd->channel_freq = timing_advert->chan_freq; 3880 cmd->timestamp_offset = timing_advert->timestamp_offset; 3881 cmd->time_value_offset = timing_advert->time_value_offset; 3882 cmd->timing_advert_template_length = timing_advert->template_length; 3883 buf_ptr += sizeof(*cmd); 3884 3885 /* Add the timing advert template */ 3886 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3887 len_template); 3888 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 3889 (uint8_t *)timing_advert->template_value, 3890 timing_advert->template_length); 3891 3892 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3893 WMI_OCB_START_TIMING_ADVERT_CMDID); 3894 if (QDF_IS_STATUS_ERROR(ret)) { 3895 WMI_LOGE(FL("Failed to start OCB timing advert")); 3896 wmi_buf_free(buf); 3897 } 3898 3899 return ret; 3900 } 3901 3902 /** 3903 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 3904 * on a channel 3905 * @wmi_handle: pointer to the wmi handle 3906 * @timing_advert: pointer to the timing advertisement struct 3907 * 3908 * Return: 0 on succes 3909 */ 3910 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3911 struct ocb_timing_advert_param *timing_advert) 3912 { 3913 QDF_STATUS ret; 3914 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 3915 uint8_t *buf_ptr; 3916 uint32_t len; 3917 wmi_buf_t buf; 3918 3919 len = sizeof(*cmd); 3920 buf = wmi_buf_alloc(wmi_handle, len); 3921 if (!buf) { 3922 WMI_LOGE(FL("wmi_buf_alloc failed")); 3923 return QDF_STATUS_E_NOMEM; 3924 } 3925 3926 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3927 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 3928 WMITLV_SET_HDR(&cmd->tlv_header, 3929 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 3930 WMITLV_GET_STRUCT_TLVLEN( 3931 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 3932 cmd->vdev_id = timing_advert->vdev_id; 3933 cmd->channel_freq = timing_advert->chan_freq; 3934 3935 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3936 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 3937 if (QDF_IS_STATUS_ERROR(ret)) { 3938 WMI_LOGE(FL("Failed to stop OCB timing advert")); 3939 wmi_buf_free(buf); 3940 } 3941 3942 return ret; 3943 } 3944 3945 /** 3946 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 3947 * @wmi_handle: pointer to the wmi handle 3948 * @request: pointer to the request 3949 * 3950 * Return: 0 on succes 3951 */ 3952 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 3953 uint8_t vdev_id) 3954 { 3955 QDF_STATUS ret; 3956 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 3957 uint8_t *buf_ptr; 3958 wmi_buf_t buf; 3959 int32_t len; 3960 3961 len = sizeof(*cmd); 3962 buf = wmi_buf_alloc(wmi_handle, len); 3963 if (!buf) { 3964 WMI_LOGE(FL("wmi_buf_alloc failed")); 3965 return QDF_STATUS_E_NOMEM; 3966 } 3967 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3968 3969 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 3970 qdf_mem_zero(cmd, len); 3971 WMITLV_SET_HDR(&cmd->tlv_header, 3972 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 3973 WMITLV_GET_STRUCT_TLVLEN( 3974 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 3975 cmd->vdev_id = vdev_id; 3976 3977 /* Send the WMI command */ 3978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3979 WMI_OCB_GET_TSF_TIMER_CMDID); 3980 /* If there is an error, set the completion event */ 3981 if (QDF_IS_STATUS_ERROR(ret)) { 3982 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 3983 wmi_buf_free(buf); 3984 } 3985 3986 return ret; 3987 } 3988 3989 /** 3990 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 3991 * @wmi_handle: pointer to the wmi handle 3992 * @get_stats_param: pointer to the dcc stats 3993 * 3994 * Return: 0 on succes 3995 */ 3996 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 3997 struct ocb_dcc_get_stats_param *get_stats_param) 3998 { 3999 QDF_STATUS ret; 4000 wmi_dcc_get_stats_cmd_fixed_param *cmd; 4001 wmi_dcc_channel_stats_request *channel_stats_array; 4002 wmi_buf_t buf; 4003 uint8_t *buf_ptr; 4004 uint32_t len; 4005 uint32_t i; 4006 4007 /* Validate the input */ 4008 if (get_stats_param->request_array_len != 4009 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4010 WMI_LOGE(FL("Invalid parameter")); 4011 return QDF_STATUS_E_INVAL; 4012 } 4013 4014 /* Allocate memory for the WMI command */ 4015 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4016 get_stats_param->request_array_len; 4017 4018 buf = wmi_buf_alloc(wmi_handle, len); 4019 if (!buf) { 4020 WMI_LOGE(FL("wmi_buf_alloc failed")); 4021 return QDF_STATUS_E_NOMEM; 4022 } 4023 4024 buf_ptr = wmi_buf_data(buf); 4025 qdf_mem_zero(buf_ptr, len); 4026 4027 /* Populate the WMI command */ 4028 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4029 buf_ptr += sizeof(*cmd); 4030 4031 WMITLV_SET_HDR(&cmd->tlv_header, 4032 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4033 WMITLV_GET_STRUCT_TLVLEN( 4034 wmi_dcc_get_stats_cmd_fixed_param)); 4035 cmd->vdev_id = get_stats_param->vdev_id; 4036 cmd->num_channels = get_stats_param->channel_count; 4037 4038 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4039 get_stats_param->request_array_len); 4040 buf_ptr += WMI_TLV_HDR_SIZE; 4041 4042 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4043 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4044 get_stats_param->request_array_len); 4045 for (i = 0; i < cmd->num_channels; i++) 4046 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4047 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4048 WMITLV_GET_STRUCT_TLVLEN( 4049 wmi_dcc_channel_stats_request)); 4050 4051 /* Send the WMI command */ 4052 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4053 WMI_DCC_GET_STATS_CMDID); 4054 4055 if (QDF_IS_STATUS_ERROR(ret)) { 4056 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4057 wmi_buf_free(buf); 4058 } 4059 4060 return ret; 4061 } 4062 4063 /** 4064 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4065 * @wmi_handle: pointer to the wmi handle 4066 * @vdev_id: vdev id 4067 * @dcc_stats_bitmap: dcc status bitmap 4068 * 4069 * Return: 0 on succes 4070 */ 4071 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4072 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4073 { 4074 QDF_STATUS ret; 4075 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4076 wmi_buf_t buf; 4077 uint8_t *buf_ptr; 4078 uint32_t len; 4079 4080 /* Allocate memory for the WMI command */ 4081 len = sizeof(*cmd); 4082 4083 buf = wmi_buf_alloc(wmi_handle, len); 4084 if (!buf) { 4085 WMI_LOGE(FL("wmi_buf_alloc failed")); 4086 return QDF_STATUS_E_NOMEM; 4087 } 4088 4089 buf_ptr = wmi_buf_data(buf); 4090 qdf_mem_zero(buf_ptr, len); 4091 4092 /* Populate the WMI command */ 4093 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4094 4095 WMITLV_SET_HDR(&cmd->tlv_header, 4096 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4097 WMITLV_GET_STRUCT_TLVLEN( 4098 wmi_dcc_clear_stats_cmd_fixed_param)); 4099 cmd->vdev_id = vdev_id; 4100 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4101 4102 /* Send the WMI command */ 4103 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4104 WMI_DCC_CLEAR_STATS_CMDID); 4105 if (QDF_IS_STATUS_ERROR(ret)) { 4106 WMI_LOGE(FL("Failed to send the WMI command")); 4107 wmi_buf_free(buf); 4108 } 4109 4110 return ret; 4111 } 4112 4113 /** 4114 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4115 * @wmi_handle: pointer to the wmi handle 4116 * @update_ndl_param: pointer to the request parameters 4117 * 4118 * Return: 0 on success 4119 */ 4120 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4121 struct ocb_dcc_update_ndl_param *update_ndl_param) 4122 { 4123 QDF_STATUS qdf_status; 4124 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4125 wmi_dcc_ndl_chan *ndl_chan_array; 4126 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4127 uint32_t active_state_count; 4128 wmi_buf_t buf; 4129 uint8_t *buf_ptr; 4130 uint32_t len; 4131 uint32_t i; 4132 4133 /* validate the input */ 4134 if (update_ndl_param->dcc_ndl_chan_list_len != 4135 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4136 WMI_LOGE(FL("Invalid parameter")); 4137 return QDF_STATUS_E_INVAL; 4138 } 4139 active_state_count = 0; 4140 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4141 for (i = 0; i < update_ndl_param->channel_count; i++) 4142 active_state_count += 4143 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4144 if (update_ndl_param->dcc_ndl_active_state_list_len != 4145 active_state_count * sizeof(*ndl_active_state_array)) { 4146 WMI_LOGE(FL("Invalid parameter")); 4147 return QDF_STATUS_E_INVAL; 4148 } 4149 4150 /* Allocate memory for the WMI command */ 4151 len = sizeof(*cmd) + 4152 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4153 WMI_TLV_HDR_SIZE + 4154 update_ndl_param->dcc_ndl_active_state_list_len; 4155 4156 buf = wmi_buf_alloc(wmi_handle, len); 4157 if (!buf) { 4158 WMI_LOGE(FL("wmi_buf_alloc failed")); 4159 return QDF_STATUS_E_NOMEM; 4160 } 4161 4162 buf_ptr = wmi_buf_data(buf); 4163 qdf_mem_zero(buf_ptr, len); 4164 4165 /* Populate the WMI command */ 4166 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4167 buf_ptr += sizeof(*cmd); 4168 4169 WMITLV_SET_HDR(&cmd->tlv_header, 4170 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4171 WMITLV_GET_STRUCT_TLVLEN( 4172 wmi_dcc_update_ndl_cmd_fixed_param)); 4173 cmd->vdev_id = update_ndl_param->vdev_id; 4174 cmd->num_channel = update_ndl_param->channel_count; 4175 4176 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4177 update_ndl_param->dcc_ndl_chan_list_len); 4178 buf_ptr += WMI_TLV_HDR_SIZE; 4179 4180 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4181 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4182 update_ndl_param->dcc_ndl_chan_list_len); 4183 for (i = 0; i < cmd->num_channel; i++) 4184 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4185 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4186 WMITLV_GET_STRUCT_TLVLEN( 4187 wmi_dcc_ndl_chan)); 4188 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4189 4190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4191 update_ndl_param->dcc_ndl_active_state_list_len); 4192 buf_ptr += WMI_TLV_HDR_SIZE; 4193 4194 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4195 qdf_mem_copy(ndl_active_state_array, 4196 update_ndl_param->dcc_ndl_active_state_list, 4197 update_ndl_param->dcc_ndl_active_state_list_len); 4198 for (i = 0; i < active_state_count; i++) { 4199 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4200 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4201 WMITLV_GET_STRUCT_TLVLEN( 4202 wmi_dcc_ndl_active_state_config)); 4203 } 4204 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4205 4206 /* Send the WMI command */ 4207 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4208 WMI_DCC_UPDATE_NDL_CMDID); 4209 /* If there is an error, set the completion event */ 4210 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4211 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4212 wmi_buf_free(buf); 4213 } 4214 4215 return qdf_status; 4216 } 4217 4218 /** 4219 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4220 * @wmi_handle: pointer to the wmi handle 4221 * @config: the OCB configuration 4222 * 4223 * Return: 0 on success 4224 */ 4225 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4226 struct ocb_config *config) 4227 { 4228 QDF_STATUS ret; 4229 wmi_ocb_set_config_cmd_fixed_param *cmd; 4230 wmi_channel *chan; 4231 wmi_ocb_channel *ocb_chan; 4232 wmi_qos_parameter *qos_param; 4233 wmi_dcc_ndl_chan *ndl_chan; 4234 wmi_dcc_ndl_active_state_config *ndl_active_config; 4235 wmi_ocb_schedule_element *sched_elem; 4236 uint8_t *buf_ptr; 4237 wmi_buf_t buf; 4238 int32_t len; 4239 int32_t i, j, active_state_count; 4240 4241 /* 4242 * Validate the dcc_ndl_chan_list_len and count the number of active 4243 * states. Validate dcc_ndl_active_state_list_len. 4244 */ 4245 active_state_count = 0; 4246 if (config->dcc_ndl_chan_list_len) { 4247 if (!config->dcc_ndl_chan_list || 4248 config->dcc_ndl_chan_list_len != 4249 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4250 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4251 config->dcc_ndl_chan_list_len); 4252 return QDF_STATUS_E_INVAL; 4253 } 4254 4255 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4256 i < config->channel_count; ++i, ++ndl_chan) 4257 active_state_count += 4258 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4259 4260 if (active_state_count) { 4261 if (!config->dcc_ndl_active_state_list || 4262 config->dcc_ndl_active_state_list_len != 4263 active_state_count * 4264 sizeof(wmi_dcc_ndl_active_state_config)) { 4265 WMI_LOGE(FL("NDL active state is invalid.")); 4266 return QDF_STATUS_E_INVAL; 4267 } 4268 } 4269 } 4270 4271 len = sizeof(*cmd) + 4272 WMI_TLV_HDR_SIZE + config->channel_count * 4273 sizeof(wmi_channel) + 4274 WMI_TLV_HDR_SIZE + config->channel_count * 4275 sizeof(wmi_ocb_channel) + 4276 WMI_TLV_HDR_SIZE + config->channel_count * 4277 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4278 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4279 WMI_TLV_HDR_SIZE + active_state_count * 4280 sizeof(wmi_dcc_ndl_active_state_config) + 4281 WMI_TLV_HDR_SIZE + config->schedule_size * 4282 sizeof(wmi_ocb_schedule_element); 4283 buf = wmi_buf_alloc(wmi_handle, len); 4284 if (!buf) { 4285 WMI_LOGE(FL("wmi_buf_alloc failed")); 4286 return QDF_STATUS_E_NOMEM; 4287 } 4288 4289 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4290 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4291 WMITLV_SET_HDR(&cmd->tlv_header, 4292 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4293 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4294 cmd->vdev_id = config->vdev_id; 4295 cmd->channel_count = config->channel_count; 4296 cmd->schedule_size = config->schedule_size; 4297 cmd->flags = config->flags; 4298 buf_ptr += sizeof(*cmd); 4299 4300 /* Add the wmi_channel info */ 4301 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4302 config->channel_count*sizeof(wmi_channel)); 4303 buf_ptr += WMI_TLV_HDR_SIZE; 4304 for (i = 0; i < config->channel_count; i++) { 4305 chan = (wmi_channel *)buf_ptr; 4306 WMITLV_SET_HDR(&chan->tlv_header, 4307 WMITLV_TAG_STRUC_wmi_channel, 4308 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4309 chan->mhz = config->channels[i].chan_freq; 4310 chan->band_center_freq1 = config->channels[i].chan_freq; 4311 chan->band_center_freq2 = 0; 4312 chan->info = 0; 4313 4314 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4315 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4316 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4317 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4318 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4319 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4320 config->channels[i].antenna_max); 4321 4322 if (config->channels[i].bandwidth < 10) 4323 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4324 else if (config->channels[i].bandwidth < 20) 4325 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4326 buf_ptr += sizeof(*chan); 4327 } 4328 4329 /* Add the wmi_ocb_channel info */ 4330 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4331 config->channel_count*sizeof(wmi_ocb_channel)); 4332 buf_ptr += WMI_TLV_HDR_SIZE; 4333 for (i = 0; i < config->channel_count; i++) { 4334 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4335 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4336 WMITLV_TAG_STRUC_wmi_ocb_channel, 4337 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4338 ocb_chan->bandwidth = config->channels[i].bandwidth; 4339 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4340 config->channels[i].mac_address.bytes, 4341 &ocb_chan->mac_address); 4342 buf_ptr += sizeof(*ocb_chan); 4343 } 4344 4345 /* Add the wmi_qos_parameter info */ 4346 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4347 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4348 buf_ptr += WMI_TLV_HDR_SIZE; 4349 /* WMI_MAX_NUM_AC parameters for each channel */ 4350 for (i = 0; i < config->channel_count; i++) { 4351 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4352 qos_param = (wmi_qos_parameter *)buf_ptr; 4353 WMITLV_SET_HDR(&qos_param->tlv_header, 4354 WMITLV_TAG_STRUC_wmi_qos_parameter, 4355 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4356 qos_param->aifsn = 4357 config->channels[i].qos_params[j].aifsn; 4358 qos_param->cwmin = 4359 config->channels[i].qos_params[j].cwmin; 4360 qos_param->cwmax = 4361 config->channels[i].qos_params[j].cwmax; 4362 buf_ptr += sizeof(*qos_param); 4363 } 4364 } 4365 4366 /* Add the wmi_dcc_ndl_chan (per channel) */ 4367 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4368 config->dcc_ndl_chan_list_len); 4369 buf_ptr += WMI_TLV_HDR_SIZE; 4370 if (config->dcc_ndl_chan_list_len) { 4371 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4372 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4373 config->dcc_ndl_chan_list_len); 4374 for (i = 0; i < config->channel_count; i++) 4375 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4376 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4377 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4378 buf_ptr += config->dcc_ndl_chan_list_len; 4379 } 4380 4381 /* Add the wmi_dcc_ndl_active_state_config */ 4382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4383 sizeof(wmi_dcc_ndl_active_state_config)); 4384 buf_ptr += WMI_TLV_HDR_SIZE; 4385 if (active_state_count) { 4386 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4387 qdf_mem_copy(ndl_active_config, 4388 config->dcc_ndl_active_state_list, 4389 active_state_count * sizeof(*ndl_active_config)); 4390 for (i = 0; i < active_state_count; ++i) 4391 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4392 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4393 WMITLV_GET_STRUCT_TLVLEN( 4394 wmi_dcc_ndl_active_state_config)); 4395 buf_ptr += active_state_count * 4396 sizeof(*ndl_active_config); 4397 } 4398 4399 /* Add the wmi_ocb_schedule_element info */ 4400 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4401 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4402 buf_ptr += WMI_TLV_HDR_SIZE; 4403 for (i = 0; i < config->schedule_size; i++) { 4404 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4405 WMITLV_SET_HDR(&sched_elem->tlv_header, 4406 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4407 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4408 sched_elem->channel_freq = config->schedule[i].chan_freq; 4409 sched_elem->total_duration = config->schedule[i].total_duration; 4410 sched_elem->guard_interval = config->schedule[i].guard_interval; 4411 buf_ptr += sizeof(*sched_elem); 4412 } 4413 4414 4415 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4416 WMI_OCB_SET_CONFIG_CMDID); 4417 if (QDF_IS_STATUS_ERROR(ret)) { 4418 WMI_LOGE("Failed to set OCB config"); 4419 wmi_buf_free(buf); 4420 } 4421 4422 return ret; 4423 } 4424 4425 /** 4426 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4427 * @wmi_handle: wmi handle 4428 * @evt_buf: wmi event buffer 4429 * @status: status buffer 4430 * 4431 * Return: QDF_STATUS_SUCCESS on success 4432 */ 4433 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4434 void *evt_buf, 4435 uint32_t *status) 4436 { 4437 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4438 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4439 4440 param_tlvs = evt_buf; 4441 fix_param = param_tlvs->fixed_param; 4442 4443 *status = fix_param->status; 4444 return QDF_STATUS_SUCCESS; 4445 } 4446 4447 /** 4448 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4449 * @wmi_handle: wmi handle 4450 * @evt_buf: wmi event buffer 4451 * @resp: response buffer 4452 * 4453 * Return: QDF_STATUS_SUCCESS on success 4454 */ 4455 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4456 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4457 { 4458 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4459 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4460 4461 param_tlvs = evt_buf; 4462 fix_param = param_tlvs->fixed_param; 4463 resp->vdev_id = fix_param->vdev_id; 4464 resp->timer_high = fix_param->tsf_timer_high; 4465 resp->timer_low = fix_param->tsf_timer_low; 4466 4467 return QDF_STATUS_SUCCESS; 4468 } 4469 4470 /** 4471 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4472 * @wmi_handle: wmi handle 4473 * @evt_buf: wmi event buffer 4474 * @resp: response buffer 4475 * 4476 * Return: QDF_STATUS_SUCCESS on success 4477 */ 4478 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4479 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4480 { 4481 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4482 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4483 4484 param_tlvs = evt_buf; 4485 fix_param = param_tlvs->fixed_param; 4486 resp->vdev_id = fix_param->vdev_id; 4487 resp->status = fix_param->status; 4488 return QDF_STATUS_SUCCESS; 4489 } 4490 4491 /** 4492 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4493 * @wmi_handle: wmi handle 4494 * @evt_buf: wmi event buffer 4495 * @resp: response buffer 4496 * 4497 * Since length of stats is variable, buffer for DCC stats will be allocated 4498 * in this function. The caller must free the buffer. 4499 * 4500 * Return: QDF_STATUS_SUCCESS on success 4501 */ 4502 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4503 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4504 { 4505 struct ocb_dcc_get_stats_response *response; 4506 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4507 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4508 4509 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4510 fix_param = param_tlvs->fixed_param; 4511 4512 /* Allocate and populate the response */ 4513 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4514 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4515 WMI_LOGE("%s: too many channels:%d", __func__, 4516 fix_param->num_channels); 4517 QDF_ASSERT(0); 4518 *resp = NULL; 4519 return QDF_STATUS_E_INVAL; 4520 } 4521 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4522 sizeof(wmi_dcc_ndl_stats_per_channel)); 4523 *resp = response; 4524 if (!response) 4525 return QDF_STATUS_E_NOMEM; 4526 4527 response->vdev_id = fix_param->vdev_id; 4528 response->num_channels = fix_param->num_channels; 4529 response->channel_stats_array_len = 4530 fix_param->num_channels * 4531 sizeof(wmi_dcc_ndl_stats_per_channel); 4532 response->channel_stats_array = ((uint8_t *)response) + 4533 sizeof(*response); 4534 qdf_mem_copy(response->channel_stats_array, 4535 param_tlvs->stats_per_channel_list, 4536 response->channel_stats_array_len); 4537 4538 return QDF_STATUS_SUCCESS; 4539 } 4540 #endif 4541 4542 /** 4543 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4544 * @wmi_handle: wmi handle 4545 * @mcc_adaptive_scheduler: enable/disable 4546 * 4547 * This function enable/disable mcc adaptive scheduler in fw. 4548 * 4549 * Return: QDF_STATUS_SUCCESS for success or error code 4550 */ 4551 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4552 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4553 uint32_t pdev_id) 4554 { 4555 QDF_STATUS ret; 4556 wmi_buf_t buf = 0; 4557 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4558 uint16_t len = 4559 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4560 4561 buf = wmi_buf_alloc(wmi_handle, len); 4562 if (!buf) { 4563 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4564 return QDF_STATUS_E_NOMEM; 4565 } 4566 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4567 wmi_buf_data(buf); 4568 4569 WMITLV_SET_HDR(&cmd->tlv_header, 4570 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4571 WMITLV_GET_STRUCT_TLVLEN 4572 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4573 cmd->enable = mcc_adaptive_scheduler; 4574 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4575 4576 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4577 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4578 if (QDF_IS_STATUS_ERROR(ret)) { 4579 WMI_LOGP("%s: Failed to send enable/disable MCC" 4580 " adaptive scheduler command", __func__); 4581 wmi_buf_free(buf); 4582 } 4583 4584 return ret; 4585 } 4586 4587 /** 4588 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4589 * @wmi: wmi handle 4590 * @mcc_channel: mcc channel 4591 * @mcc_channel_time_latency: MCC channel time latency. 4592 * 4593 * Currently used to set time latency for an MCC vdev/adapter using operating 4594 * channel of it and channel number. The info is provided run time using 4595 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4596 * 4597 * Return: CDF status 4598 */ 4599 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4600 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4601 { 4602 QDF_STATUS ret; 4603 wmi_buf_t buf = 0; 4604 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4605 uint16_t len = 0; 4606 uint8_t *buf_ptr = NULL; 4607 wmi_resmgr_chan_latency chan_latency; 4608 /* Note: we only support MCC time latency for a single channel */ 4609 uint32_t num_channels = 1; 4610 uint32_t chan1_freq = mcc_channel_freq; 4611 uint32_t latency_chan1 = mcc_channel_time_latency; 4612 4613 4614 /* If 0ms latency is provided, then FW will set to a default. 4615 * Otherwise, latency must be at least 30ms. 4616 */ 4617 if ((latency_chan1 > 0) && 4618 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4619 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4620 "Minimum is 30ms (or 0 to use default value by " 4621 "firmware)", __func__, latency_chan1); 4622 return QDF_STATUS_E_INVAL; 4623 } 4624 4625 /* Set WMI CMD for channel time latency here */ 4626 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4627 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4628 num_channels * sizeof(wmi_resmgr_chan_latency); 4629 buf = wmi_buf_alloc(wmi_handle, len); 4630 if (!buf) { 4631 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4632 return QDF_STATUS_E_NOMEM; 4633 } 4634 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4635 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4636 wmi_buf_data(buf); 4637 WMITLV_SET_HDR(&cmdTL->tlv_header, 4638 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4639 WMITLV_GET_STRUCT_TLVLEN 4640 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4641 cmdTL->num_chans = num_channels; 4642 /* Update channel time latency information for home channel(s) */ 4643 buf_ptr += sizeof(*cmdTL); 4644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4645 num_channels * sizeof(wmi_resmgr_chan_latency)); 4646 buf_ptr += WMI_TLV_HDR_SIZE; 4647 chan_latency.chan_mhz = chan1_freq; 4648 chan_latency.latency = latency_chan1; 4649 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4650 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4651 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4652 if (QDF_IS_STATUS_ERROR(ret)) { 4653 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4654 __func__); 4655 wmi_buf_free(buf); 4656 QDF_ASSERT(0); 4657 } 4658 4659 return ret; 4660 } 4661 4662 /** 4663 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4664 * @wmi: wmi handle 4665 * @adapter_1_chan_number: adapter 1 channel number 4666 * @adapter_1_quota: adapter 1 quota 4667 * @adapter_2_chan_number: adapter 2 channel number 4668 * 4669 * Return: CDF status 4670 */ 4671 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4672 uint32_t adapter_1_chan_freq, 4673 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4674 { 4675 QDF_STATUS ret; 4676 wmi_buf_t buf = 0; 4677 uint16_t len = 0; 4678 uint8_t *buf_ptr = NULL; 4679 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4680 wmi_resmgr_chan_time_quota chan_quota; 4681 uint32_t quota_chan1 = adapter_1_quota; 4682 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4683 uint32_t quota_chan2 = 100 - quota_chan1; 4684 /* Note: setting time quota for MCC requires info for 2 channels */ 4685 uint32_t num_channels = 2; 4686 uint32_t chan1_freq = adapter_1_chan_freq; 4687 uint32_t chan2_freq = adapter_2_chan_freq; 4688 4689 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4690 "freq2:%dMHz, Quota2:%dms", __func__, 4691 chan1_freq, quota_chan1, chan2_freq, 4692 quota_chan2); 4693 4694 /* 4695 * Perform sanity check on time quota values provided. 4696 */ 4697 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4698 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4699 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4700 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4701 return QDF_STATUS_E_INVAL; 4702 } 4703 /* Set WMI CMD for channel time quota here */ 4704 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4705 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4706 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4707 buf = wmi_buf_alloc(wmi_handle, len); 4708 if (!buf) { 4709 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4710 QDF_ASSERT(0); 4711 return QDF_STATUS_E_NOMEM; 4712 } 4713 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4714 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4715 wmi_buf_data(buf); 4716 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4717 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4718 WMITLV_GET_STRUCT_TLVLEN 4719 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4720 cmdTQ->num_chans = num_channels; 4721 4722 /* Update channel time quota information for home channel(s) */ 4723 buf_ptr += sizeof(*cmdTQ); 4724 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4725 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4726 buf_ptr += WMI_TLV_HDR_SIZE; 4727 chan_quota.chan_mhz = chan1_freq; 4728 chan_quota.channel_time_quota = quota_chan1; 4729 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4730 /* Construct channel and quota record for the 2nd MCC mode. */ 4731 buf_ptr += sizeof(chan_quota); 4732 chan_quota.chan_mhz = chan2_freq; 4733 chan_quota.channel_time_quota = quota_chan2; 4734 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4735 4736 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4737 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4738 if (QDF_IS_STATUS_ERROR(ret)) { 4739 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4740 wmi_buf_free(buf); 4741 QDF_ASSERT(0); 4742 } 4743 4744 return ret; 4745 } 4746 4747 /** 4748 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4749 * @wmi_handle: Pointer to wmi handle 4750 * @thermal_info: Thermal command information 4751 * 4752 * This function sends the thermal management command 4753 * to the firmware 4754 * 4755 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4756 */ 4757 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4758 struct thermal_cmd_params *thermal_info) 4759 { 4760 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4761 wmi_buf_t buf = NULL; 4762 QDF_STATUS status; 4763 uint32_t len = 0; 4764 4765 len = sizeof(*cmd); 4766 4767 buf = wmi_buf_alloc(wmi_handle, len); 4768 if (!buf) { 4769 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4770 return QDF_STATUS_E_FAILURE; 4771 } 4772 4773 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4774 4775 WMITLV_SET_HDR(&cmd->tlv_header, 4776 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4777 WMITLV_GET_STRUCT_TLVLEN 4778 (wmi_thermal_mgmt_cmd_fixed_param)); 4779 4780 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4781 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4782 cmd->enable = thermal_info->thermal_enable; 4783 4784 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4785 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4786 4787 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4788 WMI_THERMAL_MGMT_CMDID); 4789 if (QDF_IS_STATUS_ERROR(status)) { 4790 wmi_buf_free(buf); 4791 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4792 } 4793 4794 return status; 4795 } 4796 4797 4798 /** 4799 * send_lro_config_cmd_tlv() - process the LRO config command 4800 * @wmi_handle: Pointer to WMI handle 4801 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4802 * 4803 * This function sends down the LRO configuration parameters to 4804 * the firmware to enable LRO, sets the TCP flags and sets the 4805 * seed values for the toeplitz hash generation 4806 * 4807 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4808 */ 4809 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4810 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4811 { 4812 wmi_lro_info_cmd_fixed_param *cmd; 4813 wmi_buf_t buf; 4814 QDF_STATUS status; 4815 4816 4817 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4818 if (!buf) { 4819 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4820 return QDF_STATUS_E_FAILURE; 4821 } 4822 4823 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4824 4825 WMITLV_SET_HDR(&cmd->tlv_header, 4826 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4827 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4828 4829 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4830 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4831 wmi_lro_cmd->tcp_flag); 4832 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4833 wmi_lro_cmd->tcp_flag_mask); 4834 cmd->toeplitz_hash_ipv4_0_3 = 4835 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4836 cmd->toeplitz_hash_ipv4_4_7 = 4837 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4838 cmd->toeplitz_hash_ipv4_8_11 = 4839 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4840 cmd->toeplitz_hash_ipv4_12_15 = 4841 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4842 cmd->toeplitz_hash_ipv4_16 = 4843 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4844 4845 cmd->toeplitz_hash_ipv6_0_3 = 4846 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4847 cmd->toeplitz_hash_ipv6_4_7 = 4848 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4849 cmd->toeplitz_hash_ipv6_8_11 = 4850 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4851 cmd->toeplitz_hash_ipv6_12_15 = 4852 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4853 cmd->toeplitz_hash_ipv6_16_19 = 4854 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4855 cmd->toeplitz_hash_ipv6_20_23 = 4856 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4857 cmd->toeplitz_hash_ipv6_24_27 = 4858 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4859 cmd->toeplitz_hash_ipv6_28_31 = 4860 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4861 cmd->toeplitz_hash_ipv6_32_35 = 4862 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4863 cmd->toeplitz_hash_ipv6_36_39 = 4864 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4865 cmd->toeplitz_hash_ipv6_40 = 4866 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4867 4868 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 4869 cmd->lro_enable, cmd->tcp_flag_u32); 4870 4871 status = wmi_unified_cmd_send(wmi_handle, buf, 4872 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4873 if (QDF_IS_STATUS_ERROR(status)) { 4874 wmi_buf_free(buf); 4875 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4876 } 4877 4878 return status; 4879 } 4880 4881 /** 4882 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4883 * @wmi_handle: Pointer to wmi handle 4884 * @rate_report_params: Pointer to peer rate report parameters 4885 * 4886 * 4887 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4888 */ 4889 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4890 struct wmi_peer_rate_report_params *rate_report_params) 4891 { 4892 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4893 wmi_buf_t buf = NULL; 4894 QDF_STATUS status = 0; 4895 uint32_t len = 0; 4896 uint32_t i, j; 4897 4898 len = sizeof(*cmd); 4899 4900 buf = wmi_buf_alloc(wmi_handle, len); 4901 if (!buf) { 4902 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 4903 return QDF_STATUS_E_FAILURE; 4904 } 4905 4906 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4907 wmi_buf_data(buf); 4908 4909 WMITLV_SET_HDR( 4910 &cmd->tlv_header, 4911 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4912 WMITLV_GET_STRUCT_TLVLEN( 4913 wmi_peer_set_rate_report_condition_fixed_param)); 4914 4915 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4916 cmd->report_backoff_time = rate_report_params->backoff_time; 4917 cmd->report_timer_period = rate_report_params->timer_period; 4918 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4919 cmd->cond_per_phy[i].val_cond_flags = 4920 rate_report_params->report_per_phy[i].cond_flags; 4921 cmd->cond_per_phy[i].rate_delta.min_delta = 4922 rate_report_params->report_per_phy[i].delta.delta_min; 4923 cmd->cond_per_phy[i].rate_delta.percentage = 4924 rate_report_params->report_per_phy[i].delta.percent; 4925 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4926 cmd->cond_per_phy[i].rate_threshold[j] = 4927 rate_report_params->report_per_phy[i]. 4928 report_rate_threshold[j]; 4929 } 4930 } 4931 4932 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 4933 cmd->enable_rate_report, 4934 cmd->report_backoff_time, cmd->report_timer_period); 4935 4936 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4937 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4938 if (QDF_IS_STATUS_ERROR(status)) { 4939 wmi_buf_free(buf); 4940 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4941 __func__); 4942 } 4943 return status; 4944 } 4945 4946 /** 4947 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 4948 * @wmi_handle: wmi handle 4949 * @param: bcn ll cmd parameter 4950 * 4951 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4952 */ 4953 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 4954 wmi_bcn_send_from_host_cmd_fixed_param *param) 4955 { 4956 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 4957 wmi_buf_t wmi_buf; 4958 QDF_STATUS ret; 4959 4960 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4961 if (!wmi_buf) { 4962 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 4963 return QDF_STATUS_E_FAILURE; 4964 } 4965 4966 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4967 WMITLV_SET_HDR(&cmd->tlv_header, 4968 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 4969 WMITLV_GET_STRUCT_TLVLEN 4970 (wmi_bcn_send_from_host_cmd_fixed_param)); 4971 cmd->vdev_id = param->vdev_id; 4972 cmd->data_len = param->data_len; 4973 cmd->frame_ctrl = param->frame_ctrl; 4974 cmd->frag_ptr = param->frag_ptr; 4975 cmd->dtim_flag = param->dtim_flag; 4976 4977 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 4978 WMI_PDEV_SEND_BCN_CMDID); 4979 4980 if (QDF_IS_STATUS_ERROR(ret)) { 4981 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 4982 wmi_buf_free(wmi_buf); 4983 } 4984 4985 return ret; 4986 } 4987 4988 /** 4989 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 4990 * @wmi_handle: wmi handle 4991 * @vdev_id: vdev id 4992 * @max_retries: max retries 4993 * @retry_interval: retry interval 4994 * This function sets sta query related parameters in fw. 4995 * 4996 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4997 */ 4998 4999 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 5000 uint8_t vdev_id, uint32_t max_retries, 5001 uint32_t retry_interval) 5002 { 5003 wmi_buf_t buf; 5004 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 5005 int len; 5006 5007 len = sizeof(*cmd); 5008 buf = wmi_buf_alloc(wmi_handle, len); 5009 if (!buf) { 5010 WMI_LOGE(FL("wmi_buf_alloc failed")); 5011 return QDF_STATUS_E_FAILURE; 5012 } 5013 5014 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5015 WMITLV_SET_HDR(&cmd->tlv_header, 5016 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5017 WMITLV_GET_STRUCT_TLVLEN 5018 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5019 5020 5021 cmd->vdev_id = vdev_id; 5022 cmd->sa_query_max_retry_count = max_retries; 5023 cmd->sa_query_retry_interval = retry_interval; 5024 5025 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5026 vdev_id, retry_interval, max_retries); 5027 5028 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5029 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5030 WMI_LOGE(FL("Failed to offload STA SA Query")); 5031 wmi_buf_free(buf); 5032 return QDF_STATUS_E_FAILURE; 5033 } 5034 5035 WMI_LOGD(FL("Exit :")); 5036 return 0; 5037 } 5038 5039 /** 5040 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5041 * @wmi_handle: wmi handle 5042 * @params: sta keep alive parameter 5043 * 5044 * This function sets keep alive related parameters in fw. 5045 * 5046 * Return: CDF status 5047 */ 5048 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5049 struct sta_params *params) 5050 { 5051 wmi_buf_t buf; 5052 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5053 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5054 uint8_t *buf_ptr; 5055 int len; 5056 QDF_STATUS ret; 5057 5058 WMI_LOGD("%s: Enter", __func__); 5059 5060 len = sizeof(*cmd) + sizeof(*arp_rsp); 5061 buf = wmi_buf_alloc(wmi_handle, len); 5062 if (!buf) { 5063 WMI_LOGE("wmi_buf_alloc failed"); 5064 return QDF_STATUS_E_FAILURE; 5065 } 5066 5067 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5068 buf_ptr = (uint8_t *) cmd; 5069 WMITLV_SET_HDR(&cmd->tlv_header, 5070 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5071 WMITLV_GET_STRUCT_TLVLEN 5072 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5073 cmd->interval = params->timeperiod; 5074 cmd->enable = (params->timeperiod) ? 1 : 0; 5075 cmd->vdev_id = params->vdev_id; 5076 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5077 params->timeperiod, params->method); 5078 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5079 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5080 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5081 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5082 5083 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5084 (params->method == 5085 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5086 if ((NULL == params->hostv4addr) || 5087 (NULL == params->destv4addr) || 5088 (NULL == params->destmac)) { 5089 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5090 "destv4addr:%pK destmac:%pK ", __func__, 5091 params->hostv4addr, params->destv4addr, params->destmac); 5092 wmi_buf_free(buf); 5093 return QDF_STATUS_E_FAILURE; 5094 } 5095 cmd->method = params->method; 5096 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5097 WMI_IPV4_ADDR_LEN); 5098 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5099 WMI_IPV4_ADDR_LEN); 5100 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5101 } else { 5102 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5103 } 5104 5105 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5106 WMI_STA_KEEPALIVE_CMDID); 5107 if (QDF_IS_STATUS_ERROR(ret)) { 5108 WMI_LOGE("Failed to set KeepAlive"); 5109 wmi_buf_free(buf); 5110 } 5111 5112 WMI_LOGD("%s: Exit", __func__); 5113 return ret; 5114 } 5115 5116 /** 5117 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5118 * @wmi_handle: wmi handle 5119 * @if_id: vdev id 5120 * @gtx_info: GTX config params 5121 * 5122 * This function set GTX related params in firmware. 5123 * 5124 * Return: QDF_STATUS_SUCCESS for success or error code 5125 */ 5126 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5127 struct wmi_gtx_config *gtx_info) 5128 { 5129 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5130 wmi_buf_t buf; 5131 QDF_STATUS ret; 5132 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5133 5134 buf = wmi_buf_alloc(wmi_handle, len); 5135 if (!buf) { 5136 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5137 return QDF_STATUS_E_NOMEM; 5138 } 5139 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5140 WMITLV_SET_HDR(&cmd->tlv_header, 5141 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5142 WMITLV_GET_STRUCT_TLVLEN 5143 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5144 cmd->vdev_id = if_id; 5145 5146 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5147 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5148 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5149 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5150 cmd->gtxPERMargin = gtx_info->gtx_margin; 5151 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5152 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5153 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5154 5155 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5156 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5157 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5158 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5159 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5160 5161 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5162 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5163 if (QDF_IS_STATUS_ERROR(ret)) { 5164 WMI_LOGE("Failed to set GTX PARAMS"); 5165 wmi_buf_free(buf); 5166 } 5167 return ret; 5168 } 5169 5170 /** 5171 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5172 * @wmi_handle: wmi handle 5173 * @vdev_id: vdev id. 5174 * @wmm_vparams: edca parameters 5175 * 5176 * This function updates EDCA parameters to the target 5177 * 5178 * Return: CDF Status 5179 */ 5180 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5181 uint8_t vdev_id, bool mu_edca_param, 5182 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5183 { 5184 uint8_t *buf_ptr; 5185 wmi_buf_t buf; 5186 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5187 wmi_wmm_vparams *wmm_param; 5188 struct wmi_host_wme_vparams *twmm_param; 5189 int len = sizeof(*cmd); 5190 int ac; 5191 5192 buf = wmi_buf_alloc(wmi_handle, len); 5193 5194 if (!buf) { 5195 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5196 return QDF_STATUS_E_NOMEM; 5197 } 5198 5199 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5200 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5201 WMITLV_SET_HDR(&cmd->tlv_header, 5202 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5203 WMITLV_GET_STRUCT_TLVLEN 5204 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5205 cmd->vdev_id = vdev_id; 5206 cmd->wmm_param_type = mu_edca_param; 5207 5208 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5209 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5210 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5211 WMITLV_SET_HDR(&wmm_param->tlv_header, 5212 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5213 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5214 wmm_param->cwmin = twmm_param->cwmin; 5215 wmm_param->cwmax = twmm_param->cwmax; 5216 wmm_param->aifs = twmm_param->aifs; 5217 if (mu_edca_param) 5218 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5219 else 5220 wmm_param->txoplimit = twmm_param->txoplimit; 5221 wmm_param->acm = twmm_param->acm; 5222 wmm_param->no_ack = twmm_param->noackpolicy; 5223 } 5224 5225 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5226 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5227 goto fail; 5228 5229 return QDF_STATUS_SUCCESS; 5230 5231 fail: 5232 wmi_buf_free(buf); 5233 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5234 return QDF_STATUS_E_FAILURE; 5235 } 5236 5237 /** 5238 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5239 * @wmi_handle: wmi handle 5240 * @vdev_id: vdev id 5241 * @probe_rsp_info: probe response info 5242 * 5243 * Return: QDF_STATUS_SUCCESS for success or error code 5244 */ 5245 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5246 uint8_t vdev_id, 5247 struct wmi_probe_resp_params *probe_rsp_info) 5248 { 5249 wmi_prb_tmpl_cmd_fixed_param *cmd; 5250 wmi_bcn_prb_info *bcn_prb_info; 5251 wmi_buf_t wmi_buf; 5252 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5253 uint8_t *buf_ptr; 5254 QDF_STATUS ret; 5255 5256 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5257 5258 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5259 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5260 5261 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5262 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5263 tmpl_len_aligned; 5264 5265 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5266 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5267 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5268 return QDF_STATUS_E_INVAL; 5269 } 5270 5271 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5272 if (!wmi_buf) { 5273 WMI_LOGE(FL("wmi_buf_alloc failed")); 5274 return QDF_STATUS_E_NOMEM; 5275 } 5276 5277 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5278 5279 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5280 WMITLV_SET_HDR(&cmd->tlv_header, 5281 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5282 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5283 cmd->vdev_id = vdev_id; 5284 cmd->buf_len = tmpl_len; 5285 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5286 5287 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5288 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5289 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5290 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5291 bcn_prb_info->caps = 0; 5292 bcn_prb_info->erp = 0; 5293 buf_ptr += sizeof(wmi_bcn_prb_info); 5294 5295 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5296 buf_ptr += WMI_TLV_HDR_SIZE; 5297 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5298 5299 ret = wmi_unified_cmd_send(wmi_handle, 5300 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5301 if (QDF_IS_STATUS_ERROR(ret)) { 5302 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5303 wmi_buf_free(wmi_buf); 5304 } 5305 5306 return ret; 5307 } 5308 5309 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5310 #define WPI_IV_LEN 16 5311 5312 /** 5313 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5314 * 5315 * @dest_tx: destination address of tsc key counter 5316 * @src_tx: source address of tsc key counter 5317 * @dest_rx: destination address of rsc key counter 5318 * @src_rx: source address of rsc key counter 5319 * 5320 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5321 * 5322 * Return: None 5323 * 5324 */ 5325 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5326 uint8_t *dest_rx, uint8_t *src_rx) 5327 { 5328 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5329 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5330 } 5331 #else 5332 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5333 uint8_t *dest_rx, uint8_t *src_rx) 5334 { 5335 return; 5336 } 5337 #endif 5338 5339 /** 5340 * send_setup_install_key_cmd_tlv() - set key parameters 5341 * @wmi_handle: wmi handle 5342 * @key_params: key parameters 5343 * 5344 * This function fills structure from information 5345 * passed in key_params. 5346 * 5347 * Return: QDF_STATUS_SUCCESS - success 5348 * QDF_STATUS_E_FAILURE - failure 5349 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5350 */ 5351 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5352 struct set_key_params *key_params) 5353 { 5354 wmi_vdev_install_key_cmd_fixed_param *cmd; 5355 wmi_buf_t buf; 5356 uint8_t *buf_ptr; 5357 uint32_t len; 5358 uint8_t *key_data; 5359 QDF_STATUS status; 5360 5361 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5362 WMI_TLV_HDR_SIZE; 5363 5364 buf = wmi_buf_alloc(wmi_handle, len); 5365 if (!buf) { 5366 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5367 return QDF_STATUS_E_NOMEM; 5368 } 5369 5370 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5371 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5372 WMITLV_SET_HDR(&cmd->tlv_header, 5373 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5374 WMITLV_GET_STRUCT_TLVLEN 5375 (wmi_vdev_install_key_cmd_fixed_param)); 5376 cmd->vdev_id = key_params->vdev_id; 5377 cmd->key_ix = key_params->key_idx; 5378 5379 5380 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5381 cmd->key_flags |= key_params->key_flags; 5382 cmd->key_cipher = key_params->key_cipher; 5383 if ((key_params->key_txmic_len) && 5384 (key_params->key_rxmic_len)) { 5385 cmd->key_txmic_len = key_params->key_txmic_len; 5386 cmd->key_rxmic_len = key_params->key_rxmic_len; 5387 } 5388 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5389 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5390 key_params->tx_iv, 5391 cmd->wpi_key_rsc_counter, 5392 key_params->rx_iv); 5393 #endif 5394 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5395 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5396 roundup(key_params->key_len, sizeof(uint32_t))); 5397 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5398 qdf_mem_copy((void *)key_data, 5399 (const void *)key_params->key_data, key_params->key_len); 5400 if (key_params->key_rsc_counter) 5401 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5402 sizeof(wmi_key_seq_counter)); 5403 cmd->key_len = key_params->key_len; 5404 5405 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5406 WMI_VDEV_INSTALL_KEY_CMDID); 5407 if (QDF_IS_STATUS_ERROR(status)) 5408 wmi_buf_free(buf); 5409 5410 return status; 5411 } 5412 5413 /** 5414 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5415 * @wmi_handle: wmi handle 5416 * @params: sar limit params 5417 * 5418 * Return: QDF_STATUS_SUCCESS for success or error code 5419 */ 5420 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5421 struct sar_limit_cmd_params *sar_limit_params) 5422 { 5423 wmi_buf_t buf; 5424 QDF_STATUS qdf_status; 5425 wmi_sar_limits_cmd_fixed_param *cmd; 5426 int i; 5427 uint8_t *buf_ptr; 5428 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5429 struct sar_limit_cmd_row *sar_rows_list; 5430 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5431 5432 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5433 buf = wmi_buf_alloc(wmi_handle, len); 5434 if (!buf) { 5435 WMI_LOGE("Failed to allocate memory"); 5436 qdf_status = QDF_STATUS_E_NOMEM; 5437 goto end; 5438 } 5439 5440 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5441 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5442 WMITLV_SET_HDR(&cmd->tlv_header, 5443 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5444 WMITLV_GET_STRUCT_TLVLEN 5445 (wmi_sar_limits_cmd_fixed_param)); 5446 cmd->sar_enable = sar_limit_params->sar_enable; 5447 cmd->commit_limits = sar_limit_params->commit_limits; 5448 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5449 5450 WMI_LOGD("no of sar rows = %d, len = %d", 5451 sar_limit_params->num_limit_rows, len); 5452 buf_ptr += sizeof(*cmd); 5453 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5454 sizeof(wmi_sar_limit_cmd_row) * 5455 sar_limit_params->num_limit_rows); 5456 if (cmd->num_limit_rows == 0) 5457 goto send_sar_limits; 5458 5459 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5460 (buf_ptr + WMI_TLV_HDR_SIZE); 5461 sar_rows_list = sar_limit_params->sar_limit_row_list; 5462 5463 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5464 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5465 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5466 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5467 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5468 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5469 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5470 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5471 wmi_sar_rows_list->validity_bitmap = 5472 sar_rows_list->validity_bitmap; 5473 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5474 i, wmi_sar_rows_list->band_id, 5475 wmi_sar_rows_list->chain_id, 5476 wmi_sar_rows_list->mod_id, 5477 wmi_sar_rows_list->limit_value, 5478 wmi_sar_rows_list->validity_bitmap); 5479 sar_rows_list++; 5480 wmi_sar_rows_list++; 5481 } 5482 send_sar_limits: 5483 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5484 WMI_SAR_LIMITS_CMDID); 5485 5486 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5487 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5488 wmi_buf_free(buf); 5489 } 5490 5491 end: 5492 return qdf_status; 5493 } 5494 5495 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5496 { 5497 wmi_sar_get_limits_cmd_fixed_param *cmd; 5498 wmi_buf_t wmi_buf; 5499 uint32_t len; 5500 QDF_STATUS status; 5501 5502 WMI_LOGD(FL("Enter")); 5503 5504 len = sizeof(*cmd); 5505 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5506 if (!wmi_buf) { 5507 WMI_LOGP(FL("failed to allocate memory for msg")); 5508 return QDF_STATUS_E_NOMEM; 5509 } 5510 5511 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5512 5513 WMITLV_SET_HDR(&cmd->tlv_header, 5514 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5515 WMITLV_GET_STRUCT_TLVLEN 5516 (wmi_sar_get_limits_cmd_fixed_param)); 5517 5518 cmd->reserved = 0; 5519 5520 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5521 WMI_SAR_GET_LIMITS_CMDID); 5522 if (QDF_IS_STATUS_ERROR(status)) { 5523 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5524 wmi_buf_free(wmi_buf); 5525 } 5526 5527 WMI_LOGD(FL("Exit")); 5528 5529 return status; 5530 } 5531 5532 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5533 uint8_t *evt_buf, 5534 struct sar_limit_event *event) 5535 { 5536 wmi_sar_get_limits_event_fixed_param *fixed_param; 5537 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5538 wmi_sar_get_limit_event_row *row_in; 5539 struct sar_limit_event_row *row_out; 5540 uint32_t row; 5541 5542 if (!evt_buf) { 5543 WMI_LOGE(FL("input event is NULL")); 5544 return QDF_STATUS_E_INVAL; 5545 } 5546 if (!event) { 5547 WMI_LOGE(FL("output event is NULL")); 5548 return QDF_STATUS_E_INVAL; 5549 } 5550 5551 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5552 5553 fixed_param = param_buf->fixed_param; 5554 if (!fixed_param) { 5555 WMI_LOGE(FL("Invalid fixed param")); 5556 return QDF_STATUS_E_INVAL; 5557 } 5558 5559 event->sar_enable = fixed_param->sar_enable; 5560 event->num_limit_rows = fixed_param->num_limit_rows; 5561 5562 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5563 QDF_ASSERT(0); 5564 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5565 event->num_limit_rows, 5566 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5567 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5568 } 5569 5570 row_in = param_buf->sar_get_limits; 5571 row_out = &event->sar_limit_row[0]; 5572 for (row = 0; row < event->num_limit_rows; row++) { 5573 row_out->band_id = row_in->band_id; 5574 row_out->chain_id = row_in->chain_id; 5575 row_out->mod_id = row_in->mod_id; 5576 row_out->limit_value = row_in->limit_value; 5577 row_out++; 5578 row_in++; 5579 } 5580 5581 return QDF_STATUS_SUCCESS; 5582 } 5583 5584 #ifdef WLAN_FEATURE_DISA 5585 /** 5586 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5587 * @wmi_handle: wmi handle 5588 * @params: encrypt/decrypt params 5589 * 5590 * Return: QDF_STATUS_SUCCESS for success or error code 5591 */ 5592 static 5593 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5594 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5595 { 5596 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5597 wmi_buf_t wmi_buf; 5598 uint8_t *buf_ptr; 5599 QDF_STATUS ret; 5600 uint32_t len; 5601 5602 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5603 5604 len = sizeof(*cmd) + 5605 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5606 WMI_TLV_HDR_SIZE; 5607 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5608 if (!wmi_buf) { 5609 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5610 __func__); 5611 return QDF_STATUS_E_NOMEM; 5612 } 5613 5614 buf_ptr = wmi_buf_data(wmi_buf); 5615 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5616 5617 WMITLV_SET_HDR(&cmd->tlv_header, 5618 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5619 WMITLV_GET_STRUCT_TLVLEN( 5620 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5621 5622 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5623 cmd->key_flag = encrypt_decrypt_params->key_flag; 5624 cmd->key_idx = encrypt_decrypt_params->key_idx; 5625 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5626 cmd->key_len = encrypt_decrypt_params->key_len; 5627 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5628 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5629 5630 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5631 encrypt_decrypt_params->key_len); 5632 5633 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5634 MAX_MAC_HEADER_LEN); 5635 5636 cmd->data_len = encrypt_decrypt_params->data_len; 5637 5638 if (cmd->data_len) { 5639 buf_ptr += sizeof(*cmd); 5640 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5641 roundup(encrypt_decrypt_params->data_len, 5642 sizeof(uint32_t))); 5643 buf_ptr += WMI_TLV_HDR_SIZE; 5644 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5645 encrypt_decrypt_params->data_len); 5646 } 5647 5648 /* This conversion is to facilitate data to FW in little endian */ 5649 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5650 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5651 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5652 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5653 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5654 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5655 5656 ret = wmi_unified_cmd_send(wmi_handle, 5657 wmi_buf, len, 5658 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5659 if (QDF_IS_STATUS_ERROR(ret)) { 5660 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5661 wmi_buf_free(wmi_buf); 5662 } 5663 5664 return ret; 5665 } 5666 5667 /** 5668 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5669 * params from event 5670 * @wmi_handle: wmi handle 5671 * @evt_buf: pointer to event buffer 5672 * @resp: Pointer to hold resp parameters 5673 * 5674 * Return: QDF_STATUS_SUCCESS for success or error code 5675 */ 5676 static 5677 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5678 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5679 { 5680 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5681 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5682 5683 param_buf = evt_buf; 5684 if (!param_buf) { 5685 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5686 return QDF_STATUS_E_INVAL; 5687 } 5688 5689 data_event = param_buf->fixed_param; 5690 5691 resp->vdev_id = data_event->vdev_id; 5692 resp->status = data_event->status; 5693 5694 if (data_event->data_length > param_buf->num_enc80211_frame) { 5695 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5696 data_event->data_length, 5697 param_buf->num_enc80211_frame); 5698 return QDF_STATUS_E_INVAL; 5699 } 5700 5701 resp->data_len = data_event->data_length; 5702 5703 if (resp->data_len) 5704 resp->data = (uint8_t *)param_buf->enc80211_frame; 5705 5706 return QDF_STATUS_SUCCESS; 5707 } 5708 #endif 5709 5710 /** 5711 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5712 * @wmi_handle: wmi handle 5713 * @vdev_id: vdev id 5714 * @p2p_ie: p2p IE 5715 * 5716 * Return: QDF_STATUS_SUCCESS for success or error code 5717 */ 5718 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5719 uint32_t vdev_id, uint8_t *p2p_ie) 5720 { 5721 QDF_STATUS ret; 5722 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5723 wmi_buf_t wmi_buf; 5724 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5725 uint8_t *buf_ptr; 5726 5727 ie_len = (uint32_t) (p2p_ie[1] + 2); 5728 5729 /* More than one P2P IE may be included in a single frame. 5730 If multiple P2P IEs are present, the complete P2P attribute 5731 data consists of the concatenation of the P2P Attribute 5732 fields of the P2P IEs. The P2P Attributes field of each 5733 P2P IE may be any length up to the maximum (251 octets). 5734 In this case host sends one P2P IE to firmware so the length 5735 should not exceed more than 251 bytes 5736 */ 5737 if (ie_len > 251) { 5738 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5739 return QDF_STATUS_E_INVAL; 5740 } 5741 5742 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5743 5744 wmi_buf_len = 5745 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5746 WMI_TLV_HDR_SIZE; 5747 5748 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5749 if (!wmi_buf) { 5750 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5751 return QDF_STATUS_E_NOMEM; 5752 } 5753 5754 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5755 5756 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5757 WMITLV_SET_HDR(&cmd->tlv_header, 5758 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5759 WMITLV_GET_STRUCT_TLVLEN 5760 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5761 cmd->vdev_id = vdev_id; 5762 cmd->ie_buf_len = ie_len; 5763 5764 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5765 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5766 buf_ptr += WMI_TLV_HDR_SIZE; 5767 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5768 5769 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 5770 5771 ret = wmi_unified_cmd_send(wmi_handle, 5772 wmi_buf, wmi_buf_len, 5773 WMI_P2P_GO_SET_BEACON_IE); 5774 if (QDF_IS_STATUS_ERROR(ret)) { 5775 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 5776 wmi_buf_free(wmi_buf); 5777 } 5778 5779 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 5780 return ret; 5781 } 5782 5783 /** 5784 * send_set_gateway_params_cmd_tlv() - set gateway parameters 5785 * @wmi_handle: wmi handle 5786 * @req: gateway parameter update request structure 5787 * 5788 * This function reads the incoming @req and fill in the destination 5789 * WMI structure and sends down the gateway configs down to the firmware 5790 * 5791 * Return: QDF_STATUS 5792 */ 5793 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 5794 struct gateway_update_req_param *req) 5795 { 5796 wmi_roam_subnet_change_config_fixed_param *cmd; 5797 wmi_buf_t buf; 5798 QDF_STATUS ret; 5799 int len = sizeof(*cmd); 5800 5801 buf = wmi_buf_alloc(wmi_handle, len); 5802 if (!buf) { 5803 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5804 return QDF_STATUS_E_NOMEM; 5805 } 5806 5807 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 5808 WMITLV_SET_HDR(&cmd->tlv_header, 5809 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 5810 WMITLV_GET_STRUCT_TLVLEN( 5811 wmi_roam_subnet_change_config_fixed_param)); 5812 5813 cmd->vdev_id = req->session_id; 5814 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 5815 QDF_IPV4_ADDR_SIZE); 5816 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 5817 QDF_IPV6_ADDR_SIZE); 5818 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 5819 &cmd->inet_gw_mac_addr); 5820 cmd->max_retries = req->max_retries; 5821 cmd->timeout = req->timeout; 5822 cmd->num_skip_subnet_change_detection_bssid_list = 0; 5823 cmd->flag = 0; 5824 if (req->ipv4_addr_type) 5825 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 5826 5827 if (req->ipv6_addr_type) 5828 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 5829 5830 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5831 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 5832 if (QDF_IS_STATUS_ERROR(ret)) { 5833 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 5834 ret); 5835 wmi_buf_free(buf); 5836 } 5837 5838 return ret; 5839 } 5840 5841 /** 5842 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 5843 * @wmi_handle: wmi handle 5844 * @req: rssi monitoring request structure 5845 * 5846 * This function reads the incoming @req and fill in the destination 5847 * WMI structure and send down the rssi monitoring configs down to the firmware 5848 * 5849 * Return: 0 on success; error number otherwise 5850 */ 5851 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 5852 struct rssi_monitor_param *req) 5853 { 5854 wmi_rssi_breach_monitor_config_fixed_param *cmd; 5855 wmi_buf_t buf; 5856 QDF_STATUS ret; 5857 uint32_t len = sizeof(*cmd); 5858 5859 buf = wmi_buf_alloc(wmi_handle, len); 5860 if (!buf) { 5861 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5862 return QDF_STATUS_E_NOMEM; 5863 } 5864 5865 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 5866 WMITLV_SET_HDR(&cmd->tlv_header, 5867 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 5868 WMITLV_GET_STRUCT_TLVLEN( 5869 wmi_rssi_breach_monitor_config_fixed_param)); 5870 5871 cmd->vdev_id = req->session_id; 5872 cmd->request_id = req->request_id; 5873 cmd->lo_rssi_reenable_hysteresis = 0; 5874 cmd->hi_rssi_reenable_histeresis = 0; 5875 cmd->min_report_interval = 0; 5876 cmd->max_num_report = 1; 5877 if (req->control) { 5878 /* enable one threshold for each min/max */ 5879 cmd->enabled_bitmap = 0x09; 5880 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 5881 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 5882 } else { 5883 cmd->enabled_bitmap = 0; 5884 cmd->low_rssi_breach_threshold[0] = 0; 5885 cmd->hi_rssi_breach_threshold[0] = 0; 5886 } 5887 5888 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5889 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 5890 if (QDF_IS_STATUS_ERROR(ret)) { 5891 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 5892 wmi_buf_free(buf); 5893 } 5894 5895 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 5896 5897 return ret; 5898 } 5899 5900 /** 5901 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5902 * @wmi_handle: wmi handle 5903 * @psetoui: OUI parameters 5904 * 5905 * set scan probe OUI parameters in firmware 5906 * 5907 * Return: CDF status 5908 */ 5909 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5910 struct scan_mac_oui *psetoui) 5911 { 5912 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5913 wmi_buf_t wmi_buf; 5914 uint32_t len; 5915 uint8_t *buf_ptr; 5916 uint32_t *oui_buf; 5917 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 5918 5919 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5920 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 5921 5922 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5923 if (!wmi_buf) { 5924 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5925 return QDF_STATUS_E_NOMEM; 5926 } 5927 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5928 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5929 WMITLV_SET_HDR(&cmd->tlv_header, 5930 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5931 WMITLV_GET_STRUCT_TLVLEN 5932 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5933 5934 oui_buf = &cmd->prob_req_oui; 5935 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5936 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5937 | psetoui->oui[2]; 5938 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 5939 cmd->prob_req_oui); 5940 5941 cmd->vdev_id = psetoui->vdev_id; 5942 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5943 if (psetoui->enb_probe_req_sno_randomization) 5944 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5945 5946 if (ie_whitelist->white_list) { 5947 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5948 &cmd->num_vendor_oui, 5949 ie_whitelist); 5950 cmd->flags |= 5951 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5952 } 5953 5954 buf_ptr += sizeof(*cmd); 5955 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5956 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5957 buf_ptr += WMI_TLV_HDR_SIZE; 5958 5959 if (cmd->num_vendor_oui != 0) { 5960 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5961 ie_whitelist->voui); 5962 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5963 } 5964 5965 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5966 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5967 WMI_LOGE("%s: failed to send command", __func__); 5968 wmi_buf_free(wmi_buf); 5969 return QDF_STATUS_E_FAILURE; 5970 } 5971 return QDF_STATUS_SUCCESS; 5972 } 5973 5974 /** 5975 * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list 5976 * @wmi_handle: wmi handle 5977 * @req: passpoint network request structure 5978 * 5979 * This function sends down WMI command with network id set to wildcard id. 5980 * firmware shall clear all the config entries 5981 * 5982 * Return: QDF_STATUS enumeration 5983 */ 5984 static QDF_STATUS send_reset_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 5985 struct wifi_passpoint_req_param *req) 5986 { 5987 wmi_passpoint_config_cmd_fixed_param *cmd; 5988 wmi_buf_t buf; 5989 uint32_t len; 5990 int ret; 5991 5992 len = sizeof(*cmd); 5993 buf = wmi_buf_alloc(wmi_handle, len); 5994 if (!buf) { 5995 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 5996 return QDF_STATUS_E_NOMEM; 5997 } 5998 5999 cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf); 6000 6001 WMITLV_SET_HDR(&cmd->tlv_header, 6002 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 6003 WMITLV_GET_STRUCT_TLVLEN( 6004 wmi_passpoint_config_cmd_fixed_param)); 6005 cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD; 6006 6007 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6008 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6009 if (ret) { 6010 WMI_LOGE("%s: Failed to send reset passpoint network list wmi cmd", 6011 __func__); 6012 wmi_buf_free(buf); 6013 return QDF_STATUS_E_FAILURE; 6014 } 6015 6016 return QDF_STATUS_SUCCESS; 6017 } 6018 6019 /** 6020 * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list 6021 * @wmi_handle: wmi handle 6022 * @req: passpoint network request structure 6023 * 6024 * This function reads the incoming @req and fill in the destination 6025 * WMI structure and send down the passpoint configs down to the firmware 6026 * 6027 * Return: QDF_STATUS enumeration 6028 */ 6029 static QDF_STATUS send_set_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 6030 struct wifi_passpoint_req_param *req) 6031 { 6032 wmi_passpoint_config_cmd_fixed_param *cmd; 6033 u_int8_t i, j, *bytes; 6034 wmi_buf_t buf; 6035 uint32_t len; 6036 int ret; 6037 6038 len = sizeof(*cmd); 6039 for (i = 0; i < req->num_networks; i++) { 6040 buf = wmi_buf_alloc(wmi_handle, len); 6041 if (!buf) { 6042 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 6043 return QDF_STATUS_E_NOMEM; 6044 } 6045 6046 cmd = (wmi_passpoint_config_cmd_fixed_param *) 6047 wmi_buf_data(buf); 6048 6049 WMITLV_SET_HDR(&cmd->tlv_header, 6050 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 6051 WMITLV_GET_STRUCT_TLVLEN( 6052 wmi_passpoint_config_cmd_fixed_param)); 6053 cmd->id = req->networks[i].id; 6054 WMI_LOGD("%s: network id: %u", __func__, cmd->id); 6055 qdf_mem_copy(cmd->realm, req->networks[i].realm, 6056 strlen(req->networks[i].realm) + 1); 6057 WMI_LOGD("%s: realm: %s", __func__, cmd->realm); 6058 for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) { 6059 bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j]; 6060 WMI_LOGD("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x", 6061 j, bytes[0], bytes[1], bytes[2], bytes[3], 6062 bytes[4], bytes[5], bytes[6], bytes[7]); 6063 6064 qdf_mem_copy(&cmd->roaming_consortium_ids[j], 6065 &req->networks[i].roaming_consortium_ids[j], 6066 PASSPOINT_ROAMING_CONSORTIUM_ID_LEN); 6067 } 6068 qdf_mem_copy(cmd->plmn, req->networks[i].plmn, 6069 PASSPOINT_PLMN_ID_LEN); 6070 WMI_LOGD("%s: plmn: %02x:%02x:%02x", __func__, 6071 cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]); 6072 6073 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6074 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6075 if (ret) { 6076 WMI_LOGE("%s: Failed to send set passpoint network list wmi cmd", 6077 __func__); 6078 wmi_buf_free(buf); 6079 return QDF_STATUS_E_FAILURE; 6080 } 6081 } 6082 6083 return QDF_STATUS_SUCCESS; 6084 } 6085 6086 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6087 /** 6088 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6089 * @wmi_handle: wmi handle 6090 * @roam_req: Roam scan offload params 6091 * @buf_ptr: command buffer to send 6092 * @fils_tlv_len: fils tlv length 6093 * 6094 * Return: Updated buffer pointer 6095 */ 6096 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6097 struct roam_offload_scan_params *roam_req, 6098 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6099 { 6100 wmi_roam_fils_offload_tlv_param *fils_tlv; 6101 wmi_erp_info *erp_info; 6102 struct roam_fils_params *roam_fils_params; 6103 6104 if (!roam_req->add_fils_tlv) 6105 return buf_ptr; 6106 6107 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6108 sizeof(*fils_tlv)); 6109 buf_ptr += WMI_TLV_HDR_SIZE; 6110 6111 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6112 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6113 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6114 WMITLV_GET_STRUCT_TLVLEN 6115 (wmi_roam_fils_offload_tlv_param)); 6116 6117 roam_fils_params = &roam_req->roam_fils_params; 6118 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6119 6120 erp_info->username_length = roam_fils_params->username_length; 6121 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6122 erp_info->username_length); 6123 6124 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6125 6126 erp_info->rRk_length = roam_fils_params->rrk_length; 6127 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6128 erp_info->rRk_length); 6129 6130 erp_info->rIk_length = roam_fils_params->rik_length; 6131 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6132 erp_info->rIk_length); 6133 6134 erp_info->realm_len = roam_fils_params->realm_len; 6135 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6136 erp_info->realm_len); 6137 6138 buf_ptr += sizeof(*fils_tlv); 6139 return buf_ptr; 6140 } 6141 #else 6142 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6143 struct roam_offload_scan_params *roam_req, 6144 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6145 { 6146 return buf_ptr; 6147 } 6148 #endif 6149 /** 6150 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6151 * @wmi_handle: wmi handle 6152 * @scan_cmd_fp: start scan command ptr 6153 * @roam_req: roam request param 6154 * 6155 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6156 * of WMI_ROAM_SCAN_MODE. 6157 * 6158 * Return: QDF status 6159 */ 6160 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6161 wmi_start_scan_cmd_fixed_param * 6162 scan_cmd_fp, 6163 struct roam_offload_scan_params *roam_req) 6164 { 6165 wmi_buf_t buf = NULL; 6166 QDF_STATUS status; 6167 int len; 6168 uint8_t *buf_ptr; 6169 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6170 6171 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6172 int auth_mode = roam_req->auth_mode; 6173 wmi_roam_offload_tlv_param *roam_offload_params; 6174 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6175 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6176 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6177 wmi_tlv_buf_len_param *assoc_ies; 6178 uint32_t fils_tlv_len = 0; 6179 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6180 /* Need to create a buf with roam_scan command at 6181 * front and piggyback with scan command */ 6182 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6183 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6184 (2 * WMI_TLV_HDR_SIZE) + 6185 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6186 sizeof(wmi_start_scan_cmd_fixed_param); 6187 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6188 WMI_LOGD("auth_mode = %d", auth_mode); 6189 if (roam_req->is_roam_req_valid && 6190 roam_req->roam_offload_enabled) { 6191 len += sizeof(wmi_roam_offload_tlv_param); 6192 len += WMI_TLV_HDR_SIZE; 6193 if ((auth_mode != WMI_AUTH_NONE) && 6194 ((auth_mode != WMI_AUTH_OPEN) || 6195 (auth_mode == WMI_AUTH_OPEN && 6196 roam_req->mdid.mdie_present && 6197 roam_req->is_11r_assoc) || 6198 roam_req->is_ese_assoc)) { 6199 len += WMI_TLV_HDR_SIZE; 6200 if (roam_req->is_ese_assoc) 6201 len += 6202 sizeof(wmi_roam_ese_offload_tlv_param); 6203 else if (auth_mode == WMI_AUTH_FT_RSNA || 6204 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6205 (auth_mode == WMI_AUTH_OPEN && 6206 roam_req->mdid.mdie_present && 6207 roam_req->is_11r_assoc)) 6208 len += 6209 sizeof(wmi_roam_11r_offload_tlv_param); 6210 else 6211 len += 6212 sizeof(wmi_roam_11i_offload_tlv_param); 6213 } else { 6214 len += WMI_TLV_HDR_SIZE; 6215 } 6216 6217 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6218 + roundup(roam_req->assoc_ie_length, 6219 sizeof(uint32_t))); 6220 6221 if (roam_req->add_fils_tlv) { 6222 fils_tlv_len = sizeof( 6223 wmi_roam_fils_offload_tlv_param); 6224 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6225 } 6226 } else { 6227 if (roam_req->is_roam_req_valid) 6228 WMI_LOGD("%s : roam offload = %d", 6229 __func__, roam_req->roam_offload_enabled); 6230 else 6231 WMI_LOGD("%s : roam_req is NULL", __func__); 6232 len += (4 * WMI_TLV_HDR_SIZE); 6233 } 6234 if (roam_req->is_roam_req_valid && 6235 roam_req->roam_offload_enabled) { 6236 roam_req->mode = roam_req->mode | 6237 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6238 } 6239 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6240 6241 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6242 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6243 len = sizeof(wmi_roam_scan_mode_fixed_param); 6244 6245 buf = wmi_buf_alloc(wmi_handle, len); 6246 if (!buf) { 6247 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6248 return QDF_STATUS_E_NOMEM; 6249 } 6250 6251 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6252 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6253 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6254 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6255 WMITLV_GET_STRUCT_TLVLEN 6256 (wmi_roam_scan_mode_fixed_param)); 6257 6258 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6259 roam_req->roam_trigger_reason_bitmask; 6260 roam_scan_mode_fp->min_delay_btw_scans = 6261 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6262 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6263 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6264 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6265 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6266 roam_scan_mode_fp->flags |= 6267 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6268 goto send_roam_scan_mode_cmd; 6269 } 6270 6271 /* Fill in scan parameters suitable for roaming scan */ 6272 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6273 6274 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6275 sizeof(wmi_start_scan_cmd_fixed_param)); 6276 /* Ensure there is no additional IEs */ 6277 scan_cmd_fp->ie_len = 0; 6278 WMITLV_SET_HDR(buf_ptr, 6279 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6280 WMITLV_GET_STRUCT_TLVLEN 6281 (wmi_start_scan_cmd_fixed_param)); 6282 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6283 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6284 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6285 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6286 sizeof(wmi_roam_offload_tlv_param)); 6287 buf_ptr += WMI_TLV_HDR_SIZE; 6288 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6289 WMITLV_SET_HDR(buf_ptr, 6290 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6291 WMITLV_GET_STRUCT_TLVLEN 6292 (wmi_roam_offload_tlv_param)); 6293 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6294 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6295 roam_offload_params->select_5g_margin = 6296 roam_req->select_5ghz_margin; 6297 roam_offload_params->handoff_delay_for_rx = 6298 roam_req->roam_offload_params.ho_delay_for_rx; 6299 roam_offload_params->reassoc_failure_timeout = 6300 roam_req->reassoc_failure_timeout; 6301 6302 /* Fill the capabilities */ 6303 roam_offload_params->capability = 6304 roam_req->roam_offload_params.capability; 6305 roam_offload_params->ht_caps_info = 6306 roam_req->roam_offload_params.ht_caps_info; 6307 roam_offload_params->ampdu_param = 6308 roam_req->roam_offload_params.ampdu_param; 6309 roam_offload_params->ht_ext_cap = 6310 roam_req->roam_offload_params.ht_ext_cap; 6311 roam_offload_params->ht_txbf = 6312 roam_req->roam_offload_params.ht_txbf; 6313 roam_offload_params->asel_cap = 6314 roam_req->roam_offload_params.asel_cap; 6315 roam_offload_params->qos_caps = 6316 roam_req->roam_offload_params.qos_caps; 6317 roam_offload_params->qos_enabled = 6318 roam_req->roam_offload_params.qos_enabled; 6319 roam_offload_params->wmm_caps = 6320 roam_req->roam_offload_params.wmm_caps; 6321 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6322 (uint8_t *)roam_req->roam_offload_params.mcsset, 6323 ROAM_OFFLOAD_NUM_MCS_SET); 6324 6325 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6326 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6327 * they are filled in the same order.Depending on the 6328 * authentication type, the other mode TLV's are nullified 6329 * and only headers are filled.*/ 6330 if ((auth_mode != WMI_AUTH_NONE) && 6331 ((auth_mode != WMI_AUTH_OPEN) || 6332 (auth_mode == WMI_AUTH_OPEN 6333 && roam_req->mdid.mdie_present && 6334 roam_req->is_11r_assoc) || 6335 roam_req->is_ese_assoc)) { 6336 if (roam_req->is_ese_assoc) { 6337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6338 WMITLV_GET_STRUCT_TLVLEN(0)); 6339 buf_ptr += WMI_TLV_HDR_SIZE; 6340 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6341 WMITLV_GET_STRUCT_TLVLEN(0)); 6342 buf_ptr += WMI_TLV_HDR_SIZE; 6343 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6344 sizeof(wmi_roam_ese_offload_tlv_param)); 6345 buf_ptr += WMI_TLV_HDR_SIZE; 6346 roam_offload_ese = 6347 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6348 qdf_mem_copy(roam_offload_ese->krk, 6349 roam_req->krk, 6350 sizeof(roam_req->krk)); 6351 qdf_mem_copy(roam_offload_ese->btk, 6352 roam_req->btk, 6353 sizeof(roam_req->btk)); 6354 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6355 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6356 WMITLV_GET_STRUCT_TLVLEN 6357 (wmi_roam_ese_offload_tlv_param)); 6358 buf_ptr += 6359 sizeof(wmi_roam_ese_offload_tlv_param); 6360 } else if (auth_mode == WMI_AUTH_FT_RSNA 6361 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6362 || (auth_mode == WMI_AUTH_OPEN 6363 && roam_req->mdid.mdie_present && 6364 roam_req->is_11r_assoc)) { 6365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6366 0); 6367 buf_ptr += WMI_TLV_HDR_SIZE; 6368 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6369 sizeof(wmi_roam_11r_offload_tlv_param)); 6370 buf_ptr += WMI_TLV_HDR_SIZE; 6371 roam_offload_11r = 6372 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6373 roam_offload_11r->r0kh_id_len = 6374 roam_req->rokh_id_length; 6375 qdf_mem_copy(roam_offload_11r->r0kh_id, 6376 roam_req->rokh_id, 6377 roam_offload_11r->r0kh_id_len); 6378 qdf_mem_copy(roam_offload_11r->psk_msk, 6379 roam_req->psk_pmk, 6380 sizeof(roam_req->psk_pmk)); 6381 roam_offload_11r->psk_msk_len = 6382 roam_req->pmk_len; 6383 roam_offload_11r->mdie_present = 6384 roam_req->mdid.mdie_present; 6385 roam_offload_11r->mdid = 6386 roam_req->mdid.mobility_domain; 6387 if (auth_mode == WMI_AUTH_OPEN) { 6388 /* If FT-Open ensure pmk length 6389 and r0khid len are zero */ 6390 roam_offload_11r->r0kh_id_len = 0; 6391 roam_offload_11r->psk_msk_len = 0; 6392 } 6393 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6394 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6395 WMITLV_GET_STRUCT_TLVLEN 6396 (wmi_roam_11r_offload_tlv_param)); 6397 buf_ptr += 6398 sizeof(wmi_roam_11r_offload_tlv_param); 6399 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6400 WMITLV_GET_STRUCT_TLVLEN(0)); 6401 buf_ptr += WMI_TLV_HDR_SIZE; 6402 WMI_LOGD("psk_msk_len = %d", 6403 roam_offload_11r->psk_msk_len); 6404 if (roam_offload_11r->psk_msk_len) 6405 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6406 QDF_TRACE_LEVEL_DEBUG, 6407 roam_offload_11r->psk_msk, 6408 roam_offload_11r->psk_msk_len); 6409 } else { 6410 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6411 sizeof(wmi_roam_11i_offload_tlv_param)); 6412 buf_ptr += WMI_TLV_HDR_SIZE; 6413 roam_offload_11i = 6414 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6415 6416 if (roam_req->roam_key_mgmt_offload_enabled && 6417 roam_req->fw_okc) { 6418 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6419 (roam_offload_11i->flags); 6420 WMI_LOGI("LFR3:OKC enabled"); 6421 } else { 6422 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6423 (roam_offload_11i->flags); 6424 WMI_LOGI("LFR3:OKC disabled"); 6425 } 6426 if (roam_req->roam_key_mgmt_offload_enabled && 6427 roam_req->fw_pmksa_cache) { 6428 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6429 (roam_offload_11i->flags); 6430 WMI_LOGI("LFR3:PMKSA caching enabled"); 6431 } else { 6432 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6433 (roam_offload_11i->flags); 6434 WMI_LOGI("LFR3:PMKSA caching disabled"); 6435 } 6436 6437 qdf_mem_copy(roam_offload_11i->pmk, 6438 roam_req->psk_pmk, 6439 sizeof(roam_req->psk_pmk)); 6440 roam_offload_11i->pmk_len = roam_req->pmk_len; 6441 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6442 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6443 WMITLV_GET_STRUCT_TLVLEN 6444 (wmi_roam_11i_offload_tlv_param)); 6445 buf_ptr += 6446 sizeof(wmi_roam_11i_offload_tlv_param); 6447 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6448 0); 6449 buf_ptr += WMI_TLV_HDR_SIZE; 6450 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6451 0); 6452 buf_ptr += WMI_TLV_HDR_SIZE; 6453 WMI_LOGD("pmk_len = %d", 6454 roam_offload_11i->pmk_len); 6455 if (roam_offload_11i->pmk_len) 6456 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6457 QDF_TRACE_LEVEL_DEBUG, 6458 roam_offload_11i->pmk, 6459 roam_offload_11i->pmk_len); 6460 } 6461 } else { 6462 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6463 WMITLV_GET_STRUCT_TLVLEN(0)); 6464 buf_ptr += WMI_TLV_HDR_SIZE; 6465 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6466 WMITLV_GET_STRUCT_TLVLEN(0)); 6467 buf_ptr += WMI_TLV_HDR_SIZE; 6468 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6469 WMITLV_GET_STRUCT_TLVLEN(0)); 6470 buf_ptr += WMI_TLV_HDR_SIZE; 6471 } 6472 6473 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6474 sizeof(*assoc_ies)); 6475 buf_ptr += WMI_TLV_HDR_SIZE; 6476 6477 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6478 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6479 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6480 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6481 assoc_ies->buf_len = roam_req->assoc_ie_length; 6482 6483 buf_ptr += sizeof(*assoc_ies); 6484 6485 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6486 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6487 buf_ptr += WMI_TLV_HDR_SIZE; 6488 6489 if (assoc_ies->buf_len != 0) { 6490 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6491 assoc_ies->buf_len); 6492 } 6493 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6494 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6495 buf_ptr, fils_tlv_len); 6496 } else { 6497 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6498 WMITLV_GET_STRUCT_TLVLEN(0)); 6499 buf_ptr += WMI_TLV_HDR_SIZE; 6500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6501 WMITLV_GET_STRUCT_TLVLEN(0)); 6502 buf_ptr += WMI_TLV_HDR_SIZE; 6503 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6504 WMITLV_GET_STRUCT_TLVLEN(0)); 6505 buf_ptr += WMI_TLV_HDR_SIZE; 6506 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6507 WMITLV_GET_STRUCT_TLVLEN(0)); 6508 buf_ptr += WMI_TLV_HDR_SIZE; 6509 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6510 WMITLV_GET_STRUCT_TLVLEN(0)); 6511 buf_ptr += WMI_TLV_HDR_SIZE; 6512 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6513 WMITLV_GET_STRUCT_TLVLEN(0)); 6514 } 6515 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6516 6517 send_roam_scan_mode_cmd: 6518 status = wmi_unified_cmd_send(wmi_handle, buf, 6519 len, WMI_ROAM_SCAN_MODE); 6520 if (QDF_IS_STATUS_ERROR(status)) { 6521 WMI_LOGE( 6522 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6523 status); 6524 wmi_buf_free(buf); 6525 } 6526 6527 return status; 6528 } 6529 6530 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6531 struct wmi_mawc_roam_params *params) 6532 { 6533 wmi_buf_t buf = NULL; 6534 QDF_STATUS status; 6535 int len; 6536 uint8_t *buf_ptr; 6537 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6538 6539 len = sizeof(*wmi_roam_mawc_params); 6540 buf = wmi_buf_alloc(wmi_handle, len); 6541 if (!buf) { 6542 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6543 return QDF_STATUS_E_NOMEM; 6544 } 6545 6546 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6547 wmi_roam_mawc_params = 6548 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6549 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6550 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6551 WMITLV_GET_STRUCT_TLVLEN 6552 (wmi_roam_configure_mawc_cmd_fixed_param)); 6553 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6554 if (params->enable) 6555 wmi_roam_mawc_params->enable = 1; 6556 else 6557 wmi_roam_mawc_params->enable = 0; 6558 wmi_roam_mawc_params->traffic_load_threshold = 6559 params->traffic_load_threshold; 6560 wmi_roam_mawc_params->best_ap_rssi_threshold = 6561 params->best_ap_rssi_threshold; 6562 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6563 params->rssi_stationary_high_adjust; 6564 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6565 params->rssi_stationary_low_adjust; 6566 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6567 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6568 wmi_roam_mawc_params->traffic_load_threshold, 6569 wmi_roam_mawc_params->best_ap_rssi_threshold, 6570 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6571 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6572 6573 status = wmi_unified_cmd_send(wmi_handle, buf, 6574 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6575 if (QDF_IS_STATUS_ERROR(status)) { 6576 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6577 status); 6578 wmi_buf_free(buf); 6579 return status; 6580 } 6581 6582 return QDF_STATUS_SUCCESS; 6583 } 6584 6585 /** 6586 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6587 * rssi threashold 6588 * @wmi_handle: wmi handle 6589 * @roam_req: Roaming request buffer 6590 * 6591 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6592 * 6593 * Return: QDF status 6594 */ 6595 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6596 struct roam_offload_scan_rssi_params *roam_req) 6597 { 6598 wmi_buf_t buf = NULL; 6599 QDF_STATUS status; 6600 int len; 6601 uint8_t *buf_ptr; 6602 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6603 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6604 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6605 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6606 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6607 6608 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6609 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6610 len += sizeof(wmi_roam_scan_extended_threshold_param); 6611 len += WMI_TLV_HDR_SIZE; 6612 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6613 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6614 len += sizeof(wmi_roam_dense_thres_param); 6615 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6616 len += sizeof(wmi_roam_bg_scan_roaming_param); 6617 buf = wmi_buf_alloc(wmi_handle, len); 6618 if (!buf) { 6619 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6620 return QDF_STATUS_E_NOMEM; 6621 } 6622 6623 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6624 rssi_threshold_fp = 6625 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6626 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6627 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6628 WMITLV_GET_STRUCT_TLVLEN 6629 (wmi_roam_scan_rssi_threshold_fixed_param)); 6630 /* fill in threshold values */ 6631 rssi_threshold_fp->vdev_id = roam_req->session_id; 6632 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6633 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6634 rssi_threshold_fp->hirssi_scan_max_count = 6635 roam_req->hi_rssi_scan_max_count; 6636 rssi_threshold_fp->hirssi_scan_delta = 6637 roam_req->hi_rssi_scan_rssi_delta; 6638 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6639 rssi_threshold_fp->rssi_thresh_offset_5g = 6640 roam_req->rssi_thresh_offset_5g; 6641 6642 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6643 WMITLV_SET_HDR(buf_ptr, 6644 WMITLV_TAG_ARRAY_STRUC, 6645 sizeof(wmi_roam_scan_extended_threshold_param)); 6646 buf_ptr += WMI_TLV_HDR_SIZE; 6647 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6648 6649 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6650 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6651 ext_thresholds->boost_threshold_5g = 6652 roam_req->boost_threshold_5g; 6653 6654 ext_thresholds->boost_algorithm_5g = 6655 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6656 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6657 ext_thresholds->penalty_algorithm_5g = 6658 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6659 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6660 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6661 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6662 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6663 6664 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6665 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6666 WMITLV_GET_STRUCT_TLVLEN 6667 (wmi_roam_scan_extended_threshold_param)); 6668 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6669 WMITLV_SET_HDR(buf_ptr, 6670 WMITLV_TAG_ARRAY_STRUC, 6671 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6672 buf_ptr += WMI_TLV_HDR_SIZE; 6673 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6674 early_stop_thresholds->roam_earlystop_thres_min = 6675 roam_req->roam_earlystop_thres_min; 6676 early_stop_thresholds->roam_earlystop_thres_max = 6677 roam_req->roam_earlystop_thres_max; 6678 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6679 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6680 WMITLV_GET_STRUCT_TLVLEN 6681 (wmi_roam_earlystop_rssi_thres_param)); 6682 6683 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6684 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6685 sizeof(wmi_roam_dense_thres_param)); 6686 buf_ptr += WMI_TLV_HDR_SIZE; 6687 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6688 dense_thresholds->roam_dense_rssi_thres_offset = 6689 roam_req->dense_rssi_thresh_offset; 6690 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6691 dense_thresholds->roam_dense_traffic_thres = 6692 roam_req->traffic_threshold; 6693 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6694 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6695 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6696 WMITLV_GET_STRUCT_TLVLEN 6697 (wmi_roam_dense_thres_param)); 6698 6699 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6700 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6701 sizeof(wmi_roam_bg_scan_roaming_param)); 6702 buf_ptr += WMI_TLV_HDR_SIZE; 6703 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6704 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6705 roam_req->bg_scan_bad_rssi_thresh; 6706 bg_scan_params->roam_bg_scan_client_bitmap = 6707 roam_req->bg_scan_client_bitmap; 6708 bg_scan_params->bad_rssi_thresh_offset_2g = 6709 roam_req->roam_bad_rssi_thresh_offset_2g; 6710 bg_scan_params->flags = roam_req->flags; 6711 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6712 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6713 WMITLV_GET_STRUCT_TLVLEN 6714 (wmi_roam_bg_scan_roaming_param)); 6715 6716 status = wmi_unified_cmd_send(wmi_handle, buf, 6717 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6718 if (QDF_IS_STATUS_ERROR(status)) { 6719 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6720 status); 6721 wmi_buf_free(buf); 6722 } 6723 6724 return status; 6725 } 6726 6727 /** 6728 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6729 * configuration params 6730 * @wma_handle: wma handler 6731 * @dwelltime_params: pointer to dwelltime_params 6732 * 6733 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6734 */ 6735 static 6736 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6737 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6738 { 6739 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6740 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6741 wmi_buf_t buf; 6742 uint8_t *buf_ptr; 6743 int32_t err; 6744 int len; 6745 6746 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6747 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6748 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6749 buf = wmi_buf_alloc(wmi_handle, len); 6750 if (!buf) { 6751 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6752 __func__); 6753 return QDF_STATUS_E_NOMEM; 6754 } 6755 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6756 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6757 WMITLV_SET_HDR(&dwell_param->tlv_header, 6758 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6759 WMITLV_GET_STRUCT_TLVLEN 6760 (wmi_scan_adaptive_dwell_config_fixed_param)); 6761 6762 dwell_param->enable = dwelltime_params->is_enabled; 6763 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6764 WMITLV_SET_HDR(buf_ptr, 6765 WMITLV_TAG_ARRAY_STRUC, 6766 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6767 buf_ptr += WMI_TLV_HDR_SIZE; 6768 6769 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6770 WMITLV_SET_HDR(&cmd->tlv_header, 6771 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6772 WMITLV_GET_STRUCT_TLVLEN( 6773 wmi_scan_adaptive_dwell_parameters_tlv)); 6774 6775 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6776 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6777 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6778 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6779 err = wmi_unified_cmd_send(wmi_handle, buf, 6780 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6781 if (err) { 6782 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6783 wmi_buf_free(buf); 6784 return QDF_STATUS_E_FAILURE; 6785 } 6786 6787 return QDF_STATUS_SUCCESS; 6788 } 6789 6790 /** 6791 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6792 * configuration params 6793 * @wmi_handle: wmi handler 6794 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6795 * 6796 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6797 */ 6798 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6799 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6800 { 6801 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6802 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6803 wmi_buf_t buf; 6804 uint8_t *buf_ptr; 6805 QDF_STATUS err; 6806 uint32_t i; 6807 int len; 6808 6809 len = sizeof(*dbs_scan_param); 6810 len += WMI_TLV_HDR_SIZE; 6811 len += dbs_scan_params->num_clients * sizeof(*cmd); 6812 6813 buf = wmi_buf_alloc(wmi_handle, len); 6814 if (!buf) { 6815 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6816 return QDF_STATUS_E_NOMEM; 6817 } 6818 6819 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6820 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6821 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6822 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6823 WMITLV_GET_STRUCT_TLVLEN 6824 (wmi_scan_dbs_duty_cycle_fixed_param)); 6825 6826 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6827 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6828 buf_ptr += sizeof(*dbs_scan_param); 6829 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6830 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6831 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6832 6833 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6834 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6835 WMITLV_SET_HDR(&cmd->tlv_header, 6836 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6837 WMITLV_GET_STRUCT_TLVLEN( 6838 wmi_scan_dbs_duty_cycle_tlv_param)); 6839 cmd->module_id = dbs_scan_params->module_id[i]; 6840 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6841 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6842 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6843 } 6844 6845 err = wmi_unified_cmd_send(wmi_handle, buf, 6846 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6847 if (QDF_IS_STATUS_ERROR(err)) { 6848 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6849 wmi_buf_free(buf); 6850 return QDF_STATUS_E_FAILURE; 6851 } 6852 6853 return QDF_STATUS_SUCCESS; 6854 } 6855 6856 /** 6857 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6858 * @wmi_handle: wmi handle 6859 * @roam_req: Request which contains the filters 6860 * 6861 * There are filters such as whitelist, blacklist and preferred 6862 * list that need to be applied to the scan results to form the 6863 * probable candidates for roaming. 6864 * 6865 * Return: Return success upon succesfully passing the 6866 * parameters to the firmware, otherwise failure. 6867 */ 6868 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6869 struct roam_scan_filter_params *roam_req) 6870 { 6871 wmi_buf_t buf = NULL; 6872 QDF_STATUS status; 6873 uint32_t i; 6874 uint32_t len, blist_len = 0; 6875 uint8_t *buf_ptr; 6876 wmi_roam_filter_fixed_param *roam_filter; 6877 uint8_t *bssid_src_ptr = NULL; 6878 wmi_mac_addr *bssid_dst_ptr = NULL; 6879 wmi_ssid *ssid_ptr = NULL; 6880 uint32_t *bssid_preferred_factor_ptr = NULL; 6881 wmi_roam_lca_disallow_config_tlv_param *blist_param; 6882 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 6883 6884 len = sizeof(wmi_roam_filter_fixed_param); 6885 6886 len += WMI_TLV_HDR_SIZE; 6887 if (roam_req->num_bssid_black_list) 6888 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 6889 len += WMI_TLV_HDR_SIZE; 6890 if (roam_req->num_ssid_white_list) 6891 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 6892 len += 2 * WMI_TLV_HDR_SIZE; 6893 if (roam_req->num_bssid_preferred_list) { 6894 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 6895 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 6896 } 6897 len += WMI_TLV_HDR_SIZE; 6898 if (roam_req->lca_disallow_config_present) { 6899 len += sizeof(*blist_param); 6900 blist_len = sizeof(*blist_param); 6901 } 6902 6903 len += WMI_TLV_HDR_SIZE; 6904 if (roam_req->num_rssi_rejection_ap) 6905 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 6906 6907 buf = wmi_buf_alloc(wmi_handle, len); 6908 if (!buf) { 6909 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6910 return QDF_STATUS_E_NOMEM; 6911 } 6912 6913 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 6914 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 6915 WMITLV_SET_HDR(&roam_filter->tlv_header, 6916 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 6917 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 6918 /* fill in fixed values */ 6919 roam_filter->vdev_id = roam_req->session_id; 6920 roam_filter->flags = 0; 6921 roam_filter->op_bitmap = roam_req->op_bitmap; 6922 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 6923 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 6924 roam_filter->num_bssid_preferred_list = 6925 roam_req->num_bssid_preferred_list; 6926 roam_filter->num_rssi_rejection_ap = 6927 roam_req->num_rssi_rejection_ap; 6928 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 6929 6930 WMITLV_SET_HDR((buf_ptr), 6931 WMITLV_TAG_ARRAY_FIXED_STRUC, 6932 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 6933 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 6934 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6935 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 6936 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 6937 bssid_src_ptr += ATH_MAC_LEN; 6938 bssid_dst_ptr++; 6939 } 6940 buf_ptr += WMI_TLV_HDR_SIZE + 6941 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 6942 WMITLV_SET_HDR((buf_ptr), 6943 WMITLV_TAG_ARRAY_FIXED_STRUC, 6944 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 6945 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 6946 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 6947 qdf_mem_copy(&ssid_ptr->ssid, 6948 &roam_req->ssid_allowed_list[i].mac_ssid, 6949 roam_req->ssid_allowed_list[i].length); 6950 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 6951 ssid_ptr++; 6952 } 6953 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 6954 sizeof(wmi_ssid)); 6955 WMITLV_SET_HDR((buf_ptr), 6956 WMITLV_TAG_ARRAY_FIXED_STRUC, 6957 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 6958 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 6959 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6960 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6961 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 6962 (wmi_mac_addr *)bssid_dst_ptr); 6963 bssid_src_ptr += ATH_MAC_LEN; 6964 bssid_dst_ptr++; 6965 } 6966 buf_ptr += WMI_TLV_HDR_SIZE + 6967 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 6968 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6969 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 6970 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 6971 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6972 *bssid_preferred_factor_ptr = 6973 roam_req->bssid_favored_factor[i]; 6974 bssid_preferred_factor_ptr++; 6975 } 6976 buf_ptr += WMI_TLV_HDR_SIZE + 6977 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 6978 6979 WMITLV_SET_HDR(buf_ptr, 6980 WMITLV_TAG_ARRAY_STRUC, blist_len); 6981 buf_ptr += WMI_TLV_HDR_SIZE; 6982 if (roam_req->lca_disallow_config_present) { 6983 blist_param = 6984 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 6985 WMITLV_SET_HDR(&blist_param->tlv_header, 6986 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 6987 WMITLV_GET_STRUCT_TLVLEN( 6988 wmi_roam_lca_disallow_config_tlv_param)); 6989 6990 blist_param->disallow_duration = roam_req->disallow_duration; 6991 blist_param->rssi_channel_penalization = 6992 roam_req->rssi_channel_penalization; 6993 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 6994 blist_param->disallow_lca_enable_source_bitmap = 6995 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 6996 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 6997 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 6998 } 6999 7000 WMITLV_SET_HDR(buf_ptr, 7001 WMITLV_TAG_ARRAY_STRUC, 7002 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 7003 buf_ptr += WMI_TLV_HDR_SIZE; 7004 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 7005 rssi_rej = 7006 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 7007 WMITLV_SET_HDR(&rssi_rej->tlv_header, 7008 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7009 WMITLV_GET_STRUCT_TLVLEN( 7010 wmi_roam_rssi_rejection_oce_config_param)); 7011 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7012 roam_req->rssi_rejection_ap[i].bssid.bytes, 7013 &rssi_rej->bssid); 7014 rssi_rej->remaining_disallow_duration = 7015 roam_req->rssi_rejection_ap[i].remaining_duration; 7016 rssi_rej->requested_rssi = 7017 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 7018 buf_ptr += 7019 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7020 } 7021 7022 status = wmi_unified_cmd_send(wmi_handle, buf, 7023 len, WMI_ROAM_FILTER_CMDID); 7024 if (QDF_IS_STATUS_ERROR(status)) { 7025 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7026 status); 7027 wmi_buf_free(buf); 7028 } 7029 7030 return status; 7031 } 7032 7033 #if defined(WLAN_FEATURE_FILS_SK) 7034 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7035 struct hlp_params *params) 7036 { 7037 uint32_t len; 7038 uint8_t *buf_ptr; 7039 wmi_buf_t buf = NULL; 7040 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7041 7042 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7043 len += WMI_TLV_HDR_SIZE; 7044 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7045 7046 buf = wmi_buf_alloc(wmi_handle, len); 7047 if (!buf) { 7048 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7049 return QDF_STATUS_E_NOMEM; 7050 } 7051 7052 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7053 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7054 WMITLV_SET_HDR(&hlp_params->tlv_header, 7055 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7056 WMITLV_GET_STRUCT_TLVLEN( 7057 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7058 7059 hlp_params->vdev_id = params->vdev_id; 7060 hlp_params->size = params->hlp_ie_len; 7061 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7062 7063 buf_ptr += sizeof(*hlp_params); 7064 7065 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7066 round_up(params->hlp_ie_len, 7067 sizeof(uint32_t))); 7068 buf_ptr += WMI_TLV_HDR_SIZE; 7069 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7070 7071 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7072 hlp_params->vdev_id, hlp_params->size); 7073 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7074 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7075 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7076 wmi_buf_free(buf); 7077 return QDF_STATUS_E_FAILURE; 7078 } 7079 7080 return QDF_STATUS_SUCCESS; 7081 } 7082 #endif 7083 7084 /** send_set_epno_network_list_cmd_tlv() - set epno network list 7085 * @wmi_handle: wmi handle 7086 * @req: epno config params request structure 7087 * 7088 * This function reads the incoming epno config request structure 7089 * and constructs the WMI message to the firmware. 7090 * 7091 * Returns: 0 on success, error number otherwise 7092 */ 7093 static QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle, 7094 struct wifi_enhanched_pno_params *req) 7095 { 7096 wmi_nlo_config_cmd_fixed_param *cmd; 7097 nlo_configured_parameters *nlo_list; 7098 enlo_candidate_score_params *cand_score_params; 7099 u_int8_t i, *buf_ptr; 7100 wmi_buf_t buf; 7101 uint32_t len; 7102 QDF_STATUS ret; 7103 7104 /* Fixed Params */ 7105 len = sizeof(*cmd); 7106 if (req->num_networks) { 7107 /* TLV place holder for array of structures 7108 * then each nlo_configured_parameters(nlo_list) TLV. 7109 */ 7110 len += WMI_TLV_HDR_SIZE; 7111 len += (sizeof(nlo_configured_parameters) 7112 * QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS)); 7113 /* TLV for array of uint32 channel_list */ 7114 len += WMI_TLV_HDR_SIZE; 7115 /* TLV for nlo_channel_prediction_cfg */ 7116 len += WMI_TLV_HDR_SIZE; 7117 /* TLV for candidate score params */ 7118 len += sizeof(enlo_candidate_score_params); 7119 } 7120 7121 buf = wmi_buf_alloc(wmi_handle, len); 7122 if (!buf) { 7123 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7124 return QDF_STATUS_E_NOMEM; 7125 } 7126 7127 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7128 7129 buf_ptr = (u_int8_t *) cmd; 7130 WMITLV_SET_HDR(&cmd->tlv_header, 7131 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7132 WMITLV_GET_STRUCT_TLVLEN( 7133 wmi_nlo_config_cmd_fixed_param)); 7134 cmd->vdev_id = req->session_id; 7135 7136 /* set flag to reset if num of networks are 0 */ 7137 cmd->flags = (req->num_networks == 0 ? 7138 WMI_NLO_CONFIG_ENLO_RESET : WMI_NLO_CONFIG_ENLO); 7139 7140 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7141 7142 cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS); 7143 WMI_LOGD("SSID count: %d flags: %d", 7144 cmd->no_of_ssids, cmd->flags); 7145 7146 /* Fill nlo_config only when num_networks are non zero */ 7147 if (cmd->no_of_ssids) { 7148 /* Fill networks */ 7149 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7150 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7151 buf_ptr += WMI_TLV_HDR_SIZE; 7152 7153 nlo_list = (nlo_configured_parameters *) buf_ptr; 7154 for (i = 0; i < cmd->no_of_ssids; i++) { 7155 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7156 WMITLV_TAG_ARRAY_BYTE, 7157 WMITLV_GET_STRUCT_TLVLEN( 7158 nlo_configured_parameters)); 7159 /* Copy ssid and it's length */ 7160 nlo_list[i].ssid.valid = true; 7161 nlo_list[i].ssid.ssid.ssid_len = 7162 req->networks[i].ssid.length; 7163 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7164 req->networks[i].ssid.mac_ssid, 7165 nlo_list[i].ssid.ssid.ssid_len); 7166 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7167 nlo_list[i].ssid.ssid.ssid_len, 7168 (char *) nlo_list[i].ssid.ssid.ssid, 7169 nlo_list[i].ssid.ssid.ssid_len); 7170 7171 /* Copy pno flags */ 7172 nlo_list[i].bcast_nw_type.valid = true; 7173 nlo_list[i].bcast_nw_type.bcast_nw_type = 7174 req->networks[i].flags; 7175 WMI_LOGD("PNO flags (%u)", 7176 nlo_list[i].bcast_nw_type.bcast_nw_type); 7177 7178 /* Copy auth bit field */ 7179 nlo_list[i].auth_type.valid = true; 7180 nlo_list[i].auth_type.auth_type = 7181 req->networks[i].auth_bit_field; 7182 WMI_LOGD("Auth bit field (%u)", 7183 nlo_list[i].auth_type.auth_type); 7184 } 7185 7186 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7187 /* Fill the channel list */ 7188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7189 buf_ptr += WMI_TLV_HDR_SIZE; 7190 7191 /* Fill prediction_param */ 7192 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7193 buf_ptr += WMI_TLV_HDR_SIZE; 7194 7195 /* Fill epno candidate score params */ 7196 cand_score_params = (enlo_candidate_score_params *) buf_ptr; 7197 WMITLV_SET_HDR(buf_ptr, 7198 WMITLV_TAG_STRUC_enlo_candidate_score_param, 7199 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7200 cand_score_params->min5GHz_rssi = 7201 req->min_5ghz_rssi; 7202 cand_score_params->min24GHz_rssi = 7203 req->min_24ghz_rssi; 7204 cand_score_params->initial_score_max = 7205 req->initial_score_max; 7206 cand_score_params->current_connection_bonus = 7207 req->current_connection_bonus; 7208 cand_score_params->same_network_bonus = 7209 req->same_network_bonus; 7210 cand_score_params->secure_bonus = 7211 req->secure_bonus; 7212 cand_score_params->band5GHz_bonus = 7213 req->band_5ghz_bonus; 7214 buf_ptr += sizeof(enlo_candidate_score_params); 7215 } 7216 7217 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7218 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7219 if (QDF_IS_STATUS_ERROR(ret)) { 7220 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7221 wmi_buf_free(buf); 7222 return QDF_STATUS_E_INVAL; 7223 } 7224 7225 WMI_LOGD("set ePNO list request sent successfully for vdev %d", 7226 req->session_id); 7227 7228 return ret; 7229 } 7230 7231 #ifdef IPA_OFFLOAD 7232 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7233 * @wmi_handle: wmi handle 7234 * @ipa_offload: ipa offload control parameter 7235 * 7236 * Returns: 0 on success, error number otherwise 7237 */ 7238 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7239 struct ipa_uc_offload_control_params *ipa_offload) 7240 { 7241 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7242 wmi_buf_t wmi_buf; 7243 uint32_t len; 7244 u_int8_t *buf_ptr; 7245 7246 len = sizeof(*cmd); 7247 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7248 if (!wmi_buf) { 7249 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7250 return QDF_STATUS_E_NOMEM; 7251 } 7252 7253 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7254 ipa_offload->offload_type, ipa_offload->enable); 7255 7256 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7257 7258 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7259 WMITLV_SET_HDR(&cmd->tlv_header, 7260 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7261 WMITLV_GET_STRUCT_TLVLEN( 7262 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7263 7264 cmd->offload_type = ipa_offload->offload_type; 7265 cmd->vdev_id = ipa_offload->vdev_id; 7266 cmd->enable = ipa_offload->enable; 7267 7268 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7269 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7270 WMI_LOGE("%s: failed to command", __func__); 7271 wmi_buf_free(wmi_buf); 7272 return QDF_STATUS_E_FAILURE; 7273 } 7274 7275 return QDF_STATUS_SUCCESS; 7276 } 7277 #endif 7278 7279 /** 7280 * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities 7281 * @wmi_handle: wmi handle 7282 * @pgetcapab: get capabilities params 7283 * 7284 * This function send request to fw to get extscan capabilities. 7285 * 7286 * Return: CDF status 7287 */ 7288 static QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle, 7289 struct extscan_capabilities_params *pgetcapab) 7290 { 7291 wmi_extscan_get_capabilities_cmd_fixed_param *cmd; 7292 wmi_buf_t wmi_buf; 7293 uint32_t len; 7294 uint8_t *buf_ptr; 7295 7296 len = sizeof(*cmd); 7297 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7298 if (!wmi_buf) { 7299 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7300 return QDF_STATUS_E_NOMEM; 7301 } 7302 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7303 7304 cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr; 7305 WMITLV_SET_HDR(&cmd->tlv_header, 7306 WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, 7307 WMITLV_GET_STRUCT_TLVLEN 7308 (wmi_extscan_get_capabilities_cmd_fixed_param)); 7309 7310 cmd->request_id = pgetcapab->request_id; 7311 7312 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7313 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) { 7314 WMI_LOGE("%s: failed to command", __func__); 7315 wmi_buf_free(wmi_buf); 7316 return QDF_STATUS_E_FAILURE; 7317 } 7318 return QDF_STATUS_SUCCESS; 7319 } 7320 7321 /** 7322 * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results 7323 * @wmi_handle: wmi handle 7324 * @pcached_results: cached results parameters 7325 * 7326 * This function send request to fw to get cached results. 7327 * 7328 * Return: CDF status 7329 */ 7330 static QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle, 7331 struct extscan_cached_result_params *pcached_results) 7332 { 7333 wmi_extscan_get_cached_results_cmd_fixed_param *cmd; 7334 wmi_buf_t wmi_buf; 7335 uint32_t len; 7336 uint8_t *buf_ptr; 7337 7338 len = sizeof(*cmd); 7339 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7340 if (!wmi_buf) { 7341 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7342 return QDF_STATUS_E_NOMEM; 7343 } 7344 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7345 7346 cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr; 7347 WMITLV_SET_HDR(&cmd->tlv_header, 7348 WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, 7349 WMITLV_GET_STRUCT_TLVLEN 7350 (wmi_extscan_get_cached_results_cmd_fixed_param)); 7351 7352 cmd->request_id = pcached_results->request_id; 7353 cmd->vdev_id = pcached_results->session_id; 7354 cmd->control_flags = pcached_results->flush; 7355 7356 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7357 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) { 7358 WMI_LOGE("%s: failed to command", __func__); 7359 wmi_buf_free(wmi_buf); 7360 return QDF_STATUS_E_FAILURE; 7361 } 7362 return QDF_STATUS_SUCCESS; 7363 } 7364 7365 /** 7366 * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd 7367 * @wmi_handle: wmi handle 7368 * @reset_req: Reset change request params 7369 * 7370 * This function sends stop change monitor request to fw. 7371 * 7372 * Return: CDF status 7373 */ 7374 static QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7375 struct extscan_capabilities_reset_params *reset_req) 7376 { 7377 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7378 wmi_buf_t wmi_buf; 7379 uint32_t len; 7380 uint8_t *buf_ptr; 7381 int change_list = 0; 7382 7383 len = sizeof(*cmd); 7384 7385 /* reset significant change tlv is set to 0 */ 7386 len += WMI_TLV_HDR_SIZE; 7387 len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param); 7388 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7389 if (!wmi_buf) { 7390 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7391 return QDF_STATUS_E_NOMEM; 7392 } 7393 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7394 7395 cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7396 buf_ptr; 7397 WMITLV_SET_HDR(&cmd->tlv_header, 7398 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7399 WMITLV_GET_STRUCT_TLVLEN 7400 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7401 7402 cmd->request_id = reset_req->request_id; 7403 cmd->vdev_id = reset_req->session_id; 7404 cmd->mode = 0; 7405 7406 buf_ptr += sizeof(*cmd); 7407 WMITLV_SET_HDR(buf_ptr, 7408 WMITLV_TAG_ARRAY_STRUC, 7409 change_list * 7410 sizeof(wmi_extscan_wlan_change_bssid_param)); 7411 buf_ptr += WMI_TLV_HDR_SIZE + (change_list * 7412 sizeof 7413 (wmi_extscan_wlan_change_bssid_param)); 7414 7415 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7416 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7417 WMI_LOGE("%s: failed to command", __func__); 7418 wmi_buf_free(wmi_buf); 7419 return QDF_STATUS_E_FAILURE; 7420 } 7421 return QDF_STATUS_SUCCESS; 7422 } 7423 7424 /** 7425 * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request 7426 * @wmi_handle: wmi handle 7427 * @psigchange: change monitor request params 7428 * @buf: wmi buffer 7429 * @buf_len: buffer length 7430 * 7431 * This function fills elements of change monitor request buffer. 7432 * 7433 * Return: CDF status 7434 */ 7435 static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd(wmi_unified_t wmi_handle, 7436 struct extscan_set_sig_changereq_params 7437 *psigchange, wmi_buf_t *buf, int *buf_len) 7438 { 7439 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7440 wmi_extscan_wlan_change_bssid_param *dest_chglist; 7441 uint8_t *buf_ptr; 7442 int j; 7443 int len = sizeof(*cmd); 7444 uint32_t numap = psigchange->num_ap; 7445 struct ap_threshold_params *src_ap = psigchange->ap; 7446 7447 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) { 7448 WMI_LOGE("%s: Invalid number of bssid's", __func__); 7449 return QDF_STATUS_E_INVAL; 7450 } 7451 len += WMI_TLV_HDR_SIZE; 7452 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param); 7453 7454 *buf = wmi_buf_alloc(wmi_handle, len); 7455 if (!*buf) { 7456 WMI_LOGP("%s: failed to allocate memory for change monitor cmd", 7457 __func__); 7458 return QDF_STATUS_E_FAILURE; 7459 } 7460 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7461 cmd = 7462 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7463 buf_ptr; 7464 WMITLV_SET_HDR(&cmd->tlv_header, 7465 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7466 WMITLV_GET_STRUCT_TLVLEN 7467 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7468 7469 cmd->request_id = psigchange->request_id; 7470 cmd->vdev_id = psigchange->session_id; 7471 cmd->total_entries = numap; 7472 cmd->mode = 1; 7473 cmd->num_entries_in_page = numap; 7474 cmd->lost_ap_scan_count = psigchange->lostap_sample_size; 7475 cmd->max_rssi_samples = psigchange->rssi_sample_size; 7476 cmd->rssi_averaging_samples = psigchange->rssi_sample_size; 7477 cmd->max_out_of_range_count = psigchange->min_breaching; 7478 7479 buf_ptr += sizeof(*cmd); 7480 WMITLV_SET_HDR(buf_ptr, 7481 WMITLV_TAG_ARRAY_STRUC, 7482 numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7483 dest_chglist = (wmi_extscan_wlan_change_bssid_param *) 7484 (buf_ptr + WMI_TLV_HDR_SIZE); 7485 7486 for (j = 0; j < numap; j++) { 7487 WMITLV_SET_HDR(dest_chglist, 7488 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7489 WMITLV_GET_STRUCT_TLVLEN 7490 (wmi_extscan_wlan_change_bssid_param)); 7491 7492 dest_chglist->lower_rssi_limit = src_ap->low; 7493 dest_chglist->upper_rssi_limit = src_ap->high; 7494 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 7495 &dest_chglist->bssid); 7496 7497 WMI_LOGD("%s: min_rssi %d", __func__, 7498 dest_chglist->lower_rssi_limit); 7499 dest_chglist++; 7500 src_ap++; 7501 } 7502 buf_ptr += WMI_TLV_HDR_SIZE + 7503 (numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7504 *buf_len = len; 7505 return QDF_STATUS_SUCCESS; 7506 } 7507 7508 /** 7509 * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd 7510 * @wmi_handle: wmi handle 7511 * @psigchange: change monitor request params 7512 * 7513 * This function sends start change monitor request to fw. 7514 * 7515 * Return: CDF status 7516 */ 7517 static QDF_STATUS send_extscan_start_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7518 struct extscan_set_sig_changereq_params * 7519 psigchange) 7520 { 7521 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7522 wmi_buf_t buf; 7523 int len; 7524 7525 7526 qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle, 7527 psigchange, &buf, 7528 &len); 7529 if (qdf_status != QDF_STATUS_SUCCESS) { 7530 WMI_LOGE("%s: Failed to get buffer for change monitor cmd", 7531 __func__); 7532 return QDF_STATUS_E_FAILURE; 7533 } 7534 if (!buf) { 7535 WMI_LOGE("%s: Failed to get buffer", __func__); 7536 return QDF_STATUS_E_FAILURE; 7537 } 7538 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7539 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7540 WMI_LOGE("%s: failed to send command", __func__); 7541 wmi_buf_free(buf); 7542 return QDF_STATUS_E_FAILURE; 7543 } 7544 return QDF_STATUS_SUCCESS; 7545 } 7546 7547 /** 7548 * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor 7549 * @wmi_handle: wmi handle 7550 * @photlist_reset: hotlist reset params 7551 * 7552 * This function configures hotlist monitor to stop in fw. 7553 * 7554 * Return: CDF status 7555 */ 7556 static QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7557 struct extscan_bssid_hotlist_reset_params *photlist_reset) 7558 { 7559 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; 7560 wmi_buf_t wmi_buf; 7561 uint32_t len; 7562 uint8_t *buf_ptr; 7563 int hotlist_entries = 0; 7564 7565 len = sizeof(*cmd); 7566 7567 /* reset bssid hotlist with tlv set to 0 */ 7568 len += WMI_TLV_HDR_SIZE; 7569 len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry); 7570 7571 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7572 if (!wmi_buf) { 7573 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7574 return QDF_STATUS_E_NOMEM; 7575 } 7576 7577 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7578 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 7579 buf_ptr; 7580 WMITLV_SET_HDR(&cmd->tlv_header, 7581 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 7582 WMITLV_GET_STRUCT_TLVLEN 7583 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 7584 7585 cmd->request_id = photlist_reset->request_id; 7586 cmd->vdev_id = photlist_reset->session_id; 7587 cmd->mode = 0; 7588 7589 buf_ptr += sizeof(*cmd); 7590 WMITLV_SET_HDR(buf_ptr, 7591 WMITLV_TAG_ARRAY_STRUC, 7592 hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7593 buf_ptr += WMI_TLV_HDR_SIZE + 7594 (hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7595 7596 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7597 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 7598 WMI_LOGE("%s: failed to command", __func__); 7599 wmi_buf_free(wmi_buf); 7600 return QDF_STATUS_E_FAILURE; 7601 } 7602 return QDF_STATUS_SUCCESS; 7603 } 7604 7605 /** 7606 * send_stop_extscan_cmd_tlv() - stop extscan command to fw. 7607 * @wmi_handle: wmi handle 7608 * @pstopcmd: stop scan command request params 7609 * 7610 * This function sends stop extscan request to fw. 7611 * 7612 * Return: CDF Status. 7613 */ 7614 static QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7615 struct extscan_stop_req_params *pstopcmd) 7616 { 7617 wmi_extscan_stop_cmd_fixed_param *cmd; 7618 wmi_buf_t wmi_buf; 7619 uint32_t len; 7620 uint8_t *buf_ptr; 7621 7622 len = sizeof(*cmd); 7623 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7624 if (!wmi_buf) { 7625 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7626 return QDF_STATUS_E_NOMEM; 7627 } 7628 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7629 cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr; 7630 WMITLV_SET_HDR(&cmd->tlv_header, 7631 WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, 7632 WMITLV_GET_STRUCT_TLVLEN 7633 (wmi_extscan_stop_cmd_fixed_param)); 7634 7635 cmd->request_id = pstopcmd->request_id; 7636 cmd->vdev_id = pstopcmd->session_id; 7637 7638 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7639 WMI_EXTSCAN_STOP_CMDID)) { 7640 WMI_LOGE("%s: failed to command", __func__); 7641 wmi_buf_free(wmi_buf); 7642 return QDF_STATUS_E_FAILURE; 7643 } 7644 7645 return QDF_STATUS_SUCCESS; 7646 } 7647 7648 /** 7649 * wmi_get_buf_extscan_start_cmd() - Fill extscan start request 7650 * @wmi_handle: wmi handle 7651 * @pstart: scan command request params 7652 * @buf: event buffer 7653 * @buf_len: length of buffer 7654 * 7655 * This function fills individual elements of extscan request and 7656 * TLV for buckets, channel list. 7657 * 7658 * Return: CDF Status. 7659 */ 7660 static 7661 QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle, 7662 struct wifi_scan_cmd_req_params *pstart, 7663 wmi_buf_t *buf, int *buf_len) 7664 { 7665 wmi_extscan_start_cmd_fixed_param *cmd; 7666 wmi_extscan_bucket *dest_blist; 7667 wmi_extscan_bucket_channel *dest_clist; 7668 struct wifi_scan_bucket_params *src_bucket = pstart->buckets; 7669 struct wifi_scan_channelspec_params *src_channel = src_bucket->channels; 7670 struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS]; 7671 7672 uint8_t *buf_ptr; 7673 int i, k, count = 0; 7674 int len = sizeof(*cmd); 7675 int nbuckets = pstart->numBuckets; 7676 int nchannels = 0; 7677 7678 /* These TLV's are are NULL by default */ 7679 uint32_t ie_len_with_pad = 0; 7680 int num_ssid = 0; 7681 int num_bssid = 0; 7682 int ie_len = 0; 7683 7684 uint32_t base_period = pstart->basePeriod; 7685 7686 /* TLV placeholder for ssid_list (NULL) */ 7687 len += WMI_TLV_HDR_SIZE; 7688 len += num_ssid * sizeof(wmi_ssid); 7689 7690 /* TLV placeholder for bssid_list (NULL) */ 7691 len += WMI_TLV_HDR_SIZE; 7692 len += num_bssid * sizeof(wmi_mac_addr); 7693 7694 /* TLV placeholder for ie_data (NULL) */ 7695 len += WMI_TLV_HDR_SIZE; 7696 len += ie_len * sizeof(uint32_t); 7697 7698 /* TLV placeholder for bucket */ 7699 len += WMI_TLV_HDR_SIZE; 7700 len += nbuckets * sizeof(wmi_extscan_bucket); 7701 7702 /* TLV channel placeholder */ 7703 len += WMI_TLV_HDR_SIZE; 7704 for (i = 0; i < nbuckets; i++) { 7705 nchannels += src_bucket->numChannels; 7706 src_bucket++; 7707 } 7708 7709 WMI_LOGD("%s: Total buckets: %d total #of channels is %d", 7710 __func__, nbuckets, nchannels); 7711 len += nchannels * sizeof(wmi_extscan_bucket_channel); 7712 /* Allocate the memory */ 7713 *buf = wmi_buf_alloc(wmi_handle, len); 7714 if (!*buf) { 7715 WMI_LOGP("%s: failed to allocate memory" 7716 " for start extscan cmd", __func__); 7717 return QDF_STATUS_E_NOMEM; 7718 } 7719 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7720 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr; 7721 WMITLV_SET_HDR(&cmd->tlv_header, 7722 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, 7723 WMITLV_GET_STRUCT_TLVLEN 7724 (wmi_extscan_start_cmd_fixed_param)); 7725 7726 cmd->request_id = pstart->requestId; 7727 cmd->vdev_id = pstart->sessionId; 7728 cmd->base_period = pstart->basePeriod; 7729 cmd->num_buckets = nbuckets; 7730 cmd->configuration_flags = 0; 7731 if (pstart->configuration_flags & WMI_EXTSCAN_LP_EXTENDED_BATCHING) 7732 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN; 7733 WMI_LOGI("%s: configuration_flags: 0x%x", __func__, 7734 cmd->configuration_flags); 7735 #ifdef FEATURE_WLAN_EXTSCAN 7736 cmd->min_rest_time = WMI_EXTSCAN_REST_TIME; 7737 cmd->max_rest_time = WMI_EXTSCAN_REST_TIME; 7738 cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME; 7739 cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION; 7740 #endif 7741 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7742 7743 /* The max dwell time is retrieved from the first channel 7744 * of the first bucket and kept common for all channels. 7745 */ 7746 cmd->min_dwell_time_active = pstart->min_dwell_time_active; 7747 cmd->max_dwell_time_active = pstart->max_dwell_time_active; 7748 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive; 7749 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive; 7750 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7751 cmd->max_table_usage = pstart->report_threshold_percent; 7752 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans; 7753 7754 cmd->repeat_probe_time = cmd->max_dwell_time_active / 7755 WMI_SCAN_NPROBES_DEFAULT; 7756 cmd->probe_delay = 0; 7757 cmd->probe_spacing_time = 0; 7758 cmd->idle_time = 0; 7759 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ | 7760 WMI_SCAN_ADD_CCK_RATES | 7761 WMI_SCAN_ADD_OFDM_RATES | 7762 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ | 7763 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 7764 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 7765 pstart->extscan_adaptive_dwell_mode); 7766 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_LOW; 7767 cmd->num_ssids = 0; 7768 cmd->num_bssid = 0; 7769 cmd->ie_len = 0; 7770 cmd->n_probes = (cmd->repeat_probe_time > 0) ? 7771 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0; 7772 7773 buf_ptr += sizeof(*cmd); 7774 WMITLV_SET_HDR(buf_ptr, 7775 WMITLV_TAG_ARRAY_FIXED_STRUC, 7776 num_ssid * sizeof(wmi_ssid)); 7777 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid)); 7778 7779 WMITLV_SET_HDR(buf_ptr, 7780 WMITLV_TAG_ARRAY_FIXED_STRUC, 7781 num_bssid * sizeof(wmi_mac_addr)); 7782 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr)); 7783 7784 ie_len_with_pad = 0; 7785 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7786 ie_len_with_pad); 7787 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; 7788 7789 WMITLV_SET_HDR(buf_ptr, 7790 WMITLV_TAG_ARRAY_STRUC, 7791 nbuckets * sizeof(wmi_extscan_bucket)); 7792 dest_blist = (wmi_extscan_bucket *) 7793 (buf_ptr + WMI_TLV_HDR_SIZE); 7794 src_bucket = pstart->buckets; 7795 7796 /* Retrieve scanning information from each bucket and 7797 * channels and send it to the target 7798 */ 7799 for (i = 0; i < nbuckets; i++) { 7800 WMITLV_SET_HDR(dest_blist, 7801 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7802 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket)); 7803 7804 dest_blist->bucket_id = src_bucket->bucket; 7805 dest_blist->base_period_multiplier = 7806 src_bucket->period / base_period; 7807 dest_blist->min_period = src_bucket->period; 7808 dest_blist->max_period = src_bucket->max_period; 7809 dest_blist->exp_backoff = src_bucket->exponent; 7810 dest_blist->exp_max_step_count = src_bucket->step_count; 7811 dest_blist->channel_band = src_bucket->band; 7812 dest_blist->num_channels = src_bucket->numChannels; 7813 dest_blist->notify_extscan_events = 0; 7814 7815 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN) 7816 dest_blist->notify_extscan_events = 7817 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | 7818 WMI_EXTSCAN_CYCLE_STARTED_EVENT; 7819 7820 if (src_bucket->reportEvents & 7821 WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) { 7822 dest_blist->forwarding_flags = 7823 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; 7824 dest_blist->notify_extscan_events |= 7825 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT | 7826 WMI_EXTSCAN_CYCLE_STARTED_EVENT | 7827 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT; 7828 } else { 7829 dest_blist->forwarding_flags = 7830 WMI_EXTSCAN_NO_FORWARDING; 7831 } 7832 7833 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH) 7834 dest_blist->configuration_flags = 0; 7835 else 7836 dest_blist->configuration_flags = 7837 WMI_EXTSCAN_BUCKET_CACHE_RESULTS; 7838 7839 WMI_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u", 7840 __func__, dest_blist->notify_extscan_events, 7841 dest_blist->configuration_flags, 7842 dest_blist->forwarding_flags); 7843 7844 dest_blist->min_dwell_time_active = 7845 src_bucket->min_dwell_time_active; 7846 dest_blist->max_dwell_time_active = 7847 src_bucket->max_dwell_time_active; 7848 dest_blist->min_dwell_time_passive = 7849 src_bucket->min_dwell_time_passive; 7850 dest_blist->max_dwell_time_passive = 7851 src_bucket->max_dwell_time_passive; 7852 src_channel = src_bucket->channels; 7853 7854 /* save the channel info to later populate 7855 * the channel TLV 7856 */ 7857 for (k = 0; k < src_bucket->numChannels; k++) { 7858 save_channel[count++].channel = src_channel->channel; 7859 src_channel++; 7860 } 7861 dest_blist++; 7862 src_bucket++; 7863 } 7864 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket)); 7865 WMITLV_SET_HDR(buf_ptr, 7866 WMITLV_TAG_ARRAY_STRUC, 7867 nchannels * sizeof(wmi_extscan_bucket_channel)); 7868 dest_clist = (wmi_extscan_bucket_channel *) 7869 (buf_ptr + WMI_TLV_HDR_SIZE); 7870 7871 /* Active or passive scan is based on the bucket dwell time 7872 * and channel specific active,passive scans are not 7873 * supported yet 7874 */ 7875 for (i = 0; i < nchannels; i++) { 7876 WMITLV_SET_HDR(dest_clist, 7877 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, 7878 WMITLV_GET_STRUCT_TLVLEN 7879 (wmi_extscan_bucket_channel)); 7880 dest_clist->channel = save_channel[i].channel; 7881 dest_clist++; 7882 } 7883 buf_ptr += WMI_TLV_HDR_SIZE + 7884 (nchannels * sizeof(wmi_extscan_bucket_channel)); 7885 *buf_len = len; 7886 return QDF_STATUS_SUCCESS; 7887 } 7888 7889 /** 7890 * send_start_extscan_cmd_tlv() - start extscan command to fw. 7891 * @wmi_handle: wmi handle 7892 * @pstart: scan command request params 7893 * 7894 * This function sends start extscan request to fw. 7895 * 7896 * Return: CDF Status. 7897 */ 7898 static QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7899 struct wifi_scan_cmd_req_params *pstart) 7900 { 7901 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7902 wmi_buf_t buf; 7903 int len; 7904 7905 /* Fill individual elements of extscan request and 7906 * TLV for buckets, channel list. 7907 */ 7908 qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle, 7909 pstart, &buf, &len); 7910 if (qdf_status != QDF_STATUS_SUCCESS) { 7911 WMI_LOGE("%s: Failed to get buffer for ext scan cmd", __func__); 7912 return QDF_STATUS_E_FAILURE; 7913 } 7914 if (!buf) { 7915 WMI_LOGE("%s:Failed to get buffer" 7916 "for current extscan info", __func__); 7917 return QDF_STATUS_E_FAILURE; 7918 } 7919 if (wmi_unified_cmd_send(wmi_handle, buf, 7920 len, WMI_EXTSCAN_START_CMDID)) { 7921 WMI_LOGE("%s: failed to send command", __func__); 7922 wmi_buf_free(buf); 7923 return QDF_STATUS_E_FAILURE; 7924 } 7925 7926 return QDF_STATUS_SUCCESS; 7927 } 7928 7929 /** 7930 * send_plm_stop_cmd_tlv() - plm stop request 7931 * @wmi_handle: wmi handle 7932 * @plm: plm request parameters 7933 * 7934 * This function request FW to stop PLM. 7935 * 7936 * Return: CDF status 7937 */ 7938 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7939 const struct plm_req_params *plm) 7940 { 7941 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7942 int32_t len; 7943 wmi_buf_t buf; 7944 uint8_t *buf_ptr; 7945 int ret; 7946 7947 len = sizeof(*cmd); 7948 buf = wmi_buf_alloc(wmi_handle, len); 7949 if (!buf) { 7950 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7951 return QDF_STATUS_E_NOMEM; 7952 } 7953 7954 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7955 7956 buf_ptr = (uint8_t *) cmd; 7957 7958 WMITLV_SET_HDR(&cmd->tlv_header, 7959 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7960 WMITLV_GET_STRUCT_TLVLEN 7961 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7962 7963 cmd->vdev_id = plm->session_id; 7964 7965 cmd->meas_token = plm->meas_token; 7966 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7967 7968 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7969 WMI_VDEV_PLMREQ_STOP_CMDID); 7970 if (ret) { 7971 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7972 wmi_buf_free(buf); 7973 return QDF_STATUS_E_FAILURE; 7974 } 7975 7976 return QDF_STATUS_SUCCESS; 7977 } 7978 7979 /** 7980 * send_plm_start_cmd_tlv() - plm start request 7981 * @wmi_handle: wmi handle 7982 * @plm: plm request parameters 7983 * 7984 * This function request FW to start PLM. 7985 * 7986 * Return: CDF status 7987 */ 7988 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7989 const struct plm_req_params *plm, 7990 uint32_t *gchannel_list) 7991 { 7992 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7993 uint32_t *channel_list; 7994 int32_t len; 7995 wmi_buf_t buf; 7996 uint8_t *buf_ptr; 7997 uint8_t count; 7998 int ret; 7999 8000 /* TLV place holder for channel_list */ 8001 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8002 len += sizeof(uint32_t) * plm->plm_num_ch; 8003 8004 buf = wmi_buf_alloc(wmi_handle, len); 8005 if (!buf) { 8006 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8007 return QDF_STATUS_E_NOMEM; 8008 } 8009 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 8010 8011 buf_ptr = (uint8_t *) cmd; 8012 8013 WMITLV_SET_HDR(&cmd->tlv_header, 8014 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 8015 WMITLV_GET_STRUCT_TLVLEN 8016 (wmi_vdev_plmreq_start_cmd_fixed_param)); 8017 8018 cmd->vdev_id = plm->session_id; 8019 8020 cmd->meas_token = plm->meas_token; 8021 cmd->dialog_token = plm->diag_token; 8022 cmd->number_bursts = plm->num_bursts; 8023 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 8024 cmd->off_duration = plm->meas_duration; 8025 cmd->burst_cycle = plm->burst_len; 8026 cmd->tx_power = plm->desired_tx_pwr; 8027 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 8028 cmd->num_chans = plm->plm_num_ch; 8029 8030 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 8031 8032 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 8033 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 8034 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 8035 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 8036 WMI_LOGD("off_duration: %d", cmd->off_duration); 8037 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 8038 WMI_LOGD("tx_power: %d", cmd->tx_power); 8039 WMI_LOGD("Number of channels : %d", cmd->num_chans); 8040 8041 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8042 (cmd->num_chans * sizeof(uint32_t))); 8043 8044 buf_ptr += WMI_TLV_HDR_SIZE; 8045 if (cmd->num_chans) { 8046 channel_list = (uint32_t *) buf_ptr; 8047 for (count = 0; count < cmd->num_chans; count++) { 8048 channel_list[count] = plm->plm_ch_list[count]; 8049 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 8050 channel_list[count] = 8051 gchannel_list[count]; 8052 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 8053 } 8054 buf_ptr += cmd->num_chans * sizeof(uint32_t); 8055 } 8056 8057 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8058 WMI_VDEV_PLMREQ_START_CMDID); 8059 if (ret) { 8060 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 8061 wmi_buf_free(buf); 8062 return QDF_STATUS_E_FAILURE; 8063 } 8064 8065 return QDF_STATUS_SUCCESS; 8066 } 8067 8068 /** 8069 * send_pno_stop_cmd_tlv() - PNO stop request 8070 * @wmi_handle: wmi handle 8071 * @vdev_id: vdev id 8072 * 8073 * This function request FW to stop ongoing PNO operation. 8074 * 8075 * Return: CDF status 8076 */ 8077 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8078 { 8079 wmi_nlo_config_cmd_fixed_param *cmd; 8080 int32_t len = sizeof(*cmd); 8081 wmi_buf_t buf; 8082 uint8_t *buf_ptr; 8083 int ret; 8084 8085 /* 8086 * TLV place holder for array of structures nlo_configured_parameters 8087 * TLV place holder for array of uint32_t channel_list 8088 * TLV place holder for chnl prediction cfg 8089 */ 8090 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8091 buf = wmi_buf_alloc(wmi_handle, len); 8092 if (!buf) { 8093 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8094 return QDF_STATUS_E_NOMEM; 8095 } 8096 8097 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8098 buf_ptr = (uint8_t *) cmd; 8099 8100 WMITLV_SET_HDR(&cmd->tlv_header, 8101 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8102 WMITLV_GET_STRUCT_TLVLEN 8103 (wmi_nlo_config_cmd_fixed_param)); 8104 8105 cmd->vdev_id = vdev_id; 8106 cmd->flags = WMI_NLO_CONFIG_STOP; 8107 buf_ptr += sizeof(*cmd); 8108 8109 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8110 buf_ptr += WMI_TLV_HDR_SIZE; 8111 8112 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 8113 buf_ptr += WMI_TLV_HDR_SIZE; 8114 8115 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8116 buf_ptr += WMI_TLV_HDR_SIZE; 8117 8118 8119 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8120 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8121 if (ret) { 8122 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8123 wmi_buf_free(buf); 8124 return QDF_STATUS_E_FAILURE; 8125 } 8126 8127 return QDF_STATUS_SUCCESS; 8128 } 8129 8130 /** 8131 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 8132 * @buf_ptr: Buffer passed by upper layers 8133 * @pno: Buffer to be sent to the firmware 8134 * 8135 * Copy the PNO Channel prediction configuration parameters 8136 * passed by the upper layers to a WMI format TLV and send it 8137 * down to the firmware. 8138 * 8139 * Return: None 8140 */ 8141 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 8142 struct pno_scan_req_params *pno) 8143 { 8144 nlo_channel_prediction_cfg *channel_prediction_cfg = 8145 (nlo_channel_prediction_cfg *) buf_ptr; 8146 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 8147 WMITLV_TAG_ARRAY_BYTE, 8148 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 8149 #ifdef FEATURE_WLAN_SCAN_PNO 8150 channel_prediction_cfg->enable = pno->pno_channel_prediction; 8151 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 8152 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 8153 channel_prediction_cfg->full_scan_period_ms = 8154 pno->channel_prediction_full_scan; 8155 #endif 8156 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8157 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 8158 channel_prediction_cfg->enable, 8159 channel_prediction_cfg->top_k_num, 8160 channel_prediction_cfg->stationary_threshold, 8161 channel_prediction_cfg->full_scan_period_ms); 8162 } 8163 8164 /** 8165 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 8166 * @wmi_handle: wmi handle 8167 * @params: configuration parameters 8168 * 8169 * Return: QDF_STATUS 8170 */ 8171 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 8172 struct nlo_mawc_params *params) 8173 { 8174 wmi_buf_t buf = NULL; 8175 QDF_STATUS status; 8176 int len; 8177 uint8_t *buf_ptr; 8178 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 8179 8180 len = sizeof(*wmi_nlo_mawc_params); 8181 buf = wmi_buf_alloc(wmi_handle, len); 8182 if (!buf) { 8183 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8184 return QDF_STATUS_E_NOMEM; 8185 } 8186 8187 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8188 wmi_nlo_mawc_params = 8189 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 8190 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 8191 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 8192 WMITLV_GET_STRUCT_TLVLEN 8193 (wmi_nlo_configure_mawc_cmd_fixed_param)); 8194 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 8195 if (params->enable) 8196 wmi_nlo_mawc_params->enable = 1; 8197 else 8198 wmi_nlo_mawc_params->enable = 0; 8199 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 8200 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 8201 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 8202 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 8203 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 8204 wmi_nlo_mawc_params->exp_backoff_ratio, 8205 wmi_nlo_mawc_params->init_scan_interval, 8206 wmi_nlo_mawc_params->max_scan_interval); 8207 8208 status = wmi_unified_cmd_send(wmi_handle, buf, 8209 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 8210 if (QDF_IS_STATUS_ERROR(status)) { 8211 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 8212 status); 8213 wmi_buf_free(buf); 8214 return QDF_STATUS_E_FAILURE; 8215 } 8216 8217 return QDF_STATUS_SUCCESS; 8218 } 8219 8220 /** 8221 * send_pno_start_cmd_tlv() - PNO start request 8222 * @wmi_handle: wmi handle 8223 * @pno: PNO request 8224 * 8225 * This function request FW to start PNO request. 8226 * Request: CDF status 8227 */ 8228 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 8229 struct pno_scan_req_params *pno) 8230 { 8231 wmi_nlo_config_cmd_fixed_param *cmd; 8232 nlo_configured_parameters *nlo_list; 8233 uint32_t *channel_list; 8234 int32_t len; 8235 wmi_buf_t buf; 8236 uint8_t *buf_ptr; 8237 uint8_t i; 8238 int ret; 8239 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 8240 connected_nlo_rssi_params *nlo_relative_rssi; 8241 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 8242 8243 /* 8244 * TLV place holder for array nlo_configured_parameters(nlo_list) 8245 * TLV place holder for array of uint32_t channel_list 8246 * TLV place holder for chnnl prediction cfg 8247 * TLV place holder for array of wmi_vendor_oui 8248 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 8249 */ 8250 len = sizeof(*cmd) + 8251 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 8252 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8253 8254 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 8255 WMI_NLO_MAX_CHAN); 8256 len += sizeof(nlo_configured_parameters) * 8257 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8258 len += sizeof(nlo_channel_prediction_cfg); 8259 len += sizeof(enlo_candidate_score_params); 8260 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 8261 len += sizeof(connected_nlo_rssi_params); 8262 len += sizeof(connected_nlo_bss_band_rssi_pref); 8263 8264 buf = wmi_buf_alloc(wmi_handle, len); 8265 if (!buf) { 8266 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8267 return QDF_STATUS_E_NOMEM; 8268 } 8269 8270 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8271 8272 buf_ptr = (uint8_t *) cmd; 8273 WMITLV_SET_HDR(&cmd->tlv_header, 8274 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8275 WMITLV_GET_STRUCT_TLVLEN 8276 (wmi_nlo_config_cmd_fixed_param)); 8277 cmd->vdev_id = pno->vdev_id; 8278 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 8279 8280 #ifdef FEATURE_WLAN_SCAN_PNO 8281 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 8282 pno->adaptive_dwell_mode); 8283 #endif 8284 /* Current FW does not support min-max range for dwell time */ 8285 cmd->active_dwell_time = pno->active_dwell_time; 8286 cmd->passive_dwell_time = pno->passive_dwell_time; 8287 8288 if (pno->do_passive_scan) 8289 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 8290 /* Copy scan interval */ 8291 cmd->fast_scan_period = pno->fast_scan_period; 8292 cmd->slow_scan_period = pno->slow_scan_period; 8293 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 8294 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 8295 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 8296 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 8297 cmd->fast_scan_period, cmd->slow_scan_period); 8298 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 8299 8300 /* mac randomization attributes */ 8301 if (pno->scan_random.randomize) { 8302 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 8303 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 8304 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 8305 pno->scan_random.mac_mask, 8306 &cmd->mac_addr, 8307 &cmd->mac_mask); 8308 } 8309 8310 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 8311 8312 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8313 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 8314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8315 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 8316 buf_ptr += WMI_TLV_HDR_SIZE; 8317 8318 nlo_list = (nlo_configured_parameters *) buf_ptr; 8319 for (i = 0; i < cmd->no_of_ssids; i++) { 8320 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 8321 WMITLV_TAG_ARRAY_BYTE, 8322 WMITLV_GET_STRUCT_TLVLEN 8323 (nlo_configured_parameters)); 8324 /* Copy ssid and it's length */ 8325 nlo_list[i].ssid.valid = true; 8326 nlo_list[i].ssid.ssid.ssid_len = 8327 pno->networks_list[i].ssid.length; 8328 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 8329 pno->networks_list[i].ssid.ssid, 8330 nlo_list[i].ssid.ssid.ssid_len); 8331 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 8332 nlo_list[i].ssid.ssid.ssid_len, 8333 (char *)nlo_list[i].ssid.ssid.ssid, 8334 nlo_list[i].ssid.ssid.ssid_len); 8335 8336 /* Copy rssi threshold */ 8337 if (pno->networks_list[i].rssi_thresh && 8338 pno->networks_list[i].rssi_thresh > 8339 WMI_RSSI_THOLD_DEFAULT) { 8340 nlo_list[i].rssi_cond.valid = true; 8341 nlo_list[i].rssi_cond.rssi = 8342 pno->networks_list[i].rssi_thresh; 8343 WMI_LOGD("RSSI threshold : %d dBm", 8344 nlo_list[i].rssi_cond.rssi); 8345 } 8346 nlo_list[i].bcast_nw_type.valid = true; 8347 nlo_list[i].bcast_nw_type.bcast_nw_type = 8348 pno->networks_list[i].bc_new_type; 8349 WMI_LOGD("Broadcast NW type (%u)", 8350 nlo_list[i].bcast_nw_type.bcast_nw_type); 8351 } 8352 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 8353 8354 /* Copy channel info */ 8355 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 8356 WMI_NLO_MAX_CHAN); 8357 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 8358 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8359 (cmd->num_of_channels * sizeof(uint32_t))); 8360 buf_ptr += WMI_TLV_HDR_SIZE; 8361 8362 channel_list = (uint32_t *) buf_ptr; 8363 for (i = 0; i < cmd->num_of_channels; i++) { 8364 channel_list[i] = pno->networks_list[0].channels[i]; 8365 8366 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 8367 channel_list[i] = 8368 wlan_chan_to_freq(pno-> 8369 networks_list[0].channels[i]); 8370 8371 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 8372 } 8373 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 8374 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8375 sizeof(nlo_channel_prediction_cfg)); 8376 buf_ptr += WMI_TLV_HDR_SIZE; 8377 wmi_set_pno_channel_prediction(buf_ptr, pno); 8378 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8379 /** TODO: Discrete firmware doesn't have command/option to configure 8380 * App IE which comes from wpa_supplicant as of part PNO start request. 8381 */ 8382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 8383 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 8384 buf_ptr += sizeof(enlo_candidate_score_params); 8385 8386 if (ie_whitelist->white_list) { 8387 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 8388 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 8389 &cmd->num_vendor_oui, 8390 ie_whitelist); 8391 } 8392 8393 /* ie white list */ 8394 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8395 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 8396 buf_ptr += WMI_TLV_HDR_SIZE; 8397 if (cmd->num_vendor_oui != 0) { 8398 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 8399 ie_whitelist->voui); 8400 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 8401 } 8402 8403 if (pno->relative_rssi_set) 8404 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 8405 8406 /* 8407 * Firmware calculation using connected PNO params: 8408 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 8409 * deduction of rssi_pref for chosen band_pref and 8410 * addition of rssi_pref for remaining bands (other than chosen band). 8411 */ 8412 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 8413 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 8414 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 8415 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 8416 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 8417 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 8418 buf_ptr += sizeof(*nlo_relative_rssi); 8419 8420 /* 8421 * As of now Kernel and Host supports one band and rssi preference. 8422 * Firmware supports array of band and rssi preferences 8423 */ 8424 cmd->num_cnlo_band_pref = 1; 8425 WMITLV_SET_HDR(buf_ptr, 8426 WMITLV_TAG_ARRAY_STRUC, 8427 cmd->num_cnlo_band_pref * 8428 sizeof(connected_nlo_bss_band_rssi_pref)); 8429 buf_ptr += WMI_TLV_HDR_SIZE; 8430 8431 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 8432 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 8433 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 8434 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 8435 WMITLV_GET_STRUCT_TLVLEN( 8436 connected_nlo_bss_band_rssi_pref)); 8437 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 8438 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 8439 WMI_LOGI("band_pref %d, rssi_pref %d", 8440 nlo_band_rssi[i].band, 8441 nlo_band_rssi[i].rssi_pref); 8442 } 8443 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 8444 8445 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8446 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8447 if (ret) { 8448 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8449 wmi_buf_free(buf); 8450 return QDF_STATUS_E_FAILURE; 8451 } 8452 8453 return QDF_STATUS_SUCCESS; 8454 } 8455 8456 /* send_set_ric_req_cmd_tlv() - set ric request element 8457 * @wmi_handle: wmi handle 8458 * @msg: message 8459 * @is_add_ts: is addts required 8460 * 8461 * This function sets ric request element for 11r roaming. 8462 * 8463 * Return: CDF status 8464 */ 8465 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 8466 void *msg, uint8_t is_add_ts) 8467 { 8468 wmi_ric_request_fixed_param *cmd; 8469 wmi_ric_tspec *tspec_param; 8470 wmi_buf_t buf; 8471 uint8_t *buf_ptr; 8472 struct mac_tspec_ie *ptspecIE = NULL; 8473 int32_t len = sizeof(wmi_ric_request_fixed_param) + 8474 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 8475 8476 buf = wmi_buf_alloc(wmi_handle, len); 8477 if (!buf) { 8478 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8479 return QDF_STATUS_E_NOMEM; 8480 } 8481 8482 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8483 8484 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 8485 WMITLV_SET_HDR(&cmd->tlv_header, 8486 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 8487 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 8488 if (is_add_ts) 8489 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 8490 else 8491 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 8492 cmd->num_ric_request = 1; 8493 cmd->is_add_ric = is_add_ts; 8494 8495 buf_ptr += sizeof(wmi_ric_request_fixed_param); 8496 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 8497 8498 buf_ptr += WMI_TLV_HDR_SIZE; 8499 tspec_param = (wmi_ric_tspec *) buf_ptr; 8500 WMITLV_SET_HDR(&tspec_param->tlv_header, 8501 WMITLV_TAG_STRUC_wmi_ric_tspec, 8502 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 8503 8504 if (is_add_ts) 8505 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 8506 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 8507 else 8508 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 8509 #endif 8510 if (ptspecIE) { 8511 /* Fill the tsinfo in the format expected by firmware */ 8512 #ifndef ANI_LITTLE_BIT_ENDIAN 8513 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 8514 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8515 #else 8516 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 8517 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8518 #endif /* ANI_LITTLE_BIT_ENDIAN */ 8519 8520 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 8521 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 8522 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 8523 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 8524 tspec_param->inactivity_interval = ptspecIE->inactInterval; 8525 tspec_param->suspension_interval = ptspecIE->suspendInterval; 8526 tspec_param->svc_start_time = ptspecIE->svcStartTime; 8527 tspec_param->min_data_rate = ptspecIE->minDataRate; 8528 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 8529 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 8530 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 8531 tspec_param->delay_bound = ptspecIE->delayBound; 8532 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 8533 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 8534 tspec_param->medium_time = 0; 8535 } 8536 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 8537 8538 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8539 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 8540 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 8541 __func__); 8542 if (is_add_ts) 8543 ((struct add_ts_param *) msg)->status = 8544 QDF_STATUS_E_FAILURE; 8545 wmi_buf_free(buf); 8546 return QDF_STATUS_E_FAILURE; 8547 } 8548 8549 return QDF_STATUS_SUCCESS; 8550 } 8551 8552 /** 8553 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 8554 * @wmi_handle: wmi handle 8555 * @clear_req: ll stats clear request command params 8556 * 8557 * Return: QDF_STATUS_SUCCESS for success or error code 8558 */ 8559 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 8560 const struct ll_stats_clear_params *clear_req, 8561 uint8_t addr[IEEE80211_ADDR_LEN]) 8562 { 8563 wmi_clear_link_stats_cmd_fixed_param *cmd; 8564 int32_t len; 8565 wmi_buf_t buf; 8566 uint8_t *buf_ptr; 8567 int ret; 8568 8569 len = sizeof(*cmd); 8570 buf = wmi_buf_alloc(wmi_handle, len); 8571 8572 if (!buf) { 8573 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8574 return QDF_STATUS_E_NOMEM; 8575 } 8576 8577 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8578 qdf_mem_zero(buf_ptr, len); 8579 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 8580 8581 WMITLV_SET_HDR(&cmd->tlv_header, 8582 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 8583 WMITLV_GET_STRUCT_TLVLEN 8584 (wmi_clear_link_stats_cmd_fixed_param)); 8585 8586 cmd->stop_stats_collection_req = clear_req->stop_req; 8587 cmd->vdev_id = clear_req->sta_id; 8588 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 8589 8590 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8591 &cmd->peer_macaddr); 8592 8593 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 8594 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 8595 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 8596 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 8597 /* WMI_LOGD("Peer MAC Addr : %pM", 8598 cmd->peer_macaddr); */ 8599 8600 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8601 WMI_CLEAR_LINK_STATS_CMDID); 8602 if (ret) { 8603 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 8604 wmi_buf_free(buf); 8605 return QDF_STATUS_E_FAILURE; 8606 } 8607 8608 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 8609 return QDF_STATUS_SUCCESS; 8610 } 8611 8612 /** 8613 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 8614 * @wmi_handle: wmi handle 8615 * @setReq: ll stats set request command params 8616 * 8617 * Return: QDF_STATUS_SUCCESS for success or error code 8618 */ 8619 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 8620 const struct ll_stats_set_params *set_req) 8621 { 8622 wmi_start_link_stats_cmd_fixed_param *cmd; 8623 int32_t len; 8624 wmi_buf_t buf; 8625 uint8_t *buf_ptr; 8626 int ret; 8627 8628 len = sizeof(*cmd); 8629 buf = wmi_buf_alloc(wmi_handle, len); 8630 8631 if (!buf) { 8632 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8633 return QDF_STATUS_E_NOMEM; 8634 } 8635 8636 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8637 qdf_mem_zero(buf_ptr, len); 8638 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 8639 8640 WMITLV_SET_HDR(&cmd->tlv_header, 8641 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 8642 WMITLV_GET_STRUCT_TLVLEN 8643 (wmi_start_link_stats_cmd_fixed_param)); 8644 8645 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 8646 cmd->aggressive_statistics_gathering = 8647 set_req->aggressive_statistics_gathering; 8648 8649 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 8650 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 8651 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 8652 8653 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8654 WMI_START_LINK_STATS_CMDID); 8655 if (ret) { 8656 WMI_LOGE("%s: Failed to send set link stats request", __func__); 8657 wmi_buf_free(buf); 8658 return QDF_STATUS_E_FAILURE; 8659 } 8660 8661 return QDF_STATUS_SUCCESS; 8662 } 8663 8664 /** 8665 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 8666 * @wmi_handle:wmi handle 8667 * @get_req:ll stats get request command params 8668 * @addr: mac address 8669 * 8670 * Return: QDF_STATUS_SUCCESS for success or error code 8671 */ 8672 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 8673 const struct ll_stats_get_params *get_req, 8674 uint8_t addr[IEEE80211_ADDR_LEN]) 8675 { 8676 wmi_request_link_stats_cmd_fixed_param *cmd; 8677 int32_t len; 8678 wmi_buf_t buf; 8679 uint8_t *buf_ptr; 8680 int ret; 8681 8682 len = sizeof(*cmd); 8683 buf = wmi_buf_alloc(wmi_handle, len); 8684 8685 if (!buf) { 8686 WMI_LOGE("%s: buf allocation failed", __func__); 8687 return QDF_STATUS_E_NOMEM; 8688 } 8689 8690 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8691 qdf_mem_zero(buf_ptr, len); 8692 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 8693 8694 WMITLV_SET_HDR(&cmd->tlv_header, 8695 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 8696 WMITLV_GET_STRUCT_TLVLEN 8697 (wmi_request_link_stats_cmd_fixed_param)); 8698 8699 cmd->request_id = get_req->req_id; 8700 cmd->stats_type = get_req->param_id_mask; 8701 cmd->vdev_id = get_req->sta_id; 8702 8703 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8704 &cmd->peer_macaddr); 8705 8706 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 8707 WMI_LOGD("Request ID : %u", cmd->request_id); 8708 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 8709 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 8710 WMI_LOGD("Peer MAC Addr : %pM", addr); 8711 8712 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8713 WMI_REQUEST_LINK_STATS_CMDID); 8714 if (ret) { 8715 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8716 wmi_buf_free(buf); 8717 return QDF_STATUS_E_FAILURE; 8718 } 8719 8720 return QDF_STATUS_SUCCESS; 8721 } 8722 8723 8724 /** 8725 * send_congestion_cmd_tlv() - send request to fw to get CCA 8726 * @wmi_handle: wmi handle 8727 * @vdev_id: vdev id 8728 * 8729 * Return: CDF status 8730 */ 8731 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8732 uint8_t vdev_id) 8733 { 8734 wmi_buf_t buf; 8735 wmi_request_stats_cmd_fixed_param *cmd; 8736 uint8_t len; 8737 uint8_t *buf_ptr; 8738 8739 len = sizeof(*cmd); 8740 buf = wmi_buf_alloc(wmi_handle, len); 8741 if (!buf) { 8742 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8743 return QDF_STATUS_E_FAILURE; 8744 } 8745 8746 buf_ptr = wmi_buf_data(buf); 8747 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8748 WMITLV_SET_HDR(&cmd->tlv_header, 8749 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8750 WMITLV_GET_STRUCT_TLVLEN 8751 (wmi_request_stats_cmd_fixed_param)); 8752 8753 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8754 cmd->vdev_id = vdev_id; 8755 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8756 cmd->vdev_id, cmd->stats_id); 8757 8758 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8759 WMI_REQUEST_STATS_CMDID)) { 8760 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8761 __func__); 8762 wmi_buf_free(buf); 8763 return QDF_STATUS_E_FAILURE; 8764 } 8765 8766 return QDF_STATUS_SUCCESS; 8767 } 8768 8769 /** 8770 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8771 * @wmi_handle: wmi handle 8772 * @rssi_req: get RSSI request 8773 * 8774 * Return: CDF status 8775 */ 8776 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8777 { 8778 wmi_buf_t buf; 8779 wmi_request_stats_cmd_fixed_param *cmd; 8780 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8781 8782 buf = wmi_buf_alloc(wmi_handle, len); 8783 if (!buf) { 8784 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8785 return QDF_STATUS_E_FAILURE; 8786 } 8787 8788 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8789 WMITLV_SET_HDR(&cmd->tlv_header, 8790 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8791 WMITLV_GET_STRUCT_TLVLEN 8792 (wmi_request_stats_cmd_fixed_param)); 8793 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8794 if (wmi_unified_cmd_send 8795 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8796 WMI_LOGE("Failed to send host stats request to fw"); 8797 wmi_buf_free(buf); 8798 return QDF_STATUS_E_FAILURE; 8799 } 8800 8801 return QDF_STATUS_SUCCESS; 8802 } 8803 8804 /** 8805 * send_snr_cmd_tlv() - get RSSI from fw 8806 * @wmi_handle: wmi handle 8807 * @vdev_id: vdev id 8808 * 8809 * Return: CDF status 8810 */ 8811 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8812 { 8813 wmi_buf_t buf; 8814 wmi_request_stats_cmd_fixed_param *cmd; 8815 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8816 8817 buf = wmi_buf_alloc(wmi_handle, len); 8818 if (!buf) { 8819 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8820 return QDF_STATUS_E_FAILURE; 8821 } 8822 8823 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8824 cmd->vdev_id = vdev_id; 8825 8826 WMITLV_SET_HDR(&cmd->tlv_header, 8827 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8828 WMITLV_GET_STRUCT_TLVLEN 8829 (wmi_request_stats_cmd_fixed_param)); 8830 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8831 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8832 WMI_REQUEST_STATS_CMDID)) { 8833 WMI_LOGE("Failed to send host stats request to fw"); 8834 wmi_buf_free(buf); 8835 return QDF_STATUS_E_FAILURE; 8836 } 8837 8838 return QDF_STATUS_SUCCESS; 8839 } 8840 8841 /** 8842 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8843 * @wmi_handle: wmi handle 8844 * @link_status: get link params 8845 * 8846 * Return: CDF status 8847 */ 8848 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8849 struct link_status_params *link_status) 8850 { 8851 wmi_buf_t buf; 8852 wmi_request_stats_cmd_fixed_param *cmd; 8853 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8854 8855 buf = wmi_buf_alloc(wmi_handle, len); 8856 if (!buf) { 8857 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8858 return QDF_STATUS_E_FAILURE; 8859 } 8860 8861 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8862 WMITLV_SET_HDR(&cmd->tlv_header, 8863 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8864 WMITLV_GET_STRUCT_TLVLEN 8865 (wmi_request_stats_cmd_fixed_param)); 8866 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8867 cmd->vdev_id = link_status->session_id; 8868 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8869 WMI_REQUEST_STATS_CMDID)) { 8870 WMI_LOGE("Failed to send WMI link status request to fw"); 8871 wmi_buf_free(buf); 8872 return QDF_STATUS_E_FAILURE; 8873 } 8874 8875 return QDF_STATUS_SUCCESS; 8876 } 8877 8878 /** 8879 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8880 * @wmi_handle: wmi handle 8881 * @ta_dhcp_ind: DHCP indication parameter 8882 * 8883 * Return: CDF Status 8884 */ 8885 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8886 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8887 { 8888 QDF_STATUS status; 8889 wmi_buf_t buf = NULL; 8890 uint8_t *buf_ptr; 8891 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8892 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8893 8894 8895 buf = wmi_buf_alloc(wmi_handle, len); 8896 if (!buf) { 8897 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8898 return QDF_STATUS_E_NOMEM; 8899 } 8900 8901 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8902 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8903 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8904 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8905 WMITLV_GET_STRUCT_TLVLEN 8906 (wmi_peer_set_param_cmd_fixed_param)); 8907 8908 /* fill in values */ 8909 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8910 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8911 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8912 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8913 &ta_dhcp_ind->peer_macaddr, 8914 sizeof(ta_dhcp_ind->peer_macaddr)); 8915 8916 status = wmi_unified_cmd_send(wmi_handle, buf, 8917 len, WMI_PEER_SET_PARAM_CMDID); 8918 if (QDF_IS_STATUS_ERROR(status)) { 8919 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8920 " returned Error %d", __func__, status); 8921 wmi_buf_free(buf); 8922 } 8923 8924 return status; 8925 } 8926 8927 /** 8928 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8929 * @wmi_handle: wmi handle 8930 * @pLinkSpeed: link speed info 8931 * 8932 * Return: CDF status 8933 */ 8934 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8935 wmi_mac_addr peer_macaddr) 8936 { 8937 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8938 wmi_buf_t wmi_buf; 8939 uint32_t len; 8940 uint8_t *buf_ptr; 8941 8942 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8943 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8944 if (!wmi_buf) { 8945 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8946 return QDF_STATUS_E_NOMEM; 8947 } 8948 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8949 8950 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8951 WMITLV_SET_HDR(&cmd->tlv_header, 8952 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8953 WMITLV_GET_STRUCT_TLVLEN 8954 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8955 8956 /* Copy the peer macaddress to the wma buffer */ 8957 qdf_mem_copy(&cmd->peer_macaddr, 8958 &peer_macaddr, 8959 sizeof(peer_macaddr)); 8960 8961 8962 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8963 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8964 WMI_LOGE("%s: failed to send link speed command", __func__); 8965 wmi_buf_free(wmi_buf); 8966 return QDF_STATUS_E_FAILURE; 8967 } 8968 return QDF_STATUS_SUCCESS; 8969 } 8970 8971 #ifdef WLAN_SUPPORT_GREEN_AP 8972 /** 8973 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8974 * @wmi_handle: wmi handler 8975 * @egap_params: pointer to egap_params 8976 * 8977 * Return: 0 for success, otherwise appropriate error code 8978 */ 8979 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8980 struct wlan_green_ap_egap_params *egap_params) 8981 { 8982 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8983 wmi_buf_t buf; 8984 int32_t err; 8985 8986 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8987 if (!buf) { 8988 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8989 return QDF_STATUS_E_NOMEM; 8990 } 8991 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8992 WMITLV_SET_HDR(&cmd->tlv_header, 8993 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8994 WMITLV_GET_STRUCT_TLVLEN( 8995 wmi_ap_ps_egap_param_cmd_fixed_param)); 8996 8997 cmd->enable = egap_params->host_enable_egap; 8998 cmd->inactivity_time = egap_params->egap_inactivity_time; 8999 cmd->wait_time = egap_params->egap_wait_time; 9000 cmd->flags = egap_params->egap_feature_flags; 9001 err = wmi_unified_cmd_send(wmi_handle, buf, 9002 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 9003 if (err) { 9004 WMI_LOGE("Failed to send ap_ps_egap cmd"); 9005 wmi_buf_free(buf); 9006 return QDF_STATUS_E_FAILURE; 9007 } 9008 9009 return QDF_STATUS_SUCCESS; 9010 } 9011 #endif 9012 9013 /** 9014 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 9015 * @wmi_handl: wmi handle 9016 * @cmd: Profiling command index 9017 * @value1: parameter1 value 9018 * @value2: parameter2 value 9019 * 9020 * Return: QDF_STATUS_SUCCESS for success else error code 9021 */ 9022 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 9023 uint32_t cmd, uint32_t value1, uint32_t value2) 9024 { 9025 wmi_buf_t buf; 9026 int32_t len = 0; 9027 int ret; 9028 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 9029 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9030 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 9031 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 9032 9033 switch (cmd) { 9034 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 9035 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 9036 buf = wmi_buf_alloc(wmi_handle, len); 9037 if (!buf) { 9038 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9039 return QDF_STATUS_E_NOMEM; 9040 } 9041 prof_trig_cmd = 9042 (wmi_wlan_profile_trigger_cmd_fixed_param *) 9043 wmi_buf_data(buf); 9044 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 9045 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 9046 WMITLV_GET_STRUCT_TLVLEN 9047 (wmi_wlan_profile_trigger_cmd_fixed_param)); 9048 prof_trig_cmd->enable = value1; 9049 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9050 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9051 if (ret) { 9052 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 9053 value1); 9054 wmi_buf_free(buf); 9055 return ret; 9056 } 9057 break; 9058 9059 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 9060 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 9061 buf = wmi_buf_alloc(wmi_handle, len); 9062 if (!buf) { 9063 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9064 return QDF_STATUS_E_NOMEM; 9065 } 9066 profile_getdata_cmd = 9067 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 9068 wmi_buf_data(buf); 9069 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 9070 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 9071 WMITLV_GET_STRUCT_TLVLEN 9072 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 9073 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9074 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 9075 if (ret) { 9076 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 9077 value1, value2); 9078 wmi_buf_free(buf); 9079 return ret; 9080 } 9081 break; 9082 9083 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 9084 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9085 buf = wmi_buf_alloc(wmi_handle, len); 9086 if (!buf) { 9087 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9088 return QDF_STATUS_E_NOMEM; 9089 } 9090 hist_intvl_cmd = 9091 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9092 wmi_buf_data(buf); 9093 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9094 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9095 WMITLV_GET_STRUCT_TLVLEN 9096 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9097 hist_intvl_cmd->profile_id = value1; 9098 hist_intvl_cmd->value = value2; 9099 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9100 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9101 if (ret) { 9102 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 9103 value1, value2); 9104 wmi_buf_free(buf); 9105 return ret; 9106 } 9107 break; 9108 9109 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 9110 len = 9111 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 9112 buf = wmi_buf_alloc(wmi_handle, len); 9113 if (!buf) { 9114 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9115 return QDF_STATUS_E_NOMEM; 9116 } 9117 profile_enable_cmd = 9118 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 9119 wmi_buf_data(buf); 9120 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 9121 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 9122 WMITLV_GET_STRUCT_TLVLEN 9123 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 9124 profile_enable_cmd->profile_id = value1; 9125 profile_enable_cmd->enable = value2; 9126 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9127 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 9128 if (ret) { 9129 WMI_LOGE("enable cmd Failed for id %d value %d", 9130 value1, value2); 9131 wmi_buf_free(buf); 9132 return ret; 9133 } 9134 break; 9135 9136 default: 9137 WMI_LOGD("%s: invalid profiling command", __func__); 9138 break; 9139 } 9140 9141 return 0; 9142 } 9143 9144 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 9145 struct wlm_latency_level_param *params) 9146 { 9147 wmi_wlm_config_cmd_fixed_param *cmd; 9148 wmi_buf_t buf; 9149 uint32_t len = sizeof(*cmd); 9150 static uint32_t ll[4] = {100, 60, 40, 20}; 9151 9152 buf = wmi_buf_alloc(wmi_handle, len); 9153 if (!buf) { 9154 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9155 return QDF_STATUS_E_NOMEM; 9156 } 9157 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 9158 WMITLV_SET_HDR(&cmd->tlv_header, 9159 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 9160 WMITLV_GET_STRUCT_TLVLEN 9161 (wmi_wlm_config_cmd_fixed_param)); 9162 cmd->vdev_id = params->vdev_id; 9163 cmd->latency_level = params->wlm_latency_level; 9164 cmd->ul_latency = ll[params->wlm_latency_level]; 9165 cmd->dl_latency = ll[params->wlm_latency_level]; 9166 cmd->flags = params->wlm_latency_flags; 9167 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9168 WMI_WLM_CONFIG_CMDID)) { 9169 WMI_LOGE("%s: Failed to send setting latency config command", 9170 __func__); 9171 wmi_buf_free(buf); 9172 return QDF_STATUS_E_FAILURE; 9173 } 9174 9175 return 0; 9176 } 9177 /** 9178 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 9179 * @wmi_handle: wmi handle 9180 * @vdev_id: vdev id 9181 * 9182 * Return: QDF_STATUS_SUCCESS for success or error code 9183 */ 9184 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 9185 { 9186 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 9187 wmi_buf_t buf; 9188 int32_t len = sizeof(*cmd); 9189 9190 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9191 buf = wmi_buf_alloc(wmi_handle, len); 9192 if (!buf) { 9193 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9194 return QDF_STATUS_E_NOMEM; 9195 } 9196 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 9197 wmi_buf_data(buf); 9198 WMITLV_SET_HDR(&cmd->tlv_header, 9199 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 9200 WMITLV_GET_STRUCT_TLVLEN 9201 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 9202 cmd->vdev_id = vdev_id; 9203 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 9204 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9205 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 9206 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 9207 __func__); 9208 wmi_buf_free(buf); 9209 return QDF_STATUS_E_FAILURE; 9210 } 9211 9212 return 0; 9213 } 9214 9215 /** 9216 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 9217 * @wmi_handle: wmi handle 9218 * @vdev_id: vdev id 9219 * 9220 * Return: QDF_STATUS_SUCCESS for success or error code 9221 */ 9222 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 9223 uint8_t vdev_id) 9224 { 9225 wmi_csa_offload_enable_cmd_fixed_param *cmd; 9226 wmi_buf_t buf; 9227 int32_t len = sizeof(*cmd); 9228 9229 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9230 buf = wmi_buf_alloc(wmi_handle, len); 9231 if (!buf) { 9232 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9233 return QDF_STATUS_E_NOMEM; 9234 } 9235 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 9236 WMITLV_SET_HDR(&cmd->tlv_header, 9237 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 9238 WMITLV_GET_STRUCT_TLVLEN 9239 (wmi_csa_offload_enable_cmd_fixed_param)); 9240 cmd->vdev_id = vdev_id; 9241 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 9242 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9243 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 9244 WMI_LOGP("%s: Failed to send CSA offload enable command", 9245 __func__); 9246 wmi_buf_free(buf); 9247 return QDF_STATUS_E_FAILURE; 9248 } 9249 9250 return 0; 9251 } 9252 9253 #ifdef WLAN_FEATURE_CIF_CFR 9254 /** 9255 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 9256 * @wmi_handle: wmi handle 9257 * @data_len: len of dma cfg req 9258 * @data: dma cfg req 9259 * 9260 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9261 */ 9262 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9263 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 9264 { 9265 wmi_buf_t buf; 9266 uint8_t *cmd; 9267 QDF_STATUS ret; 9268 9269 WMITLV_SET_HDR(cfg, 9270 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 9271 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 9272 9273 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 9274 if (!buf) { 9275 WMI_LOGE(FL("wmi_buf_alloc failed")); 9276 return QDF_STATUS_E_FAILURE; 9277 } 9278 9279 cmd = (uint8_t *) wmi_buf_data(buf); 9280 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 9281 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 9282 sizeof(*cfg)); 9283 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 9284 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 9285 if (QDF_IS_STATUS_ERROR(ret)) { 9286 WMI_LOGE(FL(":wmi cmd send failed")); 9287 wmi_buf_free(buf); 9288 } 9289 9290 return ret; 9291 } 9292 #endif 9293 9294 /** 9295 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 9296 * @wmi_handle: wmi handle 9297 * @data_len: len of dma cfg req 9298 * @data: dma cfg req 9299 * 9300 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9301 */ 9302 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9303 struct direct_buf_rx_cfg_req *cfg) 9304 { 9305 wmi_buf_t buf; 9306 wmi_dma_ring_cfg_req_fixed_param *cmd; 9307 QDF_STATUS ret; 9308 int32_t len = sizeof(*cmd); 9309 9310 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9311 if (!buf) { 9312 WMI_LOGE(FL("wmi_buf_alloc failed")); 9313 return QDF_STATUS_E_FAILURE; 9314 } 9315 9316 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 9317 9318 WMITLV_SET_HDR(&cmd->tlv_header, 9319 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 9320 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 9321 9322 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9323 cfg->pdev_id); 9324 cmd->mod_id = cfg->mod_id; 9325 cmd->base_paddr_lo = cfg->base_paddr_lo; 9326 cmd->base_paddr_hi = cfg->base_paddr_hi; 9327 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 9328 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 9329 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 9330 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 9331 cmd->num_elems = cfg->num_elems; 9332 cmd->buf_size = cfg->buf_size; 9333 cmd->num_resp_per_event = cfg->num_resp_per_event; 9334 cmd->event_timeout_ms = cfg->event_timeout_ms; 9335 9336 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 9337 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 9338 "head idx paddr hi %x tail idx paddr lo %x" 9339 "tail idx addr hi %x num elems %d buf size %d num resp %d" 9340 "event timeout %d\n", __func__, cmd->pdev_id, 9341 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 9342 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 9343 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 9344 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 9345 cmd->event_timeout_ms); 9346 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9347 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 9348 if (QDF_IS_STATUS_ERROR(ret)) { 9349 WMI_LOGE(FL(":wmi cmd send failed")); 9350 wmi_buf_free(buf); 9351 } 9352 9353 return ret; 9354 } 9355 9356 /** 9357 * send_start_11d_scan_cmd_tlv() - start 11d scan request 9358 * @wmi_handle: wmi handle 9359 * @start_11d_scan: 11d scan start request parameters 9360 * 9361 * This function request FW to start 11d scan. 9362 * 9363 * Return: QDF status 9364 */ 9365 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9366 struct reg_start_11d_scan_req *start_11d_scan) 9367 { 9368 wmi_11d_scan_start_cmd_fixed_param *cmd; 9369 int32_t len; 9370 wmi_buf_t buf; 9371 int ret; 9372 9373 len = sizeof(*cmd); 9374 buf = wmi_buf_alloc(wmi_handle, len); 9375 if (!buf) { 9376 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9377 return QDF_STATUS_E_NOMEM; 9378 } 9379 9380 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 9381 9382 WMITLV_SET_HDR(&cmd->tlv_header, 9383 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 9384 WMITLV_GET_STRUCT_TLVLEN 9385 (wmi_11d_scan_start_cmd_fixed_param)); 9386 9387 cmd->vdev_id = start_11d_scan->vdev_id; 9388 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 9389 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 9390 9391 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 9392 9393 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9394 WMI_11D_SCAN_START_CMDID); 9395 if (ret) { 9396 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 9397 wmi_buf_free(buf); 9398 return QDF_STATUS_E_FAILURE; 9399 } 9400 9401 return QDF_STATUS_SUCCESS; 9402 } 9403 9404 /** 9405 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 9406 * @wmi_handle: wmi handle 9407 * @start_11d_scan: 11d scan stop request parameters 9408 * 9409 * This function request FW to stop 11d scan. 9410 * 9411 * Return: QDF status 9412 */ 9413 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9414 struct reg_stop_11d_scan_req *stop_11d_scan) 9415 { 9416 wmi_11d_scan_stop_cmd_fixed_param *cmd; 9417 int32_t len; 9418 wmi_buf_t buf; 9419 int ret; 9420 9421 len = sizeof(*cmd); 9422 buf = wmi_buf_alloc(wmi_handle, len); 9423 if (!buf) { 9424 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9425 return QDF_STATUS_E_NOMEM; 9426 } 9427 9428 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 9429 9430 WMITLV_SET_HDR(&cmd->tlv_header, 9431 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 9432 WMITLV_GET_STRUCT_TLVLEN 9433 (wmi_11d_scan_stop_cmd_fixed_param)); 9434 9435 cmd->vdev_id = stop_11d_scan->vdev_id; 9436 9437 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 9438 9439 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9440 WMI_11D_SCAN_STOP_CMDID); 9441 if (ret) { 9442 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 9443 wmi_buf_free(buf); 9444 return QDF_STATUS_E_FAILURE; 9445 } 9446 9447 return QDF_STATUS_SUCCESS; 9448 } 9449 9450 /** 9451 * send_start_oem_data_cmd_tlv() - start OEM data request to target 9452 * @wmi_handle: wmi handle 9453 * @startOemDataReq: start request params 9454 * 9455 * Return: CDF status 9456 */ 9457 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 9458 uint32_t data_len, 9459 uint8_t *data) 9460 { 9461 wmi_buf_t buf; 9462 uint8_t *cmd; 9463 QDF_STATUS ret; 9464 9465 buf = wmi_buf_alloc(wmi_handle, 9466 (data_len + WMI_TLV_HDR_SIZE)); 9467 if (!buf) { 9468 WMI_LOGE(FL("wmi_buf_alloc failed")); 9469 return QDF_STATUS_E_FAILURE; 9470 } 9471 9472 cmd = (uint8_t *) wmi_buf_data(buf); 9473 9474 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 9475 cmd += WMI_TLV_HDR_SIZE; 9476 qdf_mem_copy(cmd, data, 9477 data_len); 9478 9479 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 9480 data_len); 9481 9482 ret = wmi_unified_cmd_send(wmi_handle, buf, 9483 (data_len + 9484 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 9485 9486 if (QDF_IS_STATUS_ERROR(ret)) { 9487 WMI_LOGE(FL(":wmi cmd send failed")); 9488 wmi_buf_free(buf); 9489 } 9490 9491 return ret; 9492 } 9493 9494 /** 9495 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 9496 * @wmi_handle: wmi handle 9497 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 9498 * 9499 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 9500 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 9501 * to firmware based on phyerr filtering 9502 * offload status. 9503 * 9504 * Return: 1 success, 0 failure 9505 */ 9506 static QDF_STATUS 9507 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9508 bool dfs_phyerr_filter_offload) 9509 { 9510 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 9511 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 9512 wmi_buf_t buf; 9513 uint16_t len; 9514 QDF_STATUS ret; 9515 9516 9517 if (false == dfs_phyerr_filter_offload) { 9518 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 9519 __func__); 9520 len = sizeof(*disable_phyerr_offload_cmd); 9521 buf = wmi_buf_alloc(wmi_handle, len); 9522 if (!buf) { 9523 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9524 return 0; 9525 } 9526 disable_phyerr_offload_cmd = 9527 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 9528 wmi_buf_data(buf); 9529 9530 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 9531 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 9532 WMITLV_GET_STRUCT_TLVLEN 9533 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 9534 9535 /* 9536 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 9537 * to the firmware to disable the phyerror 9538 * filtering offload. 9539 */ 9540 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9541 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 9542 if (QDF_IS_STATUS_ERROR(ret)) { 9543 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 9544 __func__, ret); 9545 wmi_buf_free(buf); 9546 return QDF_STATUS_E_FAILURE; 9547 } 9548 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 9549 __func__); 9550 } else { 9551 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 9552 __func__); 9553 9554 len = sizeof(*enable_phyerr_offload_cmd); 9555 buf = wmi_buf_alloc(wmi_handle, len); 9556 if (!buf) { 9557 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9558 return QDF_STATUS_E_FAILURE; 9559 } 9560 9561 enable_phyerr_offload_cmd = 9562 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 9563 wmi_buf_data(buf); 9564 9565 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 9566 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 9567 WMITLV_GET_STRUCT_TLVLEN 9568 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 9569 9570 /* 9571 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 9572 * to the firmware to enable the phyerror 9573 * filtering offload. 9574 */ 9575 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9576 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 9577 9578 if (QDF_IS_STATUS_ERROR(ret)) { 9579 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 9580 __func__, ret); 9581 wmi_buf_free(buf); 9582 return QDF_STATUS_E_FAILURE; 9583 } 9584 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 9585 __func__); 9586 } 9587 9588 return QDF_STATUS_SUCCESS; 9589 } 9590 9591 /** 9592 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 9593 * will wake up host after specified time is elapsed 9594 * @wmi_handle: wmi handle 9595 * @vdev_id: vdev id 9596 * @cookie: value to identify reason why host set up wake call. 9597 * @time: time in ms 9598 * 9599 * Return: QDF status 9600 */ 9601 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9602 uint8_t vdev_id, uint32_t cookie, uint32_t time) 9603 { 9604 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 9605 wmi_buf_t buf; 9606 uint8_t *buf_ptr; 9607 int32_t len; 9608 int ret; 9609 9610 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 9611 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 9612 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 9613 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 9614 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 9615 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 9616 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 9617 9618 buf = wmi_buf_alloc(wmi_handle, len); 9619 if (!buf) { 9620 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9621 return QDF_STATUS_E_NOMEM; 9622 } 9623 9624 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9625 buf_ptr = (uint8_t *) cmd; 9626 9627 WMITLV_SET_HDR(&cmd->tlv_header, 9628 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 9629 WMITLV_GET_STRUCT_TLVLEN 9630 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 9631 cmd->vdev_id = vdev_id; 9632 cmd->pattern_id = cookie, 9633 cmd->pattern_type = WOW_TIMER_PATTERN; 9634 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 9635 9636 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 9637 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9638 buf_ptr += WMI_TLV_HDR_SIZE; 9639 9640 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 9641 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9642 buf_ptr += WMI_TLV_HDR_SIZE; 9643 9644 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 9645 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9646 buf_ptr += WMI_TLV_HDR_SIZE; 9647 9648 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 9649 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9650 buf_ptr += WMI_TLV_HDR_SIZE; 9651 9652 /* Fill TLV for pattern_info_timeout, and time value */ 9653 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9654 buf_ptr += WMI_TLV_HDR_SIZE; 9655 *((uint32_t *) buf_ptr) = time; 9656 buf_ptr += sizeof(uint32_t); 9657 9658 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 9659 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9660 buf_ptr += WMI_TLV_HDR_SIZE; 9661 *((uint32_t *) buf_ptr) = 0; 9662 9663 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 9664 __func__, time, vdev_id); 9665 9666 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9667 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 9668 if (ret) { 9669 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 9670 __func__); 9671 wmi_buf_free(buf); 9672 return QDF_STATUS_E_FAILURE; 9673 } 9674 9675 return QDF_STATUS_SUCCESS; 9676 } 9677 9678 #if !defined(REMOVE_PKT_LOG) 9679 /** 9680 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 9681 * @wmi_handle: wmi handle 9682 * @pktlog_event: pktlog event 9683 * @cmd_id: pktlog cmd id 9684 * 9685 * Return: CDF status 9686 */ 9687 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 9688 WMI_PKTLOG_EVENT pktlog_event, 9689 WMI_CMD_ID cmd_id, uint8_t user_triggered) 9690 { 9691 WMI_PKTLOG_EVENT PKTLOG_EVENT; 9692 WMI_CMD_ID CMD_ID; 9693 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 9694 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 9695 int len = 0; 9696 wmi_buf_t buf; 9697 9698 PKTLOG_EVENT = pktlog_event; 9699 CMD_ID = cmd_id; 9700 9701 switch (CMD_ID) { 9702 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 9703 len = sizeof(*cmd); 9704 buf = wmi_buf_alloc(wmi_handle, len); 9705 if (!buf) { 9706 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9707 return QDF_STATUS_E_NOMEM; 9708 } 9709 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 9710 wmi_buf_data(buf); 9711 WMITLV_SET_HDR(&cmd->tlv_header, 9712 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9713 WMITLV_GET_STRUCT_TLVLEN 9714 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9715 cmd->evlist = PKTLOG_EVENT; 9716 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9717 : WMI_PKTLOG_ENABLE_AUTO; 9718 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9719 WMI_HOST_PDEV_ID_SOC); 9720 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9721 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9722 WMI_LOGE("failed to send pktlog enable cmdid"); 9723 goto wmi_send_failed; 9724 } 9725 break; 9726 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9727 len = sizeof(*disable_cmd); 9728 buf = wmi_buf_alloc(wmi_handle, len); 9729 if (!buf) { 9730 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9731 return QDF_STATUS_E_NOMEM; 9732 } 9733 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9734 wmi_buf_data(buf); 9735 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9736 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9737 WMITLV_GET_STRUCT_TLVLEN 9738 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9739 disable_cmd->pdev_id = 9740 wmi_handle->ops->convert_pdev_id_host_to_target( 9741 WMI_HOST_PDEV_ID_SOC); 9742 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9743 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9744 WMI_LOGE("failed to send pktlog disable cmdid"); 9745 goto wmi_send_failed; 9746 } 9747 break; 9748 default: 9749 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9750 break; 9751 } 9752 9753 return QDF_STATUS_SUCCESS; 9754 9755 wmi_send_failed: 9756 wmi_buf_free(buf); 9757 return QDF_STATUS_E_FAILURE; 9758 } 9759 #endif /* REMOVE_PKT_LOG */ 9760 9761 /** 9762 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9763 * @wmi_handle: wmi handle 9764 * @ptrn_id: pattern id 9765 * @vdev_id: vdev id 9766 * 9767 * Return: CDF status 9768 */ 9769 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9770 uint8_t ptrn_id, uint8_t vdev_id) 9771 { 9772 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9773 wmi_buf_t buf; 9774 int32_t len; 9775 int ret; 9776 9777 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9778 9779 9780 buf = wmi_buf_alloc(wmi_handle, len); 9781 if (!buf) { 9782 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9783 return QDF_STATUS_E_NOMEM; 9784 } 9785 9786 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9787 9788 WMITLV_SET_HDR(&cmd->tlv_header, 9789 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9790 WMITLV_GET_STRUCT_TLVLEN( 9791 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9792 cmd->vdev_id = vdev_id; 9793 cmd->pattern_id = ptrn_id; 9794 cmd->pattern_type = WOW_BITMAP_PATTERN; 9795 9796 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9797 cmd->pattern_id, vdev_id); 9798 9799 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9800 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9801 if (ret) { 9802 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9803 wmi_buf_free(buf); 9804 return QDF_STATUS_E_FAILURE; 9805 } 9806 9807 return QDF_STATUS_SUCCESS; 9808 } 9809 9810 /** 9811 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9812 * @wmi_handle: wmi handle 9813 * 9814 * Sends host wakeup indication to FW. On receiving this indication, 9815 * FW will come out of WOW. 9816 * 9817 * Return: CDF status 9818 */ 9819 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9820 { 9821 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9822 wmi_buf_t buf; 9823 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9824 int32_t len; 9825 int ret; 9826 9827 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9828 9829 buf = wmi_buf_alloc(wmi_handle, len); 9830 if (!buf) { 9831 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9832 return QDF_STATUS_E_NOMEM; 9833 } 9834 9835 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9836 wmi_buf_data(buf); 9837 WMITLV_SET_HDR(&cmd->tlv_header, 9838 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9839 WMITLV_GET_STRUCT_TLVLEN 9840 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9841 9842 9843 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9844 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9845 if (ret) { 9846 WMI_LOGE("Failed to send host wakeup indication to fw"); 9847 wmi_buf_free(buf); 9848 return QDF_STATUS_E_FAILURE; 9849 } 9850 9851 return qdf_status; 9852 } 9853 9854 /** 9855 * send_del_ts_cmd_tlv() - send DELTS request to fw 9856 * @wmi_handle: wmi handle 9857 * @msg: delts params 9858 * 9859 * Return: CDF status 9860 */ 9861 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9862 uint8_t ac) 9863 { 9864 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9865 wmi_buf_t buf; 9866 int32_t len = sizeof(*cmd); 9867 9868 buf = wmi_buf_alloc(wmi_handle, len); 9869 if (!buf) { 9870 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9871 return QDF_STATUS_E_NOMEM; 9872 } 9873 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9874 WMITLV_SET_HDR(&cmd->tlv_header, 9875 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9876 WMITLV_GET_STRUCT_TLVLEN 9877 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9878 cmd->vdev_id = vdev_id; 9879 cmd->ac = ac; 9880 9881 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9882 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9883 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9884 WMI_VDEV_WMM_DELTS_CMDID)) { 9885 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9886 wmi_buf_free(buf); 9887 return QDF_STATUS_E_FAILURE; 9888 } 9889 9890 return QDF_STATUS_SUCCESS; 9891 } 9892 9893 /** 9894 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9895 * @wmi_handle: handle to wmi 9896 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9897 * 9898 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9899 * ADD_TS requestes to firmware in loop for all the ACs with 9900 * active flow. 9901 * 9902 * Return: CDF status 9903 */ 9904 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9905 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9906 { 9907 int i = 0; 9908 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9909 wmi_buf_t buf; 9910 int32_t len = sizeof(*cmd); 9911 9912 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9913 /* if flow in this AC is active */ 9914 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9915 /* 9916 * as per implementation of wma_add_ts_req() we 9917 * are not waiting any response from firmware so 9918 * apart from sending ADDTS to firmware just send 9919 * success to upper layers 9920 */ 9921 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9922 9923 buf = wmi_buf_alloc(wmi_handle, len); 9924 if (!buf) { 9925 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9926 return QDF_STATUS_E_NOMEM; 9927 } 9928 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9929 wmi_buf_data(buf); 9930 WMITLV_SET_HDR(&cmd->tlv_header, 9931 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9932 WMITLV_GET_STRUCT_TLVLEN 9933 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9934 cmd->vdev_id = aggr_qos_rsp_msg->sessionId; 9935 cmd->ac = 9936 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9937 traffic.userPrio); 9938 cmd->medium_time_us = 9939 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9940 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9941 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9942 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9943 cmd->medium_time_us, cmd->downgrade_type); 9944 if (wmi_unified_cmd_send 9945 (wmi_handle, buf, len, 9946 WMI_VDEV_WMM_ADDTS_CMDID)) { 9947 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9948 __func__); 9949 aggr_qos_rsp_msg->status[i] = 9950 QDF_STATUS_E_FAILURE; 9951 wmi_buf_free(buf); 9952 return QDF_STATUS_E_FAILURE; 9953 } 9954 } 9955 } 9956 9957 return QDF_STATUS_SUCCESS; 9958 } 9959 9960 /** 9961 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9962 * @wmi_handle: wmi handle 9963 * @msg: ADDTS params 9964 * 9965 * Return: CDF status 9966 */ 9967 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9968 struct add_ts_param *msg) 9969 { 9970 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9971 wmi_buf_t buf; 9972 int32_t len = sizeof(*cmd); 9973 9974 msg->status = QDF_STATUS_SUCCESS; 9975 9976 buf = wmi_buf_alloc(wmi_handle, len); 9977 if (!buf) { 9978 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9979 return QDF_STATUS_E_NOMEM; 9980 } 9981 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9982 WMITLV_SET_HDR(&cmd->tlv_header, 9983 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9984 WMITLV_GET_STRUCT_TLVLEN 9985 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9986 cmd->vdev_id = msg->sme_session_id; 9987 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9988 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9989 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9990 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9991 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9992 cmd->downgrade_type, __func__, __LINE__); 9993 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9994 WMI_VDEV_WMM_ADDTS_CMDID)) { 9995 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9996 msg->status = QDF_STATUS_E_FAILURE; 9997 wmi_buf_free(buf); 9998 return QDF_STATUS_E_FAILURE; 9999 } 10000 10001 return QDF_STATUS_SUCCESS; 10002 } 10003 10004 /** 10005 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 10006 * @wmi_handle: wmi handle 10007 * @pAddPeriodicTxPtrnParams: tx ptrn params 10008 * 10009 * Retrun: CDF status 10010 */ 10011 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10012 struct periodic_tx_pattern * 10013 pAddPeriodicTxPtrnParams, 10014 uint8_t vdev_id) 10015 { 10016 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10017 wmi_buf_t wmi_buf; 10018 uint32_t len; 10019 uint8_t *buf_ptr; 10020 uint32_t ptrn_len, ptrn_len_aligned; 10021 int j; 10022 10023 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 10024 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 10025 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 10026 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 10027 10028 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10029 if (!wmi_buf) { 10030 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10031 return QDF_STATUS_E_NOMEM; 10032 } 10033 10034 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10035 10036 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 10037 WMITLV_SET_HDR(&cmd->tlv_header, 10038 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10039 WMITLV_GET_STRUCT_TLVLEN 10040 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10041 10042 /* Pass the pattern id to delete for the corresponding vdev id */ 10043 cmd->vdev_id = vdev_id; 10044 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 10045 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 10046 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 10047 10048 /* Pattern info */ 10049 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10050 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 10051 buf_ptr += WMI_TLV_HDR_SIZE; 10052 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 10053 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 10054 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 10055 10056 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 10057 __func__, cmd->pattern_id, cmd->vdev_id); 10058 10059 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10060 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10061 WMI_LOGE("%s: failed to add pattern set state command", 10062 __func__); 10063 wmi_buf_free(wmi_buf); 10064 return QDF_STATUS_E_FAILURE; 10065 } 10066 return QDF_STATUS_SUCCESS; 10067 } 10068 10069 /** 10070 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 10071 * @wmi_handle: wmi handle 10072 * @vdev_id: vdev id 10073 * @pattern_id: pattern id 10074 * 10075 * Retrun: CDF status 10076 */ 10077 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10078 uint8_t vdev_id, 10079 uint8_t pattern_id) 10080 { 10081 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10082 wmi_buf_t wmi_buf; 10083 uint32_t len = 10084 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10085 10086 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10087 if (!wmi_buf) { 10088 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10089 return QDF_STATUS_E_NOMEM; 10090 } 10091 10092 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 10093 wmi_buf_data(wmi_buf); 10094 WMITLV_SET_HDR(&cmd->tlv_header, 10095 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10096 WMITLV_GET_STRUCT_TLVLEN 10097 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10098 10099 /* Pass the pattern id to delete for the corresponding vdev id */ 10100 cmd->vdev_id = vdev_id; 10101 cmd->pattern_id = pattern_id; 10102 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 10103 __func__, cmd->pattern_id, cmd->vdev_id); 10104 10105 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10106 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10107 WMI_LOGE("%s: failed to send del pattern command", __func__); 10108 wmi_buf_free(wmi_buf); 10109 return QDF_STATUS_E_FAILURE; 10110 } 10111 return QDF_STATUS_SUCCESS; 10112 } 10113 10114 /** 10115 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 10116 * @wmi_handle: wmi handle 10117 * @preq: stats ext params 10118 * 10119 * Return: CDF status 10120 */ 10121 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 10122 struct stats_ext_params *preq) 10123 { 10124 QDF_STATUS ret; 10125 wmi_req_stats_ext_cmd_fixed_param *cmd; 10126 wmi_buf_t buf; 10127 uint16_t len; 10128 uint8_t *buf_ptr; 10129 10130 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 10131 10132 buf = wmi_buf_alloc(wmi_handle, len); 10133 if (!buf) { 10134 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10135 return QDF_STATUS_E_NOMEM; 10136 } 10137 10138 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10139 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 10140 10141 WMITLV_SET_HDR(&cmd->tlv_header, 10142 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 10143 WMITLV_GET_STRUCT_TLVLEN 10144 (wmi_req_stats_ext_cmd_fixed_param)); 10145 cmd->vdev_id = preq->vdev_id; 10146 cmd->data_len = preq->request_data_len; 10147 10148 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 10149 __func__, preq->request_data_len, preq->vdev_id); 10150 10151 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 10152 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 10153 10154 buf_ptr += WMI_TLV_HDR_SIZE; 10155 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 10156 10157 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10158 WMI_REQUEST_STATS_EXT_CMDID); 10159 if (QDF_IS_STATUS_ERROR(ret)) { 10160 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 10161 ret); 10162 wmi_buf_free(buf); 10163 } 10164 10165 return ret; 10166 } 10167 10168 /** 10169 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 10170 * @wmi_handle: wmi handle 10171 * @params: ext wow params 10172 * 10173 * Return:0 for success or error code 10174 */ 10175 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 10176 struct ext_wow_params *params) 10177 { 10178 wmi_extwow_enable_cmd_fixed_param *cmd; 10179 wmi_buf_t buf; 10180 int32_t len; 10181 int ret; 10182 10183 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 10184 buf = wmi_buf_alloc(wmi_handle, len); 10185 if (!buf) { 10186 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10187 return QDF_STATUS_E_NOMEM; 10188 } 10189 10190 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 10191 10192 WMITLV_SET_HDR(&cmd->tlv_header, 10193 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 10194 WMITLV_GET_STRUCT_TLVLEN 10195 (wmi_extwow_enable_cmd_fixed_param)); 10196 10197 cmd->vdev_id = params->vdev_id; 10198 cmd->type = params->type; 10199 cmd->wakeup_pin_num = params->wakeup_pin_num; 10200 10201 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 10202 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 10203 10204 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10205 WMI_EXTWOW_ENABLE_CMDID); 10206 if (ret) { 10207 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 10208 wmi_buf_free(buf); 10209 return QDF_STATUS_E_FAILURE; 10210 } 10211 10212 return QDF_STATUS_SUCCESS; 10213 10214 } 10215 10216 /** 10217 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 10218 * @wmi_handle: wmi handle 10219 * @app_type1_params: app type1 params 10220 * 10221 * Return: CDF status 10222 */ 10223 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10224 struct app_type1_params *app_type1_params) 10225 { 10226 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 10227 wmi_buf_t buf; 10228 int32_t len; 10229 int ret; 10230 10231 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 10232 buf = wmi_buf_alloc(wmi_handle, len); 10233 if (!buf) { 10234 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10235 return QDF_STATUS_E_NOMEM; 10236 } 10237 10238 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 10239 wmi_buf_data(buf); 10240 10241 WMITLV_SET_HDR(&cmd->tlv_header, 10242 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 10243 WMITLV_GET_STRUCT_TLVLEN 10244 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 10245 10246 cmd->vdev_id = app_type1_params->vdev_id; 10247 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 10248 &cmd->wakee_mac); 10249 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 10250 cmd->ident_len = app_type1_params->id_length; 10251 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 10252 cmd->passwd_len = app_type1_params->pass_length; 10253 10254 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 10255 "identification_id %.8s id_length %u " 10256 "password %.16s pass_length %u", 10257 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 10258 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 10259 10260 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10261 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 10262 if (ret) { 10263 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 10264 wmi_buf_free(buf); 10265 return QDF_STATUS_E_FAILURE; 10266 } 10267 10268 return QDF_STATUS_SUCCESS; 10269 } 10270 10271 /** 10272 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 10273 * @wmi_handle: wmi handle 10274 * @appType2Params: app type2 params 10275 * 10276 * Return: CDF status 10277 */ 10278 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10279 struct app_type2_params *appType2Params) 10280 { 10281 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 10282 wmi_buf_t buf; 10283 int32_t len; 10284 int ret; 10285 10286 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 10287 buf = wmi_buf_alloc(wmi_handle, len); 10288 if (!buf) { 10289 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10290 return QDF_STATUS_E_NOMEM; 10291 } 10292 10293 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 10294 wmi_buf_data(buf); 10295 10296 WMITLV_SET_HDR(&cmd->tlv_header, 10297 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 10298 WMITLV_GET_STRUCT_TLVLEN 10299 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 10300 10301 cmd->vdev_id = appType2Params->vdev_id; 10302 10303 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 10304 cmd->rc4_key_len = appType2Params->rc4_key_len; 10305 10306 cmd->ip_id = appType2Params->ip_id; 10307 cmd->ip_device_ip = appType2Params->ip_device_ip; 10308 cmd->ip_server_ip = appType2Params->ip_server_ip; 10309 10310 cmd->tcp_src_port = appType2Params->tcp_src_port; 10311 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 10312 cmd->tcp_seq = appType2Params->tcp_seq; 10313 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 10314 10315 cmd->keepalive_init = appType2Params->keepalive_init; 10316 cmd->keepalive_min = appType2Params->keepalive_min; 10317 cmd->keepalive_max = appType2Params->keepalive_max; 10318 cmd->keepalive_inc = appType2Params->keepalive_inc; 10319 10320 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 10321 &cmd->gateway_mac); 10322 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 10323 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 10324 10325 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 10326 "rc4_key %.16s rc4_key_len %u " 10327 "ip_id %x ip_device_ip %x ip_server_ip %x " 10328 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 10329 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 10330 "keepalive_max %u keepalive_inc %u " 10331 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 10332 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 10333 cmd->rc4_key, cmd->rc4_key_len, 10334 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 10335 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 10336 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 10337 cmd->keepalive_max, cmd->keepalive_inc, 10338 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 10339 10340 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10341 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 10342 if (ret) { 10343 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 10344 wmi_buf_free(buf); 10345 return QDF_STATUS_E_FAILURE; 10346 } 10347 10348 return QDF_STATUS_SUCCESS; 10349 10350 } 10351 10352 /** 10353 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 10354 * @wmi_handle: wmi handle 10355 * @timer_val: auto shutdown timer value 10356 * 10357 * Return: CDF status 10358 */ 10359 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 10360 uint32_t timer_val) 10361 { 10362 QDF_STATUS status; 10363 wmi_buf_t buf = NULL; 10364 uint8_t *buf_ptr; 10365 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 10366 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 10367 10368 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 10369 __func__, timer_val); 10370 10371 buf = wmi_buf_alloc(wmi_handle, len); 10372 if (!buf) { 10373 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10374 return QDF_STATUS_E_NOMEM; 10375 } 10376 10377 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10378 wmi_auto_sh_cmd = 10379 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 10380 wmi_auto_sh_cmd->timer_value = timer_val; 10381 10382 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 10383 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 10384 WMITLV_GET_STRUCT_TLVLEN 10385 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 10386 10387 status = wmi_unified_cmd_send(wmi_handle, buf, 10388 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 10389 if (QDF_IS_STATUS_ERROR(status)) { 10390 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 10391 __func__, status); 10392 wmi_buf_free(buf); 10393 } 10394 10395 return status; 10396 } 10397 10398 /** 10399 * send_nan_req_cmd_tlv() - to send nan request to target 10400 * @wmi_handle: wmi handle 10401 * @nan_req: request data which will be non-null 10402 * 10403 * Return: CDF status 10404 */ 10405 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 10406 struct nan_req_params *nan_req) 10407 { 10408 QDF_STATUS ret; 10409 wmi_nan_cmd_param *cmd; 10410 wmi_buf_t buf; 10411 uint16_t len = sizeof(*cmd); 10412 uint16_t nan_data_len, nan_data_len_aligned; 10413 uint8_t *buf_ptr; 10414 10415 /* 10416 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 10417 * +------------+----------+-----------------------+--------------+ 10418 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 10419 * +------------+----------+-----------------------+--------------+ 10420 */ 10421 if (!nan_req) { 10422 WMI_LOGE("%s:nan req is not valid", __func__); 10423 return QDF_STATUS_E_FAILURE; 10424 } 10425 nan_data_len = nan_req->request_data_len; 10426 nan_data_len_aligned = roundup(nan_req->request_data_len, 10427 sizeof(uint32_t)); 10428 if (nan_data_len_aligned < nan_req->request_data_len) { 10429 WMI_LOGE("%s: integer overflow while rounding up data_len", 10430 __func__); 10431 return QDF_STATUS_E_FAILURE; 10432 } 10433 10434 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 10435 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 10436 __func__); 10437 return QDF_STATUS_E_FAILURE; 10438 } 10439 10440 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 10441 buf = wmi_buf_alloc(wmi_handle, len); 10442 if (!buf) { 10443 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10444 return QDF_STATUS_E_NOMEM; 10445 } 10446 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10447 cmd = (wmi_nan_cmd_param *) buf_ptr; 10448 WMITLV_SET_HDR(&cmd->tlv_header, 10449 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 10450 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 10451 cmd->data_len = nan_req->request_data_len; 10452 WMI_LOGD("%s: The data len value is %u", 10453 __func__, nan_req->request_data_len); 10454 buf_ptr += sizeof(wmi_nan_cmd_param); 10455 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 10456 buf_ptr += WMI_TLV_HDR_SIZE; 10457 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 10458 10459 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10460 WMI_NAN_CMDID); 10461 if (QDF_IS_STATUS_ERROR(ret)) { 10462 WMI_LOGE("%s Failed to send set param command ret = %d", 10463 __func__, ret); 10464 wmi_buf_free(buf); 10465 } 10466 10467 return ret; 10468 } 10469 10470 /** 10471 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 10472 * @wmi_handle: wmi handle 10473 * @params: DHCP server offload info 10474 * 10475 * Return: QDF_STATUS_SUCCESS for success or error code 10476 */ 10477 static QDF_STATUS 10478 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 10479 struct dhcp_offload_info_params *params) 10480 { 10481 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 10482 wmi_buf_t buf; 10483 QDF_STATUS status; 10484 10485 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 10486 if (!buf) { 10487 WMI_LOGE("Failed to allocate buffer to send " 10488 "set_dhcp_server_offload cmd"); 10489 return QDF_STATUS_E_NOMEM; 10490 } 10491 10492 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 10493 10494 WMITLV_SET_HDR(&cmd->tlv_header, 10495 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 10496 WMITLV_GET_STRUCT_TLVLEN 10497 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 10498 cmd->vdev_id = params->vdev_id; 10499 cmd->enable = params->dhcp_offload_enabled; 10500 cmd->num_client = params->dhcp_client_num; 10501 cmd->srv_ipv4 = params->dhcp_srv_addr; 10502 cmd->start_lsb = 0; 10503 status = wmi_unified_cmd_send(wmi_handle, buf, 10504 sizeof(*cmd), 10505 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 10506 if (QDF_IS_STATUS_ERROR(status)) { 10507 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 10508 wmi_buf_free(buf); 10509 return QDF_STATUS_E_FAILURE; 10510 } 10511 WMI_LOGD("Set dhcp server offload to vdevId %d", 10512 params->vdev_id); 10513 10514 return status; 10515 } 10516 10517 /** 10518 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 10519 * @wmi_handle: wmi handle 10520 * @flashing: flashing request 10521 * 10522 * Return: CDF status 10523 */ 10524 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 10525 struct flashing_req_params *flashing) 10526 { 10527 wmi_set_led_flashing_cmd_fixed_param *cmd; 10528 QDF_STATUS status; 10529 wmi_buf_t buf; 10530 uint8_t *buf_ptr; 10531 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 10532 10533 buf = wmi_buf_alloc(wmi_handle, len); 10534 if (!buf) { 10535 WMI_LOGP(FL("wmi_buf_alloc failed")); 10536 return QDF_STATUS_E_NOMEM; 10537 } 10538 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10539 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 10540 WMITLV_SET_HDR(&cmd->tlv_header, 10541 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 10542 WMITLV_GET_STRUCT_TLVLEN 10543 (wmi_set_led_flashing_cmd_fixed_param)); 10544 cmd->pattern_id = flashing->pattern_id; 10545 cmd->led_x0 = flashing->led_x0; 10546 cmd->led_x1 = flashing->led_x1; 10547 10548 status = wmi_unified_cmd_send(wmi_handle, buf, len, 10549 WMI_PDEV_SET_LED_FLASHING_CMDID); 10550 if (QDF_IS_STATUS_ERROR(status)) { 10551 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 10552 " returned Error %d", __func__, status); 10553 wmi_buf_free(buf); 10554 } 10555 10556 return status; 10557 } 10558 10559 /** 10560 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 10561 * @wmi_handle: wmi handle 10562 * @ch_avoid_update_req: channel avoid update params 10563 * 10564 * Return: CDF status 10565 */ 10566 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 10567 { 10568 QDF_STATUS status; 10569 wmi_buf_t buf = NULL; 10570 uint8_t *buf_ptr; 10571 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 10572 int len = sizeof(wmi_chan_avoid_update_cmd_param); 10573 10574 10575 buf = wmi_buf_alloc(wmi_handle, len); 10576 if (!buf) { 10577 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10578 return QDF_STATUS_E_NOMEM; 10579 } 10580 10581 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10582 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 10583 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 10584 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 10585 WMITLV_GET_STRUCT_TLVLEN 10586 (wmi_chan_avoid_update_cmd_param)); 10587 10588 status = wmi_unified_cmd_send(wmi_handle, buf, 10589 len, WMI_CHAN_AVOID_UPDATE_CMDID); 10590 if (QDF_IS_STATUS_ERROR(status)) { 10591 WMI_LOGE("wmi_unified_cmd_send" 10592 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 10593 " returned Error %d", status); 10594 wmi_buf_free(buf); 10595 } 10596 10597 return status; 10598 } 10599 10600 /** 10601 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 10602 * @wmi_handle: wmi handle 10603 * @param: pointer to pdev regdomain params 10604 * 10605 * Return: 0 for success or error code 10606 */ 10607 static QDF_STATUS 10608 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 10609 struct pdev_set_regdomain_params *param) 10610 { 10611 wmi_buf_t buf; 10612 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10613 int32_t len = sizeof(*cmd); 10614 10615 10616 buf = wmi_buf_alloc(wmi_handle, len); 10617 if (!buf) { 10618 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10619 return QDF_STATUS_E_NOMEM; 10620 } 10621 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10622 WMITLV_SET_HDR(&cmd->tlv_header, 10623 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10624 WMITLV_GET_STRUCT_TLVLEN 10625 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10626 10627 cmd->reg_domain = param->currentRDinuse; 10628 cmd->reg_domain_2G = param->currentRD2G; 10629 cmd->reg_domain_5G = param->currentRD5G; 10630 cmd->conformance_test_limit_2G = param->ctl_2G; 10631 cmd->conformance_test_limit_5G = param->ctl_5G; 10632 cmd->dfs_domain = param->dfsDomain; 10633 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10634 param->pdev_id); 10635 10636 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10637 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10638 WMI_LOGE("%s: Failed to send pdev set regdomain command", 10639 __func__); 10640 wmi_buf_free(buf); 10641 return QDF_STATUS_E_FAILURE; 10642 } 10643 10644 return QDF_STATUS_SUCCESS; 10645 } 10646 10647 /** 10648 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 10649 * @wmi_handle: wmi handle 10650 * @reg_dmn: reg domain 10651 * @regdmn2G: 2G reg domain 10652 * @regdmn5G: 5G reg domain 10653 * @ctl2G: 2G test limit 10654 * @ctl5G: 5G test limit 10655 * 10656 * Return: none 10657 */ 10658 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 10659 uint32_t reg_dmn, uint16_t regdmn2G, 10660 uint16_t regdmn5G, uint8_t ctl2G, 10661 uint8_t ctl5G) 10662 { 10663 wmi_buf_t buf; 10664 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10665 int32_t len = sizeof(*cmd); 10666 10667 10668 buf = wmi_buf_alloc(wmi_handle, len); 10669 if (!buf) { 10670 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10671 return QDF_STATUS_E_NOMEM; 10672 } 10673 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10674 WMITLV_SET_HDR(&cmd->tlv_header, 10675 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10676 WMITLV_GET_STRUCT_TLVLEN 10677 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10678 cmd->reg_domain = reg_dmn; 10679 cmd->reg_domain_2G = regdmn2G; 10680 cmd->reg_domain_5G = regdmn5G; 10681 cmd->conformance_test_limit_2G = ctl2G; 10682 cmd->conformance_test_limit_5G = ctl5G; 10683 10684 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10685 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10686 WMI_LOGP("%s: Failed to send pdev set regdomain command", 10687 __func__); 10688 wmi_buf_free(buf); 10689 return QDF_STATUS_E_FAILURE; 10690 } 10691 10692 return QDF_STATUS_SUCCESS; 10693 } 10694 10695 10696 /** 10697 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 10698 * @wmi_handle: wmi handle 10699 * @chan_switch_params: Pointer to tdls channel switch parameter structure 10700 * 10701 * This function sets tdls off channel mode 10702 * 10703 * Return: 0 on success; Negative errno otherwise 10704 */ 10705 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 10706 struct tdls_channel_switch_params *chan_switch_params) 10707 { 10708 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 10709 wmi_buf_t wmi_buf; 10710 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10711 10712 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10713 if (!wmi_buf) { 10714 WMI_LOGE(FL("wmi_buf_alloc failed")); 10715 return QDF_STATUS_E_FAILURE; 10716 } 10717 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10718 wmi_buf_data(wmi_buf); 10719 WMITLV_SET_HDR(&cmd->tlv_header, 10720 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10721 WMITLV_GET_STRUCT_TLVLEN( 10722 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10723 10724 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10725 &cmd->peer_macaddr); 10726 cmd->vdev_id = chan_switch_params->vdev_id; 10727 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 10728 cmd->is_peer_responder = chan_switch_params->is_responder; 10729 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10730 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10731 cmd->offchan_oper_class = chan_switch_params->oper_class; 10732 10733 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10734 cmd->peer_macaddr.mac_addr31to0, 10735 cmd->peer_macaddr.mac_addr47to32); 10736 10737 WMI_LOGD(FL( 10738 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10739 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10740 ), 10741 cmd->vdev_id, 10742 cmd->offchan_mode, 10743 cmd->offchan_num, 10744 cmd->offchan_bw_bitmap, 10745 cmd->is_peer_responder, 10746 cmd->offchan_oper_class); 10747 10748 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10749 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10750 WMI_LOGP(FL("failed to send tdls off chan command")); 10751 wmi_buf_free(wmi_buf); 10752 return QDF_STATUS_E_FAILURE; 10753 } 10754 10755 10756 return QDF_STATUS_SUCCESS; 10757 } 10758 10759 /** 10760 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10761 * @wmi_handle: wmi handle 10762 * @pwmaTdlsparams: TDLS params 10763 * 10764 * Return: 0 for success or error code 10765 */ 10766 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10767 void *tdls_param, uint8_t tdls_state) 10768 { 10769 wmi_tdls_set_state_cmd_fixed_param *cmd; 10770 wmi_buf_t wmi_buf; 10771 10772 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10773 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10774 10775 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10776 if (!wmi_buf) { 10777 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10778 return QDF_STATUS_E_FAILURE; 10779 } 10780 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10781 WMITLV_SET_HDR(&cmd->tlv_header, 10782 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10783 WMITLV_GET_STRUCT_TLVLEN 10784 (wmi_tdls_set_state_cmd_fixed_param)); 10785 cmd->vdev_id = wmi_tdls->vdev_id; 10786 cmd->state = tdls_state; 10787 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10788 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10789 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10790 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10791 cmd->rssi_delta = wmi_tdls->rssi_delta; 10792 cmd->tdls_options = wmi_tdls->tdls_options; 10793 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10794 cmd->tdls_peer_traffic_response_timeout_ms = 10795 wmi_tdls->peer_traffic_response_timeout; 10796 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10797 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10798 cmd->tdls_puapsd_rx_frame_threshold = 10799 wmi_tdls->puapsd_rx_frame_threshold; 10800 cmd->teardown_notification_ms = 10801 wmi_tdls->teardown_notification_ms; 10802 cmd->tdls_peer_kickout_threshold = 10803 wmi_tdls->tdls_peer_kickout_threshold; 10804 10805 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10806 "notification_interval_ms: %d, " 10807 "tx_discovery_threshold: %d, " 10808 "tx_teardown_threshold: %d, " 10809 "rssi_teardown_threshold: %d, " 10810 "rssi_delta: %d, " 10811 "tdls_options: 0x%x, " 10812 "tdls_peer_traffic_ind_window: %d, " 10813 "tdls_peer_traffic_response_timeout: %d, " 10814 "tdls_puapsd_mask: 0x%x, " 10815 "tdls_puapsd_inactivity_time: %d, " 10816 "tdls_puapsd_rx_frame_threshold: %d, " 10817 "teardown_notification_ms: %d, " 10818 "tdls_peer_kickout_threshold: %d", 10819 __func__, tdls_state, cmd->state, 10820 cmd->notification_interval_ms, 10821 cmd->tx_discovery_threshold, 10822 cmd->tx_teardown_threshold, 10823 cmd->rssi_teardown_threshold, 10824 cmd->rssi_delta, 10825 cmd->tdls_options, 10826 cmd->tdls_peer_traffic_ind_window, 10827 cmd->tdls_peer_traffic_response_timeout_ms, 10828 cmd->tdls_puapsd_mask, 10829 cmd->tdls_puapsd_inactivity_time_ms, 10830 cmd->tdls_puapsd_rx_frame_threshold, 10831 cmd->teardown_notification_ms, 10832 cmd->tdls_peer_kickout_threshold); 10833 10834 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10835 WMI_TDLS_SET_STATE_CMDID)) { 10836 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10837 wmi_buf_free(wmi_buf); 10838 return QDF_STATUS_E_FAILURE; 10839 } 10840 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10841 10842 return QDF_STATUS_SUCCESS; 10843 } 10844 10845 /** 10846 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10847 * @wmi_handle: wmi handle 10848 * @peerStateParams: TDLS peer state params 10849 * 10850 * Return: QDF_STATUS_SUCCESS for success or error code 10851 */ 10852 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10853 struct tdls_peer_state_params *peerStateParams, 10854 uint32_t *ch_mhz) 10855 { 10856 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10857 wmi_tdls_peer_capabilities *peer_cap; 10858 wmi_channel *chan_info; 10859 wmi_buf_t wmi_buf; 10860 uint8_t *buf_ptr; 10861 uint32_t i; 10862 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10863 sizeof(wmi_tdls_peer_capabilities); 10864 10865 10866 len += WMI_TLV_HDR_SIZE + 10867 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10868 10869 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10870 if (!wmi_buf) { 10871 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10872 return QDF_STATUS_E_FAILURE; 10873 } 10874 10875 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10876 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10877 WMITLV_SET_HDR(&cmd->tlv_header, 10878 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10879 WMITLV_GET_STRUCT_TLVLEN 10880 (wmi_tdls_peer_update_cmd_fixed_param)); 10881 10882 cmd->vdev_id = peerStateParams->vdevId; 10883 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10884 &cmd->peer_macaddr); 10885 10886 10887 cmd->peer_state = peerStateParams->peerState; 10888 10889 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10890 "peer_macaddr.mac_addr31to0: 0x%x, " 10891 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10892 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10893 cmd->peer_macaddr.mac_addr31to0, 10894 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10895 10896 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10897 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10898 WMITLV_SET_HDR(&peer_cap->tlv_header, 10899 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10900 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10901 10902 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10903 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10904 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10905 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10906 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10907 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10908 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10909 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10910 10911 /* Ack and More Data Ack are sent as 0, so no need to set 10912 * but fill SP 10913 */ 10914 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10915 peerStateParams->peerCap.peerMaxSp); 10916 10917 peer_cap->buff_sta_support = 10918 peerStateParams->peerCap.peerBuffStaSupport; 10919 peer_cap->off_chan_support = 10920 peerStateParams->peerCap.peerOffChanSupport; 10921 peer_cap->peer_curr_operclass = 10922 peerStateParams->peerCap.peerCurrOperClass; 10923 /* self curr operclass is not being used and so pass op class for 10924 * preferred off chan in it. 10925 */ 10926 peer_cap->self_curr_operclass = 10927 peerStateParams->peerCap.opClassForPrefOffChan; 10928 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10929 peer_cap->peer_operclass_len = 10930 peerStateParams->peerCap.peerOperClassLen; 10931 10932 WMI_LOGD("%s: peer_operclass_len: %d", 10933 __func__, peer_cap->peer_operclass_len); 10934 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10935 peer_cap->peer_operclass[i] = 10936 peerStateParams->peerCap.peerOperClass[i]; 10937 WMI_LOGD("%s: peer_operclass[%d]: %d", 10938 __func__, i, peer_cap->peer_operclass[i]); 10939 } 10940 10941 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10942 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10943 peer_cap->pref_offchan_bw = 10944 peerStateParams->peerCap.prefOffChanBandwidth; 10945 10946 WMI_LOGD 10947 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10948 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10949 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10950 " %d, pref_offchan_bw: %d", 10951 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10952 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10953 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10954 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10955 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10956 10957 /* next fill variable size array of peer chan info */ 10958 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10959 WMITLV_SET_HDR(buf_ptr, 10960 WMITLV_TAG_ARRAY_STRUC, 10961 sizeof(wmi_channel) * 10962 peerStateParams->peerCap.peerChanLen); 10963 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10964 10965 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10966 WMITLV_SET_HDR(&chan_info->tlv_header, 10967 WMITLV_TAG_STRUC_wmi_channel, 10968 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10969 chan_info->mhz = ch_mhz[i]; 10970 chan_info->band_center_freq1 = chan_info->mhz; 10971 chan_info->band_center_freq2 = 0; 10972 10973 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10974 10975 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10976 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10977 WMI_LOGI("chan[%d] DFS[%d]\n", 10978 peerStateParams->peerCap.peerChan[i].chanId, 10979 peerStateParams->peerCap.peerChan[i].dfsSet); 10980 } 10981 10982 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10983 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10984 else 10985 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10986 10987 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10988 peerStateParams->peerCap. 10989 peerChan[i].pwr); 10990 10991 WMI_SET_CHANNEL_REG_POWER(chan_info, 10992 peerStateParams->peerCap.peerChan[i]. 10993 pwr); 10994 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10995 peerStateParams->peerCap.peerChan[i].pwr); 10996 10997 chan_info++; 10998 } 10999 11000 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11001 WMI_TDLS_PEER_UPDATE_CMDID)) { 11002 WMI_LOGE("%s: failed to send tdls peer update state command", 11003 __func__); 11004 wmi_buf_free(wmi_buf); 11005 return QDF_STATUS_E_FAILURE; 11006 } 11007 11008 11009 return QDF_STATUS_SUCCESS; 11010 } 11011 11012 /* 11013 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 11014 * @wmi_handle: Pointer to WMi handle 11015 * @ie_data: Pointer for ie data 11016 * 11017 * This function sends IE information to firmware 11018 * 11019 * Return: QDF_STATUS_SUCCESS for success otherwise failure 11020 * 11021 */ 11022 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 11023 struct vdev_ie_info_param *ie_info) 11024 { 11025 wmi_vdev_set_ie_cmd_fixed_param *cmd; 11026 wmi_buf_t buf; 11027 uint8_t *buf_ptr; 11028 uint32_t len, ie_len_aligned; 11029 QDF_STATUS ret; 11030 11031 11032 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 11033 /* Allocate memory for the WMI command */ 11034 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 11035 11036 buf = wmi_buf_alloc(wmi_handle, len); 11037 if (!buf) { 11038 WMI_LOGE(FL("wmi_buf_alloc failed")); 11039 return QDF_STATUS_E_NOMEM; 11040 } 11041 11042 buf_ptr = wmi_buf_data(buf); 11043 qdf_mem_zero(buf_ptr, len); 11044 11045 /* Populate the WMI command */ 11046 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 11047 11048 WMITLV_SET_HDR(&cmd->tlv_header, 11049 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 11050 WMITLV_GET_STRUCT_TLVLEN( 11051 wmi_vdev_set_ie_cmd_fixed_param)); 11052 cmd->vdev_id = ie_info->vdev_id; 11053 cmd->ie_id = ie_info->ie_id; 11054 cmd->ie_len = ie_info->length; 11055 cmd->band = ie_info->band; 11056 11057 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 11058 ie_info->length, ie_info->vdev_id); 11059 11060 buf_ptr += sizeof(*cmd); 11061 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 11062 buf_ptr += WMI_TLV_HDR_SIZE; 11063 11064 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 11065 11066 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11067 WMI_VDEV_SET_IE_CMDID); 11068 if (QDF_IS_STATUS_ERROR(ret)) { 11069 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 11070 wmi_buf_free(buf); 11071 } 11072 11073 return ret; 11074 } 11075 11076 /** 11077 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 11078 * 11079 * @param wmi_handle : handle to WMI. 11080 * @param param : pointer to antenna param 11081 * 11082 * This function sends smart antenna enable command to FW 11083 * 11084 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11085 */ 11086 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 11087 struct smart_ant_enable_params *param) 11088 { 11089 /* Send WMI COMMAND to Enable */ 11090 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 11091 wmi_pdev_smart_ant_gpio_handle *gpio_param; 11092 wmi_buf_t buf; 11093 uint8_t *buf_ptr; 11094 int len = 0; 11095 QDF_STATUS ret; 11096 int loop = 0; 11097 11098 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11099 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 11100 buf = wmi_buf_alloc(wmi_handle, len); 11101 11102 if (!buf) { 11103 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11104 return QDF_STATUS_E_NOMEM; 11105 } 11106 11107 buf_ptr = wmi_buf_data(buf); 11108 qdf_mem_zero(buf_ptr, len); 11109 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 11110 11111 WMITLV_SET_HDR(&cmd->tlv_header, 11112 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 11113 WMITLV_GET_STRUCT_TLVLEN( 11114 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 11115 11116 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11117 param->pdev_id); 11118 cmd->enable = param->enable; 11119 cmd->mode = param->mode; 11120 cmd->rx_antenna = param->rx_antenna; 11121 cmd->tx_default_antenna = param->rx_antenna; 11122 11123 /* TLV indicating array of structures to follow */ 11124 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 11125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11126 WMI_HAL_MAX_SANTENNA * 11127 sizeof(wmi_pdev_smart_ant_gpio_handle)); 11128 11129 buf_ptr += WMI_TLV_HDR_SIZE; 11130 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 11131 11132 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 11133 WMITLV_SET_HDR(&gpio_param->tlv_header, 11134 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 11135 WMITLV_GET_STRUCT_TLVLEN( 11136 wmi_pdev_smart_ant_gpio_handle)); 11137 if (param->mode == SMART_ANT_MODE_SERIAL) { 11138 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 11139 gpio_param->gpio_pin = param->gpio_pin[loop]; 11140 gpio_param->gpio_func = param->gpio_func[loop]; 11141 } else { 11142 gpio_param->gpio_pin = 0; 11143 gpio_param->gpio_func = 0; 11144 } 11145 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 11146 gpio_param->gpio_pin = param->gpio_pin[loop]; 11147 gpio_param->gpio_func = param->gpio_func[loop]; 11148 } 11149 /* Setting it to 0 for now */ 11150 gpio_param->pdev_id = 11151 wmi_handle->ops->convert_pdev_id_host_to_target( 11152 param->pdev_id); 11153 gpio_param++; 11154 } 11155 11156 ret = wmi_unified_cmd_send(wmi_handle, 11157 buf, 11158 len, 11159 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 11160 11161 if (ret != 0) { 11162 WMI_LOGE(" %s :WMI Failed\n", __func__); 11163 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 11164 cmd->enable, 11165 cmd->mode, 11166 cmd->rx_antenna, 11167 param->gpio_pin[0], param->gpio_pin[1], 11168 param->gpio_pin[2], param->gpio_pin[3], 11169 param->gpio_func[0], param->gpio_func[1], 11170 param->gpio_func[2], param->gpio_func[3], 11171 ret); 11172 wmi_buf_free(buf); 11173 } 11174 11175 return ret; 11176 } 11177 11178 /** 11179 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 11180 * 11181 * @param wmi_handle : handle to WMI. 11182 * @param param : pointer to rx antenna param 11183 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11184 */ 11185 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11186 struct smart_ant_rx_ant_params *param) 11187 { 11188 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 11189 wmi_buf_t buf; 11190 uint8_t *buf_ptr; 11191 uint32_t len; 11192 QDF_STATUS ret; 11193 11194 len = sizeof(*cmd); 11195 buf = wmi_buf_alloc(wmi_handle, len); 11196 WMI_LOGD("%s:\n", __func__); 11197 if (!buf) { 11198 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11199 return QDF_STATUS_E_NOMEM; 11200 } 11201 11202 buf_ptr = wmi_buf_data(buf); 11203 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 11204 WMITLV_SET_HDR(&cmd->tlv_header, 11205 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 11206 WMITLV_GET_STRUCT_TLVLEN( 11207 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 11208 cmd->rx_antenna = param->antenna; 11209 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11210 param->pdev_id); 11211 11212 ret = wmi_unified_cmd_send(wmi_handle, 11213 buf, 11214 len, 11215 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 11216 11217 if (ret != 0) { 11218 WMI_LOGE(" %s :WMI Failed\n", __func__); 11219 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 11220 __func__, 11221 cmd->rx_antenna, 11222 ret); 11223 wmi_buf_free(buf); 11224 } 11225 11226 return ret; 11227 } 11228 11229 /** 11230 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 11231 * @wmi_handle: wmi handle 11232 * @param: pointer to hold ctl table param 11233 * 11234 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11235 */ 11236 static QDF_STATUS 11237 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 11238 struct ctl_table_params *param) 11239 { 11240 uint16_t len, ctl_tlv_len; 11241 uint8_t *buf_ptr; 11242 wmi_buf_t buf; 11243 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 11244 uint32_t *ctl_array; 11245 11246 if (!param->ctl_array) 11247 return QDF_STATUS_E_FAILURE; 11248 11249 ctl_tlv_len = WMI_TLV_HDR_SIZE + 11250 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 11251 len = sizeof(*cmd) + ctl_tlv_len; 11252 11253 buf = wmi_buf_alloc(wmi_handle, len); 11254 if (!buf) { 11255 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11256 return QDF_STATUS_E_FAILURE; 11257 } 11258 11259 buf_ptr = wmi_buf_data(buf); 11260 qdf_mem_zero(buf_ptr, len); 11261 11262 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 11263 11264 WMITLV_SET_HDR(&cmd->tlv_header, 11265 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 11266 WMITLV_GET_STRUCT_TLVLEN( 11267 wmi_pdev_set_ctl_table_cmd_fixed_param)); 11268 cmd->ctl_len = param->ctl_cmd_len; 11269 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11270 param->pdev_id); 11271 11272 buf_ptr += sizeof(*cmd); 11273 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11274 (cmd->ctl_len)); 11275 buf_ptr += WMI_TLV_HDR_SIZE; 11276 ctl_array = (uint32_t *)buf_ptr; 11277 11278 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 11279 sizeof(param->ctl_band)); 11280 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 11281 param->ctl_cmd_len - 11282 sizeof(param->ctl_band)); 11283 11284 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11285 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 11286 WMI_LOGE("%s:Failed to send command\n", __func__); 11287 wmi_buf_free(buf); 11288 return QDF_STATUS_E_FAILURE; 11289 } 11290 11291 return QDF_STATUS_SUCCESS; 11292 } 11293 11294 /** 11295 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 11296 * @wmi_handle: wmi handle 11297 * @param: pointer to hold mimogain table param 11298 * 11299 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11300 */ 11301 static QDF_STATUS 11302 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 11303 struct mimogain_table_params *param) 11304 { 11305 uint16_t len, table_tlv_len; 11306 wmi_buf_t buf; 11307 uint8_t *buf_ptr; 11308 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 11309 uint32_t *gain_table; 11310 11311 if (!param->array_gain) 11312 return QDF_STATUS_E_FAILURE; 11313 11314 /* len must be multiple of a single array gain table */ 11315 if (param->tbl_len % 11316 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 11317 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 11318 WMI_LOGE("Array gain table len not correct\n"); 11319 return QDF_STATUS_E_FAILURE; 11320 } 11321 11322 table_tlv_len = WMI_TLV_HDR_SIZE + 11323 roundup(param->tbl_len, sizeof(uint32_t)); 11324 len = sizeof(*cmd) + table_tlv_len; 11325 11326 buf = wmi_buf_alloc(wmi_handle, len); 11327 if (!buf) { 11328 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11329 return QDF_STATUS_E_FAILURE; 11330 } 11331 11332 buf_ptr = wmi_buf_data(buf); 11333 qdf_mem_zero(buf_ptr, len); 11334 11335 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 11336 11337 WMITLV_SET_HDR(&cmd->tlv_header, 11338 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 11339 WMITLV_GET_STRUCT_TLVLEN( 11340 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 11341 11342 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11343 param->pdev_id); 11344 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 11345 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 11346 param->multichain_gain_bypass); 11347 11348 buf_ptr += sizeof(*cmd); 11349 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11350 (param->tbl_len)); 11351 buf_ptr += WMI_TLV_HDR_SIZE; 11352 gain_table = (uint32_t *)buf_ptr; 11353 11354 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 11355 param->array_gain, 11356 param->tbl_len); 11357 11358 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11359 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 11360 return QDF_STATUS_E_FAILURE; 11361 } 11362 11363 return QDF_STATUS_SUCCESS; 11364 } 11365 11366 /** 11367 * enum packet_power_tlv_flags: target defined 11368 * packet power rate flags for TLV 11369 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 11370 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 11371 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 11372 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 11373 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 11374 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 11375 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 11376 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 11377 * @WMI_TLV_FLAG_STBC: STBC is set 11378 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 11379 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 11380 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 11381 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 11382 * @WMI_TLV_FLAG_RTSENA: RTS enabled 11383 * @WMI_TLV_FLAG_CTSENA: CTS enabled 11384 * @WMI_TLV_FLAG_LDPC: LDPC is set 11385 * @WMI_TLV_FLAG_SGI: Short gaurd interval 11386 * @WMI_TLV_FLAG_SU: SU Data 11387 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 11388 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 11389 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 11390 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 11391 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 11392 * 11393 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 11394 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 11395 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 11396 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 11397 */ 11398 enum packet_power_tlv_flags { 11399 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 11400 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 11401 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 11402 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 11403 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 11404 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 11405 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 11406 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 11407 WMI_TLV_FLAG_STBC = 0x00000100, 11408 WMI_TLV_FLAG_40MHZ = 0x00000200, 11409 WMI_TLV_FLAG_80MHZ = 0x00000300, 11410 WMI_TLV_FLAG_160MHZ = 0x00000400, 11411 WMI_TLV_FLAG_TXBF = 0x00000800, 11412 WMI_TLV_FLAG_RTSENA = 0x00001000, 11413 WMI_TLV_FLAG_CTSENA = 0x00002000, 11414 WMI_TLV_FLAG_LDPC = 0x00004000, 11415 WMI_TLV_FLAG_SGI = 0x00008000, 11416 WMI_TLV_FLAG_SU = 0x00100000, 11417 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 11418 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 11419 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 11420 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 11421 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 11422 11423 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 11424 WMI_TLV_FLAG_BW_MASK = 0x3, 11425 WMI_TLV_FLAG_BW_SHIFT = 9, 11426 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 11427 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 11428 }; 11429 11430 /** 11431 * convert_to_power_info_rate_flags() - convert packet_power_info_params 11432 * to FW understandable format 11433 * @param: pointer to hold packet power info param 11434 * 11435 * @return FW understandable 32 bit rate flags 11436 */ 11437 static uint32_t 11438 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 11439 { 11440 uint32_t rateflags = 0; 11441 11442 if (param->chainmask) 11443 rateflags |= 11444 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 11445 if (param->chan_width) 11446 rateflags |= 11447 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 11448 << WMI_TLV_FLAG_BW_SHIFT); 11449 if (param->su_mu_ofdma) 11450 rateflags |= 11451 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 11452 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 11453 if (param->rate_flags & WMI_HOST_FLAG_STBC) 11454 rateflags |= WMI_TLV_FLAG_STBC; 11455 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 11456 rateflags |= WMI_TLV_FLAG_LDPC; 11457 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 11458 rateflags |= WMI_TLV_FLAG_TXBF; 11459 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 11460 rateflags |= WMI_TLV_FLAG_RTSENA; 11461 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 11462 rateflags |= WMI_TLV_FLAG_CTSENA; 11463 if (param->rate_flags & WMI_HOST_FLAG_SGI) 11464 rateflags |= WMI_TLV_FLAG_SGI; 11465 11466 return rateflags; 11467 } 11468 11469 /** 11470 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 11471 * info to fw 11472 * @wmi_handle: wmi handle 11473 * @param: pointer to hold packet power info param 11474 * 11475 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11476 */ 11477 static QDF_STATUS 11478 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 11479 struct packet_power_info_params *param) 11480 { 11481 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 11482 wmi_buf_t wmibuf; 11483 uint8_t *buf_ptr; 11484 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 11485 11486 wmibuf = wmi_buf_alloc(wmi_handle, len); 11487 if (wmibuf == NULL) 11488 return QDF_STATUS_E_NOMEM; 11489 11490 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 11491 11492 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 11493 WMITLV_SET_HDR(&cmd->tlv_header, 11494 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 11495 WMITLV_GET_STRUCT_TLVLEN( 11496 wmi_pdev_get_tpc_cmd_fixed_param)); 11497 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11498 param->pdev_id); 11499 cmd->rate_flags = convert_to_power_info_rate_flags(param); 11500 cmd->nss = param->nss; 11501 cmd->preamble = param->preamble; 11502 cmd->hw_rate = param->hw_rate; 11503 11504 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 11505 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 11506 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 11507 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 11508 11509 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 11510 WMI_PDEV_GET_TPC_CMDID)) { 11511 WMI_LOGE(FL("Failed to get tpc command\n")); 11512 wmi_buf_free(wmibuf); 11513 return QDF_STATUS_E_FAILURE; 11514 } 11515 11516 return QDF_STATUS_SUCCESS; 11517 } 11518 11519 /** 11520 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 11521 * @wmi_handle: wmi handle 11522 * @param: pointer to hold config ratemask params 11523 * 11524 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11525 */ 11526 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 11527 struct config_ratemask_params *param) 11528 { 11529 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 11530 wmi_buf_t buf; 11531 int32_t len = sizeof(*cmd); 11532 11533 buf = wmi_buf_alloc(wmi_handle, len); 11534 if (!buf) { 11535 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11536 return QDF_STATUS_E_FAILURE; 11537 } 11538 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 11539 WMITLV_SET_HDR(&cmd->tlv_header, 11540 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 11541 WMITLV_GET_STRUCT_TLVLEN( 11542 wmi_vdev_config_ratemask_cmd_fixed_param)); 11543 cmd->vdev_id = param->vdev_id; 11544 cmd->type = param->type; 11545 cmd->mask_lower32 = param->lower32; 11546 cmd->mask_higher32 = param->higher32; 11547 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n", 11548 param->vdev_id, param->type, param->lower32, param->higher32); 11549 11550 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11551 WMI_VDEV_RATEMASK_CMDID)) { 11552 WMI_LOGE("Seting vdev ratemask failed\n"); 11553 wmi_buf_free(buf); 11554 return QDF_STATUS_E_FAILURE; 11555 } 11556 11557 return QDF_STATUS_SUCCESS; 11558 } 11559 11560 /** 11561 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 11562 * @param: param sent from the host side 11563 * @cmd: param to be sent to the fw side 11564 */ 11565 static inline void copy_custom_aggr_bitmap( 11566 struct set_custom_aggr_size_params *param, 11567 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 11568 { 11569 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 11570 param->ac); 11571 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 11572 param->aggr_type); 11573 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11574 param->tx_aggr_size_disable); 11575 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11576 param->rx_aggr_size_disable); 11577 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 11578 param->tx_ac_enable); 11579 } 11580 11581 /** 11582 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 11583 * @wmi_handle: wmi handle 11584 * @param: pointer to hold custom aggr size params 11585 * 11586 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11587 */ 11588 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 11589 wmi_unified_t wmi_handle, 11590 struct set_custom_aggr_size_params *param) 11591 { 11592 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 11593 wmi_buf_t buf; 11594 int32_t len = sizeof(*cmd); 11595 11596 buf = wmi_buf_alloc(wmi_handle, len); 11597 if (!buf) { 11598 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11599 return QDF_STATUS_E_FAILURE; 11600 } 11601 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 11602 wmi_buf_data(buf); 11603 WMITLV_SET_HDR(&cmd->tlv_header, 11604 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 11605 WMITLV_GET_STRUCT_TLVLEN( 11606 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 11607 cmd->vdev_id = param->vdev_id; 11608 cmd->tx_aggr_size = param->tx_aggr_size; 11609 cmd->rx_aggr_size = param->rx_aggr_size; 11610 copy_custom_aggr_bitmap(param, cmd); 11611 11612 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 11613 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 11614 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 11615 "tx_ac_enable=0x%X\n", 11616 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 11617 param->ac, param->aggr_type, param->tx_aggr_size_disable, 11618 param->rx_aggr_size_disable, param->tx_ac_enable); 11619 11620 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11621 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 11622 WMI_LOGE("Seting custom aggregation size failed\n"); 11623 wmi_buf_free(buf); 11624 return QDF_STATUS_E_FAILURE; 11625 } 11626 11627 return QDF_STATUS_SUCCESS; 11628 } 11629 11630 /** 11631 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 11632 * @param wmi_handle : handle to WMI. 11633 * @param param : pointer to tx antenna param 11634 * 11635 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11636 */ 11637 11638 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 11639 struct set_qdepth_thresh_params *param) 11640 { 11641 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 11642 wmi_msduq_qdepth_thresh_update *cmd_update; 11643 wmi_buf_t buf; 11644 int32_t len = 0; 11645 int i; 11646 uint8_t *buf_ptr; 11647 QDF_STATUS ret; 11648 11649 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 11650 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 11651 return QDF_STATUS_E_INVAL; 11652 } 11653 11654 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11655 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 11656 param->num_of_msduq_updates); 11657 buf = wmi_buf_alloc(wmi_handle, len); 11658 11659 if (!buf) { 11660 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11661 return QDF_STATUS_E_NOMEM; 11662 } 11663 11664 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11665 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 11666 buf_ptr; 11667 11668 WMITLV_SET_HDR(&cmd->tlv_header, 11669 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 11670 , WMITLV_GET_STRUCT_TLVLEN( 11671 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 11672 11673 cmd->pdev_id = 11674 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11675 cmd->vdev_id = param->vdev_id; 11676 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 11677 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 11678 11679 buf_ptr += sizeof( 11680 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 11681 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11682 param->num_of_msduq_updates * 11683 sizeof(wmi_msduq_qdepth_thresh_update)); 11684 buf_ptr += WMI_TLV_HDR_SIZE; 11685 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 11686 11687 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 11688 WMITLV_SET_HDR(&cmd_update->tlv_header, 11689 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 11690 WMITLV_GET_STRUCT_TLVLEN( 11691 wmi_msduq_qdepth_thresh_update)); 11692 cmd_update->tid_num = param->update_params[i].tid_num; 11693 cmd_update->msduq_update_mask = 11694 param->update_params[i].msduq_update_mask; 11695 cmd_update->qdepth_thresh_value = 11696 param->update_params[i].qdepth_thresh_value; 11697 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 11698 "mac_addr_upper4=%X, mac_addr_lower2:%X," 11699 " update mask=0x%X thresh val=0x%X\n", 11700 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 11701 cmd->peer_mac_address.mac_addr31to0, 11702 cmd->peer_mac_address.mac_addr47to32, 11703 cmd_update->msduq_update_mask, 11704 cmd_update->qdepth_thresh_value); 11705 cmd_update++; 11706 } 11707 11708 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11709 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 11710 11711 if (ret != 0) { 11712 WMI_LOGE(" %s :WMI Failed\n", __func__); 11713 wmi_buf_free(buf); 11714 } 11715 11716 return ret; 11717 } 11718 11719 /** 11720 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11721 * @wmi_handle: wmi handle 11722 * @param: pointer to hold vap dscp tid map param 11723 * 11724 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11725 */ 11726 static QDF_STATUS 11727 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11728 struct vap_dscp_tid_map_params *param) 11729 { 11730 wmi_buf_t buf; 11731 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11732 int32_t len = sizeof(*cmd); 11733 11734 buf = wmi_buf_alloc(wmi_handle, len); 11735 if (!buf) { 11736 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11737 return QDF_STATUS_E_FAILURE; 11738 } 11739 11740 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11741 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11742 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 11743 11744 cmd->vdev_id = param->vdev_id; 11745 cmd->enable_override = 0; 11746 11747 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11748 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11749 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11750 WMI_LOGE("Failed to set dscp cmd\n"); 11751 wmi_buf_free(buf); 11752 return QDF_STATUS_E_FAILURE; 11753 } 11754 11755 return QDF_STATUS_SUCCESS; 11756 } 11757 11758 /** 11759 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11760 * @wmi_handle: wmi handle 11761 * @macaddr: vdev mac address 11762 * @param: pointer to hold neigbour rx param 11763 * 11764 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11765 */ 11766 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11767 uint8_t macaddr[IEEE80211_ADDR_LEN], 11768 struct set_neighbour_rx_params *param) 11769 { 11770 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11771 wmi_buf_t buf; 11772 int32_t len = sizeof(*cmd); 11773 11774 buf = wmi_buf_alloc(wmi_handle, len); 11775 if (!buf) { 11776 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11777 return QDF_STATUS_E_FAILURE; 11778 } 11779 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11780 WMITLV_SET_HDR(&cmd->tlv_header, 11781 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11782 WMITLV_GET_STRUCT_TLVLEN( 11783 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11784 cmd->vdev_id = param->vdev_id; 11785 cmd->bssid_idx = param->idx; 11786 cmd->action = param->action; 11787 cmd->type = param->type; 11788 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11789 cmd->flag = 0; 11790 11791 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11792 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11793 WMI_LOGE("Failed to set neighbour rx param\n"); 11794 wmi_buf_free(buf); 11795 return QDF_STATUS_E_FAILURE; 11796 } 11797 11798 return QDF_STATUS_SUCCESS; 11799 } 11800 11801 /** 11802 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11803 * @param wmi_handle : handle to WMI. 11804 * @param macaddr : vdev mac address 11805 * @param param : pointer to tx antenna param 11806 * 11807 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11808 */ 11809 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11810 uint8_t macaddr[IEEE80211_ADDR_LEN], 11811 struct smart_ant_tx_ant_params *param) 11812 { 11813 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11814 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11815 wmi_buf_t buf; 11816 int32_t len = 0; 11817 int i; 11818 uint8_t *buf_ptr; 11819 QDF_STATUS ret; 11820 11821 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11822 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11823 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11824 buf = wmi_buf_alloc(wmi_handle, len); 11825 11826 if (!buf) { 11827 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11828 return QDF_STATUS_E_NOMEM; 11829 } 11830 11831 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11832 qdf_mem_zero(buf_ptr, len); 11833 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11834 11835 WMITLV_SET_HDR(&cmd->tlv_header, 11836 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11837 WMITLV_GET_STRUCT_TLVLEN( 11838 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11839 11840 cmd->vdev_id = param->vdev_id; 11841 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11842 11843 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11844 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11845 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11846 buf_ptr += WMI_TLV_HDR_SIZE; 11847 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11848 11849 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11850 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11851 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11852 WMITLV_GET_STRUCT_TLVLEN( 11853 wmi_peer_smart_ant_set_tx_antenna_series)); 11854 ant_tx_series->antenna_series = param->antenna_array[i]; 11855 ant_tx_series++; 11856 } 11857 11858 ret = wmi_unified_cmd_send(wmi_handle, 11859 buf, 11860 len, 11861 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11862 11863 if (ret != 0) { 11864 WMI_LOGE(" %s :WMI Failed\n", __func__); 11865 wmi_buf_free(buf); 11866 } 11867 11868 return ret; 11869 } 11870 11871 /** 11872 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11873 * @wmi_handle: wmi handle 11874 * @param: pointer to hold ant switch tbl param 11875 * 11876 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11877 */ 11878 static QDF_STATUS 11879 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11880 struct ant_switch_tbl_params *param) 11881 { 11882 uint8_t len; 11883 wmi_buf_t buf; 11884 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11885 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11886 uint8_t *buf_ptr; 11887 11888 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11889 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11890 buf = wmi_buf_alloc(wmi_handle, len); 11891 11892 if (!buf) { 11893 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11894 return QDF_STATUS_E_NOMEM; 11895 } 11896 11897 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11898 qdf_mem_zero(buf_ptr, len); 11899 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11900 11901 WMITLV_SET_HDR(&cmd->tlv_header, 11902 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11903 WMITLV_GET_STRUCT_TLVLEN( 11904 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11905 11906 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11907 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11908 cmd->mac_id = 11909 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11910 11911 /* TLV indicating array of structures to follow */ 11912 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11913 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11914 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11915 buf_ptr += WMI_TLV_HDR_SIZE; 11916 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11917 11918 ctrl_chain->pdev_id = 11919 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11920 ctrl_chain->antCtrlChain = param->antCtrlChain; 11921 11922 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11923 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11924 wmi_buf_free(buf); 11925 return QDF_STATUS_E_FAILURE; 11926 } 11927 11928 return QDF_STATUS_SUCCESS; 11929 } 11930 11931 /** 11932 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11933 * training information function 11934 * @param wmi_handle : handle to WMI. 11935 * @macaddr : vdev mac address 11936 * @param param : pointer to tx antenna param 11937 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11938 */ 11939 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11940 wmi_unified_t wmi_handle, 11941 uint8_t macaddr[IEEE80211_ADDR_LEN], 11942 struct smart_ant_training_info_params *param) 11943 { 11944 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11945 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11946 wmi_buf_t buf; 11947 uint8_t *buf_ptr; 11948 int32_t len = 0; 11949 QDF_STATUS ret; 11950 int loop; 11951 11952 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11953 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11954 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11955 buf = wmi_buf_alloc(wmi_handle, len); 11956 11957 if (!buf) { 11958 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11959 return QDF_STATUS_E_NOMEM; 11960 } 11961 11962 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11963 qdf_mem_zero(buf_ptr, len); 11964 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11965 11966 WMITLV_SET_HDR(&cmd->tlv_header, 11967 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11968 WMITLV_GET_STRUCT_TLVLEN( 11969 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11970 11971 cmd->vdev_id = param->vdev_id; 11972 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11973 cmd->num_pkts = param->numpkts; 11974 11975 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11976 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11977 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11978 WMI_SMART_ANT_MAX_RATE_SERIES); 11979 11980 buf_ptr += WMI_TLV_HDR_SIZE; 11981 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11982 11983 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11984 WMITLV_SET_HDR(&train_param->tlv_header, 11985 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11986 WMITLV_GET_STRUCT_TLVLEN( 11987 wmi_peer_smart_ant_set_train_antenna_param)); 11988 train_param->train_rate_series = param->rate_array[loop]; 11989 train_param->train_antenna_series = param->antenna_array[loop]; 11990 train_param->rc_flags = 0; 11991 WMI_LOGI(FL("Series number:%d\n"), loop); 11992 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11993 train_param->train_rate_series, 11994 train_param->train_antenna_series); 11995 train_param++; 11996 } 11997 11998 ret = wmi_unified_cmd_send(wmi_handle, 11999 buf, 12000 len, 12001 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 12002 12003 if (ret != 0) { 12004 WMI_LOGE(" %s :WMI Failed\n", __func__); 12005 wmi_buf_free(buf); 12006 return QDF_STATUS_E_FAILURE; 12007 } 12008 12009 return ret; 12010 } 12011 12012 /** 12013 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 12014 * configuration function 12015 * @param wmi_handle : handle to WMI. 12016 * @macaddr : vdev mad address 12017 * @param param : pointer to tx antenna param 12018 * 12019 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12020 */ 12021 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 12022 wmi_unified_t wmi_handle, 12023 uint8_t macaddr[IEEE80211_ADDR_LEN], 12024 struct smart_ant_node_config_params *param) 12025 { 12026 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 12027 wmi_buf_t buf; 12028 uint8_t *buf_ptr; 12029 int32_t len = 0, args_tlv_len; 12030 int ret; 12031 int i = 0; 12032 uint32_t *node_config_args; 12033 12034 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 12035 len = sizeof(*cmd) + args_tlv_len; 12036 12037 if (param->args_count == 0) { 12038 WMI_LOGE("%s: Can't send a command with %d arguments\n", 12039 __func__, param->args_count); 12040 return QDF_STATUS_E_FAILURE; 12041 } 12042 12043 buf = wmi_buf_alloc(wmi_handle, len); 12044 if (!buf) { 12045 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12046 return QDF_STATUS_E_NOMEM; 12047 } 12048 12049 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 12050 wmi_buf_data(buf); 12051 buf_ptr = (uint8_t *)cmd; 12052 WMITLV_SET_HDR(&cmd->tlv_header, 12053 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 12054 WMITLV_GET_STRUCT_TLVLEN( 12055 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 12056 cmd->vdev_id = param->vdev_id; 12057 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12058 cmd->cmd_id = param->cmd_id; 12059 cmd->args_count = param->args_count; 12060 buf_ptr += sizeof( 12061 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 12062 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12063 (cmd->args_count * sizeof(uint32_t))); 12064 buf_ptr += WMI_TLV_HDR_SIZE; 12065 node_config_args = (uint32_t *)buf_ptr; 12066 12067 for (i = 0; i < param->args_count; i++) { 12068 node_config_args[i] = param->args_arr[i]; 12069 WMI_LOGI("%d", param->args_arr[i]); 12070 } 12071 12072 ret = wmi_unified_cmd_send(wmi_handle, 12073 buf, 12074 len, 12075 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 12076 12077 if (ret != 0) { 12078 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 12079 __func__, param->cmd_id, macaddr[0], 12080 macaddr[1], macaddr[2], macaddr[3], 12081 macaddr[4], macaddr[5], ret); 12082 wmi_buf_free(buf); 12083 } 12084 12085 return ret; 12086 } 12087 12088 /** 12089 * send_set_atf_cmd_tlv() - send set atf command to fw 12090 * @wmi_handle: wmi handle 12091 * @param: pointer to set atf param 12092 * 12093 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12094 */ 12095 static QDF_STATUS 12096 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 12097 struct set_atf_params *param) 12098 { 12099 wmi_atf_peer_info *peer_info; 12100 wmi_peer_atf_request_fixed_param *cmd; 12101 wmi_buf_t buf; 12102 uint8_t *buf_ptr; 12103 int i; 12104 int32_t len = 0; 12105 QDF_STATUS retval; 12106 12107 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12108 len += param->num_peers * sizeof(wmi_atf_peer_info); 12109 buf = wmi_buf_alloc(wmi_handle, len); 12110 if (!buf) { 12111 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12112 return QDF_STATUS_E_FAILURE; 12113 } 12114 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12115 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 12116 WMITLV_SET_HDR(&cmd->tlv_header, 12117 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 12118 WMITLV_GET_STRUCT_TLVLEN( 12119 wmi_peer_atf_request_fixed_param)); 12120 cmd->num_peers = param->num_peers; 12121 12122 buf_ptr += sizeof(*cmd); 12123 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12124 sizeof(wmi_atf_peer_info) * 12125 cmd->num_peers); 12126 buf_ptr += WMI_TLV_HDR_SIZE; 12127 peer_info = (wmi_atf_peer_info *)buf_ptr; 12128 12129 for (i = 0; i < cmd->num_peers; i++) { 12130 WMITLV_SET_HDR(&peer_info->tlv_header, 12131 WMITLV_TAG_STRUC_wmi_atf_peer_info, 12132 WMITLV_GET_STRUCT_TLVLEN( 12133 wmi_atf_peer_info)); 12134 qdf_mem_copy(&(peer_info->peer_macaddr), 12135 &(param->peer_info[i].peer_macaddr), 12136 sizeof(wmi_mac_addr)); 12137 peer_info->atf_units = param->peer_info[i].percentage_peer; 12138 peer_info->vdev_id = param->peer_info[i].vdev_id; 12139 peer_info->pdev_id = 12140 wmi_handle->ops->convert_pdev_id_host_to_target( 12141 param->peer_info[i].pdev_id); 12142 /* 12143 * TLV definition for peer atf request fixed param combines 12144 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 12145 * stats and atf extension stats as two different 12146 * implementations. 12147 * Need to discuss with FW on this. 12148 * 12149 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 12150 * peer_info->atf_units_reserved = 12151 * param->peer_ext_info[i].atf_index_reserved; 12152 */ 12153 peer_info++; 12154 } 12155 12156 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12157 WMI_PEER_ATF_REQUEST_CMDID); 12158 12159 if (retval != QDF_STATUS_SUCCESS) { 12160 WMI_LOGE("%s : WMI Failed\n", __func__); 12161 wmi_buf_free(buf); 12162 } 12163 12164 return retval; 12165 } 12166 12167 /** 12168 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 12169 * @wmi_handle: wmi handle 12170 * @param: pointer to hold fwtest param 12171 * 12172 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12173 */ 12174 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 12175 struct set_fwtest_params *param) 12176 { 12177 wmi_fwtest_set_param_cmd_fixed_param *cmd; 12178 wmi_buf_t buf; 12179 int32_t len = sizeof(*cmd); 12180 12181 buf = wmi_buf_alloc(wmi_handle, len); 12182 12183 if (!buf) { 12184 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12185 return QDF_STATUS_E_FAILURE; 12186 } 12187 12188 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 12189 WMITLV_SET_HDR(&cmd->tlv_header, 12190 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 12191 WMITLV_GET_STRUCT_TLVLEN( 12192 wmi_fwtest_set_param_cmd_fixed_param)); 12193 cmd->param_id = param->arg; 12194 cmd->param_value = param->value; 12195 12196 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 12197 WMI_LOGE("Setting FW test param failed\n"); 12198 wmi_buf_free(buf); 12199 return QDF_STATUS_E_FAILURE; 12200 } 12201 12202 return QDF_STATUS_SUCCESS; 12203 } 12204 12205 /** 12206 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 12207 * @wmi_handle: wmi handle 12208 * @param: pointer to qboost params 12209 * @macaddr: vdev mac address 12210 * 12211 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12212 */ 12213 static QDF_STATUS 12214 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 12215 uint8_t macaddr[IEEE80211_ADDR_LEN], 12216 struct set_qboost_params *param) 12217 { 12218 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 12219 wmi_buf_t buf; 12220 int32_t len; 12221 QDF_STATUS ret; 12222 12223 len = sizeof(*cmd); 12224 12225 buf = wmi_buf_alloc(wmi_handle, len); 12226 if (!buf) { 12227 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12228 return QDF_STATUS_E_FAILURE; 12229 } 12230 12231 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 12232 WMITLV_SET_HDR(&cmd->tlv_header, 12233 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 12234 WMITLV_GET_STRUCT_TLVLEN( 12235 WMI_QBOOST_CFG_CMD_fixed_param)); 12236 cmd->vdev_id = param->vdev_id; 12237 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12238 cmd->qb_enable = param->value; 12239 12240 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12241 WMI_QBOOST_CFG_CMDID); 12242 12243 if (ret != 0) { 12244 WMI_LOGE("Setting qboost cmd failed\n"); 12245 wmi_buf_free(buf); 12246 } 12247 12248 return ret; 12249 } 12250 12251 /** 12252 * send_gpio_config_cmd_tlv() - send gpio config to fw 12253 * @wmi_handle: wmi handle 12254 * @param: pointer to hold gpio config param 12255 * 12256 * Return: 0 for success or error code 12257 */ 12258 static QDF_STATUS 12259 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 12260 struct gpio_config_params *param) 12261 { 12262 wmi_gpio_config_cmd_fixed_param *cmd; 12263 wmi_buf_t buf; 12264 int32_t len; 12265 QDF_STATUS ret; 12266 12267 len = sizeof(*cmd); 12268 12269 /* Sanity Checks */ 12270 if (param->pull_type > WMI_GPIO_PULL_DOWN || 12271 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 12272 return QDF_STATUS_E_FAILURE; 12273 } 12274 12275 buf = wmi_buf_alloc(wmi_handle, len); 12276 if (!buf) { 12277 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12278 return QDF_STATUS_E_FAILURE; 12279 } 12280 12281 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 12282 WMITLV_SET_HDR(&cmd->tlv_header, 12283 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 12284 WMITLV_GET_STRUCT_TLVLEN( 12285 wmi_gpio_config_cmd_fixed_param)); 12286 cmd->gpio_num = param->gpio_num; 12287 cmd->input = param->input; 12288 cmd->pull_type = param->pull_type; 12289 cmd->intr_mode = param->intr_mode; 12290 12291 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12292 WMI_GPIO_CONFIG_CMDID); 12293 12294 if (ret != 0) { 12295 WMI_LOGE("Sending GPIO config cmd failed\n"); 12296 wmi_buf_free(buf); 12297 } 12298 12299 return ret; 12300 } 12301 12302 /** 12303 * send_gpio_output_cmd_tlv() - send gpio output to fw 12304 * @wmi_handle: wmi handle 12305 * @param: pointer to hold gpio output param 12306 * 12307 * Return: 0 for success or error code 12308 */ 12309 static QDF_STATUS 12310 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 12311 struct gpio_output_params *param) 12312 { 12313 wmi_gpio_output_cmd_fixed_param *cmd; 12314 wmi_buf_t buf; 12315 int32_t len; 12316 QDF_STATUS ret; 12317 12318 len = sizeof(*cmd); 12319 12320 buf = wmi_buf_alloc(wmi_handle, len); 12321 if (!buf) { 12322 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12323 return QDF_STATUS_E_FAILURE; 12324 } 12325 12326 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 12327 WMITLV_SET_HDR(&cmd->tlv_header, 12328 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 12329 WMITLV_GET_STRUCT_TLVLEN( 12330 wmi_gpio_output_cmd_fixed_param)); 12331 cmd->gpio_num = param->gpio_num; 12332 cmd->set = param->set; 12333 12334 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12335 WMI_GPIO_OUTPUT_CMDID); 12336 12337 if (ret != 0) { 12338 WMI_LOGE("Sending GPIO output cmd failed\n"); 12339 wmi_buf_free(buf); 12340 } 12341 12342 return ret; 12343 12344 } 12345 12346 /** 12347 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 12348 * 12349 * @param wmi_handle : handle to WMI. 12350 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12351 */ 12352 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 12353 { 12354 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 12355 wmi_buf_t buf; 12356 QDF_STATUS ret; 12357 int32_t len; 12358 12359 len = sizeof(*cmd); 12360 12361 buf = wmi_buf_alloc(wmi_handle, len); 12362 if (!buf) { 12363 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12364 return QDF_STATUS_E_FAILURE; 12365 } 12366 12367 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 12368 WMITLV_SET_HDR(&cmd->tlv_header, 12369 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 12370 WMITLV_GET_STRUCT_TLVLEN( 12371 wmi_pdev_dfs_disable_cmd_fixed_param)); 12372 /* Filling it with WMI_PDEV_ID_SOC for now */ 12373 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12374 WMI_HOST_PDEV_ID_SOC); 12375 12376 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12377 WMI_PDEV_DFS_DISABLE_CMDID); 12378 12379 if (ret != 0) { 12380 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 12381 wmi_buf_free(buf); 12382 } 12383 12384 return ret; 12385 } 12386 12387 /** 12388 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 12389 * 12390 * @param wmi_handle : handle to WMI. 12391 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12392 */ 12393 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 12394 { 12395 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 12396 wmi_buf_t buf; 12397 QDF_STATUS ret; 12398 int32_t len; 12399 12400 len = sizeof(*cmd); 12401 12402 buf = wmi_buf_alloc(wmi_handle, len); 12403 if (!buf) { 12404 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12405 return QDF_STATUS_E_FAILURE; 12406 } 12407 12408 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 12409 WMITLV_SET_HDR(&cmd->tlv_header, 12410 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 12411 WMITLV_GET_STRUCT_TLVLEN( 12412 wmi_pdev_dfs_enable_cmd_fixed_param)); 12413 /* Reserved for future use */ 12414 cmd->reserved0 = 0; 12415 12416 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12417 WMI_PDEV_DFS_ENABLE_CMDID); 12418 12419 if (ret != 0) { 12420 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 12421 wmi_buf_free(buf); 12422 } 12423 12424 return ret; 12425 } 12426 12427 /** 12428 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 12429 * to fw 12430 * @wmi_handle: wmi handle 12431 * @param: pointer to hold periodic chan stats param 12432 * 12433 * Return: 0 for success or error code 12434 */ 12435 static QDF_STATUS 12436 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 12437 struct periodic_chan_stats_params *param) 12438 { 12439 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 12440 wmi_buf_t buf; 12441 QDF_STATUS ret; 12442 int32_t len; 12443 12444 len = sizeof(*cmd); 12445 12446 buf = wmi_buf_alloc(wmi_handle, len); 12447 if (!buf) { 12448 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12449 return QDF_STATUS_E_FAILURE; 12450 } 12451 12452 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 12453 wmi_buf_data(buf); 12454 WMITLV_SET_HDR(&cmd->tlv_header, 12455 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 12456 WMITLV_GET_STRUCT_TLVLEN( 12457 wmi_set_periodic_channel_stats_config_fixed_param)); 12458 cmd->enable = param->enable; 12459 cmd->stats_period = param->stats_period; 12460 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12461 param->pdev_id); 12462 12463 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12464 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 12465 12466 if (ret != 0) { 12467 WMI_LOGE("Sending periodic chan stats config failed"); 12468 wmi_buf_free(buf); 12469 } 12470 12471 return ret; 12472 } 12473 12474 /** 12475 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 12476 * @wmi_handle: wmi handle 12477 * @mac_id: radio context 12478 * 12479 * Return: 0 for success or error code 12480 */ 12481 static QDF_STATUS 12482 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 12483 { 12484 wmi_buf_t buf; 12485 QDF_STATUS ret; 12486 wmi_pdev_get_nfcal_power_fixed_param *cmd; 12487 int32_t len = sizeof(*cmd); 12488 12489 buf = wmi_buf_alloc(wmi_handle, len); 12490 if (buf == NULL) 12491 return QDF_STATUS_E_NOMEM; 12492 12493 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 12494 WMITLV_SET_HDR(&cmd->tlv_header, 12495 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 12496 WMITLV_GET_STRUCT_TLVLEN 12497 (wmi_pdev_get_nfcal_power_fixed_param)); 12498 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 12499 12500 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12501 WMI_PDEV_GET_NFCAL_POWER_CMDID); 12502 if (ret != 0) { 12503 WMI_LOGE("Sending get nfcal power cmd failed\n"); 12504 wmi_buf_free(buf); 12505 } 12506 12507 return ret; 12508 } 12509 12510 /** 12511 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 12512 * @wmi_handle: wmi handle 12513 * @param: pointer to ht ie param 12514 * 12515 * Return: 0 for success or error code 12516 */ 12517 static QDF_STATUS 12518 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12519 struct ht_ie_params *param) 12520 { 12521 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 12522 wmi_buf_t buf; 12523 QDF_STATUS ret; 12524 int32_t len; 12525 uint8_t *buf_ptr; 12526 12527 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12528 roundup(param->ie_len, sizeof(uint32_t)); 12529 12530 buf = wmi_buf_alloc(wmi_handle, len); 12531 if (!buf) { 12532 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12533 return QDF_STATUS_E_FAILURE; 12534 } 12535 12536 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12537 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 12538 WMITLV_SET_HDR(&cmd->tlv_header, 12539 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 12540 WMITLV_GET_STRUCT_TLVLEN( 12541 wmi_pdev_set_ht_ie_cmd_fixed_param)); 12542 cmd->reserved0 = 0; 12543 cmd->ie_len = param->ie_len; 12544 cmd->tx_streams = param->tx_streams; 12545 cmd->rx_streams = param->rx_streams; 12546 12547 buf_ptr += sizeof(*cmd); 12548 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12549 buf_ptr += WMI_TLV_HDR_SIZE; 12550 if (param->ie_len) 12551 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12552 cmd->ie_len); 12553 12554 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12555 WMI_PDEV_SET_HT_CAP_IE_CMDID); 12556 12557 if (ret != 0) { 12558 WMI_LOGE("Sending set ht ie cmd failed\n"); 12559 wmi_buf_free(buf); 12560 } 12561 12562 return ret; 12563 } 12564 12565 /** 12566 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 12567 * @wmi_handle: wmi handle 12568 * @param: pointer to vht ie param 12569 * 12570 * Return: 0 for success or error code 12571 */ 12572 static QDF_STATUS 12573 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12574 struct vht_ie_params *param) 12575 { 12576 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 12577 wmi_buf_t buf; 12578 QDF_STATUS ret; 12579 int32_t len; 12580 uint8_t *buf_ptr; 12581 12582 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12583 roundup(param->ie_len, sizeof(uint32_t)); 12584 12585 buf = wmi_buf_alloc(wmi_handle, len); 12586 if (!buf) { 12587 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12588 return QDF_STATUS_E_FAILURE; 12589 } 12590 12591 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12592 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 12593 WMITLV_SET_HDR(&cmd->tlv_header, 12594 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 12595 WMITLV_GET_STRUCT_TLVLEN( 12596 wmi_pdev_set_vht_ie_cmd_fixed_param)); 12597 cmd->reserved0 = 0; 12598 cmd->ie_len = param->ie_len; 12599 cmd->tx_streams = param->tx_streams; 12600 cmd->rx_streams = param->rx_streams; 12601 12602 buf_ptr += sizeof(*cmd); 12603 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12604 buf_ptr += WMI_TLV_HDR_SIZE; 12605 if (param->ie_len) 12606 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12607 cmd->ie_len); 12608 12609 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12610 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 12611 12612 if (ret != 0) { 12613 WMI_LOGE("Sending set vht ie cmd failed\n"); 12614 wmi_buf_free(buf); 12615 } 12616 12617 return ret; 12618 } 12619 12620 /** 12621 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 12622 * @wmi_handle: wmi handle 12623 * @param: pointer to quiet mode params 12624 * 12625 * Return: 0 for success or error code 12626 */ 12627 static QDF_STATUS 12628 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 12629 struct set_quiet_mode_params *param) 12630 { 12631 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 12632 wmi_buf_t buf; 12633 QDF_STATUS ret; 12634 int32_t len; 12635 12636 len = sizeof(*quiet_cmd); 12637 buf = wmi_buf_alloc(wmi_handle, len); 12638 if (!buf) { 12639 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12640 return QDF_STATUS_E_FAILURE; 12641 } 12642 12643 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12644 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 12645 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 12646 WMITLV_GET_STRUCT_TLVLEN( 12647 wmi_pdev_set_quiet_cmd_fixed_param)); 12648 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12649 quiet_cmd->enabled = param->enabled; 12650 quiet_cmd->period = (param->period)*(param->intval); 12651 quiet_cmd->duration = param->duration; 12652 quiet_cmd->next_start = param->offset; 12653 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12654 WMI_HOST_PDEV_ID_SOC); 12655 12656 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12657 WMI_PDEV_SET_QUIET_MODE_CMDID); 12658 12659 if (ret != 0) { 12660 WMI_LOGE("Sending set quiet cmd failed\n"); 12661 wmi_buf_free(buf); 12662 } 12663 12664 return ret; 12665 } 12666 12667 /** 12668 * send_set_bwf_cmd_tlv() - send set bwf command to fw 12669 * @wmi_handle: wmi handle 12670 * @param: pointer to set bwf param 12671 * 12672 * Return: 0 for success or error code 12673 */ 12674 static QDF_STATUS 12675 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12676 struct set_bwf_params *param) 12677 { 12678 wmi_bwf_peer_info *peer_info; 12679 wmi_peer_bwf_request_fixed_param *cmd; 12680 wmi_buf_t buf; 12681 QDF_STATUS retval; 12682 int32_t len; 12683 uint8_t *buf_ptr; 12684 int i; 12685 12686 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12687 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12688 buf = wmi_buf_alloc(wmi_handle, len); 12689 if (!buf) { 12690 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12691 return QDF_STATUS_E_FAILURE; 12692 } 12693 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12694 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12695 WMITLV_SET_HDR(&cmd->tlv_header, 12696 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12697 WMITLV_GET_STRUCT_TLVLEN( 12698 wmi_peer_bwf_request_fixed_param)); 12699 cmd->num_peers = param->num_peers; 12700 12701 buf_ptr += sizeof(*cmd); 12702 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12703 sizeof(wmi_bwf_peer_info) * 12704 cmd->num_peers); 12705 buf_ptr += WMI_TLV_HDR_SIZE; 12706 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12707 12708 for (i = 0; i < cmd->num_peers; i++) { 12709 WMITLV_SET_HDR(&peer_info->tlv_header, 12710 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12711 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12712 peer_info->bwf_guaranteed_bandwidth = 12713 param->peer_info[i].throughput; 12714 peer_info->bwf_max_airtime = 12715 param->peer_info[i].max_airtime; 12716 peer_info->bwf_peer_priority = 12717 param->peer_info[i].priority; 12718 qdf_mem_copy(&peer_info->peer_macaddr, 12719 ¶m->peer_info[i].peer_macaddr, 12720 sizeof(param->peer_info[i].peer_macaddr)); 12721 peer_info->vdev_id = 12722 param->peer_info[i].vdev_id; 12723 peer_info->pdev_id = 12724 wmi_handle->ops->convert_pdev_id_host_to_target( 12725 param->peer_info[i].pdev_id); 12726 peer_info++; 12727 } 12728 12729 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12730 WMI_PEER_BWF_REQUEST_CMDID); 12731 12732 if (retval != QDF_STATUS_SUCCESS) { 12733 WMI_LOGE("%s : WMI Failed\n", __func__); 12734 wmi_buf_free(buf); 12735 } 12736 12737 return retval; 12738 } 12739 12740 /** 12741 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12742 * @wmi_handle: wmi handle 12743 * @param: pointer to hold mcast update param 12744 * 12745 * Return: 0 for success or error code 12746 */ 12747 static QDF_STATUS 12748 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12749 struct mcast_group_update_params *param) 12750 { 12751 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12752 wmi_buf_t buf; 12753 QDF_STATUS ret; 12754 int32_t len; 12755 int offset = 0; 12756 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12757 12758 len = sizeof(*cmd); 12759 buf = wmi_buf_alloc(wmi_handle, len); 12760 if (!buf) { 12761 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12762 return QDF_STATUS_E_FAILURE; 12763 } 12764 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12765 WMITLV_SET_HDR(&cmd->tlv_header, 12766 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12767 WMITLV_GET_STRUCT_TLVLEN( 12768 wmi_peer_mcast_group_cmd_fixed_param)); 12769 /* confirm the buffer is 4-byte aligned */ 12770 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12771 qdf_mem_zero(cmd, sizeof(*cmd)); 12772 12773 cmd->vdev_id = param->vap_id; 12774 /* construct the message assuming our endianness matches the target */ 12775 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12776 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12777 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12778 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12779 if (param->is_action_delete) 12780 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12781 12782 if (param->is_mcast_addr_len) 12783 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12784 12785 if (param->is_filter_mode_snoop) 12786 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12787 12788 /* unicast address spec only applies for non-wildcard cases */ 12789 if (!param->wildcard && param->ucast_mac_addr) { 12790 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12791 &cmd->ucast_mac_addr); 12792 } 12793 12794 if (param->mcast_ip_addr) { 12795 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12796 sizeof(cmd->mcast_ip_addr)); 12797 offset = sizeof(cmd->mcast_ip_addr) - 12798 param->mcast_ip_addr_bytes; 12799 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12800 param->mcast_ip_addr, 12801 param->mcast_ip_addr_bytes); 12802 } 12803 if (!param->mask) 12804 param->mask = &dummymask[0]; 12805 12806 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12807 param->mask, 12808 param->mcast_ip_addr_bytes); 12809 12810 if (param->srcs && param->nsrcs) { 12811 cmd->num_filter_addr = param->nsrcs; 12812 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12813 sizeof(cmd->filter_addr)); 12814 12815 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12816 param->nsrcs * param->mcast_ip_addr_bytes); 12817 } 12818 12819 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12820 WMI_PEER_MCAST_GROUP_CMDID); 12821 12822 if (ret != QDF_STATUS_SUCCESS) { 12823 WMI_LOGE("%s : WMI Failed\n", __func__); 12824 wmi_buf_free(buf); 12825 } 12826 12827 return ret; 12828 } 12829 12830 /** 12831 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12832 * command to fw 12833 * @wmi_handle: wmi handle 12834 * @param: pointer to hold spectral config parameter 12835 * 12836 * Return: 0 for success or error code 12837 */ 12838 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12839 struct vdev_spectral_configure_params *param) 12840 { 12841 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12842 wmi_buf_t buf; 12843 QDF_STATUS ret; 12844 int32_t len; 12845 12846 len = sizeof(*cmd); 12847 buf = wmi_buf_alloc(wmi_handle, len); 12848 if (!buf) { 12849 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12850 return QDF_STATUS_E_FAILURE; 12851 } 12852 12853 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12854 WMITLV_SET_HDR(&cmd->tlv_header, 12855 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12856 WMITLV_GET_STRUCT_TLVLEN( 12857 wmi_vdev_spectral_configure_cmd_fixed_param)); 12858 12859 cmd->vdev_id = param->vdev_id; 12860 cmd->spectral_scan_count = param->count; 12861 cmd->spectral_scan_period = param->period; 12862 cmd->spectral_scan_priority = param->spectral_pri; 12863 cmd->spectral_scan_fft_size = param->fft_size; 12864 cmd->spectral_scan_gc_ena = param->gc_enable; 12865 cmd->spectral_scan_restart_ena = param->restart_enable; 12866 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12867 cmd->spectral_scan_init_delay = param->init_delay; 12868 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12869 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12870 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12871 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12872 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12873 cmd->spectral_scan_pwr_format = param->pwr_format; 12874 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12875 cmd->spectral_scan_bin_scale = param->bin_scale; 12876 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12877 cmd->spectral_scan_chn_mask = param->chn_mask; 12878 12879 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12880 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12881 12882 if (ret != 0) { 12883 WMI_LOGE("Sending set quiet cmd failed\n"); 12884 wmi_buf_free(buf); 12885 } 12886 12887 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12888 __func__); 12889 12890 WMI_LOGI("vdev_id = %u\n" 12891 "spectral_scan_count = %u\n" 12892 "spectral_scan_period = %u\n" 12893 "spectral_scan_priority = %u\n" 12894 "spectral_scan_fft_size = %u\n" 12895 "spectral_scan_gc_ena = %u\n" 12896 "spectral_scan_restart_ena = %u\n" 12897 "spectral_scan_noise_floor_ref = %u\n" 12898 "spectral_scan_init_delay = %u\n" 12899 "spectral_scan_nb_tone_thr = %u\n" 12900 "spectral_scan_str_bin_thr = %u\n" 12901 "spectral_scan_wb_rpt_mode = %u\n" 12902 "spectral_scan_rssi_rpt_mode = %u\n" 12903 "spectral_scan_rssi_thr = %u\n" 12904 "spectral_scan_pwr_format = %u\n" 12905 "spectral_scan_rpt_mode = %u\n" 12906 "spectral_scan_bin_scale = %u\n" 12907 "spectral_scan_dBm_adj = %u\n" 12908 "spectral_scan_chn_mask = %u\n", 12909 param->vdev_id, 12910 param->count, 12911 param->period, 12912 param->spectral_pri, 12913 param->fft_size, 12914 param->gc_enable, 12915 param->restart_enable, 12916 param->noise_floor_ref, 12917 param->init_delay, 12918 param->nb_tone_thr, 12919 param->str_bin_thr, 12920 param->wb_rpt_mode, 12921 param->rssi_rpt_mode, 12922 param->rssi_thr, 12923 param->pwr_format, 12924 param->rpt_mode, 12925 param->bin_scale, 12926 param->dbm_adj, 12927 param->chn_mask); 12928 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12929 12930 return ret; 12931 } 12932 12933 /** 12934 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12935 * command to fw 12936 * @wmi_handle: wmi handle 12937 * @param: pointer to hold spectral enable parameter 12938 * 12939 * Return: 0 for success or error code 12940 */ 12941 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12942 struct vdev_spectral_enable_params *param) 12943 { 12944 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12945 wmi_buf_t buf; 12946 QDF_STATUS ret; 12947 int32_t len; 12948 12949 len = sizeof(*cmd); 12950 buf = wmi_buf_alloc(wmi_handle, len); 12951 if (!buf) { 12952 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12953 return QDF_STATUS_E_FAILURE; 12954 } 12955 12956 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12957 WMITLV_SET_HDR(&cmd->tlv_header, 12958 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12959 WMITLV_GET_STRUCT_TLVLEN( 12960 wmi_vdev_spectral_enable_cmd_fixed_param)); 12961 12962 cmd->vdev_id = param->vdev_id; 12963 12964 if (param->active_valid) { 12965 cmd->trigger_cmd = param->active ? 1 : 2; 12966 /* 1: Trigger, 2: Clear Trigger */ 12967 } else { 12968 cmd->trigger_cmd = 0; /* 0: Ignore */ 12969 } 12970 12971 if (param->enabled_valid) { 12972 cmd->enable_cmd = param->enabled ? 1 : 2; 12973 /* 1: Enable 2: Disable */ 12974 } else { 12975 cmd->enable_cmd = 0; /* 0: Ignore */ 12976 } 12977 12978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12979 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12980 12981 if (ret != 0) { 12982 WMI_LOGE("Sending scan enable CMD failed\n"); 12983 wmi_buf_free(buf); 12984 } 12985 12986 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12987 12988 WMI_LOGI("vdev_id = %u\n" 12989 "trigger_cmd = %u\n" 12990 "enable_cmd = %u\n", 12991 cmd->vdev_id, 12992 cmd->trigger_cmd, 12993 cmd->enable_cmd); 12994 12995 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12996 12997 return ret; 12998 } 12999 13000 /** 13001 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 13002 * @param wmi_handle : handle to WMI. 13003 * @param param : pointer to hold thermal mitigation param 13004 * 13005 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 13006 */ 13007 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 13008 wmi_unified_t wmi_handle, 13009 struct thermal_mitigation_params *param) 13010 { 13011 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 13012 wmi_therm_throt_level_config_info *lvl_conf = NULL; 13013 wmi_buf_t buf = NULL; 13014 uint8_t *buf_ptr = NULL; 13015 int error; 13016 int32_t len; 13017 int i; 13018 13019 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 13020 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 13021 13022 buf = wmi_buf_alloc(wmi_handle, len); 13023 if (!buf) { 13024 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13025 return QDF_STATUS_E_NOMEM; 13026 } 13027 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 13028 13029 /* init fixed params */ 13030 WMITLV_SET_HDR(tt_conf, 13031 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 13032 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 13033 13034 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13035 param->pdev_id); 13036 tt_conf->enable = param->enable; 13037 tt_conf->dc = param->dc; 13038 tt_conf->dc_per_event = param->dc_per_event; 13039 tt_conf->therm_throt_levels = THERMAL_LEVELS; 13040 13041 buf_ptr = (uint8_t *) ++tt_conf; 13042 /* init TLV params */ 13043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13044 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 13045 13046 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 13047 for (i = 0; i < THERMAL_LEVELS; i++) { 13048 WMITLV_SET_HDR(&lvl_conf->tlv_header, 13049 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 13050 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 13051 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 13052 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 13053 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 13054 lvl_conf->prio = param->levelconf[i].priority; 13055 lvl_conf++; 13056 } 13057 13058 error = wmi_unified_cmd_send(wmi_handle, buf, len, 13059 WMI_THERM_THROT_SET_CONF_CMDID); 13060 if (QDF_IS_STATUS_ERROR(error)) { 13061 wmi_buf_free(buf); 13062 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 13063 } 13064 13065 return error; 13066 } 13067 13068 /** 13069 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 13070 * @wmi_handle: wmi handle 13071 * @param: pointer to pdev_qvit_params 13072 * 13073 * Return: 0 for success or error code 13074 */ 13075 static QDF_STATUS 13076 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 13077 struct pdev_qvit_params *param) 13078 { 13079 wmi_buf_t buf; 13080 QDF_STATUS ret = QDF_STATUS_E_INVAL; 13081 uint8_t *cmd; 13082 static uint8_t msgref = 1; 13083 uint8_t segnumber = 0, seginfo, numsegments; 13084 uint16_t chunk_len, total_bytes; 13085 uint8_t *bufpos; 13086 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 13087 13088 bufpos = param->utf_payload; 13089 total_bytes = param->len; 13090 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 13091 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 13092 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 13093 13094 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 13095 numsegments++; 13096 13097 while (param->len) { 13098 if (param->len > MAX_WMI_QVIT_LEN) 13099 chunk_len = MAX_WMI_QVIT_LEN; /* MAX messsage */ 13100 else 13101 chunk_len = param->len; 13102 13103 buf = wmi_buf_alloc(wmi_handle, 13104 (chunk_len + sizeof(seghdrinfo) + 13105 WMI_TLV_HDR_SIZE)); 13106 if (!buf) { 13107 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13108 return QDF_STATUS_E_NOMEM; 13109 } 13110 13111 cmd = (uint8_t *) wmi_buf_data(buf); 13112 13113 seghdrinfo.len = total_bytes; 13114 seghdrinfo.msgref = msgref; 13115 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 13116 seghdrinfo.segmentInfo = seginfo; 13117 13118 segnumber++; 13119 13120 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 13121 (chunk_len + sizeof(seghdrinfo))); 13122 cmd += WMI_TLV_HDR_SIZE; 13123 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 13124 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 13125 13126 ret = wmi_unified_cmd_send(wmi_handle, buf, 13127 (chunk_len + sizeof(seghdrinfo) + 13128 WMI_TLV_HDR_SIZE), 13129 WMI_PDEV_QVIT_CMDID); 13130 13131 if (ret != 0) { 13132 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 13133 wmi_buf_free(buf); 13134 break; 13135 } 13136 13137 param->len -= chunk_len; 13138 bufpos += chunk_len; 13139 } 13140 msgref++; 13141 13142 return ret; 13143 } 13144 13145 /** 13146 * send_wmm_update_cmd_tlv() - send wmm update command to fw 13147 * @wmi_handle: wmi handle 13148 * @param: pointer to wmm update param 13149 * 13150 * Return: 0 for success or error code 13151 */ 13152 static QDF_STATUS 13153 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 13154 struct wmm_update_params *param) 13155 { 13156 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 13157 wmi_wmm_params *wmm_param; 13158 wmi_buf_t buf; 13159 QDF_STATUS ret; 13160 int32_t len; 13161 int ac = 0; 13162 struct wmi_host_wmeParams *wmep; 13163 uint8_t *buf_ptr; 13164 13165 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 13166 buf = wmi_buf_alloc(wmi_handle, len); 13167 if (!buf) { 13168 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13169 return QDF_STATUS_E_FAILURE; 13170 } 13171 13172 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13173 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 13174 WMITLV_SET_HDR(&cmd->tlv_header, 13175 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 13176 WMITLV_GET_STRUCT_TLVLEN 13177 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 13178 13179 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 13180 13181 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 13182 13183 for (ac = 0; ac < WME_NUM_AC; ac++) { 13184 wmep = ¶m->wmep_array[ac]; 13185 wmm_param = (wmi_wmm_params *)buf_ptr; 13186 WMITLV_SET_HDR(&wmm_param->tlv_header, 13187 WMITLV_TAG_STRUC_wmi_wmm_params, 13188 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 13189 wmm_param->aifs = wmep->wmep_aifsn; 13190 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 13191 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 13192 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 13193 wmm_param->acm = wmep->wmep_acm; 13194 wmm_param->no_ack = wmep->wmep_noackPolicy; 13195 buf_ptr += sizeof(wmi_wmm_params); 13196 } 13197 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13198 WMI_PDEV_SET_WMM_PARAMS_CMDID); 13199 13200 if (ret != 0) { 13201 WMI_LOGE("Sending WMM update CMD failed\n"); 13202 wmi_buf_free(buf); 13203 } 13204 13205 return ret; 13206 } 13207 13208 /** 13209 * send_coex_config_cmd_tlv() - send coex config command to fw 13210 * @wmi_handle: wmi handle 13211 * @param: pointer to coex config param 13212 * 13213 * Return: 0 for success or error code 13214 */ 13215 static QDF_STATUS 13216 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 13217 struct coex_config_params *param) 13218 { 13219 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 13220 wmi_buf_t buf; 13221 QDF_STATUS ret; 13222 int32_t len; 13223 13224 len = sizeof(*cmd); 13225 buf = wmi_buf_alloc(wmi_handle, len); 13226 if (!buf) { 13227 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13228 return QDF_STATUS_E_FAILURE; 13229 } 13230 13231 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 13232 WMITLV_SET_HDR(&cmd->tlv_header, 13233 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 13234 WMITLV_GET_STRUCT_TLVLEN( 13235 WMI_COEX_CONFIG_CMD_fixed_param)); 13236 13237 cmd->vdev_id = param->vdev_id; 13238 cmd->config_type = param->config_type; 13239 cmd->config_arg1 = param->config_arg1; 13240 cmd->config_arg2 = param->config_arg2; 13241 cmd->config_arg3 = param->config_arg3; 13242 cmd->config_arg4 = param->config_arg4; 13243 cmd->config_arg5 = param->config_arg5; 13244 cmd->config_arg6 = param->config_arg6; 13245 13246 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13247 WMI_COEX_CONFIG_CMDID); 13248 13249 if (ret != 0) { 13250 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 13251 wmi_buf_free(buf); 13252 } 13253 13254 return ret; 13255 } 13256 13257 13258 #ifdef WLAN_SUPPORT_TWT 13259 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 13260 target_resource_config *tgt_res_cfg) 13261 { 13262 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 13263 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 13264 } 13265 #else 13266 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 13267 target_resource_config *tgt_res_cfg) 13268 { 13269 resource_cfg->twt_ap_pdev_count = 0; 13270 resource_cfg->twt_ap_sta_count = 0; 13271 } 13272 #endif 13273 13274 static 13275 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 13276 target_resource_config *tgt_res_cfg) 13277 { 13278 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 13279 resource_cfg->num_peers = tgt_res_cfg->num_peers; 13280 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 13281 resource_cfg->num_offload_reorder_buffs = 13282 tgt_res_cfg->num_offload_reorder_buffs; 13283 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 13284 resource_cfg->num_tids = tgt_res_cfg->num_tids; 13285 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 13286 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 13287 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 13288 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 13289 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 13290 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 13291 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 13292 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 13293 resource_cfg->scan_max_pending_req = 13294 tgt_res_cfg->scan_max_pending_req; 13295 resource_cfg->bmiss_offload_max_vdev = 13296 tgt_res_cfg->bmiss_offload_max_vdev; 13297 resource_cfg->roam_offload_max_vdev = 13298 tgt_res_cfg->roam_offload_max_vdev; 13299 resource_cfg->roam_offload_max_ap_profiles = 13300 tgt_res_cfg->roam_offload_max_ap_profiles; 13301 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 13302 resource_cfg->num_mcast_table_elems = 13303 tgt_res_cfg->num_mcast_table_elems; 13304 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 13305 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 13306 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 13307 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 13308 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 13309 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 13310 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 13311 resource_cfg->vow_config = tgt_res_cfg->vow_config; 13312 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 13313 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 13314 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 13315 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 13316 resource_cfg->num_tdls_conn_table_entries = 13317 tgt_res_cfg->num_tdls_conn_table_entries; 13318 resource_cfg->beacon_tx_offload_max_vdev = 13319 tgt_res_cfg->beacon_tx_offload_max_vdev; 13320 resource_cfg->num_multicast_filter_entries = 13321 tgt_res_cfg->num_multicast_filter_entries; 13322 resource_cfg->num_wow_filters = 13323 tgt_res_cfg->num_wow_filters; 13324 resource_cfg->num_keep_alive_pattern = 13325 tgt_res_cfg->num_keep_alive_pattern; 13326 resource_cfg->keep_alive_pattern_size = 13327 tgt_res_cfg->keep_alive_pattern_size; 13328 resource_cfg->max_tdls_concurrent_sleep_sta = 13329 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 13330 resource_cfg->max_tdls_concurrent_buffer_sta = 13331 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 13332 resource_cfg->wmi_send_separate = 13333 tgt_res_cfg->wmi_send_separate; 13334 resource_cfg->num_ocb_vdevs = 13335 tgt_res_cfg->num_ocb_vdevs; 13336 resource_cfg->num_ocb_channels = 13337 tgt_res_cfg->num_ocb_channels; 13338 resource_cfg->num_ocb_schedules = 13339 tgt_res_cfg->num_ocb_schedules; 13340 resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size; 13341 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 13342 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 13343 resource_cfg->max_num_dbs_scan_duty_cycle = 13344 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 13345 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 13346 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 13347 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 13348 13349 if (tgt_res_cfg->atf_config) 13350 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 13351 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 13352 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 13353 resource_cfg->flag1, 1); 13354 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 13355 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 13356 resource_cfg->flag1, 1); 13357 if (tgt_res_cfg->cce_disable) 13358 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 13359 13360 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 13361 } 13362 13363 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 13364 * @wmi_handle: pointer to wmi handle 13365 * @buf_ptr: pointer to current position in init command buffer 13366 * @len: pointer to length. This will be updated with current lenght of cmd 13367 * @param: point host parameters for init command 13368 * 13369 * Return: Updated pointer of buf_ptr. 13370 */ 13371 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 13372 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 13373 { 13374 uint16_t idx; 13375 13376 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 13377 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 13378 wmi_pdev_band_to_mac *band_to_mac; 13379 13380 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 13381 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 13382 sizeof(wmi_resource_config) + 13383 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 13384 sizeof(wlan_host_memory_chunk))); 13385 13386 WMITLV_SET_HDR(&hw_mode->tlv_header, 13387 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13388 (WMITLV_GET_STRUCT_TLVLEN 13389 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 13390 13391 hw_mode->hw_mode_index = param->hw_mode_id; 13392 hw_mode->num_band_to_mac = param->num_band_to_mac; 13393 13394 buf_ptr = (uint8_t *) (hw_mode + 1); 13395 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 13396 WMI_TLV_HDR_SIZE); 13397 for (idx = 0; idx < param->num_band_to_mac; idx++) { 13398 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 13399 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 13400 WMITLV_GET_STRUCT_TLVLEN 13401 (wmi_pdev_band_to_mac)); 13402 band_to_mac[idx].pdev_id = 13403 wmi_handle->ops->convert_pdev_id_host_to_target( 13404 param->band_to_mac[idx].pdev_id); 13405 band_to_mac[idx].start_freq = 13406 param->band_to_mac[idx].start_freq; 13407 band_to_mac[idx].end_freq = 13408 param->band_to_mac[idx].end_freq; 13409 } 13410 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 13411 (param->num_band_to_mac * 13412 sizeof(wmi_pdev_band_to_mac)) + 13413 WMI_TLV_HDR_SIZE; 13414 13415 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13416 (param->num_band_to_mac * 13417 sizeof(wmi_pdev_band_to_mac))); 13418 } 13419 13420 return buf_ptr; 13421 } 13422 13423 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 13424 wmi_init_cmd_fixed_param *cmd) 13425 { 13426 int num_whitelist; 13427 wmi_abi_version my_vers; 13428 13429 num_whitelist = sizeof(version_whitelist) / 13430 sizeof(wmi_whitelist_version_info); 13431 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 13432 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 13433 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 13434 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 13435 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 13436 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 13437 13438 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 13439 &my_vers, 13440 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 13441 &cmd->host_abi_vers); 13442 13443 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 13444 __func__, 13445 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 13446 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 13447 cmd->host_abi_vers.abi_version_ns_0, 13448 cmd->host_abi_vers.abi_version_ns_1, 13449 cmd->host_abi_vers.abi_version_ns_2, 13450 cmd->host_abi_vers.abi_version_ns_3); 13451 13452 /* Save version sent from host - 13453 * Will be used to check ready event 13454 */ 13455 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 13456 sizeof(wmi_abi_version)); 13457 } 13458 13459 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13460 { 13461 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13462 wmi_service_ready_event_fixed_param *ev; 13463 13464 13465 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13466 13467 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13468 if (!ev) 13469 return QDF_STATUS_E_FAILURE; 13470 13471 /*Save fw version from service ready message */ 13472 /*This will be used while sending INIT message */ 13473 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13474 sizeof(wmi_handle->fw_abi_version)); 13475 13476 return QDF_STATUS_SUCCESS; 13477 } 13478 13479 /** 13480 * wmi_unified_save_fw_version_cmd() - save fw version 13481 * @wmi_handle: pointer to wmi handle 13482 * @res_cfg: resource config 13483 * @num_mem_chunks: no of mem chunck 13484 * @mem_chunk: pointer to mem chunck structure 13485 * 13486 * This function sends IE information to firmware 13487 * 13488 * Return: QDF_STATUS_SUCCESS for success otherwise failure 13489 * 13490 */ 13491 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 13492 void *evt_buf) 13493 { 13494 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13495 wmi_ready_event_fixed_param *ev = NULL; 13496 13497 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13498 ev = param_buf->fixed_param; 13499 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 13500 &wmi_handle->final_abi_vers, 13501 &ev->fw_abi_vers)) { 13502 /* 13503 * Error: Our host version and the given firmware version 13504 * are incompatible. 13505 **/ 13506 WMI_LOGD("%s: Error: Incompatible WMI version." 13507 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 13508 __func__, 13509 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 13510 abi_version_0), 13511 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 13512 abi_version_0), 13513 wmi_handle->final_abi_vers.abi_version_ns_0, 13514 wmi_handle->final_abi_vers.abi_version_ns_1, 13515 wmi_handle->final_abi_vers.abi_version_ns_2, 13516 wmi_handle->final_abi_vers.abi_version_ns_3, 13517 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 13518 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 13519 ev->fw_abi_vers.abi_version_ns_0, 13520 ev->fw_abi_vers.abi_version_ns_1, 13521 ev->fw_abi_vers.abi_version_ns_2, 13522 ev->fw_abi_vers.abi_version_ns_3); 13523 13524 return QDF_STATUS_E_FAILURE; 13525 } 13526 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 13527 sizeof(wmi_abi_version)); 13528 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13529 sizeof(wmi_abi_version)); 13530 13531 return QDF_STATUS_SUCCESS; 13532 } 13533 13534 /** 13535 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 13536 * @wmi_handle: wmi handle 13537 * @custom_addr: base mac address 13538 * 13539 * Return: QDF_STATUS_SUCCESS for success or error code 13540 */ 13541 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 13542 uint8_t *custom_addr) 13543 { 13544 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 13545 wmi_buf_t buf; 13546 int err; 13547 13548 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13549 if (!buf) { 13550 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 13551 return QDF_STATUS_E_NOMEM; 13552 } 13553 13554 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 13555 qdf_mem_zero(cmd, sizeof(*cmd)); 13556 13557 WMITLV_SET_HDR(&cmd->tlv_header, 13558 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 13559 WMITLV_GET_STRUCT_TLVLEN 13560 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 13561 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 13562 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13563 WMI_HOST_PDEV_ID_SOC); 13564 err = wmi_unified_cmd_send(wmi_handle, buf, 13565 sizeof(*cmd), 13566 WMI_PDEV_SET_BASE_MACADDR_CMDID); 13567 if (err) { 13568 WMI_LOGE("Failed to send set_base_macaddr cmd"); 13569 wmi_buf_free(buf); 13570 return QDF_STATUS_E_FAILURE; 13571 } 13572 13573 return 0; 13574 } 13575 13576 /** 13577 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 13578 * @handle: wmi handle 13579 * @event: Event received from FW 13580 * @len: Length of the event 13581 * 13582 * Enables the low frequency events and disables the high frequency 13583 * events. Bit 17 indicates if the event if low/high frequency. 13584 * 1 - high frequency, 0 - low frequency 13585 * 13586 * Return: 0 on successfully enabling/disabling the events 13587 */ 13588 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 13589 uint8_t *event, 13590 uint32_t len) 13591 { 13592 uint32_t num_of_diag_events_logs; 13593 wmi_diag_event_log_config_fixed_param *cmd; 13594 wmi_buf_t buf; 13595 uint8_t *buf_ptr; 13596 uint32_t *cmd_args, *evt_args; 13597 uint32_t buf_len, i; 13598 13599 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 13600 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 13601 13602 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 13603 13604 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 13605 if (!param_buf) { 13606 WMI_LOGE("Invalid log supported event buffer"); 13607 return QDF_STATUS_E_INVAL; 13608 } 13609 wmi_event = param_buf->fixed_param; 13610 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 13611 13612 if (num_of_diag_events_logs > 13613 param_buf->num_diag_events_logs_list) { 13614 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 13615 num_of_diag_events_logs, 13616 param_buf->num_diag_events_logs_list); 13617 return QDF_STATUS_E_INVAL; 13618 } 13619 13620 evt_args = param_buf->diag_events_logs_list; 13621 if (!evt_args) { 13622 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 13623 __func__, num_of_diag_events_logs); 13624 return QDF_STATUS_E_INVAL; 13625 } 13626 13627 WMI_LOGD("%s: num_of_diag_events_logs=%d", 13628 __func__, num_of_diag_events_logs); 13629 13630 /* Free any previous allocation */ 13631 if (wmi_handle->events_logs_list) 13632 qdf_mem_free(wmi_handle->events_logs_list); 13633 13634 if (num_of_diag_events_logs > 13635 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 13636 WMI_LOGE("%s: excess num of logs:%d", __func__, 13637 num_of_diag_events_logs); 13638 QDF_ASSERT(0); 13639 return QDF_STATUS_E_INVAL; 13640 } 13641 /* Store the event list for run time enable/disable */ 13642 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 13643 sizeof(uint32_t)); 13644 if (!wmi_handle->events_logs_list) { 13645 WMI_LOGE("%s: event log list memory allocation failed", 13646 __func__); 13647 return QDF_STATUS_E_NOMEM; 13648 } 13649 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 13650 13651 /* Prepare the send buffer */ 13652 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13653 (num_of_diag_events_logs * sizeof(uint32_t)); 13654 13655 buf = wmi_buf_alloc(wmi_handle, buf_len); 13656 if (!buf) { 13657 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13658 qdf_mem_free(wmi_handle->events_logs_list); 13659 wmi_handle->events_logs_list = NULL; 13660 return QDF_STATUS_E_NOMEM; 13661 } 13662 13663 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13664 buf_ptr = (uint8_t *) cmd; 13665 13666 WMITLV_SET_HDR(&cmd->tlv_header, 13667 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13668 WMITLV_GET_STRUCT_TLVLEN( 13669 wmi_diag_event_log_config_fixed_param)); 13670 13671 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13672 13673 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13674 13675 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13676 (num_of_diag_events_logs * sizeof(uint32_t))); 13677 13678 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13679 13680 /* Populate the events */ 13681 for (i = 0; i < num_of_diag_events_logs; i++) { 13682 /* Low freq (0) - Enable (1) the event 13683 * High freq (1) - Disable (0) the event 13684 */ 13685 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13686 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13687 /* Set the event ID */ 13688 WMI_DIAG_ID_SET(cmd_args[i], 13689 WMI_DIAG_ID_GET(evt_args[i])); 13690 /* Set the type */ 13691 WMI_DIAG_TYPE_SET(cmd_args[i], 13692 WMI_DIAG_TYPE_GET(evt_args[i])); 13693 /* Storing the event/log list in WMI */ 13694 wmi_handle->events_logs_list[i] = evt_args[i]; 13695 } 13696 13697 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13698 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13699 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13700 __func__); 13701 wmi_buf_free(buf); 13702 /* Not clearing events_logs_list, though wmi cmd failed. 13703 * Host can still have this list 13704 */ 13705 return QDF_STATUS_E_INVAL; 13706 } 13707 13708 return 0; 13709 } 13710 13711 /** 13712 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13713 * @wmi_handle: wmi handle 13714 * @start_log: Start logging related parameters 13715 * 13716 * Send the command to the FW based on which specific logging of diag 13717 * event/log id can be started/stopped 13718 * 13719 * Return: None 13720 */ 13721 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13722 struct wmi_wifi_start_log *start_log) 13723 { 13724 wmi_diag_event_log_config_fixed_param *cmd; 13725 wmi_buf_t buf; 13726 uint8_t *buf_ptr; 13727 uint32_t len, count, log_level, i; 13728 uint32_t *cmd_args; 13729 uint32_t total_len; 13730 count = 0; 13731 13732 if (!wmi_handle->events_logs_list) { 13733 WMI_LOGE("%s: Not received event/log list from FW, yet", 13734 __func__); 13735 return QDF_STATUS_E_NOMEM; 13736 } 13737 /* total_len stores the number of events where BITS 17 and 18 are set. 13738 * i.e., events of high frequency (17) and for extended debugging (18) 13739 */ 13740 total_len = 0; 13741 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13742 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13743 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13744 total_len++; 13745 } 13746 13747 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13748 (total_len * sizeof(uint32_t)); 13749 13750 buf = wmi_buf_alloc(wmi_handle, len); 13751 if (!buf) { 13752 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13753 return QDF_STATUS_E_NOMEM; 13754 } 13755 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13756 buf_ptr = (uint8_t *) cmd; 13757 13758 WMITLV_SET_HDR(&cmd->tlv_header, 13759 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13760 WMITLV_GET_STRUCT_TLVLEN( 13761 wmi_diag_event_log_config_fixed_param)); 13762 13763 cmd->num_of_diag_events_logs = total_len; 13764 13765 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13766 13767 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13768 (total_len * sizeof(uint32_t))); 13769 13770 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13771 13772 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13773 log_level = 1; 13774 else 13775 log_level = 0; 13776 13777 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13778 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13779 uint32_t val = wmi_handle->events_logs_list[i]; 13780 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13781 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13782 13783 WMI_DIAG_ID_SET(cmd_args[count], 13784 WMI_DIAG_ID_GET(val)); 13785 WMI_DIAG_TYPE_SET(cmd_args[count], 13786 WMI_DIAG_TYPE_GET(val)); 13787 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13788 log_level); 13789 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13790 count++; 13791 } 13792 } 13793 13794 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13795 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13796 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13797 __func__); 13798 wmi_buf_free(buf); 13799 return QDF_STATUS_E_INVAL; 13800 } 13801 13802 return QDF_STATUS_SUCCESS; 13803 } 13804 13805 /** 13806 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13807 * @wmi_handle: WMI handle 13808 * 13809 * This function is used to send the flush command to the FW, 13810 * that will flush the fw logs that are residue in the FW 13811 * 13812 * Return: None 13813 */ 13814 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13815 { 13816 wmi_debug_mesg_flush_fixed_param *cmd; 13817 wmi_buf_t buf; 13818 int len = sizeof(*cmd); 13819 QDF_STATUS ret; 13820 13821 buf = wmi_buf_alloc(wmi_handle, len); 13822 if (!buf) { 13823 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13824 return QDF_STATUS_E_NOMEM; 13825 } 13826 13827 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13828 WMITLV_SET_HDR(&cmd->tlv_header, 13829 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13830 WMITLV_GET_STRUCT_TLVLEN( 13831 wmi_debug_mesg_flush_fixed_param)); 13832 cmd->reserved0 = 0; 13833 13834 ret = wmi_unified_cmd_send(wmi_handle, 13835 buf, 13836 len, 13837 WMI_DEBUG_MESG_FLUSH_CMDID); 13838 if (QDF_IS_STATUS_ERROR(ret)) { 13839 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13840 wmi_buf_free(buf); 13841 return QDF_STATUS_E_INVAL; 13842 } 13843 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13844 13845 return ret; 13846 } 13847 13848 /** 13849 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13850 * @wmi_handle: wmi handle 13851 * @msg: PCL structure containing the PCL and the number of channels 13852 * 13853 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13854 * firmware. The DBS Manager is the consumer of this information in the WLAN 13855 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13856 * to migrate to a new channel without host driver involvement. An example of 13857 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13858 * manage the channel selection without firmware involvement. 13859 * 13860 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13861 * channel list. The weights corresponds to the channels sent in 13862 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13863 * weightage compared to the non PCL channels. 13864 * 13865 * Return: Success if the cmd is sent successfully to the firmware 13866 */ 13867 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13868 struct wmi_pcl_chan_weights *msg) 13869 { 13870 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13871 wmi_buf_t buf; 13872 uint8_t *buf_ptr; 13873 uint32_t *cmd_args, i, len; 13874 uint32_t chan_len; 13875 13876 chan_len = msg->saved_num_chan; 13877 13878 len = sizeof(*cmd) + 13879 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13880 13881 buf = wmi_buf_alloc(wmi_handle, len); 13882 if (!buf) { 13883 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13884 return QDF_STATUS_E_NOMEM; 13885 } 13886 13887 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13888 buf_ptr = (uint8_t *) cmd; 13889 WMITLV_SET_HDR(&cmd->tlv_header, 13890 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13891 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13892 13893 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13894 WMI_HOST_PDEV_ID_SOC); 13895 cmd->num_chan = chan_len; 13896 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13897 13898 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13899 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13900 (chan_len * sizeof(uint32_t))); 13901 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13902 for (i = 0; i < chan_len ; i++) { 13903 cmd_args[i] = msg->weighed_valid_list[i]; 13904 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13905 msg->saved_chan_list[i], cmd_args[i]); 13906 } 13907 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13908 WMI_PDEV_SET_PCL_CMDID)) { 13909 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13910 wmi_buf_free(buf); 13911 return QDF_STATUS_E_FAILURE; 13912 } 13913 return QDF_STATUS_SUCCESS; 13914 } 13915 13916 /** 13917 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13918 * @wmi_handle: wmi handle 13919 * @msg: Structure containing the following parameters 13920 * 13921 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13922 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13923 * 13924 * Provides notification to the WLAN firmware that host driver is requesting a 13925 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13926 * configurations that include the Dual Band Simultaneous (DBS) feature. 13927 * 13928 * Return: Success if the cmd is sent successfully to the firmware 13929 */ 13930 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13931 uint32_t hw_mode_index) 13932 { 13933 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13934 wmi_buf_t buf; 13935 uint32_t len; 13936 13937 len = sizeof(*cmd); 13938 13939 buf = wmi_buf_alloc(wmi_handle, len); 13940 if (!buf) { 13941 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13942 return QDF_STATUS_E_NOMEM; 13943 } 13944 13945 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13946 WMITLV_SET_HDR(&cmd->tlv_header, 13947 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13948 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13949 13950 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13951 WMI_HOST_PDEV_ID_SOC); 13952 cmd->hw_mode_index = hw_mode_index; 13953 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13954 13955 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13956 WMI_PDEV_SET_HW_MODE_CMDID)) { 13957 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13958 __func__); 13959 wmi_buf_free(buf); 13960 return QDF_STATUS_E_FAILURE; 13961 } 13962 13963 return QDF_STATUS_SUCCESS; 13964 } 13965 13966 #ifdef WLAN_POLICY_MGR_ENABLE 13967 /** 13968 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13969 * @wmi_handle: wmi handle 13970 * @msg: Dual MAC config parameters 13971 * 13972 * Configures WLAN firmware with the dual MAC features 13973 * 13974 * Return: QDF_STATUS. 0 on success. 13975 */ 13976 static 13977 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13978 struct policy_mgr_dual_mac_config *msg) 13979 { 13980 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13981 wmi_buf_t buf; 13982 uint32_t len; 13983 13984 len = sizeof(*cmd); 13985 13986 buf = wmi_buf_alloc(wmi_handle, len); 13987 if (!buf) { 13988 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13989 return QDF_STATUS_E_FAILURE; 13990 } 13991 13992 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13993 WMITLV_SET_HDR(&cmd->tlv_header, 13994 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13995 WMITLV_GET_STRUCT_TLVLEN( 13996 wmi_pdev_set_mac_config_cmd_fixed_param)); 13997 13998 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13999 WMI_HOST_PDEV_ID_SOC); 14000 cmd->concurrent_scan_config_bits = msg->scan_config; 14001 cmd->fw_mode_config_bits = msg->fw_mode_config; 14002 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 14003 __func__, msg->scan_config, msg->fw_mode_config); 14004 14005 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14006 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 14007 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 14008 __func__); 14009 wmi_buf_free(buf); 14010 } 14011 return QDF_STATUS_SUCCESS; 14012 } 14013 #endif 14014 14015 #ifdef BIG_ENDIAN_HOST 14016 /** 14017 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14018 * @param data_len - data length 14019 * @param data - pointer to data 14020 * 14021 * Return: QDF_STATUS - success or error status 14022 */ 14023 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14024 struct fips_params *param) 14025 { 14026 unsigned char *key_unaligned, *data_unaligned; 14027 int c; 14028 u_int8_t *key_aligned = NULL; 14029 u_int8_t *data_aligned = NULL; 14030 14031 /* Assigning unaligned space to copy the key */ 14032 key_unaligned = qdf_mem_malloc( 14033 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 14034 data_unaligned = qdf_mem_malloc( 14035 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 14036 14037 /* Checking if kmalloc is succesful to allocate space */ 14038 if (key_unaligned == NULL) 14039 return QDF_STATUS_SUCCESS; 14040 /* Checking if space is aligned */ 14041 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 14042 /* align to 4 */ 14043 key_aligned = 14044 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 14045 FIPS_ALIGN); 14046 } else { 14047 key_aligned = (u_int8_t *)key_unaligned; 14048 } 14049 14050 /* memset and copy content from key to key aligned */ 14051 OS_MEMSET(key_aligned, 0, param->key_len); 14052 OS_MEMCPY(key_aligned, param->key, param->key_len); 14053 14054 /* print a hexdump for host debug */ 14055 print_hex_dump(KERN_DEBUG, 14056 "\t Aligned and Copied Key:@@@@ ", 14057 DUMP_PREFIX_NONE, 14058 16, 1, key_aligned, param->key_len, true); 14059 14060 /* Checking if kmalloc is succesful to allocate space */ 14061 if (data_unaligned == NULL) 14062 return QDF_STATUS_SUCCESS; 14063 /* Checking of space is aligned */ 14064 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14065 /* align to 4 */ 14066 data_aligned = 14067 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 14068 FIPS_ALIGN); 14069 } else { 14070 data_aligned = (u_int8_t *)data_unaligned; 14071 } 14072 14073 /* memset and copy content from data to data aligned */ 14074 OS_MEMSET(data_aligned, 0, param->data_len); 14075 OS_MEMCPY(data_aligned, param->data, param->data_len); 14076 14077 /* print a hexdump for host debug */ 14078 print_hex_dump(KERN_DEBUG, 14079 "\t Properly Aligned and Copied Data:@@@@ ", 14080 DUMP_PREFIX_NONE, 14081 16, 1, data_aligned, param->data_len, true); 14082 14083 /* converting to little Endian both key_aligned and 14084 * data_aligned*/ 14085 for (c = 0; c < param->key_len/4; c++) { 14086 *((u_int32_t *)key_aligned+c) = 14087 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 14088 } 14089 for (c = 0; c < param->data_len/4; c++) { 14090 *((u_int32_t *)data_aligned+c) = 14091 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 14092 } 14093 14094 /* update endian data to key and data vectors */ 14095 OS_MEMCPY(param->key, key_aligned, param->key_len); 14096 OS_MEMCPY(param->data, data_aligned, param->data_len); 14097 14098 /* clean up allocated spaces */ 14099 qdf_mem_free(key_unaligned); 14100 key_unaligned = NULL; 14101 key_aligned = NULL; 14102 14103 qdf_mem_free(data_unaligned); 14104 data_unaligned = NULL; 14105 data_aligned = NULL; 14106 14107 return QDF_STATUS_SUCCESS; 14108 } 14109 #else 14110 /** 14111 * fips_align_data_be() - DUMMY for LE platform 14112 * 14113 * Return: QDF_STATUS - success 14114 */ 14115 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14116 struct fips_params *param) 14117 { 14118 return QDF_STATUS_SUCCESS; 14119 } 14120 #endif 14121 14122 14123 /** 14124 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 14125 * @wmi_handle: wmi handle 14126 * @param: pointer to hold pdev fips param 14127 * 14128 * Return: 0 for success or error code 14129 */ 14130 static QDF_STATUS 14131 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 14132 struct fips_params *param) 14133 { 14134 wmi_pdev_fips_cmd_fixed_param *cmd; 14135 wmi_buf_t buf; 14136 uint8_t *buf_ptr; 14137 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 14138 QDF_STATUS retval = QDF_STATUS_SUCCESS; 14139 14140 /* Length TLV placeholder for array of bytes */ 14141 len += WMI_TLV_HDR_SIZE; 14142 if (param->data_len) 14143 len += (param->data_len*sizeof(uint8_t)); 14144 14145 /* 14146 * Data length must be multiples of 16 bytes - checked against 0xF - 14147 * and must be less than WMI_SVC_MSG_SIZE - static size of 14148 * wmi_pdev_fips_cmd structure 14149 */ 14150 14151 /* do sanity on the input */ 14152 if (!(((param->data_len & 0xF) == 0) && 14153 ((param->data_len > 0) && 14154 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 14155 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 14156 return QDF_STATUS_E_INVAL; 14157 } 14158 14159 buf = wmi_buf_alloc(wmi_handle, len); 14160 if (!buf) { 14161 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 14162 return QDF_STATUS_E_FAILURE; 14163 } 14164 14165 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14166 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 14167 WMITLV_SET_HDR(&cmd->tlv_header, 14168 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 14169 WMITLV_GET_STRUCT_TLVLEN 14170 (wmi_pdev_fips_cmd_fixed_param)); 14171 14172 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 14173 param->pdev_id); 14174 if (param->key != NULL && param->data != NULL) { 14175 cmd->key_len = param->key_len; 14176 cmd->data_len = param->data_len; 14177 cmd->fips_cmd = !!(param->op); 14178 14179 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 14180 return QDF_STATUS_E_FAILURE; 14181 14182 qdf_mem_copy(cmd->key, param->key, param->key_len); 14183 14184 if (param->mode == FIPS_ENGINE_AES_CTR || 14185 param->mode == FIPS_ENGINE_AES_MIC) { 14186 cmd->mode = param->mode; 14187 } else { 14188 cmd->mode = FIPS_ENGINE_AES_CTR; 14189 } 14190 qdf_print(KERN_ERR "Key len = %d, Data len = %d\n", 14191 cmd->key_len, cmd->data_len); 14192 14193 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 14194 cmd->key, cmd->key_len, true); 14195 buf_ptr += sizeof(*cmd); 14196 14197 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 14198 14199 buf_ptr += WMI_TLV_HDR_SIZE; 14200 if (param->data_len) 14201 qdf_mem_copy(buf_ptr, 14202 (uint8_t *) param->data, param->data_len); 14203 14204 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 14205 16, 1, buf_ptr, cmd->data_len, true); 14206 14207 buf_ptr += param->data_len; 14208 14209 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 14210 WMI_PDEV_FIPS_CMDID); 14211 qdf_print("%s return value %d\n", __func__, retval); 14212 } else { 14213 qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__); 14214 wmi_buf_free(buf); 14215 retval = -QDF_STATUS_E_BADMSG; 14216 } 14217 14218 return retval; 14219 } 14220 14221 #ifdef WLAN_PMO_ENABLE 14222 /** 14223 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 14224 * @wmi_handle: wmi handle 14225 * @vdev_id: vdev id 14226 * @bitmap: Event bitmap 14227 * @enable: enable/disable 14228 * 14229 * Return: CDF status 14230 */ 14231 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 14232 uint32_t vdev_id, 14233 uint32_t *bitmap, 14234 bool enable) 14235 { 14236 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 14237 uint16_t len; 14238 wmi_buf_t buf; 14239 int ret; 14240 14241 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 14242 buf = wmi_buf_alloc(wmi_handle, len); 14243 if (!buf) { 14244 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14245 return QDF_STATUS_E_NOMEM; 14246 } 14247 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 14248 WMITLV_SET_HDR(&cmd->tlv_header, 14249 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 14250 WMITLV_GET_STRUCT_TLVLEN 14251 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 14252 cmd->vdev_id = vdev_id; 14253 cmd->is_add = enable; 14254 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 14255 WMI_WOW_MAX_EVENT_BM_LEN); 14256 14257 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 14258 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 14259 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 14260 14261 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14262 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 14263 if (ret) { 14264 WMI_LOGE("Failed to config wow wakeup event"); 14265 wmi_buf_free(buf); 14266 return QDF_STATUS_E_FAILURE; 14267 } 14268 14269 return QDF_STATUS_SUCCESS; 14270 } 14271 14272 /** 14273 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 14274 * @wmi_handle: wmi handle 14275 * @vdev_id: vdev id 14276 * @ptrn_id: pattern id 14277 * @ptrn: pattern 14278 * @ptrn_len: pattern length 14279 * @ptrn_offset: pattern offset 14280 * @mask: mask 14281 * @mask_len: mask length 14282 * @user: true for user configured pattern and false for default pattern 14283 * @default_patterns: default patterns 14284 * 14285 * Return: CDF status 14286 */ 14287 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 14288 uint8_t vdev_id, uint8_t ptrn_id, 14289 const uint8_t *ptrn, uint8_t ptrn_len, 14290 uint8_t ptrn_offset, const uint8_t *mask, 14291 uint8_t mask_len, bool user, 14292 uint8_t default_patterns) 14293 { 14294 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14295 WOW_BITMAP_PATTERN_T *bitmap_pattern; 14296 wmi_buf_t buf; 14297 uint8_t *buf_ptr; 14298 int32_t len; 14299 int ret; 14300 14301 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14302 WMI_TLV_HDR_SIZE + 14303 1 * sizeof(WOW_BITMAP_PATTERN_T) + 14304 WMI_TLV_HDR_SIZE + 14305 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14306 WMI_TLV_HDR_SIZE + 14307 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14308 WMI_TLV_HDR_SIZE + 14309 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14310 WMI_TLV_HDR_SIZE + 14311 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14312 14313 buf = wmi_buf_alloc(wmi_handle, len); 14314 if (!buf) { 14315 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14316 return QDF_STATUS_E_NOMEM; 14317 } 14318 14319 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14320 buf_ptr = (uint8_t *) cmd; 14321 14322 WMITLV_SET_HDR(&cmd->tlv_header, 14323 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14324 WMITLV_GET_STRUCT_TLVLEN 14325 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14326 cmd->vdev_id = vdev_id; 14327 cmd->pattern_id = ptrn_id; 14328 14329 cmd->pattern_type = WOW_BITMAP_PATTERN; 14330 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14331 14332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14333 sizeof(WOW_BITMAP_PATTERN_T)); 14334 buf_ptr += WMI_TLV_HDR_SIZE; 14335 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 14336 14337 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 14338 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 14339 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 14340 14341 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 14342 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 14343 14344 bitmap_pattern->pattern_offset = ptrn_offset; 14345 bitmap_pattern->pattern_len = ptrn_len; 14346 14347 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 14348 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 14349 14350 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 14351 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 14352 14353 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 14354 bitmap_pattern->pattern_id = ptrn_id; 14355 14356 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 14357 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 14358 bitmap_pattern->pattern_offset, user); 14359 WMI_LOGI("Pattern : "); 14360 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14361 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 14362 14363 WMI_LOGI("Mask : "); 14364 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14365 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 14366 14367 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 14368 14369 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14371 buf_ptr += WMI_TLV_HDR_SIZE; 14372 14373 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14374 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14375 buf_ptr += WMI_TLV_HDR_SIZE; 14376 14377 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14378 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14379 buf_ptr += WMI_TLV_HDR_SIZE; 14380 14381 /* Fill TLV for pattern_info_timeout but no data. */ 14382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14383 buf_ptr += WMI_TLV_HDR_SIZE; 14384 14385 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 14386 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 14387 buf_ptr += WMI_TLV_HDR_SIZE; 14388 *(uint32_t *) buf_ptr = 0; 14389 14390 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14391 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14392 if (ret) { 14393 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 14394 wmi_buf_free(buf); 14395 return QDF_STATUS_E_FAILURE; 14396 } 14397 14398 return QDF_STATUS_SUCCESS; 14399 } 14400 14401 /** 14402 * fill_arp_offload_params_tlv() - Fill ARP offload data 14403 * @wmi_handle: wmi handle 14404 * @offload_req: offload request 14405 * @buf_ptr: buffer pointer 14406 * 14407 * To fill ARP offload data to firmware 14408 * when target goes to wow mode. 14409 * 14410 * Return: None 14411 */ 14412 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 14413 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 14414 { 14415 14416 int i; 14417 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 14418 bool enable_or_disable = offload_req->enable; 14419 14420 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14421 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 14422 *buf_ptr += WMI_TLV_HDR_SIZE; 14423 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 14424 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 14425 WMITLV_SET_HDR(&arp_tuple->tlv_header, 14426 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 14427 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 14428 14429 /* Fill data for ARP and NS in the first tupple for LA */ 14430 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 14431 /* Copy the target ip addr and flags */ 14432 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 14433 qdf_mem_copy(&arp_tuple->target_ipaddr, 14434 offload_req->host_ipv4_addr, 14435 WMI_IPV4_ADDR_LEN); 14436 WMI_LOGD("ARPOffload IP4 address: %pI4", 14437 offload_req->host_ipv4_addr); 14438 } 14439 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 14440 } 14441 } 14442 14443 #ifdef WLAN_NS_OFFLOAD 14444 /** 14445 * fill_ns_offload_params_tlv() - Fill NS offload data 14446 * @wmi|_handle: wmi handle 14447 * @offload_req: offload request 14448 * @buf_ptr: buffer pointer 14449 * 14450 * To fill NS offload data to firmware 14451 * when target goes to wow mode. 14452 * 14453 * Return: None 14454 */ 14455 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14456 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14457 { 14458 14459 int i; 14460 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14461 14462 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14463 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14464 *buf_ptr += WMI_TLV_HDR_SIZE; 14465 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 14466 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14467 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14468 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14469 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 14470 14471 /* 14472 * Fill data only for NS offload in the first ARP tuple for LA 14473 */ 14474 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14475 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14476 /* Copy the target/solicitation/remote ip addr */ 14477 if (ns_req->target_ipv6_addr_valid[i]) 14478 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14479 &ns_req->target_ipv6_addr[i], 14480 sizeof(WMI_IPV6_ADDR)); 14481 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14482 &ns_req->self_ipv6_addr[i], 14483 sizeof(WMI_IPV6_ADDR)); 14484 if (ns_req->target_ipv6_addr_ac_type[i]) { 14485 ns_tuple->flags |= 14486 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14487 } 14488 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14489 i, &ns_req->self_ipv6_addr[i], 14490 &ns_req->target_ipv6_addr[i]); 14491 14492 /* target MAC is optional, check if it is valid, 14493 * if this is not valid, the target will use the known 14494 * local MAC address rather than the tuple 14495 */ 14496 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14497 ns_req->self_macaddr.bytes, 14498 &ns_tuple->target_mac); 14499 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14500 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14501 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14502 } 14503 } 14504 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14505 } 14506 } 14507 14508 14509 /** 14510 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 14511 * @wmi: wmi handle 14512 * @offload_req: offload request 14513 * @buf_ptr: buffer pointer 14514 * 14515 * To fill extended NS offload extended data to firmware 14516 * when target goes to wow mode. 14517 * 14518 * Return: None 14519 */ 14520 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14521 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14522 { 14523 int i; 14524 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14525 uint32_t count, num_ns_ext_tuples; 14526 14527 count = ns_req->num_ns_offload_count; 14528 num_ns_ext_tuples = ns_req->num_ns_offload_count - 14529 WMI_MAX_NS_OFFLOADS; 14530 14531 /* Populate extended NS offload tuples */ 14532 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14533 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14534 *buf_ptr += WMI_TLV_HDR_SIZE; 14535 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 14536 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14537 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14538 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14539 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 14540 14541 /* 14542 * Fill data only for NS offload in the first ARP tuple for LA 14543 */ 14544 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14545 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14546 /* Copy the target/solicitation/remote ip addr */ 14547 if (ns_req->target_ipv6_addr_valid[i]) 14548 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14549 &ns_req->target_ipv6_addr[i], 14550 sizeof(WMI_IPV6_ADDR)); 14551 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14552 &ns_req->self_ipv6_addr[i], 14553 sizeof(WMI_IPV6_ADDR)); 14554 if (ns_req->target_ipv6_addr_ac_type[i]) { 14555 ns_tuple->flags |= 14556 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14557 } 14558 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14559 i, &ns_req->self_ipv6_addr[i], 14560 &ns_req->target_ipv6_addr[i]); 14561 14562 /* target MAC is optional, check if it is valid, 14563 * if this is not valid, the target will use the 14564 * known local MAC address rather than the tuple 14565 */ 14566 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14567 ns_req->self_macaddr.bytes, 14568 &ns_tuple->target_mac); 14569 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14570 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14571 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14572 } 14573 } 14574 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14575 } 14576 } 14577 #else 14578 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14579 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14580 { 14581 } 14582 14583 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14584 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14585 { 14586 } 14587 #endif 14588 14589 /** 14590 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 14591 * @wma: wmi handle 14592 * @arp_offload_req: arp offload request 14593 * @ns_offload_req: ns offload request 14594 * @arp_only: flag 14595 * 14596 * To configure ARP NS off load data to firmware 14597 * when target goes to wow mode. 14598 * 14599 * Return: QDF Status 14600 */ 14601 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 14602 struct pmo_arp_offload_params *arp_offload_req, 14603 struct pmo_ns_offload_params *ns_offload_req, 14604 uint8_t vdev_id) 14605 { 14606 int32_t res; 14607 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 14608 uint8_t *buf_ptr; 14609 wmi_buf_t buf; 14610 int32_t len; 14611 uint32_t count = 0, num_ns_ext_tuples = 0; 14612 14613 count = ns_offload_req->num_ns_offload_count; 14614 14615 /* 14616 * TLV place holder size for array of NS tuples 14617 * TLV place holder size for array of ARP tuples 14618 */ 14619 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 14620 WMI_TLV_HDR_SIZE + 14621 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 14622 WMI_TLV_HDR_SIZE + 14623 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 14624 14625 /* 14626 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 14627 * extra length for extended NS offload tuples which follows ARP offload 14628 * tuples. Host needs to fill this structure in following format: 14629 * 2 NS ofload tuples 14630 * 2 ARP offload tuples 14631 * N numbers of extended NS offload tuples if HDD has given more than 14632 * 2 NS offload addresses 14633 */ 14634 if (count > WMI_MAX_NS_OFFLOADS) { 14635 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 14636 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 14637 * sizeof(WMI_NS_OFFLOAD_TUPLE); 14638 } 14639 14640 buf = wmi_buf_alloc(wmi_handle, len); 14641 if (!buf) { 14642 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14643 return QDF_STATUS_E_NOMEM; 14644 } 14645 14646 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14647 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 14648 WMITLV_SET_HDR(&cmd->tlv_header, 14649 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 14650 WMITLV_GET_STRUCT_TLVLEN 14651 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 14652 cmd->flags = 0; 14653 cmd->vdev_id = vdev_id; 14654 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 14655 14656 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 14657 14658 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 14659 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14660 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 14661 if (num_ns_ext_tuples) 14662 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14663 14664 res = wmi_unified_cmd_send(wmi_handle, buf, len, 14665 WMI_SET_ARP_NS_OFFLOAD_CMDID); 14666 if (res) { 14667 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 14668 wmi_buf_free(buf); 14669 return QDF_STATUS_E_FAILURE; 14670 } 14671 14672 return QDF_STATUS_SUCCESS; 14673 } 14674 14675 /** 14676 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14677 * @wmi_handle: wmi handle 14678 * @vdev_id: vdev id 14679 * @action: true for enable else false 14680 * 14681 * To enable enhance multicast offload to firmware 14682 * when target goes to wow mode. 14683 * 14684 * Return: QDF Status 14685 */ 14686 14687 static 14688 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14689 wmi_unified_t wmi_handle, 14690 uint8_t vdev_id, bool action) 14691 { 14692 QDF_STATUS status; 14693 wmi_buf_t buf; 14694 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14695 14696 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14697 if (!buf) { 14698 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14699 return QDF_STATUS_E_NOMEM; 14700 } 14701 14702 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14703 wmi_buf_data(buf); 14704 14705 WMITLV_SET_HDR(&cmd->tlv_header, 14706 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14707 WMITLV_GET_STRUCT_TLVLEN( 14708 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14709 14710 cmd->vdev_id = vdev_id; 14711 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14712 ENHANCED_MCAST_FILTER_ENABLED); 14713 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14714 __func__, action, vdev_id); 14715 status = wmi_unified_cmd_send(wmi_handle, buf, 14716 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14717 if (status != QDF_STATUS_SUCCESS) { 14718 qdf_nbuf_free(buf); 14719 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14720 __func__); 14721 } 14722 14723 return status; 14724 } 14725 14726 /** 14727 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14728 * @wmi_handle: wmi handle 14729 * @param evt_buf: pointer to event buffer 14730 * @param hdr: Pointer to hold header 14731 * @param bufp: Pointer to hold pointer to rx param buffer 14732 * 14733 * Return: QDF_STATUS_SUCCESS for success or error code 14734 */ 14735 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14736 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14737 { 14738 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14739 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14740 14741 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14742 if (!param_buf) { 14743 WMI_LOGE("gtk param_buf is NULL"); 14744 return QDF_STATUS_E_INVAL; 14745 } 14746 14747 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14748 WMI_LOGE("Invalid length for GTK status"); 14749 return QDF_STATUS_E_INVAL; 14750 } 14751 14752 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14753 param_buf->fixed_param; 14754 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14755 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14756 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14757 qdf_mem_copy(>k_rsp_param->replay_counter, 14758 &fixed_param->replay_counter, 14759 GTK_REPLAY_COUNTER_BYTES); 14760 14761 return QDF_STATUS_SUCCESS; 14762 14763 } 14764 14765 #ifdef FEATURE_WLAN_RA_FILTERING 14766 /** 14767 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14768 * @wmi_handle: wmi handle 14769 * @vdev_id: vdev id 14770 * 14771 * Return: CDF status 14772 */ 14773 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14774 uint8_t vdev_id, uint8_t default_pattern, 14775 uint16_t rate_limit_interval) 14776 { 14777 14778 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14779 wmi_buf_t buf; 14780 uint8_t *buf_ptr; 14781 int32_t len; 14782 int ret; 14783 14784 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14785 WMI_TLV_HDR_SIZE + 14786 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14787 WMI_TLV_HDR_SIZE + 14788 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14789 WMI_TLV_HDR_SIZE + 14790 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14791 WMI_TLV_HDR_SIZE + 14792 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14793 WMI_TLV_HDR_SIZE + 14794 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14795 14796 buf = wmi_buf_alloc(wmi_handle, len); 14797 if (!buf) { 14798 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14799 return QDF_STATUS_E_NOMEM; 14800 } 14801 14802 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14803 buf_ptr = (uint8_t *) cmd; 14804 14805 WMITLV_SET_HDR(&cmd->tlv_header, 14806 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14807 WMITLV_GET_STRUCT_TLVLEN 14808 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14809 cmd->vdev_id = vdev_id; 14810 cmd->pattern_id = default_pattern, 14811 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14812 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14813 14814 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14815 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14816 buf_ptr += WMI_TLV_HDR_SIZE; 14817 14818 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14819 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14820 buf_ptr += WMI_TLV_HDR_SIZE; 14821 14822 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14823 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14824 buf_ptr += WMI_TLV_HDR_SIZE; 14825 14826 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14827 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14828 buf_ptr += WMI_TLV_HDR_SIZE; 14829 14830 /* Fill TLV for pattern_info_timeout but no data. */ 14831 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14832 buf_ptr += WMI_TLV_HDR_SIZE; 14833 14834 /* Fill TLV for ra_ratelimit_interval. */ 14835 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14836 buf_ptr += WMI_TLV_HDR_SIZE; 14837 14838 *((uint32_t *) buf_ptr) = rate_limit_interval; 14839 14840 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14841 rate_limit_interval, vdev_id); 14842 14843 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14844 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14845 if (ret) { 14846 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14847 wmi_buf_free(buf); 14848 return QDF_STATUS_E_FAILURE; 14849 } 14850 14851 return QDF_STATUS_SUCCESS; 14852 14853 } 14854 #endif /* FEATURE_WLAN_RA_FILTERING */ 14855 14856 /** 14857 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14858 * @wmi_handle: wmi handle 14859 * @vdev_id: vdev id 14860 * @multicastAddr: mcast address 14861 * @clearList: clear list flag 14862 * 14863 * Return: QDF_STATUS_SUCCESS for success or error code 14864 */ 14865 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14866 uint8_t vdev_id, 14867 struct qdf_mac_addr multicast_addr, 14868 bool clearList) 14869 { 14870 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14871 wmi_buf_t buf; 14872 int err; 14873 14874 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14875 if (!buf) { 14876 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14877 return QDF_STATUS_E_NOMEM; 14878 } 14879 14880 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14881 qdf_mem_zero(cmd, sizeof(*cmd)); 14882 14883 WMITLV_SET_HDR(&cmd->tlv_header, 14884 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14885 WMITLV_GET_STRUCT_TLVLEN 14886 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14887 cmd->action = 14888 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14889 cmd->vdev_id = vdev_id; 14890 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14891 14892 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14893 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14894 14895 err = wmi_unified_cmd_send(wmi_handle, buf, 14896 sizeof(*cmd), 14897 WMI_SET_MCASTBCAST_FILTER_CMDID); 14898 if (err) { 14899 WMI_LOGE("Failed to send set_param cmd"); 14900 wmi_buf_free(buf); 14901 return QDF_STATUS_E_FAILURE; 14902 } 14903 14904 return QDF_STATUS_SUCCESS; 14905 } 14906 14907 /** 14908 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14909 * command to fw 14910 * @wmi_handle: wmi handle 14911 * @vdev_id: vdev id 14912 * @mcast_filter_params: mcast filter params 14913 * 14914 * Return: QDF_STATUS_SUCCESS for success or error code 14915 */ 14916 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14917 wmi_unified_t wmi_handle, 14918 uint8_t vdev_id, 14919 struct pmo_mcast_filter_params *filter_param) 14920 14921 { 14922 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14923 uint8_t *buf_ptr; 14924 wmi_buf_t buf; 14925 int err; 14926 int i; 14927 uint8_t *mac_addr_src_ptr = NULL; 14928 wmi_mac_addr *mac_addr_dst_ptr; 14929 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14930 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14931 14932 buf = wmi_buf_alloc(wmi_handle, len); 14933 if (!buf) { 14934 WMI_LOGE("Failed to allocate memory"); 14935 return QDF_STATUS_E_NOMEM; 14936 } 14937 14938 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14939 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14940 wmi_buf_data(buf); 14941 qdf_mem_zero(cmd, sizeof(*cmd)); 14942 14943 WMITLV_SET_HDR(&cmd->tlv_header, 14944 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14945 WMITLV_GET_STRUCT_TLVLEN 14946 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14947 cmd->operation = 14948 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14949 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14950 cmd->vdev_id = vdev_id; 14951 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14952 14953 buf_ptr += sizeof(*cmd); 14954 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14955 sizeof(wmi_mac_addr) * 14956 filter_param->multicast_addr_cnt); 14957 14958 if (filter_param->multicast_addr_cnt == 0) 14959 goto send_cmd; 14960 14961 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14962 mac_addr_dst_ptr = (wmi_mac_addr *) 14963 (buf_ptr + WMI_TLV_HDR_SIZE); 14964 14965 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14966 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14967 mac_addr_src_ptr += ATH_MAC_LEN; 14968 mac_addr_dst_ptr++; 14969 } 14970 14971 send_cmd: 14972 err = wmi_unified_cmd_send(wmi_handle, buf, 14973 len, 14974 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14975 if (err) { 14976 WMI_LOGE("Failed to send set_param cmd"); 14977 wmi_buf_free(buf); 14978 return QDF_STATUS_E_FAILURE; 14979 } 14980 14981 return QDF_STATUS_SUCCESS; 14982 } 14983 14984 14985 /** 14986 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14987 * @wmi_handle: wmi handle 14988 * @vdev_id: vdev id 14989 * @params: GTK offload parameters 14990 * 14991 * Return: CDF status 14992 */ 14993 static 14994 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14995 struct pmo_gtk_req *params, 14996 bool enable_offload, 14997 uint32_t gtk_offload_opcode) 14998 { 14999 int len; 15000 wmi_buf_t buf; 15001 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 15002 wmi_gtk_offload_fils_tlv_param *ext_param; 15003 QDF_STATUS status = QDF_STATUS_SUCCESS; 15004 uint8_t *buf_ptr; 15005 15006 WMI_LOGD("%s Enter", __func__); 15007 15008 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param); 15009 15010 /* alloc wmi buffer */ 15011 buf = wmi_buf_alloc(wmi_handle, len); 15012 if (!buf) { 15013 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15014 status = QDF_STATUS_E_NOMEM; 15015 goto out; 15016 } 15017 15018 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15019 buf_ptr = (uint8_t *)cmd; 15020 WMITLV_SET_HDR(&cmd->tlv_header, 15021 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15022 WMITLV_GET_STRUCT_TLVLEN 15023 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15024 15025 cmd->vdev_id = vdev_id; 15026 15027 /* Request target to enable GTK offload */ 15028 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 15029 cmd->flags = gtk_offload_opcode; 15030 15031 /* Copy the keys and replay counter */ 15032 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 15033 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 15034 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 15035 GTK_REPLAY_COUNTER_BYTES); 15036 } else { 15037 cmd->flags = gtk_offload_opcode; 15038 } 15039 15040 buf_ptr += sizeof(*cmd); 15041 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param)); 15042 buf_ptr += WMI_TLV_HDR_SIZE; 15043 15044 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 15045 WMITLV_SET_HDR(&ext_param->tlv_header, 15046 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 15047 WMITLV_GET_STRUCT_TLVLEN( 15048 wmi_gtk_offload_fils_tlv_param)); 15049 ext_param->vdev_id = vdev_id; 15050 ext_param->flags = cmd->flags; 15051 ext_param->kek_len = params->kek_len; 15052 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 15053 qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES); 15054 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 15055 GTK_REPLAY_COUNTER_BYTES); 15056 15057 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 15058 /* send the wmi command */ 15059 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15060 WMI_GTK_OFFLOAD_CMDID)) { 15061 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 15062 wmi_buf_free(buf); 15063 status = QDF_STATUS_E_FAILURE; 15064 } 15065 15066 out: 15067 WMI_LOGD("%s Exit", __func__); 15068 return status; 15069 } 15070 15071 /** 15072 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 15073 * @wmi_handle: wmi handle 15074 * @params: GTK offload params 15075 * 15076 * Return: CDF status 15077 */ 15078 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 15079 wmi_unified_t wmi_handle, 15080 uint8_t vdev_id, 15081 uint64_t offload_req_opcode) 15082 { 15083 int len; 15084 wmi_buf_t buf; 15085 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 15086 QDF_STATUS status = QDF_STATUS_SUCCESS; 15087 15088 len = sizeof(*cmd); 15089 15090 /* alloc wmi buffer */ 15091 buf = wmi_buf_alloc(wmi_handle, len); 15092 if (!buf) { 15093 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15094 status = QDF_STATUS_E_NOMEM; 15095 goto out; 15096 } 15097 15098 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15099 WMITLV_SET_HDR(&cmd->tlv_header, 15100 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15101 WMITLV_GET_STRUCT_TLVLEN 15102 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15103 15104 /* Request for GTK offload status */ 15105 cmd->flags = offload_req_opcode; 15106 cmd->vdev_id = vdev_id; 15107 15108 /* send the wmi command */ 15109 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15110 WMI_GTK_OFFLOAD_CMDID)) { 15111 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 15112 wmi_buf_free(buf); 15113 status = QDF_STATUS_E_FAILURE; 15114 } 15115 15116 out: 15117 return status; 15118 } 15119 15120 /** 15121 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 15122 * @wmi_handle: wmi handler 15123 * @action_params: pointer to action_params 15124 * 15125 * Return: 0 for success, otherwise appropriate error code 15126 */ 15127 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 15128 struct pmo_action_wakeup_set_params *action_params) 15129 { 15130 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 15131 wmi_buf_t buf; 15132 int i; 15133 int32_t err; 15134 uint32_t len = 0, *cmd_args; 15135 uint8_t *buf_ptr; 15136 15137 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 15138 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 15139 buf = wmi_buf_alloc(wmi_handle, len); 15140 if (!buf) { 15141 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 15142 return QDF_STATUS_E_NOMEM; 15143 } 15144 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 15145 buf_ptr = (uint8_t *)cmd; 15146 WMITLV_SET_HDR(&cmd->tlv_header, 15147 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 15148 WMITLV_GET_STRUCT_TLVLEN( 15149 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 15150 15151 cmd->vdev_id = action_params->vdev_id; 15152 cmd->operation = action_params->operation; 15153 15154 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 15155 cmd->action_category_map[i] = 15156 action_params->action_category_map[i]; 15157 15158 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 15159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15160 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 15161 buf_ptr += WMI_TLV_HDR_SIZE; 15162 cmd_args = (uint32_t *) buf_ptr; 15163 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 15164 cmd_args[i] = action_params->action_per_category[i]; 15165 15166 err = wmi_unified_cmd_send(wmi_handle, buf, 15167 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 15168 if (err) { 15169 WMI_LOGE("Failed to send ap_ps_egap cmd"); 15170 wmi_buf_free(buf); 15171 return QDF_STATUS_E_FAILURE; 15172 } 15173 15174 return QDF_STATUS_SUCCESS; 15175 } 15176 15177 #ifdef FEATURE_WLAN_LPHB 15178 15179 /** 15180 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 15181 * @wmi_handle: wmi handle 15182 * @lphb_conf_req: configuration info 15183 * 15184 * Return: CDF status 15185 */ 15186 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 15187 wmi_hb_set_enable_cmd_fixed_param *params) 15188 { 15189 QDF_STATUS status; 15190 wmi_buf_t buf = NULL; 15191 uint8_t *buf_ptr; 15192 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 15193 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 15194 15195 15196 buf = wmi_buf_alloc(wmi_handle, len); 15197 if (!buf) { 15198 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15199 return QDF_STATUS_E_NOMEM; 15200 } 15201 15202 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15203 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 15204 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 15205 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 15206 WMITLV_GET_STRUCT_TLVLEN 15207 (wmi_hb_set_enable_cmd_fixed_param)); 15208 15209 /* fill in values */ 15210 hb_enable_fp->vdev_id = params->session; 15211 hb_enable_fp->enable = params->enable; 15212 hb_enable_fp->item = params->item; 15213 hb_enable_fp->session = params->session; 15214 15215 status = wmi_unified_cmd_send(wmi_handle, buf, 15216 len, WMI_HB_SET_ENABLE_CMDID); 15217 if (QDF_IS_STATUS_ERROR(status)) { 15218 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 15219 status); 15220 wmi_buf_free(buf); 15221 } 15222 15223 return status; 15224 } 15225 15226 /** 15227 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 15228 * @wmi_handle: wmi handle 15229 * @lphb_conf_req: lphb config request 15230 * 15231 * Return: CDF status 15232 */ 15233 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 15234 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 15235 { 15236 QDF_STATUS status; 15237 wmi_buf_t buf = NULL; 15238 uint8_t *buf_ptr; 15239 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 15240 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 15241 15242 buf = wmi_buf_alloc(wmi_handle, len); 15243 if (!buf) { 15244 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15245 return QDF_STATUS_E_NOMEM; 15246 } 15247 15248 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15249 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 15250 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 15251 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 15252 WMITLV_GET_STRUCT_TLVLEN 15253 (wmi_hb_set_tcp_params_cmd_fixed_param)); 15254 15255 /* fill in values */ 15256 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15257 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15258 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15259 hb_tcp_params_fp->seq = lphb_conf_req->seq; 15260 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 15261 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 15262 hb_tcp_params_fp->interval = lphb_conf_req->interval; 15263 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 15264 hb_tcp_params_fp->session = lphb_conf_req->session; 15265 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 15266 &lphb_conf_req->gateway_mac, 15267 sizeof(hb_tcp_params_fp->gateway_mac)); 15268 15269 status = wmi_unified_cmd_send(wmi_handle, buf, 15270 len, WMI_HB_SET_TCP_PARAMS_CMDID); 15271 if (QDF_IS_STATUS_ERROR(status)) { 15272 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 15273 status); 15274 wmi_buf_free(buf); 15275 } 15276 15277 return status; 15278 } 15279 15280 /** 15281 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 15282 * @wmi_handle: wmi handle 15283 * @lphb_conf_req: lphb config request 15284 * 15285 * Return: CDF status 15286 */ 15287 static 15288 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15289 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 15290 { 15291 QDF_STATUS status; 15292 wmi_buf_t buf = NULL; 15293 uint8_t *buf_ptr; 15294 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 15295 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 15296 15297 buf = wmi_buf_alloc(wmi_handle, len); 15298 if (!buf) { 15299 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15300 return QDF_STATUS_E_NOMEM; 15301 } 15302 15303 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15304 hb_tcp_filter_fp = 15305 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 15306 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 15307 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 15308 WMITLV_GET_STRUCT_TLVLEN 15309 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 15310 15311 /* fill in values */ 15312 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 15313 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 15314 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 15315 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 15316 memcpy((void *)&hb_tcp_filter_fp->filter, 15317 (void *)&g_hb_tcp_filter_fp->filter, 15318 WMI_WLAN_HB_MAX_FILTER_SIZE); 15319 15320 status = wmi_unified_cmd_send(wmi_handle, buf, 15321 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 15322 if (QDF_IS_STATUS_ERROR(status)) { 15323 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 15324 status); 15325 wmi_buf_free(buf); 15326 } 15327 15328 return status; 15329 } 15330 15331 /** 15332 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 15333 * @wmi_handle: wmi handle 15334 * @lphb_conf_req: lphb config request 15335 * 15336 * Return: CDF status 15337 */ 15338 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 15339 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 15340 { 15341 QDF_STATUS status; 15342 wmi_buf_t buf = NULL; 15343 uint8_t *buf_ptr; 15344 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 15345 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 15346 15347 buf = wmi_buf_alloc(wmi_handle, len); 15348 if (!buf) { 15349 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15350 return QDF_STATUS_E_NOMEM; 15351 } 15352 15353 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15354 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 15355 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 15356 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 15357 WMITLV_GET_STRUCT_TLVLEN 15358 (wmi_hb_set_udp_params_cmd_fixed_param)); 15359 15360 /* fill in values */ 15361 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15362 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15363 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15364 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 15365 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 15366 hb_udp_params_fp->interval = lphb_conf_req->interval; 15367 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 15368 hb_udp_params_fp->session = lphb_conf_req->session; 15369 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 15370 &lphb_conf_req->gateway_mac, 15371 sizeof(lphb_conf_req->gateway_mac)); 15372 15373 status = wmi_unified_cmd_send(wmi_handle, buf, 15374 len, WMI_HB_SET_UDP_PARAMS_CMDID); 15375 if (QDF_IS_STATUS_ERROR(status)) { 15376 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 15377 status); 15378 wmi_buf_free(buf); 15379 } 15380 15381 return status; 15382 } 15383 15384 /** 15385 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 15386 * @wmi_handle: wmi handle 15387 * @lphb_conf_req: lphb config request 15388 * 15389 * Return: CDF status 15390 */ 15391 static 15392 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15393 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 15394 { 15395 QDF_STATUS status; 15396 wmi_buf_t buf = NULL; 15397 uint8_t *buf_ptr; 15398 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 15399 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 15400 15401 buf = wmi_buf_alloc(wmi_handle, len); 15402 if (!buf) { 15403 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15404 return QDF_STATUS_E_NOMEM; 15405 } 15406 15407 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15408 hb_udp_filter_fp = 15409 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 15410 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 15411 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 15412 WMITLV_GET_STRUCT_TLVLEN 15413 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 15414 15415 /* fill in values */ 15416 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 15417 hb_udp_filter_fp->length = lphb_conf_req->length; 15418 hb_udp_filter_fp->offset = lphb_conf_req->offset; 15419 hb_udp_filter_fp->session = lphb_conf_req->session; 15420 memcpy((void *)&hb_udp_filter_fp->filter, 15421 (void *)&lphb_conf_req->filter, 15422 WMI_WLAN_HB_MAX_FILTER_SIZE); 15423 15424 status = wmi_unified_cmd_send(wmi_handle, buf, 15425 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 15426 if (QDF_IS_STATUS_ERROR(status)) { 15427 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 15428 status); 15429 wmi_buf_free(buf); 15430 } 15431 15432 return status; 15433 } 15434 #endif /* FEATURE_WLAN_LPHB */ 15435 15436 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 15437 struct pmo_hw_filter_params *req) 15438 { 15439 QDF_STATUS status; 15440 wmi_hw_data_filter_cmd_fixed_param *cmd; 15441 wmi_buf_t wmi_buf; 15442 15443 if (!req) { 15444 WMI_LOGE("req is null"); 15445 return QDF_STATUS_E_INVAL; 15446 } 15447 15448 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 15449 if (!wmi_buf) { 15450 WMI_LOGE(FL("Out of memory")); 15451 return QDF_STATUS_E_NOMEM; 15452 } 15453 15454 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15455 WMITLV_SET_HDR(&cmd->tlv_header, 15456 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 15457 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 15458 cmd->vdev_id = req->vdev_id; 15459 cmd->enable = req->mode != PMO_HW_FILTER_DISABLED; 15460 cmd->hw_filter_bitmap = req->mode; 15461 15462 WMI_LOGD("configure hw filter (vdev_id: %d, mode: %d)", 15463 req->vdev_id, req->mode); 15464 15465 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 15466 WMI_HW_DATA_FILTER_CMDID); 15467 if (QDF_IS_STATUS_ERROR(status)) { 15468 WMI_LOGE("Failed to configure hw filter"); 15469 wmi_buf_free(wmi_buf); 15470 } 15471 15472 return status; 15473 } 15474 15475 /** 15476 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 15477 * @wmi_handle: wmi handle 15478 * @vdev_id: vdev id 15479 * @enable: Flag to enable/disable packet filter 15480 * 15481 * Return: QDF_STATUS_SUCCESS for success or error code 15482 */ 15483 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 15484 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 15485 { 15486 int32_t len; 15487 int ret = 0; 15488 wmi_buf_t buf; 15489 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 15490 15491 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 15492 15493 buf = wmi_buf_alloc(wmi_handle, len); 15494 if (!buf) { 15495 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 15496 return QDF_STATUS_E_NOMEM; 15497 } 15498 15499 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 15500 WMITLV_SET_HDR(&cmd->tlv_header, 15501 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 15502 WMITLV_GET_STRUCT_TLVLEN( 15503 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 15504 15505 cmd->vdev_id = vdev_id; 15506 if (enable) 15507 cmd->enable = PACKET_FILTER_SET_ENABLE; 15508 else 15509 cmd->enable = PACKET_FILTER_SET_DISABLE; 15510 15511 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 15512 __func__, cmd->enable, vdev_id); 15513 15514 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15515 WMI_PACKET_FILTER_ENABLE_CMDID); 15516 if (ret) { 15517 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 15518 wmi_buf_free(buf); 15519 } 15520 15521 return ret; 15522 } 15523 15524 /** 15525 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 15526 * @wmi_handle: wmi handle 15527 * @vdev_id: vdev id 15528 * @rcv_filter_param: Packet filter parameters 15529 * @filter_id: Filter id 15530 * @enable: Flag to add/delete packet filter configuration 15531 * 15532 * Return: QDF_STATUS_SUCCESS for success or error code 15533 */ 15534 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 15535 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 15536 uint8_t filter_id, bool enable) 15537 { 15538 int len, i; 15539 int err = 0; 15540 wmi_buf_t buf; 15541 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 15542 15543 15544 /* allocate the memory */ 15545 len = sizeof(*cmd); 15546 buf = wmi_buf_alloc(wmi_handle, len); 15547 if (!buf) { 15548 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 15549 return QDF_STATUS_E_NOMEM; 15550 } 15551 15552 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 15553 WMITLV_SET_HDR(&cmd->tlv_header, 15554 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 15555 WMITLV_GET_STRUCT_TLVLEN 15556 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 15557 15558 cmd->vdev_id = vdev_id; 15559 cmd->filter_id = filter_id; 15560 if (enable) 15561 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 15562 else 15563 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 15564 15565 if (enable) { 15566 cmd->num_params = QDF_MIN( 15567 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 15568 rcv_filter_param->num_params); 15569 cmd->filter_type = rcv_filter_param->filter_type; 15570 cmd->coalesce_time = rcv_filter_param->coalesce_time; 15571 15572 for (i = 0; i < cmd->num_params; i++) { 15573 cmd->paramsData[i].proto_type = 15574 rcv_filter_param->params_data[i].protocol_layer; 15575 cmd->paramsData[i].cmp_type = 15576 rcv_filter_param->params_data[i].compare_flag; 15577 cmd->paramsData[i].data_length = 15578 rcv_filter_param->params_data[i].data_length; 15579 cmd->paramsData[i].data_offset = 15580 rcv_filter_param->params_data[i].data_offset; 15581 memcpy(&cmd->paramsData[i].compareData, 15582 rcv_filter_param->params_data[i].compare_data, 15583 sizeof(cmd->paramsData[i].compareData)); 15584 memcpy(&cmd->paramsData[i].dataMask, 15585 rcv_filter_param->params_data[i].data_mask, 15586 sizeof(cmd->paramsData[i].dataMask)); 15587 } 15588 } 15589 15590 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 15591 cmd->filter_action, cmd->filter_id, cmd->num_params); 15592 /* send the command along with data */ 15593 err = wmi_unified_cmd_send(wmi_handle, buf, len, 15594 WMI_PACKET_FILTER_CONFIG_CMDID); 15595 if (err) { 15596 WMI_LOGE("Failed to send pkt_filter cmd"); 15597 wmi_buf_free(buf); 15598 return QDF_STATUS_E_FAILURE; 15599 } 15600 15601 return QDF_STATUS_SUCCESS; 15602 } 15603 #endif /* End of WLAN_PMO_ENABLE */ 15604 15605 /** 15606 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 15607 * @wmi_handle: wmi handle 15608 * @request: SSID hotlist set request 15609 * 15610 * Return: QDF_STATUS enumeration 15611 */ 15612 static QDF_STATUS 15613 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 15614 struct ssid_hotlist_request_params *request) 15615 { 15616 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 15617 wmi_buf_t wmi_buf; 15618 uint32_t len; 15619 uint32_t array_size; 15620 uint8_t *buf_ptr; 15621 15622 /* length of fixed portion */ 15623 len = sizeof(*cmd); 15624 15625 /* length of variable portion */ 15626 array_size = 15627 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 15628 len += WMI_TLV_HDR_SIZE + array_size; 15629 15630 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15631 if (!wmi_buf) { 15632 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15633 return QDF_STATUS_E_NOMEM; 15634 } 15635 15636 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 15637 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 15638 buf_ptr; 15639 WMITLV_SET_HDR 15640 (&cmd->tlv_header, 15641 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 15642 WMITLV_GET_STRUCT_TLVLEN 15643 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 15644 15645 cmd->request_id = request->request_id; 15646 cmd->requestor_id = 0; 15647 cmd->vdev_id = request->session_id; 15648 cmd->table_id = 0; 15649 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 15650 cmd->total_entries = request->ssid_count; 15651 cmd->num_entries_in_page = request->ssid_count; 15652 cmd->first_entry_index = 0; 15653 15654 buf_ptr += sizeof(*cmd); 15655 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15656 15657 if (request->ssid_count) { 15658 wmi_extscan_hotlist_ssid_entry *entry; 15659 int i; 15660 15661 buf_ptr += WMI_TLV_HDR_SIZE; 15662 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15663 for (i = 0; i < request->ssid_count; i++) { 15664 WMITLV_SET_HDR 15665 (entry, 15666 WMITLV_TAG_ARRAY_STRUC, 15667 WMITLV_GET_STRUCT_TLVLEN 15668 (wmi_extscan_hotlist_ssid_entry)); 15669 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15670 qdf_mem_copy(entry->ssid.ssid, 15671 request->ssids[i].ssid.mac_ssid, 15672 request->ssids[i].ssid.length); 15673 entry->band = request->ssids[i].band; 15674 entry->min_rssi = request->ssids[i].rssi_low; 15675 entry->max_rssi = request->ssids[i].rssi_high; 15676 entry++; 15677 } 15678 cmd->mode = WMI_EXTSCAN_MODE_START; 15679 } else { 15680 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15681 } 15682 15683 if (wmi_unified_cmd_send 15684 (wmi_handle, wmi_buf, len, 15685 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15686 WMI_LOGE("%s: failed to send command", __func__); 15687 wmi_buf_free(wmi_buf); 15688 return QDF_STATUS_E_FAILURE; 15689 } 15690 15691 return QDF_STATUS_SUCCESS; 15692 } 15693 15694 /** 15695 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 15696 * @wmi_handle: wmi handle 15697 * @vdev_id: vdev id 15698 * 15699 * This function sends roam synch complete event to fw. 15700 * 15701 * Return: CDF STATUS 15702 */ 15703 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 15704 uint8_t vdev_id) 15705 { 15706 wmi_roam_synch_complete_fixed_param *cmd; 15707 wmi_buf_t wmi_buf; 15708 uint8_t *buf_ptr; 15709 uint16_t len; 15710 len = sizeof(wmi_roam_synch_complete_fixed_param); 15711 15712 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15713 if (!wmi_buf) { 15714 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15715 return QDF_STATUS_E_NOMEM; 15716 } 15717 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15718 buf_ptr = (uint8_t *) cmd; 15719 WMITLV_SET_HDR(&cmd->tlv_header, 15720 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15721 WMITLV_GET_STRUCT_TLVLEN 15722 (wmi_roam_synch_complete_fixed_param)); 15723 cmd->vdev_id = vdev_id; 15724 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15725 WMI_ROAM_SYNCH_COMPLETE)) { 15726 WMI_LOGP("%s: failed to send roam synch confirmation", 15727 __func__); 15728 wmi_buf_free(wmi_buf); 15729 return QDF_STATUS_E_FAILURE; 15730 } 15731 15732 return QDF_STATUS_SUCCESS; 15733 } 15734 15735 /** 15736 * send_fw_test_cmd_tlv() - send fw test command to fw. 15737 * @wmi_handle: wmi handle 15738 * @wmi_fwtest: fw test command 15739 * 15740 * This function sends fw test command to fw. 15741 * 15742 * Return: CDF STATUS 15743 */ 15744 static 15745 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15746 struct set_fwtest_params *wmi_fwtest) 15747 { 15748 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15749 wmi_buf_t wmi_buf; 15750 uint16_t len; 15751 15752 len = sizeof(*cmd); 15753 15754 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15755 if (!wmi_buf) { 15756 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15757 return QDF_STATUS_E_NOMEM; 15758 } 15759 15760 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15761 WMITLV_SET_HDR(&cmd->tlv_header, 15762 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15763 WMITLV_GET_STRUCT_TLVLEN( 15764 wmi_fwtest_set_param_cmd_fixed_param)); 15765 cmd->param_id = wmi_fwtest->arg; 15766 cmd->param_value = wmi_fwtest->value; 15767 15768 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15769 WMI_FWTEST_CMDID)) { 15770 WMI_LOGP("%s: failed to send fw test command", __func__); 15771 qdf_nbuf_free(wmi_buf); 15772 return QDF_STATUS_E_FAILURE; 15773 } 15774 15775 return QDF_STATUS_SUCCESS; 15776 } 15777 15778 /** 15779 * send_unit_test_cmd_tlv() - send unit test command to fw. 15780 * @wmi_handle: wmi handle 15781 * @wmi_utest: unit test command 15782 * 15783 * This function send unit test command to fw. 15784 * 15785 * Return: CDF STATUS 15786 */ 15787 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15788 struct wmi_unit_test_cmd *wmi_utest) 15789 { 15790 wmi_unit_test_cmd_fixed_param *cmd; 15791 wmi_buf_t wmi_buf; 15792 uint8_t *buf_ptr; 15793 int i; 15794 uint16_t len, args_tlv_len; 15795 uint32_t *unit_test_cmd_args; 15796 15797 args_tlv_len = 15798 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15799 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15800 15801 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15802 if (!wmi_buf) { 15803 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15804 return QDF_STATUS_E_NOMEM; 15805 } 15806 15807 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15808 buf_ptr = (uint8_t *) cmd; 15809 WMITLV_SET_HDR(&cmd->tlv_header, 15810 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15811 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15812 cmd->vdev_id = wmi_utest->vdev_id; 15813 cmd->module_id = wmi_utest->module_id; 15814 cmd->num_args = wmi_utest->num_args; 15815 cmd->diag_token = wmi_utest->diag_token; 15816 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15817 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15818 (wmi_utest->num_args * sizeof(uint32_t))); 15819 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15820 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15821 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15822 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15823 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15824 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15825 unit_test_cmd_args[i] = wmi_utest->args[i]; 15826 WMI_LOGI("%d,", wmi_utest->args[i]); 15827 } 15828 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15829 WMI_UNIT_TEST_CMDID)) { 15830 WMI_LOGP("%s: failed to send unit test command", __func__); 15831 wmi_buf_free(wmi_buf); 15832 return QDF_STATUS_E_FAILURE; 15833 } 15834 15835 return QDF_STATUS_SUCCESS; 15836 } 15837 15838 /** 15839 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15840 * @wmi_handle: wma handle 15841 * @roaminvoke: roam invoke command 15842 * 15843 * Send roam invoke command to fw for fastreassoc. 15844 * 15845 * Return: CDF STATUS 15846 */ 15847 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15848 struct wmi_roam_invoke_cmd *roaminvoke, 15849 uint32_t ch_hz) 15850 { 15851 wmi_roam_invoke_cmd_fixed_param *cmd; 15852 wmi_buf_t wmi_buf; 15853 u_int8_t *buf_ptr; 15854 u_int16_t len, args_tlv_len; 15855 uint32_t *channel_list; 15856 wmi_mac_addr *bssid_list; 15857 wmi_tlv_buf_len_param *buf_len_tlv; 15858 15859 /* Host sends only one channel and one bssid */ 15860 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15861 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15862 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15863 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15864 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15865 if (!wmi_buf) { 15866 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15867 return QDF_STATUS_E_NOMEM; 15868 } 15869 15870 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15871 buf_ptr = (u_int8_t *) cmd; 15872 WMITLV_SET_HDR(&cmd->tlv_header, 15873 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15874 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15875 cmd->vdev_id = roaminvoke->vdev_id; 15876 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15877 if (roaminvoke->is_same_bssid) 15878 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15879 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15880 15881 if (roaminvoke->frame_len) { 15882 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15883 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15884 cmd->num_buf = 1; 15885 } else { 15886 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15887 cmd->num_buf = 0; 15888 } 15889 15890 cmd->roam_ap_sel_mode = 0; 15891 cmd->roam_delay = 0; 15892 cmd->num_chan = 1; 15893 cmd->num_bssid = 1; 15894 15895 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15896 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15897 (sizeof(u_int32_t))); 15898 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15899 *channel_list = ch_hz; 15900 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15901 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15902 (sizeof(wmi_mac_addr))); 15903 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15904 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15905 15906 /* move to next tlv i.e. bcn_prb_buf_list */ 15907 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15908 15909 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15910 sizeof(wmi_tlv_buf_len_param)); 15911 15912 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15913 buf_len_tlv->buf_len = roaminvoke->frame_len; 15914 15915 /* move to next tlv i.e. bcn_prb_frm */ 15916 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15917 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15918 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15919 15920 /* copy frame after the header */ 15921 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15922 roaminvoke->frame_buf, 15923 roaminvoke->frame_len); 15924 15925 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15926 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 15927 buf_ptr + WMI_TLV_HDR_SIZE, 15928 roaminvoke->frame_len); 15929 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15930 cmd->flags, cmd->roam_scan_mode, 15931 cmd->roam_ap_sel_mode, cmd->roam_delay, 15932 cmd->num_chan, cmd->num_bssid); 15933 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15934 15935 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15936 WMI_ROAM_INVOKE_CMDID)) { 15937 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15938 wmi_buf_free(wmi_buf); 15939 return QDF_STATUS_E_FAILURE; 15940 } 15941 15942 return QDF_STATUS_SUCCESS; 15943 } 15944 15945 /** 15946 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15947 * @wmi_handle: wmi handle 15948 * @command: command 15949 * @vdev_id: vdev id 15950 * 15951 * This function set roam offload command to fw. 15952 * 15953 * Return: CDF status 15954 */ 15955 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15956 uint32_t command, uint32_t vdev_id) 15957 { 15958 QDF_STATUS status; 15959 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15960 wmi_buf_t buf = NULL; 15961 int len; 15962 uint8_t *buf_ptr; 15963 15964 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15965 buf = wmi_buf_alloc(wmi_handle, len); 15966 if (!buf) { 15967 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15968 return QDF_STATUS_E_NOMEM; 15969 } 15970 15971 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15972 15973 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15974 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15975 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15976 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15977 cmd_fp->vdev_id = vdev_id; 15978 cmd_fp->command_arg = command; 15979 15980 status = wmi_unified_cmd_send(wmi_handle, buf, 15981 len, WMI_ROAM_SCAN_CMD); 15982 if (QDF_IS_STATUS_ERROR(status)) { 15983 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15984 status); 15985 goto error; 15986 } 15987 15988 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15989 return QDF_STATUS_SUCCESS; 15990 15991 error: 15992 wmi_buf_free(buf); 15993 15994 return status; 15995 } 15996 15997 /** 15998 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15999 * @wmi_handle: wmi handle 16000 * @ap_profile_p: ap profile 16001 * @vdev_id: vdev id 16002 * 16003 * Send WMI_ROAM_AP_PROFILE to firmware 16004 * 16005 * Return: CDF status 16006 */ 16007 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 16008 struct ap_profile_params *ap_profile) 16009 { 16010 wmi_buf_t buf = NULL; 16011 QDF_STATUS status; 16012 int len; 16013 uint8_t *buf_ptr; 16014 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 16015 wmi_roam_cnd_scoring_param *score_param; 16016 wmi_ap_profile *profile; 16017 16018 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 16019 len += sizeof(*score_param); 16020 buf = wmi_buf_alloc(wmi_handle, len); 16021 if (!buf) { 16022 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16023 return QDF_STATUS_E_NOMEM; 16024 } 16025 16026 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16027 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 16028 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 16029 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 16030 WMITLV_GET_STRUCT_TLVLEN 16031 (wmi_roam_ap_profile_fixed_param)); 16032 /* fill in threshold values */ 16033 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 16034 roam_ap_profile_fp->id = 0; 16035 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 16036 16037 profile = (wmi_ap_profile *)buf_ptr; 16038 WMITLV_SET_HDR(&profile->tlv_header, 16039 WMITLV_TAG_STRUC_wmi_ap_profile, 16040 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 16041 profile->flags = ap_profile->profile.flags; 16042 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 16043 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 16044 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 16045 profile->ssid.ssid_len); 16046 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 16047 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 16048 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 16049 profile->rsn_mcastmgmtcipherset = 16050 ap_profile->profile.rsn_mcastmgmtcipherset; 16051 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 16052 16053 WMI_LOGD("AP profile: flags %x rssi_threshold %d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d", 16054 profile->flags, profile->rssi_threshold, 16055 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 16056 profile->rsn_authmode, profile->rsn_ucastcipherset, 16057 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 16058 profile->rssi_abs_thresh); 16059 16060 buf_ptr += sizeof(wmi_ap_profile); 16061 16062 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 16063 WMITLV_SET_HDR(&score_param->tlv_header, 16064 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 16065 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 16066 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 16067 score_param->rssi_weightage_pcnt = 16068 ap_profile->param.rssi_weightage; 16069 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 16070 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 16071 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 16072 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 16073 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 16074 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 16075 score_param->esp_qbss_weightage_pcnt = 16076 ap_profile->param.esp_qbss_weightage; 16077 score_param->beamforming_weightage_pcnt = 16078 ap_profile->param.beamforming_weightage; 16079 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 16080 score_param->oce_wan_weightage_pcnt = 16081 ap_profile->param.oce_wan_weightage; 16082 16083 WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d", 16084 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 16085 score_param->ht_weightage_pcnt, 16086 score_param->vht_weightage_pcnt, 16087 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 16088 score_param->band_weightage_pcnt, 16089 score_param->nss_weightage_pcnt, 16090 score_param->esp_qbss_weightage_pcnt, 16091 score_param->beamforming_weightage_pcnt, 16092 score_param->pcl_weightage_pcnt, 16093 score_param->oce_wan_weightage_pcnt); 16094 16095 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 16096 score_param->band_scoring.score_pcnt = 16097 ap_profile->param.band_index_score; 16098 score_param->nss_scoring.score_pcnt = 16099 ap_profile->param.nss_index_score; 16100 16101 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 16102 score_param->bw_scoring.score_pcnt, 16103 score_param->band_scoring.score_pcnt, 16104 score_param->nss_scoring.score_pcnt); 16105 16106 score_param->rssi_scoring.best_rssi_threshold = 16107 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 16108 score_param->rssi_scoring.good_rssi_threshold = 16109 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 16110 score_param->rssi_scoring.bad_rssi_threshold = 16111 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 16112 score_param->rssi_scoring.good_rssi_pcnt = 16113 ap_profile->param.rssi_scoring.good_rssi_pcnt; 16114 score_param->rssi_scoring.bad_rssi_pcnt = 16115 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 16116 score_param->rssi_scoring.good_bucket_size = 16117 ap_profile->param.rssi_scoring.good_bucket_size; 16118 score_param->rssi_scoring.bad_bucket_size = 16119 ap_profile->param.rssi_scoring.bad_bucket_size; 16120 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 16121 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 16122 16123 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 16124 score_param->rssi_scoring.best_rssi_threshold, 16125 score_param->rssi_scoring.good_rssi_threshold, 16126 score_param->rssi_scoring.bad_rssi_threshold, 16127 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 16128 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 16129 score_param->rssi_scoring.good_rssi_pcnt, 16130 score_param->rssi_scoring.bad_rssi_pcnt, 16131 score_param->rssi_scoring.good_bucket_size, 16132 score_param->rssi_scoring.bad_bucket_size); 16133 16134 score_param->esp_qbss_scoring.num_slot = 16135 ap_profile->param.esp_qbss_scoring.num_slot; 16136 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 16137 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 16138 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 16139 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 16140 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 16141 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 16142 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 16143 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 16144 16145 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16146 score_param->esp_qbss_scoring.num_slot, 16147 score_param->esp_qbss_scoring.score_pcnt3_to_0, 16148 score_param->esp_qbss_scoring.score_pcnt7_to_4, 16149 score_param->esp_qbss_scoring.score_pcnt11_to_8, 16150 score_param->esp_qbss_scoring.score_pcnt15_to_12); 16151 16152 score_param->oce_wan_scoring.num_slot = 16153 ap_profile->param.oce_wan_scoring.num_slot; 16154 score_param->oce_wan_scoring.score_pcnt3_to_0 = 16155 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 16156 score_param->oce_wan_scoring.score_pcnt7_to_4 = 16157 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 16158 score_param->oce_wan_scoring.score_pcnt11_to_8 = 16159 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 16160 score_param->oce_wan_scoring.score_pcnt15_to_12 = 16161 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 16162 16163 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16164 score_param->oce_wan_scoring.num_slot, 16165 score_param->oce_wan_scoring.score_pcnt3_to_0, 16166 score_param->oce_wan_scoring.score_pcnt7_to_4, 16167 score_param->oce_wan_scoring.score_pcnt11_to_8, 16168 score_param->oce_wan_scoring.score_pcnt15_to_12); 16169 16170 status = wmi_unified_cmd_send(wmi_handle, buf, 16171 len, WMI_ROAM_AP_PROFILE); 16172 if (QDF_IS_STATUS_ERROR(status)) { 16173 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 16174 status); 16175 wmi_buf_free(buf); 16176 } 16177 16178 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 16179 16180 return status; 16181 } 16182 16183 /** 16184 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 16185 * @wmi_handle: wmi handle 16186 * @scan_period: scan period 16187 * @scan_age: scan age 16188 * @vdev_id: vdev id 16189 * 16190 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 16191 * 16192 * Return: CDF status 16193 */ 16194 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 16195 uint32_t scan_period, 16196 uint32_t scan_age, 16197 uint32_t vdev_id) 16198 { 16199 QDF_STATUS status; 16200 wmi_buf_t buf = NULL; 16201 int len; 16202 uint8_t *buf_ptr; 16203 wmi_roam_scan_period_fixed_param *scan_period_fp; 16204 16205 /* Send scan period values */ 16206 len = sizeof(wmi_roam_scan_period_fixed_param); 16207 buf = wmi_buf_alloc(wmi_handle, len); 16208 if (!buf) { 16209 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16210 return QDF_STATUS_E_NOMEM; 16211 } 16212 16213 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16214 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 16215 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 16216 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 16217 WMITLV_GET_STRUCT_TLVLEN 16218 (wmi_roam_scan_period_fixed_param)); 16219 /* fill in scan period values */ 16220 scan_period_fp->vdev_id = vdev_id; 16221 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 16222 scan_period_fp->roam_scan_age = scan_age; 16223 16224 status = wmi_unified_cmd_send(wmi_handle, buf, 16225 len, WMI_ROAM_SCAN_PERIOD); 16226 if (QDF_IS_STATUS_ERROR(status)) { 16227 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 16228 status); 16229 goto error; 16230 } 16231 16232 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 16233 __func__, scan_period, scan_age); 16234 return QDF_STATUS_SUCCESS; 16235 error: 16236 wmi_buf_free(buf); 16237 16238 return status; 16239 } 16240 16241 /** 16242 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 16243 * @wmi_handle: wmi handle 16244 * @chan_count: channel count 16245 * @chan_list: channel list 16246 * @list_type: list type 16247 * @vdev_id: vdev id 16248 * 16249 * Set roam offload channel list. 16250 * 16251 * Return: CDF status 16252 */ 16253 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 16254 uint8_t chan_count, 16255 uint32_t *chan_list, 16256 uint8_t list_type, uint32_t vdev_id) 16257 { 16258 wmi_buf_t buf = NULL; 16259 QDF_STATUS status; 16260 int len, list_tlv_len; 16261 int i; 16262 uint8_t *buf_ptr; 16263 wmi_roam_chan_list_fixed_param *chan_list_fp; 16264 uint32_t *roam_chan_list_array; 16265 16266 if (chan_count == 0) { 16267 WMI_LOGD("%s : invalid number of channels %d", __func__, 16268 chan_count); 16269 return QDF_STATUS_E_EMPTY; 16270 } 16271 /* Channel list is a table of 2 TLV's */ 16272 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 16273 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 16274 buf = wmi_buf_alloc(wmi_handle, len); 16275 if (!buf) { 16276 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16277 return QDF_STATUS_E_NOMEM; 16278 } 16279 16280 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16281 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 16282 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 16283 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 16284 WMITLV_GET_STRUCT_TLVLEN 16285 (wmi_roam_chan_list_fixed_param)); 16286 chan_list_fp->vdev_id = vdev_id; 16287 chan_list_fp->num_chan = chan_count; 16288 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 16289 /* external app is controlling channel list */ 16290 chan_list_fp->chan_list_type = 16291 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 16292 } else { 16293 /* umac supplied occupied channel list in LFR */ 16294 chan_list_fp->chan_list_type = 16295 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 16296 } 16297 16298 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 16299 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16300 (chan_list_fp->num_chan * sizeof(uint32_t))); 16301 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16302 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 16303 for (i = 0; ((i < chan_list_fp->num_chan) && 16304 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 16305 roam_chan_list_array[i] = chan_list[i]; 16306 WMI_LOGI("%d,", roam_chan_list_array[i]); 16307 } 16308 16309 status = wmi_unified_cmd_send(wmi_handle, buf, 16310 len, WMI_ROAM_CHAN_LIST); 16311 if (QDF_IS_STATUS_ERROR(status)) { 16312 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 16313 status); 16314 goto error; 16315 } 16316 16317 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 16318 return QDF_STATUS_SUCCESS; 16319 error: 16320 wmi_buf_free(buf); 16321 16322 return status; 16323 } 16324 16325 /** 16326 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 16327 * @wmi_handle: wmi handle 16328 * @req_buf: per roam config buffer 16329 * 16330 * Return: QDF status 16331 */ 16332 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 16333 struct wmi_per_roam_config_req *req_buf) 16334 { 16335 wmi_buf_t buf = NULL; 16336 QDF_STATUS status; 16337 int len; 16338 uint8_t *buf_ptr; 16339 wmi_roam_per_config_fixed_param *wmi_per_config; 16340 16341 len = sizeof(wmi_roam_per_config_fixed_param); 16342 buf = wmi_buf_alloc(wmi_handle, len); 16343 if (!buf) { 16344 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16345 return QDF_STATUS_E_NOMEM; 16346 } 16347 16348 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16349 wmi_per_config = 16350 (wmi_roam_per_config_fixed_param *) buf_ptr; 16351 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 16352 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 16353 WMITLV_GET_STRUCT_TLVLEN 16354 (wmi_roam_per_config_fixed_param)); 16355 16356 /* fill in per roam config values */ 16357 wmi_per_config->vdev_id = req_buf->vdev_id; 16358 16359 wmi_per_config->enable = req_buf->per_config.enable; 16360 wmi_per_config->high_rate_thresh = 16361 (req_buf->per_config.tx_high_rate_thresh << 16) | 16362 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 16363 wmi_per_config->low_rate_thresh = 16364 (req_buf->per_config.tx_low_rate_thresh << 16) | 16365 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 16366 wmi_per_config->pkt_err_rate_thresh_pct = 16367 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 16368 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 16369 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 16370 wmi_per_config->pkt_err_rate_mon_time = 16371 (req_buf->per_config.tx_per_mon_time << 16) | 16372 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 16373 wmi_per_config->min_candidate_rssi = 16374 req_buf->per_config.min_candidate_rssi; 16375 16376 /* Send per roam config parameters */ 16377 status = wmi_unified_cmd_send(wmi_handle, buf, 16378 len, WMI_ROAM_PER_CONFIG_CMDID); 16379 if (QDF_IS_STATUS_ERROR(status)) { 16380 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 16381 status); 16382 wmi_buf_free(buf); 16383 return status; 16384 } 16385 16386 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 16387 req_buf->per_config.enable, req_buf->vdev_id); 16388 return QDF_STATUS_SUCCESS; 16389 } 16390 16391 /** 16392 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 16393 * @wmi_handle: wmi handle 16394 * @rssi_change_thresh: RSSI Change threshold 16395 * @bcn_rssi_weight: beacon RSSI weight 16396 * @vdev_id: vdev id 16397 * 16398 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 16399 * 16400 * Return: CDF status 16401 */ 16402 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 16403 uint32_t vdev_id, 16404 int32_t rssi_change_thresh, 16405 uint32_t bcn_rssi_weight, 16406 uint32_t hirssi_delay_btw_scans) 16407 { 16408 wmi_buf_t buf = NULL; 16409 QDF_STATUS status; 16410 int len; 16411 uint8_t *buf_ptr; 16412 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 16413 16414 /* Send rssi change parameters */ 16415 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 16416 buf = wmi_buf_alloc(wmi_handle, len); 16417 if (!buf) { 16418 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16419 return QDF_STATUS_E_NOMEM; 16420 } 16421 16422 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16423 rssi_change_fp = 16424 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 16425 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 16426 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 16427 WMITLV_GET_STRUCT_TLVLEN 16428 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 16429 /* fill in rssi change threshold (hysteresis) values */ 16430 rssi_change_fp->vdev_id = vdev_id; 16431 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 16432 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 16433 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 16434 16435 status = wmi_unified_cmd_send(wmi_handle, buf, 16436 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 16437 if (QDF_IS_STATUS_ERROR(status)) { 16438 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 16439 status); 16440 goto error; 16441 } 16442 16443 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 16444 rssi_change_thresh, bcn_rssi_weight); 16445 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 16446 return QDF_STATUS_SUCCESS; 16447 error: 16448 wmi_buf_free(buf); 16449 16450 return status; 16451 } 16452 16453 /** wmi_get_hotlist_entries_per_page() - hotlist entries per page 16454 * @wmi_handle: wmi handle. 16455 * @cmd: size of command structure. 16456 * @per_entry_size: per entry size. 16457 * 16458 * This utility function calculates how many hotlist entries can 16459 * fit in one page. 16460 * 16461 * Return: number of entries 16462 */ 16463 static inline int wmi_get_hotlist_entries_per_page(wmi_unified_t wmi_handle, 16464 size_t cmd_size, 16465 size_t per_entry_size) 16466 { 16467 uint32_t avail_space = 0; 16468 int num_entries = 0; 16469 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle); 16470 16471 /* Calculate number of hotlist entries that can 16472 * be passed in wma message request. 16473 */ 16474 avail_space = max_msg_len - cmd_size; 16475 num_entries = avail_space / per_entry_size; 16476 return num_entries; 16477 } 16478 16479 /** 16480 * send_get_buf_extscan_hotlist_cmd_tlv() - prepare hotlist command 16481 * @wmi_handle: wmi handle 16482 * @photlist: hotlist command params 16483 * @buf_len: buffer length 16484 * 16485 * This function fills individual elements for hotlist request and 16486 * TLV for bssid entries 16487 * 16488 * Return: CDF Status. 16489 */ 16490 static QDF_STATUS send_get_buf_extscan_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 16491 struct ext_scan_setbssi_hotlist_params * 16492 photlist, int *buf_len) 16493 { 16494 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL; 16495 wmi_extscan_hotlist_entry *dest_hotlist; 16496 struct ap_threshold_params *src_ap = photlist->ap; 16497 wmi_buf_t buf; 16498 uint8_t *buf_ptr; 16499 16500 int j, index = 0; 16501 int cmd_len = 0; 16502 int num_entries; 16503 int min_entries = 0; 16504 uint32_t numap = photlist->numAp; 16505 int len = sizeof(*cmd); 16506 16507 len += WMI_TLV_HDR_SIZE; 16508 cmd_len = len; 16509 16510 num_entries = wmi_get_hotlist_entries_per_page(wmi_handle, 16511 cmd_len, 16512 sizeof(*dest_hotlist)); 16513 /* setbssid hotlist expects the bssid list 16514 * to be non zero value 16515 */ 16516 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS)) { 16517 WMI_LOGE("Invalid number of APs: %d", numap); 16518 return QDF_STATUS_E_INVAL; 16519 } 16520 16521 /* Split the hot list entry pages and send multiple command 16522 * requests if the buffer reaches the maximum request size 16523 */ 16524 while (index < numap) { 16525 min_entries = QDF_MIN(num_entries, numap); 16526 len += min_entries * sizeof(wmi_extscan_hotlist_entry); 16527 buf = wmi_buf_alloc(wmi_handle, len); 16528 if (!buf) { 16529 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 16530 return QDF_STATUS_E_FAILURE; 16531 } 16532 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16533 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 16534 buf_ptr; 16535 WMITLV_SET_HDR(&cmd->tlv_header, 16536 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 16537 WMITLV_GET_STRUCT_TLVLEN 16538 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 16539 16540 /* Multiple requests are sent until the num_entries_in_page 16541 * matches the total_entries 16542 */ 16543 cmd->request_id = photlist->requestId; 16544 cmd->vdev_id = photlist->sessionId; 16545 cmd->total_entries = numap; 16546 cmd->mode = 1; 16547 cmd->num_entries_in_page = min_entries; 16548 cmd->lost_ap_scan_count = photlist->lost_ap_sample_size; 16549 cmd->first_entry_index = index; 16550 16551 WMI_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d", 16552 __func__, cmd->vdev_id, cmd->total_entries, 16553 cmd->num_entries_in_page, 16554 cmd->lost_ap_scan_count); 16555 16556 buf_ptr += sizeof(*cmd); 16557 WMITLV_SET_HDR(buf_ptr, 16558 WMITLV_TAG_ARRAY_STRUC, 16559 min_entries * sizeof(wmi_extscan_hotlist_entry)); 16560 dest_hotlist = (wmi_extscan_hotlist_entry *) 16561 (buf_ptr + WMI_TLV_HDR_SIZE); 16562 16563 /* Populate bssid, channel info and rssi 16564 * for the bssid's that are sent as hotlists. 16565 */ 16566 for (j = 0; j < min_entries; j++) { 16567 WMITLV_SET_HDR(dest_hotlist, 16568 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 16569 WMITLV_GET_STRUCT_TLVLEN 16570 (wmi_extscan_hotlist_entry)); 16571 16572 dest_hotlist->min_rssi = src_ap->low; 16573 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 16574 &dest_hotlist->bssid); 16575 16576 WMI_LOGD("%s:channel:%d min_rssi %d", 16577 __func__, dest_hotlist->channel, 16578 dest_hotlist->min_rssi); 16579 WMI_LOGD 16580 ("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16581 __func__, dest_hotlist->bssid.mac_addr31to0, 16582 dest_hotlist->bssid.mac_addr47to32); 16583 dest_hotlist++; 16584 src_ap++; 16585 } 16586 buf_ptr += WMI_TLV_HDR_SIZE + 16587 (min_entries * sizeof(wmi_extscan_hotlist_entry)); 16588 16589 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16590 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 16591 WMI_LOGE("%s: failed to send command", __func__); 16592 wmi_buf_free(buf); 16593 return QDF_STATUS_E_FAILURE; 16594 } 16595 index = index + min_entries; 16596 num_entries = numap - min_entries; 16597 len = cmd_len; 16598 } 16599 return QDF_STATUS_SUCCESS; 16600 } 16601 16602 /** 16603 * send_set_active_bpf_mode_cmd_tlv() - configure active BPF mode in FW 16604 * @wmi_handle: the WMI handle 16605 * @vdev_id: the Id of the vdev to apply the configuration to 16606 * @ucast_mode: the active BPF mode to configure for unicast packets 16607 * @mcast_bcast_mode: the active BPF mode to configure for multicast/broadcast 16608 * packets 16609 * 16610 * Return: QDF status 16611 */ 16612 static QDF_STATUS send_set_active_bpf_mode_cmd_tlv(wmi_unified_t wmi_handle, 16613 uint8_t vdev_id, 16614 enum wmi_host_active_bpf_mode ucast_mode, 16615 enum wmi_host_active_bpf_mode mcast_bcast_mode) 16616 { 16617 const WMITLV_TAG_ID tag_id = 16618 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param; 16619 const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN( 16620 wmi_bpf_set_vdev_active_mode_cmd_fixed_param); 16621 QDF_STATUS status; 16622 wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd; 16623 wmi_buf_t buf; 16624 16625 WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)", 16626 vdev_id, ucast_mode, mcast_bcast_mode); 16627 16628 /* allocate command buffer */ 16629 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 16630 if (!buf) { 16631 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 16632 return QDF_STATUS_E_NOMEM; 16633 } 16634 16635 /* set TLV header */ 16636 cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf); 16637 WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len); 16638 16639 /* populate data */ 16640 cmd->vdev_id = vdev_id; 16641 cmd->uc_mode = ucast_mode; 16642 cmd->mcbc_mode = mcast_bcast_mode; 16643 16644 /* send to FW */ 16645 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 16646 WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID); 16647 if (QDF_IS_STATUS_ERROR(status)) { 16648 WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d", 16649 status); 16650 wmi_buf_free(buf); 16651 return status; 16652 } 16653 16654 WMI_LOGD("Sent WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID successfully"); 16655 16656 return QDF_STATUS_SUCCESS; 16657 } 16658 16659 /** 16660 * send_power_dbg_cmd_tlv() - send power debug commands 16661 * @wmi_handle: wmi handle 16662 * @param: wmi power debug parameter 16663 * 16664 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 16665 * 16666 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16667 */ 16668 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 16669 struct wmi_power_dbg_params *param) 16670 { 16671 wmi_buf_t buf = NULL; 16672 QDF_STATUS status; 16673 int len, args_tlv_len; 16674 uint8_t *buf_ptr; 16675 uint8_t i; 16676 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 16677 uint32_t *cmd_args; 16678 16679 /* Prepare and send power debug cmd parameters */ 16680 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 16681 len = sizeof(*cmd) + args_tlv_len; 16682 buf = wmi_buf_alloc(wmi_handle, len); 16683 if (!buf) { 16684 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16685 return QDF_STATUS_E_NOMEM; 16686 } 16687 16688 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16689 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 16690 WMITLV_SET_HDR(&cmd->tlv_header, 16691 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 16692 WMITLV_GET_STRUCT_TLVLEN 16693 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 16694 16695 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16696 param->pdev_id); 16697 cmd->module_id = param->module_id; 16698 cmd->num_args = param->num_args; 16699 buf_ptr += sizeof(*cmd); 16700 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16701 (param->num_args * sizeof(uint32_t))); 16702 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16703 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 16704 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 16705 cmd_args[i] = param->args[i]; 16706 WMI_LOGI("%d,", param->args[i]); 16707 } 16708 16709 status = wmi_unified_cmd_send(wmi_handle, buf, 16710 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 16711 if (QDF_IS_STATUS_ERROR(status)) { 16712 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 16713 status); 16714 goto error; 16715 } 16716 16717 return QDF_STATUS_SUCCESS; 16718 error: 16719 wmi_buf_free(buf); 16720 16721 return status; 16722 } 16723 16724 /** 16725 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 16726 * @wmi_handle: wmi handle 16727 * @param: wmi multiple vdev restart req param 16728 * 16729 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 16730 * 16731 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16732 */ 16733 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 16734 wmi_unified_t wmi_handle, 16735 struct multiple_vdev_restart_params *param) 16736 { 16737 wmi_buf_t buf; 16738 QDF_STATUS qdf_status; 16739 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 16740 int i; 16741 uint8_t *buf_ptr; 16742 uint32_t *vdev_ids; 16743 wmi_channel *chan_info; 16744 struct channel_param *tchan_info; 16745 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 16746 16747 len += sizeof(wmi_channel); 16748 if (param->num_vdevs) 16749 len += sizeof(uint32_t) * param->num_vdevs; 16750 16751 buf = wmi_buf_alloc(wmi_handle, len); 16752 if (!buf) { 16753 WMI_LOGE("Failed to allocate memory\n"); 16754 qdf_status = QDF_STATUS_E_NOMEM; 16755 goto end; 16756 } 16757 16758 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16759 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 16760 buf_ptr; 16761 16762 WMITLV_SET_HDR(&cmd->tlv_header, 16763 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 16764 WMITLV_GET_STRUCT_TLVLEN 16765 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 16766 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16767 param->pdev_id); 16768 cmd->requestor_id = param->requestor_id; 16769 cmd->disable_hw_ack = param->disable_hw_ack; 16770 cmd->cac_duration_ms = param->cac_duration_ms; 16771 cmd->num_vdevs = param->num_vdevs; 16772 16773 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 16774 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 16775 " cmd->num_vdevs: %d ", 16776 __func__, cmd->pdev_id, cmd->requestor_id, 16777 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 16778 buf_ptr += sizeof(*cmd); 16779 16780 WMITLV_SET_HDR(buf_ptr, 16781 WMITLV_TAG_ARRAY_UINT32, 16782 sizeof(uint32_t) * param->num_vdevs); 16783 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 16784 for (i = 0; i < param->num_vdevs; i++) { 16785 vdev_ids[i] = param->vdev_ids[i]; 16786 } 16787 16788 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 16789 16790 WMITLV_SET_HDR(buf_ptr, 16791 WMITLV_TAG_STRUC_wmi_channel, 16792 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16793 chan_info = (wmi_channel *)buf_ptr; 16794 tchan_info = &(param->ch_param); 16795 chan_info->mhz = tchan_info->mhz; 16796 chan_info->band_center_freq1 = tchan_info->cfreq1; 16797 chan_info->band_center_freq2 = tchan_info->cfreq2; 16798 if (tchan_info->is_chan_passive) 16799 WMI_SET_CHANNEL_FLAG(chan_info, 16800 WMI_CHAN_FLAG_PASSIVE); 16801 if (tchan_info->dfs_set) 16802 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 16803 16804 if (tchan_info->allow_vht) 16805 WMI_SET_CHANNEL_FLAG(chan_info, 16806 WMI_CHAN_FLAG_ALLOW_VHT); 16807 else if (tchan_info->allow_ht) 16808 WMI_SET_CHANNEL_FLAG(chan_info, 16809 WMI_CHAN_FLAG_ALLOW_HT); 16810 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 16811 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 16812 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 16813 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 16814 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 16815 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 16816 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 16817 16818 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 16819 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 16820 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 16821 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 16822 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 16823 "tchan_info->reg_class_id: %d ," 16824 "tchan_info->maxregpower : %d ", __func__, 16825 tchan_info->is_chan_passive, tchan_info->dfs_set, 16826 tchan_info->allow_vht, tchan_info->allow_ht, 16827 tchan_info->antennamax, tchan_info->phy_mode, 16828 tchan_info->minpower, tchan_info->maxpower, 16829 tchan_info->maxregpower, tchan_info->reg_class_id, 16830 tchan_info->maxregpower); 16831 16832 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 16833 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 16834 16835 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16836 WMI_LOGE("%s: Failed to send\n", __func__); 16837 wmi_buf_free(buf); 16838 } 16839 16840 end: 16841 return qdf_status; 16842 } 16843 16844 /** 16845 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 16846 * @wmi_handle: wmi handle 16847 * @pdev_id: pdev id 16848 * 16849 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 16850 * 16851 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16852 */ 16853 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 16854 uint32_t pdev_id) 16855 { 16856 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 16857 wmi_buf_t buf; 16858 uint16_t len; 16859 QDF_STATUS ret; 16860 16861 len = sizeof(*cmd); 16862 buf = wmi_buf_alloc(wmi_handle, len); 16863 16864 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16865 16866 if (!buf) { 16867 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16868 return QDF_STATUS_E_NOMEM; 16869 } 16870 16871 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16872 wmi_buf_data(buf); 16873 16874 WMITLV_SET_HDR(&cmd->tlv_header, 16875 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16876 WMITLV_GET_STRUCT_TLVLEN( 16877 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16878 16879 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16880 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16881 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16882 if (QDF_IS_STATUS_ERROR(ret)) { 16883 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16884 __func__, ret, pdev_id); 16885 wmi_buf_free(buf); 16886 return QDF_STATUS_E_FAILURE; 16887 } 16888 16889 return QDF_STATUS_SUCCESS; 16890 } 16891 16892 /** 16893 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16894 * @wmi_handle: wmi handle 16895 * @pdev_id: pdev id 16896 * 16897 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16898 * 16899 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16900 */ 16901 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16902 uint32_t pdev_id) 16903 { 16904 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16905 wmi_buf_t buf; 16906 uint16_t len; 16907 QDF_STATUS ret; 16908 16909 len = sizeof(*cmd); 16910 buf = wmi_buf_alloc(wmi_handle, len); 16911 16912 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16913 16914 if (!buf) { 16915 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16916 return QDF_STATUS_E_NOMEM; 16917 } 16918 16919 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16920 wmi_buf_data(buf); 16921 16922 WMITLV_SET_HDR(&cmd->tlv_header, 16923 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16924 WMITLV_GET_STRUCT_TLVLEN( 16925 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16926 16927 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16928 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16929 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16930 if (QDF_IS_STATUS_ERROR(ret)) { 16931 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16932 __func__, ret, pdev_id); 16933 wmi_buf_free(buf); 16934 return QDF_STATUS_E_FAILURE; 16935 } 16936 16937 return QDF_STATUS_SUCCESS; 16938 } 16939 16940 /** 16941 * init_cmd_send_tlv() - send initialization cmd to fw 16942 * @wmi_handle: wmi handle 16943 * @param param: pointer to wmi init param 16944 * 16945 * Return: QDF_STATUS_SUCCESS for success or error code 16946 */ 16947 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16948 struct wmi_init_cmd_param *param) 16949 { 16950 wmi_buf_t buf; 16951 wmi_init_cmd_fixed_param *cmd; 16952 uint8_t *buf_ptr; 16953 wmi_resource_config *resource_cfg; 16954 wlan_host_memory_chunk *host_mem_chunks; 16955 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16956 uint16_t idx; 16957 int len; 16958 QDF_STATUS ret; 16959 16960 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16961 WMI_TLV_HDR_SIZE; 16962 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16963 16964 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16965 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16966 WMI_TLV_HDR_SIZE + 16967 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16968 16969 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16970 if (!buf) { 16971 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16972 return QDF_STATUS_E_FAILURE; 16973 } 16974 16975 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16976 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16977 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16978 16979 host_mem_chunks = (wlan_host_memory_chunk *) 16980 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16981 + WMI_TLV_HDR_SIZE); 16982 16983 WMITLV_SET_HDR(&cmd->tlv_header, 16984 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16985 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16986 16987 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16988 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16989 WMITLV_TAG_STRUC_wmi_resource_config, 16990 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16991 16992 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16993 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16994 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16995 WMITLV_GET_STRUCT_TLVLEN 16996 (wlan_host_memory_chunk)); 16997 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16998 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16999 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 17000 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 17001 "chunk %d len %d requested ,ptr 0x%x ", 17002 idx, host_mem_chunks[idx].size, 17003 host_mem_chunks[idx].ptr); 17004 } 17005 cmd->num_host_mem_chunks = param->num_mem_chunks; 17006 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 17007 17008 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 17009 WMITLV_TAG_ARRAY_STRUC, 17010 (sizeof(wlan_host_memory_chunk) * 17011 param->num_mem_chunks)); 17012 17013 /* Fill hw mode id config */ 17014 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 17015 17016 /* Fill fw_abi_vers */ 17017 copy_fw_abi_version_tlv(wmi_handle, cmd); 17018 17019 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 17020 if (QDF_IS_STATUS_ERROR(ret)) { 17021 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 17022 ret); 17023 wmi_buf_free(buf); 17024 } 17025 17026 return ret; 17027 17028 } 17029 17030 /** 17031 * send_addba_send_cmd_tlv() - send addba send command to fw 17032 * @wmi_handle: wmi handle 17033 * @param: pointer to delba send params 17034 * @macaddr: peer mac address 17035 * 17036 * Send WMI_ADDBA_SEND_CMDID command to firmware 17037 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17038 */ 17039 static QDF_STATUS 17040 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 17041 uint8_t macaddr[IEEE80211_ADDR_LEN], 17042 struct addba_send_params *param) 17043 { 17044 wmi_addba_send_cmd_fixed_param *cmd; 17045 wmi_buf_t buf; 17046 uint16_t len; 17047 QDF_STATUS ret; 17048 17049 len = sizeof(*cmd); 17050 17051 buf = wmi_buf_alloc(wmi_handle, len); 17052 if (!buf) { 17053 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17054 return QDF_STATUS_E_NOMEM; 17055 } 17056 17057 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 17058 17059 WMITLV_SET_HDR(&cmd->tlv_header, 17060 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 17061 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 17062 17063 cmd->vdev_id = param->vdev_id; 17064 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17065 cmd->tid = param->tidno; 17066 cmd->buffersize = param->buffersize; 17067 17068 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 17069 if (QDF_IS_STATUS_ERROR(ret)) { 17070 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17071 wmi_buf_free(buf); 17072 return QDF_STATUS_E_FAILURE; 17073 } 17074 17075 return QDF_STATUS_SUCCESS; 17076 } 17077 17078 /** 17079 * send_delba_send_cmd_tlv() - send delba send command to fw 17080 * @wmi_handle: wmi handle 17081 * @param: pointer to delba send params 17082 * @macaddr: peer mac address 17083 * 17084 * Send WMI_DELBA_SEND_CMDID command to firmware 17085 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17086 */ 17087 static QDF_STATUS 17088 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 17089 uint8_t macaddr[IEEE80211_ADDR_LEN], 17090 struct delba_send_params *param) 17091 { 17092 wmi_delba_send_cmd_fixed_param *cmd; 17093 wmi_buf_t buf; 17094 uint16_t len; 17095 QDF_STATUS ret; 17096 17097 len = sizeof(*cmd); 17098 17099 buf = wmi_buf_alloc(wmi_handle, len); 17100 if (!buf) { 17101 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17102 return QDF_STATUS_E_NOMEM; 17103 } 17104 17105 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 17106 17107 WMITLV_SET_HDR(&cmd->tlv_header, 17108 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 17109 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 17110 17111 cmd->vdev_id = param->vdev_id; 17112 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17113 cmd->tid = param->tidno; 17114 cmd->initiator = param->initiator; 17115 cmd->reasoncode = param->reasoncode; 17116 17117 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 17118 if (QDF_IS_STATUS_ERROR(ret)) { 17119 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17120 wmi_buf_free(buf); 17121 return QDF_STATUS_E_FAILURE; 17122 } 17123 17124 return QDF_STATUS_SUCCESS; 17125 } 17126 17127 /** 17128 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 17129 * to fw 17130 * @wmi_handle: wmi handle 17131 * @param: pointer to addba clearresp params 17132 * @macaddr: peer mac address 17133 * Return: 0 for success or error code 17134 */ 17135 static QDF_STATUS 17136 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 17137 uint8_t macaddr[IEEE80211_ADDR_LEN], 17138 struct addba_clearresponse_params *param) 17139 { 17140 wmi_addba_clear_resp_cmd_fixed_param *cmd; 17141 wmi_buf_t buf; 17142 uint16_t len; 17143 QDF_STATUS ret; 17144 17145 len = sizeof(*cmd); 17146 17147 buf = wmi_buf_alloc(wmi_handle, len); 17148 if (!buf) { 17149 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 17150 return QDF_STATUS_E_FAILURE; 17151 } 17152 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 17153 17154 WMITLV_SET_HDR(&cmd->tlv_header, 17155 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 17156 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 17157 17158 cmd->vdev_id = param->vdev_id; 17159 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17160 17161 ret = wmi_unified_cmd_send(wmi_handle, 17162 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 17163 if (QDF_IS_STATUS_ERROR(ret)) { 17164 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17165 wmi_buf_free(buf); 17166 return QDF_STATUS_E_FAILURE; 17167 } 17168 17169 return QDF_STATUS_SUCCESS; 17170 } 17171 17172 /** 17173 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 17174 * @wmi_handle: wmi handle 17175 * @bcn_ctrl_param: pointer to bcn_offload_control param 17176 * 17177 * Return: QDF_STATUS_SUCCESS for success or error code 17178 */ 17179 static 17180 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 17181 struct bcn_offload_control *bcn_ctrl_param) 17182 { 17183 wmi_buf_t buf; 17184 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 17185 QDF_STATUS ret; 17186 uint32_t len; 17187 17188 len = sizeof(*cmd); 17189 17190 buf = wmi_buf_alloc(wmi_handle, len); 17191 if (!buf) { 17192 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17193 return QDF_STATUS_E_FAILURE; 17194 } 17195 17196 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 17197 WMITLV_SET_HDR(&cmd->tlv_header, 17198 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 17199 WMITLV_GET_STRUCT_TLVLEN 17200 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 17201 cmd->vdev_id = bcn_ctrl_param->vdev_id; 17202 switch (bcn_ctrl_param->bcn_ctrl_op) { 17203 case BCN_OFFLD_CTRL_TX_DISABLE: 17204 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 17205 break; 17206 case BCN_OFFLD_CTRL_TX_ENABLE: 17207 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 17208 break; 17209 case BCN_OFFLD_CTRL_SWBA_DISABLE: 17210 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 17211 break; 17212 case BCN_OFFLD_CTRL_SWBA_ENABLE: 17213 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 17214 break; 17215 default: 17216 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 17217 bcn_ctrl_param->bcn_ctrl_op); 17218 wmi_buf_free(buf); 17219 return QDF_STATUS_E_FAILURE; 17220 break; 17221 } 17222 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17223 WMI_BCN_OFFLOAD_CTRL_CMDID); 17224 17225 if (QDF_IS_STATUS_ERROR(ret)) { 17226 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 17227 ret); 17228 wmi_buf_free(buf); 17229 } 17230 17231 return ret; 17232 } 17233 17234 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 17235 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 17236 struct nan_datapath_initiator_req *ndp_req) 17237 { 17238 uint16_t len; 17239 wmi_buf_t buf; 17240 uint8_t *tlv_ptr; 17241 QDF_STATUS status; 17242 wmi_channel *ch_tlv; 17243 wmi_ndp_initiator_req_fixed_param *cmd; 17244 uint32_t passphrase_len, service_name_len; 17245 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 17246 17247 /* 17248 * WMI command expects 4 byte alligned len: 17249 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17250 */ 17251 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 17252 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 17253 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 17254 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 17255 service_name_len = 17256 qdf_roundup(ndp_req->service_name.service_name_len, 4); 17257 /* allocated memory for fixed params as well as variable size data */ 17258 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 17259 + ndp_cfg_len + ndp_app_info_len + pmk_len 17260 + passphrase_len + service_name_len; 17261 17262 buf = wmi_buf_alloc(wmi_handle, len); 17263 if (!buf) { 17264 WMI_LOGE("wmi_buf_alloc failed"); 17265 return QDF_STATUS_E_NOMEM; 17266 } 17267 17268 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 17269 WMITLV_SET_HDR(&cmd->tlv_header, 17270 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 17271 WMITLV_GET_STRUCT_TLVLEN( 17272 wmi_ndp_initiator_req_fixed_param)); 17273 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 17274 cmd->transaction_id = ndp_req->transaction_id; 17275 cmd->service_instance_id = ndp_req->service_instance_id; 17276 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 17277 &cmd->peer_discovery_mac_addr); 17278 17279 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 17280 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 17281 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 17282 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 17283 cmd->nan_csid = ndp_req->ncs_sk_type; 17284 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 17285 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 17286 17287 ch_tlv = (wmi_channel *)&cmd[1]; 17288 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 17289 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 17290 ch_tlv->mhz = ndp_req->channel; 17291 tlv_ptr = (uint8_t *)&ch_tlv[1]; 17292 17293 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17294 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17295 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17296 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17297 17298 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17299 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17300 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 17301 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17302 17303 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17304 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 17305 cmd->nan_pmk_len); 17306 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17307 17308 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17309 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 17310 cmd->nan_passphrase_len); 17311 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17312 17313 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17314 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17315 ndp_req->service_name.service_name, 17316 cmd->nan_servicename_len); 17317 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17318 17319 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 17320 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 17321 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 17322 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 17323 cmd->peer_discovery_mac_addr.mac_addr31to0, 17324 cmd->peer_discovery_mac_addr.mac_addr47to32); 17325 17326 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 17327 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17328 ndp_req->ndp_config.ndp_cfg, 17329 ndp_req->ndp_config.ndp_cfg_len); 17330 17331 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 17332 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17333 ndp_req->ndp_info.ndp_app_info, 17334 ndp_req->ndp_info.ndp_app_info_len); 17335 17336 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17337 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17338 ndp_req->pmk.pmk, cmd->nan_pmk_len); 17339 17340 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17341 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17342 ndp_req->passphrase.passphrase, 17343 cmd->nan_passphrase_len); 17344 17345 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17346 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17347 ndp_req->service_name.service_name, 17348 cmd->nan_servicename_len); 17349 17350 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 17351 WMI_NDP_INITIATOR_REQ_CMDID); 17352 17353 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17354 WMI_NDP_INITIATOR_REQ_CMDID); 17355 if (QDF_IS_STATUS_ERROR(status)) { 17356 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 17357 wmi_buf_free(buf); 17358 } 17359 17360 return status; 17361 } 17362 17363 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 17364 struct nan_datapath_responder_req *req) 17365 { 17366 uint16_t len; 17367 wmi_buf_t buf; 17368 uint8_t *tlv_ptr; 17369 QDF_STATUS status; 17370 wmi_ndp_responder_req_fixed_param *cmd; 17371 uint32_t passphrase_len, service_name_len; 17372 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 17373 17374 vdev_id = wlan_vdev_get_id(req->vdev); 17375 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 17376 vdev_id, req->transaction_id, 17377 req->ndp_rsp, 17378 req->ndp_instance_id, 17379 req->ndp_info.ndp_app_info_len); 17380 17381 /* 17382 * WMI command expects 4 byte alligned len: 17383 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17384 */ 17385 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 17386 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 17387 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 17388 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 17389 service_name_len = 17390 qdf_roundup(req->service_name.service_name_len, 4); 17391 17392 /* allocated memory for fixed params as well as variable size data */ 17393 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 17394 + pmk_len + passphrase_len + service_name_len; 17395 17396 buf = wmi_buf_alloc(wmi_handle, len); 17397 if (!buf) { 17398 WMI_LOGE("wmi_buf_alloc failed"); 17399 return QDF_STATUS_E_NOMEM; 17400 } 17401 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 17402 WMITLV_SET_HDR(&cmd->tlv_header, 17403 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 17404 WMITLV_GET_STRUCT_TLVLEN( 17405 wmi_ndp_responder_req_fixed_param)); 17406 cmd->vdev_id = vdev_id; 17407 cmd->transaction_id = req->transaction_id; 17408 cmd->ndp_instance_id = req->ndp_instance_id; 17409 cmd->rsp_code = req->ndp_rsp; 17410 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 17411 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 17412 cmd->nan_pmk_len = req->pmk.pmk_len; 17413 cmd->nan_csid = req->ncs_sk_type; 17414 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 17415 cmd->nan_servicename_len = req->service_name.service_name_len; 17416 17417 tlv_ptr = (uint8_t *)&cmd[1]; 17418 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17419 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17420 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17421 17422 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17423 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17424 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17425 req->ndp_info.ndp_app_info, 17426 req->ndp_info.ndp_app_info_len); 17427 17428 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17429 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17430 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 17431 cmd->nan_pmk_len); 17432 17433 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17434 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17435 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17436 req->passphrase.passphrase, 17437 cmd->nan_passphrase_len); 17438 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17439 17440 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17441 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17442 req->service_name.service_name, 17443 cmd->nan_servicename_len); 17444 17445 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17446 17447 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 17448 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 17449 17450 WMI_LOGD("ndp_config len: %d", 17451 req->ndp_config.ndp_cfg_len); 17452 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17453 req->ndp_config.ndp_cfg, 17454 req->ndp_config.ndp_cfg_len); 17455 17456 WMI_LOGD("ndp_app_info len: %d", 17457 req->ndp_info.ndp_app_info_len); 17458 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17459 req->ndp_info.ndp_app_info, 17460 req->ndp_info.ndp_app_info_len); 17461 17462 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17463 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17464 req->pmk.pmk, cmd->nan_pmk_len); 17465 17466 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17467 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17468 req->passphrase.passphrase, 17469 cmd->nan_passphrase_len); 17470 17471 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17472 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17473 req->service_name.service_name, 17474 cmd->nan_servicename_len); 17475 17476 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 17477 WMI_NDP_RESPONDER_REQ_CMDID); 17478 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17479 WMI_NDP_RESPONDER_REQ_CMDID); 17480 if (QDF_IS_STATUS_ERROR(status)) { 17481 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 17482 wmi_buf_free(buf); 17483 } 17484 return status; 17485 } 17486 17487 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 17488 struct nan_datapath_end_req *req) 17489 { 17490 uint16_t len; 17491 wmi_buf_t buf; 17492 QDF_STATUS status; 17493 uint32_t ndp_end_req_len, i; 17494 wmi_ndp_end_req *ndp_end_req_lst; 17495 wmi_ndp_end_req_fixed_param *cmd; 17496 17497 /* len of tlv following fixed param */ 17498 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 17499 /* above comes out to 4 byte alligned already, no need of padding */ 17500 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 17501 buf = wmi_buf_alloc(wmi_handle, len); 17502 if (!buf) { 17503 WMI_LOGE("Malloc failed"); 17504 return QDF_STATUS_E_NOMEM; 17505 } 17506 17507 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 17508 WMITLV_SET_HDR(&cmd->tlv_header, 17509 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 17510 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 17511 17512 cmd->transaction_id = req->transaction_id; 17513 17514 /* set tlv pointer to end of fixed param */ 17515 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 17516 ndp_end_req_len); 17517 17518 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 17519 WMI_TLV_HDR_SIZE); 17520 for (i = 0; i < req->num_ndp_instances; i++) { 17521 WMITLV_SET_HDR(&ndp_end_req_lst[i], 17522 WMITLV_TAG_ARRAY_FIXED_STRUC, 17523 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 17524 17525 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 17526 } 17527 17528 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 17529 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17530 WMI_NDP_END_REQ_CMDID); 17531 if (QDF_IS_STATUS_ERROR(status)) { 17532 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 17533 wmi_buf_free(buf); 17534 } 17535 17536 return status; 17537 } 17538 17539 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 17540 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 17541 { 17542 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 17543 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 17544 17545 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 17546 fixed_params = event->fixed_param; 17547 17548 rsp->vdev = 17549 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17550 fixed_params->vdev_id, 17551 WLAN_NAN_ID); 17552 if (!rsp->vdev) { 17553 WMI_LOGE("vdev is null"); 17554 return QDF_STATUS_E_INVAL; 17555 } 17556 17557 rsp->transaction_id = fixed_params->transaction_id; 17558 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17559 rsp->status = fixed_params->rsp_status; 17560 rsp->reason = fixed_params->reason_code; 17561 17562 return QDF_STATUS_SUCCESS; 17563 } 17564 17565 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 17566 uint8_t *data, struct nan_datapath_indication_event *rsp) 17567 { 17568 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 17569 wmi_ndp_indication_event_fixed_param *fixed_params; 17570 17571 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 17572 fixed_params = 17573 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 17574 17575 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17576 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17577 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17578 return QDF_STATUS_E_INVAL; 17579 } 17580 17581 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17582 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17583 fixed_params->ndp_app_info_len, 17584 event->num_ndp_app_info); 17585 return QDF_STATUS_E_INVAL; 17586 } 17587 17588 rsp->vdev = 17589 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17590 fixed_params->vdev_id, 17591 WLAN_NAN_ID); 17592 if (!rsp->vdev) { 17593 WMI_LOGE("vdev is null"); 17594 return QDF_STATUS_E_INVAL; 17595 } 17596 rsp->service_instance_id = fixed_params->service_instance_id; 17597 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17598 rsp->role = fixed_params->self_ndp_role; 17599 rsp->policy = fixed_params->accept_policy; 17600 17601 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17602 rsp->peer_mac_addr.bytes); 17603 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 17604 rsp->peer_discovery_mac_addr.bytes); 17605 17606 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 17607 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 17608 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 17609 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 17610 fixed_params->service_instance_id, 17611 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 17612 fixed_params->accept_policy, 17613 fixed_params->nan_csid, fixed_params->nan_scid_len, 17614 rsp->peer_mac_addr.bytes, 17615 rsp->peer_discovery_mac_addr.bytes); 17616 17617 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17618 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17619 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17620 17621 WMI_LOGD("ndp_app_info - %d bytes", 17622 fixed_params->ndp_app_info_len); 17623 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17624 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17625 17626 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 17627 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17628 rsp->ncs_sk_type = fixed_params->nan_csid; 17629 rsp->scid.scid_len = fixed_params->nan_scid_len; 17630 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 17631 rsp->ndp_config.ndp_cfg_len); 17632 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17633 rsp->ndp_info.ndp_app_info_len); 17634 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 17635 WMI_LOGD("scid hex dump:"); 17636 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17637 rsp->scid.scid, rsp->scid.scid_len); 17638 17639 return QDF_STATUS_SUCCESS; 17640 } 17641 17642 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 17643 uint8_t *data, struct nan_datapath_confirm_event *rsp) 17644 { 17645 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 17646 wmi_ndp_confirm_event_fixed_param *fixed_params; 17647 17648 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 17649 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 17650 WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) recieved. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d", 17651 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 17652 fixed_params->ndp_instance_id, fixed_params->rsp_code, 17653 fixed_params->reason_code, 17654 fixed_params->num_active_ndps_on_peer); 17655 17656 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17657 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17658 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17659 return QDF_STATUS_E_INVAL; 17660 } 17661 17662 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17663 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17664 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17665 17666 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17667 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17668 fixed_params->ndp_app_info_len, 17669 event->num_ndp_app_info); 17670 return QDF_STATUS_E_INVAL; 17671 } 17672 17673 WMI_LOGD("ndp_app_info - %d bytes", 17674 fixed_params->ndp_app_info_len); 17675 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17676 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17677 17678 rsp->vdev = 17679 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17680 fixed_params->vdev_id, 17681 WLAN_NAN_ID); 17682 if (!rsp->vdev) { 17683 WMI_LOGE("vdev is null"); 17684 return QDF_STATUS_E_INVAL; 17685 } 17686 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17687 rsp->rsp_code = fixed_params->rsp_code; 17688 rsp->reason_code = fixed_params->reason_code; 17689 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 17690 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17691 rsp->peer_ndi_mac_addr.bytes); 17692 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17693 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17694 rsp->ndp_info.ndp_app_info_len); 17695 17696 return QDF_STATUS_SUCCESS; 17697 } 17698 17699 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 17700 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 17701 { 17702 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17703 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17704 17705 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17706 fixed_params = event->fixed_param; 17707 17708 WMI_LOGD("WMI_NDP_RESPONDER_RSP_EVENTID(0x%X) received. vdev_id: %d, peer_mac_addr: %pM,transaction_id: %d, status_code %d, reason_code: %d, create_peer: %d", 17709 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17710 rsp->peer_mac_addr.bytes, rsp->transaction_id, 17711 rsp->status, rsp->reason, rsp->create_peer); 17712 17713 rsp->vdev = 17714 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17715 fixed_params->vdev_id, 17716 WLAN_NAN_ID); 17717 if (!rsp->vdev) { 17718 WMI_LOGE("vdev is null"); 17719 return QDF_STATUS_E_INVAL; 17720 } 17721 rsp->transaction_id = fixed_params->transaction_id; 17722 rsp->reason = fixed_params->reason_code; 17723 rsp->status = fixed_params->rsp_status; 17724 rsp->create_peer = fixed_params->create_peer; 17725 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17726 rsp->peer_mac_addr.bytes); 17727 17728 return QDF_STATUS_SUCCESS; 17729 } 17730 17731 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17732 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 17733 { 17734 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17735 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17736 17737 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17738 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17739 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d", 17740 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17741 fixed_params->rsp_status, fixed_params->reason_code); 17742 17743 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17744 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17745 if (!rsp->vdev) { 17746 WMI_LOGE("vdev is null"); 17747 return QDF_STATUS_E_INVAL; 17748 } 17749 rsp->transaction_id = fixed_params->transaction_id; 17750 rsp->reason = fixed_params->reason_code; 17751 rsp->status = fixed_params->rsp_status; 17752 17753 return QDF_STATUS_SUCCESS; 17754 } 17755 17756 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17757 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17758 { 17759 uint32_t i, buf_size; 17760 wmi_ndp_end_indication *ind; 17761 struct qdf_mac_addr peer_addr; 17762 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17763 17764 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17765 ind = event->ndp_end_indication_list; 17766 17767 if (event->num_ndp_end_indication_list == 0) { 17768 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17769 return QDF_STATUS_E_INVAL; 17770 } 17771 17772 WMI_LOGD("number of ndp instances = %d", 17773 event->num_ndp_end_indication_list); 17774 17775 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17776 sizeof((*rsp)->ndp_map[0]))) { 17777 WMI_LOGE("num_ndp_end_ind_list %d too large", 17778 event->num_ndp_end_indication_list); 17779 return QDF_STATUS_E_INVAL; 17780 } 17781 17782 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17783 sizeof((*rsp)->ndp_map[0]); 17784 *rsp = qdf_mem_malloc(buf_size); 17785 if (!(*rsp)) { 17786 WMI_LOGE("Failed to allocate memory"); 17787 return QDF_STATUS_E_NOMEM; 17788 } 17789 17790 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17791 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17792 if (!(*rsp)->vdev) { 17793 WMI_LOGE("vdev is null"); 17794 qdf_mem_free(*rsp); 17795 *rsp = NULL; 17796 return QDF_STATUS_E_INVAL; 17797 } 17798 17799 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17800 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17801 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17802 peer_addr.bytes); 17803 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17804 i, ind[i].type, ind[i].reason_code, 17805 ind[i].ndp_instance_id, 17806 ind[i].num_active_ndps_on_peer); 17807 /* Add each instance entry to the list */ 17808 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17809 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17810 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17811 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17812 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17813 ind[i].num_active_ndps_on_peer; 17814 (*rsp)->ndp_map[i].type = ind[i].type; 17815 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17816 } 17817 17818 return QDF_STATUS_SUCCESS; 17819 } 17820 #endif 17821 17822 #ifdef QCA_SUPPORT_CP_STATS 17823 /** 17824 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17825 * @wmi_handle: wma handle 17826 * @evt_buf: event buffer 17827 * @out_buff: buffer to populated after stats extraction 17828 * 17829 * Return: status of operation 17830 */ 17831 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17832 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17833 { 17834 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17835 wmi_congestion_stats *congestion_stats; 17836 17837 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17838 congestion_stats = param_buf->congestion_stats; 17839 if (!congestion_stats) { 17840 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17841 return QDF_STATUS_E_INVAL; 17842 } 17843 17844 out_buff->vdev_id = congestion_stats->vdev_id; 17845 out_buff->congestion = congestion_stats->congestion; 17846 17847 WMI_LOGD("%s: cca stats event processed", __func__); 17848 return QDF_STATUS_SUCCESS; 17849 } 17850 #endif /* QCA_SUPPORT_CP_STATS */ 17851 17852 /** 17853 * save_service_bitmap_tlv() - save service bitmap 17854 * @wmi_handle: wmi handle 17855 * @param evt_buf: pointer to event buffer 17856 * @param bitmap_buf: bitmap buffer, for converged legacy support 17857 * 17858 * Return: QDF_STATUS 17859 */ 17860 static 17861 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17862 void *bitmap_buf) 17863 { 17864 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17865 struct wmi_soc *soc = wmi_handle->soc; 17866 17867 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17868 17869 /* If it is already allocated, use that buffer. This can happen 17870 * during target stop/start scenarios where host allocation is skipped. 17871 */ 17872 if (!soc->wmi_service_bitmap) { 17873 soc->wmi_service_bitmap = 17874 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17875 if (!soc->wmi_service_bitmap) { 17876 WMI_LOGE("Failed memory allocation for service bitmap"); 17877 return QDF_STATUS_E_NOMEM; 17878 } 17879 } 17880 17881 qdf_mem_copy(soc->wmi_service_bitmap, 17882 param_buf->wmi_service_bitmap, 17883 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17884 17885 if (bitmap_buf) 17886 qdf_mem_copy(bitmap_buf, 17887 param_buf->wmi_service_bitmap, 17888 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17889 17890 return QDF_STATUS_SUCCESS; 17891 } 17892 17893 /** 17894 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17895 * @wmi_handle: wmi handle 17896 * @param evt_buf: pointer to event buffer 17897 * @param bitmap_buf: bitmap buffer, for converged legacy support 17898 * 17899 * Return: QDF_STATUS 17900 */ 17901 static 17902 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17903 void *bitmap_buf) 17904 { 17905 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17906 wmi_service_available_event_fixed_param *ev; 17907 struct wmi_soc *soc = wmi_handle->soc; 17908 17909 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17910 17911 ev = param_buf->fixed_param; 17912 17913 /* If it is already allocated, use that buffer. This can happen 17914 * during target stop/start scenarios where host allocation is skipped. 17915 */ 17916 if (!soc->wmi_ext_service_bitmap) { 17917 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17918 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17919 if (!soc->wmi_ext_service_bitmap) { 17920 WMI_LOGE("Failed memory allocation for service bitmap"); 17921 return QDF_STATUS_E_NOMEM; 17922 } 17923 } 17924 17925 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17926 ev->wmi_service_segment_bitmap, 17927 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17928 17929 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17930 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17931 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17932 17933 if (bitmap_buf) 17934 qdf_mem_copy(bitmap_buf, 17935 soc->wmi_ext_service_bitmap, 17936 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17937 17938 return QDF_STATUS_SUCCESS; 17939 } 17940 /** 17941 * is_service_enabled_tlv() - Check if service enabled 17942 * @param wmi_handle: wmi handle 17943 * @param service_id: service identifier 17944 * 17945 * Return: 1 enabled, 0 disabled 17946 */ 17947 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17948 uint32_t service_id) 17949 { 17950 struct wmi_soc *soc = wmi_handle->soc; 17951 17952 if (!soc->wmi_service_bitmap) { 17953 WMI_LOGE("WMI service bit map is not saved yet\n"); 17954 return false; 17955 } 17956 17957 /* if wmi_service_enabled was received with extended bitmap, 17958 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17959 */ 17960 if (soc->wmi_ext_service_bitmap) 17961 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17962 soc->wmi_ext_service_bitmap, 17963 service_id); 17964 17965 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17966 service_id); 17967 } 17968 17969 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17970 struct wlan_psoc_target_capability_info *cap) 17971 { 17972 /* except LDPC all flags are common betwen legacy and here 17973 * also IBFEER is not defined for TLV 17974 */ 17975 cap->ht_cap_info |= ev_target_cap & ( 17976 WMI_HT_CAP_ENABLED 17977 | WMI_HT_CAP_HT20_SGI 17978 | WMI_HT_CAP_DYNAMIC_SMPS 17979 | WMI_HT_CAP_TX_STBC 17980 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17981 | WMI_HT_CAP_RX_STBC 17982 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17983 | WMI_HT_CAP_LDPC 17984 | WMI_HT_CAP_L_SIG_TXOP_PROT 17985 | WMI_HT_CAP_MPDU_DENSITY 17986 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17987 | WMI_HT_CAP_HT40_SGI); 17988 if (ev_target_cap & WMI_HT_CAP_LDPC) 17989 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17990 WMI_HOST_HT_CAP_TX_LDPC; 17991 } 17992 /** 17993 * extract_service_ready_tlv() - extract service ready event 17994 * @wmi_handle: wmi handle 17995 * @param evt_buf: pointer to received event buffer 17996 * @param cap: pointer to hold target capability information extracted from even 17997 * 17998 * Return: QDF_STATUS_SUCCESS for success or error code 17999 */ 18000 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 18001 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 18002 { 18003 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18004 wmi_service_ready_event_fixed_param *ev; 18005 18006 18007 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18008 18009 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18010 if (!ev) { 18011 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18012 return QDF_STATUS_E_FAILURE; 18013 } 18014 18015 cap->phy_capability = ev->phy_capability; 18016 cap->max_frag_entry = ev->max_frag_entry; 18017 cap->num_rf_chains = ev->num_rf_chains; 18018 copy_ht_cap_info(ev->ht_cap_info, cap); 18019 cap->vht_cap_info = ev->vht_cap_info; 18020 cap->vht_supp_mcs = ev->vht_supp_mcs; 18021 cap->hw_min_tx_power = ev->hw_min_tx_power; 18022 cap->hw_max_tx_power = ev->hw_max_tx_power; 18023 cap->sys_cap_info = ev->sys_cap_info; 18024 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 18025 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 18026 cap->max_num_scan_channels = ev->max_num_scan_channels; 18027 cap->max_supported_macs = ev->max_supported_macs; 18028 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 18029 cap->txrx_chainmask = ev->txrx_chainmask; 18030 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 18031 cap->num_msdu_desc = ev->num_msdu_desc; 18032 cap->fw_version = ev->fw_build_vers; 18033 /* fw_version_1 is not available in TLV. */ 18034 cap->fw_version_1 = 0; 18035 18036 return QDF_STATUS_SUCCESS; 18037 } 18038 18039 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 18040 * to host internal WMI_HOST_REGDMN_MODE values. 18041 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 18042 * host currently. Add this in the future if required. 18043 * 11AX (Phase II) : 11ax related values are not currently 18044 * advertised separately by FW. As part of phase II regulatory bring-up, 18045 * finalize the advertisement mechanism. 18046 * @target_wireless_mode: target wireless mode received in message 18047 * 18048 * Return: returns the host internal wireless mode. 18049 */ 18050 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 18051 { 18052 18053 uint32_t wireless_modes = 0; 18054 18055 if (target_wireless_mode & REGDMN_MODE_11A) 18056 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 18057 18058 if (target_wireless_mode & REGDMN_MODE_TURBO) 18059 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 18060 18061 if (target_wireless_mode & REGDMN_MODE_11B) 18062 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 18063 18064 if (target_wireless_mode & REGDMN_MODE_PUREG) 18065 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 18066 18067 if (target_wireless_mode & REGDMN_MODE_11G) 18068 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 18069 18070 if (target_wireless_mode & REGDMN_MODE_108G) 18071 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 18072 18073 if (target_wireless_mode & REGDMN_MODE_108A) 18074 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 18075 18076 if (target_wireless_mode & REGDMN_MODE_XR) 18077 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 18078 18079 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 18080 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 18081 18082 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 18083 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 18084 18085 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 18086 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 18087 18088 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 18089 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 18090 18091 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 18092 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 18093 18094 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 18095 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 18096 18097 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 18098 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 18099 18100 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 18101 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 18102 18103 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 18104 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 18105 18106 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 18107 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 18108 18109 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 18110 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 18111 18112 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 18113 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 18114 18115 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 18116 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 18117 18118 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 18119 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 18120 18121 return wireless_modes; 18122 } 18123 18124 /** 18125 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 18126 * @wmi_handle: wmi handle 18127 * @param evt_buf: Pointer to event buffer 18128 * @param cap: pointer to hold HAL reg capabilities 18129 * 18130 * Return: QDF_STATUS_SUCCESS for success or error code 18131 */ 18132 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 18133 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 18134 { 18135 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18136 18137 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18138 18139 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 18140 sizeof(uint32_t)), 18141 sizeof(struct wlan_psoc_hal_reg_capability)); 18142 18143 cap->wireless_modes = convert_wireless_modes_tlv( 18144 param_buf->hal_reg_capabilities->wireless_modes); 18145 18146 return QDF_STATUS_SUCCESS; 18147 } 18148 18149 /** 18150 * extract_host_mem_req_tlv() - Extract host memory request event 18151 * @wmi_handle: wmi handle 18152 * @param evt_buf: pointer to event buffer 18153 * @param num_entries: pointer to hold number of entries requested 18154 * 18155 * Return: Number of entries requested 18156 */ 18157 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 18158 void *evt_buf, uint8_t *num_entries) 18159 { 18160 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18161 wmi_service_ready_event_fixed_param *ev; 18162 18163 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18164 18165 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18166 if (!ev) { 18167 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18168 return NULL; 18169 } 18170 18171 *num_entries = ev->num_mem_reqs; 18172 18173 return (host_mem_req *)param_buf->mem_reqs; 18174 } 18175 18176 /** 18177 * save_fw_version_in_service_ready_tlv() - Save fw version in service 18178 * ready function 18179 * @wmi_handle: wmi handle 18180 * @param evt_buf: pointer to event buffer 18181 * 18182 * Return: QDF_STATUS_SUCCESS for success or error code 18183 */ 18184 static QDF_STATUS 18185 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 18186 { 18187 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18188 wmi_service_ready_event_fixed_param *ev; 18189 18190 18191 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18192 18193 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18194 if (!ev) { 18195 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18196 return QDF_STATUS_E_FAILURE; 18197 } 18198 18199 /*Save fw version from service ready message */ 18200 /*This will be used while sending INIT message */ 18201 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 18202 sizeof(wmi_handle->fw_abi_version)); 18203 18204 return QDF_STATUS_SUCCESS; 18205 } 18206 18207 /** 18208 * ready_extract_init_status_tlv() - Extract init status from ready event 18209 * @wmi_handle: wmi handle 18210 * @param evt_buf: Pointer to event buffer 18211 * 18212 * Return: ready status 18213 */ 18214 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 18215 void *evt_buf) 18216 { 18217 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18218 wmi_ready_event_fixed_param *ev = NULL; 18219 18220 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18221 ev = param_buf->fixed_param; 18222 18223 qdf_print("%s:%d\n", __func__, ev->status); 18224 18225 return ev->status; 18226 } 18227 18228 /** 18229 * ready_extract_mac_addr_tlv() - extract mac address from ready event 18230 * @wmi_handle: wmi handle 18231 * @param evt_buf: pointer to event buffer 18232 * @param macaddr: Pointer to hold MAC address 18233 * 18234 * Return: QDF_STATUS_SUCCESS for success or error code 18235 */ 18236 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 18237 void *evt_buf, uint8_t *macaddr) 18238 { 18239 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18240 wmi_ready_event_fixed_param *ev = NULL; 18241 18242 18243 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18244 ev = param_buf->fixed_param; 18245 18246 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 18247 18248 return QDF_STATUS_SUCCESS; 18249 } 18250 18251 /** 18252 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 18253 * @wmi_handle: wmi handle 18254 * @param evt_buf: pointer to event buffer 18255 * @param macaddr: Pointer to hold number of MAC addresses 18256 * 18257 * Return: Pointer to addr list 18258 */ 18259 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 18260 void *evt_buf, uint8_t *num_mac) 18261 { 18262 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18263 wmi_ready_event_fixed_param *ev = NULL; 18264 18265 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18266 ev = param_buf->fixed_param; 18267 18268 *num_mac = ev->num_extra_mac_addr; 18269 18270 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 18271 } 18272 18273 /** 18274 * extract_ready_params_tlv() - Extract data from ready event apart from 18275 * status, macaddr and version. 18276 * @wmi_handle: Pointer to WMI handle. 18277 * @evt_buf: Pointer to Ready event buffer. 18278 * @ev_param: Pointer to host defined struct to copy the data from event. 18279 * 18280 * Return: QDF_STATUS_SUCCESS on success. 18281 */ 18282 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 18283 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 18284 { 18285 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18286 wmi_ready_event_fixed_param *ev = NULL; 18287 18288 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18289 ev = param_buf->fixed_param; 18290 18291 ev_param->status = ev->status; 18292 ev_param->num_dscp_table = ev->num_dscp_table; 18293 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 18294 ev_param->num_total_peer = ev->num_total_peers; 18295 ev_param->num_extra_peer = ev->num_extra_peers; 18296 /* Agile_cap in ready event is not supported in TLV target */ 18297 ev_param->agile_capability = false; 18298 18299 return QDF_STATUS_SUCCESS; 18300 } 18301 18302 /** 18303 * extract_dbglog_data_len_tlv() - extract debuglog data length 18304 * @wmi_handle: wmi handle 18305 * @param evt_buf: pointer to event buffer 18306 * 18307 * Return: length 18308 */ 18309 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 18310 void *evt_buf, uint32_t *len) 18311 { 18312 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 18313 18314 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 18315 18316 *len = param_buf->num_bufp; 18317 18318 return param_buf->bufp; 18319 } 18320 18321 /** 18322 * extract_vdev_start_resp_tlv() - extract vdev start response 18323 * @wmi_handle: wmi handle 18324 * @param evt_buf: pointer to event buffer 18325 * @param vdev_rsp: Pointer to hold vdev response 18326 * 18327 * Return: QDF_STATUS_SUCCESS for success or error code 18328 */ 18329 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 18330 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 18331 { 18332 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 18333 wmi_vdev_start_response_event_fixed_param *ev; 18334 18335 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 18336 if (!param_buf) { 18337 qdf_print("Invalid start response event buffer\n"); 18338 return QDF_STATUS_E_INVAL; 18339 } 18340 18341 ev = param_buf->fixed_param; 18342 if (!ev) { 18343 qdf_print("Invalid start response event buffer\n"); 18344 return QDF_STATUS_E_INVAL; 18345 } 18346 18347 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 18348 18349 vdev_rsp->vdev_id = ev->vdev_id; 18350 vdev_rsp->requestor_id = ev->requestor_id; 18351 switch (ev->resp_type) { 18352 case WMI_VDEV_START_RESP_EVENT: 18353 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 18354 break; 18355 case WMI_VDEV_RESTART_RESP_EVENT: 18356 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 18357 break; 18358 default: 18359 qdf_print("Invalid start response event buffer\n"); 18360 break; 18361 }; 18362 vdev_rsp->status = ev->status; 18363 vdev_rsp->chain_mask = ev->chain_mask; 18364 vdev_rsp->smps_mode = ev->smps_mode; 18365 vdev_rsp->mac_id = ev->mac_id; 18366 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 18367 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 18368 18369 return QDF_STATUS_SUCCESS; 18370 } 18371 18372 /** 18373 * extract_vdev_delete_resp_tlv() - extract vdev delete response 18374 * @wmi_handle: wmi handle 18375 * @param evt_buf: pointer to event buffer 18376 * @param delete_rsp: Pointer to hold vdev delete response 18377 * 18378 * Return: QDF_STATUS_SUCCESS for success or error code 18379 */ 18380 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 18381 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 18382 { 18383 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 18384 wmi_vdev_delete_resp_event_fixed_param *ev; 18385 18386 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 18387 if (!param_buf) { 18388 WMI_LOGE("Invalid vdev delete response event buffer\n"); 18389 return QDF_STATUS_E_INVAL; 18390 } 18391 18392 ev = param_buf->fixed_param; 18393 if (!ev) { 18394 WMI_LOGE("Invalid vdev delete response event\n"); 18395 return QDF_STATUS_E_INVAL; 18396 } 18397 18398 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 18399 delete_rsp->vdev_id = ev->vdev_id; 18400 18401 return QDF_STATUS_SUCCESS; 18402 } 18403 18404 18405 /** 18406 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 18407 * @wmi_handle: wmi handle 18408 * @param evt_buf: pointer to event buffer 18409 * @param num_vdevs: Pointer to hold num vdev 18410 * 18411 * Return: QDF_STATUS_SUCCESS for success or error code 18412 */ 18413 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18414 void *evt_buf, uint32_t *num_vdevs) 18415 { 18416 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18417 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18418 uint32_t vdev_map; 18419 18420 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 18421 if (!param_buf) { 18422 qdf_print("Invalid tbtt update ext event buffer\n"); 18423 return QDF_STATUS_E_INVAL; 18424 } 18425 tbtt_offset_event = param_buf->fixed_param; 18426 vdev_map = tbtt_offset_event->vdev_map; 18427 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18428 18429 return QDF_STATUS_SUCCESS; 18430 } 18431 18432 /** 18433 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 18434 * @wmi_handle: wmi handle 18435 * @param evt_buf: pointer to event buffer 18436 * @param num_vdevs: Pointer to hold num vdev 18437 * 18438 * Return: QDF_STATUS_SUCCESS for success or error code 18439 */ 18440 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18441 void *evt_buf, uint32_t *num_vdevs) 18442 { 18443 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18444 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 18445 18446 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18447 if (!param_buf) { 18448 qdf_print("Invalid tbtt update ext event buffer\n"); 18449 return QDF_STATUS_E_INVAL; 18450 } 18451 tbtt_offset_ext_event = param_buf->fixed_param; 18452 18453 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 18454 18455 return QDF_STATUS_SUCCESS; 18456 } 18457 18458 /** 18459 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 18460 * @wmi_handle: wmi handle 18461 * @param evt_buf: pointer to event buffer 18462 * @param idx: Index refering to a vdev 18463 * @param tbtt_param: Pointer to tbttoffset event param 18464 * 18465 * Return: QDF_STATUS_SUCCESS for success or error code 18466 */ 18467 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 18468 void *evt_buf, uint8_t idx, 18469 struct tbttoffset_params *tbtt_param) 18470 { 18471 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18472 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18473 uint32_t vdev_map; 18474 18475 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 18476 if (!param_buf) { 18477 qdf_print("Invalid tbtt update event buffer\n"); 18478 return QDF_STATUS_E_INVAL; 18479 } 18480 18481 tbtt_offset_event = param_buf->fixed_param; 18482 vdev_map = tbtt_offset_event->vdev_map; 18483 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 18484 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 18485 return QDF_STATUS_E_INVAL; 18486 tbtt_param->tbttoffset = 18487 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 18488 18489 return QDF_STATUS_SUCCESS; 18490 } 18491 18492 /** 18493 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 18494 * @wmi_handle: wmi handle 18495 * @param evt_buf: pointer to event buffer 18496 * @param idx: Index refering to a vdev 18497 * @param tbtt_param: Pointer to tbttoffset event param 18498 * 18499 * Return: QDF_STATUS_SUCCESS for success or error code 18500 */ 18501 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 18502 void *evt_buf, uint8_t idx, 18503 struct tbttoffset_params *tbtt_param) 18504 { 18505 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18506 wmi_tbtt_offset_info *tbtt_offset_info; 18507 18508 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18509 if (!param_buf) { 18510 qdf_print("Invalid tbtt update event buffer\n"); 18511 return QDF_STATUS_E_INVAL; 18512 } 18513 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 18514 18515 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 18516 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 18517 18518 return QDF_STATUS_SUCCESS; 18519 } 18520 18521 /** 18522 * extract_mgmt_rx_params_tlv() - extract management rx params from event 18523 * @wmi_handle: wmi handle 18524 * @param evt_buf: pointer to event buffer 18525 * @param hdr: Pointer to hold header 18526 * @param bufp: Pointer to hold pointer to rx param buffer 18527 * 18528 * Return: QDF_STATUS_SUCCESS for success or error code 18529 */ 18530 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 18531 void *evt_buf, struct mgmt_rx_event_params *hdr, 18532 uint8_t **bufp) 18533 { 18534 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 18535 wmi_mgmt_rx_hdr *ev_hdr = NULL; 18536 int i; 18537 18538 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 18539 if (!param_tlvs) { 18540 WMI_LOGE("Get NULL point message from FW"); 18541 return QDF_STATUS_E_INVAL; 18542 } 18543 18544 ev_hdr = param_tlvs->hdr; 18545 if (!hdr) { 18546 WMI_LOGE("Rx event is NULL"); 18547 return QDF_STATUS_E_INVAL; 18548 } 18549 18550 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18551 ev_hdr->pdev_id); 18552 18553 hdr->channel = ev_hdr->channel; 18554 hdr->snr = ev_hdr->snr; 18555 hdr->rate = ev_hdr->rate; 18556 hdr->phy_mode = ev_hdr->phy_mode; 18557 hdr->buf_len = ev_hdr->buf_len; 18558 hdr->status = ev_hdr->status; 18559 hdr->flags = ev_hdr->flags; 18560 hdr->rssi = ev_hdr->rssi; 18561 hdr->tsf_delta = ev_hdr->tsf_delta; 18562 for (i = 0; i < ATH_MAX_ANTENNA; i++) 18563 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 18564 18565 *bufp = param_tlvs->bufp; 18566 18567 return QDF_STATUS_SUCCESS; 18568 } 18569 18570 /** 18571 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 18572 * @wmi_handle: wmi handle 18573 * @param evt_buf: pointer to event buffer 18574 * @param vdev_id: Pointer to hold vdev identifier 18575 * 18576 * Return: QDF_STATUS_SUCCESS for success or error code 18577 */ 18578 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 18579 void *evt_buf, uint32_t *vdev_id) 18580 { 18581 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 18582 wmi_vdev_stopped_event_fixed_param *resp_event; 18583 18584 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 18585 if (!param_buf) { 18586 WMI_LOGE("Invalid event buffer"); 18587 return QDF_STATUS_E_INVAL; 18588 } 18589 resp_event = param_buf->fixed_param; 18590 *vdev_id = resp_event->vdev_id; 18591 18592 return QDF_STATUS_SUCCESS; 18593 } 18594 18595 /** 18596 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 18597 * @wmi_handle: wmi handle 18598 * @param evt_buf: pointer to event buffer 18599 * @param param: Pointer to hold roam param 18600 * 18601 * Return: QDF_STATUS_SUCCESS for success or error code 18602 */ 18603 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 18604 void *evt_buf, wmi_host_roam_event *param) 18605 { 18606 WMI_ROAM_EVENTID_param_tlvs *param_buf; 18607 wmi_roam_event_fixed_param *evt; 18608 18609 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 18610 if (!param_buf) { 18611 WMI_LOGE("Invalid roam event buffer"); 18612 return QDF_STATUS_E_INVAL; 18613 } 18614 18615 evt = param_buf->fixed_param; 18616 qdf_mem_zero(param, sizeof(*param)); 18617 18618 param->vdev_id = evt->vdev_id; 18619 param->reason = evt->reason; 18620 param->rssi = evt->rssi; 18621 18622 return QDF_STATUS_SUCCESS; 18623 } 18624 18625 /** 18626 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 18627 * @wmi_handle: wmi handle 18628 * @param evt_buf: pointer to event buffer 18629 * @param param: Pointer to hold vdev scan param 18630 * 18631 * Return: QDF_STATUS_SUCCESS for success or error code 18632 */ 18633 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18634 void *evt_buf, struct scan_event *param) 18635 { 18636 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18637 wmi_scan_event_fixed_param *evt = NULL; 18638 18639 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18640 evt = param_buf->fixed_param; 18641 18642 qdf_mem_zero(param, sizeof(*param)); 18643 18644 switch (evt->event) { 18645 case WMI_SCAN_EVENT_STARTED: 18646 param->type = SCAN_EVENT_TYPE_STARTED; 18647 break; 18648 case WMI_SCAN_EVENT_COMPLETED: 18649 param->type = SCAN_EVENT_TYPE_COMPLETED; 18650 break; 18651 case WMI_SCAN_EVENT_BSS_CHANNEL: 18652 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18653 break; 18654 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18655 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18656 break; 18657 case WMI_SCAN_EVENT_DEQUEUED: 18658 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18659 break; 18660 case WMI_SCAN_EVENT_PREEMPTED: 18661 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18662 break; 18663 case WMI_SCAN_EVENT_START_FAILED: 18664 param->type = SCAN_EVENT_TYPE_START_FAILED; 18665 break; 18666 case WMI_SCAN_EVENT_RESTARTED: 18667 param->type = SCAN_EVENT_TYPE_RESTARTED; 18668 break; 18669 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18670 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18671 break; 18672 case WMI_SCAN_EVENT_MAX: 18673 default: 18674 param->type = SCAN_EVENT_TYPE_MAX; 18675 break; 18676 }; 18677 18678 switch (evt->reason) { 18679 case WMI_SCAN_REASON_NONE: 18680 param->reason = SCAN_REASON_NONE; 18681 break; 18682 case WMI_SCAN_REASON_COMPLETED: 18683 param->reason = SCAN_REASON_COMPLETED; 18684 break; 18685 case WMI_SCAN_REASON_CANCELLED: 18686 param->reason = SCAN_REASON_CANCELLED; 18687 break; 18688 case WMI_SCAN_REASON_PREEMPTED: 18689 param->reason = SCAN_REASON_PREEMPTED; 18690 break; 18691 case WMI_SCAN_REASON_TIMEDOUT: 18692 param->reason = SCAN_REASON_TIMEDOUT; 18693 break; 18694 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18695 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18696 break; 18697 case WMI_SCAN_REASON_SUSPENDED: 18698 param->reason = SCAN_REASON_SUSPENDED; 18699 break; 18700 case WMI_SCAN_REASON_MAX: 18701 param->reason = SCAN_REASON_MAX; 18702 break; 18703 default: 18704 param->reason = SCAN_REASON_MAX; 18705 break; 18706 }; 18707 18708 param->chan_freq = evt->channel_freq; 18709 param->requester = evt->requestor; 18710 param->scan_id = evt->scan_id; 18711 param->vdev_id = evt->vdev_id; 18712 param->timestamp = evt->tsf_timestamp; 18713 18714 return QDF_STATUS_SUCCESS; 18715 } 18716 18717 #ifdef CONVERGED_TDLS_ENABLE 18718 /** 18719 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18720 * @wmi_handle: wmi handle 18721 * @param evt_buf: pointer to event buffer 18722 * @param param: Pointer to hold vdev tdls param 18723 * 18724 * Return: QDF_STATUS_SUCCESS for success or error code 18725 */ 18726 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18727 void *evt_buf, struct tdls_event_info *param) 18728 { 18729 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18730 wmi_tdls_peer_event_fixed_param *evt; 18731 18732 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18733 if (!param_buf) { 18734 WMI_LOGE("%s: NULL param_buf", __func__); 18735 return QDF_STATUS_E_NULL_VALUE; 18736 } 18737 18738 evt = param_buf->fixed_param; 18739 18740 qdf_mem_zero(param, sizeof(*param)); 18741 18742 param->vdev_id = evt->vdev_id; 18743 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18744 param->peermac.bytes); 18745 switch (evt->peer_status) { 18746 case WMI_TDLS_SHOULD_DISCOVER: 18747 param->message_type = TDLS_SHOULD_DISCOVER; 18748 break; 18749 case WMI_TDLS_SHOULD_TEARDOWN: 18750 param->message_type = TDLS_SHOULD_TEARDOWN; 18751 break; 18752 case WMI_TDLS_PEER_DISCONNECTED: 18753 param->message_type = TDLS_PEER_DISCONNECTED; 18754 break; 18755 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18756 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18757 break; 18758 default: 18759 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18760 __func__, evt->peer_status); 18761 return QDF_STATUS_E_INVAL; 18762 }; 18763 18764 switch (evt->peer_reason) { 18765 case WMI_TDLS_TEARDOWN_REASON_TX: 18766 param->peer_reason = TDLS_TEARDOWN_TX; 18767 break; 18768 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18769 param->peer_reason = TDLS_TEARDOWN_RSSI; 18770 break; 18771 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18772 param->peer_reason = TDLS_TEARDOWN_SCAN; 18773 break; 18774 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18775 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18776 break; 18777 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18778 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18779 break; 18780 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18781 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18782 break; 18783 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18784 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18785 break; 18786 case WMI_TDLS_ENTER_BUF_STA: 18787 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18788 break; 18789 case WMI_TDLS_EXIT_BUF_STA: 18790 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18791 break; 18792 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18793 param->peer_reason = TDLS_ENTER_BT_BUSY; 18794 break; 18795 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18796 param->peer_reason = TDLS_EXIT_BT_BUSY; 18797 break; 18798 case WMI_TDLS_SCAN_STARTED_EVENT: 18799 param->peer_reason = TDLS_SCAN_STARTED; 18800 break; 18801 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18802 param->peer_reason = TDLS_SCAN_COMPLETED; 18803 break; 18804 18805 default: 18806 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18807 __func__, evt->peer_reason, evt->peer_status); 18808 return QDF_STATUS_E_INVAL; 18809 }; 18810 18811 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18812 __func__, param->peermac.bytes, param->message_type, 18813 param->peer_reason, param->vdev_id); 18814 18815 return QDF_STATUS_SUCCESS; 18816 } 18817 #endif 18818 18819 /** 18820 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18821 * @wmi_handle: wmi handle 18822 * @param evt_buf: pointer to event buffer 18823 * @param param: Pointer to hold MGMT TX completion params 18824 * 18825 * Return: QDF_STATUS_SUCCESS for success or error code 18826 */ 18827 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18828 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18829 { 18830 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18831 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18832 18833 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18834 evt_buf; 18835 if (!param_buf) { 18836 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18837 return QDF_STATUS_E_INVAL; 18838 } 18839 cmpl_params = param_buf->fixed_param; 18840 18841 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18842 cmpl_params->pdev_id); 18843 param->desc_id = cmpl_params->desc_id; 18844 param->status = cmpl_params->status; 18845 param->ppdu_id = cmpl_params->ppdu_id; 18846 18847 return QDF_STATUS_SUCCESS; 18848 } 18849 18850 /** 18851 * extract_offchan_data_tx_compl_param_tlv() - 18852 * extract Offchan data tx completion event params 18853 * @wmi_handle: wmi handle 18854 * @param evt_buf: pointer to event buffer 18855 * @param param: Pointer to hold offchan data TX completion params 18856 * 18857 * Return: QDF_STATUS_SUCCESS for success or error code 18858 */ 18859 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18860 wmi_unified_t wmi_handle, void *evt_buf, 18861 struct wmi_host_offchan_data_tx_compl_event *param) 18862 { 18863 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18864 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18865 18866 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18867 evt_buf; 18868 if (!param_buf) { 18869 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18870 return QDF_STATUS_E_INVAL; 18871 } 18872 cmpl_params = param_buf->fixed_param; 18873 18874 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18875 cmpl_params->pdev_id); 18876 param->desc_id = cmpl_params->desc_id; 18877 param->status = cmpl_params->status; 18878 18879 return QDF_STATUS_SUCCESS; 18880 } 18881 18882 /** 18883 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18884 * status tlv 18885 * @wmi_handle: wmi handle 18886 * @param evt_buf: pointer to event buffer 18887 * @param param: Pointer to hold csa switch count status event param 18888 * 18889 * Return: QDF_STATUS_SUCCESS for success or error code 18890 */ 18891 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18892 wmi_unified_t wmi_handle, 18893 void *evt_buf, 18894 struct pdev_csa_switch_count_status *param) 18895 { 18896 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18897 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18898 18899 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18900 evt_buf; 18901 if (!param_buf) { 18902 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18903 return QDF_STATUS_E_INVAL; 18904 } 18905 18906 csa_status = param_buf->fixed_param; 18907 18908 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18909 csa_status->pdev_id); 18910 param->current_switch_count = csa_status->current_switch_count; 18911 param->num_vdevs = csa_status->num_vdevs; 18912 param->vdev_ids = param_buf->vdev_ids; 18913 18914 return QDF_STATUS_SUCCESS; 18915 } 18916 18917 /** 18918 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18919 * param from event 18920 * @wmi_handle: wmi handle 18921 * @param evt_buf: pointer to event buffer 18922 * @param param: Pointer to hold tpc configuration 18923 * 18924 * Return: 0 for success or error code 18925 */ 18926 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18927 void *evt_buf, 18928 wmi_host_pdev_tpc_config_event *param) 18929 { 18930 wmi_pdev_tpc_config_event_fixed_param *event = 18931 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18932 18933 if (!event) { 18934 WMI_LOGE("Invalid event buffer"); 18935 return QDF_STATUS_E_INVAL; 18936 } 18937 18938 param->pdev_id = event->pdev_id; 18939 param->regDomain = event->regDomain; 18940 param->chanFreq = event->chanFreq; 18941 param->phyMode = event->phyMode; 18942 param->twiceAntennaReduction = event->twiceAntennaReduction; 18943 param->twiceMaxRDPower = event->twiceMaxRDPower; 18944 param->powerLimit = event->powerLimit; 18945 param->rateMax = event->rateMax; 18946 param->numTxChain = event->numTxChain; 18947 param->ctl = event->ctl; 18948 param->flags = event->flags; 18949 18950 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18951 sizeof(param->maxRegAllowedPower)); 18952 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18953 event->maxRegAllowedPowerAGCDD, 18954 sizeof(param->maxRegAllowedPowerAGCDD)); 18955 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18956 event->maxRegAllowedPowerAGSTBC, 18957 sizeof(param->maxRegAllowedPowerAGSTBC)); 18958 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18959 event->maxRegAllowedPowerAGTXBF, 18960 sizeof(param->maxRegAllowedPowerAGTXBF)); 18961 WMI_LOGD("%s:extract success", __func__); 18962 18963 return QDF_STATUS_SUCCESS; 18964 } 18965 18966 /** 18967 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18968 * @wmi_handle: wmi handle 18969 * @param evt_buf: pointer to event buffer 18970 * @param num_vdevs: Pointer to hold num vdevs 18971 * 18972 * Return: QDF_STATUS_SUCCESS for success or error code 18973 */ 18974 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18975 void *evt_buf, uint32_t *num_vdevs) 18976 { 18977 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18978 wmi_host_swba_event_fixed_param *swba_event; 18979 uint32_t vdev_map; 18980 18981 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18982 if (!param_buf) { 18983 WMI_LOGE("Invalid swba event buffer"); 18984 return QDF_STATUS_E_INVAL; 18985 } 18986 18987 swba_event = param_buf->fixed_param; 18988 *num_vdevs = swba_event->num_vdevs; 18989 if (!(*num_vdevs)) { 18990 vdev_map = swba_event->vdev_map; 18991 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18992 } 18993 18994 return QDF_STATUS_SUCCESS; 18995 } 18996 18997 /** 18998 * extract_swba_tim_info_tlv() - extract swba tim info from event 18999 * @wmi_handle: wmi handle 19000 * @param evt_buf: pointer to event buffer 19001 * @param idx: Index to bcn info 19002 * @param tim_info: Pointer to hold tim info 19003 * 19004 * Return: QDF_STATUS_SUCCESS for success or error code 19005 */ 19006 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 19007 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 19008 { 19009 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 19010 wmi_tim_info *tim_info_ev; 19011 19012 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 19013 if (!param_buf) { 19014 WMI_LOGE("Invalid swba event buffer"); 19015 return QDF_STATUS_E_INVAL; 19016 } 19017 19018 tim_info_ev = ¶m_buf->tim_info[idx]; 19019 19020 tim_info->tim_len = tim_info_ev->tim_len; 19021 tim_info->tim_mcast = tim_info_ev->tim_mcast; 19022 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 19023 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 19024 tim_info->tim_changed = tim_info_ev->tim_changed; 19025 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 19026 tim_info->vdev_id = tim_info_ev->vdev_id; 19027 19028 return QDF_STATUS_SUCCESS; 19029 } 19030 19031 /** 19032 * extract_swba_noa_info_tlv() - extract swba NoA information from event 19033 * @wmi_handle: wmi handle 19034 * @param evt_buf: pointer to event buffer 19035 * @param idx: Index to bcn info 19036 * @param p2p_desc: Pointer to hold p2p NoA info 19037 * 19038 * Return: QDF_STATUS_SUCCESS for success or error code 19039 */ 19040 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 19041 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 19042 { 19043 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 19044 wmi_p2p_noa_info *p2p_noa_info; 19045 uint8_t i = 0; 19046 19047 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 19048 if (!param_buf) { 19049 WMI_LOGE("Invalid swba event buffer"); 19050 return QDF_STATUS_E_INVAL; 19051 } 19052 19053 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 19054 19055 p2p_desc->modified = false; 19056 p2p_desc->num_descriptors = 0; 19057 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 19058 p2p_desc->modified = true; 19059 p2p_desc->index = 19060 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 19061 p2p_desc->oppPS = 19062 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 19063 p2p_desc->ctwindow = 19064 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 19065 p2p_desc->num_descriptors = 19066 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 19067 (p2p_noa_info); 19068 for (i = 0; i < p2p_desc->num_descriptors; i++) { 19069 p2p_desc->noa_descriptors[i].type_count = 19070 (uint8_t) p2p_noa_info->noa_descriptors[i]. 19071 type_count; 19072 p2p_desc->noa_descriptors[i].duration = 19073 p2p_noa_info->noa_descriptors[i].duration; 19074 p2p_desc->noa_descriptors[i].interval = 19075 p2p_noa_info->noa_descriptors[i].interval; 19076 p2p_desc->noa_descriptors[i].start_time = 19077 p2p_noa_info->noa_descriptors[i].start_time; 19078 } 19079 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 19080 } 19081 19082 return QDF_STATUS_SUCCESS; 19083 } 19084 19085 #ifdef CONVERGED_P2P_ENABLE 19086 /** 19087 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 19088 * @wmi_handle: wmi handle 19089 * @param evt_buf: pointer to event buffer 19090 * @param param: Pointer to hold p2p noa info 19091 * 19092 * Return: QDF_STATUS_SUCCESS for success or error code 19093 */ 19094 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 19095 wmi_unified_t wmi_handle, void *evt_buf, 19096 struct p2p_noa_info *param) 19097 { 19098 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 19099 wmi_p2p_noa_event_fixed_param *fixed_param; 19100 uint8_t i; 19101 wmi_p2p_noa_info *wmi_noa_info; 19102 uint8_t *buf_ptr; 19103 uint32_t descriptors; 19104 19105 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 19106 if (!param_tlvs) { 19107 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 19108 return QDF_STATUS_E_INVAL; 19109 } 19110 19111 if (!param) { 19112 WMI_LOGE("noa information param is null"); 19113 return QDF_STATUS_E_INVAL; 19114 } 19115 19116 fixed_param = param_tlvs->fixed_param; 19117 buf_ptr = (uint8_t *) fixed_param; 19118 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 19119 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 19120 19121 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 19122 WMI_LOGE("%s: noa attr is not modified", __func__); 19123 return QDF_STATUS_E_INVAL; 19124 } 19125 19126 param->vdev_id = fixed_param->vdev_id; 19127 param->index = 19128 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 19129 param->opps_ps = 19130 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 19131 param->ct_window = 19132 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 19133 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 19134 param->num_desc = (uint8_t) descriptors; 19135 19136 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 19137 param->index, param->opps_ps, param->ct_window, 19138 param->num_desc); 19139 for (i = 0; i < param->num_desc; i++) { 19140 param->noa_desc[i].type_count = 19141 (uint8_t) wmi_noa_info->noa_descriptors[i]. 19142 type_count; 19143 param->noa_desc[i].duration = 19144 wmi_noa_info->noa_descriptors[i].duration; 19145 param->noa_desc[i].interval = 19146 wmi_noa_info->noa_descriptors[i].interval; 19147 param->noa_desc[i].start_time = 19148 wmi_noa_info->noa_descriptors[i].start_time; 19149 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 19150 __func__, i, param->noa_desc[i].type_count, 19151 param->noa_desc[i].duration, 19152 param->noa_desc[i].interval, 19153 param->noa_desc[i].start_time); 19154 } 19155 19156 return QDF_STATUS_SUCCESS; 19157 } 19158 19159 /** 19160 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 19161 * information from event 19162 * @wmi_handle: wmi handle 19163 * @param evt_buf: pointer to event buffer 19164 * @param param: Pointer to hold p2p lo stop event information 19165 * 19166 * Return: QDF_STATUS_SUCCESS for success or error code 19167 */ 19168 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 19169 wmi_unified_t wmi_handle, void *evt_buf, 19170 struct p2p_lo_event *param) 19171 { 19172 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 19173 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 19174 19175 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 19176 evt_buf; 19177 if (!param_tlvs) { 19178 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 19179 return QDF_STATUS_E_INVAL; 19180 } 19181 19182 if (!param) { 19183 WMI_LOGE("lo stop event param is null"); 19184 return QDF_STATUS_E_INVAL; 19185 } 19186 19187 lo_param = param_tlvs->fixed_param; 19188 param->vdev_id = lo_param->vdev_id; 19189 param->reason_code = lo_param->reason; 19190 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 19191 param->vdev_id, param->reason_code); 19192 19193 return QDF_STATUS_SUCCESS; 19194 } 19195 #endif /* End of CONVERGED_P2P_ENABLE */ 19196 19197 /** 19198 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 19199 * @wmi_handle: wmi handle 19200 * @param evt_buf: pointer to event buffer 19201 * @param ev: Pointer to hold peer param 19202 * 19203 * Return: QDF_STATUS_SUCCESS for success or error code 19204 */ 19205 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 19206 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 19207 { 19208 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 19209 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 19210 19211 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 19212 kickout_event = param_buf->fixed_param; 19213 19214 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 19215 ev->peer_macaddr); 19216 19217 ev->reason = kickout_event->reason; 19218 ev->rssi = kickout_event->rssi; 19219 19220 return QDF_STATUS_SUCCESS; 19221 } 19222 19223 /** 19224 * extract_all_stats_counts_tlv() - extract all stats count from event 19225 * @wmi_handle: wmi handle 19226 * @param evt_buf: pointer to event buffer 19227 * @param stats_param: Pointer to hold stats count 19228 * 19229 * Return: QDF_STATUS_SUCCESS for success or error code 19230 */ 19231 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 19232 void *evt_buf, wmi_host_stats_event *stats_param) 19233 { 19234 wmi_stats_event_fixed_param *ev; 19235 wmi_per_chain_rssi_stats *rssi_event; 19236 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19237 19238 qdf_mem_zero(stats_param, sizeof(*stats_param)); 19239 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19240 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19241 rssi_event = param_buf->chain_stats; 19242 if (!ev) { 19243 WMI_LOGE("%s: event fixed param NULL\n", __func__); 19244 return QDF_STATUS_E_FAILURE; 19245 } 19246 19247 switch (ev->stats_id) { 19248 case WMI_REQUEST_PEER_STAT: 19249 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 19250 break; 19251 19252 case WMI_REQUEST_AP_STAT: 19253 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 19254 break; 19255 19256 case WMI_REQUEST_PDEV_STAT: 19257 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 19258 break; 19259 19260 case WMI_REQUEST_VDEV_STAT: 19261 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 19262 break; 19263 19264 case WMI_REQUEST_BCNFLT_STAT: 19265 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 19266 break; 19267 19268 case WMI_REQUEST_VDEV_RATE_STAT: 19269 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 19270 break; 19271 19272 case WMI_REQUEST_BCN_STAT: 19273 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 19274 break; 19275 19276 default: 19277 stats_param->stats_id = 0; 19278 break; 19279 19280 } 19281 19282 stats_param->num_pdev_stats = ev->num_pdev_stats; 19283 stats_param->num_pdev_ext_stats = 0; 19284 stats_param->num_vdev_stats = ev->num_vdev_stats; 19285 stats_param->num_peer_stats = ev->num_peer_stats; 19286 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 19287 stats_param->num_chan_stats = ev->num_chan_stats; 19288 stats_param->num_bcn_stats = ev->num_bcn_stats; 19289 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19290 ev->pdev_id); 19291 19292 /* if chain_stats is not populated */ 19293 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 19294 return QDF_STATUS_SUCCESS; 19295 19296 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 19297 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 19298 return QDF_STATUS_SUCCESS; 19299 19300 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 19301 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 19302 return QDF_STATUS_SUCCESS; 19303 19304 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 19305 19306 return QDF_STATUS_SUCCESS; 19307 } 19308 19309 /** 19310 * extract_pdev_tx_stats() - extract pdev tx stats from event 19311 */ 19312 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 19313 { 19314 /* Tx Stats */ 19315 tx->comp_queued = tx_stats->comp_queued; 19316 tx->comp_delivered = tx_stats->comp_delivered; 19317 tx->msdu_enqued = tx_stats->msdu_enqued; 19318 tx->mpdu_enqued = tx_stats->mpdu_enqued; 19319 tx->wmm_drop = tx_stats->wmm_drop; 19320 tx->local_enqued = tx_stats->local_enqued; 19321 tx->local_freed = tx_stats->local_freed; 19322 tx->hw_queued = tx_stats->hw_queued; 19323 tx->hw_reaped = tx_stats->hw_reaped; 19324 tx->underrun = tx_stats->underrun; 19325 tx->tx_abort = tx_stats->tx_abort; 19326 tx->mpdus_requed = tx_stats->mpdus_requed; 19327 tx->data_rc = tx_stats->data_rc; 19328 tx->self_triggers = tx_stats->self_triggers; 19329 tx->sw_retry_failure = tx_stats->sw_retry_failure; 19330 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 19331 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 19332 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 19333 tx->pdev_resets = tx_stats->pdev_resets; 19334 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 19335 tx->phy_underrun = tx_stats->phy_underrun; 19336 tx->txop_ovf = tx_stats->txop_ovf; 19337 19338 return; 19339 } 19340 19341 19342 /** 19343 * extract_pdev_rx_stats() - extract pdev rx stats from event 19344 */ 19345 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 19346 { 19347 /* Rx Stats */ 19348 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 19349 rx->status_rcvd = rx_stats->status_rcvd; 19350 rx->r0_frags = rx_stats->r0_frags; 19351 rx->r1_frags = rx_stats->r1_frags; 19352 rx->r2_frags = rx_stats->r2_frags; 19353 /* Only TLV */ 19354 rx->r3_frags = 0; 19355 rx->htt_msdus = rx_stats->htt_msdus; 19356 rx->htt_mpdus = rx_stats->htt_mpdus; 19357 rx->loc_msdus = rx_stats->loc_msdus; 19358 rx->loc_mpdus = rx_stats->loc_mpdus; 19359 rx->oversize_amsdu = rx_stats->oversize_amsdu; 19360 rx->phy_errs = rx_stats->phy_errs; 19361 rx->phy_err_drop = rx_stats->phy_err_drop; 19362 rx->mpdu_errs = rx_stats->mpdu_errs; 19363 19364 return; 19365 } 19366 19367 /** 19368 * extract_pdev_stats_tlv() - extract pdev stats from event 19369 * @wmi_handle: wmi handle 19370 * @param evt_buf: pointer to event buffer 19371 * @param index: Index into pdev stats 19372 * @param pdev_stats: Pointer to hold pdev stats 19373 * 19374 * Return: QDF_STATUS_SUCCESS for success or error code 19375 */ 19376 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 19377 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 19378 { 19379 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19380 wmi_stats_event_fixed_param *ev_param; 19381 uint8_t *data; 19382 19383 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19384 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19385 19386 data = param_buf->data; 19387 19388 if (index < ev_param->num_pdev_stats) { 19389 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 19390 (index * sizeof(wmi_pdev_stats))); 19391 19392 pdev_stats->chan_nf = ev->chan_nf; 19393 pdev_stats->tx_frame_count = ev->tx_frame_count; 19394 pdev_stats->rx_frame_count = ev->rx_frame_count; 19395 pdev_stats->rx_clear_count = ev->rx_clear_count; 19396 pdev_stats->cycle_count = ev->cycle_count; 19397 pdev_stats->phy_err_count = ev->phy_err_count; 19398 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 19399 19400 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 19401 &(ev->pdev_stats.tx)); 19402 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 19403 &(ev->pdev_stats.rx)); 19404 } 19405 19406 return QDF_STATUS_SUCCESS; 19407 } 19408 19409 /** 19410 * extract_unit_test_tlv() - extract unit test data 19411 * @wmi_handle: wmi handle 19412 * @param evt_buf: pointer to event buffer 19413 * @param unit_test: pointer to hold unit test data 19414 * @param maxspace: Amount of space in evt_buf 19415 * 19416 * Return: QDF_STATUS_SUCCESS for success or error code 19417 */ 19418 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 19419 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 19420 { 19421 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 19422 wmi_unit_test_event_fixed_param *ev_param; 19423 uint32_t num_bufp; 19424 uint32_t copy_size; 19425 uint8_t *bufp; 19426 19427 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 19428 ev_param = param_buf->fixed_param; 19429 bufp = param_buf->bufp; 19430 num_bufp = param_buf->num_bufp; 19431 unit_test->vdev_id = ev_param->vdev_id; 19432 unit_test->module_id = ev_param->module_id; 19433 unit_test->diag_token = ev_param->diag_token; 19434 unit_test->flag = ev_param->flag; 19435 unit_test->payload_len = ev_param->payload_len; 19436 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 19437 ev_param->vdev_id, 19438 ev_param->module_id, 19439 ev_param->diag_token, 19440 ev_param->flag); 19441 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 19442 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 19443 bufp, num_bufp); 19444 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 19445 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 19446 unit_test->buffer_len = copy_size; 19447 19448 return QDF_STATUS_SUCCESS; 19449 } 19450 19451 /** 19452 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 19453 * @wmi_handle: wmi handle 19454 * @param evt_buf: pointer to event buffer 19455 * @param index: Index into extended pdev stats 19456 * @param pdev_ext_stats: Pointer to hold extended pdev stats 19457 * 19458 * Return: QDF_STATUS_SUCCESS for success or error code 19459 */ 19460 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 19461 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 19462 { 19463 return QDF_STATUS_SUCCESS; 19464 } 19465 19466 /** 19467 * extract_vdev_stats_tlv() - extract vdev stats from event 19468 * @wmi_handle: wmi handle 19469 * @param evt_buf: pointer to event buffer 19470 * @param index: Index into vdev stats 19471 * @param vdev_stats: Pointer to hold vdev stats 19472 * 19473 * Return: QDF_STATUS_SUCCESS for success or error code 19474 */ 19475 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 19476 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 19477 { 19478 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19479 wmi_stats_event_fixed_param *ev_param; 19480 uint8_t *data; 19481 19482 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19483 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19484 data = (uint8_t *) param_buf->data; 19485 19486 if (index < ev_param->num_vdev_stats) { 19487 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 19488 ((ev_param->num_pdev_stats) * 19489 sizeof(wmi_pdev_stats)) + 19490 (index * sizeof(wmi_vdev_stats))); 19491 19492 vdev_stats->vdev_id = ev->vdev_id; 19493 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 19494 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 19495 19496 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 19497 sizeof(ev->tx_frm_cnt)); 19498 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 19499 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 19500 ev->multiple_retry_cnt, 19501 sizeof(ev->multiple_retry_cnt)); 19502 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 19503 sizeof(ev->fail_cnt)); 19504 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 19505 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 19506 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 19507 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 19508 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 19509 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 19510 sizeof(ev->tx_rate_history)); 19511 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 19512 sizeof(ev->bcn_rssi_history)); 19513 19514 } 19515 19516 return QDF_STATUS_SUCCESS; 19517 } 19518 19519 /** 19520 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 19521 * buffer 19522 * @wmi_handle: wmi handle 19523 * @evt_buf: pointer to event buffer 19524 * @index: Index into vdev stats 19525 * @rssi_stats: Pointer to hold rssi stats 19526 * 19527 * Return: QDF_STATUS_SUCCESS for success or error code 19528 */ 19529 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 19530 void *evt_buf, uint32_t index, 19531 struct wmi_host_per_chain_rssi_stats *rssi_stats) 19532 { 19533 uint8_t *data; 19534 wmi_rssi_stats *fw_rssi_stats; 19535 wmi_per_chain_rssi_stats *rssi_event; 19536 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19537 19538 if (!evt_buf) { 19539 WMI_LOGE("evt_buf is null"); 19540 return QDF_STATUS_E_NULL_VALUE; 19541 } 19542 19543 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19544 rssi_event = param_buf->chain_stats; 19545 19546 if (index >= rssi_event->num_per_chain_rssi_stats) { 19547 WMI_LOGE("invalid index"); 19548 return QDF_STATUS_E_INVAL; 19549 } 19550 19551 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 19552 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 19553 19554 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 19555 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 19556 fw_rssi_stats->rssi_avg_beacon, 19557 sizeof(fw_rssi_stats->rssi_avg_beacon)); 19558 qdf_mem_copy(rssi_stats->rssi_avg_data, 19559 fw_rssi_stats->rssi_avg_data, 19560 sizeof(fw_rssi_stats->rssi_avg_data)); 19561 qdf_mem_copy(&rssi_stats->peer_macaddr, 19562 &fw_rssi_stats->peer_macaddr, 19563 sizeof(fw_rssi_stats->peer_macaddr)); 19564 19565 return QDF_STATUS_SUCCESS; 19566 } 19567 19568 19569 19570 /** 19571 * extract_bcn_stats_tlv() - extract bcn stats from event 19572 * @wmi_handle: wmi handle 19573 * @param evt_buf: pointer to event buffer 19574 * @param index: Index into vdev stats 19575 * @param bcn_stats: Pointer to hold bcn stats 19576 * 19577 * Return: QDF_STATUS_SUCCESS for success or error code 19578 */ 19579 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 19580 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 19581 { 19582 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19583 wmi_stats_event_fixed_param *ev_param; 19584 uint8_t *data; 19585 19586 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19587 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19588 data = (uint8_t *) param_buf->data; 19589 19590 if (index < ev_param->num_bcn_stats) { 19591 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 19592 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19593 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19594 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19595 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 19596 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 19597 (index * sizeof(wmi_bcn_stats))); 19598 19599 bcn_stats->vdev_id = ev->vdev_id; 19600 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 19601 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 19602 } 19603 19604 return QDF_STATUS_SUCCESS; 19605 } 19606 19607 /** 19608 * extract_peer_stats_tlv() - extract peer stats from event 19609 * @wmi_handle: wmi handle 19610 * @param evt_buf: pointer to event buffer 19611 * @param index: Index into peer stats 19612 * @param peer_stats: Pointer to hold peer stats 19613 * 19614 * Return: QDF_STATUS_SUCCESS for success or error code 19615 */ 19616 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 19617 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 19618 { 19619 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19620 wmi_stats_event_fixed_param *ev_param; 19621 uint8_t *data; 19622 19623 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19624 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19625 data = (uint8_t *) param_buf->data; 19626 19627 if (index < ev_param->num_peer_stats) { 19628 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 19629 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19630 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19631 (index * sizeof(wmi_peer_stats))); 19632 19633 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19634 19635 OS_MEMCPY(&(peer_stats->peer_macaddr), 19636 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19637 19638 peer_stats->peer_rssi = ev->peer_rssi; 19639 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19640 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19641 } 19642 19643 return QDF_STATUS_SUCCESS; 19644 } 19645 19646 /** 19647 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19648 * @wmi_handle: wmi handle 19649 * @param evt_buf: pointer to event buffer 19650 * @param index: Index into bcn fault stats 19651 * @param bcnflt_stats: Pointer to hold bcn fault stats 19652 * 19653 * Return: QDF_STATUS_SUCCESS for success or error code 19654 */ 19655 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19656 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19657 { 19658 return QDF_STATUS_SUCCESS; 19659 } 19660 19661 /** 19662 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19663 * @wmi_handle: wmi handle 19664 * @param evt_buf: pointer to event buffer 19665 * @param index: Index into extended peer stats 19666 * @param peer_extd_stats: Pointer to hold extended peer stats 19667 * 19668 * Return: QDF_STATUS_SUCCESS for success or error code 19669 */ 19670 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19671 void *evt_buf, uint32_t index, 19672 wmi_host_peer_extd_stats *peer_extd_stats) 19673 { 19674 return QDF_STATUS_SUCCESS; 19675 } 19676 19677 /** 19678 * extract_chan_stats_tlv() - extract chan stats from event 19679 * @wmi_handle: wmi handle 19680 * @param evt_buf: pointer to event buffer 19681 * @param index: Index into chan stats 19682 * @param vdev_extd_stats: Pointer to hold chan stats 19683 * 19684 * Return: QDF_STATUS_SUCCESS for success or error code 19685 */ 19686 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19687 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19688 { 19689 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19690 wmi_stats_event_fixed_param *ev_param; 19691 uint8_t *data; 19692 19693 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19694 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19695 data = (uint8_t *) param_buf->data; 19696 19697 if (index < ev_param->num_chan_stats) { 19698 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19699 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19700 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19701 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19702 (index * sizeof(wmi_chan_stats))); 19703 19704 19705 /* Non-TLV doesnt have num_chan_stats */ 19706 chan_stats->chan_mhz = ev->chan_mhz; 19707 chan_stats->sampling_period_us = ev->sampling_period_us; 19708 chan_stats->rx_clear_count = ev->rx_clear_count; 19709 chan_stats->tx_duration_us = ev->tx_duration_us; 19710 chan_stats->rx_duration_us = ev->rx_duration_us; 19711 } 19712 19713 return QDF_STATUS_SUCCESS; 19714 } 19715 19716 /** 19717 * extract_profile_ctx_tlv() - extract profile context from event 19718 * @wmi_handle: wmi handle 19719 * @param evt_buf: pointer to event buffer 19720 * @idx: profile stats index to extract 19721 * @param profile_ctx: Pointer to hold profile context 19722 * 19723 * Return: QDF_STATUS_SUCCESS for success or error code 19724 */ 19725 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19726 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19727 { 19728 return QDF_STATUS_SUCCESS; 19729 } 19730 19731 /** 19732 * extract_profile_data_tlv() - extract profile data from event 19733 * @wmi_handle: wmi handle 19734 * @param evt_buf: pointer to event buffer 19735 * @param profile_data: Pointer to hold profile data 19736 * 19737 * Return: QDF_STATUS_SUCCESS for success or error code 19738 */ 19739 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19740 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19741 { 19742 19743 return QDF_STATUS_SUCCESS; 19744 } 19745 19746 /** 19747 * extract_chan_info_event_tlv() - extract chan information from event 19748 * @wmi_handle: wmi handle 19749 * @param evt_buf: pointer to event buffer 19750 * @param chan_info: Pointer to hold chan information 19751 * 19752 * Return: QDF_STATUS_SUCCESS for success or error code 19753 */ 19754 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19755 void *evt_buf, wmi_host_chan_info_event *chan_info) 19756 { 19757 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19758 wmi_chan_info_event_fixed_param *ev; 19759 19760 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19761 19762 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19763 if (!ev) { 19764 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19765 return QDF_STATUS_E_FAILURE; 19766 } 19767 19768 chan_info->err_code = ev->err_code; 19769 chan_info->freq = ev->freq; 19770 chan_info->cmd_flags = ev->cmd_flags; 19771 chan_info->noise_floor = ev->noise_floor; 19772 chan_info->rx_clear_count = ev->rx_clear_count; 19773 chan_info->cycle_count = ev->cycle_count; 19774 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19775 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19776 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19777 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19778 ev->vdev_id, WLAN_SCAN_ID); 19779 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19780 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19781 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19782 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19783 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19784 chan_info->rx_frame_count = ev->rx_frame_count; 19785 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19786 chan_info->vdev_id = ev->vdev_id; 19787 19788 return QDF_STATUS_SUCCESS; 19789 } 19790 19791 /** 19792 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19793 * @wmi_handle: WMI handle 19794 * @param evt_buf: Pointer to event buffer 19795 * @param param: Pointer to hold data 19796 * 19797 * Return : QDF_STATUS_SUCCESS for success or error code 19798 */ 19799 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19800 uint8_t *evt_buf, 19801 struct wmi_host_pdev_utf_event *event) 19802 { 19803 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19804 struct wmi_host_utf_seg_header_info *seg_hdr; 19805 19806 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19807 event->data = param_buf->data; 19808 event->datalen = param_buf->num_data; 19809 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19810 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19811 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19812 seg_hdr->pdev_id); 19813 19814 return QDF_STATUS_SUCCESS; 19815 } 19816 19817 /** 19818 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19819 * @wmi_handle: wmi handle 19820 * @param evt_buf: pointer to event buffer 19821 * @param param: Pointer to hold evt buf 19822 * 19823 * Return: QDF_STATUS_SUCCESS for success or error code 19824 */ 19825 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19826 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19827 { 19828 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19829 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19830 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19831 uint8_t i = 0, j = 0; 19832 19833 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19834 if (!param_buf) 19835 return QDF_STATUS_E_INVAL; 19836 19837 hw_caps = param_buf->soc_hw_mode_caps; 19838 if (!hw_caps) 19839 return QDF_STATUS_E_INVAL; 19840 19841 if (!hw_caps->num_chainmask_tables) 19842 return QDF_STATUS_E_INVAL; 19843 19844 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19845 19846 if (chainmask_caps == NULL) 19847 return QDF_STATUS_E_INVAL; 19848 19849 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19850 19851 qdf_print("Dumping chain mask combo data for table : %d\n", i); 19852 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19853 19854 chainmask_table[i].cap_list[j].chainmask = 19855 chainmask_caps->chainmask; 19856 19857 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19858 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19859 19860 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19861 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19862 19863 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19864 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19865 19866 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19867 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19868 19869 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19870 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19871 19872 chainmask_table[i].cap_list[j].chain_mask_2G = 19873 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19874 19875 chainmask_table[i].cap_list[j].chain_mask_5G = 19876 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19877 19878 chainmask_table[i].cap_list[j].chain_mask_tx = 19879 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19880 19881 chainmask_table[i].cap_list[j].chain_mask_rx = 19882 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19883 19884 chainmask_table[i].cap_list[j].supports_aDFS = 19885 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19886 19887 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x\n", 19888 chainmask_caps->supported_flags, 19889 chainmask_caps->chainmask 19890 ); 19891 chainmask_caps++; 19892 } 19893 } 19894 19895 return QDF_STATUS_SUCCESS; 19896 } 19897 19898 /** 19899 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19900 * from event 19901 * @wmi_handle: wmi handle 19902 * @param evt_buf: pointer to event buffer 19903 * @param param: Pointer to hold evt buf 19904 * 19905 * Return: QDF_STATUS_SUCCESS for success or error code 19906 */ 19907 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19908 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19909 { 19910 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19911 wmi_service_ready_ext_event_fixed_param *ev; 19912 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19913 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19914 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19915 uint8_t i = 0; 19916 19917 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19918 if (!param_buf) 19919 return QDF_STATUS_E_INVAL; 19920 19921 ev = param_buf->fixed_param; 19922 if (!ev) 19923 return QDF_STATUS_E_INVAL; 19924 19925 /* Move this to host based bitmap */ 19926 param->default_conc_scan_config_bits = 19927 ev->default_conc_scan_config_bits; 19928 param->default_fw_config_bits = ev->default_fw_config_bits; 19929 param->he_cap_info = ev->he_cap_info; 19930 param->mpdu_density = ev->mpdu_density; 19931 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19932 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19933 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19934 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19935 19936 hw_caps = param_buf->soc_hw_mode_caps; 19937 if (hw_caps) 19938 param->num_hw_modes = hw_caps->num_hw_modes; 19939 else 19940 param->num_hw_modes = 0; 19941 19942 reg_caps = param_buf->soc_hal_reg_caps; 19943 if (reg_caps) 19944 param->num_phy = reg_caps->num_phy; 19945 else 19946 param->num_phy = 0; 19947 19948 if (hw_caps) { 19949 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19950 qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables); 19951 } else 19952 param->num_chainmask_tables = 0; 19953 19954 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19955 19956 if (chain_mask_combo == NULL) 19957 return QDF_STATUS_SUCCESS; 19958 19959 qdf_print("Dumping chain mask combo data\n"); 19960 19961 for (i = 0; i < param->num_chainmask_tables; i++) { 19962 19963 qdf_print("table_id : %d Num valid chainmasks: %d\n", 19964 chain_mask_combo->chainmask_table_id, 19965 chain_mask_combo->num_valid_chainmask 19966 ); 19967 19968 param->chainmask_table[i].table_id = 19969 chain_mask_combo->chainmask_table_id; 19970 param->chainmask_table[i].num_valid_chainmasks = 19971 chain_mask_combo->num_valid_chainmask; 19972 chain_mask_combo++; 19973 } 19974 qdf_print("chain mask combo end\n"); 19975 19976 return QDF_STATUS_SUCCESS; 19977 } 19978 19979 /** 19980 * extract_hw_mode_cap_service_ready_ext_tlv() - 19981 * extract HW mode cap from service ready event 19982 * @wmi_handle: wmi handle 19983 * @param evt_buf: pointer to event buffer 19984 * @param param: Pointer to hold evt buf 19985 * @param hw_mode_idx: hw mode idx should be less than num_mode 19986 * 19987 * Return: QDF_STATUS_SUCCESS for success or error code 19988 */ 19989 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19990 wmi_unified_t wmi_handle, 19991 uint8_t *event, uint8_t hw_mode_idx, 19992 struct wlan_psoc_host_hw_mode_caps *param) 19993 { 19994 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19995 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19996 19997 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19998 if (!param_buf) 19999 return QDF_STATUS_E_INVAL; 20000 20001 hw_caps = param_buf->soc_hw_mode_caps; 20002 if (!hw_caps) 20003 return QDF_STATUS_E_INVAL; 20004 20005 if (hw_mode_idx >= hw_caps->num_hw_modes) 20006 return QDF_STATUS_E_INVAL; 20007 20008 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 20009 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 20010 20011 param->hw_mode_config_type = 20012 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 20013 20014 return QDF_STATUS_SUCCESS; 20015 } 20016 20017 /** 20018 * extract_mac_phy_cap_service_ready_ext_tlv() - 20019 * extract MAC phy cap from service ready event 20020 * @wmi_handle: wmi handle 20021 * @param evt_buf: pointer to event buffer 20022 * @param param: Pointer to hold evt buf 20023 * @param hw_mode_idx: hw mode idx should be less than num_mode 20024 * @param phy_id: phy id within hw_mode 20025 * 20026 * Return: QDF_STATUS_SUCCESS for success or error code 20027 */ 20028 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 20029 wmi_unified_t wmi_handle, 20030 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 20031 struct wlan_psoc_host_mac_phy_caps *param) 20032 { 20033 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20034 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 20035 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 20036 uint32_t phy_map; 20037 uint8_t hw_idx, phy_idx = 0; 20038 20039 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 20040 if (!param_buf) 20041 return QDF_STATUS_E_INVAL; 20042 20043 hw_caps = param_buf->soc_hw_mode_caps; 20044 if (!hw_caps) 20045 return QDF_STATUS_E_INVAL; 20046 20047 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 20048 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 20049 break; 20050 20051 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 20052 while (phy_map) { 20053 phy_map >>= 1; 20054 phy_idx++; 20055 } 20056 } 20057 20058 if (hw_idx == hw_caps->num_hw_modes) 20059 return QDF_STATUS_E_INVAL; 20060 20061 phy_idx += phy_id; 20062 if (phy_idx >= param_buf->num_mac_phy_caps) 20063 return QDF_STATUS_E_INVAL; 20064 20065 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 20066 20067 param->hw_mode_id = mac_phy_caps->hw_mode_id; 20068 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20069 mac_phy_caps->pdev_id); 20070 param->phy_id = mac_phy_caps->phy_id; 20071 param->supports_11b = 20072 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 20073 param->supports_11g = 20074 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 20075 param->supports_11a = 20076 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 20077 param->supports_11n = 20078 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 20079 param->supports_11ac = 20080 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 20081 param->supports_11ax = 20082 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 20083 20084 param->supported_bands = mac_phy_caps->supported_bands; 20085 param->ampdu_density = mac_phy_caps->ampdu_density; 20086 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 20087 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 20088 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 20089 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 20090 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 20091 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 20092 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 20093 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 20094 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 20095 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 20096 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 20097 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 20098 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 20099 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 20100 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 20101 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 20102 qdf_mem_copy(¶m->he_cap_phy_info_2G, 20103 &mac_phy_caps->he_cap_phy_info_2G, 20104 sizeof(param->he_cap_phy_info_2G)); 20105 qdf_mem_copy(¶m->he_cap_phy_info_5G, 20106 &mac_phy_caps->he_cap_phy_info_5G, 20107 sizeof(param->he_cap_phy_info_5G)); 20108 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 20109 sizeof(param->he_ppet2G)); 20110 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 20111 sizeof(param->he_ppet5G)); 20112 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 20113 20114 return QDF_STATUS_SUCCESS; 20115 } 20116 20117 /** 20118 * extract_reg_cap_service_ready_ext_tlv() - 20119 * extract REG cap from service ready event 20120 * @wmi_handle: wmi handle 20121 * @param evt_buf: pointer to event buffer 20122 * @param param: Pointer to hold evt buf 20123 * @param phy_idx: phy idx should be less than num_mode 20124 * 20125 * Return: QDF_STATUS_SUCCESS for success or error code 20126 */ 20127 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 20128 wmi_unified_t wmi_handle, 20129 uint8_t *event, uint8_t phy_idx, 20130 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 20131 { 20132 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20133 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 20134 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 20135 20136 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 20137 if (!param_buf) 20138 return QDF_STATUS_E_INVAL; 20139 20140 reg_caps = param_buf->soc_hal_reg_caps; 20141 if (!reg_caps) 20142 return QDF_STATUS_E_INVAL; 20143 20144 if (phy_idx >= reg_caps->num_phy) 20145 return QDF_STATUS_E_INVAL; 20146 20147 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 20148 20149 param->phy_id = ext_reg_cap->phy_id; 20150 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 20151 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 20152 param->regcap1 = ext_reg_cap->regcap1; 20153 param->regcap2 = ext_reg_cap->regcap2; 20154 param->wireless_modes = convert_wireless_modes_tlv( 20155 ext_reg_cap->wireless_modes); 20156 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 20157 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 20158 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 20159 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 20160 20161 return QDF_STATUS_SUCCESS; 20162 } 20163 20164 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 20165 wmi_unified_t wmi_handle, 20166 uint8_t *event, uint8_t idx, 20167 struct wlan_psoc_host_dbr_ring_caps *param) 20168 { 20169 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20170 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 20171 20172 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 20173 if (!param_buf) 20174 return QDF_STATUS_E_INVAL; 20175 20176 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 20177 20178 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20179 dbr_ring_caps->pdev_id); 20180 param->mod_id = dbr_ring_caps->mod_id; 20181 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 20182 param->min_buf_size = dbr_ring_caps->min_buf_size; 20183 param->min_buf_align = dbr_ring_caps->min_buf_align; 20184 20185 return QDF_STATUS_SUCCESS; 20186 } 20187 20188 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 20189 uint8_t *event, struct direct_buf_rx_rsp *param) 20190 { 20191 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20192 wmi_dma_buf_release_fixed_param *ev; 20193 20194 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20195 if (!param_buf) 20196 return QDF_STATUS_E_INVAL; 20197 20198 ev = param_buf->fixed_param; 20199 if (!ev) 20200 return QDF_STATUS_E_INVAL; 20201 20202 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20203 ev->pdev_id); 20204 param->mod_id = ev->mod_id; 20205 param->num_buf_release_entry = ev->num_buf_release_entry; 20206 param->num_meta_data_entry = ev->num_meta_data_entry; 20207 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 20208 param->pdev_id, param->mod_id, param->num_buf_release_entry); 20209 20210 return QDF_STATUS_SUCCESS; 20211 } 20212 20213 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 20214 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 20215 { 20216 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20217 wmi_dma_buf_release_entry *entry; 20218 20219 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20220 if (!param_buf) 20221 return QDF_STATUS_E_INVAL; 20222 20223 entry = ¶m_buf->entries[idx]; 20224 20225 if (!entry) { 20226 WMI_LOGE("%s: Entry is NULL\n", __func__); 20227 return QDF_STATUS_E_FAILURE; 20228 } 20229 20230 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 20231 20232 param->paddr_lo = entry->paddr_lo; 20233 param->paddr_hi = entry->paddr_hi; 20234 20235 return QDF_STATUS_SUCCESS; 20236 } 20237 20238 static QDF_STATUS extract_dbr_buf_metadata_tlv( 20239 wmi_unified_t wmi_handle, uint8_t *event, 20240 uint8_t idx, struct direct_buf_rx_metadata *param) 20241 { 20242 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20243 wmi_dma_buf_release_spectral_meta_data *entry; 20244 20245 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20246 if (!param_buf) 20247 return QDF_STATUS_E_INVAL; 20248 20249 entry = ¶m_buf->meta_data[idx]; 20250 20251 if (!entry) { 20252 WMI_LOGE("%s: Entry is NULL\n", __func__); 20253 return QDF_STATUS_E_FAILURE; 20254 } 20255 20256 qdf_mem_copy(param->noisefloor, entry->noise_floor, 20257 sizeof(entry->noise_floor)); 20258 return QDF_STATUS_SUCCESS; 20259 } 20260 20261 /** 20262 * extract_dcs_interference_type_tlv() - extract dcs interference type 20263 * from event 20264 * @wmi_handle: wmi handle 20265 * @param evt_buf: pointer to event buffer 20266 * @param param: Pointer to hold dcs interference param 20267 * 20268 * Return: 0 for success or error code 20269 */ 20270 static QDF_STATUS extract_dcs_interference_type_tlv( 20271 wmi_unified_t wmi_handle, 20272 void *evt_buf, struct wmi_host_dcs_interference_param *param) 20273 { 20274 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20275 20276 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20277 if (!param_buf) 20278 return QDF_STATUS_E_INVAL; 20279 20280 param->interference_type = param_buf->fixed_param->interference_type; 20281 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20282 param_buf->fixed_param->pdev_id); 20283 20284 return QDF_STATUS_SUCCESS; 20285 } 20286 20287 /* 20288 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 20289 * @wmi_handle: wmi handle 20290 * @param evt_buf: pointer to event buffer 20291 * @param cw_int: Pointer to hold cw interference 20292 * 20293 * Return: 0 for success or error code 20294 */ 20295 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 20296 void *evt_buf, 20297 wmi_host_ath_dcs_cw_int *cw_int) 20298 { 20299 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20300 wlan_dcs_cw_int *ev; 20301 20302 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20303 if (!param_buf) 20304 return QDF_STATUS_E_INVAL; 20305 20306 ev = param_buf->cw_int; 20307 20308 cw_int->channel = ev->channel; 20309 20310 return QDF_STATUS_SUCCESS; 20311 } 20312 20313 /** 20314 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 20315 * @wmi_handle: wmi handle 20316 * @param evt_buf: pointer to event buffer 20317 * @param wlan_stat: Pointer to hold wlan stats 20318 * 20319 * Return: 0 for success or error code 20320 */ 20321 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 20322 void *evt_buf, 20323 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 20324 { 20325 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20326 wlan_dcs_im_tgt_stats_t *ev; 20327 20328 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20329 if (!param_buf) 20330 return QDF_STATUS_E_INVAL; 20331 20332 ev = param_buf->wlan_stat; 20333 wlan_stat->reg_tsf32 = ev->reg_tsf32; 20334 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 20335 wlan_stat->tx_waste_time = ev->tx_waste_time; 20336 wlan_stat->rx_time = ev->rx_time; 20337 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 20338 wlan_stat->mib_stats.listen_time = ev->listen_time; 20339 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 20340 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 20341 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 20342 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 20343 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 20344 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 20345 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 20346 wlan_stat->chan_nf = ev->chan_nf; 20347 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 20348 20349 return QDF_STATUS_SUCCESS; 20350 } 20351 20352 /** 20353 * extract_thermal_stats_tlv() - extract thermal stats from event 20354 * @wmi_handle: wmi handle 20355 * @param evt_buf: Pointer to event buffer 20356 * @param temp: Pointer to hold extracted temperature 20357 * @param level: Pointer to hold extracted level 20358 * 20359 * Return: 0 for success or error code 20360 */ 20361 static QDF_STATUS 20362 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 20363 void *evt_buf, uint32_t *temp, 20364 uint32_t *level, uint32_t *pdev_id) 20365 { 20366 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20367 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 20368 20369 param_buf = 20370 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20371 if (!param_buf) 20372 return QDF_STATUS_E_INVAL; 20373 20374 tt_stats_event = param_buf->fixed_param; 20375 20376 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20377 tt_stats_event->pdev_id); 20378 *temp = tt_stats_event->temp; 20379 *level = tt_stats_event->level; 20380 20381 return QDF_STATUS_SUCCESS; 20382 } 20383 20384 /** 20385 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 20386 * @wmi_handle: wmi handle 20387 * @param evt_buf: pointer to event buffer 20388 * @param idx: Index to level stats 20389 * @param levelcount: Pointer to hold levelcount 20390 * @param dccount: Pointer to hold dccount 20391 * 20392 * Return: 0 for success or error code 20393 */ 20394 static QDF_STATUS 20395 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 20396 void *evt_buf, uint8_t idx, uint32_t *levelcount, 20397 uint32_t *dccount) 20398 { 20399 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20400 wmi_therm_throt_level_stats_info *tt_level_info; 20401 20402 param_buf = 20403 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20404 if (!param_buf) 20405 return QDF_STATUS_E_INVAL; 20406 20407 tt_level_info = param_buf->therm_throt_level_stats_info; 20408 20409 if (idx < THERMAL_LEVELS) { 20410 *levelcount = tt_level_info[idx].level_count; 20411 *dccount = tt_level_info[idx].dc_count; 20412 return QDF_STATUS_SUCCESS; 20413 } 20414 20415 return QDF_STATUS_E_FAILURE; 20416 } 20417 #ifdef BIG_ENDIAN_HOST 20418 /** 20419 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 20420 * @param data_len - data length 20421 * @param data - pointer to data 20422 * 20423 * Return: QDF_STATUS - success or error status 20424 */ 20425 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20426 { 20427 uint8_t *data_aligned = NULL; 20428 int c; 20429 unsigned char *data_unaligned; 20430 20431 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 20432 FIPS_ALIGN)); 20433 /* Assigning unaligned space to copy the data */ 20434 /* Checking if kmalloc does succesful allocation */ 20435 if (data_unaligned == NULL) 20436 return QDF_STATUS_E_FAILURE; 20437 20438 /* Checking if space is alligned */ 20439 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 20440 /* align the data space */ 20441 data_aligned = 20442 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 20443 } else { 20444 data_aligned = (u_int8_t *)data_unaligned; 20445 } 20446 20447 /* memset and copy content from data to data aligned */ 20448 OS_MEMSET(data_aligned, 0, data_len); 20449 OS_MEMCPY(data_aligned, data, data_len); 20450 /* Endianness to LE */ 20451 for (c = 0; c < data_len/4; c++) { 20452 *((u_int32_t *)data_aligned + c) = 20453 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 20454 } 20455 20456 /* Copy content to event->data */ 20457 OS_MEMCPY(data, data_aligned, data_len); 20458 20459 /* clean up allocated space */ 20460 qdf_mem_free(data_unaligned); 20461 data_aligned = NULL; 20462 data_unaligned = NULL; 20463 20464 /*************************************************************/ 20465 20466 return QDF_STATUS_SUCCESS; 20467 } 20468 #else 20469 /** 20470 * fips_conv_data_be() - DUMMY for LE platform 20471 * 20472 * Return: QDF_STATUS - success 20473 */ 20474 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20475 { 20476 return QDF_STATUS_SUCCESS; 20477 } 20478 #endif 20479 20480 /** 20481 * extract_fips_event_data_tlv() - extract fips event data 20482 * @wmi_handle: wmi handle 20483 * @param evt_buf: pointer to event buffer 20484 * @param param: pointer FIPS event params 20485 * 20486 * Return: 0 for success or error code 20487 */ 20488 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 20489 void *evt_buf, struct wmi_host_fips_event_param *param) 20490 { 20491 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 20492 wmi_pdev_fips_event_fixed_param *event; 20493 20494 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 20495 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 20496 20497 if (fips_conv_data_be(event->data_len, param_buf->data) != 20498 QDF_STATUS_SUCCESS) 20499 return QDF_STATUS_E_FAILURE; 20500 20501 param->data = (uint32_t *)param_buf->data; 20502 param->data_len = event->data_len; 20503 param->error_status = event->error_status; 20504 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20505 event->pdev_id); 20506 20507 return QDF_STATUS_SUCCESS; 20508 } 20509 20510 /* 20511 * extract_peer_delete_response_event_tlv() - extract peer delete response event 20512 * @wmi_handle: wmi handle 20513 * @param evt_buf: pointer to event buffer 20514 * @param vdev_id: Pointer to hold vdev_id 20515 * @param mac_addr: Pointer to hold peer mac address 20516 * 20517 * Return: QDF_STATUS_SUCCESS for success or error code 20518 */ 20519 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 20520 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 20521 { 20522 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 20523 wmi_peer_delete_resp_event_fixed_param *ev; 20524 20525 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 20526 20527 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 20528 if (!ev) { 20529 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 20530 return QDF_STATUS_E_FAILURE; 20531 } 20532 20533 param->vdev_id = ev->vdev_id; 20534 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 20535 ¶m->mac_address.bytes[0]); 20536 20537 return QDF_STATUS_SUCCESS; 20538 } 20539 20540 static bool is_management_record_tlv(uint32_t cmd_id) 20541 { 20542 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 20543 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 20544 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 20545 return true; 20546 } 20547 20548 return false; 20549 } 20550 20551 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20552 { 20553 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 20554 20555 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20556 20557 switch (set_cmd->param_id) { 20558 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 20559 case WMI_VDEV_PARAM_DTIM_POLICY: 20560 return HTC_TX_PACKET_TAG_AUTO_PM; 20561 default: 20562 break; 20563 } 20564 20565 return 0; 20566 } 20567 20568 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20569 { 20570 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 20571 20572 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 20573 20574 switch (ps_cmd->param) { 20575 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 20576 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 20577 case WMI_STA_PS_ENABLE_QPOWER: 20578 return HTC_TX_PACKET_TAG_AUTO_PM; 20579 default: 20580 break; 20581 } 20582 20583 return 0; 20584 } 20585 20586 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 20587 uint32_t cmd_id) 20588 { 20589 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 20590 return 0; 20591 20592 switch (cmd_id) { 20593 case WMI_VDEV_SET_PARAM_CMDID: 20594 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 20595 case WMI_STA_POWERSAVE_PARAM_CMDID: 20596 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 20597 default: 20598 break; 20599 } 20600 20601 return 0; 20602 } 20603 20604 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20605 { 20606 uint16_t tag = 0; 20607 20608 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20609 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20610 __func__); 20611 return tag; 20612 } 20613 20614 if (wmi_handle->tag_crash_inject) 20615 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20616 20617 wmi_handle->tag_crash_inject = false; 20618 return tag; 20619 } 20620 20621 /** 20622 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20623 * @wmi_handle: WMI handle 20624 * @buf: WMI buffer 20625 * @cmd_id: WMI command Id 20626 * 20627 * Return htc_tx_tag 20628 */ 20629 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20630 wmi_buf_t buf, 20631 uint32_t cmd_id) 20632 { 20633 uint16_t htc_tx_tag = 0; 20634 20635 switch (cmd_id) { 20636 case WMI_WOW_ENABLE_CMDID: 20637 case WMI_PDEV_SUSPEND_CMDID: 20638 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20639 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20640 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20641 case WMI_PDEV_RESUME_CMDID: 20642 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20643 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20644 #ifdef FEATURE_WLAN_D0WOW 20645 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20646 #endif 20647 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20648 break; 20649 case WMI_FORCE_FW_HANG_CMDID: 20650 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20651 break; 20652 case WMI_VDEV_SET_PARAM_CMDID: 20653 case WMI_STA_POWERSAVE_PARAM_CMDID: 20654 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20655 default: 20656 break; 20657 } 20658 20659 return htc_tx_tag; 20660 } 20661 20662 /** 20663 * extract_channel_hopping_event_tlv() - extract channel hopping param 20664 * from event 20665 * @wmi_handle: wmi handle 20666 * @param evt_buf: pointer to event buffer 20667 * @param ch_hopping: Pointer to hold channel hopping param 20668 * 20669 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20670 */ 20671 static QDF_STATUS extract_channel_hopping_event_tlv( 20672 wmi_unified_t wmi_handle, void *evt_buf, 20673 wmi_host_pdev_channel_hopping_event *ch_hopping) 20674 { 20675 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20676 wmi_pdev_channel_hopping_event_fixed_param *event; 20677 20678 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20679 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20680 param_buf->fixed_param; 20681 20682 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20683 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20684 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20685 event->pdev_id); 20686 20687 return QDF_STATUS_SUCCESS; 20688 } 20689 20690 /** 20691 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20692 * @wmi_handle: wmi handle 20693 * @param evt_buf: pointer to event buffer 20694 * @param param: Pointer to hold tpc param 20695 * 20696 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20697 */ 20698 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20699 void *evt_buf, 20700 wmi_host_pdev_tpc_event *param) 20701 { 20702 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20703 wmi_pdev_tpc_event_fixed_param *event; 20704 20705 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20706 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20707 20708 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20709 event->pdev_id); 20710 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20711 20712 return QDF_STATUS_SUCCESS; 20713 } 20714 20715 /** 20716 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20717 * power param from event 20718 * @wmi_handle: wmi handle 20719 * @param evt_buf: pointer to event buffer 20720 * @param param: Pointer to hold nf cal power param 20721 * 20722 * Return: 0 for success or error code 20723 */ 20724 static QDF_STATUS 20725 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20726 void *evt_buf, 20727 wmi_host_pdev_nfcal_power_all_channels_event *param) 20728 { 20729 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20730 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20731 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20732 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20733 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20734 uint32_t i; 20735 20736 param_buf = 20737 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20738 event = param_buf->fixed_param; 20739 ch_nfdbr = param_buf->nfdbr; 20740 ch_nfdbm = param_buf->nfdbm; 20741 ch_freqnum = param_buf->freqnum; 20742 20743 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20744 event->pdev_id, param_buf->num_nfdbr, 20745 param_buf->num_nfdbm, param_buf->num_freqnum); 20746 20747 if (param_buf->num_nfdbr > 20748 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20749 WMI_LOGE("invalid number of nfdBr"); 20750 return QDF_STATUS_E_FAILURE; 20751 } 20752 20753 if (param_buf->num_nfdbm > 20754 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20755 WMI_LOGE("invalid number of nfdBm"); 20756 return QDF_STATUS_E_FAILURE; 20757 } 20758 20759 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20760 WMI_LOGE("invalid number of freqNum"); 20761 return QDF_STATUS_E_FAILURE; 20762 } 20763 20764 for (i = 0; i < param_buf->num_nfdbr; i++) { 20765 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20766 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20767 ch_nfdbr++; 20768 ch_nfdbm++; 20769 } 20770 20771 for (i = 0; i < param_buf->num_freqnum; i++) { 20772 param->freqnum[i] = ch_freqnum->freqNum; 20773 ch_freqnum++; 20774 } 20775 20776 param->pdev_id = event->pdev_id; 20777 20778 return QDF_STATUS_SUCCESS; 20779 } 20780 20781 20782 #ifdef BIG_ENDIAN_HOST 20783 /** 20784 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20785 * @param data_len - data length 20786 * @param data - pointer to data 20787 * 20788 * Return: QDF_STATUS - success or error status 20789 */ 20790 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20791 { 20792 uint8_t *datap = (uint8_t *)ev; 20793 int i; 20794 /* Skip swapping the first word */ 20795 datap += sizeof(uint32_t); 20796 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20797 i++, datap += sizeof(uint32_t)) { 20798 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20799 } 20800 20801 return QDF_STATUS_SUCCESS; 20802 } 20803 #else 20804 /** 20805 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20806 * @param data_len - data length 20807 * @param data - pointer to data 20808 * 20809 * Return: QDF_STATUS - success or error status 20810 */ 20811 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20812 { 20813 return QDF_STATUS_SUCCESS; 20814 } 20815 #endif 20816 20817 /** 20818 * extract_wds_addr_event_tlv() - extract wds address from event 20819 * @wmi_handle: wmi handle 20820 * @param evt_buf: pointer to event buffer 20821 * @param wds_ev: Pointer to hold wds address 20822 * 20823 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20824 */ 20825 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20826 void *evt_buf, 20827 uint16_t len, wds_addr_event_t *wds_ev) 20828 { 20829 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20830 wmi_wds_addr_event_fixed_param *ev; 20831 int i; 20832 20833 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20834 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20835 20836 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20837 return QDF_STATUS_E_FAILURE; 20838 20839 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20840 sizeof(wds_ev->event_type)); 20841 for (i = 0; i < 4; i++) { 20842 wds_ev->peer_mac[i] = 20843 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20844 wds_ev->dest_mac[i] = 20845 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20846 } 20847 for (i = 0; i < 2; i++) { 20848 wds_ev->peer_mac[4+i] = 20849 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20850 wds_ev->dest_mac[4+i] = 20851 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20852 } 20853 return QDF_STATUS_SUCCESS; 20854 } 20855 20856 /** 20857 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20858 * from event 20859 * @wmi_handle: wmi handle 20860 * @param evt_buf: pointer to event buffer 20861 * @param ev: Pointer to hold peer param and ps state 20862 * 20863 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20864 */ 20865 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20866 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20867 { 20868 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20869 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20870 20871 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20872 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20873 param_buf->fixed_param; 20874 20875 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20876 ev->peer_ps_state = event->peer_ps_state; 20877 20878 return QDF_STATUS_SUCCESS; 20879 } 20880 20881 /** 20882 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20883 * @wmi_handle: wmi handle 20884 * @param evt_buf: pointer to event buffer 20885 * @param inst_rssi_resp: Pointer to hold inst rssi response 20886 * 20887 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20888 */ 20889 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20890 wmi_unified_t wmi_handle, void *evt_buf, 20891 wmi_host_inst_stats_resp *inst_rssi_resp) 20892 { 20893 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20894 wmi_inst_rssi_stats_resp_fixed_param *event; 20895 20896 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20897 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20898 20899 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20900 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20901 inst_rssi_resp->iRSSI = event->iRSSI; 20902 20903 return QDF_STATUS_SUCCESS; 20904 } 20905 20906 static struct cur_reg_rule 20907 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20908 wmi_regulatory_rule_struct *wmi_reg_rule) 20909 { 20910 struct cur_reg_rule *reg_rule_ptr; 20911 uint32_t count; 20912 20913 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20914 20915 if (NULL == reg_rule_ptr) { 20916 WMI_LOGE("memory allocation failure"); 20917 return NULL; 20918 } 20919 20920 for (count = 0; count < num_reg_rules; count++) { 20921 reg_rule_ptr[count].start_freq = 20922 WMI_REG_RULE_START_FREQ_GET( 20923 wmi_reg_rule[count].freq_info); 20924 reg_rule_ptr[count].end_freq = 20925 WMI_REG_RULE_END_FREQ_GET( 20926 wmi_reg_rule[count].freq_info); 20927 reg_rule_ptr[count].max_bw = 20928 WMI_REG_RULE_MAX_BW_GET( 20929 wmi_reg_rule[count].bw_pwr_info); 20930 reg_rule_ptr[count].reg_power = 20931 WMI_REG_RULE_REG_POWER_GET( 20932 wmi_reg_rule[count].bw_pwr_info); 20933 reg_rule_ptr[count].ant_gain = 20934 WMI_REG_RULE_ANTENNA_GAIN_GET( 20935 wmi_reg_rule[count].bw_pwr_info); 20936 reg_rule_ptr[count].flags = 20937 WMI_REG_RULE_FLAGS_GET( 20938 wmi_reg_rule[count].flag_info); 20939 } 20940 20941 return reg_rule_ptr; 20942 } 20943 20944 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20945 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20946 struct cur_regulatory_info *reg_info, uint32_t len) 20947 { 20948 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20949 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20950 wmi_regulatory_rule_struct *wmi_reg_rule; 20951 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20952 20953 WMI_LOGD("processing regulatory channel list"); 20954 20955 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20956 if (!param_buf) { 20957 WMI_LOGE("invalid channel list event buf"); 20958 return QDF_STATUS_E_FAILURE; 20959 } 20960 20961 chan_list_event_hdr = param_buf->fixed_param; 20962 20963 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20964 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20965 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20966 REG_ALPHA2_LEN); 20967 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20968 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20969 reg_info->offload_enabled = true; 20970 reg_info->num_phy = chan_list_event_hdr->num_phy; 20971 reg_info->phy_id = chan_list_event_hdr->phy_id; 20972 reg_info->ctry_code = chan_list_event_hdr->country_id; 20973 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20974 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20975 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20976 else if (chan_list_event_hdr->status_code == 20977 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20978 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20979 else if (chan_list_event_hdr->status_code == 20980 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20981 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20982 else if (chan_list_event_hdr->status_code == 20983 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20984 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20985 else if (chan_list_event_hdr->status_code == 20986 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20987 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20988 else if (chan_list_event_hdr->status_code == 20989 WMI_REG_SET_CC_STATUS_FAIL) 20990 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20991 20992 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20993 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20994 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20995 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20996 20997 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20998 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20999 21000 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 21001 __func__, reg_info->alpha2, reg_info->dfs_region, 21002 reg_info->min_bw_2g, reg_info->max_bw_2g, 21003 reg_info->min_bw_5g, reg_info->max_bw_5g); 21004 21005 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 21006 num_2g_reg_rules, num_5g_reg_rules); 21007 wmi_reg_rule = 21008 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 21009 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 21010 + WMI_TLV_HDR_SIZE); 21011 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 21012 wmi_reg_rule); 21013 wmi_reg_rule += num_2g_reg_rules; 21014 21015 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 21016 wmi_reg_rule); 21017 21018 WMI_LOGD("processed regulatory channel list"); 21019 21020 return QDF_STATUS_SUCCESS; 21021 } 21022 21023 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 21024 wmi_unified_t wmi_handle, uint8_t *evt_buf, 21025 struct reg_11d_new_country *reg_11d_country, uint32_t len) 21026 { 21027 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 21028 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 21029 21030 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 21031 if (!param_buf) { 21032 WMI_LOGE("invalid 11d country event buf"); 21033 return QDF_STATUS_E_FAILURE; 21034 } 21035 21036 reg_11d_country_event = param_buf->fixed_param; 21037 21038 qdf_mem_copy(reg_11d_country->alpha2, 21039 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 21040 21041 WMI_LOGD("processed 11d country event, new cc %s", 21042 reg_11d_country->alpha2); 21043 21044 return QDF_STATUS_SUCCESS; 21045 } 21046 21047 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 21048 wmi_unified_t wmi_handle, uint8_t *evt_buf, 21049 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 21050 { 21051 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 21052 wmi_avoid_freq_range_desc *afr_desc; 21053 uint32_t num_freq_ranges, freq_range_idx; 21054 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 21055 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 21056 21057 if (!param_buf) { 21058 WMI_LOGE("Invalid channel avoid event buffer"); 21059 return QDF_STATUS_E_INVAL; 21060 } 21061 21062 afr_fixed_param = param_buf->fixed_param; 21063 if (!afr_fixed_param) { 21064 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 21065 return QDF_STATUS_E_INVAL; 21066 } 21067 21068 if (!ch_avoid_ind) { 21069 WMI_LOGE("Invalid channel avoid indication buffer"); 21070 return QDF_STATUS_E_INVAL; 21071 } 21072 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 21073 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 21074 afr_fixed_param->num_freq_ranges; 21075 21076 WMI_LOGD("Channel avoid event received with %d ranges", 21077 num_freq_ranges); 21078 21079 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 21080 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 21081 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 21082 freq_range_idx++) { 21083 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 21084 afr_desc->start_freq; 21085 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 21086 afr_desc->end_freq; 21087 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 21088 freq_range_idx, afr_desc->tlv_header, 21089 afr_desc->start_freq, afr_desc->end_freq); 21090 afr_desc++; 21091 } 21092 21093 return QDF_STATUS_SUCCESS; 21094 } 21095 #ifdef DFS_COMPONENT_ENABLE 21096 /** 21097 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 21098 * @wmi_handle: wma handle 21099 * @evt_buf: event buffer 21100 * @vdev_id: vdev id 21101 * @len: length of buffer 21102 * 21103 * Return: 0 for success or error code 21104 */ 21105 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 21106 uint8_t *evt_buf, 21107 uint32_t *vdev_id, 21108 uint32_t len) 21109 { 21110 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 21111 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 21112 21113 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 21114 if (!param_tlvs) { 21115 WMI_LOGE("invalid cac complete event buf"); 21116 return QDF_STATUS_E_FAILURE; 21117 } 21118 21119 cac_event = param_tlvs->fixed_param; 21120 *vdev_id = cac_event->vdev_id; 21121 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 21122 21123 return QDF_STATUS_SUCCESS; 21124 } 21125 21126 /** 21127 * extract_dfs_radar_detection_event_tlv() - extract radar found event 21128 * @wmi_handle: wma handle 21129 * @evt_buf: event buffer 21130 * @radar_found: radar found event info 21131 * @len: length of buffer 21132 * 21133 * Return: 0 for success or error code 21134 */ 21135 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 21136 wmi_unified_t wmi_handle, 21137 uint8_t *evt_buf, 21138 struct radar_found_info *radar_found, 21139 uint32_t len) 21140 { 21141 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 21142 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 21143 21144 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 21145 if (!param_tlv) { 21146 WMI_LOGE("invalid radar detection event buf"); 21147 return QDF_STATUS_E_FAILURE; 21148 } 21149 21150 radar_event = param_tlv->fixed_param; 21151 radar_found->pdev_id = wmi_handle->ops-> 21152 convert_pdev_id_target_to_host(radar_event->pdev_id); 21153 radar_found->detection_mode = radar_event->detection_mode; 21154 radar_found->chan_freq = radar_event->chan_freq; 21155 radar_found->chan_width = radar_event->chan_width; 21156 radar_found->detector_id = radar_event->detector_id; 21157 radar_found->segment_id = radar_event->segment_id; 21158 radar_found->timestamp = radar_event->timestamp; 21159 radar_found->is_chirp = radar_event->is_chirp; 21160 radar_found->freq_offset = radar_event->freq_offset; 21161 radar_found->sidx = radar_event->sidx; 21162 21163 WMI_LOGI("processed radar found event pdev %d," 21164 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 21165 "chan_width (RSSI) %d,detector_id (false_radar) %d," 21166 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 21167 "is_chirp %d,detection mode %d\n", 21168 radar_event->pdev_id, radar_event->pdev_id, 21169 radar_event->timestamp, radar_event->chan_freq, 21170 radar_event->chan_width, radar_event->detector_id, 21171 radar_event->freq_offset, radar_event->segment_id, 21172 radar_event->sidx, radar_event->is_chirp, 21173 radar_event->detection_mode); 21174 21175 return QDF_STATUS_SUCCESS; 21176 } 21177 21178 #ifdef QCA_MCL_DFS_SUPPORT 21179 /** 21180 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 21181 * @wmi_handle: wma handle 21182 * @evt_buf: event buffer 21183 * @wlan_radar_event: Pointer to struct radar_event_info 21184 * @len: length of buffer 21185 * 21186 * Return: QDF_STATUS 21187 */ 21188 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21189 wmi_unified_t wmi_handle, 21190 uint8_t *evt_buf, 21191 struct radar_event_info *wlan_radar_event, 21192 uint32_t len) 21193 { 21194 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 21195 wmi_dfs_radar_event_fixed_param *radar_event; 21196 21197 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 21198 if (!param_tlv) { 21199 WMI_LOGE("invalid wlan radar event buf"); 21200 return QDF_STATUS_E_FAILURE; 21201 } 21202 21203 radar_event = param_tlv->fixed_param; 21204 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 21205 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 21206 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 21207 wlan_radar_event->rssi = radar_event->rssi; 21208 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 21209 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 21210 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 21211 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 21212 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 21213 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 21214 wlan_radar_event->pdev_id = radar_event->pdev_id; 21215 21216 return QDF_STATUS_SUCCESS; 21217 } 21218 #else 21219 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21220 wmi_unified_t wmi_handle, 21221 uint8_t *evt_buf, 21222 struct radar_event_info *wlan_radar_event, 21223 uint32_t len) 21224 { 21225 return QDF_STATUS_SUCCESS; 21226 } 21227 #endif 21228 #endif 21229 21230 /** 21231 * send_get_rcpi_cmd_tlv() - send request for rcpi value 21232 * @wmi_handle: wmi handle 21233 * @get_rcpi_param: rcpi params 21234 * 21235 * Return: QDF status 21236 */ 21237 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 21238 struct rcpi_req *get_rcpi_param) 21239 { 21240 wmi_buf_t buf; 21241 wmi_request_rcpi_cmd_fixed_param *cmd; 21242 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 21243 21244 buf = wmi_buf_alloc(wmi_handle, len); 21245 if (!buf) { 21246 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21247 return QDF_STATUS_E_NOMEM; 21248 } 21249 21250 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 21251 WMITLV_SET_HDR(&cmd->tlv_header, 21252 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 21253 WMITLV_GET_STRUCT_TLVLEN 21254 (wmi_request_rcpi_cmd_fixed_param)); 21255 21256 cmd->vdev_id = get_rcpi_param->vdev_id; 21257 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 21258 &cmd->peer_macaddr); 21259 21260 switch (get_rcpi_param->measurement_type) { 21261 21262 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21263 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21264 break; 21265 21266 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 21267 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 21268 break; 21269 21270 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21271 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21272 break; 21273 21274 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 21275 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 21276 break; 21277 21278 default: 21279 /* 21280 * invalid rcpi measurement type, fall back to 21281 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 21282 */ 21283 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21284 break; 21285 } 21286 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 21287 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21288 WMI_REQUEST_RCPI_CMDID)) { 21289 21290 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 21291 __func__); 21292 wmi_buf_free(buf); 21293 return QDF_STATUS_E_FAILURE; 21294 } 21295 21296 return QDF_STATUS_SUCCESS; 21297 } 21298 21299 /** 21300 * extract_rcpi_response_event_tlv() - Extract RCPI event params 21301 * @wmi_handle: wmi handle 21302 * @evt_buf: pointer to event buffer 21303 * @res: pointer to hold rcpi response from firmware 21304 * 21305 * Return: QDF_STATUS_SUCCESS for successful event parse 21306 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 21307 */ 21308 static QDF_STATUS 21309 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 21310 void *evt_buf, struct rcpi_res *res) 21311 { 21312 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 21313 wmi_update_rcpi_event_fixed_param *event; 21314 21315 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 21316 if (!param_buf) { 21317 WMI_LOGE(FL("Invalid rcpi event")); 21318 return QDF_STATUS_E_INVAL; 21319 } 21320 21321 event = param_buf->fixed_param; 21322 res->vdev_id = event->vdev_id; 21323 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 21324 21325 switch (event->measurement_type) { 21326 21327 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21328 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21329 break; 21330 21331 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 21332 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 21333 break; 21334 21335 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21336 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21337 break; 21338 21339 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 21340 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 21341 break; 21342 21343 default: 21344 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 21345 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 21346 return QDF_STATUS_E_FAILURE; 21347 } 21348 21349 if (event->status) 21350 return QDF_STATUS_E_FAILURE; 21351 else 21352 return QDF_STATUS_SUCCESS; 21353 } 21354 21355 /** 21356 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 21357 * host to target defines. For legacy there is not conversion 21358 * required. Just return pdev_id as it is. 21359 * @param pdev_id: host pdev_id to be converted. 21360 * Return: target pdev_id after conversion. 21361 */ 21362 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 21363 uint32_t pdev_id) 21364 { 21365 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 21366 return WMI_PDEV_ID_SOC; 21367 21368 /*No conversion required*/ 21369 return pdev_id; 21370 } 21371 21372 /** 21373 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 21374 * target to host defines. For legacy there is not conversion 21375 * required. Just return pdev_id as it is. 21376 * @param pdev_id: target pdev_id to be converted. 21377 * Return: host pdev_id after conversion. 21378 */ 21379 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 21380 uint32_t pdev_id) 21381 { 21382 /*No conversion required*/ 21383 return pdev_id; 21384 } 21385 21386 /** 21387 * send_set_country_cmd_tlv() - WMI scan channel list function 21388 * @param wmi_handle : handle to WMI. 21389 * @param param : pointer to hold scan channel list parameter 21390 * 21391 * Return: 0 on success and -ve on failure. 21392 */ 21393 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 21394 struct set_country *params) 21395 { 21396 wmi_buf_t buf; 21397 QDF_STATUS qdf_status; 21398 wmi_set_current_country_cmd_fixed_param *cmd; 21399 uint16_t len = sizeof(*cmd); 21400 21401 buf = wmi_buf_alloc(wmi_handle, len); 21402 if (!buf) { 21403 WMI_LOGE("Failed to allocate memory"); 21404 qdf_status = QDF_STATUS_E_NOMEM; 21405 goto end; 21406 } 21407 21408 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 21409 WMITLV_SET_HDR(&cmd->tlv_header, 21410 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 21411 WMITLV_GET_STRUCT_TLVLEN 21412 (wmi_set_current_country_cmd_fixed_param)); 21413 21414 WMI_LOGD("setting cuurnet country to %s", params->country); 21415 21416 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 21417 21418 cmd->pdev_id = params->pdev_id; 21419 21420 qdf_status = wmi_unified_cmd_send(wmi_handle, 21421 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 21422 21423 if (QDF_IS_STATUS_ERROR(qdf_status)) { 21424 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 21425 wmi_buf_free(buf); 21426 } 21427 21428 end: 21429 return qdf_status; 21430 } 21431 21432 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 21433 WMI_SET_BITS(alpha, 0, 8, val0); \ 21434 WMI_SET_BITS(alpha, 8, 8, val1); \ 21435 WMI_SET_BITS(alpha, 16, 8, val2); \ 21436 } while (0) 21437 21438 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 21439 uint8_t pdev_id, struct cc_regdmn_s *rd) 21440 { 21441 wmi_set_init_country_cmd_fixed_param *cmd; 21442 uint16_t len; 21443 wmi_buf_t buf; 21444 int ret; 21445 21446 len = sizeof(wmi_set_init_country_cmd_fixed_param); 21447 buf = wmi_buf_alloc(wmi_handle, len); 21448 if (!buf) { 21449 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 21450 return QDF_STATUS_E_NOMEM; 21451 } 21452 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 21453 WMITLV_SET_HDR(&cmd->tlv_header, 21454 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 21455 WMITLV_GET_STRUCT_TLVLEN 21456 (wmi_set_init_country_cmd_fixed_param)); 21457 21458 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 21459 21460 if (rd->flags == CC_IS_SET) { 21461 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 21462 cmd->country_code.country_id = rd->cc.country_code; 21463 } else if (rd->flags == ALPHA_IS_SET) { 21464 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 21465 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 21466 rd->cc.alpha[0], 21467 rd->cc.alpha[1], 21468 rd->cc.alpha[2]); 21469 } else if (rd->flags == REGDMN_IS_SET) { 21470 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 21471 cmd->country_code.domain_code = rd->cc.regdmn_id; 21472 } 21473 21474 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21475 WMI_SET_INIT_COUNTRY_CMDID); 21476 if (ret) { 21477 WMI_LOGE("Failed to config wow wakeup event"); 21478 wmi_buf_free(buf); 21479 return QDF_STATUS_E_FAILURE; 21480 } 21481 21482 return QDF_STATUS_SUCCESS; 21483 } 21484 21485 /** 21486 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 21487 * configuration params 21488 * @wmi_handle: wmi handler 21489 * @limit_off_chan_param: pointer to wmi_off_chan_param 21490 * 21491 * Return: 0 for success and non zero for failure 21492 */ 21493 static 21494 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 21495 struct wmi_limit_off_chan_param *limit_off_chan_param) 21496 { 21497 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 21498 wmi_buf_t buf; 21499 uint32_t len = sizeof(*cmd); 21500 int err; 21501 21502 buf = wmi_buf_alloc(wmi_handle, len); 21503 if (!buf) { 21504 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 21505 __func__); 21506 return QDF_STATUS_E_NOMEM; 21507 } 21508 21509 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 21510 21511 WMITLV_SET_HDR(&cmd->tlv_header, 21512 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 21513 WMITLV_GET_STRUCT_TLVLEN( 21514 wmi_vdev_limit_offchan_cmd_fixed_param)); 21515 21516 cmd->vdev_id = limit_off_chan_param->vdev_id; 21517 21518 cmd->flags &= 0; 21519 if (limit_off_chan_param->status) 21520 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 21521 if (limit_off_chan_param->skip_dfs_chans) 21522 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 21523 21524 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 21525 cmd->rest_time = limit_off_chan_param->rest_time; 21526 21527 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 21528 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 21529 cmd->rest_time); 21530 21531 err = wmi_unified_cmd_send(wmi_handle, buf, 21532 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 21533 if (QDF_IS_STATUS_ERROR(err)) { 21534 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 21535 wmi_buf_free(buf); 21536 return QDF_STATUS_E_FAILURE; 21537 } 21538 21539 return QDF_STATUS_SUCCESS; 21540 } 21541 21542 /** 21543 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 21544 * @wmi_handle: wmi handler 21545 * @req_buf: set arp stats request buffer 21546 * 21547 * Return: 0 for success and non zero for failure 21548 */ 21549 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21550 struct set_arp_stats *req_buf) 21551 { 21552 wmi_buf_t buf = NULL; 21553 QDF_STATUS status; 21554 int len; 21555 uint8_t *buf_ptr; 21556 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 21557 21558 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21559 if (req_buf->pkt_type_bitmap) { 21560 len += WMI_TLV_HDR_SIZE; 21561 len += sizeof(wmi_vdev_set_connectivity_check_stats); 21562 } 21563 buf = wmi_buf_alloc(wmi_handle, len); 21564 if (!buf) { 21565 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21566 return QDF_STATUS_E_NOMEM; 21567 } 21568 21569 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21570 wmi_set_arp = 21571 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 21572 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 21573 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 21574 WMITLV_GET_STRUCT_TLVLEN 21575 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 21576 21577 /* fill in per roam config values */ 21578 wmi_set_arp->vdev_id = req_buf->vdev_id; 21579 21580 wmi_set_arp->set_clr = req_buf->flag; 21581 wmi_set_arp->pkt_type = req_buf->pkt_type; 21582 wmi_set_arp->ipv4 = req_buf->ip_addr; 21583 21584 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 21585 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 21586 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 21587 21588 /* 21589 * pkt_type_bitmap should be non-zero to ensure 21590 * presence of additional stats. 21591 */ 21592 if (req_buf->pkt_type_bitmap) { 21593 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21594 21595 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21596 WMITLV_SET_HDR(buf_ptr, 21597 WMITLV_TAG_ARRAY_STRUC, 21598 sizeof(wmi_vdev_set_connectivity_check_stats)); 21599 buf_ptr += WMI_TLV_HDR_SIZE; 21600 wmi_set_connect_stats = 21601 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21602 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21603 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21604 WMITLV_GET_STRUCT_TLVLEN( 21605 wmi_vdev_set_connectivity_check_stats)); 21606 wmi_set_connect_stats->pkt_type_bitmap = 21607 req_buf->pkt_type_bitmap; 21608 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21609 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21610 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21611 21612 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21613 wmi_set_connect_stats->pkt_type_bitmap, 21614 wmi_set_connect_stats->tcp_src_port, 21615 wmi_set_connect_stats->tcp_dst_port, 21616 wmi_set_connect_stats->icmp_ipv4); 21617 } 21618 21619 /* Send per roam config parameters */ 21620 status = wmi_unified_cmd_send(wmi_handle, buf, 21621 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21622 if (QDF_IS_STATUS_ERROR(status)) { 21623 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21624 status); 21625 goto error; 21626 } 21627 21628 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 21629 req_buf->flag, req_buf->vdev_id); 21630 return QDF_STATUS_SUCCESS; 21631 error: 21632 wmi_buf_free(buf); 21633 21634 return status; 21635 } 21636 21637 /** 21638 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21639 * @wmi_handle: wmi handler 21640 * @req_buf: get arp stats request buffer 21641 * 21642 * Return: 0 for success and non zero for failure 21643 */ 21644 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21645 struct get_arp_stats *req_buf) 21646 { 21647 wmi_buf_t buf = NULL; 21648 QDF_STATUS status; 21649 int len; 21650 uint8_t *buf_ptr; 21651 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21652 21653 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21654 buf = wmi_buf_alloc(wmi_handle, len); 21655 if (!buf) { 21656 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21657 return QDF_STATUS_E_NOMEM; 21658 } 21659 21660 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21661 get_arp_stats = 21662 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21663 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21664 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21665 WMITLV_GET_STRUCT_TLVLEN 21666 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21667 21668 /* fill in arp stats req cmd values */ 21669 get_arp_stats->vdev_id = req_buf->vdev_id; 21670 21671 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21672 /* Send per roam config parameters */ 21673 status = wmi_unified_cmd_send(wmi_handle, buf, 21674 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21675 if (QDF_IS_STATUS_ERROR(status)) { 21676 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21677 status); 21678 goto error; 21679 } 21680 21681 return QDF_STATUS_SUCCESS; 21682 error: 21683 wmi_buf_free(buf); 21684 21685 return status; 21686 } 21687 21688 /** 21689 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21690 * @wmi_handle: wmi handler 21691 * @pmk_info: pointer to PMK cache entry 21692 * @vdev_id: vdev id 21693 * 21694 * Return: 0 for success and non zero for failure 21695 */ 21696 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21697 struct wmi_unified_pmk_cache *pmk_info) 21698 { 21699 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21700 wmi_buf_t buf; 21701 QDF_STATUS status; 21702 uint8_t *buf_ptr; 21703 wmi_pmk_cache *pmksa; 21704 uint32_t len = sizeof(*cmd); 21705 21706 if (pmk_info->pmk_len) 21707 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21708 21709 buf = wmi_buf_alloc(wmi_handle, len); 21710 if (!buf) { 21711 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21712 __func__); 21713 return QDF_STATUS_E_NOMEM; 21714 } 21715 21716 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21717 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21718 21719 WMITLV_SET_HDR(&cmd->tlv_header, 21720 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21721 WMITLV_GET_STRUCT_TLVLEN( 21722 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21723 21724 cmd->vdev_id = pmk_info->session_id; 21725 21726 /* If pmk_info->pmk_len is 0, this is a flush request */ 21727 if (!pmk_info->pmk_len) { 21728 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21729 cmd->num_cache = 0; 21730 goto send_cmd; 21731 } 21732 21733 cmd->num_cache = 1; 21734 buf_ptr += sizeof(*cmd); 21735 21736 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21737 sizeof(*pmksa)); 21738 buf_ptr += WMI_TLV_HDR_SIZE; 21739 21740 pmksa = (wmi_pmk_cache *)buf_ptr; 21741 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21742 WMITLV_GET_STRUCT_TLVLEN 21743 (wmi_pmk_cache)); 21744 pmksa->pmk_len = pmk_info->pmk_len; 21745 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21746 pmksa->pmkid_len = pmk_info->pmkid_len; 21747 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21748 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21749 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21750 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21751 pmksa->ssid.ssid_len); 21752 pmksa->cache_id = pmk_info->cache_id; 21753 pmksa->cat_flag = pmk_info->cat_flag; 21754 pmksa->action_flag = pmk_info->action_flag; 21755 21756 send_cmd: 21757 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21758 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21759 if (status != QDF_STATUS_SUCCESS) { 21760 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21761 __func__, status); 21762 wmi_buf_free(buf); 21763 } 21764 21765 return status; 21766 } 21767 21768 /** 21769 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21770 * @wmi_handle: wmi handle 21771 * @param: reserved param 21772 * 21773 * Return: 0 for success or error code 21774 */ 21775 static QDF_STATUS 21776 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21777 uint32_t param) 21778 { 21779 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21780 wmi_buf_t buf; 21781 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21782 21783 buf = wmi_buf_alloc(wmi_handle, len); 21784 if (!buf) { 21785 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21786 return QDF_STATUS_E_FAILURE; 21787 } 21788 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21789 WMITLV_SET_HDR(&cmd->tlv_header, 21790 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21791 WMITLV_GET_STRUCT_TLVLEN 21792 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21793 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21794 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21795 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21796 wmi_buf_free(buf); 21797 return QDF_STATUS_E_FAILURE; 21798 } 21799 21800 return QDF_STATUS_SUCCESS; 21801 } 21802 21803 /** 21804 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 21805 * host to target defines. 21806 * @param pdev_id: host pdev_id to be converted. 21807 * Return: target pdev_id after conversion. 21808 */ 21809 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 21810 { 21811 switch (pdev_id) { 21812 case WMI_HOST_PDEV_ID_SOC: 21813 return WMI_PDEV_ID_SOC; 21814 case WMI_HOST_PDEV_ID_0: 21815 return WMI_PDEV_ID_1ST; 21816 case WMI_HOST_PDEV_ID_1: 21817 return WMI_PDEV_ID_2ND; 21818 case WMI_HOST_PDEV_ID_2: 21819 return WMI_PDEV_ID_3RD; 21820 } 21821 21822 QDF_ASSERT(0); 21823 21824 return WMI_PDEV_ID_SOC; 21825 } 21826 21827 /** 21828 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 21829 * target to host defines. 21830 * @param pdev_id: target pdev_id to be converted. 21831 * Return: host pdev_id after conversion. 21832 */ 21833 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 21834 { 21835 switch (pdev_id) { 21836 case WMI_PDEV_ID_SOC: 21837 return WMI_HOST_PDEV_ID_SOC; 21838 case WMI_PDEV_ID_1ST: 21839 return WMI_HOST_PDEV_ID_0; 21840 case WMI_PDEV_ID_2ND: 21841 return WMI_HOST_PDEV_ID_1; 21842 case WMI_PDEV_ID_3RD: 21843 return WMI_HOST_PDEV_ID_2; 21844 } 21845 21846 QDF_ASSERT(0); 21847 21848 return WMI_HOST_PDEV_ID_SOC; 21849 } 21850 21851 /** 21852 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 21853 * 21854 * Return None. 21855 */ 21856 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 21857 { 21858 wmi_handle->ops->convert_pdev_id_host_to_target = 21859 convert_host_pdev_id_to_target_pdev_id; 21860 wmi_handle->ops->convert_pdev_id_target_to_host = 21861 convert_target_pdev_id_to_host_pdev_id; 21862 } 21863 21864 /** 21865 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21866 * @wmi_handle: wmi handle 21867 * @param evt_buf: pointer to event buffer 21868 * @param param: Pointer to hold peer caldata version data 21869 * 21870 * Return: 0 for success or error code 21871 */ 21872 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21873 wmi_unified_t wmi_handle, 21874 void *evt_buf, 21875 wmi_host_pdev_check_cal_version_event *param) 21876 { 21877 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21878 wmi_pdev_check_cal_version_event_fixed_param *event; 21879 21880 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21881 if (!param_tlvs) { 21882 WMI_LOGE("invalid cal version event buf"); 21883 return QDF_STATUS_E_FAILURE; 21884 } 21885 event = param_tlvs->fixed_param; 21886 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21887 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21888 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21889 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21890 21891 param->software_cal_version = event->software_cal_version; 21892 param->board_cal_version = event->board_cal_version; 21893 param->cal_ok = event->cal_status; 21894 21895 return QDF_STATUS_SUCCESS; 21896 } 21897 21898 /* 21899 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21900 * @wmi_handle: wmi handle 21901 * @params: pointer to wmi_btm_config 21902 * 21903 * Return: QDF_STATUS 21904 */ 21905 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21906 struct wmi_btm_config *params) 21907 { 21908 21909 wmi_btm_config_fixed_param *cmd; 21910 wmi_buf_t buf; 21911 uint32_t len; 21912 21913 len = sizeof(*cmd); 21914 buf = wmi_buf_alloc(wmi_handle, len); 21915 if (!buf) { 21916 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21917 return QDF_STATUS_E_NOMEM; 21918 } 21919 21920 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21921 WMITLV_SET_HDR(&cmd->tlv_header, 21922 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21923 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21924 cmd->vdev_id = params->vdev_id; 21925 cmd->flags = params->btm_offload_config; 21926 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21927 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21928 cmd->stick_time_seconds = params->btm_sticky_time; 21929 21930 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21931 WMI_ROAM_BTM_CONFIG_CMDID)) { 21932 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21933 __func__); 21934 wmi_buf_free(buf); 21935 return QDF_STATUS_E_FAILURE; 21936 } 21937 21938 return QDF_STATUS_SUCCESS; 21939 } 21940 21941 /** 21942 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21943 * configurations to firmware. 21944 * @wmi_handle: wmi handle 21945 * @obss_cfg_param: obss detection configurations 21946 * 21947 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21948 * 21949 * Return: QDF_STATUS 21950 */ 21951 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21952 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21953 { 21954 wmi_buf_t buf; 21955 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21956 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21957 21958 buf = wmi_buf_alloc(wmi_handle, len); 21959 if (!buf) { 21960 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21961 return QDF_STATUS_E_NOMEM; 21962 } 21963 21964 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21965 WMITLV_SET_HDR(&cmd->tlv_header, 21966 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21967 WMITLV_GET_STRUCT_TLVLEN 21968 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21969 21970 cmd->vdev_id = obss_cfg_param->vdev_id; 21971 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21972 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21973 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21974 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21975 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21976 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21977 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21978 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21979 21980 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21981 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21982 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21983 wmi_buf_free(buf); 21984 return QDF_STATUS_E_FAILURE; 21985 } 21986 21987 return QDF_STATUS_SUCCESS; 21988 } 21989 21990 /** 21991 * extract_obss_detection_info_tlv() - Extract obss detection info 21992 * received from firmware. 21993 * @evt_buf: pointer to event buffer 21994 * @obss_detection: Pointer to hold obss detection info 21995 * 21996 * Return: QDF_STATUS 21997 */ 21998 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21999 struct wmi_obss_detect_info 22000 *obss_detection) 22001 { 22002 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 22003 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 22004 22005 if (!obss_detection) { 22006 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 22007 return QDF_STATUS_E_INVAL; 22008 } 22009 22010 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 22011 if (!param_buf) { 22012 WMI_LOGE("%s: Invalid evt_buf", __func__); 22013 return QDF_STATUS_E_INVAL; 22014 } 22015 22016 fix_param = param_buf->fixed_param; 22017 obss_detection->vdev_id = fix_param->vdev_id; 22018 obss_detection->matched_detection_masks = 22019 fix_param->matched_detection_masks; 22020 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 22021 &obss_detection->matched_bssid_addr[0]); 22022 switch (fix_param->reason) { 22023 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 22024 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 22025 break; 22026 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 22027 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 22028 break; 22029 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 22030 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 22031 break; 22032 default: 22033 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 22034 return QDF_STATUS_E_INVAL; 22035 } 22036 22037 return QDF_STATUS_SUCCESS; 22038 } 22039 22040 /** 22041 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 22042 * @wmi_handle: wmi handler 22043 * @params: pointer to 11k offload params 22044 * 22045 * Return: 0 for success and non zero for failure 22046 */ 22047 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 22048 struct wmi_11k_offload_params *params) 22049 { 22050 wmi_11k_offload_report_fixed_param *cmd; 22051 wmi_buf_t buf; 22052 QDF_STATUS status; 22053 uint8_t *buf_ptr; 22054 wmi_neighbor_report_11k_offload_tlv_param 22055 *neighbor_report_offload_params; 22056 wmi_neighbor_report_offload *neighbor_report_offload; 22057 22058 uint32_t len = sizeof(*cmd); 22059 22060 if (params->offload_11k_bitmask & 22061 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 22062 len += WMI_TLV_HDR_SIZE + 22063 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 22064 22065 buf = wmi_buf_alloc(wmi_handle, len); 22066 if (!buf) { 22067 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 22068 __func__); 22069 return QDF_STATUS_E_NOMEM; 22070 } 22071 22072 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22073 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 22074 22075 WMITLV_SET_HDR(&cmd->tlv_header, 22076 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 22077 WMITLV_GET_STRUCT_TLVLEN( 22078 wmi_11k_offload_report_fixed_param)); 22079 22080 cmd->vdev_id = params->vdev_id; 22081 cmd->offload_11k = params->offload_11k_bitmask; 22082 22083 if (params->offload_11k_bitmask & 22084 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 22085 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 22086 22087 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 22088 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 22089 buf_ptr += WMI_TLV_HDR_SIZE; 22090 22091 neighbor_report_offload_params = 22092 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 22093 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 22094 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 22095 WMITLV_GET_STRUCT_TLVLEN( 22096 wmi_neighbor_report_11k_offload_tlv_param)); 22097 22098 neighbor_report_offload = &neighbor_report_offload_params-> 22099 neighbor_rep_ofld_params; 22100 22101 neighbor_report_offload->time_offset = 22102 params->neighbor_report_params.time_offset; 22103 neighbor_report_offload->low_rssi_offset = 22104 params->neighbor_report_params.low_rssi_offset; 22105 neighbor_report_offload->bmiss_count_trigger = 22106 params->neighbor_report_params.bmiss_count_trigger; 22107 neighbor_report_offload->per_threshold_offset = 22108 params->neighbor_report_params.per_threshold_offset; 22109 neighbor_report_offload->neighbor_report_cache_timeout = 22110 params->neighbor_report_params. 22111 neighbor_report_cache_timeout; 22112 neighbor_report_offload->max_neighbor_report_req_cap = 22113 params->neighbor_report_params. 22114 max_neighbor_report_req_cap; 22115 neighbor_report_offload->ssid.ssid_len = 22116 params->neighbor_report_params.ssid.length; 22117 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 22118 ¶ms->neighbor_report_params.ssid.mac_ssid, 22119 neighbor_report_offload->ssid.ssid_len); 22120 } 22121 22122 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22123 WMI_11K_OFFLOAD_REPORT_CMDID); 22124 if (status != QDF_STATUS_SUCCESS) { 22125 WMI_LOGE("%s: failed to send 11k offload command %d", 22126 __func__, status); 22127 wmi_buf_free(buf); 22128 } 22129 22130 return status; 22131 } 22132 22133 /** 22134 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 22135 * command 22136 * @wmi_handle: wmi handler 22137 * @params: pointer to neighbor report invoke params 22138 * 22139 * Return: 0 for success and non zero for failure 22140 */ 22141 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 22142 struct wmi_invoke_neighbor_report_params *params) 22143 { 22144 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 22145 wmi_buf_t buf; 22146 QDF_STATUS status; 22147 uint8_t *buf_ptr; 22148 uint32_t len = sizeof(*cmd); 22149 22150 buf = wmi_buf_alloc(wmi_handle, len); 22151 if (!buf) { 22152 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 22153 __func__); 22154 return QDF_STATUS_E_NOMEM; 22155 } 22156 22157 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22158 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 22159 22160 WMITLV_SET_HDR(&cmd->tlv_header, 22161 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 22162 WMITLV_GET_STRUCT_TLVLEN( 22163 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 22164 22165 cmd->vdev_id = params->vdev_id; 22166 cmd->flags = params->send_resp_to_host; 22167 22168 cmd->ssid.ssid_len = params->ssid.length; 22169 qdf_mem_copy(cmd->ssid.ssid, 22170 ¶ms->ssid.mac_ssid, 22171 cmd->ssid.ssid_len); 22172 22173 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22174 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 22175 if (status != QDF_STATUS_SUCCESS) { 22176 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 22177 __func__, status); 22178 wmi_buf_free(buf); 22179 } 22180 22181 return status; 22182 } 22183 22184 #ifdef WLAN_SUPPORT_GREEN_AP 22185 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 22186 uint8_t *evt_buf, 22187 struct wlan_green_ap_egap_status_info *egap_status_info_params) 22188 { 22189 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 22190 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 22191 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 22192 22193 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 22194 if (!param_buf) { 22195 WMI_LOGE("Invalid EGAP Info status event buffer"); 22196 return QDF_STATUS_E_INVAL; 22197 } 22198 22199 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 22200 param_buf->fixed_param; 22201 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 22202 param_buf->chainmask_list; 22203 22204 egap_status_info_params->status = egap_info_event->status; 22205 egap_status_info_params->mac_id = chainmask_event->mac_id; 22206 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 22207 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 22208 22209 return QDF_STATUS_SUCCESS; 22210 } 22211 #endif 22212 22213 /* 22214 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 22215 * updating bss color change within firmware when AP announces bss color change. 22216 * @wmi_handle: wmi handle 22217 * @vdev_id: vdev ID 22218 * @enable: enable bss color change within firmware 22219 * 22220 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 22221 * 22222 * Return: QDF_STATUS 22223 */ 22224 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 22225 uint32_t vdev_id, 22226 bool enable) 22227 { 22228 wmi_buf_t buf; 22229 wmi_bss_color_change_enable_fixed_param *cmd; 22230 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 22231 22232 buf = wmi_buf_alloc(wmi_handle, len); 22233 if (!buf) { 22234 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22235 return QDF_STATUS_E_NOMEM; 22236 } 22237 22238 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 22239 WMITLV_SET_HDR(&cmd->tlv_header, 22240 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 22241 WMITLV_GET_STRUCT_TLVLEN 22242 (wmi_bss_color_change_enable_fixed_param)); 22243 cmd->vdev_id = vdev_id; 22244 cmd->enable = enable; 22245 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22246 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 22247 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 22248 wmi_buf_free(buf); 22249 return QDF_STATUS_E_FAILURE; 22250 } 22251 22252 return QDF_STATUS_SUCCESS; 22253 } 22254 22255 /** 22256 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 22257 * configurations to firmware. 22258 * @wmi_handle: wmi handle 22259 * @cfg_param: obss detection configurations 22260 * 22261 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 22262 * 22263 * Return: QDF_STATUS 22264 */ 22265 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 22266 wmi_unified_t wmi_handle, 22267 struct wmi_obss_color_collision_cfg_param *cfg_param) 22268 { 22269 wmi_buf_t buf; 22270 wmi_obss_color_collision_det_config_fixed_param *cmd; 22271 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 22272 22273 buf = wmi_buf_alloc(wmi_handle, len); 22274 if (!buf) { 22275 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22276 return QDF_STATUS_E_NOMEM; 22277 } 22278 22279 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 22280 buf); 22281 WMITLV_SET_HDR(&cmd->tlv_header, 22282 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 22283 WMITLV_GET_STRUCT_TLVLEN 22284 (wmi_obss_color_collision_det_config_fixed_param)); 22285 cmd->vdev_id = cfg_param->vdev_id; 22286 cmd->flags = cfg_param->flags; 22287 cmd->current_bss_color = cfg_param->current_bss_color; 22288 cmd->detection_period_ms = cfg_param->detection_period_ms; 22289 cmd->scan_period_ms = cfg_param->scan_period_ms; 22290 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 22291 22292 switch (cfg_param->evt_type) { 22293 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 22294 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 22295 break; 22296 case OBSS_COLOR_COLLISION_DETECTION: 22297 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 22298 break; 22299 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22300 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22301 break; 22302 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 22303 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 22304 break; 22305 default: 22306 WMI_LOGE("%s: invalid event type: %d", 22307 __func__, cfg_param->evt_type); 22308 wmi_buf_free(buf); 22309 return QDF_STATUS_E_FAILURE; 22310 } 22311 22312 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22313 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 22314 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 22315 __func__, cfg_param->vdev_id); 22316 wmi_buf_free(buf); 22317 return QDF_STATUS_E_FAILURE; 22318 } 22319 22320 return QDF_STATUS_SUCCESS; 22321 } 22322 22323 /** 22324 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 22325 * received from firmware. 22326 * @evt_buf: pointer to event buffer 22327 * @info: Pointer to hold bss collision info 22328 * 22329 * Return: QDF_STATUS 22330 */ 22331 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 22332 struct wmi_obss_color_collision_info *info) 22333 { 22334 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 22335 wmi_obss_color_collision_evt_fixed_param *fix_param; 22336 22337 if (!info) { 22338 WMI_LOGE("%s: Invalid obss color buffer", __func__); 22339 return QDF_STATUS_E_INVAL; 22340 } 22341 22342 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 22343 evt_buf; 22344 if (!param_buf) { 22345 WMI_LOGE("%s: Invalid evt_buf", __func__); 22346 return QDF_STATUS_E_INVAL; 22347 } 22348 22349 fix_param = param_buf->fixed_param; 22350 info->vdev_id = fix_param->vdev_id; 22351 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 22352 info->obss_color_bitmap_bit32to63 = 22353 fix_param->bss_color_bitmap_bit32to63; 22354 22355 switch (fix_param->evt_type) { 22356 case WMI_BSS_COLOR_COLLISION_DISABLE: 22357 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 22358 break; 22359 case WMI_BSS_COLOR_COLLISION_DETECTION: 22360 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 22361 break; 22362 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22363 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22364 break; 22365 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 22366 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 22367 break; 22368 default: 22369 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 22370 __func__, fix_param->evt_type, fix_param->vdev_id); 22371 return QDF_STATUS_E_FAILURE; 22372 } 22373 22374 return QDF_STATUS_SUCCESS; 22375 } 22376 22377 /* 22378 * extract_comb_phyerr_tlv() - extract comb phy error from event 22379 * @wmi_handle: wmi handle 22380 * @evt_buf: pointer to event buffer 22381 * @datalen: data length of event buffer 22382 * @buf_offset: Pointer to hold value of current event buffer offset 22383 * post extraction 22384 * @phyerr: Pointer to hold phyerr 22385 * 22386 * Return: QDF_STATUS 22387 */ 22388 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 22389 void *evt_buf, 22390 uint16_t datalen, 22391 uint16_t *buf_offset, 22392 wmi_host_phyerr_t *phyerr) 22393 { 22394 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 22395 wmi_comb_phyerr_rx_hdr *pe_hdr; 22396 22397 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 22398 if (!param_tlvs) { 22399 WMI_LOGD("%s: Received null data from FW", __func__); 22400 return QDF_STATUS_E_FAILURE; 22401 } 22402 22403 pe_hdr = param_tlvs->hdr; 22404 if (!pe_hdr) { 22405 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 22406 return QDF_STATUS_E_FAILURE; 22407 } 22408 22409 /* Ensure it's at least the size of the header */ 22410 if (datalen < sizeof(*pe_hdr)) { 22411 WMI_LOGD("%s: Expected minimum size %zu, received %d", 22412 __func__, sizeof(*pe_hdr), datalen); 22413 return QDF_STATUS_E_FAILURE; 22414 } 22415 22416 phyerr->pdev_id = wmi_handle->ops-> 22417 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 22418 phyerr->tsf64 = pe_hdr->tsf_l32; 22419 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 22420 phyerr->bufp = param_tlvs->bufp; 22421 phyerr->buf_len = pe_hdr->buf_len; 22422 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 22423 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 22424 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 22425 22426 return QDF_STATUS_SUCCESS; 22427 } 22428 22429 /** 22430 * extract_single_phyerr_tlv() - extract single phy error from event 22431 * @wmi_handle: wmi handle 22432 * @evt_buf: pointer to event buffer 22433 * @datalen: data length of event buffer 22434 * @buf_offset: Pointer to hold value of current event buffer offset 22435 * post extraction 22436 * @phyerr: Pointer to hold phyerr 22437 * 22438 * Return: QDF_STATUS 22439 */ 22440 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 22441 void *evt_buf, 22442 uint16_t datalen, 22443 uint16_t *buf_offset, 22444 wmi_host_phyerr_t *phyerr) 22445 { 22446 wmi_single_phyerr_rx_event *ev; 22447 uint16_t n = *buf_offset; 22448 uint8_t *data = (uint8_t *)evt_buf; 22449 22450 if (n < datalen) { 22451 if ((datalen - n) < sizeof(ev->hdr)) { 22452 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 22453 __func__, datalen, n, sizeof(ev->hdr)); 22454 return QDF_STATUS_E_FAILURE; 22455 } 22456 22457 /* 22458 * Obtain a pointer to the beginning of the current event. 22459 * data[0] is the beginning of the WMI payload. 22460 */ 22461 ev = (wmi_single_phyerr_rx_event *)&data[n]; 22462 22463 /* 22464 * Sanity check the buffer length of the event against 22465 * what we currently have. 22466 * 22467 * Since buf_len is 32 bits, we check if it overflows 22468 * a large 32 bit value. It's not 0x7fffffff because 22469 * we increase n by (buf_len + sizeof(hdr)), which would 22470 * in itself cause n to overflow. 22471 * 22472 * If "int" is 64 bits then this becomes a moot point. 22473 */ 22474 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 22475 WMI_LOGD("%s: buf_len is garbage 0x%x", 22476 __func__, ev->hdr.buf_len); 22477 return QDF_STATUS_E_FAILURE; 22478 } 22479 22480 if ((n + ev->hdr.buf_len) > datalen) { 22481 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 22482 __func__, n, ev->hdr.buf_len, datalen); 22483 return QDF_STATUS_E_FAILURE; 22484 } 22485 22486 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 22487 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 22488 phyerr->bufp = &ev->bufp[0]; 22489 phyerr->buf_len = ev->hdr.buf_len; 22490 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 22491 22492 /* 22493 * Advance the buffer pointer to the next PHY error. 22494 * buflen is the length of this payload, so we need to 22495 * advance past the current header _AND_ the payload. 22496 */ 22497 n += sizeof(*ev) + ev->hdr.buf_len; 22498 } 22499 *buf_offset = n; 22500 22501 return QDF_STATUS_SUCCESS; 22502 } 22503 22504 struct wmi_ops tlv_ops = { 22505 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 22506 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 22507 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 22508 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 22509 .send_hidden_ssid_vdev_restart_cmd = 22510 send_hidden_ssid_vdev_restart_cmd_tlv, 22511 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 22512 .send_peer_param_cmd = send_peer_param_cmd_tlv, 22513 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 22514 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 22515 .send_peer_create_cmd = send_peer_create_cmd_tlv, 22516 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 22517 .send_peer_rx_reorder_queue_setup_cmd = 22518 send_peer_rx_reorder_queue_setup_cmd_tlv, 22519 .send_peer_rx_reorder_queue_remove_cmd = 22520 send_peer_rx_reorder_queue_remove_cmd_tlv, 22521 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 22522 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 22523 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 22524 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 22525 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 22526 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 22527 .send_suspend_cmd = send_suspend_cmd_tlv, 22528 .send_resume_cmd = send_resume_cmd_tlv, 22529 #ifdef FEATURE_WLAN_D0WOW 22530 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 22531 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 22532 #endif 22533 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 22534 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 22535 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 22536 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 22537 .send_dbglog_cmd = send_dbglog_cmd_tlv, 22538 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 22539 .send_stats_request_cmd = send_stats_request_cmd_tlv, 22540 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 22541 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 22542 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 22543 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 22544 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 22545 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 22546 .send_scan_start_cmd = send_scan_start_cmd_tlv, 22547 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 22548 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 22549 .send_mgmt_cmd = send_mgmt_cmd_tlv, 22550 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 22551 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 22552 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 22553 .send_set_sta_uapsd_auto_trig_cmd = 22554 send_set_sta_uapsd_auto_trig_cmd_tlv, 22555 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 22556 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 22557 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 22558 #ifdef CONVERGED_P2P_ENABLE 22559 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 22560 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 22561 #endif 22562 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 22563 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 22564 #ifdef WLAN_FEATURE_DSRC 22565 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 22566 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 22567 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 22568 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 22569 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 22570 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 22571 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 22572 .send_ocb_start_timing_advert_cmd = 22573 send_ocb_start_timing_advert_cmd_tlv, 22574 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 22575 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 22576 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 22577 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 22578 #endif 22579 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 22580 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 22581 .send_set_mcc_channel_time_latency_cmd = 22582 send_set_mcc_channel_time_latency_cmd_tlv, 22583 .send_set_mcc_channel_time_quota_cmd = 22584 send_set_mcc_channel_time_quota_cmd_tlv, 22585 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 22586 .send_lro_config_cmd = send_lro_config_cmd_tlv, 22587 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 22588 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 22589 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 22590 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 22591 .send_probe_rsp_tmpl_send_cmd = 22592 send_probe_rsp_tmpl_send_cmd_tlv, 22593 .send_p2p_go_set_beacon_ie_cmd = 22594 send_p2p_go_set_beacon_ie_cmd_tlv, 22595 .send_setup_install_key_cmd = 22596 send_setup_install_key_cmd_tlv, 22597 .send_set_gateway_params_cmd = 22598 send_set_gateway_params_cmd_tlv, 22599 .send_set_rssi_monitoring_cmd = 22600 send_set_rssi_monitoring_cmd_tlv, 22601 .send_scan_probe_setoui_cmd = 22602 send_scan_probe_setoui_cmd_tlv, 22603 .send_reset_passpoint_network_list_cmd = 22604 send_reset_passpoint_network_list_cmd_tlv, 22605 .send_set_passpoint_network_list_cmd = 22606 send_set_passpoint_network_list_cmd_tlv, 22607 .send_roam_scan_offload_rssi_thresh_cmd = 22608 send_roam_scan_offload_rssi_thresh_cmd_tlv, 22609 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 22610 .send_roam_scan_filter_cmd = 22611 send_roam_scan_filter_cmd_tlv, 22612 .send_set_epno_network_list_cmd = 22613 send_set_epno_network_list_cmd_tlv, 22614 #ifdef IPA_OFFLOAD 22615 .send_ipa_offload_control_cmd = 22616 send_ipa_offload_control_cmd_tlv, 22617 #endif 22618 .send_extscan_get_capabilities_cmd = 22619 send_extscan_get_capabilities_cmd_tlv, 22620 .send_extscan_get_cached_results_cmd = 22621 send_extscan_get_cached_results_cmd_tlv, 22622 .send_extscan_stop_change_monitor_cmd = 22623 send_extscan_stop_change_monitor_cmd_tlv, 22624 .send_extscan_start_change_monitor_cmd = 22625 send_extscan_start_change_monitor_cmd_tlv, 22626 .send_extscan_stop_hotlist_monitor_cmd = 22627 send_extscan_stop_hotlist_monitor_cmd_tlv, 22628 .send_stop_extscan_cmd = send_stop_extscan_cmd_tlv, 22629 .send_start_extscan_cmd = send_start_extscan_cmd_tlv, 22630 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 22631 .send_plm_start_cmd = send_plm_start_cmd_tlv, 22632 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 22633 .send_pno_start_cmd = send_pno_start_cmd_tlv, 22634 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 22635 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 22636 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 22637 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 22638 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 22639 .send_congestion_cmd = send_congestion_cmd_tlv, 22640 .send_snr_request_cmd = send_snr_request_cmd_tlv, 22641 .send_snr_cmd = send_snr_cmd_tlv, 22642 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 22643 #ifdef WLAN_PMO_ENABLE 22644 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 22645 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 22646 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 22647 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 22648 .send_multiple_add_clear_mcbc_filter_cmd = 22649 send_multiple_add_clear_mcbc_filter_cmd_tlv, 22650 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 22651 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 22652 .send_process_gtk_offload_getinfo_cmd = 22653 send_process_gtk_offload_getinfo_cmd_tlv, 22654 .send_enable_enhance_multicast_offload_cmd = 22655 send_enable_enhance_multicast_offload_tlv, 22656 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 22657 #ifdef FEATURE_WLAN_RA_FILTERING 22658 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 22659 #endif 22660 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 22661 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 22662 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 22663 .send_lphb_config_tcp_pkt_filter_cmd = 22664 send_lphb_config_tcp_pkt_filter_cmd_tlv, 22665 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22666 .send_lphb_config_udp_pkt_filter_cmd = 22667 send_lphb_config_udp_pkt_filter_cmd_tlv, 22668 .send_enable_disable_packet_filter_cmd = 22669 send_enable_disable_packet_filter_cmd_tlv, 22670 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22671 #endif /* End of WLAN_PMO_ENABLE */ 22672 #ifdef CONFIG_MCL 22673 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22674 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22675 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22676 .send_roam_scan_offload_mode_cmd = 22677 send_roam_scan_offload_mode_cmd_tlv, 22678 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22679 .send_roam_scan_offload_ap_profile_cmd = 22680 send_roam_scan_offload_ap_profile_cmd_tlv, 22681 #endif 22682 #ifdef WLAN_SUPPORT_GREEN_AP 22683 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22684 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22685 .extract_green_ap_egap_status_info = 22686 extract_green_ap_egap_status_info_tlv, 22687 #endif 22688 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22689 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22690 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22691 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22692 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22693 #ifdef WLAN_FEATURE_CIF_CFR 22694 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22695 #endif 22696 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22697 .send_dfs_phyerr_filter_offload_en_cmd = 22698 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22699 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22700 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22701 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22702 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22703 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22704 .send_process_add_periodic_tx_ptrn_cmd = 22705 send_process_add_periodic_tx_ptrn_cmd_tlv, 22706 .send_process_del_periodic_tx_ptrn_cmd = 22707 send_process_del_periodic_tx_ptrn_cmd_tlv, 22708 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22709 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22710 .send_set_app_type2_params_in_fw_cmd = 22711 send_set_app_type2_params_in_fw_cmd_tlv, 22712 .send_set_auto_shutdown_timer_cmd = 22713 send_set_auto_shutdown_timer_cmd_tlv, 22714 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22715 .send_process_dhcpserver_offload_cmd = 22716 send_process_dhcpserver_offload_cmd_tlv, 22717 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22718 .send_process_ch_avoid_update_cmd = 22719 send_process_ch_avoid_update_cmd_tlv, 22720 .send_pdev_set_regdomain_cmd = 22721 send_pdev_set_regdomain_cmd_tlv, 22722 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22723 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22724 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22725 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22726 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22727 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22728 .check_and_update_fw_version = 22729 check_and_update_fw_version_cmd_tlv, 22730 .send_set_base_macaddr_indicate_cmd = 22731 send_set_base_macaddr_indicate_cmd_tlv, 22732 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22733 .send_enable_specific_fw_logs_cmd = 22734 send_enable_specific_fw_logs_cmd_tlv, 22735 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22736 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22737 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22738 #ifdef WLAN_POLICY_MGR_ENABLE 22739 .send_pdev_set_dual_mac_config_cmd = 22740 send_pdev_set_dual_mac_config_cmd_tlv, 22741 #endif 22742 .send_app_type1_params_in_fw_cmd = 22743 send_app_type1_params_in_fw_cmd_tlv, 22744 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22745 .send_process_roam_synch_complete_cmd = 22746 send_process_roam_synch_complete_cmd_tlv, 22747 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22748 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22749 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22750 .send_roam_scan_offload_scan_period_cmd = 22751 send_roam_scan_offload_scan_period_cmd_tlv, 22752 .send_roam_scan_offload_chan_list_cmd = 22753 send_roam_scan_offload_chan_list_cmd_tlv, 22754 .send_roam_scan_offload_rssi_change_cmd = 22755 send_roam_scan_offload_rssi_change_cmd_tlv, 22756 .send_get_buf_extscan_hotlist_cmd = 22757 send_get_buf_extscan_hotlist_cmd_tlv, 22758 .send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv, 22759 .send_adapt_dwelltime_params_cmd = 22760 send_adapt_dwelltime_params_cmd_tlv, 22761 .send_dbs_scan_sel_params_cmd = 22762 send_dbs_scan_sel_params_cmd_tlv, 22763 .init_cmd_send = init_cmd_send_tlv, 22764 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22765 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22766 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22767 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22768 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22769 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22770 .send_vdev_set_custom_aggr_size_cmd = 22771 send_vdev_set_custom_aggr_size_cmd_tlv, 22772 .send_vdev_set_qdepth_thresh_cmd = 22773 send_vdev_set_qdepth_thresh_cmd_tlv, 22774 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22775 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22776 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22777 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22778 .send_smart_ant_set_training_info_cmd = 22779 send_smart_ant_set_training_info_cmd_tlv, 22780 .send_smart_ant_set_node_config_cmd = 22781 send_smart_ant_set_node_config_cmd_tlv, 22782 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22783 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22784 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22785 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22786 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22787 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22788 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22789 .send_periodic_chan_stats_config_cmd = 22790 send_periodic_chan_stats_config_cmd_tlv, 22791 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22792 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22793 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22794 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22795 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22796 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22797 .send_vdev_spectral_configure_cmd = 22798 send_vdev_spectral_configure_cmd_tlv, 22799 .send_vdev_spectral_enable_cmd = 22800 send_vdev_spectral_enable_cmd_tlv, 22801 .send_thermal_mitigation_param_cmd = 22802 send_thermal_mitigation_param_cmd_tlv, 22803 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22804 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22805 .send_process_update_edca_param_cmd = 22806 send_process_update_edca_param_cmd_tlv, 22807 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22808 .send_set_country_cmd = send_set_country_cmd_tlv, 22809 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22810 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22811 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22812 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22813 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22814 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22815 .extract_host_mem_req = extract_host_mem_req_tlv, 22816 .save_service_bitmap = save_service_bitmap_tlv, 22817 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22818 .is_service_enabled = is_service_enabled_tlv, 22819 .save_fw_version = save_fw_version_in_service_ready_tlv, 22820 .ready_extract_init_status = ready_extract_init_status_tlv, 22821 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22822 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22823 .extract_ready_event_params = extract_ready_event_params_tlv, 22824 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22825 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22826 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22827 .extract_tbttoffset_update_params = 22828 extract_tbttoffset_update_params_tlv, 22829 .extract_ext_tbttoffset_update_params = 22830 extract_ext_tbttoffset_update_params_tlv, 22831 .extract_tbttoffset_num_vdevs = 22832 extract_tbttoffset_num_vdevs_tlv, 22833 .extract_ext_tbttoffset_num_vdevs = 22834 extract_ext_tbttoffset_num_vdevs_tlv, 22835 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22836 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22837 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22838 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22839 #ifdef CONVERGED_TDLS_ENABLE 22840 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22841 #endif 22842 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22843 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22844 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22845 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22846 #ifdef CONVERGED_P2P_ENABLE 22847 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22848 .extract_p2p_lo_stop_ev_param = 22849 extract_p2p_lo_stop_ev_param_tlv, 22850 #endif 22851 .extract_offchan_data_tx_compl_param = 22852 extract_offchan_data_tx_compl_param_tlv, 22853 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22854 .extract_all_stats_count = extract_all_stats_counts_tlv, 22855 .extract_pdev_stats = extract_pdev_stats_tlv, 22856 .extract_unit_test = extract_unit_test_tlv, 22857 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22858 .extract_vdev_stats = extract_vdev_stats_tlv, 22859 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22860 .extract_peer_stats = extract_peer_stats_tlv, 22861 .extract_bcn_stats = extract_bcn_stats_tlv, 22862 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22863 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22864 .extract_chan_stats = extract_chan_stats_tlv, 22865 .extract_profile_ctx = extract_profile_ctx_tlv, 22866 .extract_profile_data = extract_profile_data_tlv, 22867 .extract_chan_info_event = extract_chan_info_event_tlv, 22868 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22869 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22870 #ifdef WLAN_FEATURE_DISA 22871 .send_encrypt_decrypt_send_cmd = 22872 send_encrypt_decrypt_send_cmd_tlv, 22873 .extract_encrypt_decrypt_resp_event = 22874 extract_encrypt_decrypt_resp_event_tlv, 22875 #endif 22876 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22877 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22878 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22879 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22880 .send_multiple_vdev_restart_req_cmd = 22881 send_multiple_vdev_restart_req_cmd_tlv, 22882 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22883 .extract_hw_mode_cap_service_ready_ext = 22884 extract_hw_mode_cap_service_ready_ext_tlv, 22885 .extract_mac_phy_cap_service_ready_ext = 22886 extract_mac_phy_cap_service_ready_ext_tlv, 22887 .extract_reg_cap_service_ready_ext = 22888 extract_reg_cap_service_ready_ext_tlv, 22889 .extract_dbr_ring_cap_service_ready_ext = 22890 extract_dbr_ring_cap_service_ready_ext_tlv, 22891 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22892 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22893 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22894 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22895 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22896 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22897 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22898 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22899 .extract_fips_event_data = extract_fips_event_data_tlv, 22900 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22901 .extract_peer_delete_response_event = 22902 extract_peer_delete_response_event_tlv, 22903 .is_management_record = is_management_record_tlv, 22904 .extract_pdev_csa_switch_count_status = 22905 extract_pdev_csa_switch_count_status_tlv, 22906 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22907 .extract_pdev_tpc_config_ev_param = 22908 extract_pdev_tpc_config_ev_param_tlv, 22909 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22910 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22911 .extract_peer_sta_ps_statechange_ev = 22912 extract_peer_sta_ps_statechange_ev_tlv, 22913 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22914 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22915 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22916 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22917 .extract_reg_chan_list_update_event = 22918 extract_reg_chan_list_update_event_tlv, 22919 .extract_chainmask_tables = 22920 extract_chainmask_tables_tlv, 22921 .extract_thermal_stats = extract_thermal_stats_tlv, 22922 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22923 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22924 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22925 #ifdef DFS_COMPONENT_ENABLE 22926 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22927 .extract_dfs_radar_detection_event = 22928 extract_dfs_radar_detection_event_tlv, 22929 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22930 #endif 22931 .convert_pdev_id_host_to_target = 22932 convert_host_pdev_id_to_target_pdev_id_legacy, 22933 .convert_pdev_id_target_to_host = 22934 convert_target_pdev_id_to_host_pdev_id_legacy, 22935 22936 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22937 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22938 .extract_reg_11d_new_country_event = 22939 extract_reg_11d_new_country_event_tlv, 22940 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22941 .send_limit_off_chan_cmd = 22942 send_limit_off_chan_cmd_tlv, 22943 .extract_reg_ch_avoid_event = 22944 extract_reg_ch_avoid_event_tlv, 22945 .send_pdev_caldata_version_check_cmd = 22946 send_pdev_caldata_version_check_cmd_tlv, 22947 .extract_pdev_caldata_version_check_ev_param = 22948 extract_pdev_caldata_version_check_ev_param_tlv, 22949 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22950 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22951 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22952 #if defined(WLAN_FEATURE_FILS_SK) 22953 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22954 #endif 22955 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22956 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22957 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22958 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22959 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22960 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22961 .extract_ndp_ind = extract_ndp_ind_tlv, 22962 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22963 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22964 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22965 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22966 #endif 22967 .send_btm_config = send_btm_config_cmd_tlv, 22968 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22969 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22970 #ifdef WLAN_SUPPORT_FILS 22971 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22972 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22973 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22974 #endif /* WLAN_SUPPORT_FILS */ 22975 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22976 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22977 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22978 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22979 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22980 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22981 .send_bss_color_change_enable_cmd = 22982 send_bss_color_change_enable_cmd_tlv, 22983 .send_obss_color_collision_cfg_cmd = 22984 send_obss_color_collision_cfg_cmd_tlv, 22985 .extract_obss_color_collision_info = 22986 extract_obss_color_collision_info_tlv, 22987 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22988 .extract_single_phyerr = extract_single_phyerr_tlv, 22989 #ifdef QCA_SUPPORT_CP_STATS 22990 .extract_cca_stats = extract_cca_stats_tlv, 22991 #endif 22992 }; 22993 22994 /** 22995 * populate_tlv_event_id() - populates wmi event ids 22996 * 22997 * @param event_ids: Pointer to hold event ids 22998 * Return: None 22999 */ 23000 static void populate_tlv_events_id(uint32_t *event_ids) 23001 { 23002 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 23003 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 23004 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 23005 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23006 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 23007 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 23008 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 23009 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 23010 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 23011 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 23012 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 23013 event_ids[wmi_service_ready_ext_event_id] = 23014 WMI_SERVICE_READY_EXT_EVENTID; 23015 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 23016 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 23017 event_ids[wmi_vdev_install_key_complete_event_id] = 23018 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 23019 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 23020 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 23021 23022 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 23023 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 23024 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 23025 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 23026 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 23027 event_ids[wmi_peer_estimated_linkspeed_event_id] = 23028 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 23029 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 23030 event_ids[wmi_peer_delete_response_event_id] = 23031 WMI_PEER_DELETE_RESP_EVENTID; 23032 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 23033 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 23034 event_ids[wmi_tbttoffset_update_event_id] = 23035 WMI_TBTTOFFSET_UPDATE_EVENTID; 23036 event_ids[wmi_ext_tbttoffset_update_event_id] = 23037 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 23038 event_ids[wmi_offload_bcn_tx_status_event_id] = 23039 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 23040 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 23041 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 23042 event_ids[wmi_mgmt_tx_completion_event_id] = 23043 WMI_MGMT_TX_COMPLETION_EVENTID; 23044 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 23045 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 23046 event_ids[wmi_tx_delba_complete_event_id] = 23047 WMI_TX_DELBA_COMPLETE_EVENTID; 23048 event_ids[wmi_tx_addba_complete_event_id] = 23049 WMI_TX_ADDBA_COMPLETE_EVENTID; 23050 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 23051 23052 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 23053 23054 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 23055 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 23056 23057 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 23058 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 23059 23060 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 23061 23062 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 23063 event_ids[wmi_p2p_lo_stop_event_id] = 23064 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 23065 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 23066 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 23067 event_ids[wmi_d0_wow_disable_ack_event_id] = 23068 WMI_D0_WOW_DISABLE_ACK_EVENTID; 23069 event_ids[wmi_wow_initial_wakeup_event_id] = 23070 WMI_WOW_INITIAL_WAKEUP_EVENTID; 23071 23072 event_ids[wmi_rtt_meas_report_event_id] = 23073 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 23074 event_ids[wmi_tsf_meas_report_event_id] = 23075 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 23076 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 23077 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 23078 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 23079 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 23080 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 23081 event_ids[wmi_diag_event_id_log_supported_event_id] = 23082 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 23083 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 23084 event_ids[wmi_nlo_scan_complete_event_id] = 23085 WMI_NLO_SCAN_COMPLETE_EVENTID; 23086 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 23087 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 23088 23089 event_ids[wmi_gtk_offload_status_event_id] = 23090 WMI_GTK_OFFLOAD_STATUS_EVENTID; 23091 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 23092 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 23093 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 23094 23095 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 23096 23097 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 23098 23099 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 23100 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 23101 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 23102 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 23103 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 23104 event_ids[wmi_wlan_profile_data_event_id] = 23105 WMI_WLAN_PROFILE_DATA_EVENTID; 23106 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 23107 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 23108 event_ids[wmi_vdev_get_keepalive_event_id] = 23109 WMI_VDEV_GET_KEEPALIVE_EVENTID; 23110 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 23111 23112 event_ids[wmi_diag_container_event_id] = 23113 WMI_DIAG_DATA_CONTAINER_EVENTID; 23114 23115 event_ids[wmi_host_auto_shutdown_event_id] = 23116 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 23117 23118 event_ids[wmi_update_whal_mib_stats_event_id] = 23119 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 23120 23121 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 23122 event_ids[wmi_update_vdev_rate_stats_event_id] = 23123 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 23124 23125 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 23126 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 23127 23128 /** Set OCB Sched Response, deprecated */ 23129 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 23130 23131 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 23132 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 23133 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 23134 23135 /* GPIO Event */ 23136 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 23137 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 23138 23139 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 23140 event_ids[wmi_rfkill_state_change_event_id] = 23141 WMI_RFKILL_STATE_CHANGE_EVENTID; 23142 23143 /* TDLS Event */ 23144 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 23145 23146 event_ids[wmi_batch_scan_enabled_event_id] = 23147 WMI_BATCH_SCAN_ENABLED_EVENTID; 23148 event_ids[wmi_batch_scan_result_event_id] = 23149 WMI_BATCH_SCAN_RESULT_EVENTID; 23150 /* OEM Event */ 23151 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 23152 event_ids[wmi_oem_meas_report_event_id] = 23153 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 23154 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 23155 23156 /* NAN Event */ 23157 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 23158 23159 /* LPI Event */ 23160 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 23161 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 23162 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 23163 23164 /* ExtScan events */ 23165 event_ids[wmi_extscan_start_stop_event_id] = 23166 WMI_EXTSCAN_START_STOP_EVENTID; 23167 event_ids[wmi_extscan_operation_event_id] = 23168 WMI_EXTSCAN_OPERATION_EVENTID; 23169 event_ids[wmi_extscan_table_usage_event_id] = 23170 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 23171 event_ids[wmi_extscan_cached_results_event_id] = 23172 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 23173 event_ids[wmi_extscan_wlan_change_results_event_id] = 23174 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 23175 event_ids[wmi_extscan_hotlist_match_event_id] = 23176 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 23177 event_ids[wmi_extscan_capabilities_event_id] = 23178 WMI_EXTSCAN_CAPABILITIES_EVENTID; 23179 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 23180 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 23181 23182 /* mDNS offload events */ 23183 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 23184 23185 /* SAP Authentication offload events */ 23186 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 23187 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 23188 23189 /** Out-of-context-of-bss (OCB) events */ 23190 event_ids[wmi_ocb_set_config_resp_event_id] = 23191 WMI_OCB_SET_CONFIG_RESP_EVENTID; 23192 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 23193 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 23194 event_ids[wmi_dcc_get_stats_resp_event_id] = 23195 WMI_DCC_GET_STATS_RESP_EVENTID; 23196 event_ids[wmi_dcc_update_ndl_resp_event_id] = 23197 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 23198 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 23199 /* System-On-Chip events */ 23200 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 23201 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 23202 event_ids[wmi_soc_hw_mode_transition_event_id] = 23203 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 23204 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 23205 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 23206 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 23207 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 23208 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 23209 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 23210 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 23211 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23212 event_ids[wmi_peer_sta_ps_statechg_event_id] = 23213 WMI_PEER_STA_PS_STATECHG_EVENTID; 23214 event_ids[wmi_pdev_channel_hopping_event_id] = 23215 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 23216 event_ids[wmi_offchan_data_tx_completion_event] = 23217 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 23218 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 23219 event_ids[wmi_dfs_radar_detection_event_id] = 23220 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 23221 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 23222 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 23223 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 23224 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 23225 event_ids[wmi_service_available_event_id] = 23226 WMI_SERVICE_AVAILABLE_EVENTID; 23227 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 23228 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 23229 /* NDP events */ 23230 event_ids[wmi_ndp_initiator_rsp_event_id] = 23231 WMI_NDP_INITIATOR_RSP_EVENTID; 23232 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 23233 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 23234 event_ids[wmi_ndp_responder_rsp_event_id] = 23235 WMI_NDP_RESPONDER_RSP_EVENTID; 23236 event_ids[wmi_ndp_end_indication_event_id] = 23237 WMI_NDP_END_INDICATION_EVENTID; 23238 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 23239 23240 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 23241 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 23242 event_ids[wmi_pdev_chip_power_stats_event_id] = 23243 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 23244 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 23245 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 23246 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 23247 event_ids[wmi_bpf_capability_info_event_id] = 23248 WMI_BPF_CAPABILIY_INFO_EVENTID; 23249 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 23250 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 23251 event_ids[wmi_report_rx_aggr_failure_event_id] = 23252 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 23253 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 23254 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 23255 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 23256 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 23257 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 23258 event_ids[wmi_pdev_hw_mode_transition_event_id] = 23259 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 23260 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 23261 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 23262 event_ids[wmi_coex_bt_activity_event_id] = 23263 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 23264 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 23265 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 23266 event_ids[wmi_radio_tx_power_level_stats_event_id] = 23267 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 23268 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 23269 event_ids[wmi_dma_buf_release_event_id] = 23270 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 23271 event_ids[wmi_sap_obss_detection_report_event_id] = 23272 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 23273 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 23274 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 23275 event_ids[wmi_obss_color_collision_report_event_id] = 23276 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 23277 event_ids[wmi_pdev_div_rssi_antid_event_id] = 23278 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 23279 } 23280 23281 /** 23282 * populate_tlv_service() - populates wmi services 23283 * 23284 * @param wmi_service: Pointer to hold wmi_service 23285 * Return: None 23286 */ 23287 static void populate_tlv_service(uint32_t *wmi_service) 23288 { 23289 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 23290 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 23291 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 23292 wmi_service[wmi_service_roam_scan_offload] = 23293 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 23294 wmi_service[wmi_service_bcn_miss_offload] = 23295 WMI_SERVICE_BCN_MISS_OFFLOAD; 23296 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 23297 wmi_service[wmi_service_sta_advanced_pwrsave] = 23298 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 23299 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 23300 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 23301 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 23302 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 23303 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 23304 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 23305 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 23306 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 23307 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 23308 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 23309 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 23310 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 23311 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 23312 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 23313 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 23314 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 23315 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 23316 wmi_service[wmi_service_packet_power_save] = 23317 WMI_SERVICE_PACKET_POWER_SAVE; 23318 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 23319 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 23320 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 23321 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 23322 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 23323 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 23324 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 23325 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 23326 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 23327 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 23328 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 23329 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 23330 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 23331 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 23332 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 23333 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 23334 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 23335 wmi_service[wmi_service_mcc_bcn_interval_change] = 23336 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 23337 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 23338 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 23339 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 23340 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 23341 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 23342 wmi_service[wmi_service_lte_ant_share_support] = 23343 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 23344 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 23345 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 23346 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 23347 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 23348 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 23349 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 23350 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 23351 wmi_service[wmi_service_bcn_txrate_override] = 23352 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 23353 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 23354 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 23355 wmi_service[wmi_service_estimate_linkspeed] = 23356 WMI_SERVICE_ESTIMATE_LINKSPEED; 23357 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 23358 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 23359 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 23360 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 23361 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 23362 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 23363 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 23364 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 23365 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 23366 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 23367 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 23368 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 23369 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 23370 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 23371 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 23372 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 23373 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 23374 wmi_service[wmi_service_sap_auth_offload] = 23375 WMI_SERVICE_SAP_AUTH_OFFLOAD; 23376 wmi_service[wmi_service_dual_band_simultaneous_support] = 23377 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 23378 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 23379 wmi_service[wmi_service_ap_arpns_offload] = 23380 WMI_SERVICE_AP_ARPNS_OFFLOAD; 23381 wmi_service[wmi_service_per_band_chainmask_support] = 23382 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 23383 wmi_service[wmi_service_packet_filter_offload] = 23384 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 23385 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 23386 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 23387 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 23388 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 23389 wmi_service[wmi_service_multiple_vdev_restart] = 23390 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 23391 23392 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 23393 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 23394 wmi_service[wmi_service_smart_antenna_sw_support] = 23395 WMI_SERVICE_UNAVAILABLE; 23396 wmi_service[wmi_service_smart_antenna_hw_support] = 23397 WMI_SERVICE_UNAVAILABLE; 23398 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 23399 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 23400 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 23401 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 23402 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 23403 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 23404 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 23405 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 23406 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 23407 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 23408 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 23409 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 23410 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 23411 wmi_service[wmi_service_periodic_chan_stat_support] = 23412 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 23413 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 23414 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 23415 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 23416 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 23417 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 23418 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23419 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 23420 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 23421 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 23422 wmi_service[wmi_service_unified_wow_capability] = 23423 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 23424 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23425 wmi_service[wmi_service_bpf_offload] = WMI_SERVICE_BPF_OFFLOAD; 23426 wmi_service[wmi_service_sync_delete_cmds] = 23427 WMI_SERVICE_SYNC_DELETE_CMDS; 23428 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 23429 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 23430 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 23431 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 23432 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 23433 wmi_service[wmi_service_deprecated_replace] = 23434 WMI_SERVICE_DEPRECATED_REPLACE; 23435 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 23436 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 23437 wmi_service[wmi_service_enhanced_mcast_filter] = 23438 WMI_SERVICE_ENHANCED_MCAST_FILTER; 23439 wmi_service[wmi_service_half_rate_quarter_rate_support] = 23440 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 23441 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 23442 wmi_service[wmi_service_p2p_listen_offload_support] = 23443 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 23444 wmi_service[wmi_service_mark_first_wakeup_packet] = 23445 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 23446 wmi_service[wmi_service_multiple_mcast_filter_set] = 23447 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 23448 wmi_service[wmi_service_host_managed_rx_reorder] = 23449 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 23450 wmi_service[wmi_service_flash_rdwr_support] = 23451 WMI_SERVICE_FLASH_RDWR_SUPPORT; 23452 wmi_service[wmi_service_wlan_stats_report] = 23453 WMI_SERVICE_WLAN_STATS_REPORT; 23454 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 23455 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 23456 wmi_service[wmi_service_dfs_phyerr_offload] = 23457 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 23458 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 23459 wmi_service[wmi_service_fw_mem_dump_support] = 23460 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 23461 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 23462 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 23463 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 23464 wmi_service[wmi_service_hw_data_filtering] = 23465 WMI_SERVICE_HW_DATA_FILTERING; 23466 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 23467 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 23468 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 23469 wmi_service[wmi_service_extended_nss_support] = 23470 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 23471 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 23472 wmi_service[wmi_service_bcn_offload_start_stop_support] = 23473 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 23474 wmi_service[wmi_service_offchan_data_tid_support] = 23475 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 23476 wmi_service[wmi_service_support_dma] = 23477 WMI_SERVICE_SUPPORT_DIRECT_DMA; 23478 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 23479 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 23480 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 23481 wmi_service[wmi_service_11k_neighbour_report_support] = 23482 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 23483 wmi_service[wmi_service_ap_obss_detection_offload] = 23484 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 23485 wmi_service[wmi_service_bss_color_offload] = 23486 WMI_SERVICE_BSS_COLOR_OFFLOAD; 23487 wmi_service[wmi_service_gmac_offload_support] = 23488 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 23489 23490 } 23491 23492 #ifndef CONFIG_MCL 23493 23494 /** 23495 * populate_pdev_param_tlv() - populates pdev params 23496 * 23497 * @param pdev_param: Pointer to hold pdev params 23498 * Return: None 23499 */ 23500 static void populate_pdev_param_tlv(uint32_t *pdev_param) 23501 { 23502 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 23503 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 23504 pdev_param[wmi_pdev_param_txpower_limit2g] = 23505 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 23506 pdev_param[wmi_pdev_param_txpower_limit5g] = 23507 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 23508 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 23509 pdev_param[wmi_pdev_param_beacon_gen_mode] = 23510 WMI_PDEV_PARAM_BEACON_GEN_MODE; 23511 pdev_param[wmi_pdev_param_beacon_tx_mode] = 23512 WMI_PDEV_PARAM_BEACON_TX_MODE; 23513 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 23514 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 23515 pdev_param[wmi_pdev_param_protection_mode] = 23516 WMI_PDEV_PARAM_PROTECTION_MODE; 23517 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 23518 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 23519 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 23520 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 23521 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 23522 pdev_param[wmi_pdev_param_sta_kickout_th] = 23523 WMI_PDEV_PARAM_STA_KICKOUT_TH; 23524 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 23525 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 23526 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 23527 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 23528 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 23529 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 23530 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 23531 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 23532 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 23533 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 23534 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 23535 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 23536 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 23537 pdev_param[wmi_pdev_param_ltr_sleep_override] = 23538 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 23539 pdev_param[wmi_pdev_param_ltr_rx_override] = 23540 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 23541 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 23542 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 23543 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 23544 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 23545 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 23546 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 23547 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 23548 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 23549 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 23550 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 23551 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 23552 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 23553 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 23554 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 23555 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 23556 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 23557 pdev_param[wmi_pdev_param_peer_stats_update_period] = 23558 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 23559 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 23560 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 23561 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 23562 pdev_param[wmi_pdev_param_arp_ac_override] = 23563 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 23564 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 23565 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 23566 pdev_param[wmi_pdev_param_ani_poll_period] = 23567 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 23568 pdev_param[wmi_pdev_param_ani_listen_period] = 23569 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 23570 pdev_param[wmi_pdev_param_ani_ofdm_level] = 23571 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 23572 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 23573 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 23574 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 23575 pdev_param[wmi_pdev_param_idle_ps_config] = 23576 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 23577 pdev_param[wmi_pdev_param_power_gating_sleep] = 23578 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 23579 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 23580 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 23581 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 23582 pdev_param[wmi_pdev_param_hw_rfkill_config] = 23583 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 23584 pdev_param[wmi_pdev_param_low_power_rf_enable] = 23585 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 23586 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 23587 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 23588 pdev_param[wmi_pdev_param_power_collapse_enable] = 23589 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 23590 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 23591 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 23592 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 23593 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 23594 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 23595 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 23596 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 23597 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 23598 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 23599 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 23600 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 23601 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 23602 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 23603 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 23604 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 23605 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 23606 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 23607 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 23608 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 23609 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 23610 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 23611 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 23612 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 23613 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 23614 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 23615 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 23616 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 23617 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 23618 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 23619 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 23620 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 23621 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 23622 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 23623 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 23624 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 23625 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 23626 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 23627 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 23628 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 23629 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 23630 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 23631 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 23632 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23633 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23634 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23635 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23636 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23637 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23638 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23639 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23640 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23641 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23642 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23643 WMI_PDEV_PARAM_PROXY_STA_MODE; 23644 pdev_param[wmi_pdev_param_mu_group_policy] = 23645 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23646 pdev_param[wmi_pdev_param_noise_detection] = 23647 WMI_PDEV_PARAM_NOISE_DETECTION; 23648 pdev_param[wmi_pdev_param_noise_threshold] = 23649 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23650 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23651 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23652 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23653 pdev_param[wmi_pdev_param_atf_strict_sch] = 23654 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23655 pdev_param[wmi_pdev_param_atf_sched_duration] = 23656 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23657 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23658 pdev_param[wmi_pdev_param_sensitivity_level] = 23659 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23660 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23661 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23662 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23663 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23664 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23665 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23666 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23667 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23668 pdev_param[wmi_pdev_param_cca_threshold] = 23669 WMI_PDEV_PARAM_CCA_THRESHOLD; 23670 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23671 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23672 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23673 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23674 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23675 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23676 pdev_param[wmi_pdev_param_arp_srcaddr] = 23677 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23678 pdev_param[wmi_pdev_param_arp_dstaddr] = 23679 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23680 pdev_param[wmi_pdev_param_txpower_decr_db] = 23681 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23682 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23683 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23684 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23685 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23686 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23687 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23688 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23689 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23690 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23691 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23692 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23693 WMI_UNAVAILABLE_PARAM; 23694 pdev_param[wmi_pdev_param_igmpmld_override] = WMI_UNAVAILABLE_PARAM; 23695 pdev_param[wmi_pdev_param_igmpmld_tid] = WMI_UNAVAILABLE_PARAM; 23696 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23697 pdev_param[wmi_pdev_param_block_interbss] = 23698 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23699 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23700 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23701 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23702 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23703 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23704 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23705 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23706 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23707 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23708 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23709 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23710 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23711 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23712 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23713 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23714 pdev_param[wmi_pdev_param_igmpmld_ac_override] = 23715 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23716 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23717 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23718 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23719 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23720 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23721 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23722 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23723 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23724 pdev_param[wmi_pdev_param_fast_channel_reset] = 23725 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23726 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23727 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23728 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23729 } 23730 23731 /** 23732 * populate_vdev_param_tlv() - populates vdev params 23733 * 23734 * @param vdev_param: Pointer to hold vdev params 23735 * Return: None 23736 */ 23737 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23738 { 23739 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23740 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23741 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23742 vdev_param[wmi_vdev_param_beacon_interval] = 23743 WMI_VDEV_PARAM_BEACON_INTERVAL; 23744 vdev_param[wmi_vdev_param_listen_interval] = 23745 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23746 vdev_param[wmi_vdev_param_multicast_rate] = 23747 WMI_VDEV_PARAM_MULTICAST_RATE; 23748 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23749 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23750 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23751 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23752 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23753 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23754 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23755 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23756 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23757 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23758 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23759 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23760 vdev_param[wmi_vdev_param_bmiss_count_max] = 23761 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23762 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23763 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23764 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23765 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23766 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23767 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23768 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23769 vdev_param[wmi_vdev_param_disable_htprotection] = 23770 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23771 vdev_param[wmi_vdev_param_sta_quickkickout] = 23772 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23773 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23774 vdev_param[wmi_vdev_param_protection_mode] = 23775 WMI_VDEV_PARAM_PROTECTION_MODE; 23776 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23777 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23778 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23779 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23780 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23781 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23782 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23783 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23784 vdev_param[wmi_vdev_param_bcast_data_rate] = 23785 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23786 vdev_param[wmi_vdev_param_mcast_data_rate] = 23787 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23788 vdev_param[wmi_vdev_param_mcast_indicate] = 23789 WMI_VDEV_PARAM_MCAST_INDICATE; 23790 vdev_param[wmi_vdev_param_dhcp_indicate] = 23791 WMI_VDEV_PARAM_DHCP_INDICATE; 23792 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23793 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23794 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23795 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23796 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23797 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23798 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23799 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23800 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23801 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23802 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23803 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23804 vdev_param[wmi_vdev_param_packet_powersave] = 23805 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23806 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23807 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23808 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23809 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23810 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23811 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23812 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23813 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23814 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23815 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23816 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23817 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23818 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23819 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23820 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23821 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23822 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23823 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23824 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23825 vdev_param[wmi_vdev_param_roam_fw_offload] = 23826 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23827 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23828 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23829 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23830 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23831 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23832 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23833 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23834 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23835 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23836 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23837 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23838 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23839 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23840 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23841 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23842 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23843 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23844 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23845 vdev_param[wmi_vdev_param_inactivity_cnt] = 23846 WMI_VDEV_PARAM_INACTIVITY_CNT; 23847 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23848 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23849 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23850 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23851 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23852 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23853 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23854 vdev_param[wmi_vdev_param_rx_leak_window] = 23855 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23856 vdev_param[wmi_vdev_param_stats_avg_factor] = 23857 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23858 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23859 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23860 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23861 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23862 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23863 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23864 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23865 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23866 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23867 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23868 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23869 WMI_VDEV_PARAM_HE_RANGE_EXT; 23870 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23871 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23872 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23873 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23874 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23875 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23876 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23877 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23878 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23879 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23880 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23881 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23882 vdev_param[wmi_vdev_param_rc_num_retries] = 23883 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23884 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23885 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23886 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23887 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23888 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23889 vdev_param[wmi_vdev_param_vht80_ratemask] = 23890 WMI_VDEV_PARAM_VHT80_RATEMASK; 23891 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23892 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23893 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23894 vdev_param[wmi_vdev_param_set_he_ltf] = 23895 WMI_VDEV_PARAM_HE_LTF; 23896 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23897 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23898 vdev_param[wmi_vdev_param_set_ba_mode] = 23899 WMI_VDEV_PARAM_BA_MODE; 23900 vdev_param[wmi_vdev_param_capabilities] = 23901 WMI_VDEV_PARAM_CAPABILITIES; 23902 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 23903 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 23904 } 23905 #endif 23906 23907 /** 23908 * populate_target_defines_tlv() - Populate target defines and params 23909 * @wmi_handle: pointer to wmi handle 23910 * 23911 * Return: None 23912 */ 23913 #ifndef CONFIG_MCL 23914 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23915 { 23916 populate_pdev_param_tlv(wmi_handle->pdev_param); 23917 populate_vdev_param_tlv(wmi_handle->vdev_param); 23918 } 23919 #else 23920 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23921 { } 23922 #endif 23923 23924 /** 23925 * wmi_ocb_ut_attach() - Attach OCB test framework 23926 * @wmi_handle: wmi handle 23927 * 23928 * Return: None 23929 */ 23930 #ifdef WLAN_OCB_UT 23931 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23932 #else 23933 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23934 { 23935 return; 23936 } 23937 #endif 23938 23939 #ifdef WLAN_SUPPORT_TWT 23940 void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle); 23941 #else 23942 static void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle) 23943 { 23944 return; 23945 } 23946 #endif 23947 /** 23948 * wmi_tlv_attach() - Attach TLV APIs 23949 * 23950 * Return: None 23951 */ 23952 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23953 { 23954 wmi_handle->ops = &tlv_ops; 23955 wmi_ocb_ut_attach(wmi_handle); 23956 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23957 #ifdef WMI_INTERFACE_EVENT_LOGGING 23958 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23959 wmi_handle->log_info.buf_offset_command = 8; 23960 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23961 wmi_handle->log_info.buf_offset_event = 4; 23962 #endif 23963 populate_tlv_events_id(wmi_handle->wmi_events); 23964 populate_tlv_service(wmi_handle->services); 23965 populate_target_defines_tlv(wmi_handle); 23966 wmi_twt_attach_tlv(wmi_handle); 23967 } 23968 qdf_export_symbol(wmi_tlv_attach); 23969 23970 /** 23971 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23972 * 23973 * Return: None 23974 */ 23975 void wmi_tlv_init(void) 23976 { 23977 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23978 } 23979