1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "wmi_unified_api.h" 20 #include "wmi.h" 21 #include "wmi_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_version_whitelist.h" 24 #include <qdf_module.h> 25 #include <wlan_defs.h> 26 #include <htc_services.h> 27 28 #ifdef CONVERGED_P2P_ENABLE 29 #include "wlan_p2p_public_struct.h" 30 #endif 31 #ifdef WLAN_PMO_ENABLE 32 #include "wlan_pmo_hw_filter_public_struct.h" 33 #endif 34 #include <wlan_utility.h> 35 #ifdef WLAN_SUPPORT_GREEN_AP 36 #include "wlan_green_ap_api.h" 37 #endif 38 39 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 40 #include "nan_public_structs.h" 41 #endif 42 #include "wmi_unified_twt_api.h" 43 44 #ifdef WLAN_POLICY_MGR_ENABLE 45 #include "wlan_policy_mgr_public_struct.h" 46 #endif 47 48 /* HTC service ids for WMI for multi-radio */ 49 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 50 WMI_CONTROL_SVC_WMAC1, 51 WMI_CONTROL_SVC_WMAC2}; 52 53 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 54 * buffer. 55 * @wmi_handle: pointer to wmi_handle 56 * @cmd: pointer target vdev create command buffer 57 * @param: pointer host params for vdev create 58 * 59 * Return: None 60 */ 61 #ifdef CONFIG_MCL 62 static inline void copy_vdev_create_pdev_id( 63 struct wmi_unified *wmi_handle, 64 wmi_vdev_create_cmd_fixed_param * cmd, 65 struct vdev_create_params *param) 66 { 67 cmd->pdev_id = WMI_PDEV_ID_SOC; 68 } 69 #else 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_handle->ops->convert_pdev_id_host_to_target( 76 param->pdev_id); 77 } 78 #endif 79 80 /** 81 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 82 * @wmi_handle: wmi handle 83 * @param: pointer to hold vdev create parameter 84 * @macaddr: vdev mac address 85 * 86 * Return: QDF_STATUS_SUCCESS for success or error code 87 */ 88 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 89 uint8_t macaddr[IEEE80211_ADDR_LEN], 90 struct vdev_create_params *param) 91 { 92 wmi_vdev_create_cmd_fixed_param *cmd; 93 wmi_buf_t buf; 94 int32_t len = sizeof(*cmd); 95 QDF_STATUS ret; 96 int num_bands = 2; 97 uint8_t *buf_ptr; 98 wmi_vdev_txrx_streams *txrx_streams; 99 100 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 101 buf = wmi_buf_alloc(wmi_handle, len); 102 if (!buf) { 103 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 104 return QDF_STATUS_E_NOMEM; 105 } 106 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 107 WMITLV_SET_HDR(&cmd->tlv_header, 108 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 109 WMITLV_GET_STRUCT_TLVLEN 110 (wmi_vdev_create_cmd_fixed_param)); 111 cmd->vdev_id = param->if_id; 112 cmd->vdev_type = param->type; 113 cmd->vdev_subtype = param->subtype; 114 cmd->num_cfg_txrx_streams = num_bands; 115 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 116 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 117 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 118 __func__, param->if_id, cmd->pdev_id, 119 macaddr[0], macaddr[1], macaddr[2], 120 macaddr[3], macaddr[4], macaddr[5]); 121 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 122 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 123 (num_bands * sizeof(wmi_vdev_txrx_streams))); 124 buf_ptr += WMI_TLV_HDR_SIZE; 125 126 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 127 param->type, param->subtype, 128 param->nss_2g, param->nss_5g); 129 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 130 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 131 txrx_streams->supported_tx_streams = param->nss_2g; 132 txrx_streams->supported_rx_streams = param->nss_2g; 133 WMITLV_SET_HDR(&txrx_streams->tlv_header, 134 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 135 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 136 137 txrx_streams++; 138 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 139 txrx_streams->supported_tx_streams = param->nss_5g; 140 txrx_streams->supported_rx_streams = param->nss_5g; 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 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 145 if (QDF_IS_STATUS_ERROR(ret)) { 146 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 147 wmi_buf_free(buf); 148 } 149 150 return ret; 151 } 152 153 /** 154 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 155 * @wmi_handle: wmi handle 156 * @if_id: vdev id 157 * 158 * Return: QDF_STATUS_SUCCESS for success or error code 159 */ 160 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 161 uint8_t if_id) 162 { 163 wmi_vdev_delete_cmd_fixed_param *cmd; 164 wmi_buf_t buf; 165 QDF_STATUS ret; 166 167 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 168 if (!buf) { 169 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 170 return QDF_STATUS_E_NOMEM; 171 } 172 173 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 174 WMITLV_SET_HDR(&cmd->tlv_header, 175 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 176 WMITLV_GET_STRUCT_TLVLEN 177 (wmi_vdev_delete_cmd_fixed_param)); 178 cmd->vdev_id = if_id; 179 ret = wmi_unified_cmd_send(wmi_handle, buf, 180 sizeof(wmi_vdev_delete_cmd_fixed_param), 181 WMI_VDEV_DELETE_CMDID); 182 if (QDF_IS_STATUS_ERROR(ret)) { 183 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 184 wmi_buf_free(buf); 185 } 186 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 187 188 return ret; 189 } 190 191 /** 192 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 193 * @wmi: wmi handle 194 * @vdev_id: vdev id 195 * 196 * Return: QDF_STATUS_SUCCESS for success or erro code 197 */ 198 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 199 uint8_t vdev_id) 200 { 201 wmi_vdev_stop_cmd_fixed_param *cmd; 202 wmi_buf_t buf; 203 int32_t len = sizeof(*cmd); 204 205 buf = wmi_buf_alloc(wmi, len); 206 if (!buf) { 207 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 208 return QDF_STATUS_E_NOMEM; 209 } 210 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 211 WMITLV_SET_HDR(&cmd->tlv_header, 212 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 213 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 214 cmd->vdev_id = vdev_id; 215 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 216 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 217 wmi_buf_free(buf); 218 return QDF_STATUS_E_FAILURE; 219 } 220 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 221 222 return 0; 223 } 224 225 /** 226 * send_vdev_down_cmd_tlv() - send vdev down command to fw 227 * @wmi: wmi handle 228 * @vdev_id: vdev id 229 * 230 * Return: QDF_STATUS_SUCCESS for success or error code 231 */ 232 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 233 { 234 wmi_vdev_down_cmd_fixed_param *cmd; 235 wmi_buf_t buf; 236 int32_t len = sizeof(*cmd); 237 238 buf = wmi_buf_alloc(wmi, len); 239 if (!buf) { 240 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 241 return QDF_STATUS_E_NOMEM; 242 } 243 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 244 WMITLV_SET_HDR(&cmd->tlv_header, 245 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 246 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 247 cmd->vdev_id = vdev_id; 248 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 249 WMI_LOGP("%s: Failed to send vdev down", __func__); 250 wmi_buf_free(buf); 251 return QDF_STATUS_E_FAILURE; 252 } 253 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 254 255 return 0; 256 } 257 258 #ifdef CONFIG_MCL 259 static inline void copy_channel_info( 260 wmi_vdev_start_request_cmd_fixed_param * cmd, 261 wmi_channel *chan, 262 struct vdev_start_params *req) 263 { 264 chan->mhz = req->chan_freq; 265 266 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 267 268 chan->band_center_freq1 = req->band_center_freq1; 269 chan->band_center_freq2 = req->band_center_freq2; 270 271 if (req->is_half_rate) 272 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 273 else if (req->is_quarter_rate) 274 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 275 276 if (req->is_dfs && req->flag_dfs) { 277 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 278 cmd->disable_hw_ack = req->dis_hw_ack; 279 } 280 281 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 282 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 283 284 } 285 #else 286 static inline void copy_channel_info( 287 wmi_vdev_start_request_cmd_fixed_param * cmd, 288 wmi_channel *chan, 289 struct vdev_start_params *req) 290 { 291 chan->mhz = req->channel.mhz; 292 293 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 294 295 chan->band_center_freq1 = req->channel.cfreq1; 296 chan->band_center_freq2 = req->channel.cfreq2; 297 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 298 299 if (req->channel.half_rate) 300 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 301 else if (req->channel.quarter_rate) 302 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 303 304 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 305 306 if (req->channel.dfs_set) { 307 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 308 cmd->disable_hw_ack = req->disable_hw_ack; 309 } 310 311 if (req->channel.dfs_set_cfreq2) 312 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 313 314 /* According to firmware both reg power and max tx power 315 * on set channel power is used and set it to max reg 316 * power from regulatory. 317 */ 318 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 319 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 320 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 321 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 322 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 323 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 324 325 } 326 #endif 327 /** 328 * send_vdev_start_cmd_tlv() - send vdev start request to fw 329 * @wmi_handle: wmi handle 330 * @req: vdev start params 331 * 332 * Return: QDF status 333 */ 334 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 335 struct vdev_start_params *req) 336 { 337 wmi_vdev_start_request_cmd_fixed_param *cmd; 338 wmi_buf_t buf; 339 wmi_channel *chan; 340 int32_t len, ret; 341 uint8_t *buf_ptr; 342 343 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 344 buf = wmi_buf_alloc(wmi_handle, len); 345 if (!buf) { 346 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 347 return QDF_STATUS_E_NOMEM; 348 } 349 buf_ptr = (uint8_t *) wmi_buf_data(buf); 350 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 351 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 352 WMITLV_SET_HDR(&cmd->tlv_header, 353 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 354 WMITLV_GET_STRUCT_TLVLEN 355 (wmi_vdev_start_request_cmd_fixed_param)); 356 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 357 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 358 cmd->vdev_id = req->vdev_id; 359 360 /* Fill channel info */ 361 copy_channel_info(cmd, chan, req); 362 363 cmd->beacon_interval = req->beacon_intval; 364 cmd->dtim_period = req->dtim_period; 365 366 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 367 if (req->bcn_tx_rate_code) 368 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 369 370 if (!req->is_restart) { 371 cmd->beacon_interval = req->beacon_intval; 372 cmd->dtim_period = req->dtim_period; 373 374 /* Copy the SSID */ 375 if (req->ssid.length) { 376 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 377 cmd->ssid.ssid_len = req->ssid.length; 378 else 379 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 380 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 381 cmd->ssid.ssid_len); 382 } 383 384 if (req->hidden_ssid) 385 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 386 387 if (req->pmf_enabled) 388 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 389 } 390 391 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 392 cmd->num_noa_descriptors = req->num_noa_descriptors; 393 cmd->preferred_rx_streams = req->preferred_rx_streams; 394 cmd->preferred_tx_streams = req->preferred_tx_streams; 395 cmd->cac_duration_ms = req->cac_duration_ms; 396 cmd->regdomain = req->regdomain; 397 cmd->he_ops = req->he_ops; 398 399 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 400 sizeof(wmi_channel)); 401 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 402 cmd->num_noa_descriptors * 403 sizeof(wmi_p2p_noa_descriptor)); 404 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 405 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 406 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 407 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 408 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 409 chan->mhz, req->chan_mode, chan->info, 410 req->is_dfs, req->beacon_intval, cmd->dtim_period, 411 chan->band_center_freq1, chan->band_center_freq2, 412 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 413 req->preferred_tx_streams, req->preferred_rx_streams, 414 req->ldpc_rx_enabled, req->cac_duration_ms, 415 req->regdomain, req->he_ops, 416 req->dis_hw_ack); 417 418 if (req->is_restart) 419 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 420 WMI_VDEV_RESTART_REQUEST_CMDID); 421 else 422 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 423 WMI_VDEV_START_REQUEST_CMDID); 424 if (ret) { 425 WMI_LOGP("%s: Failed to send vdev start command", __func__); 426 wmi_buf_free(buf); 427 return QDF_STATUS_E_FAILURE; 428 } 429 430 return QDF_STATUS_SUCCESS; 431 } 432 433 /** 434 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 435 * @wmi_handle: wmi handle 436 * @restart_params: vdev restart params 437 * 438 * Return: QDF_STATUS_SUCCESS for success or error code 439 */ 440 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 441 struct hidden_ssid_vdev_restart_params *restart_params) 442 { 443 wmi_vdev_start_request_cmd_fixed_param *cmd; 444 wmi_buf_t buf; 445 wmi_channel *chan; 446 int32_t len; 447 uint8_t *buf_ptr; 448 QDF_STATUS ret = 0; 449 450 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 451 buf = wmi_buf_alloc(wmi_handle, len); 452 if (!buf) { 453 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 454 return QDF_STATUS_E_NOMEM; 455 } 456 buf_ptr = (uint8_t *) wmi_buf_data(buf); 457 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 458 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 459 460 WMITLV_SET_HDR(&cmd->tlv_header, 461 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 462 WMITLV_GET_STRUCT_TLVLEN 463 (wmi_vdev_start_request_cmd_fixed_param)); 464 465 WMITLV_SET_HDR(&chan->tlv_header, 466 WMITLV_TAG_STRUC_wmi_channel, 467 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 468 469 cmd->vdev_id = restart_params->session_id; 470 cmd->ssid.ssid_len = restart_params->ssid_len; 471 qdf_mem_copy(cmd->ssid.ssid, 472 restart_params->ssid, 473 cmd->ssid.ssid_len); 474 cmd->flags = restart_params->flags; 475 cmd->requestor_id = restart_params->requestor_id; 476 cmd->disable_hw_ack = restart_params->disable_hw_ack; 477 478 chan->mhz = restart_params->mhz; 479 chan->band_center_freq1 = 480 restart_params->band_center_freq1; 481 chan->band_center_freq2 = 482 restart_params->band_center_freq2; 483 chan->info = restart_params->info; 484 chan->reg_info_1 = restart_params->reg_info_1; 485 chan->reg_info_2 = restart_params->reg_info_2; 486 487 cmd->num_noa_descriptors = 0; 488 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 489 sizeof(wmi_channel)); 490 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 491 cmd->num_noa_descriptors * 492 sizeof(wmi_p2p_noa_descriptor)); 493 494 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 495 WMI_VDEV_RESTART_REQUEST_CMDID); 496 if (QDF_IS_STATUS_ERROR(ret)) { 497 wmi_buf_free(buf); 498 return QDF_STATUS_E_FAILURE; 499 } 500 return QDF_STATUS_SUCCESS; 501 } 502 503 504 /** 505 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 506 * @wmi: wmi handle 507 * @peer_addr: peer mac address 508 * @param: pointer to hold peer flush tid parameter 509 * 510 * Return: 0 for success or error code 511 */ 512 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 513 uint8_t peer_addr[IEEE80211_ADDR_LEN], 514 struct peer_flush_params *param) 515 { 516 wmi_peer_flush_tids_cmd_fixed_param *cmd; 517 wmi_buf_t buf; 518 int32_t len = sizeof(*cmd); 519 520 buf = wmi_buf_alloc(wmi, len); 521 if (!buf) { 522 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 523 return QDF_STATUS_E_NOMEM; 524 } 525 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 526 WMITLV_SET_HDR(&cmd->tlv_header, 527 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 528 WMITLV_GET_STRUCT_TLVLEN 529 (wmi_peer_flush_tids_cmd_fixed_param)); 530 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 531 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 532 cmd->vdev_id = param->vdev_id; 533 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 534 peer_addr, param->vdev_id, 535 param->peer_tid_bitmap); 536 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 537 WMI_LOGP("%s: Failed to send flush tid command", __func__); 538 wmi_buf_free(buf); 539 return QDF_STATUS_E_FAILURE; 540 } 541 542 return 0; 543 } 544 545 /** 546 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 547 * @wmi: wmi handle 548 * @peer_addr: peer mac addr 549 * @vdev_id: vdev id 550 * 551 * Return: QDF_STATUS_SUCCESS for success or error code 552 */ 553 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 554 uint8_t peer_addr[IEEE80211_ADDR_LEN], 555 uint8_t vdev_id) 556 { 557 wmi_peer_delete_cmd_fixed_param *cmd; 558 wmi_buf_t buf; 559 int32_t len = sizeof(*cmd); 560 buf = wmi_buf_alloc(wmi, len); 561 if (!buf) { 562 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 563 return QDF_STATUS_E_NOMEM; 564 } 565 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 566 WMITLV_SET_HDR(&cmd->tlv_header, 567 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 568 WMITLV_GET_STRUCT_TLVLEN 569 (wmi_peer_delete_cmd_fixed_param)); 570 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 571 cmd->vdev_id = vdev_id; 572 573 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 574 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 575 WMI_LOGP("%s: Failed to send peer delete command", __func__); 576 wmi_buf_free(buf); 577 return QDF_STATUS_E_FAILURE; 578 } 579 580 return 0; 581 } 582 583 /** 584 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 585 * to target id. 586 * @targ_paramid: Target parameter id to hold the result. 587 * @peer_param_id: host param id. 588 * 589 * Return: QDF_STATUS_SUCCESS for success 590 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 591 */ 592 #ifdef CONFIG_MCL 593 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 594 uint32_t *targ_paramid, 595 uint32_t peer_param_id) 596 { 597 *targ_paramid = peer_param_id; 598 return QDF_STATUS_SUCCESS; 599 } 600 #else 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 switch (peer_param_id) { 606 case WMI_HOST_PEER_MIMO_PS_STATE: 607 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 608 break; 609 case WMI_HOST_PEER_AMPDU: 610 *targ_paramid = WMI_PEER_AMPDU; 611 break; 612 case WMI_HOST_PEER_AUTHORIZE: 613 *targ_paramid = WMI_PEER_AUTHORIZE; 614 break; 615 case WMI_HOST_PEER_CHWIDTH: 616 *targ_paramid = WMI_PEER_CHWIDTH; 617 break; 618 case WMI_HOST_PEER_NSS: 619 *targ_paramid = WMI_PEER_NSS; 620 break; 621 case WMI_HOST_PEER_USE_4ADDR: 622 *targ_paramid = WMI_PEER_USE_4ADDR; 623 break; 624 case WMI_HOST_PEER_MEMBERSHIP: 625 *targ_paramid = WMI_PEER_MEMBERSHIP; 626 break; 627 case WMI_HOST_PEER_USERPOS: 628 *targ_paramid = WMI_PEER_USERPOS; 629 break; 630 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 631 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 632 break; 633 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 634 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 635 break; 636 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 637 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 638 break; 639 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 640 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 641 break; 642 case WMI_HOST_PEER_PHYMODE: 643 *targ_paramid = WMI_PEER_PHYMODE; 644 break; 645 case WMI_HOST_PEER_USE_FIXED_PWR: 646 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 647 break; 648 case WMI_HOST_PEER_PARAM_FIXED_RATE: 649 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 650 break; 651 case WMI_HOST_PEER_SET_MU_WHITELIST: 652 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 653 break; 654 case WMI_HOST_PEER_SET_MAC_TX_RATE: 655 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 656 break; 657 case WMI_HOST_PEER_SET_MIN_TX_RATE: 658 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 659 break; 660 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 661 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 662 break; 663 case WMI_HOST_PEER_NSS_VHT160: 664 *targ_paramid = WMI_PEER_NSS_VHT160; 665 break; 666 case WMI_HOST_PEER_NSS_VHT80_80: 667 *targ_paramid = WMI_PEER_NSS_VHT80_80; 668 break; 669 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 670 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 671 break; 672 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 673 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 674 break; 675 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 676 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 677 break; 678 case WMI_HOST_PEER_PARAM_MU_ENABLE: 679 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 680 break; 681 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 682 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 683 break; 684 default: 685 return QDF_STATUS_E_NOSUPPORT; 686 } 687 688 return QDF_STATUS_SUCCESS; 689 } 690 #endif 691 /** 692 * send_peer_param_cmd_tlv() - set peer parameter in fw 693 * @wmi: wmi handle 694 * @peer_addr: peer mac address 695 * @param : pointer to hold peer set parameter 696 * 697 * Return: QDF_STATUS_SUCCESS for success or error code 698 */ 699 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 700 uint8_t peer_addr[IEEE80211_ADDR_LEN], 701 struct peer_set_params *param) 702 { 703 wmi_peer_set_param_cmd_fixed_param *cmd; 704 wmi_buf_t buf; 705 int32_t err; 706 uint32_t param_id; 707 708 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 709 param->param_id) != QDF_STATUS_SUCCESS) 710 return QDF_STATUS_E_NOSUPPORT; 711 712 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 713 if (!buf) { 714 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 715 return QDF_STATUS_E_NOMEM; 716 } 717 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 718 WMITLV_SET_HDR(&cmd->tlv_header, 719 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 720 WMITLV_GET_STRUCT_TLVLEN 721 (wmi_peer_set_param_cmd_fixed_param)); 722 cmd->vdev_id = param->vdev_id; 723 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 724 cmd->param_id = param_id; 725 cmd->param_value = param->param_value; 726 err = wmi_unified_cmd_send(wmi, buf, 727 sizeof(wmi_peer_set_param_cmd_fixed_param), 728 WMI_PEER_SET_PARAM_CMDID); 729 if (err) { 730 WMI_LOGE("Failed to send set_param cmd"); 731 wmi_buf_free(buf); 732 return QDF_STATUS_E_FAILURE; 733 } 734 735 return 0; 736 } 737 738 /** 739 * send_vdev_up_cmd_tlv() - send vdev up command in fw 740 * @wmi: wmi handle 741 * @bssid: bssid 742 * @vdev_up_params: pointer to hold vdev up parameter 743 * 744 * Return: QDF_STATUS_SUCCESS for success or error code 745 */ 746 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 747 uint8_t bssid[IEEE80211_ADDR_LEN], 748 struct vdev_up_params *params) 749 { 750 wmi_vdev_up_cmd_fixed_param *cmd; 751 wmi_buf_t buf; 752 int32_t len = sizeof(*cmd); 753 754 WMI_LOGD("%s: VDEV_UP", __func__); 755 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 756 params->vdev_id, params->assoc_id, bssid); 757 buf = wmi_buf_alloc(wmi, len); 758 if (!buf) { 759 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 760 return QDF_STATUS_E_NOMEM; 761 } 762 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 763 WMITLV_SET_HDR(&cmd->tlv_header, 764 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 765 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 766 cmd->vdev_id = params->vdev_id; 767 cmd->vdev_assoc_id = params->assoc_id; 768 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 769 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 770 WMI_LOGP("%s: Failed to send vdev up command", __func__); 771 wmi_buf_free(buf); 772 return QDF_STATUS_E_FAILURE; 773 } 774 775 return 0; 776 } 777 778 /** 779 * send_peer_create_cmd_tlv() - send peer create command to fw 780 * @wmi: wmi handle 781 * @peer_addr: peer mac address 782 * @peer_type: peer type 783 * @vdev_id: vdev id 784 * 785 * Return: QDF_STATUS_SUCCESS for success or error code 786 */ 787 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 788 struct peer_create_params *param) 789 { 790 wmi_peer_create_cmd_fixed_param *cmd; 791 wmi_buf_t buf; 792 int32_t len = sizeof(*cmd); 793 794 buf = wmi_buf_alloc(wmi, len); 795 if (!buf) { 796 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 797 return QDF_STATUS_E_NOMEM; 798 } 799 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 800 WMITLV_SET_HDR(&cmd->tlv_header, 801 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 802 WMITLV_GET_STRUCT_TLVLEN 803 (wmi_peer_create_cmd_fixed_param)); 804 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 805 cmd->peer_type = param->peer_type; 806 cmd->vdev_id = param->vdev_id; 807 808 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 809 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 810 wmi_buf_free(buf); 811 return QDF_STATUS_E_FAILURE; 812 } 813 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 814 param->vdev_id); 815 816 return 0; 817 } 818 819 /** 820 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 821 * command to fw 822 * @wmi: wmi handle 823 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 824 * 825 * Return: 0 for success or error code 826 */ 827 static 828 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 829 struct rx_reorder_queue_setup_params *param) 830 { 831 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 832 wmi_buf_t buf; 833 int32_t len = sizeof(*cmd); 834 835 buf = wmi_buf_alloc(wmi, len); 836 if (!buf) { 837 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 838 return QDF_STATUS_E_NOMEM; 839 } 840 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 841 WMITLV_SET_HDR(&cmd->tlv_header, 842 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 843 WMITLV_GET_STRUCT_TLVLEN 844 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 845 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 846 cmd->vdev_id = param->vdev_id; 847 cmd->tid = param->tid; 848 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 849 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 850 cmd->queue_no = param->queue_no; 851 852 if (wmi_unified_cmd_send(wmi, buf, len, 853 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 854 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 855 __func__); 856 qdf_nbuf_free(buf); 857 return QDF_STATUS_E_FAILURE; 858 } 859 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 860 param->peer_macaddr, param->vdev_id, param->tid); 861 862 return QDF_STATUS_SUCCESS; 863 } 864 865 /** 866 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 867 * command to fw 868 * @wmi: wmi handle 869 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 870 * 871 * Return: 0 for success or error code 872 */ 873 static 874 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 875 struct rx_reorder_queue_remove_params *param) 876 { 877 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 878 wmi_buf_t buf; 879 int32_t len = sizeof(*cmd); 880 881 buf = wmi_buf_alloc(wmi, len); 882 if (!buf) { 883 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 884 return QDF_STATUS_E_NOMEM; 885 } 886 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 887 wmi_buf_data(buf); 888 WMITLV_SET_HDR(&cmd->tlv_header, 889 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 890 WMITLV_GET_STRUCT_TLVLEN 891 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 892 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 893 cmd->vdev_id = param->vdev_id; 894 cmd->tid_mask = param->peer_tid_bitmap; 895 896 if (wmi_unified_cmd_send(wmi, buf, len, 897 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 898 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 899 __func__); 900 qdf_nbuf_free(buf); 901 return QDF_STATUS_E_FAILURE; 902 } 903 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 904 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 905 906 return QDF_STATUS_SUCCESS; 907 } 908 909 /** 910 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 911 * @wmi_handle: wmi handle 912 * @param: pointer holding peer details 913 * 914 * Return: 0 for success or error code 915 */ 916 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 917 struct peer_add_wds_entry_params *param) 918 { 919 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 920 wmi_buf_t buf; 921 int len = sizeof(*cmd); 922 923 buf = wmi_buf_alloc(wmi_handle, len); 924 if (!buf) { 925 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 926 return QDF_STATUS_E_FAILURE; 927 } 928 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 929 WMITLV_SET_HDR(&cmd->tlv_header, 930 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 931 WMITLV_GET_STRUCT_TLVLEN 932 (wmi_peer_add_wds_entry_cmd_fixed_param)); 933 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 934 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 935 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 936 cmd->vdev_id = param->vdev_id; 937 938 return wmi_unified_cmd_send(wmi_handle, buf, len, 939 WMI_PEER_ADD_WDS_ENTRY_CMDID); 940 } 941 942 /** 943 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 944 * @wmi_handle: wmi handle 945 * @param: pointer holding peer details 946 * 947 * Return: 0 for success or error code 948 */ 949 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 950 struct peer_del_wds_entry_params *param) 951 { 952 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 953 wmi_buf_t buf; 954 int len = sizeof(*cmd); 955 956 buf = wmi_buf_alloc(wmi_handle, len); 957 if (!buf) { 958 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 959 return QDF_STATUS_E_NOMEM; 960 } 961 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 962 WMITLV_SET_HDR(&cmd->tlv_header, 963 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 964 WMITLV_GET_STRUCT_TLVLEN 965 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 966 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 967 cmd->vdev_id = param->vdev_id; 968 return wmi_unified_cmd_send(wmi_handle, buf, len, 969 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 970 } 971 972 /** 973 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 974 * @wmi_handle: wmi handle 975 * @param: pointer holding peer details 976 * 977 * Return: 0 for success or error code 978 */ 979 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 980 struct peer_update_wds_entry_params *param) 981 { 982 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 983 wmi_buf_t buf; 984 int len = sizeof(*cmd); 985 986 buf = wmi_buf_alloc(wmi_handle, len); 987 if (!buf) { 988 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 989 return QDF_STATUS_E_NOMEM; 990 } 991 992 /* wmi_buf_alloc returns zeroed command buffer */ 993 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 994 WMITLV_SET_HDR(&cmd->tlv_header, 995 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 996 WMITLV_GET_STRUCT_TLVLEN 997 (wmi_peer_update_wds_entry_cmd_fixed_param)); 998 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 999 cmd->vdev_id = param->vdev_id; 1000 if (param->wds_macaddr) 1001 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1002 &cmd->wds_macaddr); 1003 if (param->peer_macaddr) 1004 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1005 &cmd->peer_macaddr); 1006 return wmi_unified_cmd_send(wmi_handle, buf, len, 1007 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1008 } 1009 1010 /** 1011 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1012 * @wmi_handle: wmi handle 1013 * @param: pointer to get tpc config params 1014 * 1015 * Return: 0 for success or error code 1016 */ 1017 static QDF_STATUS 1018 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1019 uint32_t param) 1020 { 1021 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1022 wmi_buf_t buf; 1023 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1024 1025 buf = wmi_buf_alloc(wmi_handle, len); 1026 if (!buf) { 1027 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1028 return QDF_STATUS_E_NOMEM; 1029 } 1030 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1031 WMITLV_SET_HDR(&cmd->tlv_header, 1032 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1033 WMITLV_GET_STRUCT_TLVLEN 1034 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1035 1036 cmd->param = param; 1037 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1038 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1039 WMI_LOGE("Send pdev get tpc config cmd failed"); 1040 wmi_buf_free(buf); 1041 return QDF_STATUS_E_FAILURE; 1042 1043 } 1044 WMI_LOGD("%s:send success", __func__); 1045 1046 return QDF_STATUS_SUCCESS; 1047 } 1048 1049 #ifdef WLAN_SUPPORT_GREEN_AP 1050 /** 1051 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1052 * @wmi_handle: wmi handle 1053 * @value: value 1054 * @pdev_id: pdev id to have radio context 1055 * 1056 * Return: QDF_STATUS_SUCCESS for success or error code 1057 */ 1058 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1059 uint32_t value, uint8_t pdev_id) 1060 { 1061 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1062 wmi_buf_t buf; 1063 int32_t len = sizeof(*cmd); 1064 1065 WMI_LOGD("Set Green AP PS val %d", value); 1066 1067 buf = wmi_buf_alloc(wmi_handle, len); 1068 if (!buf) { 1069 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1070 return QDF_STATUS_E_NOMEM; 1071 } 1072 1073 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1074 WMITLV_SET_HDR(&cmd->tlv_header, 1075 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1076 WMITLV_GET_STRUCT_TLVLEN 1077 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1078 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1079 cmd->enable = value; 1080 1081 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1082 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1083 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1084 wmi_buf_free(buf); 1085 return QDF_STATUS_E_FAILURE; 1086 } 1087 1088 return 0; 1089 } 1090 #endif 1091 1092 /** 1093 * send_pdev_utf_cmd_tlv() - send utf command to fw 1094 * @wmi_handle: wmi handle 1095 * @param: pointer to pdev_utf_params 1096 * @mac_id: mac id to have radio context 1097 * 1098 * Return: QDF_STATUS_SUCCESS for success or error code 1099 */ 1100 static QDF_STATUS 1101 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1102 struct pdev_utf_params *param, 1103 uint8_t mac_id) 1104 { 1105 wmi_buf_t buf; 1106 uint8_t *cmd; 1107 /* if param->len is 0 no data is sent, return error */ 1108 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1109 static uint8_t msgref = 1; 1110 uint8_t segNumber = 0, segInfo, numSegments; 1111 uint16_t chunk_len, total_bytes; 1112 uint8_t *bufpos; 1113 struct seg_hdr_info segHdrInfo; 1114 1115 bufpos = param->utf_payload; 1116 total_bytes = param->len; 1117 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1118 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1119 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1120 1121 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1122 numSegments++; 1123 1124 while (param->len) { 1125 if (param->len > MAX_WMI_UTF_LEN) 1126 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1127 else 1128 chunk_len = param->len; 1129 1130 buf = wmi_buf_alloc(wmi_handle, 1131 (chunk_len + sizeof(segHdrInfo) + 1132 WMI_TLV_HDR_SIZE)); 1133 if (!buf) { 1134 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1135 return QDF_STATUS_E_NOMEM; 1136 } 1137 1138 cmd = (uint8_t *) wmi_buf_data(buf); 1139 1140 segHdrInfo.len = total_bytes; 1141 segHdrInfo.msgref = msgref; 1142 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1143 segHdrInfo.segmentInfo = segInfo; 1144 segHdrInfo.pad = 0; 1145 1146 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1147 " segHdrInfo.segmentInfo = %d", 1148 __func__, segHdrInfo.len, segHdrInfo.msgref, 1149 segHdrInfo.segmentInfo); 1150 1151 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1152 "chunk len %d", __func__, total_bytes, segNumber, 1153 numSegments, chunk_len); 1154 1155 segNumber++; 1156 1157 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1158 (chunk_len + sizeof(segHdrInfo))); 1159 cmd += WMI_TLV_HDR_SIZE; 1160 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1161 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1162 1163 ret = wmi_unified_cmd_send(wmi_handle, buf, 1164 (chunk_len + sizeof(segHdrInfo) + 1165 WMI_TLV_HDR_SIZE), 1166 WMI_PDEV_UTF_CMDID); 1167 1168 if (QDF_IS_STATUS_ERROR(ret)) { 1169 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1170 wmi_buf_free(buf); 1171 break; 1172 } 1173 1174 param->len -= chunk_len; 1175 bufpos += chunk_len; 1176 } 1177 1178 msgref++; 1179 1180 return ret; 1181 } 1182 #ifdef CONFIG_MCL 1183 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1184 uint32_t host_param) 1185 { 1186 return host_param; 1187 } 1188 #else 1189 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1190 uint32_t host_param) 1191 { 1192 if (host_param < wmi_pdev_param_max) 1193 return wmi_handle->pdev_param[host_param]; 1194 1195 return WMI_UNAVAILABLE_PARAM; 1196 } 1197 #endif 1198 /** 1199 * send_pdev_param_cmd_tlv() - set pdev parameters 1200 * @wmi_handle: wmi handle 1201 * @param: pointer to pdev parameter 1202 * @mac_id: radio context 1203 * 1204 * Return: 0 on success, errno on failure 1205 */ 1206 static QDF_STATUS 1207 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1208 struct pdev_params *param, 1209 uint8_t mac_id) 1210 { 1211 QDF_STATUS ret; 1212 wmi_pdev_set_param_cmd_fixed_param *cmd; 1213 wmi_buf_t buf; 1214 uint16_t len = sizeof(*cmd); 1215 uint32_t pdev_param; 1216 1217 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1218 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1219 WMI_LOGW("%s: Unavailable param %d\n", 1220 __func__, param->param_id); 1221 return QDF_STATUS_E_INVAL; 1222 } 1223 1224 buf = wmi_buf_alloc(wmi_handle, len); 1225 if (!buf) { 1226 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1227 return QDF_STATUS_E_NOMEM; 1228 } 1229 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1230 WMITLV_SET_HDR(&cmd->tlv_header, 1231 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1232 WMITLV_GET_STRUCT_TLVLEN 1233 (wmi_pdev_set_param_cmd_fixed_param)); 1234 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1235 cmd->param_id = pdev_param; 1236 cmd->param_value = param->param_value; 1237 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1238 param->param_value); 1239 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1240 WMI_PDEV_SET_PARAM_CMDID); 1241 if (QDF_IS_STATUS_ERROR(ret)) { 1242 WMI_LOGE("Failed to send set param command ret = %d", ret); 1243 wmi_buf_free(buf); 1244 } 1245 return ret; 1246 } 1247 1248 /** 1249 * send_suspend_cmd_tlv() - WMI suspend function 1250 * @param wmi_handle : handle to WMI. 1251 * @param param : pointer to hold suspend parameter 1252 * @mac_id: radio context 1253 * 1254 * Return 0 on success and -ve on failure. 1255 */ 1256 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1257 struct suspend_params *param, 1258 uint8_t mac_id) 1259 { 1260 wmi_pdev_suspend_cmd_fixed_param *cmd; 1261 wmi_buf_t wmibuf; 1262 uint32_t len = sizeof(*cmd); 1263 int32_t ret; 1264 1265 /* 1266 * send the command to Target to ignore the 1267 * PCIE reset so as to ensure that Host and target 1268 * states are in sync 1269 */ 1270 wmibuf = wmi_buf_alloc(wmi_handle, len); 1271 if (wmibuf == NULL) 1272 return QDF_STATUS_E_NOMEM; 1273 1274 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1275 WMITLV_SET_HDR(&cmd->tlv_header, 1276 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1277 WMITLV_GET_STRUCT_TLVLEN 1278 (wmi_pdev_suspend_cmd_fixed_param)); 1279 if (param->disable_target_intr) 1280 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1281 else 1282 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1283 1284 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1285 1286 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1287 WMI_PDEV_SUSPEND_CMDID); 1288 if (ret) { 1289 wmi_buf_free(wmibuf); 1290 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1291 } 1292 1293 return ret; 1294 } 1295 1296 /** 1297 * send_resume_cmd_tlv() - WMI resume function 1298 * @param wmi_handle : handle to WMI. 1299 * @mac_id: radio context 1300 * 1301 * Return: 0 on success and -ve on failure. 1302 */ 1303 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1304 uint8_t mac_id) 1305 { 1306 wmi_buf_t wmibuf; 1307 wmi_pdev_resume_cmd_fixed_param *cmd; 1308 QDF_STATUS ret; 1309 1310 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1311 if (wmibuf == NULL) 1312 return QDF_STATUS_E_NOMEM; 1313 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1314 WMITLV_SET_HDR(&cmd->tlv_header, 1315 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1316 WMITLV_GET_STRUCT_TLVLEN 1317 (wmi_pdev_resume_cmd_fixed_param)); 1318 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1319 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1320 WMI_PDEV_RESUME_CMDID); 1321 if (QDF_IS_STATUS_ERROR(ret)) { 1322 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1323 wmi_buf_free(wmibuf); 1324 } 1325 1326 return ret; 1327 } 1328 1329 #ifdef FEATURE_WLAN_D0WOW 1330 /** 1331 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1332 * @param wmi_handle: handle to WMI. 1333 * @mac_id: radio context 1334 * 1335 * Return: 0 on success and error code on failure. 1336 */ 1337 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1338 uint8_t mac_id) 1339 { 1340 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1341 wmi_buf_t buf; 1342 int32_t len; 1343 QDF_STATUS status; 1344 1345 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1346 1347 buf = wmi_buf_alloc(wmi_handle, len); 1348 if (!buf) { 1349 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1350 return QDF_STATUS_E_NOMEM; 1351 } 1352 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1353 WMITLV_SET_HDR(&cmd->tlv_header, 1354 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1355 WMITLV_GET_STRUCT_TLVLEN 1356 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1357 1358 cmd->enable = true; 1359 1360 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1361 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1362 if (QDF_IS_STATUS_ERROR(status)) 1363 wmi_buf_free(buf); 1364 1365 return status; 1366 } 1367 1368 /** 1369 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1370 * @param wmi_handle: handle to WMI. 1371 * @mac_id: radio context 1372 * 1373 * Return: 0 on success and error code on failure. 1374 */ 1375 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1376 uint8_t mac_id) 1377 { 1378 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1379 wmi_buf_t buf; 1380 int32_t len; 1381 QDF_STATUS status; 1382 1383 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1384 1385 buf = wmi_buf_alloc(wmi_handle, len); 1386 if (!buf) { 1387 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1388 return QDF_STATUS_E_NOMEM; 1389 } 1390 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1391 WMITLV_SET_HDR(&cmd->tlv_header, 1392 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1393 WMITLV_GET_STRUCT_TLVLEN 1394 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1395 1396 cmd->enable = false; 1397 1398 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1399 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1400 if (QDF_IS_STATUS_ERROR(status)) 1401 wmi_buf_free(buf); 1402 1403 return status; 1404 } 1405 #endif 1406 1407 /** 1408 * send_wow_enable_cmd_tlv() - WMI wow enable function 1409 * @param wmi_handle : handle to WMI. 1410 * @param param : pointer to hold wow enable parameter 1411 * @mac_id: radio context 1412 * 1413 * Return: 0 on success and -ve on failure. 1414 */ 1415 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1416 struct wow_cmd_params *param, 1417 uint8_t mac_id) 1418 { 1419 wmi_wow_enable_cmd_fixed_param *cmd; 1420 wmi_buf_t buf; 1421 int32_t len; 1422 int32_t ret; 1423 1424 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1425 1426 buf = wmi_buf_alloc(wmi_handle, len); 1427 if (!buf) { 1428 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1429 return QDF_STATUS_E_NOMEM; 1430 } 1431 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1432 WMITLV_SET_HDR(&cmd->tlv_header, 1433 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1434 WMITLV_GET_STRUCT_TLVLEN 1435 (wmi_wow_enable_cmd_fixed_param)); 1436 cmd->enable = param->enable; 1437 if (param->can_suspend_link) 1438 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1439 else 1440 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1441 cmd->flags = param->flags; 1442 1443 WMI_LOGI("suspend type: %s", 1444 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1445 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1446 1447 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1448 WMI_WOW_ENABLE_CMDID); 1449 if (ret) 1450 wmi_buf_free(buf); 1451 1452 return ret; 1453 } 1454 1455 /** 1456 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1457 * @wmi_handle: wmi handle 1458 * @peer_addr: peer mac address 1459 * @param: pointer to ap_ps parameter structure 1460 * 1461 * Return: QDF_STATUS_SUCCESS for success or error code 1462 */ 1463 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1464 uint8_t *peer_addr, 1465 struct ap_ps_params *param) 1466 { 1467 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1468 wmi_buf_t buf; 1469 int32_t err; 1470 1471 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1472 if (!buf) { 1473 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1474 return QDF_STATUS_E_NOMEM; 1475 } 1476 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1477 WMITLV_SET_HDR(&cmd->tlv_header, 1478 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1479 WMITLV_GET_STRUCT_TLVLEN 1480 (wmi_ap_ps_peer_cmd_fixed_param)); 1481 cmd->vdev_id = param->vdev_id; 1482 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1483 cmd->param = param->param; 1484 cmd->value = param->value; 1485 err = wmi_unified_cmd_send(wmi_handle, buf, 1486 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1487 if (err) { 1488 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1489 wmi_buf_free(buf); 1490 return QDF_STATUS_E_FAILURE; 1491 } 1492 1493 return 0; 1494 } 1495 1496 /** 1497 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1498 * @wmi_handle: wmi handle 1499 * @peer_addr: peer mac address 1500 * @param: pointer to sta_ps parameter structure 1501 * 1502 * Return: QDF_STATUS_SUCCESS for success or error code 1503 */ 1504 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1505 struct sta_ps_params *param) 1506 { 1507 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1508 wmi_buf_t buf; 1509 int32_t len = sizeof(*cmd); 1510 1511 buf = wmi_buf_alloc(wmi_handle, len); 1512 if (!buf) { 1513 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1514 return QDF_STATUS_E_NOMEM; 1515 } 1516 1517 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1518 WMITLV_SET_HDR(&cmd->tlv_header, 1519 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1520 WMITLV_GET_STRUCT_TLVLEN 1521 (wmi_sta_powersave_param_cmd_fixed_param)); 1522 cmd->vdev_id = param->vdev_id; 1523 cmd->param = param->param; 1524 cmd->value = param->value; 1525 1526 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1527 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1528 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1529 param->vdev_id, param->param, param->value); 1530 wmi_buf_free(buf); 1531 return QDF_STATUS_E_FAILURE; 1532 } 1533 1534 return 0; 1535 } 1536 1537 /** 1538 * send_crash_inject_cmd_tlv() - inject fw crash 1539 * @wmi_handle: wmi handle 1540 * @param: ponirt to crash inject parameter structure 1541 * 1542 * Return: QDF_STATUS_SUCCESS for success or return error 1543 */ 1544 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1545 struct crash_inject *param) 1546 { 1547 int32_t ret = 0; 1548 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1549 uint16_t len = sizeof(*cmd); 1550 wmi_buf_t buf; 1551 1552 buf = wmi_buf_alloc(wmi_handle, len); 1553 if (!buf) { 1554 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1555 return QDF_STATUS_E_NOMEM; 1556 } 1557 1558 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1559 WMITLV_SET_HDR(&cmd->tlv_header, 1560 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1561 WMITLV_GET_STRUCT_TLVLEN 1562 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1563 cmd->type = param->type; 1564 cmd->delay_time_ms = param->delay_time_ms; 1565 1566 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1567 WMI_FORCE_FW_HANG_CMDID); 1568 if (ret) { 1569 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1570 __func__, ret); 1571 wmi_buf_free(buf); 1572 } 1573 1574 return ret; 1575 } 1576 1577 #ifdef FEATURE_FW_LOG_PARSING 1578 /** 1579 * send_dbglog_cmd_tlv() - set debug log level 1580 * @param wmi_handle : handle to WMI. 1581 * @param param : pointer to hold dbglog level parameter 1582 * 1583 * Return: 0 on success and -ve on failure. 1584 */ 1585 static QDF_STATUS 1586 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1587 struct dbglog_params *dbglog_param) 1588 { 1589 wmi_buf_t buf; 1590 wmi_debug_log_config_cmd_fixed_param *configmsg; 1591 QDF_STATUS status; 1592 int32_t i; 1593 int32_t len; 1594 int8_t *buf_ptr; 1595 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1596 1597 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1598 1599 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1600 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1601 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1602 buf = wmi_buf_alloc(wmi_handle, len); 1603 if (buf == NULL) 1604 return QDF_STATUS_E_NOMEM; 1605 1606 configmsg = 1607 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1608 buf_ptr = (int8_t *) configmsg; 1609 WMITLV_SET_HDR(&configmsg->tlv_header, 1610 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1611 WMITLV_GET_STRUCT_TLVLEN 1612 (wmi_debug_log_config_cmd_fixed_param)); 1613 configmsg->dbg_log_param = dbglog_param->param; 1614 configmsg->value = dbglog_param->val; 1615 /* Filling in the data part of second tlv -- should 1616 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1617 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1618 sizeof 1619 (wmi_debug_log_config_cmd_fixed_param) 1620 + WMI_TLV_HDR_SIZE); 1621 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1622 WMITLV_TAG_ARRAY_UINT32, 1623 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1624 if (dbglog_param->module_id_bitmap) { 1625 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1626 module_id_bitmap_array[i] = 1627 dbglog_param->module_id_bitmap[i]; 1628 } 1629 } 1630 1631 status = wmi_unified_cmd_send(wmi_handle, buf, 1632 len, WMI_DBGLOG_CFG_CMDID); 1633 1634 if (status != QDF_STATUS_SUCCESS) 1635 wmi_buf_free(buf); 1636 1637 return status; 1638 } 1639 #endif 1640 1641 #ifdef CONFIG_MCL 1642 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1643 uint32_t host_param) 1644 { 1645 return host_param; 1646 } 1647 #else 1648 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1649 uint32_t host_param) 1650 { 1651 if (host_param < wmi_vdev_param_max) 1652 return wmi_handle->vdev_param[host_param]; 1653 1654 return WMI_UNAVAILABLE_PARAM; 1655 } 1656 #endif 1657 /** 1658 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1659 * @param wmi_handle : handle to WMI. 1660 * @param macaddr : MAC address 1661 * @param param : pointer to hold vdev set parameter 1662 * 1663 * Return: 0 on success and -ve on failure. 1664 */ 1665 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1666 struct vdev_set_params *param) 1667 { 1668 QDF_STATUS ret; 1669 wmi_vdev_set_param_cmd_fixed_param *cmd; 1670 wmi_buf_t buf; 1671 uint16_t len = sizeof(*cmd); 1672 uint32_t vdev_param; 1673 1674 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1675 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1676 WMI_LOGW("%s:Vdev param %d not available", __func__, 1677 param->param_id); 1678 return QDF_STATUS_E_INVAL; 1679 1680 } 1681 1682 buf = wmi_buf_alloc(wmi_handle, len); 1683 if (!buf) { 1684 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1685 return QDF_STATUS_E_NOMEM; 1686 } 1687 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1688 WMITLV_SET_HDR(&cmd->tlv_header, 1689 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1690 WMITLV_GET_STRUCT_TLVLEN 1691 (wmi_vdev_set_param_cmd_fixed_param)); 1692 cmd->vdev_id = param->if_id; 1693 cmd->param_id = vdev_param; 1694 cmd->param_value = param->param_value; 1695 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1696 cmd->vdev_id, cmd->param_id, cmd->param_value); 1697 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1698 WMI_VDEV_SET_PARAM_CMDID); 1699 if (QDF_IS_STATUS_ERROR(ret)) { 1700 WMI_LOGE("Failed to send set param command ret = %d", ret); 1701 wmi_buf_free(buf); 1702 } 1703 1704 return ret; 1705 } 1706 1707 /** 1708 * send_stats_request_cmd_tlv() - WMI request stats function 1709 * @param wmi_handle : handle to WMI. 1710 * @param macaddr : MAC address 1711 * @param param : pointer to hold stats request parameter 1712 * 1713 * Return: 0 on success and -ve on failure. 1714 */ 1715 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1716 uint8_t macaddr[IEEE80211_ADDR_LEN], 1717 struct stats_request_params *param) 1718 { 1719 int32_t ret; 1720 wmi_request_stats_cmd_fixed_param *cmd; 1721 wmi_buf_t buf; 1722 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1723 1724 buf = wmi_buf_alloc(wmi_handle, len); 1725 if (!buf) { 1726 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1727 return -QDF_STATUS_E_NOMEM; 1728 } 1729 1730 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1731 WMITLV_SET_HDR(&cmd->tlv_header, 1732 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1733 WMITLV_GET_STRUCT_TLVLEN 1734 (wmi_request_stats_cmd_fixed_param)); 1735 cmd->stats_id = param->stats_id; 1736 cmd->vdev_id = param->vdev_id; 1737 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1738 param->pdev_id); 1739 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1740 1741 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1742 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1743 1744 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1745 WMI_REQUEST_STATS_CMDID); 1746 1747 if (ret) { 1748 WMI_LOGE("Failed to send status request to fw =%d", ret); 1749 wmi_buf_free(buf); 1750 } 1751 1752 return ret; 1753 } 1754 1755 #ifdef CONFIG_WIN 1756 /** 1757 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1758 * @param wmi_handle : handle to WMI. 1759 * @param PKTLOG_EVENT : packet log event 1760 * @mac_id: mac id to have radio context 1761 * 1762 * Return: 0 on success and -ve on failure. 1763 */ 1764 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1765 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1766 { 1767 int32_t ret; 1768 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1769 wmi_buf_t buf; 1770 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1771 1772 buf = wmi_buf_alloc(wmi_handle, len); 1773 if (!buf) { 1774 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1775 return -QDF_STATUS_E_NOMEM; 1776 } 1777 1778 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1779 WMITLV_SET_HDR(&cmd->tlv_header, 1780 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1781 WMITLV_GET_STRUCT_TLVLEN 1782 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1783 cmd->evlist = PKTLOG_EVENT; 1784 cmd->pdev_id = mac_id; 1785 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1786 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1787 if (ret) { 1788 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1789 wmi_buf_free(buf); 1790 } 1791 1792 return ret; 1793 } 1794 1795 /** 1796 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1797 * @param wmi_handle : handle to WMI. 1798 * @mac_id: mac id to have radio context 1799 * 1800 * Return: 0 on success and -ve on failure. 1801 */ 1802 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1803 uint8_t mac_id) 1804 { 1805 int32_t ret; 1806 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1807 wmi_buf_t buf; 1808 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1809 1810 buf = wmi_buf_alloc(wmi_handle, len); 1811 if (!buf) { 1812 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1813 return -QDF_STATUS_E_NOMEM; 1814 } 1815 1816 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1817 WMITLV_SET_HDR(&cmd->tlv_header, 1818 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1819 WMITLV_GET_STRUCT_TLVLEN 1820 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1821 cmd->pdev_id = mac_id; 1822 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1823 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1824 if (ret) { 1825 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1826 wmi_buf_free(buf); 1827 } 1828 1829 return ret; 1830 } 1831 #else 1832 /** 1833 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1834 * packet-log 1835 * @param wmi_handle : handle to WMI. 1836 * @param macaddr : MAC address 1837 * @param param : pointer to hold stats request parameter 1838 * 1839 * Return: 0 on success and -ve on failure. 1840 */ 1841 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1842 uint8_t macaddr[IEEE80211_ADDR_LEN], 1843 struct packet_enable_params *param) 1844 { 1845 return 0; 1846 } 1847 /** 1848 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1849 * packet-log 1850 * @param wmi_handle : handle to WMI. 1851 * @mac_id: mac id to have radio context 1852 * 1853 * Return: 0 on success and -ve on failure. 1854 */ 1855 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1856 uint8_t mac_id) 1857 { 1858 return 0; 1859 } 1860 #endif 1861 1862 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1863 /** 1864 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1865 * sync time between bwtween host and firmware 1866 * @param wmi_handle : handle to WMI. 1867 * 1868 * Return: None 1869 */ 1870 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1871 { 1872 wmi_buf_t buf; 1873 QDF_STATUS status = QDF_STATUS_SUCCESS; 1874 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1875 int32_t len; 1876 qdf_time_t time_ms; 1877 1878 len = sizeof(*time_stamp); 1879 buf = wmi_buf_alloc(wmi_handle, len); 1880 1881 if (!buf) { 1882 WMI_LOGP(FL("wmi_buf_alloc failed")); 1883 return; 1884 } 1885 time_stamp = 1886 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1887 (wmi_buf_data(buf)); 1888 WMITLV_SET_HDR(&time_stamp->tlv_header, 1889 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1890 WMITLV_GET_STRUCT_TLVLEN( 1891 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1892 1893 time_ms = qdf_get_time_of_the_day_ms(); 1894 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1895 time_stamp->time_stamp_low = time_ms & 1896 WMI_FW_TIME_STAMP_LOW_MASK; 1897 /* 1898 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1899 * wont exceed 27 bit 1900 */ 1901 time_stamp->time_stamp_high = 0; 1902 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1903 time_stamp->mode, time_stamp->time_stamp_low, 1904 time_stamp->time_stamp_high); 1905 1906 status = wmi_unified_cmd_send(wmi_handle, buf, 1907 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1908 if (status) { 1909 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1910 wmi_buf_free(buf); 1911 } 1912 1913 } 1914 1915 #ifdef WLAN_SUPPORT_FILS 1916 /** 1917 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 1918 * @wmi_handle: wmi handle 1919 * @evt_buf: pointer to event buffer 1920 * @vdev_id: pointer to hold vdev id 1921 * 1922 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 1923 */ 1924 static QDF_STATUS 1925 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 1926 void *evt_buf, uint32_t *vdev_id) 1927 { 1928 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 1929 wmi_host_swfda_event_fixed_param *swfda_event; 1930 1931 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 1932 if (!param_buf) { 1933 WMI_LOGE("Invalid swfda event buffer"); 1934 return QDF_STATUS_E_INVAL; 1935 } 1936 swfda_event = param_buf->fixed_param; 1937 *vdev_id = swfda_event->vdev_id; 1938 1939 return QDF_STATUS_SUCCESS; 1940 } 1941 1942 /** 1943 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 1944 * @wmi_handle: wmi handle 1945 * @param: pointer to hold FILS discovery enable param 1946 * 1947 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 1948 */ 1949 static QDF_STATUS 1950 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 1951 struct config_fils_params *param) 1952 { 1953 wmi_enable_fils_cmd_fixed_param *cmd; 1954 wmi_buf_t buf; 1955 QDF_STATUS status; 1956 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 1957 1958 buf = wmi_buf_alloc(wmi_handle, len); 1959 if (!buf) { 1960 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 1961 return QDF_STATUS_E_NOMEM; 1962 } 1963 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 1964 WMITLV_SET_HDR(&cmd->tlv_header, 1965 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 1966 WMITLV_GET_STRUCT_TLVLEN( 1967 wmi_enable_fils_cmd_fixed_param)); 1968 cmd->vdev_id = param->vdev_id; 1969 cmd->fd_period = param->fd_period; 1970 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 1971 param->fd_period, param->vdev_id); 1972 1973 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1974 WMI_ENABLE_FILS_CMDID); 1975 if (status != QDF_STATUS_SUCCESS) { 1976 wmi_buf_free(buf); 1977 return QDF_STATUS_E_FAILURE; 1978 } 1979 1980 return QDF_STATUS_SUCCESS; 1981 } 1982 1983 /** 1984 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 1985 * @wmi_handle: wmi handle 1986 * @param: pointer to hold FD send cmd parameter 1987 * 1988 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 1989 */ 1990 static QDF_STATUS 1991 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 1992 struct fd_params *param) 1993 { 1994 QDF_STATUS ret; 1995 wmi_fd_send_from_host_cmd_fixed_param *cmd; 1996 wmi_buf_t wmi_buf; 1997 qdf_dma_addr_t dma_addr; 1998 1999 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2000 if (!wmi_buf) { 2001 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2002 return QDF_STATUS_E_NOMEM; 2003 } 2004 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2005 WMITLV_SET_HDR(&cmd->tlv_header, 2006 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2007 WMITLV_GET_STRUCT_TLVLEN( 2008 wmi_fd_send_from_host_cmd_fixed_param)); 2009 cmd->vdev_id = param->vdev_id; 2010 cmd->data_len = qdf_nbuf_len(param->wbuf); 2011 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2012 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2013 cmd->frame_ctrl = param->frame_ctrl; 2014 2015 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2016 WMI_PDEV_SEND_FD_CMDID); 2017 if (ret != QDF_STATUS_SUCCESS) { 2018 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2019 __func__, ret); 2020 wmi_buf_free(wmi_buf); 2021 } 2022 2023 return ret; 2024 } 2025 #endif /* WLAN_SUPPORT_FILS */ 2026 2027 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2028 struct beacon_params *param) 2029 { 2030 QDF_STATUS ret; 2031 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2032 wmi_buf_t wmi_buf; 2033 qdf_dma_addr_t dma_addr; 2034 uint32_t dtim_flag = 0; 2035 2036 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2037 if (!wmi_buf) { 2038 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2039 return QDF_STATUS_E_NOMEM; 2040 } 2041 if (param->is_dtim_count_zero) { 2042 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2043 if (param->is_bitctl_reqd) { 2044 /* deliver CAB traffic in next DTIM beacon */ 2045 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2046 } 2047 } 2048 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2049 WMITLV_SET_HDR(&cmd->tlv_header, 2050 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2051 WMITLV_GET_STRUCT_TLVLEN 2052 (wmi_bcn_send_from_host_cmd_fixed_param)); 2053 cmd->vdev_id = param->vdev_id; 2054 cmd->data_len = qdf_nbuf_len(param->wbuf); 2055 cmd->frame_ctrl = param->frame_ctrl; 2056 cmd->dtim_flag = dtim_flag; 2057 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2058 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2059 #if defined(HTT_PADDR64) 2060 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2061 #endif 2062 cmd->bcn_antenna = param->bcn_txant; 2063 2064 ret = wmi_unified_cmd_send(wmi_handle, 2065 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2066 if (ret != QDF_STATUS_SUCCESS) { 2067 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2068 wmi_buf_free(wmi_buf); 2069 } 2070 2071 return ret; 2072 } 2073 2074 /** 2075 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2076 * @param wmi_handle : handle to WMI. 2077 * @param param : pointer to hold beacon send cmd parameter 2078 * 2079 * Return: 0 on success and -ve on failure. 2080 */ 2081 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2082 struct beacon_tmpl_params *param) 2083 { 2084 int32_t ret; 2085 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2086 wmi_bcn_prb_info *bcn_prb_info; 2087 wmi_buf_t wmi_buf; 2088 uint8_t *buf_ptr; 2089 uint32_t wmi_buf_len; 2090 2091 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2092 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2093 param->tmpl_len_aligned; 2094 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2095 if (!wmi_buf) { 2096 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2097 return QDF_STATUS_E_NOMEM; 2098 } 2099 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2100 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2101 WMITLV_SET_HDR(&cmd->tlv_header, 2102 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2103 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2104 cmd->vdev_id = param->vdev_id; 2105 cmd->tim_ie_offset = param->tim_ie_offset; 2106 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2107 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2108 cmd->buf_len = param->tmpl_len; 2109 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2110 2111 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2112 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2113 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2114 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2115 bcn_prb_info->caps = 0; 2116 bcn_prb_info->erp = 0; 2117 buf_ptr += sizeof(wmi_bcn_prb_info); 2118 2119 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2120 buf_ptr += WMI_TLV_HDR_SIZE; 2121 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2122 2123 ret = wmi_unified_cmd_send(wmi_handle, 2124 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2125 if (ret) { 2126 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2127 wmi_buf_free(wmi_buf); 2128 } 2129 2130 return 0; 2131 } 2132 2133 #ifdef CONFIG_MCL 2134 static inline void copy_peer_flags_tlv( 2135 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2136 struct peer_assoc_params *param) 2137 { 2138 cmd->peer_flags = param->peer_flags; 2139 } 2140 #else 2141 static inline void copy_peer_flags_tlv( 2142 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2143 struct peer_assoc_params *param) 2144 { 2145 /* 2146 * The target only needs a subset of the flags maintained in the host. 2147 * Just populate those flags and send it down 2148 */ 2149 cmd->peer_flags = 0; 2150 2151 /* 2152 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2153 */ 2154 if (param->is_wme_set) { 2155 2156 if (param->qos_flag) 2157 cmd->peer_flags |= WMI_PEER_QOS; 2158 if (param->apsd_flag) 2159 cmd->peer_flags |= WMI_PEER_APSD; 2160 if (param->ht_flag) 2161 cmd->peer_flags |= WMI_PEER_HT; 2162 if (param->bw_40) 2163 cmd->peer_flags |= WMI_PEER_40MHZ; 2164 if (param->bw_80) 2165 cmd->peer_flags |= WMI_PEER_80MHZ; 2166 if (param->bw_160) 2167 cmd->peer_flags |= WMI_PEER_160MHZ; 2168 2169 /* Typically if STBC is enabled for VHT it should be enabled 2170 * for HT as well 2171 **/ 2172 if (param->stbc_flag) 2173 cmd->peer_flags |= WMI_PEER_STBC; 2174 2175 /* Typically if LDPC is enabled for VHT it should be enabled 2176 * for HT as well 2177 **/ 2178 if (param->ldpc_flag) 2179 cmd->peer_flags |= WMI_PEER_LDPC; 2180 2181 if (param->static_mimops_flag) 2182 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2183 if (param->dynamic_mimops_flag) 2184 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2185 if (param->spatial_mux_flag) 2186 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2187 if (param->vht_flag) 2188 cmd->peer_flags |= WMI_PEER_VHT; 2189 if (param->he_flag) 2190 cmd->peer_flags |= WMI_PEER_HE; 2191 } 2192 2193 if (param->is_pmf_enabled) 2194 cmd->peer_flags |= WMI_PEER_PMF; 2195 /* 2196 * Suppress authorization for all AUTH modes that need 4-way handshake 2197 * (during re-association). 2198 * Authorization will be done for these modes on key installation. 2199 */ 2200 if (param->auth_flag) 2201 cmd->peer_flags |= WMI_PEER_AUTH; 2202 if (param->need_ptk_4_way) 2203 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2204 else 2205 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2206 if (param->need_gtk_2_way) 2207 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2208 /* safe mode bypass the 4-way handshake */ 2209 if (param->safe_mode_enabled) 2210 cmd->peer_flags &= 2211 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2212 /* Disable AMSDU for station transmit, if user configures it */ 2213 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2214 * it 2215 * if (param->amsdu_disable) Add after FW support 2216 **/ 2217 2218 /* Target asserts if node is marked HT and all MCS is set to 0. 2219 * Mark the node as non-HT if all the mcs rates are disabled through 2220 * iwpriv 2221 **/ 2222 if (param->peer_ht_rates.num_rates == 0) 2223 cmd->peer_flags &= ~WMI_PEER_HT; 2224 } 2225 #endif 2226 2227 #ifdef CONFIG_MCL 2228 static inline void copy_peer_mac_addr_tlv( 2229 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2230 struct peer_assoc_params *param) 2231 { 2232 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2233 sizeof(param->peer_macaddr)); 2234 } 2235 #else 2236 static inline void copy_peer_mac_addr_tlv( 2237 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2238 struct peer_assoc_params *param) 2239 { 2240 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2241 } 2242 #endif 2243 2244 /** 2245 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2246 * @param wmi_handle : handle to WMI. 2247 * @param param : pointer to peer assoc parameter 2248 * 2249 * Return: 0 on success and -ve on failure. 2250 */ 2251 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2252 struct peer_assoc_params *param) 2253 { 2254 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2255 wmi_vht_rate_set *mcs; 2256 wmi_he_rate_set *he_mcs; 2257 wmi_buf_t buf; 2258 int32_t len; 2259 uint8_t *buf_ptr; 2260 QDF_STATUS ret; 2261 uint32_t peer_legacy_rates_align; 2262 uint32_t peer_ht_rates_align; 2263 int32_t i; 2264 2265 2266 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2267 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2268 2269 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2270 (peer_legacy_rates_align * sizeof(uint8_t)) + 2271 WMI_TLV_HDR_SIZE + 2272 (peer_ht_rates_align * sizeof(uint8_t)) + 2273 sizeof(wmi_vht_rate_set) + 2274 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2275 + WMI_TLV_HDR_SIZE); 2276 2277 buf = wmi_buf_alloc(wmi_handle, len); 2278 if (!buf) { 2279 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2280 return QDF_STATUS_E_NOMEM; 2281 } 2282 2283 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2284 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2285 WMITLV_SET_HDR(&cmd->tlv_header, 2286 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2287 WMITLV_GET_STRUCT_TLVLEN 2288 (wmi_peer_assoc_complete_cmd_fixed_param)); 2289 2290 cmd->vdev_id = param->vdev_id; 2291 2292 cmd->peer_new_assoc = param->peer_new_assoc; 2293 cmd->peer_associd = param->peer_associd; 2294 2295 copy_peer_flags_tlv(cmd, param); 2296 copy_peer_mac_addr_tlv(cmd, param); 2297 2298 cmd->peer_rate_caps = param->peer_rate_caps; 2299 cmd->peer_caps = param->peer_caps; 2300 cmd->peer_listen_intval = param->peer_listen_intval; 2301 cmd->peer_ht_caps = param->peer_ht_caps; 2302 cmd->peer_max_mpdu = param->peer_max_mpdu; 2303 cmd->peer_mpdu_density = param->peer_mpdu_density; 2304 cmd->peer_vht_caps = param->peer_vht_caps; 2305 cmd->peer_phymode = param->peer_phymode; 2306 2307 /* Update 11ax capabilities */ 2308 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2309 cmd->peer_he_ops = param->peer_he_ops; 2310 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2311 sizeof(param->peer_he_cap_phyinfo)); 2312 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2313 sizeof(param->peer_ppet)); 2314 2315 /* Update peer legacy rate information */ 2316 buf_ptr += sizeof(*cmd); 2317 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2318 peer_legacy_rates_align); 2319 buf_ptr += WMI_TLV_HDR_SIZE; 2320 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2321 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2322 param->peer_legacy_rates.num_rates); 2323 2324 /* Update peer HT rate information */ 2325 buf_ptr += peer_legacy_rates_align; 2326 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2327 peer_ht_rates_align); 2328 buf_ptr += WMI_TLV_HDR_SIZE; 2329 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2330 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2331 param->peer_ht_rates.num_rates); 2332 2333 /* VHT Rates */ 2334 buf_ptr += peer_ht_rates_align; 2335 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2336 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2337 2338 cmd->peer_nss = param->peer_nss; 2339 2340 /* Update bandwidth-NSS mapping */ 2341 cmd->peer_bw_rxnss_override = 0; 2342 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2343 2344 mcs = (wmi_vht_rate_set *) buf_ptr; 2345 if (param->vht_capable) { 2346 mcs->rx_max_rate = param->rx_max_rate; 2347 mcs->rx_mcs_set = param->rx_mcs_set; 2348 mcs->tx_max_rate = param->tx_max_rate; 2349 mcs->tx_mcs_set = param->tx_mcs_set; 2350 } 2351 2352 /* HE Rates */ 2353 cmd->peer_he_mcs = param->peer_he_mcs_count; 2354 buf_ptr += sizeof(wmi_vht_rate_set); 2355 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2356 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2357 buf_ptr += WMI_TLV_HDR_SIZE; 2358 2359 /* Loop through the HE rate set */ 2360 for (i = 0; i < param->peer_he_mcs_count; i++) { 2361 he_mcs = (wmi_he_rate_set *) buf_ptr; 2362 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2363 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2364 2365 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2366 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2367 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2368 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2369 buf_ptr += sizeof(wmi_he_rate_set); 2370 } 2371 2372 2373 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2374 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2375 "nss %d phymode %d peer_mpdu_density %d " 2376 "cmd->peer_vht_caps %x " 2377 "HE cap_info %x ops %x " 2378 "HE phy %x %x %x " 2379 "peer_bw_rxnss_override %x", __func__, 2380 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2381 cmd->peer_rate_caps, cmd->peer_caps, 2382 cmd->peer_listen_intval, cmd->peer_ht_caps, 2383 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2384 cmd->peer_mpdu_density, 2385 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2386 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2387 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2388 cmd->peer_bw_rxnss_override); 2389 2390 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2391 WMI_PEER_ASSOC_CMDID); 2392 if (QDF_IS_STATUS_ERROR(ret)) { 2393 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2394 __func__, ret); 2395 wmi_buf_free(buf); 2396 } 2397 2398 return ret; 2399 } 2400 2401 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2402 */ 2403 static inline void copy_scan_event_cntrl_flags( 2404 wmi_start_scan_cmd_fixed_param * cmd, 2405 struct scan_req_params *param) 2406 { 2407 2408 /* Scan events subscription */ 2409 if (param->scan_ev_started) 2410 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2411 if (param->scan_ev_completed) 2412 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2413 if (param->scan_ev_bss_chan) 2414 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2415 if (param->scan_ev_foreign_chan) 2416 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2417 if (param->scan_ev_dequeued) 2418 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2419 if (param->scan_ev_preempted) 2420 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2421 if (param->scan_ev_start_failed) 2422 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2423 if (param->scan_ev_restarted) 2424 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2425 if (param->scan_ev_foreign_chn_exit) 2426 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2427 if (param->scan_ev_suspended) 2428 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2429 if (param->scan_ev_resumed) 2430 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2431 2432 /** Set scan control flags */ 2433 cmd->scan_ctrl_flags = 0; 2434 if (param->scan_f_passive) 2435 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2436 if (param->scan_f_strict_passive_pch) 2437 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2438 if (param->scan_f_promisc_mode) 2439 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2440 if (param->scan_f_capture_phy_err) 2441 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2442 if (param->scan_f_half_rate) 2443 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2444 if (param->scan_f_quarter_rate) 2445 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2446 if (param->scan_f_cck_rates) 2447 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2448 if (param->scan_f_ofdm_rates) 2449 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2450 if (param->scan_f_chan_stat_evnt) 2451 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2452 if (param->scan_f_filter_prb_req) 2453 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2454 if (param->scan_f_bcast_probe) 2455 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2456 if (param->scan_f_offchan_mgmt_tx) 2457 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2458 if (param->scan_f_offchan_data_tx) 2459 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2460 if (param->scan_f_force_active_dfs_chn) 2461 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2462 if (param->scan_f_add_tpc_ie_in_probe) 2463 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2464 if (param->scan_f_add_ds_ie_in_probe) 2465 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2466 if (param->scan_f_add_spoofed_mac_in_probe) 2467 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2468 if (param->scan_f_add_rand_seq_in_probe) 2469 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2470 if (param->scan_f_en_ie_whitelist_in_probe) 2471 cmd->scan_ctrl_flags |= 2472 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2473 2474 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2475 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2476 param->adaptive_dwell_time_mode); 2477 } 2478 2479 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2480 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2481 struct scan_req_params *params) 2482 { 2483 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2484 } 2485 2486 /** 2487 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2488 * @mac: random mac addr 2489 * @mask: random mac mask 2490 * @mac_addr: wmi random mac 2491 * @mac_mask: wmi random mac mask 2492 * 2493 * Return None. 2494 */ 2495 static inline 2496 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2497 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2498 { 2499 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2500 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2501 } 2502 2503 /* 2504 * wmi_fill_vendor_oui() - fill vendor OUIs 2505 * @buf_ptr: pointer to wmi tlv buffer 2506 * @num_vendor_oui: number of vendor OUIs to be filled 2507 * @param_voui: pointer to OUI buffer 2508 * 2509 * This function populates the wmi tlv buffer when vendor specific OUIs are 2510 * present. 2511 * 2512 * Return: None 2513 */ 2514 static inline 2515 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2516 uint32_t *pvoui) 2517 { 2518 wmi_vendor_oui *voui = NULL; 2519 uint32_t i; 2520 2521 voui = (wmi_vendor_oui *)buf_ptr; 2522 2523 for (i = 0; i < num_vendor_oui; i++) { 2524 WMITLV_SET_HDR(&voui[i].tlv_header, 2525 WMITLV_TAG_STRUC_wmi_vendor_oui, 2526 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2527 voui[i].oui_type_subtype = pvoui[i]; 2528 } 2529 } 2530 2531 /* 2532 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2533 * @ie_bitmap: output pointer to ie bit map in cmd 2534 * @num_vendor_oui: output pointer to num vendor OUIs 2535 * @ie_whitelist: input parameter 2536 * 2537 * This function populates the IE whitelist attrs of scan, pno and 2538 * scan oui commands for ie_whitelist parameter. 2539 * 2540 * Return: None 2541 */ 2542 static inline 2543 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2544 uint32_t *num_vendor_oui, 2545 struct probe_req_whitelist_attr *ie_whitelist) 2546 { 2547 uint32_t i = 0; 2548 2549 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2550 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2551 2552 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2553 } 2554 2555 /** 2556 * send_scan_start_cmd_tlv() - WMI scan start function 2557 * @param wmi_handle : handle to WMI. 2558 * @param param : pointer to hold scan start cmd parameter 2559 * 2560 * Return: 0 on success and -ve on failure. 2561 */ 2562 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2563 struct scan_req_params *params) 2564 { 2565 int32_t ret = 0; 2566 int32_t i; 2567 wmi_buf_t wmi_buf; 2568 wmi_start_scan_cmd_fixed_param *cmd; 2569 uint8_t *buf_ptr; 2570 uint32_t *tmp_ptr; 2571 wmi_ssid *ssid = NULL; 2572 wmi_mac_addr *bssid; 2573 int len = sizeof(*cmd); 2574 uint8_t extraie_len_with_pad = 0; 2575 uint8_t phymode_roundup = 0; 2576 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2577 2578 /* Length TLV placeholder for array of uint32_t */ 2579 len += WMI_TLV_HDR_SIZE; 2580 /* calculate the length of buffer required */ 2581 if (params->chan_list.num_chan) 2582 len += params->chan_list.num_chan * sizeof(uint32_t); 2583 2584 /* Length TLV placeholder for array of wmi_ssid structures */ 2585 len += WMI_TLV_HDR_SIZE; 2586 if (params->num_ssids) 2587 len += params->num_ssids * sizeof(wmi_ssid); 2588 2589 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2590 len += WMI_TLV_HDR_SIZE; 2591 if (params->num_bssid) 2592 len += sizeof(wmi_mac_addr) * params->num_bssid; 2593 2594 /* Length TLV placeholder for array of bytes */ 2595 len += WMI_TLV_HDR_SIZE; 2596 if (params->extraie.len) 2597 extraie_len_with_pad = 2598 roundup(params->extraie.len, sizeof(uint32_t)); 2599 len += extraie_len_with_pad; 2600 2601 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2602 if (ie_whitelist->num_vendor_oui) 2603 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2604 2605 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2606 if (params->scan_f_wide_band) 2607 phymode_roundup = 2608 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2609 sizeof(uint32_t)); 2610 len += phymode_roundup; 2611 2612 /* Allocate the memory */ 2613 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2614 if (!wmi_buf) { 2615 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2616 __func__); 2617 return QDF_STATUS_E_FAILURE; 2618 } 2619 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2620 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2621 WMITLV_SET_HDR(&cmd->tlv_header, 2622 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2623 WMITLV_GET_STRUCT_TLVLEN 2624 (wmi_start_scan_cmd_fixed_param)); 2625 2626 cmd->scan_id = params->scan_id; 2627 cmd->scan_req_id = params->scan_req_id; 2628 cmd->vdev_id = params->vdev_id; 2629 cmd->scan_priority = params->scan_priority; 2630 2631 copy_scan_event_cntrl_flags(cmd, params); 2632 2633 cmd->dwell_time_active = params->dwell_time_active; 2634 cmd->dwell_time_passive = params->dwell_time_passive; 2635 cmd->min_rest_time = params->min_rest_time; 2636 cmd->max_rest_time = params->max_rest_time; 2637 cmd->repeat_probe_time = params->repeat_probe_time; 2638 cmd->probe_spacing_time = params->probe_spacing_time; 2639 cmd->idle_time = params->idle_time; 2640 cmd->max_scan_time = params->max_scan_time; 2641 cmd->probe_delay = params->probe_delay; 2642 cmd->burst_duration = params->burst_duration; 2643 cmd->num_chan = params->chan_list.num_chan; 2644 cmd->num_bssid = params->num_bssid; 2645 cmd->num_ssids = params->num_ssids; 2646 cmd->ie_len = params->extraie.len; 2647 cmd->n_probes = params->n_probes; 2648 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2649 2650 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2651 2652 if (params->scan_random.randomize) 2653 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2654 params->scan_random.mac_mask, 2655 &cmd->mac_addr, 2656 &cmd->mac_mask); 2657 2658 if (ie_whitelist->white_list) 2659 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2660 &cmd->num_vendor_oui, 2661 ie_whitelist); 2662 2663 buf_ptr += sizeof(*cmd); 2664 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2665 for (i = 0; i < params->chan_list.num_chan; ++i) 2666 tmp_ptr[i] = params->chan_list.chan[i].freq; 2667 2668 WMITLV_SET_HDR(buf_ptr, 2669 WMITLV_TAG_ARRAY_UINT32, 2670 (params->chan_list.num_chan * sizeof(uint32_t))); 2671 buf_ptr += WMI_TLV_HDR_SIZE + 2672 (params->chan_list.num_chan * sizeof(uint32_t)); 2673 2674 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2675 WMI_LOGE("Invalid value for numSsid"); 2676 goto error; 2677 } 2678 2679 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2680 (params->num_ssids * sizeof(wmi_ssid))); 2681 2682 if (params->num_ssids) { 2683 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2684 for (i = 0; i < params->num_ssids; ++i) { 2685 ssid->ssid_len = params->ssid[i].length; 2686 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2687 params->ssid[i].length); 2688 ssid++; 2689 } 2690 } 2691 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2692 2693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2694 (params->num_bssid * sizeof(wmi_mac_addr))); 2695 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2696 2697 if (params->num_bssid) { 2698 for (i = 0; i < params->num_bssid; ++i) { 2699 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2700 ¶ms->bssid_list[i].bytes[0], bssid); 2701 bssid++; 2702 } 2703 } 2704 2705 buf_ptr += WMI_TLV_HDR_SIZE + 2706 (params->num_bssid * sizeof(wmi_mac_addr)); 2707 2708 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2709 if (params->extraie.len) 2710 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2711 params); 2712 2713 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2714 2715 /* probe req ie whitelisting */ 2716 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2717 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2718 2719 buf_ptr += WMI_TLV_HDR_SIZE; 2720 2721 if (cmd->num_vendor_oui) { 2722 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2723 ie_whitelist->voui); 2724 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2725 } 2726 2727 /* Add phy mode TLV if it's a wide band scan */ 2728 if (params->scan_f_wide_band) { 2729 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2730 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2731 for (i = 0; i < params->chan_list.num_chan; ++i) 2732 buf_ptr[i] = 2733 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2734 buf_ptr += phymode_roundup; 2735 } else { 2736 /* Add ZERO legth phy mode TLV */ 2737 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2738 } 2739 2740 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2741 len, WMI_START_SCAN_CMDID); 2742 if (ret) { 2743 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2744 wmi_buf_free(wmi_buf); 2745 } 2746 return ret; 2747 error: 2748 wmi_buf_free(wmi_buf); 2749 return QDF_STATUS_E_FAILURE; 2750 } 2751 2752 /** 2753 * send_scan_stop_cmd_tlv() - WMI scan start function 2754 * @param wmi_handle : handle to WMI. 2755 * @param param : pointer to hold scan cancel cmd parameter 2756 * 2757 * Return: 0 on success and -ve on failure. 2758 */ 2759 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2760 struct scan_cancel_param *param) 2761 { 2762 wmi_stop_scan_cmd_fixed_param *cmd; 2763 int ret; 2764 int len = sizeof(*cmd); 2765 wmi_buf_t wmi_buf; 2766 2767 /* Allocate the memory */ 2768 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2769 if (!wmi_buf) { 2770 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2771 __func__); 2772 ret = QDF_STATUS_E_NOMEM; 2773 goto error; 2774 } 2775 2776 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2777 WMITLV_SET_HDR(&cmd->tlv_header, 2778 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2779 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2780 cmd->vdev_id = param->vdev_id; 2781 cmd->requestor = param->requester; 2782 cmd->scan_id = param->scan_id; 2783 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2784 param->pdev_id); 2785 /* stop the scan with the corresponding scan_id */ 2786 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2787 /* Cancelling all scans */ 2788 cmd->req_type = WMI_SCAN_STOP_ALL; 2789 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2790 /* Cancelling VAP scans */ 2791 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2792 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2793 /* Cancelling specific scan */ 2794 cmd->req_type = WMI_SCAN_STOP_ONE; 2795 } else { 2796 WMI_LOGE("%s: Invalid Command : ", __func__); 2797 wmi_buf_free(wmi_buf); 2798 return QDF_STATUS_E_INVAL; 2799 } 2800 2801 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2802 len, WMI_STOP_SCAN_CMDID); 2803 if (ret) { 2804 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2805 wmi_buf_free(wmi_buf); 2806 } 2807 2808 error: 2809 return ret; 2810 } 2811 2812 #ifdef CONFIG_MCL 2813 /** 2814 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2815 * @param wmi_handle : handle to WMI. 2816 * @param param : pointer to hold scan channel list parameter 2817 * 2818 * Return: 0 on success and -ve on failure. 2819 */ 2820 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2821 struct scan_chan_list_params *chan_list) 2822 { 2823 wmi_buf_t buf; 2824 QDF_STATUS qdf_status; 2825 wmi_scan_chan_list_cmd_fixed_param *cmd; 2826 int i; 2827 uint8_t *buf_ptr; 2828 wmi_channel_param *chan_info, *tchan_info; 2829 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2830 2831 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2832 buf = wmi_buf_alloc(wmi_handle, len); 2833 if (!buf) { 2834 WMI_LOGE("Failed to allocate memory"); 2835 qdf_status = QDF_STATUS_E_NOMEM; 2836 goto end; 2837 } 2838 2839 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2840 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2841 WMITLV_SET_HDR(&cmd->tlv_header, 2842 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2843 WMITLV_GET_STRUCT_TLVLEN 2844 (wmi_scan_chan_list_cmd_fixed_param)); 2845 2846 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2847 2848 cmd->num_scan_chans = chan_list->num_scan_chans; 2849 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2850 WMITLV_TAG_ARRAY_STRUC, 2851 sizeof(wmi_channel) * chan_list->num_scan_chans); 2852 chan_info = (wmi_channel_param *) 2853 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2854 tchan_info = chan_list->chan_info; 2855 2856 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2857 WMITLV_SET_HDR(&chan_info->tlv_header, 2858 WMITLV_TAG_STRUC_wmi_channel, 2859 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2860 chan_info->mhz = tchan_info->mhz; 2861 chan_info->band_center_freq1 = 2862 tchan_info->band_center_freq1; 2863 chan_info->band_center_freq2 = 2864 tchan_info->band_center_freq2; 2865 chan_info->info = tchan_info->info; 2866 chan_info->reg_info_1 = tchan_info->reg_info_1; 2867 chan_info->reg_info_2 = tchan_info->reg_info_2; 2868 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2869 2870 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2871 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2872 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2873 tchan_info++; 2874 chan_info++; 2875 } 2876 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2877 chan_list->pdev_id); 2878 2879 qdf_status = wmi_unified_cmd_send(wmi_handle, 2880 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2881 2882 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2883 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2884 wmi_buf_free(buf); 2885 } 2886 2887 end: 2888 return qdf_status; 2889 } 2890 #else 2891 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2892 struct scan_chan_list_params *chan_list) 2893 { 2894 wmi_buf_t buf; 2895 QDF_STATUS qdf_status; 2896 wmi_scan_chan_list_cmd_fixed_param *cmd; 2897 int i; 2898 uint8_t *buf_ptr; 2899 wmi_channel *chan_info; 2900 struct channel_param *tchan_info; 2901 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2902 2903 len += sizeof(wmi_channel) * chan_list->nallchans; 2904 buf = wmi_buf_alloc(wmi_handle, len); 2905 if (!buf) { 2906 WMI_LOGE("Failed to allocate memory"); 2907 qdf_status = QDF_STATUS_E_NOMEM; 2908 goto end; 2909 } 2910 2911 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2912 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2913 WMITLV_SET_HDR(&cmd->tlv_header, 2914 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2915 WMITLV_GET_STRUCT_TLVLEN 2916 (wmi_scan_chan_list_cmd_fixed_param)); 2917 2918 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2919 2920 if (chan_list->append) 2921 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2922 2923 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2924 chan_list->pdev_id); 2925 cmd->num_scan_chans = chan_list->nallchans; 2926 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2927 WMITLV_TAG_ARRAY_STRUC, 2928 sizeof(wmi_channel) * chan_list->nallchans); 2929 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2930 tchan_info = &(chan_list->ch_param[0]); 2931 2932 for (i = 0; i < chan_list->nallchans; ++i) { 2933 WMITLV_SET_HDR(&chan_info->tlv_header, 2934 WMITLV_TAG_STRUC_wmi_channel, 2935 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2936 chan_info->mhz = tchan_info->mhz; 2937 chan_info->band_center_freq1 = 2938 tchan_info->cfreq1; 2939 chan_info->band_center_freq2 = 2940 tchan_info->cfreq2; 2941 2942 if (tchan_info->is_chan_passive) 2943 WMI_SET_CHANNEL_FLAG(chan_info, 2944 WMI_CHAN_FLAG_PASSIVE); 2945 2946 if (tchan_info->allow_vht) 2947 WMI_SET_CHANNEL_FLAG(chan_info, 2948 WMI_CHAN_FLAG_ALLOW_VHT); 2949 else if (tchan_info->allow_ht) 2950 WMI_SET_CHANNEL_FLAG(chan_info, 2951 WMI_CHAN_FLAG_ALLOW_HT); 2952 WMI_SET_CHANNEL_MODE(chan_info, 2953 tchan_info->phy_mode); 2954 2955 if (tchan_info->half_rate) 2956 WMI_SET_CHANNEL_FLAG(chan_info, 2957 WMI_CHAN_FLAG_HALF_RATE); 2958 2959 if (tchan_info->quarter_rate) 2960 WMI_SET_CHANNEL_FLAG(chan_info, 2961 WMI_CHAN_FLAG_QUARTER_RATE); 2962 2963 /* also fill in power information */ 2964 WMI_SET_CHANNEL_MIN_POWER(chan_info, 2965 tchan_info->minpower); 2966 WMI_SET_CHANNEL_MAX_POWER(chan_info, 2967 tchan_info->maxpower); 2968 WMI_SET_CHANNEL_REG_POWER(chan_info, 2969 tchan_info->maxregpower); 2970 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 2971 tchan_info->antennamax); 2972 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 2973 tchan_info->reg_class_id); 2974 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 2975 tchan_info->maxregpower); 2976 2977 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2978 2979 tchan_info++; 2980 chan_info++; 2981 } 2982 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2983 chan_list->pdev_id); 2984 2985 qdf_status = wmi_unified_cmd_send( 2986 wmi_handle, 2987 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2988 2989 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2990 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2991 wmi_buf_free(buf); 2992 } 2993 2994 end: 2995 return qdf_status; 2996 } 2997 #endif 2998 2999 /** 3000 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3001 * 3002 * @bufp: Pointer to buffer 3003 * @param: Pointer to tx param 3004 * 3005 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3006 */ 3007 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3008 struct tx_send_params param) 3009 { 3010 wmi_tx_send_params *tx_param; 3011 QDF_STATUS status = QDF_STATUS_SUCCESS; 3012 3013 if (!bufp) { 3014 status = QDF_STATUS_E_FAILURE; 3015 return status; 3016 } 3017 tx_param = (wmi_tx_send_params *)bufp; 3018 WMITLV_SET_HDR(&tx_param->tlv_header, 3019 WMITLV_TAG_STRUC_wmi_tx_send_params, 3020 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3021 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3022 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3023 param.mcs_mask); 3024 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3025 param.nss_mask); 3026 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3027 param.retry_limit); 3028 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3029 param.chain_mask); 3030 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3031 param.bw_mask); 3032 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3033 param.preamble_type); 3034 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3035 param.frame_type); 3036 3037 return status; 3038 } 3039 3040 /** 3041 * send_mgmt_cmd_tlv() - WMI scan start function 3042 * @wmi_handle : handle to WMI. 3043 * @param : pointer to hold mgmt cmd parameter 3044 * 3045 * Return: 0 on success and -ve on failure. 3046 */ 3047 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3048 struct wmi_mgmt_params *param) 3049 { 3050 wmi_buf_t buf; 3051 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3052 int32_t cmd_len; 3053 uint64_t dma_addr; 3054 void *qdf_ctx = param->qdf_ctx; 3055 uint8_t *bufp; 3056 QDF_STATUS status = QDF_STATUS_SUCCESS; 3057 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3058 mgmt_tx_dl_frm_len; 3059 3060 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3061 WMI_TLV_HDR_SIZE + 3062 roundup(bufp_len, sizeof(uint32_t)); 3063 3064 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3065 if (!buf) { 3066 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3067 return QDF_STATUS_E_NOMEM; 3068 } 3069 3070 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3071 bufp = (uint8_t *) cmd; 3072 WMITLV_SET_HDR(&cmd->tlv_header, 3073 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3074 WMITLV_GET_STRUCT_TLVLEN 3075 (wmi_mgmt_tx_send_cmd_fixed_param)); 3076 3077 cmd->vdev_id = param->vdev_id; 3078 3079 cmd->desc_id = param->desc_id; 3080 cmd->chanfreq = param->chanfreq; 3081 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3082 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3083 sizeof(uint32_t))); 3084 bufp += WMI_TLV_HDR_SIZE; 3085 qdf_mem_copy(bufp, param->pdata, bufp_len); 3086 3087 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3088 QDF_DMA_TO_DEVICE); 3089 if (status != QDF_STATUS_SUCCESS) { 3090 WMI_LOGE("%s: wmi buf map failed", __func__); 3091 goto free_buf; 3092 } 3093 3094 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3095 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3096 #if defined(HTT_PADDR64) 3097 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3098 #endif 3099 cmd->frame_len = param->frm_len; 3100 cmd->buf_len = bufp_len; 3101 cmd->tx_params_valid = param->tx_params_valid; 3102 3103 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3104 bufp, cmd->vdev_id, cmd->chanfreq); 3105 3106 bufp += roundup(bufp_len, sizeof(uint32_t)); 3107 if (param->tx_params_valid) { 3108 status = populate_tx_send_params(bufp, param->tx_param); 3109 if (status != QDF_STATUS_SUCCESS) { 3110 WMI_LOGE("%s: Populate TX send params failed", 3111 __func__); 3112 goto unmap_tx_frame; 3113 } 3114 cmd_len += sizeof(wmi_tx_send_params); 3115 } 3116 3117 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3118 WMI_MGMT_TX_SEND_CMDID)) { 3119 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3120 goto unmap_tx_frame; 3121 } 3122 return QDF_STATUS_SUCCESS; 3123 3124 unmap_tx_frame: 3125 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3126 QDF_DMA_TO_DEVICE); 3127 free_buf: 3128 wmi_buf_free(buf); 3129 return QDF_STATUS_E_FAILURE; 3130 } 3131 3132 /** 3133 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3134 * @wmi_handle : handle to WMI. 3135 * @param : pointer to offchan data tx cmd parameter 3136 * 3137 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3138 */ 3139 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3140 struct wmi_offchan_data_tx_params *param) 3141 { 3142 wmi_buf_t buf; 3143 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3144 int32_t cmd_len; 3145 uint64_t dma_addr; 3146 void *qdf_ctx = param->qdf_ctx; 3147 uint8_t *bufp; 3148 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3149 param->frm_len : mgmt_tx_dl_frm_len; 3150 QDF_STATUS status = QDF_STATUS_SUCCESS; 3151 3152 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3153 WMI_TLV_HDR_SIZE + 3154 roundup(bufp_len, sizeof(uint32_t)); 3155 3156 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3157 if (!buf) { 3158 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3159 return QDF_STATUS_E_NOMEM; 3160 } 3161 3162 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3163 bufp = (uint8_t *) cmd; 3164 WMITLV_SET_HDR(&cmd->tlv_header, 3165 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3166 WMITLV_GET_STRUCT_TLVLEN 3167 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3168 3169 cmd->vdev_id = param->vdev_id; 3170 3171 cmd->desc_id = param->desc_id; 3172 cmd->chanfreq = param->chanfreq; 3173 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3174 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3175 sizeof(uint32_t))); 3176 bufp += WMI_TLV_HDR_SIZE; 3177 qdf_mem_copy(bufp, param->pdata, bufp_len); 3178 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3179 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3180 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3181 #if defined(HTT_PADDR64) 3182 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3183 #endif 3184 cmd->frame_len = param->frm_len; 3185 cmd->buf_len = bufp_len; 3186 cmd->tx_params_valid = param->tx_params_valid; 3187 3188 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3189 bufp, cmd->vdev_id, cmd->chanfreq); 3190 3191 bufp += roundup(bufp_len, sizeof(uint32_t)); 3192 if (param->tx_params_valid) { 3193 status = populate_tx_send_params(bufp, param->tx_param); 3194 if (status != QDF_STATUS_SUCCESS) { 3195 WMI_LOGE("%s: Populate TX send params failed", 3196 __func__); 3197 goto err1; 3198 } 3199 cmd_len += sizeof(wmi_tx_send_params); 3200 } 3201 3202 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3203 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3204 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3205 goto err1; 3206 } 3207 3208 return QDF_STATUS_SUCCESS; 3209 3210 err1: 3211 wmi_buf_free(buf); 3212 return QDF_STATUS_E_FAILURE; 3213 } 3214 3215 /** 3216 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3217 * @wmi_handle: wmi handle 3218 * @param_value: parameter value 3219 * 3220 * Return: QDF_STATUS_SUCCESS for success or error code 3221 */ 3222 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3223 uint32_t param_value) 3224 { 3225 QDF_STATUS ret; 3226 wmi_modem_power_state_cmd_param *cmd; 3227 wmi_buf_t buf; 3228 uint16_t len = sizeof(*cmd); 3229 3230 buf = wmi_buf_alloc(wmi_handle, len); 3231 if (!buf) { 3232 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3233 return QDF_STATUS_E_NOMEM; 3234 } 3235 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3236 WMITLV_SET_HDR(&cmd->tlv_header, 3237 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3238 WMITLV_GET_STRUCT_TLVLEN 3239 (wmi_modem_power_state_cmd_param)); 3240 cmd->modem_power_state = param_value; 3241 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3242 param_value); 3243 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3244 WMI_MODEM_POWER_STATE_CMDID); 3245 if (QDF_IS_STATUS_ERROR(ret)) { 3246 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3247 wmi_buf_free(buf); 3248 } 3249 3250 return ret; 3251 } 3252 3253 /** 3254 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3255 * @wmi_handle: wmi handle 3256 * @vdev_id: vdev id 3257 * @val: value 3258 * 3259 * Return: QDF_STATUS_SUCCESS for success or error code. 3260 */ 3261 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3262 uint32_t vdev_id, uint8_t val) 3263 { 3264 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3265 wmi_buf_t buf; 3266 int32_t len = sizeof(*cmd); 3267 3268 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3269 3270 buf = wmi_buf_alloc(wmi_handle, len); 3271 if (!buf) { 3272 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3273 return QDF_STATUS_E_NOMEM; 3274 } 3275 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3276 WMITLV_SET_HDR(&cmd->tlv_header, 3277 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3278 WMITLV_GET_STRUCT_TLVLEN 3279 (wmi_sta_powersave_mode_cmd_fixed_param)); 3280 cmd->vdev_id = vdev_id; 3281 if (val) 3282 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3283 else 3284 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3285 3286 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3287 WMI_STA_POWERSAVE_MODE_CMDID)) { 3288 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3289 vdev_id, val); 3290 wmi_buf_free(buf); 3291 return QDF_STATUS_E_FAILURE; 3292 } 3293 return 0; 3294 } 3295 3296 /** 3297 * send_set_mimops_cmd_tlv() - set MIMO powersave 3298 * @wmi_handle: wmi handle 3299 * @vdev_id: vdev id 3300 * @value: value 3301 * 3302 * Return: QDF_STATUS_SUCCESS for success or error code. 3303 */ 3304 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3305 uint8_t vdev_id, int value) 3306 { 3307 QDF_STATUS ret; 3308 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3309 wmi_buf_t buf; 3310 uint16_t len = sizeof(*cmd); 3311 3312 buf = wmi_buf_alloc(wmi_handle, len); 3313 if (!buf) { 3314 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3315 return QDF_STATUS_E_NOMEM; 3316 } 3317 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3318 WMITLV_SET_HDR(&cmd->tlv_header, 3319 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3320 WMITLV_GET_STRUCT_TLVLEN 3321 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3322 3323 cmd->vdev_id = vdev_id; 3324 3325 /* WMI_SMPS_FORCED_MODE values do not directly map 3326 * to SM power save values defined in the specification. 3327 * Make sure to send the right mapping. 3328 */ 3329 switch (value) { 3330 case 0: 3331 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3332 break; 3333 case 1: 3334 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3335 break; 3336 case 2: 3337 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3338 break; 3339 case 3: 3340 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3341 break; 3342 default: 3343 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3344 wmi_buf_free(buf); 3345 return QDF_STATUS_E_FAILURE; 3346 } 3347 3348 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3349 3350 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3351 WMI_STA_SMPS_FORCE_MODE_CMDID); 3352 if (QDF_IS_STATUS_ERROR(ret)) { 3353 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3354 wmi_buf_free(buf); 3355 } 3356 3357 return ret; 3358 } 3359 3360 /** 3361 * send_set_smps_params_cmd_tlv() - set smps params 3362 * @wmi_handle: wmi handle 3363 * @vdev_id: vdev id 3364 * @value: value 3365 * 3366 * Return: QDF_STATUS_SUCCESS for success or error code. 3367 */ 3368 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3369 int value) 3370 { 3371 QDF_STATUS ret; 3372 wmi_sta_smps_param_cmd_fixed_param *cmd; 3373 wmi_buf_t buf; 3374 uint16_t len = sizeof(*cmd); 3375 3376 buf = wmi_buf_alloc(wmi_handle, len); 3377 if (!buf) { 3378 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3379 return QDF_STATUS_E_NOMEM; 3380 } 3381 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3382 WMITLV_SET_HDR(&cmd->tlv_header, 3383 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3384 WMITLV_GET_STRUCT_TLVLEN 3385 (wmi_sta_smps_param_cmd_fixed_param)); 3386 3387 cmd->vdev_id = vdev_id; 3388 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3389 cmd->param = 3390 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3391 3392 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3393 cmd->param); 3394 3395 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3396 WMI_STA_SMPS_PARAM_CMDID); 3397 if (QDF_IS_STATUS_ERROR(ret)) { 3398 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3399 wmi_buf_free(buf); 3400 } 3401 3402 return ret; 3403 } 3404 3405 /** 3406 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3407 * @wmi_handle: wmi handle 3408 * @noa: p2p power save parameters 3409 * 3410 * Return: CDF status 3411 */ 3412 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3413 struct p2p_ps_params *noa) 3414 { 3415 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3416 wmi_p2p_noa_descriptor *noa_discriptor; 3417 wmi_buf_t buf; 3418 uint8_t *buf_ptr; 3419 uint16_t len; 3420 QDF_STATUS status; 3421 uint32_t duration; 3422 3423 WMI_LOGD("%s: Enter", __func__); 3424 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3425 buf = wmi_buf_alloc(wmi_handle, len); 3426 if (!buf) { 3427 WMI_LOGE("Failed to allocate memory"); 3428 status = QDF_STATUS_E_FAILURE; 3429 goto end; 3430 } 3431 3432 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3433 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3434 WMITLV_SET_HDR(&cmd->tlv_header, 3435 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3436 WMITLV_GET_STRUCT_TLVLEN 3437 (wmi_p2p_set_noa_cmd_fixed_param)); 3438 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3439 cmd->vdev_id = noa->session_id; 3440 cmd->enable = (duration) ? true : false; 3441 cmd->num_noa = 1; 3442 3443 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3444 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3445 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3446 sizeof 3447 (wmi_p2p_set_noa_cmd_fixed_param) 3448 + WMI_TLV_HDR_SIZE); 3449 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3450 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3451 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3452 noa_discriptor->type_count = noa->count; 3453 noa_discriptor->duration = duration; 3454 noa_discriptor->interval = noa->interval; 3455 noa_discriptor->start_time = 0; 3456 3457 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3458 cmd->vdev_id, noa->count, noa_discriptor->duration, 3459 noa->interval); 3460 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3461 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3462 if (QDF_IS_STATUS_ERROR(status)) { 3463 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3464 wmi_buf_free(buf); 3465 } 3466 3467 end: 3468 WMI_LOGD("%s: Exit", __func__); 3469 return status; 3470 } 3471 3472 3473 /** 3474 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3475 * @wmi_handle: wmi handle 3476 * @noa: p2p opp power save parameters 3477 * 3478 * Return: CDF status 3479 */ 3480 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3481 struct p2p_ps_params *oppps) 3482 { 3483 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3484 wmi_buf_t buf; 3485 QDF_STATUS status; 3486 3487 WMI_LOGD("%s: Enter", __func__); 3488 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3489 if (!buf) { 3490 WMI_LOGE("Failed to allocate memory"); 3491 status = QDF_STATUS_E_FAILURE; 3492 goto end; 3493 } 3494 3495 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3496 WMITLV_SET_HDR(&cmd->tlv_header, 3497 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3498 WMITLV_GET_STRUCT_TLVLEN 3499 (wmi_p2p_set_oppps_cmd_fixed_param)); 3500 cmd->vdev_id = oppps->session_id; 3501 if (oppps->ctwindow) 3502 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3503 3504 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3505 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3506 cmd->vdev_id, oppps->ctwindow); 3507 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3508 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3509 if (QDF_IS_STATUS_ERROR(status)) { 3510 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3511 wmi_buf_free(buf); 3512 } 3513 3514 end: 3515 WMI_LOGD("%s: Exit", __func__); 3516 return status; 3517 } 3518 3519 #ifdef CONVERGED_P2P_ENABLE 3520 /** 3521 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3522 * @wmi_handle: wmi handle 3523 * @param: p2p listen offload start parameters 3524 * 3525 * Return: QDF status 3526 */ 3527 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3528 struct p2p_lo_start *param) 3529 { 3530 wmi_buf_t buf; 3531 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3532 int32_t len = sizeof(*cmd); 3533 uint8_t *buf_ptr; 3534 QDF_STATUS status; 3535 int device_types_len_aligned; 3536 int probe_resp_len_aligned; 3537 3538 if (!param) { 3539 WMI_LOGE("lo start param is null"); 3540 return QDF_STATUS_E_INVAL; 3541 } 3542 3543 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3544 3545 device_types_len_aligned = 3546 qdf_roundup(param->dev_types_len, 3547 sizeof(uint32_t)); 3548 probe_resp_len_aligned = 3549 qdf_roundup(param->probe_resp_len, 3550 sizeof(uint32_t)); 3551 3552 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3553 probe_resp_len_aligned; 3554 3555 buf = wmi_buf_alloc(wmi_handle, len); 3556 if (!buf) { 3557 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3558 __func__); 3559 return QDF_STATUS_E_NOMEM; 3560 } 3561 3562 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3563 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3564 3565 WMITLV_SET_HDR(&cmd->tlv_header, 3566 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3567 WMITLV_GET_STRUCT_TLVLEN( 3568 wmi_p2p_lo_start_cmd_fixed_param)); 3569 3570 cmd->vdev_id = param->vdev_id; 3571 cmd->ctl_flags = param->ctl_flags; 3572 cmd->channel = param->freq; 3573 cmd->period = param->period; 3574 cmd->interval = param->interval; 3575 cmd->count = param->count; 3576 cmd->device_types_len = param->dev_types_len; 3577 cmd->prob_resp_len = param->probe_resp_len; 3578 3579 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3580 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3581 device_types_len_aligned); 3582 buf_ptr += WMI_TLV_HDR_SIZE; 3583 qdf_mem_copy(buf_ptr, param->device_types, 3584 param->dev_types_len); 3585 3586 buf_ptr += device_types_len_aligned; 3587 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3588 probe_resp_len_aligned); 3589 buf_ptr += WMI_TLV_HDR_SIZE; 3590 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3591 param->probe_resp_len); 3592 3593 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3594 cmd->channel, cmd->period, cmd->interval, cmd->count); 3595 3596 status = wmi_unified_cmd_send(wmi_handle, 3597 buf, len, 3598 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3599 if (status != QDF_STATUS_SUCCESS) { 3600 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3601 __func__, status); 3602 wmi_buf_free(buf); 3603 return status; 3604 } 3605 3606 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3607 3608 return QDF_STATUS_SUCCESS; 3609 } 3610 3611 /** 3612 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3613 * @wmi_handle: wmi handle 3614 * @param: p2p listen offload stop parameters 3615 * 3616 * Return: QDF status 3617 */ 3618 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3619 uint8_t vdev_id) 3620 { 3621 wmi_buf_t buf; 3622 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3623 int32_t len; 3624 QDF_STATUS status; 3625 3626 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3627 3628 len = sizeof(*cmd); 3629 buf = wmi_buf_alloc(wmi_handle, len); 3630 if (!buf) { 3631 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3632 __func__); 3633 return QDF_STATUS_E_NOMEM; 3634 } 3635 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3636 3637 WMITLV_SET_HDR(&cmd->tlv_header, 3638 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3639 WMITLV_GET_STRUCT_TLVLEN( 3640 wmi_p2p_lo_stop_cmd_fixed_param)); 3641 3642 cmd->vdev_id = vdev_id; 3643 3644 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3645 3646 status = wmi_unified_cmd_send(wmi_handle, 3647 buf, len, 3648 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3649 if (status != QDF_STATUS_SUCCESS) { 3650 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3651 __func__, status); 3652 wmi_buf_free(buf); 3653 return status; 3654 } 3655 3656 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3657 3658 return QDF_STATUS_SUCCESS; 3659 } 3660 #endif /* End of CONVERGED_P2P_ENABLE */ 3661 3662 /** 3663 * send_get_temperature_cmd_tlv() - get pdev temperature req 3664 * @wmi_handle: wmi handle 3665 * 3666 * Return: QDF_STATUS_SUCCESS for success or error code. 3667 */ 3668 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3669 { 3670 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3671 wmi_buf_t wmi_buf; 3672 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3673 uint8_t *buf_ptr; 3674 3675 if (!wmi_handle) { 3676 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3677 return QDF_STATUS_E_INVAL; 3678 } 3679 3680 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3681 if (!wmi_buf) { 3682 WMI_LOGE(FL("wmi_buf_alloc failed")); 3683 return QDF_STATUS_E_NOMEM; 3684 } 3685 3686 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3687 3688 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3689 WMITLV_SET_HDR(&cmd->tlv_header, 3690 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3691 WMITLV_GET_STRUCT_TLVLEN 3692 (wmi_pdev_get_temperature_cmd_fixed_param)); 3693 3694 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3695 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3696 WMI_LOGE(FL("failed to send get temperature command")); 3697 wmi_buf_free(wmi_buf); 3698 return QDF_STATUS_E_FAILURE; 3699 } 3700 3701 return QDF_STATUS_SUCCESS; 3702 } 3703 3704 /** 3705 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3706 * @wmi_handle: wmi handle 3707 * @vdevid: vdev id 3708 * @peer_addr: peer mac address 3709 * @auto_triggerparam: auto trigger parameters 3710 * @num_ac: number of access category 3711 * 3712 * This function sets the trigger 3713 * uapsd params such as service interval, delay interval 3714 * and suspend interval which will be used by the firmware 3715 * to send trigger frames periodically when there is no 3716 * traffic on the transmit side. 3717 * 3718 * Return: QDF_STATUS_SUCCESS for success or error code. 3719 */ 3720 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3721 struct sta_uapsd_trig_params *param) 3722 { 3723 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3724 QDF_STATUS ret; 3725 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3726 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3727 uint32_t i; 3728 wmi_buf_t buf; 3729 uint8_t *buf_ptr; 3730 struct sta_uapsd_params *uapsd_param; 3731 wmi_sta_uapsd_auto_trig_param *trig_param; 3732 3733 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3734 if (!buf) { 3735 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3736 return QDF_STATUS_E_NOMEM; 3737 } 3738 3739 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3740 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3741 WMITLV_SET_HDR(&cmd->tlv_header, 3742 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3743 WMITLV_GET_STRUCT_TLVLEN 3744 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3745 cmd->vdev_id = param->vdevid; 3746 cmd->num_ac = param->num_ac; 3747 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3748 3749 /* TLV indicating array of structures to follow */ 3750 buf_ptr += sizeof(*cmd); 3751 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3752 3753 buf_ptr += WMI_TLV_HDR_SIZE; 3754 3755 /* 3756 * Update tag and length for uapsd auto trigger params (this will take 3757 * care of updating tag and length if it is not pre-filled by caller). 3758 */ 3759 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3760 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3761 for (i = 0; i < param->num_ac; i++) { 3762 WMITLV_SET_HDR((buf_ptr + 3763 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3764 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3765 WMITLV_GET_STRUCT_TLVLEN 3766 (wmi_sta_uapsd_auto_trig_param)); 3767 trig_param->wmm_ac = uapsd_param->wmm_ac; 3768 trig_param->user_priority = uapsd_param->user_priority; 3769 trig_param->service_interval = uapsd_param->service_interval; 3770 trig_param->suspend_interval = uapsd_param->suspend_interval; 3771 trig_param->delay_interval = uapsd_param->delay_interval; 3772 trig_param++; 3773 uapsd_param++; 3774 } 3775 3776 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3777 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3778 if (QDF_IS_STATUS_ERROR(ret)) { 3779 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3780 wmi_buf_free(buf); 3781 } 3782 3783 return ret; 3784 } 3785 3786 #ifdef WLAN_FEATURE_DSRC 3787 /** 3788 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3789 * @wmi_handle: pointer to the wmi handle 3790 * @utc: pointer to the UTC time struct 3791 * 3792 * Return: 0 on succes 3793 */ 3794 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3795 struct ocb_utc_param *utc) 3796 { 3797 QDF_STATUS ret; 3798 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3799 uint8_t *buf_ptr; 3800 uint32_t len, i; 3801 wmi_buf_t buf; 3802 3803 len = sizeof(*cmd); 3804 buf = wmi_buf_alloc(wmi_handle, len); 3805 if (!buf) { 3806 WMI_LOGE(FL("wmi_buf_alloc failed")); 3807 return QDF_STATUS_E_NOMEM; 3808 } 3809 3810 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3811 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3812 WMITLV_SET_HDR(&cmd->tlv_header, 3813 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3814 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3815 cmd->vdev_id = utc->vdev_id; 3816 3817 for (i = 0; i < SIZE_UTC_TIME; i++) 3818 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 3819 3820 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 3821 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 3822 3823 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3824 WMI_OCB_SET_UTC_TIME_CMDID); 3825 if (QDF_IS_STATUS_ERROR(ret)) { 3826 WMI_LOGE(FL("Failed to set OCB UTC time")); 3827 wmi_buf_free(buf); 3828 } 3829 3830 return ret; 3831 } 3832 3833 /** 3834 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 3835 * frames on a channel 3836 * @wmi_handle: pointer to the wmi handle 3837 * @timing_advert: pointer to the timing advertisement struct 3838 * 3839 * Return: 0 on succes 3840 */ 3841 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3842 struct ocb_timing_advert_param *timing_advert) 3843 { 3844 QDF_STATUS ret; 3845 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 3846 uint8_t *buf_ptr; 3847 uint32_t len, len_template; 3848 wmi_buf_t buf; 3849 3850 len = sizeof(*cmd) + 3851 WMI_TLV_HDR_SIZE; 3852 3853 len_template = timing_advert->template_length; 3854 /* Add padding to the template if needed */ 3855 if (len_template % 4 != 0) 3856 len_template += 4 - (len_template % 4); 3857 len += len_template; 3858 3859 buf = wmi_buf_alloc(wmi_handle, len); 3860 if (!buf) { 3861 WMI_LOGE(FL("wmi_buf_alloc failed")); 3862 return QDF_STATUS_E_NOMEM; 3863 } 3864 3865 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3866 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 3867 WMITLV_SET_HDR(&cmd->tlv_header, 3868 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 3869 WMITLV_GET_STRUCT_TLVLEN( 3870 wmi_ocb_start_timing_advert_cmd_fixed_param)); 3871 cmd->vdev_id = timing_advert->vdev_id; 3872 cmd->repeat_rate = timing_advert->repeat_rate; 3873 cmd->channel_freq = timing_advert->chan_freq; 3874 cmd->timestamp_offset = timing_advert->timestamp_offset; 3875 cmd->time_value_offset = timing_advert->time_value_offset; 3876 cmd->timing_advert_template_length = timing_advert->template_length; 3877 buf_ptr += sizeof(*cmd); 3878 3879 /* Add the timing advert template */ 3880 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3881 len_template); 3882 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 3883 (uint8_t *)timing_advert->template_value, 3884 timing_advert->template_length); 3885 3886 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3887 WMI_OCB_START_TIMING_ADVERT_CMDID); 3888 if (QDF_IS_STATUS_ERROR(ret)) { 3889 WMI_LOGE(FL("Failed to start OCB timing advert")); 3890 wmi_buf_free(buf); 3891 } 3892 3893 return ret; 3894 } 3895 3896 /** 3897 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 3898 * on a channel 3899 * @wmi_handle: pointer to the wmi handle 3900 * @timing_advert: pointer to the timing advertisement struct 3901 * 3902 * Return: 0 on succes 3903 */ 3904 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3905 struct ocb_timing_advert_param *timing_advert) 3906 { 3907 QDF_STATUS ret; 3908 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 3909 uint8_t *buf_ptr; 3910 uint32_t len; 3911 wmi_buf_t buf; 3912 3913 len = sizeof(*cmd); 3914 buf = wmi_buf_alloc(wmi_handle, len); 3915 if (!buf) { 3916 WMI_LOGE(FL("wmi_buf_alloc failed")); 3917 return QDF_STATUS_E_NOMEM; 3918 } 3919 3920 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3921 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 3922 WMITLV_SET_HDR(&cmd->tlv_header, 3923 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 3924 WMITLV_GET_STRUCT_TLVLEN( 3925 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 3926 cmd->vdev_id = timing_advert->vdev_id; 3927 cmd->channel_freq = timing_advert->chan_freq; 3928 3929 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3930 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 3931 if (QDF_IS_STATUS_ERROR(ret)) { 3932 WMI_LOGE(FL("Failed to stop OCB timing advert")); 3933 wmi_buf_free(buf); 3934 } 3935 3936 return ret; 3937 } 3938 3939 /** 3940 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 3941 * @wmi_handle: pointer to the wmi handle 3942 * @request: pointer to the request 3943 * 3944 * Return: 0 on succes 3945 */ 3946 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 3947 uint8_t vdev_id) 3948 { 3949 QDF_STATUS ret; 3950 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 3951 uint8_t *buf_ptr; 3952 wmi_buf_t buf; 3953 int32_t len; 3954 3955 len = sizeof(*cmd); 3956 buf = wmi_buf_alloc(wmi_handle, len); 3957 if (!buf) { 3958 WMI_LOGE(FL("wmi_buf_alloc failed")); 3959 return QDF_STATUS_E_NOMEM; 3960 } 3961 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3962 3963 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 3964 qdf_mem_zero(cmd, len); 3965 WMITLV_SET_HDR(&cmd->tlv_header, 3966 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 3967 WMITLV_GET_STRUCT_TLVLEN( 3968 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 3969 cmd->vdev_id = vdev_id; 3970 3971 /* Send the WMI command */ 3972 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3973 WMI_OCB_GET_TSF_TIMER_CMDID); 3974 /* If there is an error, set the completion event */ 3975 if (QDF_IS_STATUS_ERROR(ret)) { 3976 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 3977 wmi_buf_free(buf); 3978 } 3979 3980 return ret; 3981 } 3982 3983 /** 3984 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 3985 * @wmi_handle: pointer to the wmi handle 3986 * @get_stats_param: pointer to the dcc stats 3987 * 3988 * Return: 0 on succes 3989 */ 3990 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 3991 struct ocb_dcc_get_stats_param *get_stats_param) 3992 { 3993 QDF_STATUS ret; 3994 wmi_dcc_get_stats_cmd_fixed_param *cmd; 3995 wmi_dcc_channel_stats_request *channel_stats_array; 3996 wmi_buf_t buf; 3997 uint8_t *buf_ptr; 3998 uint32_t len; 3999 uint32_t i; 4000 4001 /* Validate the input */ 4002 if (get_stats_param->request_array_len != 4003 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4004 WMI_LOGE(FL("Invalid parameter")); 4005 return QDF_STATUS_E_INVAL; 4006 } 4007 4008 /* Allocate memory for the WMI command */ 4009 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4010 get_stats_param->request_array_len; 4011 4012 buf = wmi_buf_alloc(wmi_handle, len); 4013 if (!buf) { 4014 WMI_LOGE(FL("wmi_buf_alloc failed")); 4015 return QDF_STATUS_E_NOMEM; 4016 } 4017 4018 buf_ptr = wmi_buf_data(buf); 4019 qdf_mem_zero(buf_ptr, len); 4020 4021 /* Populate the WMI command */ 4022 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4023 buf_ptr += sizeof(*cmd); 4024 4025 WMITLV_SET_HDR(&cmd->tlv_header, 4026 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4027 WMITLV_GET_STRUCT_TLVLEN( 4028 wmi_dcc_get_stats_cmd_fixed_param)); 4029 cmd->vdev_id = get_stats_param->vdev_id; 4030 cmd->num_channels = get_stats_param->channel_count; 4031 4032 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4033 get_stats_param->request_array_len); 4034 buf_ptr += WMI_TLV_HDR_SIZE; 4035 4036 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4037 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4038 get_stats_param->request_array_len); 4039 for (i = 0; i < cmd->num_channels; i++) 4040 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4041 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4042 WMITLV_GET_STRUCT_TLVLEN( 4043 wmi_dcc_channel_stats_request)); 4044 4045 /* Send the WMI command */ 4046 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4047 WMI_DCC_GET_STATS_CMDID); 4048 4049 if (QDF_IS_STATUS_ERROR(ret)) { 4050 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4051 wmi_buf_free(buf); 4052 } 4053 4054 return ret; 4055 } 4056 4057 /** 4058 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4059 * @wmi_handle: pointer to the wmi handle 4060 * @vdev_id: vdev id 4061 * @dcc_stats_bitmap: dcc status bitmap 4062 * 4063 * Return: 0 on succes 4064 */ 4065 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4066 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4067 { 4068 QDF_STATUS ret; 4069 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4070 wmi_buf_t buf; 4071 uint8_t *buf_ptr; 4072 uint32_t len; 4073 4074 /* Allocate memory for the WMI command */ 4075 len = sizeof(*cmd); 4076 4077 buf = wmi_buf_alloc(wmi_handle, len); 4078 if (!buf) { 4079 WMI_LOGE(FL("wmi_buf_alloc failed")); 4080 return QDF_STATUS_E_NOMEM; 4081 } 4082 4083 buf_ptr = wmi_buf_data(buf); 4084 qdf_mem_zero(buf_ptr, len); 4085 4086 /* Populate the WMI command */ 4087 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4088 4089 WMITLV_SET_HDR(&cmd->tlv_header, 4090 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4091 WMITLV_GET_STRUCT_TLVLEN( 4092 wmi_dcc_clear_stats_cmd_fixed_param)); 4093 cmd->vdev_id = vdev_id; 4094 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4095 4096 /* Send the WMI command */ 4097 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4098 WMI_DCC_CLEAR_STATS_CMDID); 4099 if (QDF_IS_STATUS_ERROR(ret)) { 4100 WMI_LOGE(FL("Failed to send the WMI command")); 4101 wmi_buf_free(buf); 4102 } 4103 4104 return ret; 4105 } 4106 4107 /** 4108 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4109 * @wmi_handle: pointer to the wmi handle 4110 * @update_ndl_param: pointer to the request parameters 4111 * 4112 * Return: 0 on success 4113 */ 4114 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4115 struct ocb_dcc_update_ndl_param *update_ndl_param) 4116 { 4117 QDF_STATUS qdf_status; 4118 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4119 wmi_dcc_ndl_chan *ndl_chan_array; 4120 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4121 uint32_t active_state_count; 4122 wmi_buf_t buf; 4123 uint8_t *buf_ptr; 4124 uint32_t len; 4125 uint32_t i; 4126 4127 /* validate the input */ 4128 if (update_ndl_param->dcc_ndl_chan_list_len != 4129 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4130 WMI_LOGE(FL("Invalid parameter")); 4131 return QDF_STATUS_E_INVAL; 4132 } 4133 active_state_count = 0; 4134 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4135 for (i = 0; i < update_ndl_param->channel_count; i++) 4136 active_state_count += 4137 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4138 if (update_ndl_param->dcc_ndl_active_state_list_len != 4139 active_state_count * sizeof(*ndl_active_state_array)) { 4140 WMI_LOGE(FL("Invalid parameter")); 4141 return QDF_STATUS_E_INVAL; 4142 } 4143 4144 /* Allocate memory for the WMI command */ 4145 len = sizeof(*cmd) + 4146 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4147 WMI_TLV_HDR_SIZE + 4148 update_ndl_param->dcc_ndl_active_state_list_len; 4149 4150 buf = wmi_buf_alloc(wmi_handle, len); 4151 if (!buf) { 4152 WMI_LOGE(FL("wmi_buf_alloc failed")); 4153 return QDF_STATUS_E_NOMEM; 4154 } 4155 4156 buf_ptr = wmi_buf_data(buf); 4157 qdf_mem_zero(buf_ptr, len); 4158 4159 /* Populate the WMI command */ 4160 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4161 buf_ptr += sizeof(*cmd); 4162 4163 WMITLV_SET_HDR(&cmd->tlv_header, 4164 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4165 WMITLV_GET_STRUCT_TLVLEN( 4166 wmi_dcc_update_ndl_cmd_fixed_param)); 4167 cmd->vdev_id = update_ndl_param->vdev_id; 4168 cmd->num_channel = update_ndl_param->channel_count; 4169 4170 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4171 update_ndl_param->dcc_ndl_chan_list_len); 4172 buf_ptr += WMI_TLV_HDR_SIZE; 4173 4174 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4175 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4176 update_ndl_param->dcc_ndl_chan_list_len); 4177 for (i = 0; i < cmd->num_channel; i++) 4178 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4179 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4180 WMITLV_GET_STRUCT_TLVLEN( 4181 wmi_dcc_ndl_chan)); 4182 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4183 4184 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4185 update_ndl_param->dcc_ndl_active_state_list_len); 4186 buf_ptr += WMI_TLV_HDR_SIZE; 4187 4188 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4189 qdf_mem_copy(ndl_active_state_array, 4190 update_ndl_param->dcc_ndl_active_state_list, 4191 update_ndl_param->dcc_ndl_active_state_list_len); 4192 for (i = 0; i < active_state_count; i++) { 4193 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4194 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4195 WMITLV_GET_STRUCT_TLVLEN( 4196 wmi_dcc_ndl_active_state_config)); 4197 } 4198 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4199 4200 /* Send the WMI command */ 4201 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4202 WMI_DCC_UPDATE_NDL_CMDID); 4203 /* If there is an error, set the completion event */ 4204 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4205 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4206 wmi_buf_free(buf); 4207 } 4208 4209 return qdf_status; 4210 } 4211 4212 /** 4213 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4214 * @wmi_handle: pointer to the wmi handle 4215 * @config: the OCB configuration 4216 * 4217 * Return: 0 on success 4218 */ 4219 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4220 struct ocb_config *config) 4221 { 4222 QDF_STATUS ret; 4223 wmi_ocb_set_config_cmd_fixed_param *cmd; 4224 wmi_channel *chan; 4225 wmi_ocb_channel *ocb_chan; 4226 wmi_qos_parameter *qos_param; 4227 wmi_dcc_ndl_chan *ndl_chan; 4228 wmi_dcc_ndl_active_state_config *ndl_active_config; 4229 wmi_ocb_schedule_element *sched_elem; 4230 uint8_t *buf_ptr; 4231 wmi_buf_t buf; 4232 int32_t len; 4233 int32_t i, j, active_state_count; 4234 4235 /* 4236 * Validate the dcc_ndl_chan_list_len and count the number of active 4237 * states. Validate dcc_ndl_active_state_list_len. 4238 */ 4239 active_state_count = 0; 4240 if (config->dcc_ndl_chan_list_len) { 4241 if (!config->dcc_ndl_chan_list || 4242 config->dcc_ndl_chan_list_len != 4243 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4244 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4245 config->dcc_ndl_chan_list_len); 4246 return QDF_STATUS_E_INVAL; 4247 } 4248 4249 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4250 i < config->channel_count; ++i, ++ndl_chan) 4251 active_state_count += 4252 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4253 4254 if (active_state_count) { 4255 if (!config->dcc_ndl_active_state_list || 4256 config->dcc_ndl_active_state_list_len != 4257 active_state_count * 4258 sizeof(wmi_dcc_ndl_active_state_config)) { 4259 WMI_LOGE(FL("NDL active state is invalid.")); 4260 return QDF_STATUS_E_INVAL; 4261 } 4262 } 4263 } 4264 4265 len = sizeof(*cmd) + 4266 WMI_TLV_HDR_SIZE + config->channel_count * 4267 sizeof(wmi_channel) + 4268 WMI_TLV_HDR_SIZE + config->channel_count * 4269 sizeof(wmi_ocb_channel) + 4270 WMI_TLV_HDR_SIZE + config->channel_count * 4271 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4272 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4273 WMI_TLV_HDR_SIZE + active_state_count * 4274 sizeof(wmi_dcc_ndl_active_state_config) + 4275 WMI_TLV_HDR_SIZE + config->schedule_size * 4276 sizeof(wmi_ocb_schedule_element); 4277 buf = wmi_buf_alloc(wmi_handle, len); 4278 if (!buf) { 4279 WMI_LOGE(FL("wmi_buf_alloc failed")); 4280 return QDF_STATUS_E_NOMEM; 4281 } 4282 4283 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4284 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4285 WMITLV_SET_HDR(&cmd->tlv_header, 4286 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4287 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4288 cmd->vdev_id = config->vdev_id; 4289 cmd->channel_count = config->channel_count; 4290 cmd->schedule_size = config->schedule_size; 4291 cmd->flags = config->flags; 4292 buf_ptr += sizeof(*cmd); 4293 4294 /* Add the wmi_channel info */ 4295 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4296 config->channel_count*sizeof(wmi_channel)); 4297 buf_ptr += WMI_TLV_HDR_SIZE; 4298 for (i = 0; i < config->channel_count; i++) { 4299 chan = (wmi_channel *)buf_ptr; 4300 WMITLV_SET_HDR(&chan->tlv_header, 4301 WMITLV_TAG_STRUC_wmi_channel, 4302 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4303 chan->mhz = config->channels[i].chan_freq; 4304 chan->band_center_freq1 = config->channels[i].chan_freq; 4305 chan->band_center_freq2 = 0; 4306 chan->info = 0; 4307 4308 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4309 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4310 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4311 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4312 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4313 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4314 config->channels[i].antenna_max); 4315 4316 if (config->channels[i].bandwidth < 10) 4317 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4318 else if (config->channels[i].bandwidth < 20) 4319 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4320 buf_ptr += sizeof(*chan); 4321 } 4322 4323 /* Add the wmi_ocb_channel info */ 4324 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4325 config->channel_count*sizeof(wmi_ocb_channel)); 4326 buf_ptr += WMI_TLV_HDR_SIZE; 4327 for (i = 0; i < config->channel_count; i++) { 4328 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4329 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4330 WMITLV_TAG_STRUC_wmi_ocb_channel, 4331 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4332 ocb_chan->bandwidth = config->channels[i].bandwidth; 4333 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4334 config->channels[i].mac_address.bytes, 4335 &ocb_chan->mac_address); 4336 buf_ptr += sizeof(*ocb_chan); 4337 } 4338 4339 /* Add the wmi_qos_parameter info */ 4340 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4341 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4342 buf_ptr += WMI_TLV_HDR_SIZE; 4343 /* WMI_MAX_NUM_AC parameters for each channel */ 4344 for (i = 0; i < config->channel_count; i++) { 4345 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4346 qos_param = (wmi_qos_parameter *)buf_ptr; 4347 WMITLV_SET_HDR(&qos_param->tlv_header, 4348 WMITLV_TAG_STRUC_wmi_qos_parameter, 4349 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4350 qos_param->aifsn = 4351 config->channels[i].qos_params[j].aifsn; 4352 qos_param->cwmin = 4353 config->channels[i].qos_params[j].cwmin; 4354 qos_param->cwmax = 4355 config->channels[i].qos_params[j].cwmax; 4356 buf_ptr += sizeof(*qos_param); 4357 } 4358 } 4359 4360 /* Add the wmi_dcc_ndl_chan (per channel) */ 4361 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4362 config->dcc_ndl_chan_list_len); 4363 buf_ptr += WMI_TLV_HDR_SIZE; 4364 if (config->dcc_ndl_chan_list_len) { 4365 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4366 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4367 config->dcc_ndl_chan_list_len); 4368 for (i = 0; i < config->channel_count; i++) 4369 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4370 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4371 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4372 buf_ptr += config->dcc_ndl_chan_list_len; 4373 } 4374 4375 /* Add the wmi_dcc_ndl_active_state_config */ 4376 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4377 sizeof(wmi_dcc_ndl_active_state_config)); 4378 buf_ptr += WMI_TLV_HDR_SIZE; 4379 if (active_state_count) { 4380 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4381 qdf_mem_copy(ndl_active_config, 4382 config->dcc_ndl_active_state_list, 4383 active_state_count * sizeof(*ndl_active_config)); 4384 for (i = 0; i < active_state_count; ++i) 4385 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4386 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4387 WMITLV_GET_STRUCT_TLVLEN( 4388 wmi_dcc_ndl_active_state_config)); 4389 buf_ptr += active_state_count * 4390 sizeof(*ndl_active_config); 4391 } 4392 4393 /* Add the wmi_ocb_schedule_element info */ 4394 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4395 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4396 buf_ptr += WMI_TLV_HDR_SIZE; 4397 for (i = 0; i < config->schedule_size; i++) { 4398 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4399 WMITLV_SET_HDR(&sched_elem->tlv_header, 4400 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4401 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4402 sched_elem->channel_freq = config->schedule[i].chan_freq; 4403 sched_elem->total_duration = config->schedule[i].total_duration; 4404 sched_elem->guard_interval = config->schedule[i].guard_interval; 4405 buf_ptr += sizeof(*sched_elem); 4406 } 4407 4408 4409 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4410 WMI_OCB_SET_CONFIG_CMDID); 4411 if (QDF_IS_STATUS_ERROR(ret)) { 4412 WMI_LOGE("Failed to set OCB config"); 4413 wmi_buf_free(buf); 4414 } 4415 4416 return ret; 4417 } 4418 4419 /** 4420 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4421 * @wmi_handle: wmi handle 4422 * @evt_buf: wmi event buffer 4423 * @status: status buffer 4424 * 4425 * Return: QDF_STATUS_SUCCESS on success 4426 */ 4427 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4428 void *evt_buf, 4429 uint32_t *status) 4430 { 4431 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4432 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4433 4434 param_tlvs = evt_buf; 4435 fix_param = param_tlvs->fixed_param; 4436 4437 *status = fix_param->status; 4438 return QDF_STATUS_SUCCESS; 4439 } 4440 4441 /** 4442 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4443 * @wmi_handle: wmi handle 4444 * @evt_buf: wmi event buffer 4445 * @resp: response buffer 4446 * 4447 * Return: QDF_STATUS_SUCCESS on success 4448 */ 4449 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4450 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4451 { 4452 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4453 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4454 4455 param_tlvs = evt_buf; 4456 fix_param = param_tlvs->fixed_param; 4457 resp->vdev_id = fix_param->vdev_id; 4458 resp->timer_high = fix_param->tsf_timer_high; 4459 resp->timer_low = fix_param->tsf_timer_low; 4460 4461 return QDF_STATUS_SUCCESS; 4462 } 4463 4464 /** 4465 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4466 * @wmi_handle: wmi handle 4467 * @evt_buf: wmi event buffer 4468 * @resp: response buffer 4469 * 4470 * Return: QDF_STATUS_SUCCESS on success 4471 */ 4472 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4473 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4474 { 4475 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4476 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4477 4478 param_tlvs = evt_buf; 4479 fix_param = param_tlvs->fixed_param; 4480 resp->vdev_id = fix_param->vdev_id; 4481 resp->status = fix_param->status; 4482 return QDF_STATUS_SUCCESS; 4483 } 4484 4485 /** 4486 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4487 * @wmi_handle: wmi handle 4488 * @evt_buf: wmi event buffer 4489 * @resp: response buffer 4490 * 4491 * Since length of stats is variable, buffer for DCC stats will be allocated 4492 * in this function. The caller must free the buffer. 4493 * 4494 * Return: QDF_STATUS_SUCCESS on success 4495 */ 4496 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4497 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4498 { 4499 struct ocb_dcc_get_stats_response *response; 4500 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4501 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4502 4503 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4504 fix_param = param_tlvs->fixed_param; 4505 4506 /* Allocate and populate the response */ 4507 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4508 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4509 WMI_LOGE("%s: too many channels:%d", __func__, 4510 fix_param->num_channels); 4511 QDF_ASSERT(0); 4512 *resp = NULL; 4513 return QDF_STATUS_E_INVAL; 4514 } 4515 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4516 sizeof(wmi_dcc_ndl_stats_per_channel)); 4517 *resp = response; 4518 if (!response) 4519 return QDF_STATUS_E_NOMEM; 4520 4521 response->vdev_id = fix_param->vdev_id; 4522 response->num_channels = fix_param->num_channels; 4523 response->channel_stats_array_len = 4524 fix_param->num_channels * 4525 sizeof(wmi_dcc_ndl_stats_per_channel); 4526 response->channel_stats_array = ((uint8_t *)response) + 4527 sizeof(*response); 4528 qdf_mem_copy(response->channel_stats_array, 4529 param_tlvs->stats_per_channel_list, 4530 response->channel_stats_array_len); 4531 4532 return QDF_STATUS_SUCCESS; 4533 } 4534 #endif 4535 4536 /** 4537 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4538 * @wmi_handle: wmi handle 4539 * @mcc_adaptive_scheduler: enable/disable 4540 * 4541 * This function enable/disable mcc adaptive scheduler in fw. 4542 * 4543 * Return: QDF_STATUS_SUCCESS for success or error code 4544 */ 4545 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4546 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4547 uint32_t pdev_id) 4548 { 4549 QDF_STATUS ret; 4550 wmi_buf_t buf = 0; 4551 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4552 uint16_t len = 4553 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4554 4555 buf = wmi_buf_alloc(wmi_handle, len); 4556 if (!buf) { 4557 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4558 return QDF_STATUS_E_NOMEM; 4559 } 4560 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4561 wmi_buf_data(buf); 4562 4563 WMITLV_SET_HDR(&cmd->tlv_header, 4564 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4565 WMITLV_GET_STRUCT_TLVLEN 4566 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4567 cmd->enable = mcc_adaptive_scheduler; 4568 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4569 4570 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4571 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4572 if (QDF_IS_STATUS_ERROR(ret)) { 4573 WMI_LOGP("%s: Failed to send enable/disable MCC" 4574 " adaptive scheduler command", __func__); 4575 wmi_buf_free(buf); 4576 } 4577 4578 return ret; 4579 } 4580 4581 /** 4582 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4583 * @wmi: wmi handle 4584 * @mcc_channel: mcc channel 4585 * @mcc_channel_time_latency: MCC channel time latency. 4586 * 4587 * Currently used to set time latency for an MCC vdev/adapter using operating 4588 * channel of it and channel number. The info is provided run time using 4589 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4590 * 4591 * Return: CDF status 4592 */ 4593 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4594 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4595 { 4596 QDF_STATUS ret; 4597 wmi_buf_t buf = 0; 4598 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4599 uint16_t len = 0; 4600 uint8_t *buf_ptr = NULL; 4601 wmi_resmgr_chan_latency chan_latency; 4602 /* Note: we only support MCC time latency for a single channel */ 4603 uint32_t num_channels = 1; 4604 uint32_t chan1_freq = mcc_channel_freq; 4605 uint32_t latency_chan1 = mcc_channel_time_latency; 4606 4607 4608 /* If 0ms latency is provided, then FW will set to a default. 4609 * Otherwise, latency must be at least 30ms. 4610 */ 4611 if ((latency_chan1 > 0) && 4612 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4613 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4614 "Minimum is 30ms (or 0 to use default value by " 4615 "firmware)", __func__, latency_chan1); 4616 return QDF_STATUS_E_INVAL; 4617 } 4618 4619 /* Set WMI CMD for channel time latency here */ 4620 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4621 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4622 num_channels * sizeof(wmi_resmgr_chan_latency); 4623 buf = wmi_buf_alloc(wmi_handle, len); 4624 if (!buf) { 4625 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4626 return QDF_STATUS_E_NOMEM; 4627 } 4628 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4629 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4630 wmi_buf_data(buf); 4631 WMITLV_SET_HDR(&cmdTL->tlv_header, 4632 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4633 WMITLV_GET_STRUCT_TLVLEN 4634 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4635 cmdTL->num_chans = num_channels; 4636 /* Update channel time latency information for home channel(s) */ 4637 buf_ptr += sizeof(*cmdTL); 4638 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4639 num_channels * sizeof(wmi_resmgr_chan_latency)); 4640 buf_ptr += WMI_TLV_HDR_SIZE; 4641 chan_latency.chan_mhz = chan1_freq; 4642 chan_latency.latency = latency_chan1; 4643 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4644 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4645 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4646 if (QDF_IS_STATUS_ERROR(ret)) { 4647 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4648 __func__); 4649 wmi_buf_free(buf); 4650 QDF_ASSERT(0); 4651 } 4652 4653 return ret; 4654 } 4655 4656 /** 4657 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4658 * @wmi: wmi handle 4659 * @adapter_1_chan_number: adapter 1 channel number 4660 * @adapter_1_quota: adapter 1 quota 4661 * @adapter_2_chan_number: adapter 2 channel number 4662 * 4663 * Return: CDF status 4664 */ 4665 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4666 uint32_t adapter_1_chan_freq, 4667 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4668 { 4669 QDF_STATUS ret; 4670 wmi_buf_t buf = 0; 4671 uint16_t len = 0; 4672 uint8_t *buf_ptr = NULL; 4673 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4674 wmi_resmgr_chan_time_quota chan_quota; 4675 uint32_t quota_chan1 = adapter_1_quota; 4676 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4677 uint32_t quota_chan2 = 100 - quota_chan1; 4678 /* Note: setting time quota for MCC requires info for 2 channels */ 4679 uint32_t num_channels = 2; 4680 uint32_t chan1_freq = adapter_1_chan_freq; 4681 uint32_t chan2_freq = adapter_2_chan_freq; 4682 4683 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4684 "freq2:%dMHz, Quota2:%dms", __func__, 4685 chan1_freq, quota_chan1, chan2_freq, 4686 quota_chan2); 4687 4688 /* 4689 * Perform sanity check on time quota values provided. 4690 */ 4691 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4692 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4693 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4694 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4695 return QDF_STATUS_E_INVAL; 4696 } 4697 /* Set WMI CMD for channel time quota here */ 4698 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4699 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4700 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4701 buf = wmi_buf_alloc(wmi_handle, len); 4702 if (!buf) { 4703 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4704 QDF_ASSERT(0); 4705 return QDF_STATUS_E_NOMEM; 4706 } 4707 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4708 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4709 wmi_buf_data(buf); 4710 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4711 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4712 WMITLV_GET_STRUCT_TLVLEN 4713 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4714 cmdTQ->num_chans = num_channels; 4715 4716 /* Update channel time quota information for home channel(s) */ 4717 buf_ptr += sizeof(*cmdTQ); 4718 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4719 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4720 buf_ptr += WMI_TLV_HDR_SIZE; 4721 chan_quota.chan_mhz = chan1_freq; 4722 chan_quota.channel_time_quota = quota_chan1; 4723 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4724 /* Construct channel and quota record for the 2nd MCC mode. */ 4725 buf_ptr += sizeof(chan_quota); 4726 chan_quota.chan_mhz = chan2_freq; 4727 chan_quota.channel_time_quota = quota_chan2; 4728 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4729 4730 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4731 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4732 if (QDF_IS_STATUS_ERROR(ret)) { 4733 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4734 wmi_buf_free(buf); 4735 QDF_ASSERT(0); 4736 } 4737 4738 return ret; 4739 } 4740 4741 /** 4742 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4743 * @wmi_handle: Pointer to wmi handle 4744 * @thermal_info: Thermal command information 4745 * 4746 * This function sends the thermal management command 4747 * to the firmware 4748 * 4749 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4750 */ 4751 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4752 struct thermal_cmd_params *thermal_info) 4753 { 4754 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4755 wmi_buf_t buf = NULL; 4756 QDF_STATUS status; 4757 uint32_t len = 0; 4758 4759 len = sizeof(*cmd); 4760 4761 buf = wmi_buf_alloc(wmi_handle, len); 4762 if (!buf) { 4763 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4764 return QDF_STATUS_E_FAILURE; 4765 } 4766 4767 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4768 4769 WMITLV_SET_HDR(&cmd->tlv_header, 4770 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4771 WMITLV_GET_STRUCT_TLVLEN 4772 (wmi_thermal_mgmt_cmd_fixed_param)); 4773 4774 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4775 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4776 cmd->enable = thermal_info->thermal_enable; 4777 4778 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4779 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4780 4781 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4782 WMI_THERMAL_MGMT_CMDID); 4783 if (QDF_IS_STATUS_ERROR(status)) { 4784 wmi_buf_free(buf); 4785 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4786 } 4787 4788 return status; 4789 } 4790 4791 4792 /** 4793 * send_lro_config_cmd_tlv() - process the LRO config command 4794 * @wmi_handle: Pointer to WMI handle 4795 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4796 * 4797 * This function sends down the LRO configuration parameters to 4798 * the firmware to enable LRO, sets the TCP flags and sets the 4799 * seed values for the toeplitz hash generation 4800 * 4801 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4802 */ 4803 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4804 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4805 { 4806 wmi_lro_info_cmd_fixed_param *cmd; 4807 wmi_buf_t buf; 4808 QDF_STATUS status; 4809 4810 4811 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4812 if (!buf) { 4813 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4814 return QDF_STATUS_E_FAILURE; 4815 } 4816 4817 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4818 4819 WMITLV_SET_HDR(&cmd->tlv_header, 4820 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4821 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4822 4823 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4824 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4825 wmi_lro_cmd->tcp_flag); 4826 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4827 wmi_lro_cmd->tcp_flag_mask); 4828 cmd->toeplitz_hash_ipv4_0_3 = 4829 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4830 cmd->toeplitz_hash_ipv4_4_7 = 4831 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4832 cmd->toeplitz_hash_ipv4_8_11 = 4833 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4834 cmd->toeplitz_hash_ipv4_12_15 = 4835 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4836 cmd->toeplitz_hash_ipv4_16 = 4837 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4838 4839 cmd->toeplitz_hash_ipv6_0_3 = 4840 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4841 cmd->toeplitz_hash_ipv6_4_7 = 4842 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4843 cmd->toeplitz_hash_ipv6_8_11 = 4844 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4845 cmd->toeplitz_hash_ipv6_12_15 = 4846 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4847 cmd->toeplitz_hash_ipv6_16_19 = 4848 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4849 cmd->toeplitz_hash_ipv6_20_23 = 4850 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4851 cmd->toeplitz_hash_ipv6_24_27 = 4852 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4853 cmd->toeplitz_hash_ipv6_28_31 = 4854 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4855 cmd->toeplitz_hash_ipv6_32_35 = 4856 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4857 cmd->toeplitz_hash_ipv6_36_39 = 4858 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4859 cmd->toeplitz_hash_ipv6_40 = 4860 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4861 4862 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 4863 cmd->lro_enable, cmd->tcp_flag_u32); 4864 4865 status = wmi_unified_cmd_send(wmi_handle, buf, 4866 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4867 if (QDF_IS_STATUS_ERROR(status)) { 4868 wmi_buf_free(buf); 4869 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4870 } 4871 4872 return status; 4873 } 4874 4875 /** 4876 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4877 * @wmi_handle: Pointer to wmi handle 4878 * @rate_report_params: Pointer to peer rate report parameters 4879 * 4880 * 4881 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4882 */ 4883 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4884 struct wmi_peer_rate_report_params *rate_report_params) 4885 { 4886 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4887 wmi_buf_t buf = NULL; 4888 QDF_STATUS status = 0; 4889 uint32_t len = 0; 4890 uint32_t i, j; 4891 4892 len = sizeof(*cmd); 4893 4894 buf = wmi_buf_alloc(wmi_handle, len); 4895 if (!buf) { 4896 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 4897 return QDF_STATUS_E_FAILURE; 4898 } 4899 4900 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4901 wmi_buf_data(buf); 4902 4903 WMITLV_SET_HDR( 4904 &cmd->tlv_header, 4905 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4906 WMITLV_GET_STRUCT_TLVLEN( 4907 wmi_peer_set_rate_report_condition_fixed_param)); 4908 4909 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4910 cmd->report_backoff_time = rate_report_params->backoff_time; 4911 cmd->report_timer_period = rate_report_params->timer_period; 4912 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4913 cmd->cond_per_phy[i].val_cond_flags = 4914 rate_report_params->report_per_phy[i].cond_flags; 4915 cmd->cond_per_phy[i].rate_delta.min_delta = 4916 rate_report_params->report_per_phy[i].delta.delta_min; 4917 cmd->cond_per_phy[i].rate_delta.percentage = 4918 rate_report_params->report_per_phy[i].delta.percent; 4919 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4920 cmd->cond_per_phy[i].rate_threshold[j] = 4921 rate_report_params->report_per_phy[i]. 4922 report_rate_threshold[j]; 4923 } 4924 } 4925 4926 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 4927 cmd->enable_rate_report, 4928 cmd->report_backoff_time, cmd->report_timer_period); 4929 4930 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4931 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4932 if (QDF_IS_STATUS_ERROR(status)) { 4933 wmi_buf_free(buf); 4934 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4935 __func__); 4936 } 4937 return status; 4938 } 4939 4940 /** 4941 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 4942 * @wmi_handle: wmi handle 4943 * @param: bcn ll cmd parameter 4944 * 4945 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4946 */ 4947 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 4948 wmi_bcn_send_from_host_cmd_fixed_param *param) 4949 { 4950 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 4951 wmi_buf_t wmi_buf; 4952 QDF_STATUS ret; 4953 4954 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4955 if (!wmi_buf) { 4956 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 4957 return QDF_STATUS_E_FAILURE; 4958 } 4959 4960 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4961 WMITLV_SET_HDR(&cmd->tlv_header, 4962 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 4963 WMITLV_GET_STRUCT_TLVLEN 4964 (wmi_bcn_send_from_host_cmd_fixed_param)); 4965 cmd->vdev_id = param->vdev_id; 4966 cmd->data_len = param->data_len; 4967 cmd->frame_ctrl = param->frame_ctrl; 4968 cmd->frag_ptr = param->frag_ptr; 4969 cmd->dtim_flag = param->dtim_flag; 4970 4971 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 4972 WMI_PDEV_SEND_BCN_CMDID); 4973 4974 if (QDF_IS_STATUS_ERROR(ret)) { 4975 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 4976 wmi_buf_free(wmi_buf); 4977 } 4978 4979 return ret; 4980 } 4981 4982 /** 4983 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 4984 * @wmi_handle: wmi handle 4985 * @vdev_id: vdev id 4986 * @max_retries: max retries 4987 * @retry_interval: retry interval 4988 * This function sets sta query related parameters in fw. 4989 * 4990 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4991 */ 4992 4993 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 4994 uint8_t vdev_id, uint32_t max_retries, 4995 uint32_t retry_interval) 4996 { 4997 wmi_buf_t buf; 4998 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 4999 int len; 5000 5001 len = sizeof(*cmd); 5002 buf = wmi_buf_alloc(wmi_handle, len); 5003 if (!buf) { 5004 WMI_LOGE(FL("wmi_buf_alloc failed")); 5005 return QDF_STATUS_E_FAILURE; 5006 } 5007 5008 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5009 WMITLV_SET_HDR(&cmd->tlv_header, 5010 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5011 WMITLV_GET_STRUCT_TLVLEN 5012 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5013 5014 5015 cmd->vdev_id = vdev_id; 5016 cmd->sa_query_max_retry_count = max_retries; 5017 cmd->sa_query_retry_interval = retry_interval; 5018 5019 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5020 vdev_id, retry_interval, max_retries); 5021 5022 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5023 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5024 WMI_LOGE(FL("Failed to offload STA SA Query")); 5025 wmi_buf_free(buf); 5026 return QDF_STATUS_E_FAILURE; 5027 } 5028 5029 WMI_LOGD(FL("Exit :")); 5030 return 0; 5031 } 5032 5033 /** 5034 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5035 * @wmi_handle: wmi handle 5036 * @params: sta keep alive parameter 5037 * 5038 * This function sets keep alive related parameters in fw. 5039 * 5040 * Return: CDF status 5041 */ 5042 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5043 struct sta_params *params) 5044 { 5045 wmi_buf_t buf; 5046 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5047 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5048 uint8_t *buf_ptr; 5049 int len; 5050 QDF_STATUS ret; 5051 5052 WMI_LOGD("%s: Enter", __func__); 5053 5054 len = sizeof(*cmd) + sizeof(*arp_rsp); 5055 buf = wmi_buf_alloc(wmi_handle, len); 5056 if (!buf) { 5057 WMI_LOGE("wmi_buf_alloc failed"); 5058 return QDF_STATUS_E_FAILURE; 5059 } 5060 5061 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5062 buf_ptr = (uint8_t *) cmd; 5063 WMITLV_SET_HDR(&cmd->tlv_header, 5064 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5065 WMITLV_GET_STRUCT_TLVLEN 5066 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5067 cmd->interval = params->timeperiod; 5068 cmd->enable = (params->timeperiod) ? 1 : 0; 5069 cmd->vdev_id = params->vdev_id; 5070 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5071 params->timeperiod, params->method); 5072 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5073 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5074 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5075 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5076 5077 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5078 (params->method == 5079 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5080 if ((NULL == params->hostv4addr) || 5081 (NULL == params->destv4addr) || 5082 (NULL == params->destmac)) { 5083 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5084 "destv4addr:%pK destmac:%pK ", __func__, 5085 params->hostv4addr, params->destv4addr, params->destmac); 5086 wmi_buf_free(buf); 5087 return QDF_STATUS_E_FAILURE; 5088 } 5089 cmd->method = params->method; 5090 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5091 WMI_IPV4_ADDR_LEN); 5092 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5093 WMI_IPV4_ADDR_LEN); 5094 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5095 } else { 5096 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5097 } 5098 5099 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5100 WMI_STA_KEEPALIVE_CMDID); 5101 if (QDF_IS_STATUS_ERROR(ret)) { 5102 WMI_LOGE("Failed to set KeepAlive"); 5103 wmi_buf_free(buf); 5104 } 5105 5106 WMI_LOGD("%s: Exit", __func__); 5107 return ret; 5108 } 5109 5110 /** 5111 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5112 * @wmi_handle: wmi handle 5113 * @if_id: vdev id 5114 * @gtx_info: GTX config params 5115 * 5116 * This function set GTX related params in firmware. 5117 * 5118 * Return: QDF_STATUS_SUCCESS for success or error code 5119 */ 5120 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5121 struct wmi_gtx_config *gtx_info) 5122 { 5123 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5124 wmi_buf_t buf; 5125 QDF_STATUS ret; 5126 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5127 5128 buf = wmi_buf_alloc(wmi_handle, len); 5129 if (!buf) { 5130 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5131 return QDF_STATUS_E_NOMEM; 5132 } 5133 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5134 WMITLV_SET_HDR(&cmd->tlv_header, 5135 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5136 WMITLV_GET_STRUCT_TLVLEN 5137 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5138 cmd->vdev_id = if_id; 5139 5140 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5141 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5142 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5143 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5144 cmd->gtxPERMargin = gtx_info->gtx_margin; 5145 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5146 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5147 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5148 5149 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5150 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5151 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5152 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5153 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5154 5155 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5156 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5157 if (QDF_IS_STATUS_ERROR(ret)) { 5158 WMI_LOGE("Failed to set GTX PARAMS"); 5159 wmi_buf_free(buf); 5160 } 5161 return ret; 5162 } 5163 5164 /** 5165 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5166 * @wmi_handle: wmi handle 5167 * @vdev_id: vdev id. 5168 * @wmm_vparams: edca parameters 5169 * 5170 * This function updates EDCA parameters to the target 5171 * 5172 * Return: CDF Status 5173 */ 5174 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5175 uint8_t vdev_id, bool mu_edca_param, 5176 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5177 { 5178 uint8_t *buf_ptr; 5179 wmi_buf_t buf; 5180 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5181 wmi_wmm_vparams *wmm_param; 5182 struct wmi_host_wme_vparams *twmm_param; 5183 int len = sizeof(*cmd); 5184 int ac; 5185 5186 buf = wmi_buf_alloc(wmi_handle, len); 5187 5188 if (!buf) { 5189 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5190 return QDF_STATUS_E_NOMEM; 5191 } 5192 5193 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5194 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5195 WMITLV_SET_HDR(&cmd->tlv_header, 5196 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5197 WMITLV_GET_STRUCT_TLVLEN 5198 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5199 cmd->vdev_id = vdev_id; 5200 cmd->wmm_param_type = mu_edca_param; 5201 5202 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5203 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5204 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5205 WMITLV_SET_HDR(&wmm_param->tlv_header, 5206 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5207 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5208 wmm_param->cwmin = twmm_param->cwmin; 5209 wmm_param->cwmax = twmm_param->cwmax; 5210 wmm_param->aifs = twmm_param->aifs; 5211 if (mu_edca_param) 5212 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5213 else 5214 wmm_param->txoplimit = twmm_param->txoplimit; 5215 wmm_param->acm = twmm_param->acm; 5216 wmm_param->no_ack = twmm_param->noackpolicy; 5217 } 5218 5219 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5220 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5221 goto fail; 5222 5223 return QDF_STATUS_SUCCESS; 5224 5225 fail: 5226 wmi_buf_free(buf); 5227 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5228 return QDF_STATUS_E_FAILURE; 5229 } 5230 5231 /** 5232 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5233 * @wmi_handle: wmi handle 5234 * @vdev_id: vdev id 5235 * @probe_rsp_info: probe response info 5236 * 5237 * Return: QDF_STATUS_SUCCESS for success or error code 5238 */ 5239 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5240 uint8_t vdev_id, 5241 struct wmi_probe_resp_params *probe_rsp_info) 5242 { 5243 wmi_prb_tmpl_cmd_fixed_param *cmd; 5244 wmi_bcn_prb_info *bcn_prb_info; 5245 wmi_buf_t wmi_buf; 5246 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5247 uint8_t *buf_ptr; 5248 QDF_STATUS ret; 5249 5250 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5251 5252 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5253 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5254 5255 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5256 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5257 tmpl_len_aligned; 5258 5259 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5260 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5261 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5262 return QDF_STATUS_E_INVAL; 5263 } 5264 5265 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5266 if (!wmi_buf) { 5267 WMI_LOGE(FL("wmi_buf_alloc failed")); 5268 return QDF_STATUS_E_NOMEM; 5269 } 5270 5271 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5272 5273 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5274 WMITLV_SET_HDR(&cmd->tlv_header, 5275 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5276 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5277 cmd->vdev_id = vdev_id; 5278 cmd->buf_len = tmpl_len; 5279 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5280 5281 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5282 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5283 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5284 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5285 bcn_prb_info->caps = 0; 5286 bcn_prb_info->erp = 0; 5287 buf_ptr += sizeof(wmi_bcn_prb_info); 5288 5289 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5290 buf_ptr += WMI_TLV_HDR_SIZE; 5291 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5292 5293 ret = wmi_unified_cmd_send(wmi_handle, 5294 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5295 if (QDF_IS_STATUS_ERROR(ret)) { 5296 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5297 wmi_buf_free(wmi_buf); 5298 } 5299 5300 return ret; 5301 } 5302 5303 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5304 #define WPI_IV_LEN 16 5305 5306 /** 5307 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5308 * 5309 * @dest_tx: destination address of tsc key counter 5310 * @src_tx: source address of tsc key counter 5311 * @dest_rx: destination address of rsc key counter 5312 * @src_rx: source address of rsc key counter 5313 * 5314 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5315 * 5316 * Return: None 5317 * 5318 */ 5319 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5320 uint8_t *dest_rx, uint8_t *src_rx) 5321 { 5322 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5323 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5324 } 5325 #else 5326 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5327 uint8_t *dest_rx, uint8_t *src_rx) 5328 { 5329 return; 5330 } 5331 #endif 5332 5333 /** 5334 * send_setup_install_key_cmd_tlv() - set key parameters 5335 * @wmi_handle: wmi handle 5336 * @key_params: key parameters 5337 * 5338 * This function fills structure from information 5339 * passed in key_params. 5340 * 5341 * Return: QDF_STATUS_SUCCESS - success 5342 * QDF_STATUS_E_FAILURE - failure 5343 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5344 */ 5345 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5346 struct set_key_params *key_params) 5347 { 5348 wmi_vdev_install_key_cmd_fixed_param *cmd; 5349 wmi_buf_t buf; 5350 uint8_t *buf_ptr; 5351 uint32_t len; 5352 uint8_t *key_data; 5353 QDF_STATUS status; 5354 5355 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5356 WMI_TLV_HDR_SIZE; 5357 5358 buf = wmi_buf_alloc(wmi_handle, len); 5359 if (!buf) { 5360 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5361 return QDF_STATUS_E_NOMEM; 5362 } 5363 5364 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5365 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5366 WMITLV_SET_HDR(&cmd->tlv_header, 5367 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5368 WMITLV_GET_STRUCT_TLVLEN 5369 (wmi_vdev_install_key_cmd_fixed_param)); 5370 cmd->vdev_id = key_params->vdev_id; 5371 cmd->key_ix = key_params->key_idx; 5372 5373 5374 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5375 cmd->key_flags |= key_params->key_flags; 5376 cmd->key_cipher = key_params->key_cipher; 5377 if ((key_params->key_txmic_len) && 5378 (key_params->key_rxmic_len)) { 5379 cmd->key_txmic_len = key_params->key_txmic_len; 5380 cmd->key_rxmic_len = key_params->key_rxmic_len; 5381 } 5382 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5383 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5384 key_params->tx_iv, 5385 cmd->wpi_key_rsc_counter, 5386 key_params->rx_iv); 5387 #endif 5388 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5390 roundup(key_params->key_len, sizeof(uint32_t))); 5391 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5392 qdf_mem_copy((void *)key_data, 5393 (const void *)key_params->key_data, key_params->key_len); 5394 if (key_params->key_rsc_counter) 5395 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5396 sizeof(wmi_key_seq_counter)); 5397 cmd->key_len = key_params->key_len; 5398 5399 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5400 WMI_VDEV_INSTALL_KEY_CMDID); 5401 if (QDF_IS_STATUS_ERROR(status)) 5402 wmi_buf_free(buf); 5403 5404 return status; 5405 } 5406 5407 /** 5408 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5409 * @wmi_handle: wmi handle 5410 * @params: sar limit params 5411 * 5412 * Return: QDF_STATUS_SUCCESS for success or error code 5413 */ 5414 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5415 struct sar_limit_cmd_params *sar_limit_params) 5416 { 5417 wmi_buf_t buf; 5418 QDF_STATUS qdf_status; 5419 wmi_sar_limits_cmd_fixed_param *cmd; 5420 int i; 5421 uint8_t *buf_ptr; 5422 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5423 struct sar_limit_cmd_row *sar_rows_list; 5424 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5425 5426 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5427 buf = wmi_buf_alloc(wmi_handle, len); 5428 if (!buf) { 5429 WMI_LOGE("Failed to allocate memory"); 5430 qdf_status = QDF_STATUS_E_NOMEM; 5431 goto end; 5432 } 5433 5434 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5435 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5436 WMITLV_SET_HDR(&cmd->tlv_header, 5437 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5438 WMITLV_GET_STRUCT_TLVLEN 5439 (wmi_sar_limits_cmd_fixed_param)); 5440 cmd->sar_enable = sar_limit_params->sar_enable; 5441 cmd->commit_limits = sar_limit_params->commit_limits; 5442 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5443 5444 WMI_LOGD("no of sar rows = %d, len = %d", 5445 sar_limit_params->num_limit_rows, len); 5446 buf_ptr += sizeof(*cmd); 5447 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5448 sizeof(wmi_sar_limit_cmd_row) * 5449 sar_limit_params->num_limit_rows); 5450 if (cmd->num_limit_rows == 0) 5451 goto send_sar_limits; 5452 5453 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5454 (buf_ptr + WMI_TLV_HDR_SIZE); 5455 sar_rows_list = sar_limit_params->sar_limit_row_list; 5456 5457 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5458 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5459 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5460 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5461 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5462 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5463 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5464 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5465 wmi_sar_rows_list->validity_bitmap = 5466 sar_rows_list->validity_bitmap; 5467 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5468 i, wmi_sar_rows_list->band_id, 5469 wmi_sar_rows_list->chain_id, 5470 wmi_sar_rows_list->mod_id, 5471 wmi_sar_rows_list->limit_value, 5472 wmi_sar_rows_list->validity_bitmap); 5473 sar_rows_list++; 5474 wmi_sar_rows_list++; 5475 } 5476 send_sar_limits: 5477 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5478 WMI_SAR_LIMITS_CMDID); 5479 5480 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5481 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5482 wmi_buf_free(buf); 5483 } 5484 5485 end: 5486 return qdf_status; 5487 } 5488 5489 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5490 { 5491 wmi_sar_get_limits_cmd_fixed_param *cmd; 5492 wmi_buf_t wmi_buf; 5493 uint32_t len; 5494 QDF_STATUS status; 5495 5496 WMI_LOGD(FL("Enter")); 5497 5498 len = sizeof(*cmd); 5499 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5500 if (!wmi_buf) { 5501 WMI_LOGP(FL("failed to allocate memory for msg")); 5502 return QDF_STATUS_E_NOMEM; 5503 } 5504 5505 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5506 5507 WMITLV_SET_HDR(&cmd->tlv_header, 5508 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5509 WMITLV_GET_STRUCT_TLVLEN 5510 (wmi_sar_get_limits_cmd_fixed_param)); 5511 5512 cmd->reserved = 0; 5513 5514 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5515 WMI_SAR_GET_LIMITS_CMDID); 5516 if (QDF_IS_STATUS_ERROR(status)) { 5517 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5518 wmi_buf_free(wmi_buf); 5519 } 5520 5521 WMI_LOGD(FL("Exit")); 5522 5523 return status; 5524 } 5525 5526 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5527 uint8_t *evt_buf, 5528 struct sar_limit_event *event) 5529 { 5530 wmi_sar_get_limits_event_fixed_param *fixed_param; 5531 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5532 wmi_sar_get_limit_event_row *row_in; 5533 struct sar_limit_event_row *row_out; 5534 uint32_t row; 5535 5536 if (!evt_buf) { 5537 WMI_LOGE(FL("input event is NULL")); 5538 return QDF_STATUS_E_INVAL; 5539 } 5540 if (!event) { 5541 WMI_LOGE(FL("output event is NULL")); 5542 return QDF_STATUS_E_INVAL; 5543 } 5544 5545 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5546 5547 fixed_param = param_buf->fixed_param; 5548 if (!fixed_param) { 5549 WMI_LOGE(FL("Invalid fixed param")); 5550 return QDF_STATUS_E_INVAL; 5551 } 5552 5553 event->sar_enable = fixed_param->sar_enable; 5554 event->num_limit_rows = fixed_param->num_limit_rows; 5555 5556 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5557 QDF_ASSERT(0); 5558 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5559 event->num_limit_rows, 5560 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5561 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5562 } 5563 5564 row_in = param_buf->sar_get_limits; 5565 row_out = &event->sar_limit_row[0]; 5566 for (row = 0; row < event->num_limit_rows; row++) { 5567 row_out->band_id = row_in->band_id; 5568 row_out->chain_id = row_in->chain_id; 5569 row_out->mod_id = row_in->mod_id; 5570 row_out->limit_value = row_in->limit_value; 5571 row_out++; 5572 row_in++; 5573 } 5574 5575 return QDF_STATUS_SUCCESS; 5576 } 5577 5578 #ifdef WLAN_FEATURE_DISA 5579 /** 5580 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5581 * @wmi_handle: wmi handle 5582 * @params: encrypt/decrypt params 5583 * 5584 * Return: QDF_STATUS_SUCCESS for success or error code 5585 */ 5586 static 5587 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5588 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5589 { 5590 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5591 wmi_buf_t wmi_buf; 5592 uint8_t *buf_ptr; 5593 QDF_STATUS ret; 5594 uint32_t len; 5595 5596 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5597 5598 len = sizeof(*cmd) + 5599 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5600 WMI_TLV_HDR_SIZE; 5601 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5602 if (!wmi_buf) { 5603 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5604 __func__); 5605 return QDF_STATUS_E_NOMEM; 5606 } 5607 5608 buf_ptr = wmi_buf_data(wmi_buf); 5609 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5610 5611 WMITLV_SET_HDR(&cmd->tlv_header, 5612 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5613 WMITLV_GET_STRUCT_TLVLEN( 5614 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5615 5616 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5617 cmd->key_flag = encrypt_decrypt_params->key_flag; 5618 cmd->key_idx = encrypt_decrypt_params->key_idx; 5619 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5620 cmd->key_len = encrypt_decrypt_params->key_len; 5621 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5622 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5623 5624 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5625 encrypt_decrypt_params->key_len); 5626 5627 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5628 MAX_MAC_HEADER_LEN); 5629 5630 cmd->data_len = encrypt_decrypt_params->data_len; 5631 5632 if (cmd->data_len) { 5633 buf_ptr += sizeof(*cmd); 5634 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5635 roundup(encrypt_decrypt_params->data_len, 5636 sizeof(uint32_t))); 5637 buf_ptr += WMI_TLV_HDR_SIZE; 5638 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5639 encrypt_decrypt_params->data_len); 5640 } 5641 5642 /* This conversion is to facilitate data to FW in little endian */ 5643 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5644 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5645 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5646 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5647 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5648 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5649 5650 ret = wmi_unified_cmd_send(wmi_handle, 5651 wmi_buf, len, 5652 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5653 if (QDF_IS_STATUS_ERROR(ret)) { 5654 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5655 wmi_buf_free(wmi_buf); 5656 } 5657 5658 return ret; 5659 } 5660 5661 /** 5662 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5663 * params from event 5664 * @wmi_handle: wmi handle 5665 * @evt_buf: pointer to event buffer 5666 * @resp: Pointer to hold resp parameters 5667 * 5668 * Return: QDF_STATUS_SUCCESS for success or error code 5669 */ 5670 static 5671 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5672 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5673 { 5674 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5675 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5676 5677 param_buf = evt_buf; 5678 if (!param_buf) { 5679 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5680 return QDF_STATUS_E_INVAL; 5681 } 5682 5683 data_event = param_buf->fixed_param; 5684 5685 resp->vdev_id = data_event->vdev_id; 5686 resp->status = data_event->status; 5687 5688 if (data_event->data_length > param_buf->num_enc80211_frame) { 5689 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5690 data_event->data_length, 5691 param_buf->num_enc80211_frame); 5692 return QDF_STATUS_E_INVAL; 5693 } 5694 5695 resp->data_len = data_event->data_length; 5696 5697 if (resp->data_len) 5698 resp->data = (uint8_t *)param_buf->enc80211_frame; 5699 5700 return QDF_STATUS_SUCCESS; 5701 } 5702 #endif 5703 5704 /** 5705 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5706 * @wmi_handle: wmi handle 5707 * @vdev_id: vdev id 5708 * @p2p_ie: p2p IE 5709 * 5710 * Return: QDF_STATUS_SUCCESS for success or error code 5711 */ 5712 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5713 uint32_t vdev_id, uint8_t *p2p_ie) 5714 { 5715 QDF_STATUS ret; 5716 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5717 wmi_buf_t wmi_buf; 5718 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5719 uint8_t *buf_ptr; 5720 5721 ie_len = (uint32_t) (p2p_ie[1] + 2); 5722 5723 /* More than one P2P IE may be included in a single frame. 5724 If multiple P2P IEs are present, the complete P2P attribute 5725 data consists of the concatenation of the P2P Attribute 5726 fields of the P2P IEs. The P2P Attributes field of each 5727 P2P IE may be any length up to the maximum (251 octets). 5728 In this case host sends one P2P IE to firmware so the length 5729 should not exceed more than 251 bytes 5730 */ 5731 if (ie_len > 251) { 5732 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5733 return QDF_STATUS_E_INVAL; 5734 } 5735 5736 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5737 5738 wmi_buf_len = 5739 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5740 WMI_TLV_HDR_SIZE; 5741 5742 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5743 if (!wmi_buf) { 5744 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5745 return QDF_STATUS_E_NOMEM; 5746 } 5747 5748 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5749 5750 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5751 WMITLV_SET_HDR(&cmd->tlv_header, 5752 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5753 WMITLV_GET_STRUCT_TLVLEN 5754 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5755 cmd->vdev_id = vdev_id; 5756 cmd->ie_buf_len = ie_len; 5757 5758 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5759 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5760 buf_ptr += WMI_TLV_HDR_SIZE; 5761 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5762 5763 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 5764 5765 ret = wmi_unified_cmd_send(wmi_handle, 5766 wmi_buf, wmi_buf_len, 5767 WMI_P2P_GO_SET_BEACON_IE); 5768 if (QDF_IS_STATUS_ERROR(ret)) { 5769 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 5770 wmi_buf_free(wmi_buf); 5771 } 5772 5773 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 5774 return ret; 5775 } 5776 5777 /** 5778 * send_set_gateway_params_cmd_tlv() - set gateway parameters 5779 * @wmi_handle: wmi handle 5780 * @req: gateway parameter update request structure 5781 * 5782 * This function reads the incoming @req and fill in the destination 5783 * WMI structure and sends down the gateway configs down to the firmware 5784 * 5785 * Return: QDF_STATUS 5786 */ 5787 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 5788 struct gateway_update_req_param *req) 5789 { 5790 wmi_roam_subnet_change_config_fixed_param *cmd; 5791 wmi_buf_t buf; 5792 QDF_STATUS ret; 5793 int len = sizeof(*cmd); 5794 5795 buf = wmi_buf_alloc(wmi_handle, len); 5796 if (!buf) { 5797 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5798 return QDF_STATUS_E_NOMEM; 5799 } 5800 5801 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 5802 WMITLV_SET_HDR(&cmd->tlv_header, 5803 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 5804 WMITLV_GET_STRUCT_TLVLEN( 5805 wmi_roam_subnet_change_config_fixed_param)); 5806 5807 cmd->vdev_id = req->session_id; 5808 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 5809 QDF_IPV4_ADDR_SIZE); 5810 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 5811 QDF_IPV6_ADDR_SIZE); 5812 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 5813 &cmd->inet_gw_mac_addr); 5814 cmd->max_retries = req->max_retries; 5815 cmd->timeout = req->timeout; 5816 cmd->num_skip_subnet_change_detection_bssid_list = 0; 5817 cmd->flag = 0; 5818 if (req->ipv4_addr_type) 5819 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 5820 5821 if (req->ipv6_addr_type) 5822 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 5823 5824 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5825 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 5826 if (QDF_IS_STATUS_ERROR(ret)) { 5827 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 5828 ret); 5829 wmi_buf_free(buf); 5830 } 5831 5832 return ret; 5833 } 5834 5835 /** 5836 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 5837 * @wmi_handle: wmi handle 5838 * @req: rssi monitoring request structure 5839 * 5840 * This function reads the incoming @req and fill in the destination 5841 * WMI structure and send down the rssi monitoring configs down to the firmware 5842 * 5843 * Return: 0 on success; error number otherwise 5844 */ 5845 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 5846 struct rssi_monitor_param *req) 5847 { 5848 wmi_rssi_breach_monitor_config_fixed_param *cmd; 5849 wmi_buf_t buf; 5850 QDF_STATUS ret; 5851 uint32_t len = sizeof(*cmd); 5852 5853 buf = wmi_buf_alloc(wmi_handle, len); 5854 if (!buf) { 5855 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5856 return QDF_STATUS_E_NOMEM; 5857 } 5858 5859 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 5860 WMITLV_SET_HDR(&cmd->tlv_header, 5861 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 5862 WMITLV_GET_STRUCT_TLVLEN( 5863 wmi_rssi_breach_monitor_config_fixed_param)); 5864 5865 cmd->vdev_id = req->session_id; 5866 cmd->request_id = req->request_id; 5867 cmd->lo_rssi_reenable_hysteresis = 0; 5868 cmd->hi_rssi_reenable_histeresis = 0; 5869 cmd->min_report_interval = 0; 5870 cmd->max_num_report = 1; 5871 if (req->control) { 5872 /* enable one threshold for each min/max */ 5873 cmd->enabled_bitmap = 0x09; 5874 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 5875 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 5876 } else { 5877 cmd->enabled_bitmap = 0; 5878 cmd->low_rssi_breach_threshold[0] = 0; 5879 cmd->hi_rssi_breach_threshold[0] = 0; 5880 } 5881 5882 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5883 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 5884 if (QDF_IS_STATUS_ERROR(ret)) { 5885 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 5886 wmi_buf_free(buf); 5887 } 5888 5889 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 5890 5891 return ret; 5892 } 5893 5894 /** 5895 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5896 * @wmi_handle: wmi handle 5897 * @psetoui: OUI parameters 5898 * 5899 * set scan probe OUI parameters in firmware 5900 * 5901 * Return: CDF status 5902 */ 5903 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5904 struct scan_mac_oui *psetoui) 5905 { 5906 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5907 wmi_buf_t wmi_buf; 5908 uint32_t len; 5909 uint8_t *buf_ptr; 5910 uint32_t *oui_buf; 5911 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 5912 5913 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5914 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 5915 5916 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5917 if (!wmi_buf) { 5918 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5919 return QDF_STATUS_E_NOMEM; 5920 } 5921 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5922 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5923 WMITLV_SET_HDR(&cmd->tlv_header, 5924 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5925 WMITLV_GET_STRUCT_TLVLEN 5926 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5927 5928 oui_buf = &cmd->prob_req_oui; 5929 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5930 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5931 | psetoui->oui[2]; 5932 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 5933 cmd->prob_req_oui); 5934 5935 cmd->vdev_id = psetoui->vdev_id; 5936 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5937 if (psetoui->enb_probe_req_sno_randomization) 5938 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5939 5940 if (ie_whitelist->white_list) { 5941 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5942 &cmd->num_vendor_oui, 5943 ie_whitelist); 5944 cmd->flags |= 5945 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5946 } 5947 5948 buf_ptr += sizeof(*cmd); 5949 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5950 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5951 buf_ptr += WMI_TLV_HDR_SIZE; 5952 5953 if (cmd->num_vendor_oui != 0) { 5954 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5955 ie_whitelist->voui); 5956 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5957 } 5958 5959 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5960 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5961 WMI_LOGE("%s: failed to send command", __func__); 5962 wmi_buf_free(wmi_buf); 5963 return QDF_STATUS_E_FAILURE; 5964 } 5965 return QDF_STATUS_SUCCESS; 5966 } 5967 5968 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 5969 /** 5970 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 5971 * @wmi_handle: wmi handle 5972 * @roam_req: Roam scan offload params 5973 * @buf_ptr: command buffer to send 5974 * @fils_tlv_len: fils tlv length 5975 * 5976 * Return: Updated buffer pointer 5977 */ 5978 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 5979 struct roam_offload_scan_params *roam_req, 5980 uint8_t *buf_ptr, uint32_t fils_tlv_len) 5981 { 5982 wmi_roam_fils_offload_tlv_param *fils_tlv; 5983 wmi_erp_info *erp_info; 5984 struct roam_fils_params *roam_fils_params; 5985 5986 if (!roam_req->add_fils_tlv) 5987 return buf_ptr; 5988 5989 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5990 sizeof(*fils_tlv)); 5991 buf_ptr += WMI_TLV_HDR_SIZE; 5992 5993 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 5994 WMITLV_SET_HDR(&fils_tlv->tlv_header, 5995 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 5996 WMITLV_GET_STRUCT_TLVLEN 5997 (wmi_roam_fils_offload_tlv_param)); 5998 5999 roam_fils_params = &roam_req->roam_fils_params; 6000 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6001 6002 erp_info->username_length = roam_fils_params->username_length; 6003 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6004 erp_info->username_length); 6005 6006 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6007 6008 erp_info->rRk_length = roam_fils_params->rrk_length; 6009 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6010 erp_info->rRk_length); 6011 6012 erp_info->rIk_length = roam_fils_params->rik_length; 6013 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6014 erp_info->rIk_length); 6015 6016 erp_info->realm_len = roam_fils_params->realm_len; 6017 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6018 erp_info->realm_len); 6019 6020 buf_ptr += sizeof(*fils_tlv); 6021 return buf_ptr; 6022 } 6023 #else 6024 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6025 struct roam_offload_scan_params *roam_req, 6026 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6027 { 6028 return buf_ptr; 6029 } 6030 #endif 6031 /** 6032 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6033 * @wmi_handle: wmi handle 6034 * @scan_cmd_fp: start scan command ptr 6035 * @roam_req: roam request param 6036 * 6037 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6038 * of WMI_ROAM_SCAN_MODE. 6039 * 6040 * Return: QDF status 6041 */ 6042 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6043 wmi_start_scan_cmd_fixed_param * 6044 scan_cmd_fp, 6045 struct roam_offload_scan_params *roam_req) 6046 { 6047 wmi_buf_t buf = NULL; 6048 QDF_STATUS status; 6049 int len; 6050 uint8_t *buf_ptr; 6051 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6052 6053 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6054 int auth_mode = roam_req->auth_mode; 6055 wmi_roam_offload_tlv_param *roam_offload_params; 6056 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6057 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6058 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6059 wmi_tlv_buf_len_param *assoc_ies; 6060 uint32_t fils_tlv_len = 0; 6061 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6062 /* Need to create a buf with roam_scan command at 6063 * front and piggyback with scan command */ 6064 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6065 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6066 (2 * WMI_TLV_HDR_SIZE) + 6067 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6068 sizeof(wmi_start_scan_cmd_fixed_param); 6069 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6070 WMI_LOGD("auth_mode = %d", auth_mode); 6071 if (roam_req->is_roam_req_valid && 6072 roam_req->roam_offload_enabled) { 6073 len += sizeof(wmi_roam_offload_tlv_param); 6074 len += WMI_TLV_HDR_SIZE; 6075 if ((auth_mode != WMI_AUTH_NONE) && 6076 ((auth_mode != WMI_AUTH_OPEN) || 6077 (auth_mode == WMI_AUTH_OPEN && 6078 roam_req->mdid.mdie_present && 6079 roam_req->is_11r_assoc) || 6080 roam_req->is_ese_assoc)) { 6081 len += WMI_TLV_HDR_SIZE; 6082 if (roam_req->is_ese_assoc) 6083 len += 6084 sizeof(wmi_roam_ese_offload_tlv_param); 6085 else if (auth_mode == WMI_AUTH_FT_RSNA || 6086 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6087 (auth_mode == WMI_AUTH_OPEN && 6088 roam_req->mdid.mdie_present && 6089 roam_req->is_11r_assoc)) 6090 len += 6091 sizeof(wmi_roam_11r_offload_tlv_param); 6092 else 6093 len += 6094 sizeof(wmi_roam_11i_offload_tlv_param); 6095 } else { 6096 len += WMI_TLV_HDR_SIZE; 6097 } 6098 6099 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6100 + roundup(roam_req->assoc_ie_length, 6101 sizeof(uint32_t))); 6102 6103 if (roam_req->add_fils_tlv) { 6104 fils_tlv_len = sizeof( 6105 wmi_roam_fils_offload_tlv_param); 6106 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6107 } 6108 } else { 6109 if (roam_req->is_roam_req_valid) 6110 WMI_LOGD("%s : roam offload = %d", 6111 __func__, roam_req->roam_offload_enabled); 6112 else 6113 WMI_LOGD("%s : roam_req is NULL", __func__); 6114 len += (4 * WMI_TLV_HDR_SIZE); 6115 } 6116 if (roam_req->is_roam_req_valid && 6117 roam_req->roam_offload_enabled) { 6118 roam_req->mode = roam_req->mode | 6119 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6120 } 6121 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6122 6123 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6124 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6125 len = sizeof(wmi_roam_scan_mode_fixed_param); 6126 6127 buf = wmi_buf_alloc(wmi_handle, len); 6128 if (!buf) { 6129 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6130 return QDF_STATUS_E_NOMEM; 6131 } 6132 6133 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6134 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6135 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6136 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6137 WMITLV_GET_STRUCT_TLVLEN 6138 (wmi_roam_scan_mode_fixed_param)); 6139 6140 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6141 roam_req->roam_trigger_reason_bitmask; 6142 roam_scan_mode_fp->min_delay_btw_scans = 6143 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6144 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6145 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6146 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6147 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6148 roam_scan_mode_fp->flags |= 6149 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6150 goto send_roam_scan_mode_cmd; 6151 } 6152 6153 /* Fill in scan parameters suitable for roaming scan */ 6154 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6155 6156 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6157 sizeof(wmi_start_scan_cmd_fixed_param)); 6158 /* Ensure there is no additional IEs */ 6159 scan_cmd_fp->ie_len = 0; 6160 WMITLV_SET_HDR(buf_ptr, 6161 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6162 WMITLV_GET_STRUCT_TLVLEN 6163 (wmi_start_scan_cmd_fixed_param)); 6164 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6165 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6166 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6168 sizeof(wmi_roam_offload_tlv_param)); 6169 buf_ptr += WMI_TLV_HDR_SIZE; 6170 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6171 WMITLV_SET_HDR(buf_ptr, 6172 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6173 WMITLV_GET_STRUCT_TLVLEN 6174 (wmi_roam_offload_tlv_param)); 6175 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6176 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6177 roam_offload_params->select_5g_margin = 6178 roam_req->select_5ghz_margin; 6179 roam_offload_params->handoff_delay_for_rx = 6180 roam_req->roam_offload_params.ho_delay_for_rx; 6181 roam_offload_params->reassoc_failure_timeout = 6182 roam_req->reassoc_failure_timeout; 6183 6184 /* Fill the capabilities */ 6185 roam_offload_params->capability = 6186 roam_req->roam_offload_params.capability; 6187 roam_offload_params->ht_caps_info = 6188 roam_req->roam_offload_params.ht_caps_info; 6189 roam_offload_params->ampdu_param = 6190 roam_req->roam_offload_params.ampdu_param; 6191 roam_offload_params->ht_ext_cap = 6192 roam_req->roam_offload_params.ht_ext_cap; 6193 roam_offload_params->ht_txbf = 6194 roam_req->roam_offload_params.ht_txbf; 6195 roam_offload_params->asel_cap = 6196 roam_req->roam_offload_params.asel_cap; 6197 roam_offload_params->qos_caps = 6198 roam_req->roam_offload_params.qos_caps; 6199 roam_offload_params->qos_enabled = 6200 roam_req->roam_offload_params.qos_enabled; 6201 roam_offload_params->wmm_caps = 6202 roam_req->roam_offload_params.wmm_caps; 6203 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6204 (uint8_t *)roam_req->roam_offload_params.mcsset, 6205 ROAM_OFFLOAD_NUM_MCS_SET); 6206 6207 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6208 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6209 * they are filled in the same order.Depending on the 6210 * authentication type, the other mode TLV's are nullified 6211 * and only headers are filled.*/ 6212 if ((auth_mode != WMI_AUTH_NONE) && 6213 ((auth_mode != WMI_AUTH_OPEN) || 6214 (auth_mode == WMI_AUTH_OPEN 6215 && roam_req->mdid.mdie_present && 6216 roam_req->is_11r_assoc) || 6217 roam_req->is_ese_assoc)) { 6218 if (roam_req->is_ese_assoc) { 6219 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6220 WMITLV_GET_STRUCT_TLVLEN(0)); 6221 buf_ptr += WMI_TLV_HDR_SIZE; 6222 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6223 WMITLV_GET_STRUCT_TLVLEN(0)); 6224 buf_ptr += WMI_TLV_HDR_SIZE; 6225 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6226 sizeof(wmi_roam_ese_offload_tlv_param)); 6227 buf_ptr += WMI_TLV_HDR_SIZE; 6228 roam_offload_ese = 6229 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6230 qdf_mem_copy(roam_offload_ese->krk, 6231 roam_req->krk, 6232 sizeof(roam_req->krk)); 6233 qdf_mem_copy(roam_offload_ese->btk, 6234 roam_req->btk, 6235 sizeof(roam_req->btk)); 6236 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6237 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6238 WMITLV_GET_STRUCT_TLVLEN 6239 (wmi_roam_ese_offload_tlv_param)); 6240 buf_ptr += 6241 sizeof(wmi_roam_ese_offload_tlv_param); 6242 } else if (auth_mode == WMI_AUTH_FT_RSNA 6243 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6244 || (auth_mode == WMI_AUTH_OPEN 6245 && roam_req->mdid.mdie_present && 6246 roam_req->is_11r_assoc)) { 6247 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6248 0); 6249 buf_ptr += WMI_TLV_HDR_SIZE; 6250 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6251 sizeof(wmi_roam_11r_offload_tlv_param)); 6252 buf_ptr += WMI_TLV_HDR_SIZE; 6253 roam_offload_11r = 6254 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6255 roam_offload_11r->r0kh_id_len = 6256 roam_req->rokh_id_length; 6257 qdf_mem_copy(roam_offload_11r->r0kh_id, 6258 roam_req->rokh_id, 6259 roam_offload_11r->r0kh_id_len); 6260 qdf_mem_copy(roam_offload_11r->psk_msk, 6261 roam_req->psk_pmk, 6262 sizeof(roam_req->psk_pmk)); 6263 roam_offload_11r->psk_msk_len = 6264 roam_req->pmk_len; 6265 roam_offload_11r->mdie_present = 6266 roam_req->mdid.mdie_present; 6267 roam_offload_11r->mdid = 6268 roam_req->mdid.mobility_domain; 6269 if (auth_mode == WMI_AUTH_OPEN) { 6270 /* If FT-Open ensure pmk length 6271 and r0khid len are zero */ 6272 roam_offload_11r->r0kh_id_len = 0; 6273 roam_offload_11r->psk_msk_len = 0; 6274 } 6275 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6276 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6277 WMITLV_GET_STRUCT_TLVLEN 6278 (wmi_roam_11r_offload_tlv_param)); 6279 buf_ptr += 6280 sizeof(wmi_roam_11r_offload_tlv_param); 6281 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6282 WMITLV_GET_STRUCT_TLVLEN(0)); 6283 buf_ptr += WMI_TLV_HDR_SIZE; 6284 WMI_LOGD("psk_msk_len = %d", 6285 roam_offload_11r->psk_msk_len); 6286 if (roam_offload_11r->psk_msk_len) 6287 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6288 QDF_TRACE_LEVEL_DEBUG, 6289 roam_offload_11r->psk_msk, 6290 roam_offload_11r->psk_msk_len); 6291 } else { 6292 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6293 sizeof(wmi_roam_11i_offload_tlv_param)); 6294 buf_ptr += WMI_TLV_HDR_SIZE; 6295 roam_offload_11i = 6296 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6297 6298 if (roam_req->roam_key_mgmt_offload_enabled && 6299 roam_req->fw_okc) { 6300 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6301 (roam_offload_11i->flags); 6302 WMI_LOGI("LFR3:OKC enabled"); 6303 } else { 6304 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6305 (roam_offload_11i->flags); 6306 WMI_LOGI("LFR3:OKC disabled"); 6307 } 6308 if (roam_req->roam_key_mgmt_offload_enabled && 6309 roam_req->fw_pmksa_cache) { 6310 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6311 (roam_offload_11i->flags); 6312 WMI_LOGI("LFR3:PMKSA caching enabled"); 6313 } else { 6314 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6315 (roam_offload_11i->flags); 6316 WMI_LOGI("LFR3:PMKSA caching disabled"); 6317 } 6318 6319 qdf_mem_copy(roam_offload_11i->pmk, 6320 roam_req->psk_pmk, 6321 sizeof(roam_req->psk_pmk)); 6322 roam_offload_11i->pmk_len = roam_req->pmk_len; 6323 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6324 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6325 WMITLV_GET_STRUCT_TLVLEN 6326 (wmi_roam_11i_offload_tlv_param)); 6327 buf_ptr += 6328 sizeof(wmi_roam_11i_offload_tlv_param); 6329 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6330 0); 6331 buf_ptr += WMI_TLV_HDR_SIZE; 6332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6333 0); 6334 buf_ptr += WMI_TLV_HDR_SIZE; 6335 WMI_LOGD("pmk_len = %d", 6336 roam_offload_11i->pmk_len); 6337 if (roam_offload_11i->pmk_len) 6338 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6339 QDF_TRACE_LEVEL_DEBUG, 6340 roam_offload_11i->pmk, 6341 roam_offload_11i->pmk_len); 6342 } 6343 } else { 6344 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6345 WMITLV_GET_STRUCT_TLVLEN(0)); 6346 buf_ptr += WMI_TLV_HDR_SIZE; 6347 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6348 WMITLV_GET_STRUCT_TLVLEN(0)); 6349 buf_ptr += WMI_TLV_HDR_SIZE; 6350 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6351 WMITLV_GET_STRUCT_TLVLEN(0)); 6352 buf_ptr += WMI_TLV_HDR_SIZE; 6353 } 6354 6355 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6356 sizeof(*assoc_ies)); 6357 buf_ptr += WMI_TLV_HDR_SIZE; 6358 6359 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6360 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6361 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6362 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6363 assoc_ies->buf_len = roam_req->assoc_ie_length; 6364 6365 buf_ptr += sizeof(*assoc_ies); 6366 6367 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6368 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6369 buf_ptr += WMI_TLV_HDR_SIZE; 6370 6371 if (assoc_ies->buf_len != 0) { 6372 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6373 assoc_ies->buf_len); 6374 } 6375 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6376 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6377 buf_ptr, fils_tlv_len); 6378 } else { 6379 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6380 WMITLV_GET_STRUCT_TLVLEN(0)); 6381 buf_ptr += WMI_TLV_HDR_SIZE; 6382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6383 WMITLV_GET_STRUCT_TLVLEN(0)); 6384 buf_ptr += WMI_TLV_HDR_SIZE; 6385 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6386 WMITLV_GET_STRUCT_TLVLEN(0)); 6387 buf_ptr += WMI_TLV_HDR_SIZE; 6388 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6389 WMITLV_GET_STRUCT_TLVLEN(0)); 6390 buf_ptr += WMI_TLV_HDR_SIZE; 6391 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6392 WMITLV_GET_STRUCT_TLVLEN(0)); 6393 buf_ptr += WMI_TLV_HDR_SIZE; 6394 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6395 WMITLV_GET_STRUCT_TLVLEN(0)); 6396 } 6397 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6398 6399 send_roam_scan_mode_cmd: 6400 status = wmi_unified_cmd_send(wmi_handle, buf, 6401 len, WMI_ROAM_SCAN_MODE); 6402 if (QDF_IS_STATUS_ERROR(status)) { 6403 WMI_LOGE( 6404 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6405 status); 6406 wmi_buf_free(buf); 6407 } 6408 6409 return status; 6410 } 6411 6412 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6413 struct wmi_mawc_roam_params *params) 6414 { 6415 wmi_buf_t buf = NULL; 6416 QDF_STATUS status; 6417 int len; 6418 uint8_t *buf_ptr; 6419 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6420 6421 len = sizeof(*wmi_roam_mawc_params); 6422 buf = wmi_buf_alloc(wmi_handle, len); 6423 if (!buf) { 6424 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6425 return QDF_STATUS_E_NOMEM; 6426 } 6427 6428 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6429 wmi_roam_mawc_params = 6430 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6431 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6432 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6433 WMITLV_GET_STRUCT_TLVLEN 6434 (wmi_roam_configure_mawc_cmd_fixed_param)); 6435 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6436 if (params->enable) 6437 wmi_roam_mawc_params->enable = 1; 6438 else 6439 wmi_roam_mawc_params->enable = 0; 6440 wmi_roam_mawc_params->traffic_load_threshold = 6441 params->traffic_load_threshold; 6442 wmi_roam_mawc_params->best_ap_rssi_threshold = 6443 params->best_ap_rssi_threshold; 6444 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6445 params->rssi_stationary_high_adjust; 6446 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6447 params->rssi_stationary_low_adjust; 6448 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6449 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6450 wmi_roam_mawc_params->traffic_load_threshold, 6451 wmi_roam_mawc_params->best_ap_rssi_threshold, 6452 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6453 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6454 6455 status = wmi_unified_cmd_send(wmi_handle, buf, 6456 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6457 if (QDF_IS_STATUS_ERROR(status)) { 6458 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6459 status); 6460 wmi_buf_free(buf); 6461 return status; 6462 } 6463 6464 return QDF_STATUS_SUCCESS; 6465 } 6466 6467 /** 6468 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6469 * rssi threashold 6470 * @wmi_handle: wmi handle 6471 * @roam_req: Roaming request buffer 6472 * 6473 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6474 * 6475 * Return: QDF status 6476 */ 6477 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6478 struct roam_offload_scan_rssi_params *roam_req) 6479 { 6480 wmi_buf_t buf = NULL; 6481 QDF_STATUS status; 6482 int len; 6483 uint8_t *buf_ptr; 6484 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6485 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6486 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6487 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6488 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6489 6490 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6491 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6492 len += sizeof(wmi_roam_scan_extended_threshold_param); 6493 len += WMI_TLV_HDR_SIZE; 6494 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6495 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6496 len += sizeof(wmi_roam_dense_thres_param); 6497 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6498 len += sizeof(wmi_roam_bg_scan_roaming_param); 6499 buf = wmi_buf_alloc(wmi_handle, len); 6500 if (!buf) { 6501 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6502 return QDF_STATUS_E_NOMEM; 6503 } 6504 6505 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6506 rssi_threshold_fp = 6507 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6508 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6509 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6510 WMITLV_GET_STRUCT_TLVLEN 6511 (wmi_roam_scan_rssi_threshold_fixed_param)); 6512 /* fill in threshold values */ 6513 rssi_threshold_fp->vdev_id = roam_req->session_id; 6514 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6515 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6516 rssi_threshold_fp->hirssi_scan_max_count = 6517 roam_req->hi_rssi_scan_max_count; 6518 rssi_threshold_fp->hirssi_scan_delta = 6519 roam_req->hi_rssi_scan_rssi_delta; 6520 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6521 rssi_threshold_fp->rssi_thresh_offset_5g = 6522 roam_req->rssi_thresh_offset_5g; 6523 6524 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6525 WMITLV_SET_HDR(buf_ptr, 6526 WMITLV_TAG_ARRAY_STRUC, 6527 sizeof(wmi_roam_scan_extended_threshold_param)); 6528 buf_ptr += WMI_TLV_HDR_SIZE; 6529 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6530 6531 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6532 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6533 ext_thresholds->boost_threshold_5g = 6534 roam_req->boost_threshold_5g; 6535 6536 ext_thresholds->boost_algorithm_5g = 6537 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6538 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6539 ext_thresholds->penalty_algorithm_5g = 6540 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6541 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6542 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6543 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6544 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6545 6546 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6547 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6548 WMITLV_GET_STRUCT_TLVLEN 6549 (wmi_roam_scan_extended_threshold_param)); 6550 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6551 WMITLV_SET_HDR(buf_ptr, 6552 WMITLV_TAG_ARRAY_STRUC, 6553 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6554 buf_ptr += WMI_TLV_HDR_SIZE; 6555 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6556 early_stop_thresholds->roam_earlystop_thres_min = 6557 roam_req->roam_earlystop_thres_min; 6558 early_stop_thresholds->roam_earlystop_thres_max = 6559 roam_req->roam_earlystop_thres_max; 6560 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6561 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6562 WMITLV_GET_STRUCT_TLVLEN 6563 (wmi_roam_earlystop_rssi_thres_param)); 6564 6565 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6566 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6567 sizeof(wmi_roam_dense_thres_param)); 6568 buf_ptr += WMI_TLV_HDR_SIZE; 6569 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6570 dense_thresholds->roam_dense_rssi_thres_offset = 6571 roam_req->dense_rssi_thresh_offset; 6572 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6573 dense_thresholds->roam_dense_traffic_thres = 6574 roam_req->traffic_threshold; 6575 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6576 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6577 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6578 WMITLV_GET_STRUCT_TLVLEN 6579 (wmi_roam_dense_thres_param)); 6580 6581 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6582 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6583 sizeof(wmi_roam_bg_scan_roaming_param)); 6584 buf_ptr += WMI_TLV_HDR_SIZE; 6585 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6586 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6587 roam_req->bg_scan_bad_rssi_thresh; 6588 bg_scan_params->roam_bg_scan_client_bitmap = 6589 roam_req->bg_scan_client_bitmap; 6590 bg_scan_params->bad_rssi_thresh_offset_2g = 6591 roam_req->roam_bad_rssi_thresh_offset_2g; 6592 bg_scan_params->flags = roam_req->flags; 6593 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6594 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6595 WMITLV_GET_STRUCT_TLVLEN 6596 (wmi_roam_bg_scan_roaming_param)); 6597 6598 status = wmi_unified_cmd_send(wmi_handle, buf, 6599 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6600 if (QDF_IS_STATUS_ERROR(status)) { 6601 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6602 status); 6603 wmi_buf_free(buf); 6604 } 6605 6606 return status; 6607 } 6608 6609 /** 6610 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6611 * configuration params 6612 * @wma_handle: wma handler 6613 * @dwelltime_params: pointer to dwelltime_params 6614 * 6615 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6616 */ 6617 static 6618 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6619 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6620 { 6621 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6622 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6623 wmi_buf_t buf; 6624 uint8_t *buf_ptr; 6625 int32_t err; 6626 int len; 6627 6628 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6629 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6630 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6631 buf = wmi_buf_alloc(wmi_handle, len); 6632 if (!buf) { 6633 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6634 __func__); 6635 return QDF_STATUS_E_NOMEM; 6636 } 6637 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6638 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6639 WMITLV_SET_HDR(&dwell_param->tlv_header, 6640 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6641 WMITLV_GET_STRUCT_TLVLEN 6642 (wmi_scan_adaptive_dwell_config_fixed_param)); 6643 6644 dwell_param->enable = dwelltime_params->is_enabled; 6645 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6646 WMITLV_SET_HDR(buf_ptr, 6647 WMITLV_TAG_ARRAY_STRUC, 6648 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6649 buf_ptr += WMI_TLV_HDR_SIZE; 6650 6651 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6652 WMITLV_SET_HDR(&cmd->tlv_header, 6653 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6654 WMITLV_GET_STRUCT_TLVLEN( 6655 wmi_scan_adaptive_dwell_parameters_tlv)); 6656 6657 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6658 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6659 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6660 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6661 err = wmi_unified_cmd_send(wmi_handle, buf, 6662 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6663 if (err) { 6664 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6665 wmi_buf_free(buf); 6666 return QDF_STATUS_E_FAILURE; 6667 } 6668 6669 return QDF_STATUS_SUCCESS; 6670 } 6671 6672 /** 6673 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6674 * configuration params 6675 * @wmi_handle: wmi handler 6676 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6677 * 6678 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6679 */ 6680 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6681 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6682 { 6683 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6684 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6685 wmi_buf_t buf; 6686 uint8_t *buf_ptr; 6687 QDF_STATUS err; 6688 uint32_t i; 6689 int len; 6690 6691 len = sizeof(*dbs_scan_param); 6692 len += WMI_TLV_HDR_SIZE; 6693 len += dbs_scan_params->num_clients * sizeof(*cmd); 6694 6695 buf = wmi_buf_alloc(wmi_handle, len); 6696 if (!buf) { 6697 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6698 return QDF_STATUS_E_NOMEM; 6699 } 6700 6701 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6702 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6703 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6704 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6705 WMITLV_GET_STRUCT_TLVLEN 6706 (wmi_scan_dbs_duty_cycle_fixed_param)); 6707 6708 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6709 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6710 buf_ptr += sizeof(*dbs_scan_param); 6711 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6712 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6713 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6714 6715 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6716 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6717 WMITLV_SET_HDR(&cmd->tlv_header, 6718 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6719 WMITLV_GET_STRUCT_TLVLEN( 6720 wmi_scan_dbs_duty_cycle_tlv_param)); 6721 cmd->module_id = dbs_scan_params->module_id[i]; 6722 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6723 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6724 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6725 } 6726 6727 err = wmi_unified_cmd_send(wmi_handle, buf, 6728 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6729 if (QDF_IS_STATUS_ERROR(err)) { 6730 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6731 wmi_buf_free(buf); 6732 return QDF_STATUS_E_FAILURE; 6733 } 6734 6735 return QDF_STATUS_SUCCESS; 6736 } 6737 6738 /** 6739 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6740 * @wmi_handle: wmi handle 6741 * @roam_req: Request which contains the filters 6742 * 6743 * There are filters such as whitelist, blacklist and preferred 6744 * list that need to be applied to the scan results to form the 6745 * probable candidates for roaming. 6746 * 6747 * Return: Return success upon successfully passing the 6748 * parameters to the firmware, otherwise failure. 6749 */ 6750 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6751 struct roam_scan_filter_params *roam_req) 6752 { 6753 wmi_buf_t buf = NULL; 6754 QDF_STATUS status; 6755 uint32_t i; 6756 uint32_t len, blist_len = 0; 6757 uint8_t *buf_ptr; 6758 wmi_roam_filter_fixed_param *roam_filter; 6759 uint8_t *bssid_src_ptr = NULL; 6760 wmi_mac_addr *bssid_dst_ptr = NULL; 6761 wmi_ssid *ssid_ptr = NULL; 6762 uint32_t *bssid_preferred_factor_ptr = NULL; 6763 wmi_roam_lca_disallow_config_tlv_param *blist_param; 6764 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 6765 6766 len = sizeof(wmi_roam_filter_fixed_param); 6767 6768 len += WMI_TLV_HDR_SIZE; 6769 if (roam_req->num_bssid_black_list) 6770 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 6771 len += WMI_TLV_HDR_SIZE; 6772 if (roam_req->num_ssid_white_list) 6773 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 6774 len += 2 * WMI_TLV_HDR_SIZE; 6775 if (roam_req->num_bssid_preferred_list) { 6776 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 6777 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 6778 } 6779 len += WMI_TLV_HDR_SIZE; 6780 if (roam_req->lca_disallow_config_present) { 6781 len += sizeof(*blist_param); 6782 blist_len = sizeof(*blist_param); 6783 } 6784 6785 len += WMI_TLV_HDR_SIZE; 6786 if (roam_req->num_rssi_rejection_ap) 6787 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 6788 6789 buf = wmi_buf_alloc(wmi_handle, len); 6790 if (!buf) { 6791 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6792 return QDF_STATUS_E_NOMEM; 6793 } 6794 6795 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 6796 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 6797 WMITLV_SET_HDR(&roam_filter->tlv_header, 6798 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 6799 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 6800 /* fill in fixed values */ 6801 roam_filter->vdev_id = roam_req->session_id; 6802 roam_filter->flags = 0; 6803 roam_filter->op_bitmap = roam_req->op_bitmap; 6804 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 6805 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 6806 roam_filter->num_bssid_preferred_list = 6807 roam_req->num_bssid_preferred_list; 6808 roam_filter->num_rssi_rejection_ap = 6809 roam_req->num_rssi_rejection_ap; 6810 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 6811 6812 WMITLV_SET_HDR((buf_ptr), 6813 WMITLV_TAG_ARRAY_FIXED_STRUC, 6814 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 6815 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 6816 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6817 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 6818 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 6819 bssid_src_ptr += ATH_MAC_LEN; 6820 bssid_dst_ptr++; 6821 } 6822 buf_ptr += WMI_TLV_HDR_SIZE + 6823 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 6824 WMITLV_SET_HDR((buf_ptr), 6825 WMITLV_TAG_ARRAY_FIXED_STRUC, 6826 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 6827 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 6828 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 6829 qdf_mem_copy(&ssid_ptr->ssid, 6830 &roam_req->ssid_allowed_list[i].mac_ssid, 6831 roam_req->ssid_allowed_list[i].length); 6832 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 6833 ssid_ptr++; 6834 } 6835 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 6836 sizeof(wmi_ssid)); 6837 WMITLV_SET_HDR((buf_ptr), 6838 WMITLV_TAG_ARRAY_FIXED_STRUC, 6839 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 6840 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 6841 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6842 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6843 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 6844 (wmi_mac_addr *)bssid_dst_ptr); 6845 bssid_src_ptr += ATH_MAC_LEN; 6846 bssid_dst_ptr++; 6847 } 6848 buf_ptr += WMI_TLV_HDR_SIZE + 6849 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 6850 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6851 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 6852 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 6853 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6854 *bssid_preferred_factor_ptr = 6855 roam_req->bssid_favored_factor[i]; 6856 bssid_preferred_factor_ptr++; 6857 } 6858 buf_ptr += WMI_TLV_HDR_SIZE + 6859 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 6860 6861 WMITLV_SET_HDR(buf_ptr, 6862 WMITLV_TAG_ARRAY_STRUC, blist_len); 6863 buf_ptr += WMI_TLV_HDR_SIZE; 6864 if (roam_req->lca_disallow_config_present) { 6865 blist_param = 6866 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 6867 WMITLV_SET_HDR(&blist_param->tlv_header, 6868 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 6869 WMITLV_GET_STRUCT_TLVLEN( 6870 wmi_roam_lca_disallow_config_tlv_param)); 6871 6872 blist_param->disallow_duration = roam_req->disallow_duration; 6873 blist_param->rssi_channel_penalization = 6874 roam_req->rssi_channel_penalization; 6875 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 6876 blist_param->disallow_lca_enable_source_bitmap = 6877 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 6878 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 6879 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 6880 } 6881 6882 WMITLV_SET_HDR(buf_ptr, 6883 WMITLV_TAG_ARRAY_STRUC, 6884 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 6885 buf_ptr += WMI_TLV_HDR_SIZE; 6886 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 6887 rssi_rej = 6888 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 6889 WMITLV_SET_HDR(&rssi_rej->tlv_header, 6890 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 6891 WMITLV_GET_STRUCT_TLVLEN( 6892 wmi_roam_rssi_rejection_oce_config_param)); 6893 WMI_CHAR_ARRAY_TO_MAC_ADDR( 6894 roam_req->rssi_rejection_ap[i].bssid.bytes, 6895 &rssi_rej->bssid); 6896 rssi_rej->remaining_disallow_duration = 6897 roam_req->rssi_rejection_ap[i].remaining_duration; 6898 rssi_rej->requested_rssi = 6899 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 6900 buf_ptr += 6901 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 6902 } 6903 6904 status = wmi_unified_cmd_send(wmi_handle, buf, 6905 len, WMI_ROAM_FILTER_CMDID); 6906 if (QDF_IS_STATUS_ERROR(status)) { 6907 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 6908 status); 6909 wmi_buf_free(buf); 6910 } 6911 6912 return status; 6913 } 6914 6915 #if defined(WLAN_FEATURE_FILS_SK) 6916 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 6917 struct hlp_params *params) 6918 { 6919 uint32_t len; 6920 uint8_t *buf_ptr; 6921 wmi_buf_t buf = NULL; 6922 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 6923 6924 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 6925 len += WMI_TLV_HDR_SIZE; 6926 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 6927 6928 buf = wmi_buf_alloc(wmi_handle, len); 6929 if (!buf) { 6930 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6931 return QDF_STATUS_E_NOMEM; 6932 } 6933 6934 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6935 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 6936 WMITLV_SET_HDR(&hlp_params->tlv_header, 6937 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 6938 WMITLV_GET_STRUCT_TLVLEN( 6939 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 6940 6941 hlp_params->vdev_id = params->vdev_id; 6942 hlp_params->size = params->hlp_ie_len; 6943 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 6944 6945 buf_ptr += sizeof(*hlp_params); 6946 6947 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6948 round_up(params->hlp_ie_len, 6949 sizeof(uint32_t))); 6950 buf_ptr += WMI_TLV_HDR_SIZE; 6951 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 6952 6953 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 6954 hlp_params->vdev_id, hlp_params->size); 6955 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6956 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 6957 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 6958 wmi_buf_free(buf); 6959 return QDF_STATUS_E_FAILURE; 6960 } 6961 6962 return QDF_STATUS_SUCCESS; 6963 } 6964 #endif 6965 6966 #ifdef IPA_OFFLOAD 6967 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6968 * @wmi_handle: wmi handle 6969 * @ipa_offload: ipa offload control parameter 6970 * 6971 * Returns: 0 on success, error number otherwise 6972 */ 6973 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6974 struct ipa_uc_offload_control_params *ipa_offload) 6975 { 6976 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6977 wmi_buf_t wmi_buf; 6978 uint32_t len; 6979 u_int8_t *buf_ptr; 6980 6981 len = sizeof(*cmd); 6982 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6983 if (!wmi_buf) { 6984 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 6985 return QDF_STATUS_E_NOMEM; 6986 } 6987 6988 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 6989 ipa_offload->offload_type, ipa_offload->enable); 6990 6991 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6992 6993 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6994 WMITLV_SET_HDR(&cmd->tlv_header, 6995 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6996 WMITLV_GET_STRUCT_TLVLEN( 6997 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6998 6999 cmd->offload_type = ipa_offload->offload_type; 7000 cmd->vdev_id = ipa_offload->vdev_id; 7001 cmd->enable = ipa_offload->enable; 7002 7003 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7004 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7005 WMI_LOGE("%s: failed to command", __func__); 7006 wmi_buf_free(wmi_buf); 7007 return QDF_STATUS_E_FAILURE; 7008 } 7009 7010 return QDF_STATUS_SUCCESS; 7011 } 7012 #endif 7013 7014 /** 7015 * send_plm_stop_cmd_tlv() - plm stop request 7016 * @wmi_handle: wmi handle 7017 * @plm: plm request parameters 7018 * 7019 * This function request FW to stop PLM. 7020 * 7021 * Return: CDF status 7022 */ 7023 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7024 const struct plm_req_params *plm) 7025 { 7026 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7027 int32_t len; 7028 wmi_buf_t buf; 7029 uint8_t *buf_ptr; 7030 int ret; 7031 7032 len = sizeof(*cmd); 7033 buf = wmi_buf_alloc(wmi_handle, len); 7034 if (!buf) { 7035 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7036 return QDF_STATUS_E_NOMEM; 7037 } 7038 7039 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7040 7041 buf_ptr = (uint8_t *) cmd; 7042 7043 WMITLV_SET_HDR(&cmd->tlv_header, 7044 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7045 WMITLV_GET_STRUCT_TLVLEN 7046 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7047 7048 cmd->vdev_id = plm->session_id; 7049 7050 cmd->meas_token = plm->meas_token; 7051 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7052 7053 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7054 WMI_VDEV_PLMREQ_STOP_CMDID); 7055 if (ret) { 7056 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7057 wmi_buf_free(buf); 7058 return QDF_STATUS_E_FAILURE; 7059 } 7060 7061 return QDF_STATUS_SUCCESS; 7062 } 7063 7064 /** 7065 * send_plm_start_cmd_tlv() - plm start request 7066 * @wmi_handle: wmi handle 7067 * @plm: plm request parameters 7068 * 7069 * This function request FW to start PLM. 7070 * 7071 * Return: CDF status 7072 */ 7073 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7074 const struct plm_req_params *plm, 7075 uint32_t *gchannel_list) 7076 { 7077 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7078 uint32_t *channel_list; 7079 int32_t len; 7080 wmi_buf_t buf; 7081 uint8_t *buf_ptr; 7082 uint8_t count; 7083 int ret; 7084 7085 /* TLV place holder for channel_list */ 7086 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7087 len += sizeof(uint32_t) * plm->plm_num_ch; 7088 7089 buf = wmi_buf_alloc(wmi_handle, len); 7090 if (!buf) { 7091 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7092 return QDF_STATUS_E_NOMEM; 7093 } 7094 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 7095 7096 buf_ptr = (uint8_t *) cmd; 7097 7098 WMITLV_SET_HDR(&cmd->tlv_header, 7099 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 7100 WMITLV_GET_STRUCT_TLVLEN 7101 (wmi_vdev_plmreq_start_cmd_fixed_param)); 7102 7103 cmd->vdev_id = plm->session_id; 7104 7105 cmd->meas_token = plm->meas_token; 7106 cmd->dialog_token = plm->diag_token; 7107 cmd->number_bursts = plm->num_bursts; 7108 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 7109 cmd->off_duration = plm->meas_duration; 7110 cmd->burst_cycle = plm->burst_len; 7111 cmd->tx_power = plm->desired_tx_pwr; 7112 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 7113 cmd->num_chans = plm->plm_num_ch; 7114 7115 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 7116 7117 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 7118 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 7119 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 7120 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 7121 WMI_LOGD("off_duration: %d", cmd->off_duration); 7122 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 7123 WMI_LOGD("tx_power: %d", cmd->tx_power); 7124 WMI_LOGD("Number of channels : %d", cmd->num_chans); 7125 7126 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7127 (cmd->num_chans * sizeof(uint32_t))); 7128 7129 buf_ptr += WMI_TLV_HDR_SIZE; 7130 if (cmd->num_chans) { 7131 channel_list = (uint32_t *) buf_ptr; 7132 for (count = 0; count < cmd->num_chans; count++) { 7133 channel_list[count] = plm->plm_ch_list[count]; 7134 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 7135 channel_list[count] = 7136 gchannel_list[count]; 7137 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 7138 } 7139 buf_ptr += cmd->num_chans * sizeof(uint32_t); 7140 } 7141 7142 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7143 WMI_VDEV_PLMREQ_START_CMDID); 7144 if (ret) { 7145 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 7146 wmi_buf_free(buf); 7147 return QDF_STATUS_E_FAILURE; 7148 } 7149 7150 return QDF_STATUS_SUCCESS; 7151 } 7152 7153 /** 7154 * send_pno_stop_cmd_tlv() - PNO stop request 7155 * @wmi_handle: wmi handle 7156 * @vdev_id: vdev id 7157 * 7158 * This function request FW to stop ongoing PNO operation. 7159 * 7160 * Return: CDF status 7161 */ 7162 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7163 { 7164 wmi_nlo_config_cmd_fixed_param *cmd; 7165 int32_t len = sizeof(*cmd); 7166 wmi_buf_t buf; 7167 uint8_t *buf_ptr; 7168 int ret; 7169 7170 /* 7171 * TLV place holder for array of structures nlo_configured_parameters 7172 * TLV place holder for array of uint32_t channel_list 7173 * TLV place holder for chnl prediction cfg 7174 */ 7175 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7176 buf = wmi_buf_alloc(wmi_handle, len); 7177 if (!buf) { 7178 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7179 return QDF_STATUS_E_NOMEM; 7180 } 7181 7182 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7183 buf_ptr = (uint8_t *) cmd; 7184 7185 WMITLV_SET_HDR(&cmd->tlv_header, 7186 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7187 WMITLV_GET_STRUCT_TLVLEN 7188 (wmi_nlo_config_cmd_fixed_param)); 7189 7190 cmd->vdev_id = vdev_id; 7191 cmd->flags = WMI_NLO_CONFIG_STOP; 7192 buf_ptr += sizeof(*cmd); 7193 7194 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7195 buf_ptr += WMI_TLV_HDR_SIZE; 7196 7197 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7198 buf_ptr += WMI_TLV_HDR_SIZE; 7199 7200 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7201 buf_ptr += WMI_TLV_HDR_SIZE; 7202 7203 7204 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7205 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7206 if (ret) { 7207 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7208 wmi_buf_free(buf); 7209 return QDF_STATUS_E_FAILURE; 7210 } 7211 7212 return QDF_STATUS_SUCCESS; 7213 } 7214 7215 /** 7216 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 7217 * @buf_ptr: Buffer passed by upper layers 7218 * @pno: Buffer to be sent to the firmware 7219 * 7220 * Copy the PNO Channel prediction configuration parameters 7221 * passed by the upper layers to a WMI format TLV and send it 7222 * down to the firmware. 7223 * 7224 * Return: None 7225 */ 7226 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 7227 struct pno_scan_req_params *pno) 7228 { 7229 nlo_channel_prediction_cfg *channel_prediction_cfg = 7230 (nlo_channel_prediction_cfg *) buf_ptr; 7231 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 7232 WMITLV_TAG_ARRAY_BYTE, 7233 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 7234 #ifdef FEATURE_WLAN_SCAN_PNO 7235 channel_prediction_cfg->enable = pno->pno_channel_prediction; 7236 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 7237 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 7238 channel_prediction_cfg->full_scan_period_ms = 7239 pno->channel_prediction_full_scan; 7240 #endif 7241 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7242 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 7243 channel_prediction_cfg->enable, 7244 channel_prediction_cfg->top_k_num, 7245 channel_prediction_cfg->stationary_threshold, 7246 channel_prediction_cfg->full_scan_period_ms); 7247 } 7248 7249 /** 7250 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 7251 * @wmi_handle: wmi handle 7252 * @params: configuration parameters 7253 * 7254 * Return: QDF_STATUS 7255 */ 7256 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 7257 struct nlo_mawc_params *params) 7258 { 7259 wmi_buf_t buf = NULL; 7260 QDF_STATUS status; 7261 int len; 7262 uint8_t *buf_ptr; 7263 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 7264 7265 len = sizeof(*wmi_nlo_mawc_params); 7266 buf = wmi_buf_alloc(wmi_handle, len); 7267 if (!buf) { 7268 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7269 return QDF_STATUS_E_NOMEM; 7270 } 7271 7272 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7273 wmi_nlo_mawc_params = 7274 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 7275 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 7276 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 7277 WMITLV_GET_STRUCT_TLVLEN 7278 (wmi_nlo_configure_mawc_cmd_fixed_param)); 7279 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 7280 if (params->enable) 7281 wmi_nlo_mawc_params->enable = 1; 7282 else 7283 wmi_nlo_mawc_params->enable = 0; 7284 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 7285 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 7286 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 7287 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 7288 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 7289 wmi_nlo_mawc_params->exp_backoff_ratio, 7290 wmi_nlo_mawc_params->init_scan_interval, 7291 wmi_nlo_mawc_params->max_scan_interval); 7292 7293 status = wmi_unified_cmd_send(wmi_handle, buf, 7294 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 7295 if (QDF_IS_STATUS_ERROR(status)) { 7296 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 7297 status); 7298 wmi_buf_free(buf); 7299 return QDF_STATUS_E_FAILURE; 7300 } 7301 7302 return QDF_STATUS_SUCCESS; 7303 } 7304 7305 /** 7306 * send_pno_start_cmd_tlv() - PNO start request 7307 * @wmi_handle: wmi handle 7308 * @pno: PNO request 7309 * 7310 * This function request FW to start PNO request. 7311 * Request: CDF status 7312 */ 7313 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 7314 struct pno_scan_req_params *pno) 7315 { 7316 wmi_nlo_config_cmd_fixed_param *cmd; 7317 nlo_configured_parameters *nlo_list; 7318 uint32_t *channel_list; 7319 int32_t len; 7320 wmi_buf_t buf; 7321 uint8_t *buf_ptr; 7322 uint8_t i; 7323 int ret; 7324 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 7325 connected_nlo_rssi_params *nlo_relative_rssi; 7326 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 7327 7328 /* 7329 * TLV place holder for array nlo_configured_parameters(nlo_list) 7330 * TLV place holder for array of uint32_t channel_list 7331 * TLV place holder for chnnl prediction cfg 7332 * TLV place holder for array of wmi_vendor_oui 7333 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 7334 */ 7335 len = sizeof(*cmd) + 7336 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 7337 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7338 7339 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 7340 WMI_NLO_MAX_CHAN); 7341 len += sizeof(nlo_configured_parameters) * 7342 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7343 len += sizeof(nlo_channel_prediction_cfg); 7344 len += sizeof(enlo_candidate_score_params); 7345 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 7346 len += sizeof(connected_nlo_rssi_params); 7347 len += sizeof(connected_nlo_bss_band_rssi_pref); 7348 7349 buf = wmi_buf_alloc(wmi_handle, len); 7350 if (!buf) { 7351 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7352 return QDF_STATUS_E_NOMEM; 7353 } 7354 7355 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7356 7357 buf_ptr = (uint8_t *) cmd; 7358 WMITLV_SET_HDR(&cmd->tlv_header, 7359 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7360 WMITLV_GET_STRUCT_TLVLEN 7361 (wmi_nlo_config_cmd_fixed_param)); 7362 cmd->vdev_id = pno->vdev_id; 7363 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 7364 7365 #ifdef FEATURE_WLAN_SCAN_PNO 7366 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 7367 pno->adaptive_dwell_mode); 7368 #endif 7369 /* Current FW does not support min-max range for dwell time */ 7370 cmd->active_dwell_time = pno->active_dwell_time; 7371 cmd->passive_dwell_time = pno->passive_dwell_time; 7372 7373 if (pno->do_passive_scan) 7374 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 7375 /* Copy scan interval */ 7376 cmd->fast_scan_period = pno->fast_scan_period; 7377 cmd->slow_scan_period = pno->slow_scan_period; 7378 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 7379 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 7380 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 7381 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 7382 cmd->fast_scan_period, cmd->slow_scan_period); 7383 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 7384 7385 /* mac randomization attributes */ 7386 if (pno->scan_random.randomize) { 7387 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 7388 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 7389 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 7390 pno->scan_random.mac_mask, 7391 &cmd->mac_addr, 7392 &cmd->mac_mask); 7393 } 7394 7395 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7396 7397 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7398 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 7399 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7400 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7401 buf_ptr += WMI_TLV_HDR_SIZE; 7402 7403 nlo_list = (nlo_configured_parameters *) buf_ptr; 7404 for (i = 0; i < cmd->no_of_ssids; i++) { 7405 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7406 WMITLV_TAG_ARRAY_BYTE, 7407 WMITLV_GET_STRUCT_TLVLEN 7408 (nlo_configured_parameters)); 7409 /* Copy ssid and it's length */ 7410 nlo_list[i].ssid.valid = true; 7411 nlo_list[i].ssid.ssid.ssid_len = 7412 pno->networks_list[i].ssid.length; 7413 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7414 pno->networks_list[i].ssid.ssid, 7415 nlo_list[i].ssid.ssid.ssid_len); 7416 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7417 nlo_list[i].ssid.ssid.ssid_len, 7418 (char *)nlo_list[i].ssid.ssid.ssid, 7419 nlo_list[i].ssid.ssid.ssid_len); 7420 7421 /* Copy rssi threshold */ 7422 if (pno->networks_list[i].rssi_thresh && 7423 pno->networks_list[i].rssi_thresh > 7424 WMI_RSSI_THOLD_DEFAULT) { 7425 nlo_list[i].rssi_cond.valid = true; 7426 nlo_list[i].rssi_cond.rssi = 7427 pno->networks_list[i].rssi_thresh; 7428 WMI_LOGD("RSSI threshold : %d dBm", 7429 nlo_list[i].rssi_cond.rssi); 7430 } 7431 nlo_list[i].bcast_nw_type.valid = true; 7432 nlo_list[i].bcast_nw_type.bcast_nw_type = 7433 pno->networks_list[i].bc_new_type; 7434 WMI_LOGD("Broadcast NW type (%u)", 7435 nlo_list[i].bcast_nw_type.bcast_nw_type); 7436 } 7437 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7438 7439 /* Copy channel info */ 7440 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 7441 WMI_NLO_MAX_CHAN); 7442 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 7443 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7444 (cmd->num_of_channels * sizeof(uint32_t))); 7445 buf_ptr += WMI_TLV_HDR_SIZE; 7446 7447 channel_list = (uint32_t *) buf_ptr; 7448 for (i = 0; i < cmd->num_of_channels; i++) { 7449 channel_list[i] = pno->networks_list[0].channels[i]; 7450 7451 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 7452 channel_list[i] = 7453 wlan_chan_to_freq(pno-> 7454 networks_list[0].channels[i]); 7455 7456 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 7457 } 7458 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 7459 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7460 sizeof(nlo_channel_prediction_cfg)); 7461 buf_ptr += WMI_TLV_HDR_SIZE; 7462 wmi_set_pno_channel_prediction(buf_ptr, pno); 7463 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7464 /** TODO: Discrete firmware doesn't have command/option to configure 7465 * App IE which comes from wpa_supplicant as of part PNO start request. 7466 */ 7467 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 7468 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7469 buf_ptr += sizeof(enlo_candidate_score_params); 7470 7471 if (ie_whitelist->white_list) { 7472 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 7473 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 7474 &cmd->num_vendor_oui, 7475 ie_whitelist); 7476 } 7477 7478 /* ie white list */ 7479 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7480 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 7481 buf_ptr += WMI_TLV_HDR_SIZE; 7482 if (cmd->num_vendor_oui != 0) { 7483 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 7484 ie_whitelist->voui); 7485 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 7486 } 7487 7488 if (pno->relative_rssi_set) 7489 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 7490 7491 /* 7492 * Firmware calculation using connected PNO params: 7493 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 7494 * deduction of rssi_pref for chosen band_pref and 7495 * addition of rssi_pref for remaining bands (other than chosen band). 7496 */ 7497 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 7498 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 7499 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 7500 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 7501 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 7502 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 7503 buf_ptr += sizeof(*nlo_relative_rssi); 7504 7505 /* 7506 * As of now Kernel and Host supports one band and rssi preference. 7507 * Firmware supports array of band and rssi preferences 7508 */ 7509 cmd->num_cnlo_band_pref = 1; 7510 WMITLV_SET_HDR(buf_ptr, 7511 WMITLV_TAG_ARRAY_STRUC, 7512 cmd->num_cnlo_band_pref * 7513 sizeof(connected_nlo_bss_band_rssi_pref)); 7514 buf_ptr += WMI_TLV_HDR_SIZE; 7515 7516 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 7517 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 7518 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 7519 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 7520 WMITLV_GET_STRUCT_TLVLEN( 7521 connected_nlo_bss_band_rssi_pref)); 7522 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 7523 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 7524 WMI_LOGI("band_pref %d, rssi_pref %d", 7525 nlo_band_rssi[i].band, 7526 nlo_band_rssi[i].rssi_pref); 7527 } 7528 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 7529 7530 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7531 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7532 if (ret) { 7533 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7534 wmi_buf_free(buf); 7535 return QDF_STATUS_E_FAILURE; 7536 } 7537 7538 return QDF_STATUS_SUCCESS; 7539 } 7540 7541 /* send_set_ric_req_cmd_tlv() - set ric request element 7542 * @wmi_handle: wmi handle 7543 * @msg: message 7544 * @is_add_ts: is addts required 7545 * 7546 * This function sets ric request element for 11r roaming. 7547 * 7548 * Return: CDF status 7549 */ 7550 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 7551 void *msg, uint8_t is_add_ts) 7552 { 7553 wmi_ric_request_fixed_param *cmd; 7554 wmi_ric_tspec *tspec_param; 7555 wmi_buf_t buf; 7556 uint8_t *buf_ptr; 7557 struct mac_tspec_ie *ptspecIE = NULL; 7558 int32_t len = sizeof(wmi_ric_request_fixed_param) + 7559 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 7560 7561 buf = wmi_buf_alloc(wmi_handle, len); 7562 if (!buf) { 7563 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 7564 return QDF_STATUS_E_NOMEM; 7565 } 7566 7567 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7568 7569 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 7570 WMITLV_SET_HDR(&cmd->tlv_header, 7571 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 7572 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 7573 if (is_add_ts) 7574 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 7575 else 7576 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 7577 cmd->num_ric_request = 1; 7578 cmd->is_add_ric = is_add_ts; 7579 7580 buf_ptr += sizeof(wmi_ric_request_fixed_param); 7581 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 7582 7583 buf_ptr += WMI_TLV_HDR_SIZE; 7584 tspec_param = (wmi_ric_tspec *) buf_ptr; 7585 WMITLV_SET_HDR(&tspec_param->tlv_header, 7586 WMITLV_TAG_STRUC_wmi_ric_tspec, 7587 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 7588 7589 if (is_add_ts) 7590 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 7591 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7592 else 7593 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 7594 #endif 7595 if (ptspecIE) { 7596 /* Fill the tsinfo in the format expected by firmware */ 7597 #ifndef ANI_LITTLE_BIT_ENDIAN 7598 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 7599 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7600 #else 7601 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 7602 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7603 #endif /* ANI_LITTLE_BIT_ENDIAN */ 7604 7605 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 7606 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 7607 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 7608 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 7609 tspec_param->inactivity_interval = ptspecIE->inactInterval; 7610 tspec_param->suspension_interval = ptspecIE->suspendInterval; 7611 tspec_param->svc_start_time = ptspecIE->svcStartTime; 7612 tspec_param->min_data_rate = ptspecIE->minDataRate; 7613 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 7614 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 7615 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 7616 tspec_param->delay_bound = ptspecIE->delayBound; 7617 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 7618 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 7619 tspec_param->medium_time = 0; 7620 } 7621 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 7622 7623 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7624 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 7625 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 7626 __func__); 7627 if (is_add_ts) 7628 ((struct add_ts_param *) msg)->status = 7629 QDF_STATUS_E_FAILURE; 7630 wmi_buf_free(buf); 7631 return QDF_STATUS_E_FAILURE; 7632 } 7633 7634 return QDF_STATUS_SUCCESS; 7635 } 7636 7637 /** 7638 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 7639 * @wmi_handle: wmi handle 7640 * @clear_req: ll stats clear request command params 7641 * 7642 * Return: QDF_STATUS_SUCCESS for success or error code 7643 */ 7644 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 7645 const struct ll_stats_clear_params *clear_req, 7646 uint8_t addr[IEEE80211_ADDR_LEN]) 7647 { 7648 wmi_clear_link_stats_cmd_fixed_param *cmd; 7649 int32_t len; 7650 wmi_buf_t buf; 7651 uint8_t *buf_ptr; 7652 int ret; 7653 7654 len = sizeof(*cmd); 7655 buf = wmi_buf_alloc(wmi_handle, len); 7656 7657 if (!buf) { 7658 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7659 return QDF_STATUS_E_NOMEM; 7660 } 7661 7662 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7663 qdf_mem_zero(buf_ptr, len); 7664 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 7665 7666 WMITLV_SET_HDR(&cmd->tlv_header, 7667 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 7668 WMITLV_GET_STRUCT_TLVLEN 7669 (wmi_clear_link_stats_cmd_fixed_param)); 7670 7671 cmd->stop_stats_collection_req = clear_req->stop_req; 7672 cmd->vdev_id = clear_req->sta_id; 7673 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 7674 7675 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 7676 &cmd->peer_macaddr); 7677 7678 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 7679 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 7680 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 7681 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 7682 /* WMI_LOGD("Peer MAC Addr : %pM", 7683 cmd->peer_macaddr); */ 7684 7685 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7686 WMI_CLEAR_LINK_STATS_CMDID); 7687 if (ret) { 7688 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 7689 wmi_buf_free(buf); 7690 return QDF_STATUS_E_FAILURE; 7691 } 7692 7693 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 7694 return QDF_STATUS_SUCCESS; 7695 } 7696 7697 /** 7698 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 7699 * @wmi_handle: wmi handle 7700 * @setReq: ll stats set request command params 7701 * 7702 * Return: QDF_STATUS_SUCCESS for success or error code 7703 */ 7704 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7705 const struct ll_stats_set_params *set_req) 7706 { 7707 wmi_start_link_stats_cmd_fixed_param *cmd; 7708 int32_t len; 7709 wmi_buf_t buf; 7710 uint8_t *buf_ptr; 7711 int ret; 7712 7713 len = sizeof(*cmd); 7714 buf = wmi_buf_alloc(wmi_handle, len); 7715 7716 if (!buf) { 7717 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7718 return QDF_STATUS_E_NOMEM; 7719 } 7720 7721 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7722 qdf_mem_zero(buf_ptr, len); 7723 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7724 7725 WMITLV_SET_HDR(&cmd->tlv_header, 7726 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7727 WMITLV_GET_STRUCT_TLVLEN 7728 (wmi_start_link_stats_cmd_fixed_param)); 7729 7730 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7731 cmd->aggressive_statistics_gathering = 7732 set_req->aggressive_statistics_gathering; 7733 7734 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 7735 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 7736 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 7737 7738 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7739 WMI_START_LINK_STATS_CMDID); 7740 if (ret) { 7741 WMI_LOGE("%s: Failed to send set link stats request", __func__); 7742 wmi_buf_free(buf); 7743 return QDF_STATUS_E_FAILURE; 7744 } 7745 7746 return QDF_STATUS_SUCCESS; 7747 } 7748 7749 /** 7750 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7751 * @wmi_handle:wmi handle 7752 * @get_req:ll stats get request command params 7753 * @addr: mac address 7754 * 7755 * Return: QDF_STATUS_SUCCESS for success or error code 7756 */ 7757 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7758 const struct ll_stats_get_params *get_req, 7759 uint8_t addr[IEEE80211_ADDR_LEN]) 7760 { 7761 wmi_request_link_stats_cmd_fixed_param *cmd; 7762 int32_t len; 7763 wmi_buf_t buf; 7764 uint8_t *buf_ptr; 7765 int ret; 7766 7767 len = sizeof(*cmd); 7768 buf = wmi_buf_alloc(wmi_handle, len); 7769 7770 if (!buf) { 7771 WMI_LOGE("%s: buf allocation failed", __func__); 7772 return QDF_STATUS_E_NOMEM; 7773 } 7774 7775 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7776 qdf_mem_zero(buf_ptr, len); 7777 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 7778 7779 WMITLV_SET_HDR(&cmd->tlv_header, 7780 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 7781 WMITLV_GET_STRUCT_TLVLEN 7782 (wmi_request_link_stats_cmd_fixed_param)); 7783 7784 cmd->request_id = get_req->req_id; 7785 cmd->stats_type = get_req->param_id_mask; 7786 cmd->vdev_id = get_req->sta_id; 7787 7788 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 7789 &cmd->peer_macaddr); 7790 7791 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 7792 WMI_LOGD("Request ID : %u", cmd->request_id); 7793 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 7794 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 7795 WMI_LOGD("Peer MAC Addr : %pM", addr); 7796 7797 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7798 WMI_REQUEST_LINK_STATS_CMDID); 7799 if (ret) { 7800 WMI_LOGE("%s: Failed to send get link stats request", __func__); 7801 wmi_buf_free(buf); 7802 return QDF_STATUS_E_FAILURE; 7803 } 7804 7805 return QDF_STATUS_SUCCESS; 7806 } 7807 7808 7809 /** 7810 * send_congestion_cmd_tlv() - send request to fw to get CCA 7811 * @wmi_handle: wmi handle 7812 * @vdev_id: vdev id 7813 * 7814 * Return: CDF status 7815 */ 7816 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7817 uint8_t vdev_id) 7818 { 7819 wmi_buf_t buf; 7820 wmi_request_stats_cmd_fixed_param *cmd; 7821 uint8_t len; 7822 uint8_t *buf_ptr; 7823 7824 len = sizeof(*cmd); 7825 buf = wmi_buf_alloc(wmi_handle, len); 7826 if (!buf) { 7827 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 7828 return QDF_STATUS_E_FAILURE; 7829 } 7830 7831 buf_ptr = wmi_buf_data(buf); 7832 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7833 WMITLV_SET_HDR(&cmd->tlv_header, 7834 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7835 WMITLV_GET_STRUCT_TLVLEN 7836 (wmi_request_stats_cmd_fixed_param)); 7837 7838 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7839 cmd->vdev_id = vdev_id; 7840 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 7841 cmd->vdev_id, cmd->stats_id); 7842 7843 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7844 WMI_REQUEST_STATS_CMDID)) { 7845 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 7846 __func__); 7847 wmi_buf_free(buf); 7848 return QDF_STATUS_E_FAILURE; 7849 } 7850 7851 return QDF_STATUS_SUCCESS; 7852 } 7853 7854 /** 7855 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7856 * @wmi_handle: wmi handle 7857 * @rssi_req: get RSSI request 7858 * 7859 * Return: CDF status 7860 */ 7861 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7862 { 7863 wmi_buf_t buf; 7864 wmi_request_stats_cmd_fixed_param *cmd; 7865 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7866 7867 buf = wmi_buf_alloc(wmi_handle, len); 7868 if (!buf) { 7869 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7870 return QDF_STATUS_E_FAILURE; 7871 } 7872 7873 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7874 WMITLV_SET_HDR(&cmd->tlv_header, 7875 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7876 WMITLV_GET_STRUCT_TLVLEN 7877 (wmi_request_stats_cmd_fixed_param)); 7878 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7879 if (wmi_unified_cmd_send 7880 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 7881 WMI_LOGE("Failed to send host stats request to fw"); 7882 wmi_buf_free(buf); 7883 return QDF_STATUS_E_FAILURE; 7884 } 7885 7886 return QDF_STATUS_SUCCESS; 7887 } 7888 7889 /** 7890 * send_snr_cmd_tlv() - get RSSI from fw 7891 * @wmi_handle: wmi handle 7892 * @vdev_id: vdev id 7893 * 7894 * Return: CDF status 7895 */ 7896 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7897 { 7898 wmi_buf_t buf; 7899 wmi_request_stats_cmd_fixed_param *cmd; 7900 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7901 7902 buf = wmi_buf_alloc(wmi_handle, len); 7903 if (!buf) { 7904 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7905 return QDF_STATUS_E_FAILURE; 7906 } 7907 7908 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7909 cmd->vdev_id = vdev_id; 7910 7911 WMITLV_SET_HDR(&cmd->tlv_header, 7912 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7913 WMITLV_GET_STRUCT_TLVLEN 7914 (wmi_request_stats_cmd_fixed_param)); 7915 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7916 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7917 WMI_REQUEST_STATS_CMDID)) { 7918 WMI_LOGE("Failed to send host stats request to fw"); 7919 wmi_buf_free(buf); 7920 return QDF_STATUS_E_FAILURE; 7921 } 7922 7923 return QDF_STATUS_SUCCESS; 7924 } 7925 7926 /** 7927 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7928 * @wmi_handle: wmi handle 7929 * @link_status: get link params 7930 * 7931 * Return: CDF status 7932 */ 7933 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7934 struct link_status_params *link_status) 7935 { 7936 wmi_buf_t buf; 7937 wmi_request_stats_cmd_fixed_param *cmd; 7938 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7939 7940 buf = wmi_buf_alloc(wmi_handle, len); 7941 if (!buf) { 7942 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7943 return QDF_STATUS_E_FAILURE; 7944 } 7945 7946 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7947 WMITLV_SET_HDR(&cmd->tlv_header, 7948 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7949 WMITLV_GET_STRUCT_TLVLEN 7950 (wmi_request_stats_cmd_fixed_param)); 7951 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7952 cmd->vdev_id = link_status->session_id; 7953 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7954 WMI_REQUEST_STATS_CMDID)) { 7955 WMI_LOGE("Failed to send WMI link status request to fw"); 7956 wmi_buf_free(buf); 7957 return QDF_STATUS_E_FAILURE; 7958 } 7959 7960 return QDF_STATUS_SUCCESS; 7961 } 7962 7963 /** 7964 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 7965 * @wmi_handle: wmi handle 7966 * @ta_dhcp_ind: DHCP indication parameter 7967 * 7968 * Return: CDF Status 7969 */ 7970 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 7971 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 7972 { 7973 QDF_STATUS status; 7974 wmi_buf_t buf = NULL; 7975 uint8_t *buf_ptr; 7976 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 7977 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 7978 7979 7980 buf = wmi_buf_alloc(wmi_handle, len); 7981 if (!buf) { 7982 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7983 return QDF_STATUS_E_NOMEM; 7984 } 7985 7986 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7987 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 7988 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 7989 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 7990 WMITLV_GET_STRUCT_TLVLEN 7991 (wmi_peer_set_param_cmd_fixed_param)); 7992 7993 /* fill in values */ 7994 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 7995 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 7996 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 7997 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 7998 &ta_dhcp_ind->peer_macaddr, 7999 sizeof(ta_dhcp_ind->peer_macaddr)); 8000 8001 status = wmi_unified_cmd_send(wmi_handle, buf, 8002 len, WMI_PEER_SET_PARAM_CMDID); 8003 if (QDF_IS_STATUS_ERROR(status)) { 8004 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8005 " returned Error %d", __func__, status); 8006 wmi_buf_free(buf); 8007 } 8008 8009 return status; 8010 } 8011 8012 /** 8013 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8014 * @wmi_handle: wmi handle 8015 * @pLinkSpeed: link speed info 8016 * 8017 * Return: CDF status 8018 */ 8019 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8020 wmi_mac_addr peer_macaddr) 8021 { 8022 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8023 wmi_buf_t wmi_buf; 8024 uint32_t len; 8025 uint8_t *buf_ptr; 8026 8027 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8028 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8029 if (!wmi_buf) { 8030 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8031 return QDF_STATUS_E_NOMEM; 8032 } 8033 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8034 8035 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8036 WMITLV_SET_HDR(&cmd->tlv_header, 8037 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8038 WMITLV_GET_STRUCT_TLVLEN 8039 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8040 8041 /* Copy the peer macaddress to the wma buffer */ 8042 qdf_mem_copy(&cmd->peer_macaddr, 8043 &peer_macaddr, 8044 sizeof(peer_macaddr)); 8045 8046 8047 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8048 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8049 WMI_LOGE("%s: failed to send link speed command", __func__); 8050 wmi_buf_free(wmi_buf); 8051 return QDF_STATUS_E_FAILURE; 8052 } 8053 return QDF_STATUS_SUCCESS; 8054 } 8055 8056 #ifdef WLAN_SUPPORT_GREEN_AP 8057 /** 8058 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8059 * @wmi_handle: wmi handler 8060 * @egap_params: pointer to egap_params 8061 * 8062 * Return: 0 for success, otherwise appropriate error code 8063 */ 8064 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8065 struct wlan_green_ap_egap_params *egap_params) 8066 { 8067 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8068 wmi_buf_t buf; 8069 int32_t err; 8070 8071 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8072 if (!buf) { 8073 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8074 return QDF_STATUS_E_NOMEM; 8075 } 8076 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8077 WMITLV_SET_HDR(&cmd->tlv_header, 8078 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8079 WMITLV_GET_STRUCT_TLVLEN( 8080 wmi_ap_ps_egap_param_cmd_fixed_param)); 8081 8082 cmd->enable = egap_params->host_enable_egap; 8083 cmd->inactivity_time = egap_params->egap_inactivity_time; 8084 cmd->wait_time = egap_params->egap_wait_time; 8085 cmd->flags = egap_params->egap_feature_flags; 8086 err = wmi_unified_cmd_send(wmi_handle, buf, 8087 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 8088 if (err) { 8089 WMI_LOGE("Failed to send ap_ps_egap cmd"); 8090 wmi_buf_free(buf); 8091 return QDF_STATUS_E_FAILURE; 8092 } 8093 8094 return QDF_STATUS_SUCCESS; 8095 } 8096 #endif 8097 8098 /** 8099 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 8100 * @wmi_handl: wmi handle 8101 * @cmd: Profiling command index 8102 * @value1: parameter1 value 8103 * @value2: parameter2 value 8104 * 8105 * Return: QDF_STATUS_SUCCESS for success else error code 8106 */ 8107 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 8108 uint32_t cmd, uint32_t value1, uint32_t value2) 8109 { 8110 wmi_buf_t buf; 8111 int32_t len = 0; 8112 int ret; 8113 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8114 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8115 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8116 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 8117 8118 switch (cmd) { 8119 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 8120 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8121 buf = wmi_buf_alloc(wmi_handle, len); 8122 if (!buf) { 8123 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8124 return QDF_STATUS_E_NOMEM; 8125 } 8126 prof_trig_cmd = 8127 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8128 wmi_buf_data(buf); 8129 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8130 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8131 WMITLV_GET_STRUCT_TLVLEN 8132 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8133 prof_trig_cmd->enable = value1; 8134 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8135 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8136 if (ret) { 8137 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 8138 value1); 8139 wmi_buf_free(buf); 8140 return ret; 8141 } 8142 break; 8143 8144 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 8145 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 8146 buf = wmi_buf_alloc(wmi_handle, len); 8147 if (!buf) { 8148 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8149 return QDF_STATUS_E_NOMEM; 8150 } 8151 profile_getdata_cmd = 8152 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 8153 wmi_buf_data(buf); 8154 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 8155 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 8156 WMITLV_GET_STRUCT_TLVLEN 8157 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 8158 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8159 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 8160 if (ret) { 8161 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 8162 value1, value2); 8163 wmi_buf_free(buf); 8164 return ret; 8165 } 8166 break; 8167 8168 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 8169 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8170 buf = wmi_buf_alloc(wmi_handle, len); 8171 if (!buf) { 8172 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8173 return QDF_STATUS_E_NOMEM; 8174 } 8175 hist_intvl_cmd = 8176 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8177 wmi_buf_data(buf); 8178 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8179 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8180 WMITLV_GET_STRUCT_TLVLEN 8181 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8182 hist_intvl_cmd->profile_id = value1; 8183 hist_intvl_cmd->value = value2; 8184 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8185 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8186 if (ret) { 8187 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 8188 value1, value2); 8189 wmi_buf_free(buf); 8190 return ret; 8191 } 8192 break; 8193 8194 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 8195 len = 8196 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8197 buf = wmi_buf_alloc(wmi_handle, len); 8198 if (!buf) { 8199 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8200 return QDF_STATUS_E_NOMEM; 8201 } 8202 profile_enable_cmd = 8203 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8204 wmi_buf_data(buf); 8205 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8206 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8207 WMITLV_GET_STRUCT_TLVLEN 8208 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8209 profile_enable_cmd->profile_id = value1; 8210 profile_enable_cmd->enable = value2; 8211 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8212 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8213 if (ret) { 8214 WMI_LOGE("enable cmd Failed for id %d value %d", 8215 value1, value2); 8216 wmi_buf_free(buf); 8217 return ret; 8218 } 8219 break; 8220 8221 default: 8222 WMI_LOGD("%s: invalid profiling command", __func__); 8223 break; 8224 } 8225 8226 return 0; 8227 } 8228 8229 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 8230 struct wlm_latency_level_param *params) 8231 { 8232 wmi_wlm_config_cmd_fixed_param *cmd; 8233 wmi_buf_t buf; 8234 uint32_t len = sizeof(*cmd); 8235 static uint32_t ll[4] = {100, 60, 40, 20}; 8236 8237 buf = wmi_buf_alloc(wmi_handle, len); 8238 if (!buf) { 8239 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8240 return QDF_STATUS_E_NOMEM; 8241 } 8242 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 8243 WMITLV_SET_HDR(&cmd->tlv_header, 8244 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 8245 WMITLV_GET_STRUCT_TLVLEN 8246 (wmi_wlm_config_cmd_fixed_param)); 8247 cmd->vdev_id = params->vdev_id; 8248 cmd->latency_level = params->wlm_latency_level; 8249 cmd->ul_latency = ll[params->wlm_latency_level]; 8250 cmd->dl_latency = ll[params->wlm_latency_level]; 8251 cmd->flags = params->wlm_latency_flags; 8252 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8253 WMI_WLM_CONFIG_CMDID)) { 8254 WMI_LOGE("%s: Failed to send setting latency config command", 8255 __func__); 8256 wmi_buf_free(buf); 8257 return QDF_STATUS_E_FAILURE; 8258 } 8259 8260 return 0; 8261 } 8262 /** 8263 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 8264 * @wmi_handle: wmi handle 8265 * @vdev_id: vdev id 8266 * 8267 * Return: QDF_STATUS_SUCCESS for success or error code 8268 */ 8269 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8270 { 8271 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 8272 wmi_buf_t buf; 8273 int32_t len = sizeof(*cmd); 8274 8275 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8276 buf = wmi_buf_alloc(wmi_handle, len); 8277 if (!buf) { 8278 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8279 return QDF_STATUS_E_NOMEM; 8280 } 8281 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 8282 wmi_buf_data(buf); 8283 WMITLV_SET_HDR(&cmd->tlv_header, 8284 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 8285 WMITLV_GET_STRUCT_TLVLEN 8286 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 8287 cmd->vdev_id = vdev_id; 8288 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 8289 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8290 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 8291 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 8292 __func__); 8293 wmi_buf_free(buf); 8294 return QDF_STATUS_E_FAILURE; 8295 } 8296 8297 return 0; 8298 } 8299 8300 /** 8301 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 8302 * @wmi_handle: wmi handle 8303 * @vdev_id: vdev id 8304 * 8305 * Return: QDF_STATUS_SUCCESS for success or error code 8306 */ 8307 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 8308 uint8_t vdev_id) 8309 { 8310 wmi_csa_offload_enable_cmd_fixed_param *cmd; 8311 wmi_buf_t buf; 8312 int32_t len = sizeof(*cmd); 8313 8314 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8315 buf = wmi_buf_alloc(wmi_handle, len); 8316 if (!buf) { 8317 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8318 return QDF_STATUS_E_NOMEM; 8319 } 8320 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 8321 WMITLV_SET_HDR(&cmd->tlv_header, 8322 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 8323 WMITLV_GET_STRUCT_TLVLEN 8324 (wmi_csa_offload_enable_cmd_fixed_param)); 8325 cmd->vdev_id = vdev_id; 8326 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 8327 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8328 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 8329 WMI_LOGP("%s: Failed to send CSA offload enable command", 8330 __func__); 8331 wmi_buf_free(buf); 8332 return QDF_STATUS_E_FAILURE; 8333 } 8334 8335 return 0; 8336 } 8337 8338 #ifdef WLAN_FEATURE_CIF_CFR 8339 /** 8340 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 8341 * @wmi_handle: wmi handle 8342 * @data_len: len of dma cfg req 8343 * @data: dma cfg req 8344 * 8345 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8346 */ 8347 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8348 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 8349 { 8350 wmi_buf_t buf; 8351 uint8_t *cmd; 8352 QDF_STATUS ret; 8353 8354 WMITLV_SET_HDR(cfg, 8355 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 8356 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 8357 8358 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 8359 if (!buf) { 8360 WMI_LOGE(FL("wmi_buf_alloc failed")); 8361 return QDF_STATUS_E_FAILURE; 8362 } 8363 8364 cmd = (uint8_t *) wmi_buf_data(buf); 8365 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 8366 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 8367 sizeof(*cfg)); 8368 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 8369 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 8370 if (QDF_IS_STATUS_ERROR(ret)) { 8371 WMI_LOGE(FL(":wmi cmd send failed")); 8372 wmi_buf_free(buf); 8373 } 8374 8375 return ret; 8376 } 8377 #endif 8378 8379 /** 8380 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 8381 * @wmi_handle: wmi handle 8382 * @data_len: len of dma cfg req 8383 * @data: dma cfg req 8384 * 8385 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8386 */ 8387 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8388 struct direct_buf_rx_cfg_req *cfg) 8389 { 8390 wmi_buf_t buf; 8391 wmi_dma_ring_cfg_req_fixed_param *cmd; 8392 QDF_STATUS ret; 8393 int32_t len = sizeof(*cmd); 8394 8395 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8396 if (!buf) { 8397 WMI_LOGE(FL("wmi_buf_alloc failed")); 8398 return QDF_STATUS_E_FAILURE; 8399 } 8400 8401 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 8402 8403 WMITLV_SET_HDR(&cmd->tlv_header, 8404 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 8405 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 8406 8407 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8408 cfg->pdev_id); 8409 cmd->mod_id = cfg->mod_id; 8410 cmd->base_paddr_lo = cfg->base_paddr_lo; 8411 cmd->base_paddr_hi = cfg->base_paddr_hi; 8412 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 8413 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 8414 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 8415 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 8416 cmd->num_elems = cfg->num_elems; 8417 cmd->buf_size = cfg->buf_size; 8418 cmd->num_resp_per_event = cfg->num_resp_per_event; 8419 cmd->event_timeout_ms = cfg->event_timeout_ms; 8420 8421 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 8422 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 8423 "head idx paddr hi %x tail idx paddr lo %x" 8424 "tail idx addr hi %x num elems %d buf size %d num resp %d" 8425 "event timeout %d\n", __func__, cmd->pdev_id, 8426 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 8427 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 8428 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 8429 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 8430 cmd->event_timeout_ms); 8431 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8432 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 8433 if (QDF_IS_STATUS_ERROR(ret)) { 8434 WMI_LOGE(FL(":wmi cmd send failed")); 8435 wmi_buf_free(buf); 8436 } 8437 8438 return ret; 8439 } 8440 8441 /** 8442 * send_start_11d_scan_cmd_tlv() - start 11d scan request 8443 * @wmi_handle: wmi handle 8444 * @start_11d_scan: 11d scan start request parameters 8445 * 8446 * This function request FW to start 11d scan. 8447 * 8448 * Return: QDF status 8449 */ 8450 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8451 struct reg_start_11d_scan_req *start_11d_scan) 8452 { 8453 wmi_11d_scan_start_cmd_fixed_param *cmd; 8454 int32_t len; 8455 wmi_buf_t buf; 8456 int ret; 8457 8458 len = sizeof(*cmd); 8459 buf = wmi_buf_alloc(wmi_handle, len); 8460 if (!buf) { 8461 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8462 return QDF_STATUS_E_NOMEM; 8463 } 8464 8465 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 8466 8467 WMITLV_SET_HDR(&cmd->tlv_header, 8468 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 8469 WMITLV_GET_STRUCT_TLVLEN 8470 (wmi_11d_scan_start_cmd_fixed_param)); 8471 8472 cmd->vdev_id = start_11d_scan->vdev_id; 8473 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 8474 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 8475 8476 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 8477 8478 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8479 WMI_11D_SCAN_START_CMDID); 8480 if (ret) { 8481 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 8482 wmi_buf_free(buf); 8483 return QDF_STATUS_E_FAILURE; 8484 } 8485 8486 return QDF_STATUS_SUCCESS; 8487 } 8488 8489 /** 8490 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 8491 * @wmi_handle: wmi handle 8492 * @start_11d_scan: 11d scan stop request parameters 8493 * 8494 * This function request FW to stop 11d scan. 8495 * 8496 * Return: QDF status 8497 */ 8498 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8499 struct reg_stop_11d_scan_req *stop_11d_scan) 8500 { 8501 wmi_11d_scan_stop_cmd_fixed_param *cmd; 8502 int32_t len; 8503 wmi_buf_t buf; 8504 int ret; 8505 8506 len = sizeof(*cmd); 8507 buf = wmi_buf_alloc(wmi_handle, len); 8508 if (!buf) { 8509 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8510 return QDF_STATUS_E_NOMEM; 8511 } 8512 8513 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 8514 8515 WMITLV_SET_HDR(&cmd->tlv_header, 8516 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 8517 WMITLV_GET_STRUCT_TLVLEN 8518 (wmi_11d_scan_stop_cmd_fixed_param)); 8519 8520 cmd->vdev_id = stop_11d_scan->vdev_id; 8521 8522 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 8523 8524 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8525 WMI_11D_SCAN_STOP_CMDID); 8526 if (ret) { 8527 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 8528 wmi_buf_free(buf); 8529 return QDF_STATUS_E_FAILURE; 8530 } 8531 8532 return QDF_STATUS_SUCCESS; 8533 } 8534 8535 /** 8536 * send_start_oem_data_cmd_tlv() - start OEM data request to target 8537 * @wmi_handle: wmi handle 8538 * @startOemDataReq: start request params 8539 * 8540 * Return: CDF status 8541 */ 8542 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 8543 uint32_t data_len, 8544 uint8_t *data) 8545 { 8546 wmi_buf_t buf; 8547 uint8_t *cmd; 8548 QDF_STATUS ret; 8549 8550 buf = wmi_buf_alloc(wmi_handle, 8551 (data_len + WMI_TLV_HDR_SIZE)); 8552 if (!buf) { 8553 WMI_LOGE(FL("wmi_buf_alloc failed")); 8554 return QDF_STATUS_E_FAILURE; 8555 } 8556 8557 cmd = (uint8_t *) wmi_buf_data(buf); 8558 8559 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 8560 cmd += WMI_TLV_HDR_SIZE; 8561 qdf_mem_copy(cmd, data, 8562 data_len); 8563 8564 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 8565 data_len); 8566 8567 ret = wmi_unified_cmd_send(wmi_handle, buf, 8568 (data_len + 8569 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 8570 8571 if (QDF_IS_STATUS_ERROR(ret)) { 8572 WMI_LOGE(FL(":wmi cmd send failed")); 8573 wmi_buf_free(buf); 8574 } 8575 8576 return ret; 8577 } 8578 8579 /** 8580 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 8581 * @wmi_handle: wmi handle 8582 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 8583 * 8584 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 8585 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 8586 * to firmware based on phyerr filtering 8587 * offload status. 8588 * 8589 * Return: 1 success, 0 failure 8590 */ 8591 static QDF_STATUS 8592 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8593 bool dfs_phyerr_filter_offload) 8594 { 8595 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 8596 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 8597 wmi_buf_t buf; 8598 uint16_t len; 8599 QDF_STATUS ret; 8600 8601 8602 if (false == dfs_phyerr_filter_offload) { 8603 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 8604 __func__); 8605 len = sizeof(*disable_phyerr_offload_cmd); 8606 buf = wmi_buf_alloc(wmi_handle, len); 8607 if (!buf) { 8608 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8609 return 0; 8610 } 8611 disable_phyerr_offload_cmd = 8612 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 8613 wmi_buf_data(buf); 8614 8615 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 8616 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 8617 WMITLV_GET_STRUCT_TLVLEN 8618 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 8619 8620 /* 8621 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 8622 * to the firmware to disable the phyerror 8623 * filtering offload. 8624 */ 8625 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8626 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 8627 if (QDF_IS_STATUS_ERROR(ret)) { 8628 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 8629 __func__, ret); 8630 wmi_buf_free(buf); 8631 return QDF_STATUS_E_FAILURE; 8632 } 8633 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 8634 __func__); 8635 } else { 8636 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 8637 __func__); 8638 8639 len = sizeof(*enable_phyerr_offload_cmd); 8640 buf = wmi_buf_alloc(wmi_handle, len); 8641 if (!buf) { 8642 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8643 return QDF_STATUS_E_FAILURE; 8644 } 8645 8646 enable_phyerr_offload_cmd = 8647 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 8648 wmi_buf_data(buf); 8649 8650 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 8651 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 8652 WMITLV_GET_STRUCT_TLVLEN 8653 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 8654 8655 /* 8656 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 8657 * to the firmware to enable the phyerror 8658 * filtering offload. 8659 */ 8660 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8661 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 8662 8663 if (QDF_IS_STATUS_ERROR(ret)) { 8664 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 8665 __func__, ret); 8666 wmi_buf_free(buf); 8667 return QDF_STATUS_E_FAILURE; 8668 } 8669 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 8670 __func__); 8671 } 8672 8673 return QDF_STATUS_SUCCESS; 8674 } 8675 8676 /** 8677 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 8678 * will wake up host after specified time is elapsed 8679 * @wmi_handle: wmi handle 8680 * @vdev_id: vdev id 8681 * @cookie: value to identify reason why host set up wake call. 8682 * @time: time in ms 8683 * 8684 * Return: QDF status 8685 */ 8686 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 8687 uint8_t vdev_id, uint32_t cookie, uint32_t time) 8688 { 8689 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 8690 wmi_buf_t buf; 8691 uint8_t *buf_ptr; 8692 int32_t len; 8693 int ret; 8694 8695 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 8696 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 8697 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 8698 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 8699 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 8700 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 8701 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 8702 8703 buf = wmi_buf_alloc(wmi_handle, len); 8704 if (!buf) { 8705 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8706 return QDF_STATUS_E_NOMEM; 8707 } 8708 8709 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 8710 buf_ptr = (uint8_t *) cmd; 8711 8712 WMITLV_SET_HDR(&cmd->tlv_header, 8713 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 8714 WMITLV_GET_STRUCT_TLVLEN 8715 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 8716 cmd->vdev_id = vdev_id; 8717 cmd->pattern_id = cookie, 8718 cmd->pattern_type = WOW_TIMER_PATTERN; 8719 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 8720 8721 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 8722 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8723 buf_ptr += WMI_TLV_HDR_SIZE; 8724 8725 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 8726 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8727 buf_ptr += WMI_TLV_HDR_SIZE; 8728 8729 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 8730 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8731 buf_ptr += WMI_TLV_HDR_SIZE; 8732 8733 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 8734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8735 buf_ptr += WMI_TLV_HDR_SIZE; 8736 8737 /* Fill TLV for pattern_info_timeout, and time value */ 8738 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8739 buf_ptr += WMI_TLV_HDR_SIZE; 8740 *((uint32_t *) buf_ptr) = time; 8741 buf_ptr += sizeof(uint32_t); 8742 8743 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 8744 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8745 buf_ptr += WMI_TLV_HDR_SIZE; 8746 *((uint32_t *) buf_ptr) = 0; 8747 8748 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 8749 __func__, time, vdev_id); 8750 8751 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8752 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 8753 if (ret) { 8754 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 8755 __func__); 8756 wmi_buf_free(buf); 8757 return QDF_STATUS_E_FAILURE; 8758 } 8759 8760 return QDF_STATUS_SUCCESS; 8761 } 8762 8763 #if !defined(REMOVE_PKT_LOG) 8764 /** 8765 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 8766 * @wmi_handle: wmi handle 8767 * @pktlog_event: pktlog event 8768 * @cmd_id: pktlog cmd id 8769 * 8770 * Return: CDF status 8771 */ 8772 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 8773 WMI_PKTLOG_EVENT pktlog_event, 8774 WMI_CMD_ID cmd_id, uint8_t user_triggered) 8775 { 8776 WMI_PKTLOG_EVENT PKTLOG_EVENT; 8777 WMI_CMD_ID CMD_ID; 8778 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 8779 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 8780 int len = 0; 8781 wmi_buf_t buf; 8782 8783 PKTLOG_EVENT = pktlog_event; 8784 CMD_ID = cmd_id; 8785 8786 switch (CMD_ID) { 8787 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 8788 len = sizeof(*cmd); 8789 buf = wmi_buf_alloc(wmi_handle, len); 8790 if (!buf) { 8791 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8792 return QDF_STATUS_E_NOMEM; 8793 } 8794 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 8795 wmi_buf_data(buf); 8796 WMITLV_SET_HDR(&cmd->tlv_header, 8797 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 8798 WMITLV_GET_STRUCT_TLVLEN 8799 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 8800 cmd->evlist = PKTLOG_EVENT; 8801 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 8802 : WMI_PKTLOG_ENABLE_AUTO; 8803 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8804 WMI_HOST_PDEV_ID_SOC); 8805 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8806 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 8807 WMI_LOGE("failed to send pktlog enable cmdid"); 8808 goto wmi_send_failed; 8809 } 8810 break; 8811 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 8812 len = sizeof(*disable_cmd); 8813 buf = wmi_buf_alloc(wmi_handle, len); 8814 if (!buf) { 8815 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8816 return QDF_STATUS_E_NOMEM; 8817 } 8818 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 8819 wmi_buf_data(buf); 8820 WMITLV_SET_HDR(&disable_cmd->tlv_header, 8821 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 8822 WMITLV_GET_STRUCT_TLVLEN 8823 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 8824 disable_cmd->pdev_id = 8825 wmi_handle->ops->convert_pdev_id_host_to_target( 8826 WMI_HOST_PDEV_ID_SOC); 8827 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8828 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 8829 WMI_LOGE("failed to send pktlog disable cmdid"); 8830 goto wmi_send_failed; 8831 } 8832 break; 8833 default: 8834 WMI_LOGD("%s: invalid PKTLOG command", __func__); 8835 break; 8836 } 8837 8838 return QDF_STATUS_SUCCESS; 8839 8840 wmi_send_failed: 8841 wmi_buf_free(buf); 8842 return QDF_STATUS_E_FAILURE; 8843 } 8844 #endif /* REMOVE_PKT_LOG */ 8845 8846 /** 8847 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 8848 * @wmi_handle: wmi handle 8849 * @ptrn_id: pattern id 8850 * @vdev_id: vdev id 8851 * 8852 * Return: CDF status 8853 */ 8854 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 8855 uint8_t ptrn_id, uint8_t vdev_id) 8856 { 8857 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 8858 wmi_buf_t buf; 8859 int32_t len; 8860 int ret; 8861 8862 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 8863 8864 8865 buf = wmi_buf_alloc(wmi_handle, len); 8866 if (!buf) { 8867 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8868 return QDF_STATUS_E_NOMEM; 8869 } 8870 8871 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 8872 8873 WMITLV_SET_HDR(&cmd->tlv_header, 8874 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 8875 WMITLV_GET_STRUCT_TLVLEN( 8876 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 8877 cmd->vdev_id = vdev_id; 8878 cmd->pattern_id = ptrn_id; 8879 cmd->pattern_type = WOW_BITMAP_PATTERN; 8880 8881 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 8882 cmd->pattern_id, vdev_id); 8883 8884 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8885 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 8886 if (ret) { 8887 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 8888 wmi_buf_free(buf); 8889 return QDF_STATUS_E_FAILURE; 8890 } 8891 8892 return QDF_STATUS_SUCCESS; 8893 } 8894 8895 /** 8896 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 8897 * @wmi_handle: wmi handle 8898 * 8899 * Sends host wakeup indication to FW. On receiving this indication, 8900 * FW will come out of WOW. 8901 * 8902 * Return: CDF status 8903 */ 8904 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 8905 { 8906 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 8907 wmi_buf_t buf; 8908 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 8909 int32_t len; 8910 int ret; 8911 8912 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 8913 8914 buf = wmi_buf_alloc(wmi_handle, len); 8915 if (!buf) { 8916 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8917 return QDF_STATUS_E_NOMEM; 8918 } 8919 8920 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 8921 wmi_buf_data(buf); 8922 WMITLV_SET_HDR(&cmd->tlv_header, 8923 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 8924 WMITLV_GET_STRUCT_TLVLEN 8925 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 8926 8927 8928 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8929 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 8930 if (ret) { 8931 WMI_LOGE("Failed to send host wakeup indication to fw"); 8932 wmi_buf_free(buf); 8933 return QDF_STATUS_E_FAILURE; 8934 } 8935 8936 return qdf_status; 8937 } 8938 8939 /** 8940 * send_del_ts_cmd_tlv() - send DELTS request to fw 8941 * @wmi_handle: wmi handle 8942 * @msg: delts params 8943 * 8944 * Return: CDF status 8945 */ 8946 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 8947 uint8_t ac) 8948 { 8949 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 8950 wmi_buf_t buf; 8951 int32_t len = sizeof(*cmd); 8952 8953 buf = wmi_buf_alloc(wmi_handle, len); 8954 if (!buf) { 8955 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8956 return QDF_STATUS_E_NOMEM; 8957 } 8958 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 8959 WMITLV_SET_HDR(&cmd->tlv_header, 8960 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 8961 WMITLV_GET_STRUCT_TLVLEN 8962 (wmi_vdev_wmm_delts_cmd_fixed_param)); 8963 cmd->vdev_id = vdev_id; 8964 cmd->ac = ac; 8965 8966 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 8967 cmd->vdev_id, cmd->ac, __func__, __LINE__); 8968 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8969 WMI_VDEV_WMM_DELTS_CMDID)) { 8970 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 8971 wmi_buf_free(buf); 8972 return QDF_STATUS_E_FAILURE; 8973 } 8974 8975 return QDF_STATUS_SUCCESS; 8976 } 8977 8978 /** 8979 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 8980 * @wmi_handle: handle to wmi 8981 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 8982 * 8983 * A function to handle WMI_AGGR_QOS_REQ. This will send out 8984 * ADD_TS requestes to firmware in loop for all the ACs with 8985 * active flow. 8986 * 8987 * Return: CDF status 8988 */ 8989 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 8990 struct aggr_add_ts_param *aggr_qos_rsp_msg) 8991 { 8992 int i = 0; 8993 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 8994 wmi_buf_t buf; 8995 int32_t len = sizeof(*cmd); 8996 8997 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 8998 /* if flow in this AC is active */ 8999 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9000 /* 9001 * as per implementation of wma_add_ts_req() we 9002 * are not waiting any response from firmware so 9003 * apart from sending ADDTS to firmware just send 9004 * success to upper layers 9005 */ 9006 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9007 9008 buf = wmi_buf_alloc(wmi_handle, len); 9009 if (!buf) { 9010 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9011 return QDF_STATUS_E_NOMEM; 9012 } 9013 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9014 wmi_buf_data(buf); 9015 WMITLV_SET_HDR(&cmd->tlv_header, 9016 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9017 WMITLV_GET_STRUCT_TLVLEN 9018 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9019 cmd->vdev_id = aggr_qos_rsp_msg->sessionId; 9020 cmd->ac = 9021 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9022 traffic.userPrio); 9023 cmd->medium_time_us = 9024 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9025 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9026 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9027 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9028 cmd->medium_time_us, cmd->downgrade_type); 9029 if (wmi_unified_cmd_send 9030 (wmi_handle, buf, len, 9031 WMI_VDEV_WMM_ADDTS_CMDID)) { 9032 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9033 __func__); 9034 aggr_qos_rsp_msg->status[i] = 9035 QDF_STATUS_E_FAILURE; 9036 wmi_buf_free(buf); 9037 return QDF_STATUS_E_FAILURE; 9038 } 9039 } 9040 } 9041 9042 return QDF_STATUS_SUCCESS; 9043 } 9044 9045 /** 9046 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9047 * @wmi_handle: wmi handle 9048 * @msg: ADDTS params 9049 * 9050 * Return: CDF status 9051 */ 9052 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9053 struct add_ts_param *msg) 9054 { 9055 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9056 wmi_buf_t buf; 9057 int32_t len = sizeof(*cmd); 9058 9059 msg->status = QDF_STATUS_SUCCESS; 9060 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 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9067 WMITLV_SET_HDR(&cmd->tlv_header, 9068 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9069 WMITLV_GET_STRUCT_TLVLEN 9070 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9071 cmd->vdev_id = msg->sme_session_id; 9072 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9073 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9074 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9075 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9076 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9077 cmd->downgrade_type, __func__, __LINE__); 9078 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9079 WMI_VDEV_WMM_ADDTS_CMDID)) { 9080 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9081 msg->status = QDF_STATUS_E_FAILURE; 9082 wmi_buf_free(buf); 9083 return QDF_STATUS_E_FAILURE; 9084 } 9085 9086 return QDF_STATUS_SUCCESS; 9087 } 9088 9089 /** 9090 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 9091 * @wmi_handle: wmi handle 9092 * @pAddPeriodicTxPtrnParams: tx ptrn params 9093 * 9094 * Retrun: CDF status 9095 */ 9096 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9097 struct periodic_tx_pattern * 9098 pAddPeriodicTxPtrnParams, 9099 uint8_t vdev_id) 9100 { 9101 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9102 wmi_buf_t wmi_buf; 9103 uint32_t len; 9104 uint8_t *buf_ptr; 9105 uint32_t ptrn_len, ptrn_len_aligned; 9106 int j; 9107 9108 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 9109 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 9110 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 9111 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 9112 9113 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9114 if (!wmi_buf) { 9115 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9116 return QDF_STATUS_E_NOMEM; 9117 } 9118 9119 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 9120 9121 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 9122 WMITLV_SET_HDR(&cmd->tlv_header, 9123 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9124 WMITLV_GET_STRUCT_TLVLEN 9125 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9126 9127 /* Pass the pattern id to delete for the corresponding vdev id */ 9128 cmd->vdev_id = vdev_id; 9129 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 9130 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 9131 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 9132 9133 /* Pattern info */ 9134 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9135 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 9136 buf_ptr += WMI_TLV_HDR_SIZE; 9137 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 9138 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 9139 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 9140 9141 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 9142 __func__, cmd->pattern_id, cmd->vdev_id); 9143 9144 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9145 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9146 WMI_LOGE("%s: failed to add pattern set state command", 9147 __func__); 9148 wmi_buf_free(wmi_buf); 9149 return QDF_STATUS_E_FAILURE; 9150 } 9151 return QDF_STATUS_SUCCESS; 9152 } 9153 9154 /** 9155 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 9156 * @wmi_handle: wmi handle 9157 * @vdev_id: vdev id 9158 * @pattern_id: pattern id 9159 * 9160 * Retrun: CDF status 9161 */ 9162 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9163 uint8_t vdev_id, 9164 uint8_t pattern_id) 9165 { 9166 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9167 wmi_buf_t wmi_buf; 9168 uint32_t len = 9169 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9170 9171 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9172 if (!wmi_buf) { 9173 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9174 return QDF_STATUS_E_NOMEM; 9175 } 9176 9177 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 9178 wmi_buf_data(wmi_buf); 9179 WMITLV_SET_HDR(&cmd->tlv_header, 9180 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9181 WMITLV_GET_STRUCT_TLVLEN 9182 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9183 9184 /* Pass the pattern id to delete for the corresponding vdev id */ 9185 cmd->vdev_id = vdev_id; 9186 cmd->pattern_id = pattern_id; 9187 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 9188 __func__, cmd->pattern_id, cmd->vdev_id); 9189 9190 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9191 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9192 WMI_LOGE("%s: failed to send del pattern command", __func__); 9193 wmi_buf_free(wmi_buf); 9194 return QDF_STATUS_E_FAILURE; 9195 } 9196 return QDF_STATUS_SUCCESS; 9197 } 9198 9199 /** 9200 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 9201 * @wmi_handle: wmi handle 9202 * @preq: stats ext params 9203 * 9204 * Return: CDF status 9205 */ 9206 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 9207 struct stats_ext_params *preq) 9208 { 9209 QDF_STATUS ret; 9210 wmi_req_stats_ext_cmd_fixed_param *cmd; 9211 wmi_buf_t buf; 9212 uint16_t len; 9213 uint8_t *buf_ptr; 9214 9215 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 9216 9217 buf = wmi_buf_alloc(wmi_handle, len); 9218 if (!buf) { 9219 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9220 return QDF_STATUS_E_NOMEM; 9221 } 9222 9223 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9224 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 9225 9226 WMITLV_SET_HDR(&cmd->tlv_header, 9227 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 9228 WMITLV_GET_STRUCT_TLVLEN 9229 (wmi_req_stats_ext_cmd_fixed_param)); 9230 cmd->vdev_id = preq->vdev_id; 9231 cmd->data_len = preq->request_data_len; 9232 9233 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 9234 __func__, preq->request_data_len, preq->vdev_id); 9235 9236 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 9237 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 9238 9239 buf_ptr += WMI_TLV_HDR_SIZE; 9240 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 9241 9242 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9243 WMI_REQUEST_STATS_EXT_CMDID); 9244 if (QDF_IS_STATUS_ERROR(ret)) { 9245 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 9246 ret); 9247 wmi_buf_free(buf); 9248 } 9249 9250 return ret; 9251 } 9252 9253 /** 9254 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 9255 * @wmi_handle: wmi handle 9256 * @params: ext wow params 9257 * 9258 * Return:0 for success or error code 9259 */ 9260 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 9261 struct ext_wow_params *params) 9262 { 9263 wmi_extwow_enable_cmd_fixed_param *cmd; 9264 wmi_buf_t buf; 9265 int32_t len; 9266 int ret; 9267 9268 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 9269 buf = wmi_buf_alloc(wmi_handle, len); 9270 if (!buf) { 9271 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9272 return QDF_STATUS_E_NOMEM; 9273 } 9274 9275 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 9276 9277 WMITLV_SET_HDR(&cmd->tlv_header, 9278 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 9279 WMITLV_GET_STRUCT_TLVLEN 9280 (wmi_extwow_enable_cmd_fixed_param)); 9281 9282 cmd->vdev_id = params->vdev_id; 9283 cmd->type = params->type; 9284 cmd->wakeup_pin_num = params->wakeup_pin_num; 9285 9286 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 9287 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 9288 9289 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9290 WMI_EXTWOW_ENABLE_CMDID); 9291 if (ret) { 9292 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 9293 wmi_buf_free(buf); 9294 return QDF_STATUS_E_FAILURE; 9295 } 9296 9297 return QDF_STATUS_SUCCESS; 9298 9299 } 9300 9301 /** 9302 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 9303 * @wmi_handle: wmi handle 9304 * @app_type1_params: app type1 params 9305 * 9306 * Return: CDF status 9307 */ 9308 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9309 struct app_type1_params *app_type1_params) 9310 { 9311 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 9312 wmi_buf_t buf; 9313 int32_t len; 9314 int ret; 9315 9316 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 9317 buf = wmi_buf_alloc(wmi_handle, len); 9318 if (!buf) { 9319 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9320 return QDF_STATUS_E_NOMEM; 9321 } 9322 9323 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 9324 wmi_buf_data(buf); 9325 9326 WMITLV_SET_HDR(&cmd->tlv_header, 9327 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 9328 WMITLV_GET_STRUCT_TLVLEN 9329 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 9330 9331 cmd->vdev_id = app_type1_params->vdev_id; 9332 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 9333 &cmd->wakee_mac); 9334 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 9335 cmd->ident_len = app_type1_params->id_length; 9336 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 9337 cmd->passwd_len = app_type1_params->pass_length; 9338 9339 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 9340 "identification_id %.8s id_length %u " 9341 "password %.16s pass_length %u", 9342 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 9343 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 9344 9345 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9346 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 9347 if (ret) { 9348 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 9349 wmi_buf_free(buf); 9350 return QDF_STATUS_E_FAILURE; 9351 } 9352 9353 return QDF_STATUS_SUCCESS; 9354 } 9355 9356 /** 9357 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 9358 * @wmi_handle: wmi handle 9359 * @appType2Params: app type2 params 9360 * 9361 * Return: CDF status 9362 */ 9363 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9364 struct app_type2_params *appType2Params) 9365 { 9366 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 9367 wmi_buf_t buf; 9368 int32_t len; 9369 int ret; 9370 9371 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 9372 buf = wmi_buf_alloc(wmi_handle, len); 9373 if (!buf) { 9374 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9375 return QDF_STATUS_E_NOMEM; 9376 } 9377 9378 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 9379 wmi_buf_data(buf); 9380 9381 WMITLV_SET_HDR(&cmd->tlv_header, 9382 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 9383 WMITLV_GET_STRUCT_TLVLEN 9384 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 9385 9386 cmd->vdev_id = appType2Params->vdev_id; 9387 9388 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 9389 cmd->rc4_key_len = appType2Params->rc4_key_len; 9390 9391 cmd->ip_id = appType2Params->ip_id; 9392 cmd->ip_device_ip = appType2Params->ip_device_ip; 9393 cmd->ip_server_ip = appType2Params->ip_server_ip; 9394 9395 cmd->tcp_src_port = appType2Params->tcp_src_port; 9396 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 9397 cmd->tcp_seq = appType2Params->tcp_seq; 9398 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 9399 9400 cmd->keepalive_init = appType2Params->keepalive_init; 9401 cmd->keepalive_min = appType2Params->keepalive_min; 9402 cmd->keepalive_max = appType2Params->keepalive_max; 9403 cmd->keepalive_inc = appType2Params->keepalive_inc; 9404 9405 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 9406 &cmd->gateway_mac); 9407 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 9408 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 9409 9410 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 9411 "rc4_key %.16s rc4_key_len %u " 9412 "ip_id %x ip_device_ip %x ip_server_ip %x " 9413 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 9414 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 9415 "keepalive_max %u keepalive_inc %u " 9416 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 9417 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 9418 cmd->rc4_key, cmd->rc4_key_len, 9419 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 9420 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 9421 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 9422 cmd->keepalive_max, cmd->keepalive_inc, 9423 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 9424 9425 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9426 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 9427 if (ret) { 9428 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 9429 wmi_buf_free(buf); 9430 return QDF_STATUS_E_FAILURE; 9431 } 9432 9433 return QDF_STATUS_SUCCESS; 9434 9435 } 9436 9437 /** 9438 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 9439 * @wmi_handle: wmi handle 9440 * @timer_val: auto shutdown timer value 9441 * 9442 * Return: CDF status 9443 */ 9444 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 9445 uint32_t timer_val) 9446 { 9447 QDF_STATUS status; 9448 wmi_buf_t buf = NULL; 9449 uint8_t *buf_ptr; 9450 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 9451 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 9452 9453 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 9454 __func__, timer_val); 9455 9456 buf = wmi_buf_alloc(wmi_handle, len); 9457 if (!buf) { 9458 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9459 return QDF_STATUS_E_NOMEM; 9460 } 9461 9462 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9463 wmi_auto_sh_cmd = 9464 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 9465 wmi_auto_sh_cmd->timer_value = timer_val; 9466 9467 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 9468 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 9469 WMITLV_GET_STRUCT_TLVLEN 9470 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 9471 9472 status = wmi_unified_cmd_send(wmi_handle, buf, 9473 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 9474 if (QDF_IS_STATUS_ERROR(status)) { 9475 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 9476 __func__, status); 9477 wmi_buf_free(buf); 9478 } 9479 9480 return status; 9481 } 9482 9483 /** 9484 * send_nan_req_cmd_tlv() - to send nan request to target 9485 * @wmi_handle: wmi handle 9486 * @nan_req: request data which will be non-null 9487 * 9488 * Return: CDF status 9489 */ 9490 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 9491 struct nan_req_params *nan_req) 9492 { 9493 QDF_STATUS ret; 9494 wmi_nan_cmd_param *cmd; 9495 wmi_buf_t buf; 9496 uint16_t len = sizeof(*cmd); 9497 uint16_t nan_data_len, nan_data_len_aligned; 9498 uint8_t *buf_ptr; 9499 9500 /* 9501 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 9502 * +------------+----------+-----------------------+--------------+ 9503 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 9504 * +------------+----------+-----------------------+--------------+ 9505 */ 9506 if (!nan_req) { 9507 WMI_LOGE("%s:nan req is not valid", __func__); 9508 return QDF_STATUS_E_FAILURE; 9509 } 9510 nan_data_len = nan_req->request_data_len; 9511 nan_data_len_aligned = roundup(nan_req->request_data_len, 9512 sizeof(uint32_t)); 9513 if (nan_data_len_aligned < nan_req->request_data_len) { 9514 WMI_LOGE("%s: integer overflow while rounding up data_len", 9515 __func__); 9516 return QDF_STATUS_E_FAILURE; 9517 } 9518 9519 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 9520 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 9521 __func__); 9522 return QDF_STATUS_E_FAILURE; 9523 } 9524 9525 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 9526 buf = wmi_buf_alloc(wmi_handle, len); 9527 if (!buf) { 9528 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9529 return QDF_STATUS_E_NOMEM; 9530 } 9531 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9532 cmd = (wmi_nan_cmd_param *) buf_ptr; 9533 WMITLV_SET_HDR(&cmd->tlv_header, 9534 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 9535 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 9536 cmd->data_len = nan_req->request_data_len; 9537 WMI_LOGD("%s: The data len value is %u", 9538 __func__, nan_req->request_data_len); 9539 buf_ptr += sizeof(wmi_nan_cmd_param); 9540 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 9541 buf_ptr += WMI_TLV_HDR_SIZE; 9542 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 9543 9544 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9545 WMI_NAN_CMDID); 9546 if (QDF_IS_STATUS_ERROR(ret)) { 9547 WMI_LOGE("%s Failed to send set param command ret = %d", 9548 __func__, ret); 9549 wmi_buf_free(buf); 9550 } 9551 9552 return ret; 9553 } 9554 9555 /** 9556 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 9557 * @wmi_handle: wmi handle 9558 * @params: DHCP server offload info 9559 * 9560 * Return: QDF_STATUS_SUCCESS for success or error code 9561 */ 9562 static QDF_STATUS 9563 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 9564 struct dhcp_offload_info_params *params) 9565 { 9566 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 9567 wmi_buf_t buf; 9568 QDF_STATUS status; 9569 9570 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9571 if (!buf) { 9572 WMI_LOGE("Failed to allocate buffer to send " 9573 "set_dhcp_server_offload cmd"); 9574 return QDF_STATUS_E_NOMEM; 9575 } 9576 9577 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 9578 9579 WMITLV_SET_HDR(&cmd->tlv_header, 9580 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 9581 WMITLV_GET_STRUCT_TLVLEN 9582 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 9583 cmd->vdev_id = params->vdev_id; 9584 cmd->enable = params->dhcp_offload_enabled; 9585 cmd->num_client = params->dhcp_client_num; 9586 cmd->srv_ipv4 = params->dhcp_srv_addr; 9587 cmd->start_lsb = 0; 9588 status = wmi_unified_cmd_send(wmi_handle, buf, 9589 sizeof(*cmd), 9590 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 9591 if (QDF_IS_STATUS_ERROR(status)) { 9592 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 9593 wmi_buf_free(buf); 9594 return QDF_STATUS_E_FAILURE; 9595 } 9596 WMI_LOGD("Set dhcp server offload to vdevId %d", 9597 params->vdev_id); 9598 9599 return status; 9600 } 9601 9602 /** 9603 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 9604 * @wmi_handle: wmi handle 9605 * @flashing: flashing request 9606 * 9607 * Return: CDF status 9608 */ 9609 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 9610 struct flashing_req_params *flashing) 9611 { 9612 wmi_set_led_flashing_cmd_fixed_param *cmd; 9613 QDF_STATUS status; 9614 wmi_buf_t buf; 9615 uint8_t *buf_ptr; 9616 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 9617 9618 buf = wmi_buf_alloc(wmi_handle, len); 9619 if (!buf) { 9620 WMI_LOGP(FL("wmi_buf_alloc failed")); 9621 return QDF_STATUS_E_NOMEM; 9622 } 9623 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9624 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 9625 WMITLV_SET_HDR(&cmd->tlv_header, 9626 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 9627 WMITLV_GET_STRUCT_TLVLEN 9628 (wmi_set_led_flashing_cmd_fixed_param)); 9629 cmd->pattern_id = flashing->pattern_id; 9630 cmd->led_x0 = flashing->led_x0; 9631 cmd->led_x1 = flashing->led_x1; 9632 9633 status = wmi_unified_cmd_send(wmi_handle, buf, len, 9634 WMI_PDEV_SET_LED_FLASHING_CMDID); 9635 if (QDF_IS_STATUS_ERROR(status)) { 9636 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 9637 " returned Error %d", __func__, status); 9638 wmi_buf_free(buf); 9639 } 9640 9641 return status; 9642 } 9643 9644 /** 9645 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 9646 * @wmi_handle: wmi handle 9647 * @ch_avoid_update_req: channel avoid update params 9648 * 9649 * Return: CDF status 9650 */ 9651 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 9652 { 9653 QDF_STATUS status; 9654 wmi_buf_t buf = NULL; 9655 uint8_t *buf_ptr; 9656 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 9657 int len = sizeof(wmi_chan_avoid_update_cmd_param); 9658 9659 9660 buf = wmi_buf_alloc(wmi_handle, len); 9661 if (!buf) { 9662 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9663 return QDF_STATUS_E_NOMEM; 9664 } 9665 9666 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9667 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 9668 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 9669 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 9670 WMITLV_GET_STRUCT_TLVLEN 9671 (wmi_chan_avoid_update_cmd_param)); 9672 9673 status = wmi_unified_cmd_send(wmi_handle, buf, 9674 len, WMI_CHAN_AVOID_UPDATE_CMDID); 9675 if (QDF_IS_STATUS_ERROR(status)) { 9676 WMI_LOGE("wmi_unified_cmd_send" 9677 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 9678 " returned Error %d", status); 9679 wmi_buf_free(buf); 9680 } 9681 9682 return status; 9683 } 9684 9685 /** 9686 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 9687 * @wmi_handle: wmi handle 9688 * @param: pointer to pdev regdomain params 9689 * 9690 * Return: 0 for success or error code 9691 */ 9692 static QDF_STATUS 9693 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 9694 struct pdev_set_regdomain_params *param) 9695 { 9696 wmi_buf_t buf; 9697 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9698 int32_t len = sizeof(*cmd); 9699 9700 9701 buf = wmi_buf_alloc(wmi_handle, len); 9702 if (!buf) { 9703 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9704 return QDF_STATUS_E_NOMEM; 9705 } 9706 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9707 WMITLV_SET_HDR(&cmd->tlv_header, 9708 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 9709 WMITLV_GET_STRUCT_TLVLEN 9710 (wmi_pdev_set_regdomain_cmd_fixed_param)); 9711 9712 cmd->reg_domain = param->currentRDinuse; 9713 cmd->reg_domain_2G = param->currentRD2G; 9714 cmd->reg_domain_5G = param->currentRD5G; 9715 cmd->conformance_test_limit_2G = param->ctl_2G; 9716 cmd->conformance_test_limit_5G = param->ctl_5G; 9717 cmd->dfs_domain = param->dfsDomain; 9718 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9719 param->pdev_id); 9720 9721 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9722 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 9723 WMI_LOGE("%s: Failed to send pdev set regdomain command", 9724 __func__); 9725 wmi_buf_free(buf); 9726 return QDF_STATUS_E_FAILURE; 9727 } 9728 9729 return QDF_STATUS_SUCCESS; 9730 } 9731 9732 /** 9733 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 9734 * @wmi_handle: wmi handle 9735 * @reg_dmn: reg domain 9736 * @regdmn2G: 2G reg domain 9737 * @regdmn5G: 5G reg domain 9738 * @ctl2G: 2G test limit 9739 * @ctl5G: 5G test limit 9740 * 9741 * Return: none 9742 */ 9743 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 9744 uint32_t reg_dmn, uint16_t regdmn2G, 9745 uint16_t regdmn5G, uint8_t ctl2G, 9746 uint8_t ctl5G) 9747 { 9748 wmi_buf_t buf; 9749 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9750 int32_t len = sizeof(*cmd); 9751 9752 9753 buf = wmi_buf_alloc(wmi_handle, len); 9754 if (!buf) { 9755 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9756 return QDF_STATUS_E_NOMEM; 9757 } 9758 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9759 WMITLV_SET_HDR(&cmd->tlv_header, 9760 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 9761 WMITLV_GET_STRUCT_TLVLEN 9762 (wmi_pdev_set_regdomain_cmd_fixed_param)); 9763 cmd->reg_domain = reg_dmn; 9764 cmd->reg_domain_2G = regdmn2G; 9765 cmd->reg_domain_5G = regdmn5G; 9766 cmd->conformance_test_limit_2G = ctl2G; 9767 cmd->conformance_test_limit_5G = ctl5G; 9768 9769 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9770 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 9771 WMI_LOGP("%s: Failed to send pdev set regdomain command", 9772 __func__); 9773 wmi_buf_free(buf); 9774 return QDF_STATUS_E_FAILURE; 9775 } 9776 9777 return QDF_STATUS_SUCCESS; 9778 } 9779 9780 9781 /** 9782 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 9783 * @wmi_handle: wmi handle 9784 * @chan_switch_params: Pointer to tdls channel switch parameter structure 9785 * 9786 * This function sets tdls off channel mode 9787 * 9788 * Return: 0 on success; Negative errno otherwise 9789 */ 9790 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 9791 struct tdls_channel_switch_params *chan_switch_params) 9792 { 9793 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 9794 wmi_buf_t wmi_buf; 9795 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 9796 9797 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9798 if (!wmi_buf) { 9799 WMI_LOGE(FL("wmi_buf_alloc failed")); 9800 return QDF_STATUS_E_FAILURE; 9801 } 9802 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 9803 wmi_buf_data(wmi_buf); 9804 WMITLV_SET_HDR(&cmd->tlv_header, 9805 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 9806 WMITLV_GET_STRUCT_TLVLEN( 9807 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 9808 9809 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 9810 &cmd->peer_macaddr); 9811 cmd->vdev_id = chan_switch_params->vdev_id; 9812 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 9813 cmd->is_peer_responder = chan_switch_params->is_responder; 9814 cmd->offchan_num = chan_switch_params->tdls_off_ch; 9815 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 9816 cmd->offchan_oper_class = chan_switch_params->oper_class; 9817 9818 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 9819 cmd->peer_macaddr.mac_addr31to0, 9820 cmd->peer_macaddr.mac_addr47to32); 9821 9822 WMI_LOGD(FL( 9823 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 9824 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 9825 ), 9826 cmd->vdev_id, 9827 cmd->offchan_mode, 9828 cmd->offchan_num, 9829 cmd->offchan_bw_bitmap, 9830 cmd->is_peer_responder, 9831 cmd->offchan_oper_class); 9832 9833 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9834 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 9835 WMI_LOGP(FL("failed to send tdls off chan command")); 9836 wmi_buf_free(wmi_buf); 9837 return QDF_STATUS_E_FAILURE; 9838 } 9839 9840 9841 return QDF_STATUS_SUCCESS; 9842 } 9843 9844 /** 9845 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 9846 * @wmi_handle: wmi handle 9847 * @pwmaTdlsparams: TDLS params 9848 * 9849 * Return: 0 for success or error code 9850 */ 9851 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 9852 void *tdls_param, uint8_t tdls_state) 9853 { 9854 wmi_tdls_set_state_cmd_fixed_param *cmd; 9855 wmi_buf_t wmi_buf; 9856 9857 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 9858 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 9859 9860 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9861 if (!wmi_buf) { 9862 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 9863 return QDF_STATUS_E_FAILURE; 9864 } 9865 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9866 WMITLV_SET_HDR(&cmd->tlv_header, 9867 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 9868 WMITLV_GET_STRUCT_TLVLEN 9869 (wmi_tdls_set_state_cmd_fixed_param)); 9870 cmd->vdev_id = wmi_tdls->vdev_id; 9871 cmd->state = tdls_state; 9872 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 9873 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 9874 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 9875 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 9876 cmd->rssi_delta = wmi_tdls->rssi_delta; 9877 cmd->tdls_options = wmi_tdls->tdls_options; 9878 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 9879 cmd->tdls_peer_traffic_response_timeout_ms = 9880 wmi_tdls->peer_traffic_response_timeout; 9881 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 9882 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 9883 cmd->tdls_puapsd_rx_frame_threshold = 9884 wmi_tdls->puapsd_rx_frame_threshold; 9885 cmd->teardown_notification_ms = 9886 wmi_tdls->teardown_notification_ms; 9887 cmd->tdls_peer_kickout_threshold = 9888 wmi_tdls->tdls_peer_kickout_threshold; 9889 9890 WMI_LOGD("%s: tdls_state: %d, state: %d, " 9891 "notification_interval_ms: %d, " 9892 "tx_discovery_threshold: %d, " 9893 "tx_teardown_threshold: %d, " 9894 "rssi_teardown_threshold: %d, " 9895 "rssi_delta: %d, " 9896 "tdls_options: 0x%x, " 9897 "tdls_peer_traffic_ind_window: %d, " 9898 "tdls_peer_traffic_response_timeout: %d, " 9899 "tdls_puapsd_mask: 0x%x, " 9900 "tdls_puapsd_inactivity_time: %d, " 9901 "tdls_puapsd_rx_frame_threshold: %d, " 9902 "teardown_notification_ms: %d, " 9903 "tdls_peer_kickout_threshold: %d", 9904 __func__, tdls_state, cmd->state, 9905 cmd->notification_interval_ms, 9906 cmd->tx_discovery_threshold, 9907 cmd->tx_teardown_threshold, 9908 cmd->rssi_teardown_threshold, 9909 cmd->rssi_delta, 9910 cmd->tdls_options, 9911 cmd->tdls_peer_traffic_ind_window, 9912 cmd->tdls_peer_traffic_response_timeout_ms, 9913 cmd->tdls_puapsd_mask, 9914 cmd->tdls_puapsd_inactivity_time_ms, 9915 cmd->tdls_puapsd_rx_frame_threshold, 9916 cmd->teardown_notification_ms, 9917 cmd->tdls_peer_kickout_threshold); 9918 9919 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9920 WMI_TDLS_SET_STATE_CMDID)) { 9921 WMI_LOGP("%s: failed to send tdls set state command", __func__); 9922 wmi_buf_free(wmi_buf); 9923 return QDF_STATUS_E_FAILURE; 9924 } 9925 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 9926 9927 return QDF_STATUS_SUCCESS; 9928 } 9929 9930 /** 9931 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 9932 * @wmi_handle: wmi handle 9933 * @peerStateParams: TDLS peer state params 9934 * 9935 * Return: QDF_STATUS_SUCCESS for success or error code 9936 */ 9937 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 9938 struct tdls_peer_state_params *peerStateParams, 9939 uint32_t *ch_mhz) 9940 { 9941 wmi_tdls_peer_update_cmd_fixed_param *cmd; 9942 wmi_tdls_peer_capabilities *peer_cap; 9943 wmi_channel *chan_info; 9944 wmi_buf_t wmi_buf; 9945 uint8_t *buf_ptr; 9946 uint32_t i; 9947 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 9948 sizeof(wmi_tdls_peer_capabilities); 9949 9950 9951 len += WMI_TLV_HDR_SIZE + 9952 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 9953 9954 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9955 if (!wmi_buf) { 9956 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9957 return QDF_STATUS_E_FAILURE; 9958 } 9959 9960 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 9961 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 9962 WMITLV_SET_HDR(&cmd->tlv_header, 9963 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 9964 WMITLV_GET_STRUCT_TLVLEN 9965 (wmi_tdls_peer_update_cmd_fixed_param)); 9966 9967 cmd->vdev_id = peerStateParams->vdevId; 9968 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 9969 &cmd->peer_macaddr); 9970 9971 9972 cmd->peer_state = peerStateParams->peerState; 9973 9974 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 9975 "peer_macaddr.mac_addr31to0: 0x%x, " 9976 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 9977 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 9978 cmd->peer_macaddr.mac_addr31to0, 9979 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 9980 9981 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 9982 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 9983 WMITLV_SET_HDR(&peer_cap->tlv_header, 9984 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 9985 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 9986 9987 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 9988 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 9989 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 9990 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 9991 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 9992 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 9993 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 9994 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 9995 9996 /* Ack and More Data Ack are sent as 0, so no need to set 9997 * but fill SP 9998 */ 9999 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10000 peerStateParams->peerCap.peerMaxSp); 10001 10002 peer_cap->buff_sta_support = 10003 peerStateParams->peerCap.peerBuffStaSupport; 10004 peer_cap->off_chan_support = 10005 peerStateParams->peerCap.peerOffChanSupport; 10006 peer_cap->peer_curr_operclass = 10007 peerStateParams->peerCap.peerCurrOperClass; 10008 /* self curr operclass is not being used and so pass op class for 10009 * preferred off chan in it. 10010 */ 10011 peer_cap->self_curr_operclass = 10012 peerStateParams->peerCap.opClassForPrefOffChan; 10013 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10014 peer_cap->peer_operclass_len = 10015 peerStateParams->peerCap.peerOperClassLen; 10016 10017 WMI_LOGD("%s: peer_operclass_len: %d", 10018 __func__, peer_cap->peer_operclass_len); 10019 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10020 peer_cap->peer_operclass[i] = 10021 peerStateParams->peerCap.peerOperClass[i]; 10022 WMI_LOGD("%s: peer_operclass[%d]: %d", 10023 __func__, i, peer_cap->peer_operclass[i]); 10024 } 10025 10026 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10027 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10028 peer_cap->pref_offchan_bw = 10029 peerStateParams->peerCap.prefOffChanBandwidth; 10030 10031 WMI_LOGD 10032 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10033 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10034 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10035 " %d, pref_offchan_bw: %d", 10036 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10037 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10038 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10039 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10040 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10041 10042 /* next fill variable size array of peer chan info */ 10043 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10044 WMITLV_SET_HDR(buf_ptr, 10045 WMITLV_TAG_ARRAY_STRUC, 10046 sizeof(wmi_channel) * 10047 peerStateParams->peerCap.peerChanLen); 10048 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10049 10050 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10051 WMITLV_SET_HDR(&chan_info->tlv_header, 10052 WMITLV_TAG_STRUC_wmi_channel, 10053 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10054 chan_info->mhz = ch_mhz[i]; 10055 chan_info->band_center_freq1 = chan_info->mhz; 10056 chan_info->band_center_freq2 = 0; 10057 10058 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10059 10060 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10061 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10062 WMI_LOGI("chan[%d] DFS[%d]\n", 10063 peerStateParams->peerCap.peerChan[i].chanId, 10064 peerStateParams->peerCap.peerChan[i].dfsSet); 10065 } 10066 10067 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10068 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10069 else 10070 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10071 10072 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10073 peerStateParams->peerCap. 10074 peerChan[i].pwr); 10075 10076 WMI_SET_CHANNEL_REG_POWER(chan_info, 10077 peerStateParams->peerCap.peerChan[i]. 10078 pwr); 10079 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10080 peerStateParams->peerCap.peerChan[i].pwr); 10081 10082 chan_info++; 10083 } 10084 10085 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10086 WMI_TDLS_PEER_UPDATE_CMDID)) { 10087 WMI_LOGE("%s: failed to send tdls peer update state command", 10088 __func__); 10089 wmi_buf_free(wmi_buf); 10090 return QDF_STATUS_E_FAILURE; 10091 } 10092 10093 10094 return QDF_STATUS_SUCCESS; 10095 } 10096 10097 /* 10098 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 10099 * @wmi_handle: Pointer to WMi handle 10100 * @ie_data: Pointer for ie data 10101 * 10102 * This function sends IE information to firmware 10103 * 10104 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10105 * 10106 */ 10107 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 10108 struct vdev_ie_info_param *ie_info) 10109 { 10110 wmi_vdev_set_ie_cmd_fixed_param *cmd; 10111 wmi_buf_t buf; 10112 uint8_t *buf_ptr; 10113 uint32_t len, ie_len_aligned; 10114 QDF_STATUS ret; 10115 10116 10117 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 10118 /* Allocate memory for the WMI command */ 10119 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 10120 10121 buf = wmi_buf_alloc(wmi_handle, len); 10122 if (!buf) { 10123 WMI_LOGE(FL("wmi_buf_alloc failed")); 10124 return QDF_STATUS_E_NOMEM; 10125 } 10126 10127 buf_ptr = wmi_buf_data(buf); 10128 qdf_mem_zero(buf_ptr, len); 10129 10130 /* Populate the WMI command */ 10131 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 10132 10133 WMITLV_SET_HDR(&cmd->tlv_header, 10134 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 10135 WMITLV_GET_STRUCT_TLVLEN( 10136 wmi_vdev_set_ie_cmd_fixed_param)); 10137 cmd->vdev_id = ie_info->vdev_id; 10138 cmd->ie_id = ie_info->ie_id; 10139 cmd->ie_len = ie_info->length; 10140 cmd->band = ie_info->band; 10141 10142 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 10143 ie_info->length, ie_info->vdev_id); 10144 10145 buf_ptr += sizeof(*cmd); 10146 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 10147 buf_ptr += WMI_TLV_HDR_SIZE; 10148 10149 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 10150 10151 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10152 WMI_VDEV_SET_IE_CMDID); 10153 if (QDF_IS_STATUS_ERROR(ret)) { 10154 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 10155 wmi_buf_free(buf); 10156 } 10157 10158 return ret; 10159 } 10160 10161 /** 10162 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 10163 * 10164 * @param wmi_handle : handle to WMI. 10165 * @param param : pointer to antenna param 10166 * 10167 * This function sends smart antenna enable command to FW 10168 * 10169 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10170 */ 10171 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 10172 struct smart_ant_enable_params *param) 10173 { 10174 /* Send WMI COMMAND to Enable */ 10175 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 10176 wmi_pdev_smart_ant_gpio_handle *gpio_param; 10177 wmi_buf_t buf; 10178 uint8_t *buf_ptr; 10179 int len = 0; 10180 QDF_STATUS ret; 10181 int loop = 0; 10182 10183 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10184 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 10185 buf = wmi_buf_alloc(wmi_handle, len); 10186 10187 if (!buf) { 10188 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10189 return QDF_STATUS_E_NOMEM; 10190 } 10191 10192 buf_ptr = wmi_buf_data(buf); 10193 qdf_mem_zero(buf_ptr, len); 10194 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 10195 10196 WMITLV_SET_HDR(&cmd->tlv_header, 10197 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 10198 WMITLV_GET_STRUCT_TLVLEN( 10199 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 10200 10201 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10202 param->pdev_id); 10203 cmd->enable = param->enable; 10204 cmd->mode = param->mode; 10205 cmd->rx_antenna = param->rx_antenna; 10206 cmd->tx_default_antenna = param->rx_antenna; 10207 10208 /* TLV indicating array of structures to follow */ 10209 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 10210 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10211 WMI_HAL_MAX_SANTENNA * 10212 sizeof(wmi_pdev_smart_ant_gpio_handle)); 10213 10214 buf_ptr += WMI_TLV_HDR_SIZE; 10215 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 10216 10217 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 10218 WMITLV_SET_HDR(&gpio_param->tlv_header, 10219 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 10220 WMITLV_GET_STRUCT_TLVLEN( 10221 wmi_pdev_smart_ant_gpio_handle)); 10222 if (param->mode == SMART_ANT_MODE_SERIAL) { 10223 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 10224 gpio_param->gpio_pin = param->gpio_pin[loop]; 10225 gpio_param->gpio_func = param->gpio_func[loop]; 10226 } else { 10227 gpio_param->gpio_pin = 0; 10228 gpio_param->gpio_func = 0; 10229 } 10230 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 10231 gpio_param->gpio_pin = param->gpio_pin[loop]; 10232 gpio_param->gpio_func = param->gpio_func[loop]; 10233 } 10234 /* Setting it to 0 for now */ 10235 gpio_param->pdev_id = 10236 wmi_handle->ops->convert_pdev_id_host_to_target( 10237 param->pdev_id); 10238 gpio_param++; 10239 } 10240 10241 ret = wmi_unified_cmd_send(wmi_handle, 10242 buf, 10243 len, 10244 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 10245 10246 if (ret != 0) { 10247 WMI_LOGE(" %s :WMI Failed\n", __func__); 10248 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 10249 cmd->enable, 10250 cmd->mode, 10251 cmd->rx_antenna, 10252 param->gpio_pin[0], param->gpio_pin[1], 10253 param->gpio_pin[2], param->gpio_pin[3], 10254 param->gpio_func[0], param->gpio_func[1], 10255 param->gpio_func[2], param->gpio_func[3], 10256 ret); 10257 wmi_buf_free(buf); 10258 } 10259 10260 return ret; 10261 } 10262 10263 /** 10264 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 10265 * 10266 * @param wmi_handle : handle to WMI. 10267 * @param param : pointer to rx antenna param 10268 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10269 */ 10270 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 10271 struct smart_ant_rx_ant_params *param) 10272 { 10273 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 10274 wmi_buf_t buf; 10275 uint8_t *buf_ptr; 10276 uint32_t len; 10277 QDF_STATUS ret; 10278 10279 len = sizeof(*cmd); 10280 buf = wmi_buf_alloc(wmi_handle, len); 10281 WMI_LOGD("%s:\n", __func__); 10282 if (!buf) { 10283 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10284 return QDF_STATUS_E_NOMEM; 10285 } 10286 10287 buf_ptr = wmi_buf_data(buf); 10288 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 10289 WMITLV_SET_HDR(&cmd->tlv_header, 10290 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 10291 WMITLV_GET_STRUCT_TLVLEN( 10292 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 10293 cmd->rx_antenna = param->antenna; 10294 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10295 param->pdev_id); 10296 10297 ret = wmi_unified_cmd_send(wmi_handle, 10298 buf, 10299 len, 10300 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 10301 10302 if (ret != 0) { 10303 WMI_LOGE(" %s :WMI Failed\n", __func__); 10304 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 10305 __func__, 10306 cmd->rx_antenna, 10307 ret); 10308 wmi_buf_free(buf); 10309 } 10310 10311 return ret; 10312 } 10313 10314 /** 10315 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 10316 * @wmi_handle: wmi handle 10317 * @param: pointer to hold ctl table param 10318 * 10319 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10320 */ 10321 static QDF_STATUS 10322 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 10323 struct ctl_table_params *param) 10324 { 10325 uint16_t len, ctl_tlv_len; 10326 uint8_t *buf_ptr; 10327 wmi_buf_t buf; 10328 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 10329 uint32_t *ctl_array; 10330 10331 if (!param->ctl_array) 10332 return QDF_STATUS_E_FAILURE; 10333 10334 ctl_tlv_len = WMI_TLV_HDR_SIZE + 10335 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 10336 len = sizeof(*cmd) + ctl_tlv_len; 10337 10338 buf = wmi_buf_alloc(wmi_handle, len); 10339 if (!buf) { 10340 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10341 return QDF_STATUS_E_FAILURE; 10342 } 10343 10344 buf_ptr = wmi_buf_data(buf); 10345 qdf_mem_zero(buf_ptr, len); 10346 10347 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 10348 10349 WMITLV_SET_HDR(&cmd->tlv_header, 10350 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 10351 WMITLV_GET_STRUCT_TLVLEN( 10352 wmi_pdev_set_ctl_table_cmd_fixed_param)); 10353 cmd->ctl_len = param->ctl_cmd_len; 10354 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10355 param->pdev_id); 10356 10357 buf_ptr += sizeof(*cmd); 10358 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10359 (cmd->ctl_len)); 10360 buf_ptr += WMI_TLV_HDR_SIZE; 10361 ctl_array = (uint32_t *)buf_ptr; 10362 10363 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 10364 sizeof(param->ctl_band)); 10365 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 10366 param->ctl_cmd_len - 10367 sizeof(param->ctl_band)); 10368 10369 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10370 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 10371 WMI_LOGE("%s:Failed to send command\n", __func__); 10372 wmi_buf_free(buf); 10373 return QDF_STATUS_E_FAILURE; 10374 } 10375 10376 return QDF_STATUS_SUCCESS; 10377 } 10378 10379 /** 10380 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 10381 * @wmi_handle: wmi handle 10382 * @param: pointer to hold mimogain table param 10383 * 10384 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10385 */ 10386 static QDF_STATUS 10387 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 10388 struct mimogain_table_params *param) 10389 { 10390 uint16_t len, table_tlv_len; 10391 wmi_buf_t buf; 10392 uint8_t *buf_ptr; 10393 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 10394 uint32_t *gain_table; 10395 10396 if (!param->array_gain) 10397 return QDF_STATUS_E_FAILURE; 10398 10399 /* len must be multiple of a single array gain table */ 10400 if (param->tbl_len % 10401 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 10402 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 10403 WMI_LOGE("Array gain table len not correct\n"); 10404 return QDF_STATUS_E_FAILURE; 10405 } 10406 10407 table_tlv_len = WMI_TLV_HDR_SIZE + 10408 roundup(param->tbl_len, sizeof(uint32_t)); 10409 len = sizeof(*cmd) + table_tlv_len; 10410 10411 buf = wmi_buf_alloc(wmi_handle, len); 10412 if (!buf) { 10413 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10414 return QDF_STATUS_E_FAILURE; 10415 } 10416 10417 buf_ptr = wmi_buf_data(buf); 10418 qdf_mem_zero(buf_ptr, len); 10419 10420 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 10421 10422 WMITLV_SET_HDR(&cmd->tlv_header, 10423 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 10424 WMITLV_GET_STRUCT_TLVLEN( 10425 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 10426 10427 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10428 param->pdev_id); 10429 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 10430 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 10431 param->multichain_gain_bypass); 10432 10433 buf_ptr += sizeof(*cmd); 10434 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10435 (param->tbl_len)); 10436 buf_ptr += WMI_TLV_HDR_SIZE; 10437 gain_table = (uint32_t *)buf_ptr; 10438 10439 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 10440 param->array_gain, 10441 param->tbl_len); 10442 10443 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10444 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 10445 return QDF_STATUS_E_FAILURE; 10446 } 10447 10448 return QDF_STATUS_SUCCESS; 10449 } 10450 10451 /** 10452 * enum packet_power_tlv_flags: target defined 10453 * packet power rate flags for TLV 10454 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 10455 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 10456 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 10457 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 10458 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 10459 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 10460 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 10461 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 10462 * @WMI_TLV_FLAG_STBC: STBC is set 10463 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 10464 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 10465 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 10466 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 10467 * @WMI_TLV_FLAG_RTSENA: RTS enabled 10468 * @WMI_TLV_FLAG_CTSENA: CTS enabled 10469 * @WMI_TLV_FLAG_LDPC: LDPC is set 10470 * @WMI_TLV_FLAG_SGI: Short gaurd interval 10471 * @WMI_TLV_FLAG_SU: SU Data 10472 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 10473 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 10474 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 10475 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 10476 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 10477 * 10478 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 10479 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 10480 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 10481 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 10482 */ 10483 enum packet_power_tlv_flags { 10484 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 10485 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 10486 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 10487 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 10488 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 10489 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 10490 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 10491 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 10492 WMI_TLV_FLAG_STBC = 0x00000100, 10493 WMI_TLV_FLAG_40MHZ = 0x00000200, 10494 WMI_TLV_FLAG_80MHZ = 0x00000300, 10495 WMI_TLV_FLAG_160MHZ = 0x00000400, 10496 WMI_TLV_FLAG_TXBF = 0x00000800, 10497 WMI_TLV_FLAG_RTSENA = 0x00001000, 10498 WMI_TLV_FLAG_CTSENA = 0x00002000, 10499 WMI_TLV_FLAG_LDPC = 0x00004000, 10500 WMI_TLV_FLAG_SGI = 0x00008000, 10501 WMI_TLV_FLAG_SU = 0x00100000, 10502 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 10503 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 10504 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 10505 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 10506 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 10507 10508 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 10509 WMI_TLV_FLAG_BW_MASK = 0x3, 10510 WMI_TLV_FLAG_BW_SHIFT = 9, 10511 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 10512 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 10513 }; 10514 10515 /** 10516 * convert_to_power_info_rate_flags() - convert packet_power_info_params 10517 * to FW understandable format 10518 * @param: pointer to hold packet power info param 10519 * 10520 * @return FW understandable 32 bit rate flags 10521 */ 10522 static uint32_t 10523 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 10524 { 10525 uint32_t rateflags = 0; 10526 10527 if (param->chainmask) 10528 rateflags |= 10529 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 10530 if (param->chan_width) 10531 rateflags |= 10532 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 10533 << WMI_TLV_FLAG_BW_SHIFT); 10534 if (param->su_mu_ofdma) 10535 rateflags |= 10536 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 10537 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 10538 if (param->rate_flags & WMI_HOST_FLAG_STBC) 10539 rateflags |= WMI_TLV_FLAG_STBC; 10540 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 10541 rateflags |= WMI_TLV_FLAG_LDPC; 10542 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 10543 rateflags |= WMI_TLV_FLAG_TXBF; 10544 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 10545 rateflags |= WMI_TLV_FLAG_RTSENA; 10546 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 10547 rateflags |= WMI_TLV_FLAG_CTSENA; 10548 if (param->rate_flags & WMI_HOST_FLAG_SGI) 10549 rateflags |= WMI_TLV_FLAG_SGI; 10550 10551 return rateflags; 10552 } 10553 10554 /** 10555 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 10556 * info to fw 10557 * @wmi_handle: wmi handle 10558 * @param: pointer to hold packet power info param 10559 * 10560 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10561 */ 10562 static QDF_STATUS 10563 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 10564 struct packet_power_info_params *param) 10565 { 10566 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 10567 wmi_buf_t wmibuf; 10568 uint8_t *buf_ptr; 10569 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 10570 10571 wmibuf = wmi_buf_alloc(wmi_handle, len); 10572 if (wmibuf == NULL) 10573 return QDF_STATUS_E_NOMEM; 10574 10575 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 10576 10577 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 10578 WMITLV_SET_HDR(&cmd->tlv_header, 10579 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 10580 WMITLV_GET_STRUCT_TLVLEN( 10581 wmi_pdev_get_tpc_cmd_fixed_param)); 10582 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10583 param->pdev_id); 10584 cmd->rate_flags = convert_to_power_info_rate_flags(param); 10585 cmd->nss = param->nss; 10586 cmd->preamble = param->preamble; 10587 cmd->hw_rate = param->hw_rate; 10588 10589 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 10590 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 10591 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 10592 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 10593 10594 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 10595 WMI_PDEV_GET_TPC_CMDID)) { 10596 WMI_LOGE(FL("Failed to get tpc command\n")); 10597 wmi_buf_free(wmibuf); 10598 return QDF_STATUS_E_FAILURE; 10599 } 10600 10601 return QDF_STATUS_SUCCESS; 10602 } 10603 10604 /** 10605 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 10606 * @wmi_handle: wmi handle 10607 * @param: pointer to hold config ratemask params 10608 * 10609 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10610 */ 10611 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 10612 struct config_ratemask_params *param) 10613 { 10614 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 10615 wmi_buf_t buf; 10616 int32_t len = sizeof(*cmd); 10617 10618 buf = wmi_buf_alloc(wmi_handle, len); 10619 if (!buf) { 10620 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10621 return QDF_STATUS_E_FAILURE; 10622 } 10623 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 10624 WMITLV_SET_HDR(&cmd->tlv_header, 10625 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 10626 WMITLV_GET_STRUCT_TLVLEN( 10627 wmi_vdev_config_ratemask_cmd_fixed_param)); 10628 cmd->vdev_id = param->vdev_id; 10629 cmd->type = param->type; 10630 cmd->mask_lower32 = param->lower32; 10631 cmd->mask_higher32 = param->higher32; 10632 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n", 10633 param->vdev_id, param->type, param->lower32, param->higher32); 10634 10635 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10636 WMI_VDEV_RATEMASK_CMDID)) { 10637 WMI_LOGE("Seting vdev ratemask failed\n"); 10638 wmi_buf_free(buf); 10639 return QDF_STATUS_E_FAILURE; 10640 } 10641 10642 return QDF_STATUS_SUCCESS; 10643 } 10644 10645 /** 10646 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 10647 * @param: param sent from the host side 10648 * @cmd: param to be sent to the fw side 10649 */ 10650 static inline void copy_custom_aggr_bitmap( 10651 struct set_custom_aggr_size_params *param, 10652 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 10653 { 10654 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 10655 param->ac); 10656 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 10657 param->aggr_type); 10658 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10659 param->tx_aggr_size_disable); 10660 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10661 param->rx_aggr_size_disable); 10662 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 10663 param->tx_ac_enable); 10664 } 10665 10666 /** 10667 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 10668 * @wmi_handle: wmi handle 10669 * @param: pointer to hold custom aggr size params 10670 * 10671 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10672 */ 10673 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 10674 wmi_unified_t wmi_handle, 10675 struct set_custom_aggr_size_params *param) 10676 { 10677 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 10678 wmi_buf_t buf; 10679 int32_t len = sizeof(*cmd); 10680 10681 buf = wmi_buf_alloc(wmi_handle, len); 10682 if (!buf) { 10683 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10684 return QDF_STATUS_E_FAILURE; 10685 } 10686 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 10687 wmi_buf_data(buf); 10688 WMITLV_SET_HDR(&cmd->tlv_header, 10689 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 10690 WMITLV_GET_STRUCT_TLVLEN( 10691 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 10692 cmd->vdev_id = param->vdev_id; 10693 cmd->tx_aggr_size = param->tx_aggr_size; 10694 cmd->rx_aggr_size = param->rx_aggr_size; 10695 copy_custom_aggr_bitmap(param, cmd); 10696 10697 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 10698 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 10699 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 10700 "tx_ac_enable=0x%X\n", 10701 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 10702 param->ac, param->aggr_type, param->tx_aggr_size_disable, 10703 param->rx_aggr_size_disable, param->tx_ac_enable); 10704 10705 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10706 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 10707 WMI_LOGE("Seting custom aggregation size failed\n"); 10708 wmi_buf_free(buf); 10709 return QDF_STATUS_E_FAILURE; 10710 } 10711 10712 return QDF_STATUS_SUCCESS; 10713 } 10714 10715 /** 10716 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 10717 * @param wmi_handle : handle to WMI. 10718 * @param param : pointer to tx antenna param 10719 * 10720 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10721 */ 10722 10723 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 10724 struct set_qdepth_thresh_params *param) 10725 { 10726 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 10727 wmi_msduq_qdepth_thresh_update *cmd_update; 10728 wmi_buf_t buf; 10729 int32_t len = 0; 10730 int i; 10731 uint8_t *buf_ptr; 10732 QDF_STATUS ret; 10733 10734 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 10735 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 10736 return QDF_STATUS_E_INVAL; 10737 } 10738 10739 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10740 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 10741 param->num_of_msduq_updates); 10742 buf = wmi_buf_alloc(wmi_handle, len); 10743 10744 if (!buf) { 10745 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10746 return QDF_STATUS_E_NOMEM; 10747 } 10748 10749 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10750 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 10751 buf_ptr; 10752 10753 WMITLV_SET_HDR(&cmd->tlv_header, 10754 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 10755 , WMITLV_GET_STRUCT_TLVLEN( 10756 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 10757 10758 cmd->pdev_id = 10759 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 10760 cmd->vdev_id = param->vdev_id; 10761 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 10762 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 10763 10764 buf_ptr += sizeof( 10765 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 10766 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10767 param->num_of_msduq_updates * 10768 sizeof(wmi_msduq_qdepth_thresh_update)); 10769 buf_ptr += WMI_TLV_HDR_SIZE; 10770 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 10771 10772 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 10773 WMITLV_SET_HDR(&cmd_update->tlv_header, 10774 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 10775 WMITLV_GET_STRUCT_TLVLEN( 10776 wmi_msduq_qdepth_thresh_update)); 10777 cmd_update->tid_num = param->update_params[i].tid_num; 10778 cmd_update->msduq_update_mask = 10779 param->update_params[i].msduq_update_mask; 10780 cmd_update->qdepth_thresh_value = 10781 param->update_params[i].qdepth_thresh_value; 10782 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 10783 "mac_addr_upper4=%X, mac_addr_lower2:%X," 10784 " update mask=0x%X thresh val=0x%X\n", 10785 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 10786 cmd->peer_mac_address.mac_addr31to0, 10787 cmd->peer_mac_address.mac_addr47to32, 10788 cmd_update->msduq_update_mask, 10789 cmd_update->qdepth_thresh_value); 10790 cmd_update++; 10791 } 10792 10793 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10794 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 10795 10796 if (ret != 0) { 10797 WMI_LOGE(" %s :WMI Failed\n", __func__); 10798 wmi_buf_free(buf); 10799 } 10800 10801 return ret; 10802 } 10803 10804 /** 10805 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 10806 * @wmi_handle: wmi handle 10807 * @param: pointer to hold vap dscp tid map param 10808 * 10809 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10810 */ 10811 static QDF_STATUS 10812 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 10813 struct vap_dscp_tid_map_params *param) 10814 { 10815 wmi_buf_t buf; 10816 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 10817 int32_t len = sizeof(*cmd); 10818 10819 buf = wmi_buf_alloc(wmi_handle, len); 10820 if (!buf) { 10821 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10822 return QDF_STATUS_E_FAILURE; 10823 } 10824 10825 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 10826 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 10827 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 10828 10829 cmd->vdev_id = param->vdev_id; 10830 cmd->enable_override = 0; 10831 10832 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 10833 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10834 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 10835 WMI_LOGE("Failed to set dscp cmd\n"); 10836 wmi_buf_free(buf); 10837 return QDF_STATUS_E_FAILURE; 10838 } 10839 10840 return QDF_STATUS_SUCCESS; 10841 } 10842 10843 /** 10844 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 10845 * @wmi_handle: wmi handle 10846 * @macaddr: vdev mac address 10847 * @param: pointer to hold neigbour rx param 10848 * 10849 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10850 */ 10851 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 10852 uint8_t macaddr[IEEE80211_ADDR_LEN], 10853 struct set_neighbour_rx_params *param) 10854 { 10855 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 10856 wmi_buf_t buf; 10857 int32_t len = sizeof(*cmd); 10858 10859 buf = wmi_buf_alloc(wmi_handle, len); 10860 if (!buf) { 10861 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10862 return QDF_STATUS_E_FAILURE; 10863 } 10864 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 10865 WMITLV_SET_HDR(&cmd->tlv_header, 10866 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 10867 WMITLV_GET_STRUCT_TLVLEN( 10868 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 10869 cmd->vdev_id = param->vdev_id; 10870 cmd->bssid_idx = param->idx; 10871 cmd->action = param->action; 10872 cmd->type = param->type; 10873 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 10874 cmd->flag = 0; 10875 10876 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10877 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 10878 WMI_LOGE("Failed to set neighbour rx param\n"); 10879 wmi_buf_free(buf); 10880 return QDF_STATUS_E_FAILURE; 10881 } 10882 10883 return QDF_STATUS_SUCCESS; 10884 } 10885 10886 /** 10887 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 10888 * @param wmi_handle : handle to WMI. 10889 * @param macaddr : vdev mac address 10890 * @param param : pointer to tx antenna param 10891 * 10892 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10893 */ 10894 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 10895 uint8_t macaddr[IEEE80211_ADDR_LEN], 10896 struct smart_ant_tx_ant_params *param) 10897 { 10898 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 10899 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 10900 wmi_buf_t buf; 10901 int32_t len = 0; 10902 int i; 10903 uint8_t *buf_ptr; 10904 QDF_STATUS ret; 10905 10906 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10907 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 10908 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 10909 buf = wmi_buf_alloc(wmi_handle, len); 10910 10911 if (!buf) { 10912 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10913 return QDF_STATUS_E_NOMEM; 10914 } 10915 10916 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10917 qdf_mem_zero(buf_ptr, len); 10918 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 10919 10920 WMITLV_SET_HDR(&cmd->tlv_header, 10921 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 10922 WMITLV_GET_STRUCT_TLVLEN( 10923 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 10924 10925 cmd->vdev_id = param->vdev_id; 10926 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10927 10928 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 10929 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10930 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 10931 buf_ptr += WMI_TLV_HDR_SIZE; 10932 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 10933 10934 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 10935 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 10936 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 10937 WMITLV_GET_STRUCT_TLVLEN( 10938 wmi_peer_smart_ant_set_tx_antenna_series)); 10939 ant_tx_series->antenna_series = param->antenna_array[i]; 10940 ant_tx_series++; 10941 } 10942 10943 ret = wmi_unified_cmd_send(wmi_handle, 10944 buf, 10945 len, 10946 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 10947 10948 if (ret != 0) { 10949 WMI_LOGE(" %s :WMI Failed\n", __func__); 10950 wmi_buf_free(buf); 10951 } 10952 10953 return ret; 10954 } 10955 10956 /** 10957 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 10958 * @wmi_handle: wmi handle 10959 * @param: pointer to hold ant switch tbl param 10960 * 10961 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10962 */ 10963 static QDF_STATUS 10964 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 10965 struct ant_switch_tbl_params *param) 10966 { 10967 uint8_t len; 10968 wmi_buf_t buf; 10969 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 10970 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 10971 uint8_t *buf_ptr; 10972 10973 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10974 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 10975 buf = wmi_buf_alloc(wmi_handle, len); 10976 10977 if (!buf) { 10978 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10979 return QDF_STATUS_E_NOMEM; 10980 } 10981 10982 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10983 qdf_mem_zero(buf_ptr, len); 10984 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 10985 10986 WMITLV_SET_HDR(&cmd->tlv_header, 10987 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 10988 WMITLV_GET_STRUCT_TLVLEN( 10989 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 10990 10991 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 10992 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 10993 cmd->mac_id = 10994 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 10995 10996 /* TLV indicating array of structures to follow */ 10997 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 10998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10999 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11000 buf_ptr += WMI_TLV_HDR_SIZE; 11001 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11002 11003 ctrl_chain->pdev_id = 11004 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11005 ctrl_chain->antCtrlChain = param->antCtrlChain; 11006 11007 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11008 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11009 wmi_buf_free(buf); 11010 return QDF_STATUS_E_FAILURE; 11011 } 11012 11013 return QDF_STATUS_SUCCESS; 11014 } 11015 11016 /** 11017 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11018 * training information function 11019 * @param wmi_handle : handle to WMI. 11020 * @macaddr : vdev mac address 11021 * @param param : pointer to tx antenna param 11022 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11023 */ 11024 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11025 wmi_unified_t wmi_handle, 11026 uint8_t macaddr[IEEE80211_ADDR_LEN], 11027 struct smart_ant_training_info_params *param) 11028 { 11029 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11030 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11031 wmi_buf_t buf; 11032 uint8_t *buf_ptr; 11033 int32_t len = 0; 11034 QDF_STATUS ret; 11035 int loop; 11036 11037 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11038 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11039 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11040 buf = wmi_buf_alloc(wmi_handle, len); 11041 11042 if (!buf) { 11043 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11044 return QDF_STATUS_E_NOMEM; 11045 } 11046 11047 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11048 qdf_mem_zero(buf_ptr, len); 11049 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11050 11051 WMITLV_SET_HDR(&cmd->tlv_header, 11052 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11053 WMITLV_GET_STRUCT_TLVLEN( 11054 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11055 11056 cmd->vdev_id = param->vdev_id; 11057 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11058 cmd->num_pkts = param->numpkts; 11059 11060 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11061 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11062 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11063 WMI_SMART_ANT_MAX_RATE_SERIES); 11064 11065 buf_ptr += WMI_TLV_HDR_SIZE; 11066 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11067 11068 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11069 WMITLV_SET_HDR(&train_param->tlv_header, 11070 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11071 WMITLV_GET_STRUCT_TLVLEN( 11072 wmi_peer_smart_ant_set_train_antenna_param)); 11073 train_param->train_rate_series = param->rate_array[loop]; 11074 train_param->train_antenna_series = param->antenna_array[loop]; 11075 train_param->rc_flags = 0; 11076 WMI_LOGI(FL("Series number:%d\n"), loop); 11077 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11078 train_param->train_rate_series, 11079 train_param->train_antenna_series); 11080 train_param++; 11081 } 11082 11083 ret = wmi_unified_cmd_send(wmi_handle, 11084 buf, 11085 len, 11086 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 11087 11088 if (ret != 0) { 11089 WMI_LOGE(" %s :WMI Failed\n", __func__); 11090 wmi_buf_free(buf); 11091 return QDF_STATUS_E_FAILURE; 11092 } 11093 11094 return ret; 11095 } 11096 11097 /** 11098 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 11099 * configuration function 11100 * @param wmi_handle : handle to WMI. 11101 * @macaddr : vdev mad address 11102 * @param param : pointer to tx antenna param 11103 * 11104 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11105 */ 11106 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 11107 wmi_unified_t wmi_handle, 11108 uint8_t macaddr[IEEE80211_ADDR_LEN], 11109 struct smart_ant_node_config_params *param) 11110 { 11111 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 11112 wmi_buf_t buf; 11113 uint8_t *buf_ptr; 11114 int32_t len = 0, args_tlv_len; 11115 int ret; 11116 int i = 0; 11117 uint32_t *node_config_args; 11118 11119 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 11120 len = sizeof(*cmd) + args_tlv_len; 11121 11122 if (param->args_count == 0) { 11123 WMI_LOGE("%s: Can't send a command with %d arguments\n", 11124 __func__, param->args_count); 11125 return QDF_STATUS_E_FAILURE; 11126 } 11127 11128 buf = wmi_buf_alloc(wmi_handle, len); 11129 if (!buf) { 11130 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11131 return QDF_STATUS_E_NOMEM; 11132 } 11133 11134 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 11135 wmi_buf_data(buf); 11136 buf_ptr = (uint8_t *)cmd; 11137 WMITLV_SET_HDR(&cmd->tlv_header, 11138 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 11139 WMITLV_GET_STRUCT_TLVLEN( 11140 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 11141 cmd->vdev_id = param->vdev_id; 11142 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11143 cmd->cmd_id = param->cmd_id; 11144 cmd->args_count = param->args_count; 11145 buf_ptr += sizeof( 11146 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 11147 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11148 (cmd->args_count * sizeof(uint32_t))); 11149 buf_ptr += WMI_TLV_HDR_SIZE; 11150 node_config_args = (uint32_t *)buf_ptr; 11151 11152 for (i = 0; i < param->args_count; i++) { 11153 node_config_args[i] = param->args_arr[i]; 11154 WMI_LOGI("%d", param->args_arr[i]); 11155 } 11156 11157 ret = wmi_unified_cmd_send(wmi_handle, 11158 buf, 11159 len, 11160 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 11161 11162 if (ret != 0) { 11163 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 11164 __func__, param->cmd_id, macaddr[0], 11165 macaddr[1], macaddr[2], macaddr[3], 11166 macaddr[4], macaddr[5], ret); 11167 wmi_buf_free(buf); 11168 } 11169 11170 return ret; 11171 } 11172 11173 /** 11174 * send_set_atf_cmd_tlv() - send set atf command to fw 11175 * @wmi_handle: wmi handle 11176 * @param: pointer to set atf param 11177 * 11178 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11179 */ 11180 static QDF_STATUS 11181 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 11182 struct set_atf_params *param) 11183 { 11184 wmi_atf_peer_info *peer_info; 11185 wmi_peer_atf_request_fixed_param *cmd; 11186 wmi_buf_t buf; 11187 uint8_t *buf_ptr; 11188 int i; 11189 int32_t len = 0; 11190 QDF_STATUS retval; 11191 11192 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11193 len += param->num_peers * sizeof(wmi_atf_peer_info); 11194 buf = wmi_buf_alloc(wmi_handle, len); 11195 if (!buf) { 11196 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11197 return QDF_STATUS_E_FAILURE; 11198 } 11199 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11200 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 11201 WMITLV_SET_HDR(&cmd->tlv_header, 11202 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 11203 WMITLV_GET_STRUCT_TLVLEN( 11204 wmi_peer_atf_request_fixed_param)); 11205 cmd->num_peers = param->num_peers; 11206 11207 buf_ptr += sizeof(*cmd); 11208 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11209 sizeof(wmi_atf_peer_info) * 11210 cmd->num_peers); 11211 buf_ptr += WMI_TLV_HDR_SIZE; 11212 peer_info = (wmi_atf_peer_info *)buf_ptr; 11213 11214 for (i = 0; i < cmd->num_peers; i++) { 11215 WMITLV_SET_HDR(&peer_info->tlv_header, 11216 WMITLV_TAG_STRUC_wmi_atf_peer_info, 11217 WMITLV_GET_STRUCT_TLVLEN( 11218 wmi_atf_peer_info)); 11219 qdf_mem_copy(&(peer_info->peer_macaddr), 11220 &(param->peer_info[i].peer_macaddr), 11221 sizeof(wmi_mac_addr)); 11222 peer_info->atf_units = param->peer_info[i].percentage_peer; 11223 peer_info->vdev_id = param->peer_info[i].vdev_id; 11224 peer_info->pdev_id = 11225 wmi_handle->ops->convert_pdev_id_host_to_target( 11226 param->peer_info[i].pdev_id); 11227 /* 11228 * TLV definition for peer atf request fixed param combines 11229 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 11230 * stats and atf extension stats as two different 11231 * implementations. 11232 * Need to discuss with FW on this. 11233 * 11234 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 11235 * peer_info->atf_units_reserved = 11236 * param->peer_ext_info[i].atf_index_reserved; 11237 */ 11238 peer_info++; 11239 } 11240 11241 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11242 WMI_PEER_ATF_REQUEST_CMDID); 11243 11244 if (retval != QDF_STATUS_SUCCESS) { 11245 WMI_LOGE("%s : WMI Failed\n", __func__); 11246 wmi_buf_free(buf); 11247 } 11248 11249 return retval; 11250 } 11251 11252 /** 11253 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 11254 * @wmi_handle: wmi handle 11255 * @param: pointer to hold fwtest param 11256 * 11257 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11258 */ 11259 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 11260 struct set_fwtest_params *param) 11261 { 11262 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11263 wmi_buf_t buf; 11264 int32_t len = sizeof(*cmd); 11265 11266 buf = wmi_buf_alloc(wmi_handle, len); 11267 11268 if (!buf) { 11269 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11270 return QDF_STATUS_E_FAILURE; 11271 } 11272 11273 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 11274 WMITLV_SET_HDR(&cmd->tlv_header, 11275 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11276 WMITLV_GET_STRUCT_TLVLEN( 11277 wmi_fwtest_set_param_cmd_fixed_param)); 11278 cmd->param_id = param->arg; 11279 cmd->param_value = param->value; 11280 11281 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 11282 WMI_LOGE("Setting FW test param failed\n"); 11283 wmi_buf_free(buf); 11284 return QDF_STATUS_E_FAILURE; 11285 } 11286 11287 return QDF_STATUS_SUCCESS; 11288 } 11289 11290 /** 11291 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 11292 * @wmi_handle: wmi handle 11293 * @param: pointer to qboost params 11294 * @macaddr: vdev mac address 11295 * 11296 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11297 */ 11298 static QDF_STATUS 11299 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 11300 uint8_t macaddr[IEEE80211_ADDR_LEN], 11301 struct set_qboost_params *param) 11302 { 11303 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 11304 wmi_buf_t buf; 11305 int32_t len; 11306 QDF_STATUS ret; 11307 11308 len = sizeof(*cmd); 11309 11310 buf = wmi_buf_alloc(wmi_handle, len); 11311 if (!buf) { 11312 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11313 return QDF_STATUS_E_FAILURE; 11314 } 11315 11316 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 11317 WMITLV_SET_HDR(&cmd->tlv_header, 11318 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 11319 WMITLV_GET_STRUCT_TLVLEN( 11320 WMI_QBOOST_CFG_CMD_fixed_param)); 11321 cmd->vdev_id = param->vdev_id; 11322 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11323 cmd->qb_enable = param->value; 11324 11325 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11326 WMI_QBOOST_CFG_CMDID); 11327 11328 if (ret != 0) { 11329 WMI_LOGE("Setting qboost cmd failed\n"); 11330 wmi_buf_free(buf); 11331 } 11332 11333 return ret; 11334 } 11335 11336 /** 11337 * send_gpio_config_cmd_tlv() - send gpio config to fw 11338 * @wmi_handle: wmi handle 11339 * @param: pointer to hold gpio config param 11340 * 11341 * Return: 0 for success or error code 11342 */ 11343 static QDF_STATUS 11344 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 11345 struct gpio_config_params *param) 11346 { 11347 wmi_gpio_config_cmd_fixed_param *cmd; 11348 wmi_buf_t buf; 11349 int32_t len; 11350 QDF_STATUS ret; 11351 11352 len = sizeof(*cmd); 11353 11354 /* Sanity Checks */ 11355 if (param->pull_type > WMI_GPIO_PULL_DOWN || 11356 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 11357 return QDF_STATUS_E_FAILURE; 11358 } 11359 11360 buf = wmi_buf_alloc(wmi_handle, len); 11361 if (!buf) { 11362 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11363 return QDF_STATUS_E_FAILURE; 11364 } 11365 11366 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 11367 WMITLV_SET_HDR(&cmd->tlv_header, 11368 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 11369 WMITLV_GET_STRUCT_TLVLEN( 11370 wmi_gpio_config_cmd_fixed_param)); 11371 cmd->gpio_num = param->gpio_num; 11372 cmd->input = param->input; 11373 cmd->pull_type = param->pull_type; 11374 cmd->intr_mode = param->intr_mode; 11375 11376 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11377 WMI_GPIO_CONFIG_CMDID); 11378 11379 if (ret != 0) { 11380 WMI_LOGE("Sending GPIO config cmd failed\n"); 11381 wmi_buf_free(buf); 11382 } 11383 11384 return ret; 11385 } 11386 11387 /** 11388 * send_gpio_output_cmd_tlv() - send gpio output to fw 11389 * @wmi_handle: wmi handle 11390 * @param: pointer to hold gpio output param 11391 * 11392 * Return: 0 for success or error code 11393 */ 11394 static QDF_STATUS 11395 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 11396 struct gpio_output_params *param) 11397 { 11398 wmi_gpio_output_cmd_fixed_param *cmd; 11399 wmi_buf_t buf; 11400 int32_t len; 11401 QDF_STATUS ret; 11402 11403 len = sizeof(*cmd); 11404 11405 buf = wmi_buf_alloc(wmi_handle, len); 11406 if (!buf) { 11407 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11408 return QDF_STATUS_E_FAILURE; 11409 } 11410 11411 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 11412 WMITLV_SET_HDR(&cmd->tlv_header, 11413 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 11414 WMITLV_GET_STRUCT_TLVLEN( 11415 wmi_gpio_output_cmd_fixed_param)); 11416 cmd->gpio_num = param->gpio_num; 11417 cmd->set = param->set; 11418 11419 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11420 WMI_GPIO_OUTPUT_CMDID); 11421 11422 if (ret != 0) { 11423 WMI_LOGE("Sending GPIO output cmd failed\n"); 11424 wmi_buf_free(buf); 11425 } 11426 11427 return ret; 11428 11429 } 11430 11431 /** 11432 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 11433 * 11434 * @param wmi_handle : handle to WMI. 11435 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11436 */ 11437 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 11438 { 11439 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 11440 wmi_buf_t buf; 11441 QDF_STATUS ret; 11442 int32_t len; 11443 11444 len = sizeof(*cmd); 11445 11446 buf = wmi_buf_alloc(wmi_handle, len); 11447 if (!buf) { 11448 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11449 return QDF_STATUS_E_FAILURE; 11450 } 11451 11452 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 11453 WMITLV_SET_HDR(&cmd->tlv_header, 11454 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 11455 WMITLV_GET_STRUCT_TLVLEN( 11456 wmi_pdev_dfs_disable_cmd_fixed_param)); 11457 /* Filling it with WMI_PDEV_ID_SOC for now */ 11458 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11459 WMI_HOST_PDEV_ID_SOC); 11460 11461 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11462 WMI_PDEV_DFS_DISABLE_CMDID); 11463 11464 if (ret != 0) { 11465 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 11466 wmi_buf_free(buf); 11467 } 11468 11469 return ret; 11470 } 11471 11472 /** 11473 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 11474 * 11475 * @param wmi_handle : handle to WMI. 11476 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11477 */ 11478 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 11479 { 11480 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 11481 wmi_buf_t buf; 11482 QDF_STATUS ret; 11483 int32_t len; 11484 11485 len = sizeof(*cmd); 11486 11487 buf = wmi_buf_alloc(wmi_handle, len); 11488 if (!buf) { 11489 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11490 return QDF_STATUS_E_FAILURE; 11491 } 11492 11493 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 11494 WMITLV_SET_HDR(&cmd->tlv_header, 11495 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 11496 WMITLV_GET_STRUCT_TLVLEN( 11497 wmi_pdev_dfs_enable_cmd_fixed_param)); 11498 /* Reserved for future use */ 11499 cmd->reserved0 = 0; 11500 11501 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11502 WMI_PDEV_DFS_ENABLE_CMDID); 11503 11504 if (ret != 0) { 11505 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 11506 wmi_buf_free(buf); 11507 } 11508 11509 return ret; 11510 } 11511 11512 /** 11513 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 11514 * to fw 11515 * @wmi_handle: wmi handle 11516 * @param: pointer to hold periodic chan stats param 11517 * 11518 * Return: 0 for success or error code 11519 */ 11520 static QDF_STATUS 11521 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 11522 struct periodic_chan_stats_params *param) 11523 { 11524 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 11525 wmi_buf_t buf; 11526 QDF_STATUS ret; 11527 int32_t len; 11528 11529 len = sizeof(*cmd); 11530 11531 buf = wmi_buf_alloc(wmi_handle, len); 11532 if (!buf) { 11533 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11534 return QDF_STATUS_E_FAILURE; 11535 } 11536 11537 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 11538 wmi_buf_data(buf); 11539 WMITLV_SET_HDR(&cmd->tlv_header, 11540 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 11541 WMITLV_GET_STRUCT_TLVLEN( 11542 wmi_set_periodic_channel_stats_config_fixed_param)); 11543 cmd->enable = param->enable; 11544 cmd->stats_period = param->stats_period; 11545 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11546 param->pdev_id); 11547 11548 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11549 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 11550 11551 if (ret != 0) { 11552 WMI_LOGE("Sending periodic chan stats config failed"); 11553 wmi_buf_free(buf); 11554 } 11555 11556 return ret; 11557 } 11558 11559 /** 11560 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 11561 * @wmi_handle: wmi handle 11562 * @mac_id: radio context 11563 * 11564 * Return: 0 for success or error code 11565 */ 11566 static QDF_STATUS 11567 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 11568 { 11569 wmi_buf_t buf; 11570 QDF_STATUS ret; 11571 wmi_pdev_get_nfcal_power_fixed_param *cmd; 11572 int32_t len = sizeof(*cmd); 11573 11574 buf = wmi_buf_alloc(wmi_handle, len); 11575 if (buf == NULL) 11576 return QDF_STATUS_E_NOMEM; 11577 11578 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 11579 WMITLV_SET_HDR(&cmd->tlv_header, 11580 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 11581 WMITLV_GET_STRUCT_TLVLEN 11582 (wmi_pdev_get_nfcal_power_fixed_param)); 11583 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 11584 11585 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11586 WMI_PDEV_GET_NFCAL_POWER_CMDID); 11587 if (ret != 0) { 11588 WMI_LOGE("Sending get nfcal power cmd failed\n"); 11589 wmi_buf_free(buf); 11590 } 11591 11592 return ret; 11593 } 11594 11595 /** 11596 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 11597 * @wmi_handle: wmi handle 11598 * @param: pointer to ht ie param 11599 * 11600 * Return: 0 for success or error code 11601 */ 11602 static QDF_STATUS 11603 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11604 struct ht_ie_params *param) 11605 { 11606 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 11607 wmi_buf_t buf; 11608 QDF_STATUS ret; 11609 int32_t len; 11610 uint8_t *buf_ptr; 11611 11612 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11613 roundup(param->ie_len, sizeof(uint32_t)); 11614 11615 buf = wmi_buf_alloc(wmi_handle, len); 11616 if (!buf) { 11617 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11618 return QDF_STATUS_E_FAILURE; 11619 } 11620 11621 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11622 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 11623 WMITLV_SET_HDR(&cmd->tlv_header, 11624 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 11625 WMITLV_GET_STRUCT_TLVLEN( 11626 wmi_pdev_set_ht_ie_cmd_fixed_param)); 11627 cmd->reserved0 = 0; 11628 cmd->ie_len = param->ie_len; 11629 cmd->tx_streams = param->tx_streams; 11630 cmd->rx_streams = param->rx_streams; 11631 11632 buf_ptr += sizeof(*cmd); 11633 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11634 buf_ptr += WMI_TLV_HDR_SIZE; 11635 if (param->ie_len) 11636 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11637 cmd->ie_len); 11638 11639 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11640 WMI_PDEV_SET_HT_CAP_IE_CMDID); 11641 11642 if (ret != 0) { 11643 WMI_LOGE("Sending set ht ie cmd failed\n"); 11644 wmi_buf_free(buf); 11645 } 11646 11647 return ret; 11648 } 11649 11650 /** 11651 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 11652 * @wmi_handle: wmi handle 11653 * @param: pointer to vht ie param 11654 * 11655 * Return: 0 for success or error code 11656 */ 11657 static QDF_STATUS 11658 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11659 struct vht_ie_params *param) 11660 { 11661 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 11662 wmi_buf_t buf; 11663 QDF_STATUS ret; 11664 int32_t len; 11665 uint8_t *buf_ptr; 11666 11667 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11668 roundup(param->ie_len, sizeof(uint32_t)); 11669 11670 buf = wmi_buf_alloc(wmi_handle, len); 11671 if (!buf) { 11672 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11673 return QDF_STATUS_E_FAILURE; 11674 } 11675 11676 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11677 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 11678 WMITLV_SET_HDR(&cmd->tlv_header, 11679 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 11680 WMITLV_GET_STRUCT_TLVLEN( 11681 wmi_pdev_set_vht_ie_cmd_fixed_param)); 11682 cmd->reserved0 = 0; 11683 cmd->ie_len = param->ie_len; 11684 cmd->tx_streams = param->tx_streams; 11685 cmd->rx_streams = param->rx_streams; 11686 11687 buf_ptr += sizeof(*cmd); 11688 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11689 buf_ptr += WMI_TLV_HDR_SIZE; 11690 if (param->ie_len) 11691 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11692 cmd->ie_len); 11693 11694 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11695 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 11696 11697 if (ret != 0) { 11698 WMI_LOGE("Sending set vht ie cmd failed\n"); 11699 wmi_buf_free(buf); 11700 } 11701 11702 return ret; 11703 } 11704 11705 /** 11706 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 11707 * @wmi_handle: wmi handle 11708 * @param: pointer to quiet mode params 11709 * 11710 * Return: 0 for success or error code 11711 */ 11712 static QDF_STATUS 11713 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 11714 struct set_quiet_mode_params *param) 11715 { 11716 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 11717 wmi_buf_t buf; 11718 QDF_STATUS ret; 11719 int32_t len; 11720 11721 len = sizeof(*quiet_cmd); 11722 buf = wmi_buf_alloc(wmi_handle, len); 11723 if (!buf) { 11724 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11725 return QDF_STATUS_E_FAILURE; 11726 } 11727 11728 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11729 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 11730 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 11731 WMITLV_GET_STRUCT_TLVLEN( 11732 wmi_pdev_set_quiet_cmd_fixed_param)); 11733 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11734 quiet_cmd->enabled = param->enabled; 11735 quiet_cmd->period = (param->period)*(param->intval); 11736 quiet_cmd->duration = param->duration; 11737 quiet_cmd->next_start = param->offset; 11738 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11739 WMI_HOST_PDEV_ID_SOC); 11740 11741 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11742 WMI_PDEV_SET_QUIET_MODE_CMDID); 11743 11744 if (ret != 0) { 11745 WMI_LOGE("Sending set quiet cmd failed\n"); 11746 wmi_buf_free(buf); 11747 } 11748 11749 return ret; 11750 } 11751 11752 /** 11753 * send_set_bwf_cmd_tlv() - send set bwf command to fw 11754 * @wmi_handle: wmi handle 11755 * @param: pointer to set bwf param 11756 * 11757 * Return: 0 for success or error code 11758 */ 11759 static QDF_STATUS 11760 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 11761 struct set_bwf_params *param) 11762 { 11763 wmi_bwf_peer_info *peer_info; 11764 wmi_peer_bwf_request_fixed_param *cmd; 11765 wmi_buf_t buf; 11766 QDF_STATUS retval; 11767 int32_t len; 11768 uint8_t *buf_ptr; 11769 int i; 11770 11771 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11772 len += param->num_peers * sizeof(wmi_bwf_peer_info); 11773 buf = wmi_buf_alloc(wmi_handle, len); 11774 if (!buf) { 11775 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11776 return QDF_STATUS_E_FAILURE; 11777 } 11778 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11779 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 11780 WMITLV_SET_HDR(&cmd->tlv_header, 11781 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 11782 WMITLV_GET_STRUCT_TLVLEN( 11783 wmi_peer_bwf_request_fixed_param)); 11784 cmd->num_peers = param->num_peers; 11785 11786 buf_ptr += sizeof(*cmd); 11787 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11788 sizeof(wmi_bwf_peer_info) * 11789 cmd->num_peers); 11790 buf_ptr += WMI_TLV_HDR_SIZE; 11791 peer_info = (wmi_bwf_peer_info *)buf_ptr; 11792 11793 for (i = 0; i < cmd->num_peers; i++) { 11794 WMITLV_SET_HDR(&peer_info->tlv_header, 11795 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 11796 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 11797 peer_info->bwf_guaranteed_bandwidth = 11798 param->peer_info[i].throughput; 11799 peer_info->bwf_max_airtime = 11800 param->peer_info[i].max_airtime; 11801 peer_info->bwf_peer_priority = 11802 param->peer_info[i].priority; 11803 qdf_mem_copy(&peer_info->peer_macaddr, 11804 ¶m->peer_info[i].peer_macaddr, 11805 sizeof(param->peer_info[i].peer_macaddr)); 11806 peer_info->vdev_id = 11807 param->peer_info[i].vdev_id; 11808 peer_info->pdev_id = 11809 wmi_handle->ops->convert_pdev_id_host_to_target( 11810 param->peer_info[i].pdev_id); 11811 peer_info++; 11812 } 11813 11814 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11815 WMI_PEER_BWF_REQUEST_CMDID); 11816 11817 if (retval != QDF_STATUS_SUCCESS) { 11818 WMI_LOGE("%s : WMI Failed\n", __func__); 11819 wmi_buf_free(buf); 11820 } 11821 11822 return retval; 11823 } 11824 11825 /** 11826 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 11827 * @wmi_handle: wmi handle 11828 * @param: pointer to hold mcast update param 11829 * 11830 * Return: 0 for success or error code 11831 */ 11832 static QDF_STATUS 11833 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 11834 struct mcast_group_update_params *param) 11835 { 11836 wmi_peer_mcast_group_cmd_fixed_param *cmd; 11837 wmi_buf_t buf; 11838 QDF_STATUS ret; 11839 int32_t len; 11840 int offset = 0; 11841 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 11842 11843 len = sizeof(*cmd); 11844 buf = wmi_buf_alloc(wmi_handle, len); 11845 if (!buf) { 11846 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11847 return QDF_STATUS_E_FAILURE; 11848 } 11849 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 11850 WMITLV_SET_HDR(&cmd->tlv_header, 11851 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 11852 WMITLV_GET_STRUCT_TLVLEN( 11853 wmi_peer_mcast_group_cmd_fixed_param)); 11854 /* confirm the buffer is 4-byte aligned */ 11855 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 11856 qdf_mem_zero(cmd, sizeof(*cmd)); 11857 11858 cmd->vdev_id = param->vap_id; 11859 /* construct the message assuming our endianness matches the target */ 11860 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 11861 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 11862 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 11863 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 11864 if (param->is_action_delete) 11865 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 11866 11867 if (param->is_mcast_addr_len) 11868 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 11869 11870 if (param->is_filter_mode_snoop) 11871 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 11872 11873 /* unicast address spec only applies for non-wildcard cases */ 11874 if (!param->wildcard && param->ucast_mac_addr) { 11875 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 11876 &cmd->ucast_mac_addr); 11877 } 11878 11879 if (param->mcast_ip_addr) { 11880 QDF_ASSERT(param->mcast_ip_addr_bytes <= 11881 sizeof(cmd->mcast_ip_addr)); 11882 offset = sizeof(cmd->mcast_ip_addr) - 11883 param->mcast_ip_addr_bytes; 11884 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 11885 param->mcast_ip_addr, 11886 param->mcast_ip_addr_bytes); 11887 } 11888 if (!param->mask) 11889 param->mask = &dummymask[0]; 11890 11891 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 11892 param->mask, 11893 param->mcast_ip_addr_bytes); 11894 11895 if (param->srcs && param->nsrcs) { 11896 cmd->num_filter_addr = param->nsrcs; 11897 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 11898 sizeof(cmd->filter_addr)); 11899 11900 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 11901 param->nsrcs * param->mcast_ip_addr_bytes); 11902 } 11903 11904 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11905 WMI_PEER_MCAST_GROUP_CMDID); 11906 11907 if (ret != QDF_STATUS_SUCCESS) { 11908 WMI_LOGE("%s : WMI Failed\n", __func__); 11909 wmi_buf_free(buf); 11910 } 11911 11912 return ret; 11913 } 11914 11915 /** 11916 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 11917 * command to fw 11918 * @wmi_handle: wmi handle 11919 * @param: pointer to hold spectral config parameter 11920 * 11921 * Return: 0 for success or error code 11922 */ 11923 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 11924 struct vdev_spectral_configure_params *param) 11925 { 11926 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 11927 wmi_buf_t buf; 11928 QDF_STATUS ret; 11929 int32_t len; 11930 11931 len = sizeof(*cmd); 11932 buf = wmi_buf_alloc(wmi_handle, len); 11933 if (!buf) { 11934 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11935 return QDF_STATUS_E_FAILURE; 11936 } 11937 11938 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 11939 WMITLV_SET_HDR(&cmd->tlv_header, 11940 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 11941 WMITLV_GET_STRUCT_TLVLEN( 11942 wmi_vdev_spectral_configure_cmd_fixed_param)); 11943 11944 cmd->vdev_id = param->vdev_id; 11945 cmd->spectral_scan_count = param->count; 11946 cmd->spectral_scan_period = param->period; 11947 cmd->spectral_scan_priority = param->spectral_pri; 11948 cmd->spectral_scan_fft_size = param->fft_size; 11949 cmd->spectral_scan_gc_ena = param->gc_enable; 11950 cmd->spectral_scan_restart_ena = param->restart_enable; 11951 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 11952 cmd->spectral_scan_init_delay = param->init_delay; 11953 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 11954 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 11955 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 11956 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 11957 cmd->spectral_scan_rssi_thr = param->rssi_thr; 11958 cmd->spectral_scan_pwr_format = param->pwr_format; 11959 cmd->spectral_scan_rpt_mode = param->rpt_mode; 11960 cmd->spectral_scan_bin_scale = param->bin_scale; 11961 cmd->spectral_scan_dBm_adj = param->dbm_adj; 11962 cmd->spectral_scan_chn_mask = param->chn_mask; 11963 11964 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11965 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 11966 11967 if (ret != 0) { 11968 WMI_LOGE("Sending set quiet cmd failed\n"); 11969 wmi_buf_free(buf); 11970 } 11971 11972 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 11973 __func__); 11974 11975 WMI_LOGI("vdev_id = %u\n" 11976 "spectral_scan_count = %u\n" 11977 "spectral_scan_period = %u\n" 11978 "spectral_scan_priority = %u\n" 11979 "spectral_scan_fft_size = %u\n" 11980 "spectral_scan_gc_ena = %u\n" 11981 "spectral_scan_restart_ena = %u\n" 11982 "spectral_scan_noise_floor_ref = %u\n" 11983 "spectral_scan_init_delay = %u\n" 11984 "spectral_scan_nb_tone_thr = %u\n" 11985 "spectral_scan_str_bin_thr = %u\n" 11986 "spectral_scan_wb_rpt_mode = %u\n" 11987 "spectral_scan_rssi_rpt_mode = %u\n" 11988 "spectral_scan_rssi_thr = %u\n" 11989 "spectral_scan_pwr_format = %u\n" 11990 "spectral_scan_rpt_mode = %u\n" 11991 "spectral_scan_bin_scale = %u\n" 11992 "spectral_scan_dBm_adj = %u\n" 11993 "spectral_scan_chn_mask = %u\n", 11994 param->vdev_id, 11995 param->count, 11996 param->period, 11997 param->spectral_pri, 11998 param->fft_size, 11999 param->gc_enable, 12000 param->restart_enable, 12001 param->noise_floor_ref, 12002 param->init_delay, 12003 param->nb_tone_thr, 12004 param->str_bin_thr, 12005 param->wb_rpt_mode, 12006 param->rssi_rpt_mode, 12007 param->rssi_thr, 12008 param->pwr_format, 12009 param->rpt_mode, 12010 param->bin_scale, 12011 param->dbm_adj, 12012 param->chn_mask); 12013 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12014 12015 return ret; 12016 } 12017 12018 /** 12019 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12020 * command to fw 12021 * @wmi_handle: wmi handle 12022 * @param: pointer to hold spectral enable parameter 12023 * 12024 * Return: 0 for success or error code 12025 */ 12026 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12027 struct vdev_spectral_enable_params *param) 12028 { 12029 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12030 wmi_buf_t buf; 12031 QDF_STATUS ret; 12032 int32_t len; 12033 12034 len = sizeof(*cmd); 12035 buf = wmi_buf_alloc(wmi_handle, len); 12036 if (!buf) { 12037 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12038 return QDF_STATUS_E_FAILURE; 12039 } 12040 12041 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12042 WMITLV_SET_HDR(&cmd->tlv_header, 12043 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12044 WMITLV_GET_STRUCT_TLVLEN( 12045 wmi_vdev_spectral_enable_cmd_fixed_param)); 12046 12047 cmd->vdev_id = param->vdev_id; 12048 12049 if (param->active_valid) { 12050 cmd->trigger_cmd = param->active ? 1 : 2; 12051 /* 1: Trigger, 2: Clear Trigger */ 12052 } else { 12053 cmd->trigger_cmd = 0; /* 0: Ignore */ 12054 } 12055 12056 if (param->enabled_valid) { 12057 cmd->enable_cmd = param->enabled ? 1 : 2; 12058 /* 1: Enable 2: Disable */ 12059 } else { 12060 cmd->enable_cmd = 0; /* 0: Ignore */ 12061 } 12062 12063 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12064 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12065 12066 if (ret != 0) { 12067 WMI_LOGE("Sending scan enable CMD failed\n"); 12068 wmi_buf_free(buf); 12069 } 12070 12071 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12072 12073 WMI_LOGI("vdev_id = %u\n" 12074 "trigger_cmd = %u\n" 12075 "enable_cmd = %u\n", 12076 cmd->vdev_id, 12077 cmd->trigger_cmd, 12078 cmd->enable_cmd); 12079 12080 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12081 12082 return ret; 12083 } 12084 12085 /** 12086 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12087 * @param wmi_handle : handle to WMI. 12088 * @param param : pointer to hold thermal mitigation param 12089 * 12090 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12091 */ 12092 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12093 wmi_unified_t wmi_handle, 12094 struct thermal_mitigation_params *param) 12095 { 12096 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 12097 wmi_therm_throt_level_config_info *lvl_conf = NULL; 12098 wmi_buf_t buf = NULL; 12099 uint8_t *buf_ptr = NULL; 12100 int error; 12101 int32_t len; 12102 int i; 12103 12104 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 12105 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 12106 12107 buf = wmi_buf_alloc(wmi_handle, len); 12108 if (!buf) { 12109 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12110 return QDF_STATUS_E_NOMEM; 12111 } 12112 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 12113 12114 /* init fixed params */ 12115 WMITLV_SET_HDR(tt_conf, 12116 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 12117 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 12118 12119 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12120 param->pdev_id); 12121 tt_conf->enable = param->enable; 12122 tt_conf->dc = param->dc; 12123 tt_conf->dc_per_event = param->dc_per_event; 12124 tt_conf->therm_throt_levels = THERMAL_LEVELS; 12125 12126 buf_ptr = (uint8_t *) ++tt_conf; 12127 /* init TLV params */ 12128 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12129 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 12130 12131 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 12132 for (i = 0; i < THERMAL_LEVELS; i++) { 12133 WMITLV_SET_HDR(&lvl_conf->tlv_header, 12134 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 12135 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 12136 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 12137 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 12138 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 12139 lvl_conf->prio = param->levelconf[i].priority; 12140 lvl_conf++; 12141 } 12142 12143 error = wmi_unified_cmd_send(wmi_handle, buf, len, 12144 WMI_THERM_THROT_SET_CONF_CMDID); 12145 if (QDF_IS_STATUS_ERROR(error)) { 12146 wmi_buf_free(buf); 12147 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 12148 } 12149 12150 return error; 12151 } 12152 12153 /** 12154 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 12155 * @wmi_handle: wmi handle 12156 * @param: pointer to pdev_qvit_params 12157 * 12158 * Return: 0 for success or error code 12159 */ 12160 static QDF_STATUS 12161 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 12162 struct pdev_qvit_params *param) 12163 { 12164 wmi_buf_t buf; 12165 QDF_STATUS ret = QDF_STATUS_E_INVAL; 12166 uint8_t *cmd; 12167 static uint8_t msgref = 1; 12168 uint8_t segnumber = 0, seginfo, numsegments; 12169 uint16_t chunk_len, total_bytes; 12170 uint8_t *bufpos; 12171 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 12172 12173 bufpos = param->utf_payload; 12174 total_bytes = param->len; 12175 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 12176 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 12177 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 12178 12179 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 12180 numsegments++; 12181 12182 while (param->len) { 12183 if (param->len > MAX_WMI_QVIT_LEN) 12184 chunk_len = MAX_WMI_QVIT_LEN; /* MAX message */ 12185 else 12186 chunk_len = param->len; 12187 12188 buf = wmi_buf_alloc(wmi_handle, 12189 (chunk_len + sizeof(seghdrinfo) + 12190 WMI_TLV_HDR_SIZE)); 12191 if (!buf) { 12192 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12193 return QDF_STATUS_E_NOMEM; 12194 } 12195 12196 cmd = (uint8_t *) wmi_buf_data(buf); 12197 12198 seghdrinfo.len = total_bytes; 12199 seghdrinfo.msgref = msgref; 12200 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 12201 seghdrinfo.segmentInfo = seginfo; 12202 12203 segnumber++; 12204 12205 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 12206 (chunk_len + sizeof(seghdrinfo))); 12207 cmd += WMI_TLV_HDR_SIZE; 12208 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 12209 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 12210 12211 ret = wmi_unified_cmd_send(wmi_handle, buf, 12212 (chunk_len + sizeof(seghdrinfo) + 12213 WMI_TLV_HDR_SIZE), 12214 WMI_PDEV_QVIT_CMDID); 12215 12216 if (ret != 0) { 12217 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 12218 wmi_buf_free(buf); 12219 break; 12220 } 12221 12222 param->len -= chunk_len; 12223 bufpos += chunk_len; 12224 } 12225 msgref++; 12226 12227 return ret; 12228 } 12229 12230 /** 12231 * send_wmm_update_cmd_tlv() - send wmm update command to fw 12232 * @wmi_handle: wmi handle 12233 * @param: pointer to wmm update param 12234 * 12235 * Return: 0 for success or error code 12236 */ 12237 static QDF_STATUS 12238 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 12239 struct wmm_update_params *param) 12240 { 12241 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 12242 wmi_wmm_params *wmm_param; 12243 wmi_buf_t buf; 12244 QDF_STATUS ret; 12245 int32_t len; 12246 int ac = 0; 12247 struct wmi_host_wmeParams *wmep; 12248 uint8_t *buf_ptr; 12249 12250 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 12251 buf = wmi_buf_alloc(wmi_handle, len); 12252 if (!buf) { 12253 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12254 return QDF_STATUS_E_FAILURE; 12255 } 12256 12257 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12258 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 12259 WMITLV_SET_HDR(&cmd->tlv_header, 12260 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 12261 WMITLV_GET_STRUCT_TLVLEN 12262 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 12263 12264 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 12265 12266 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 12267 12268 for (ac = 0; ac < WME_NUM_AC; ac++) { 12269 wmep = ¶m->wmep_array[ac]; 12270 wmm_param = (wmi_wmm_params *)buf_ptr; 12271 WMITLV_SET_HDR(&wmm_param->tlv_header, 12272 WMITLV_TAG_STRUC_wmi_wmm_params, 12273 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 12274 wmm_param->aifs = wmep->wmep_aifsn; 12275 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 12276 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 12277 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 12278 wmm_param->acm = wmep->wmep_acm; 12279 wmm_param->no_ack = wmep->wmep_noackPolicy; 12280 buf_ptr += sizeof(wmi_wmm_params); 12281 } 12282 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12283 WMI_PDEV_SET_WMM_PARAMS_CMDID); 12284 12285 if (ret != 0) { 12286 WMI_LOGE("Sending WMM update CMD failed\n"); 12287 wmi_buf_free(buf); 12288 } 12289 12290 return ret; 12291 } 12292 12293 /** 12294 * send_coex_config_cmd_tlv() - send coex config command to fw 12295 * @wmi_handle: wmi handle 12296 * @param: pointer to coex config param 12297 * 12298 * Return: 0 for success or error code 12299 */ 12300 static QDF_STATUS 12301 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 12302 struct coex_config_params *param) 12303 { 12304 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 12305 wmi_buf_t buf; 12306 QDF_STATUS ret; 12307 int32_t len; 12308 12309 len = sizeof(*cmd); 12310 buf = wmi_buf_alloc(wmi_handle, len); 12311 if (!buf) { 12312 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12313 return QDF_STATUS_E_FAILURE; 12314 } 12315 12316 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 12317 WMITLV_SET_HDR(&cmd->tlv_header, 12318 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 12319 WMITLV_GET_STRUCT_TLVLEN( 12320 WMI_COEX_CONFIG_CMD_fixed_param)); 12321 12322 cmd->vdev_id = param->vdev_id; 12323 cmd->config_type = param->config_type; 12324 cmd->config_arg1 = param->config_arg1; 12325 cmd->config_arg2 = param->config_arg2; 12326 cmd->config_arg3 = param->config_arg3; 12327 cmd->config_arg4 = param->config_arg4; 12328 cmd->config_arg5 = param->config_arg5; 12329 cmd->config_arg6 = param->config_arg6; 12330 12331 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12332 WMI_COEX_CONFIG_CMDID); 12333 12334 if (ret != 0) { 12335 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 12336 wmi_buf_free(buf); 12337 } 12338 12339 return ret; 12340 } 12341 12342 12343 #ifdef WLAN_SUPPORT_TWT 12344 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12345 target_resource_config *tgt_res_cfg) 12346 { 12347 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 12348 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 12349 } 12350 #else 12351 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12352 target_resource_config *tgt_res_cfg) 12353 { 12354 resource_cfg->twt_ap_pdev_count = 0; 12355 resource_cfg->twt_ap_sta_count = 0; 12356 } 12357 #endif 12358 12359 static 12360 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 12361 target_resource_config *tgt_res_cfg) 12362 { 12363 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 12364 resource_cfg->num_peers = tgt_res_cfg->num_peers; 12365 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 12366 resource_cfg->num_offload_reorder_buffs = 12367 tgt_res_cfg->num_offload_reorder_buffs; 12368 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 12369 resource_cfg->num_tids = tgt_res_cfg->num_tids; 12370 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 12371 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 12372 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 12373 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 12374 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 12375 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 12376 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 12377 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 12378 resource_cfg->scan_max_pending_req = 12379 tgt_res_cfg->scan_max_pending_req; 12380 resource_cfg->bmiss_offload_max_vdev = 12381 tgt_res_cfg->bmiss_offload_max_vdev; 12382 resource_cfg->roam_offload_max_vdev = 12383 tgt_res_cfg->roam_offload_max_vdev; 12384 resource_cfg->roam_offload_max_ap_profiles = 12385 tgt_res_cfg->roam_offload_max_ap_profiles; 12386 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 12387 resource_cfg->num_mcast_table_elems = 12388 tgt_res_cfg->num_mcast_table_elems; 12389 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 12390 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 12391 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 12392 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 12393 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 12394 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 12395 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 12396 resource_cfg->vow_config = tgt_res_cfg->vow_config; 12397 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 12398 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 12399 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 12400 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 12401 resource_cfg->num_tdls_conn_table_entries = 12402 tgt_res_cfg->num_tdls_conn_table_entries; 12403 resource_cfg->beacon_tx_offload_max_vdev = 12404 tgt_res_cfg->beacon_tx_offload_max_vdev; 12405 resource_cfg->num_multicast_filter_entries = 12406 tgt_res_cfg->num_multicast_filter_entries; 12407 resource_cfg->num_wow_filters = 12408 tgt_res_cfg->num_wow_filters; 12409 resource_cfg->num_keep_alive_pattern = 12410 tgt_res_cfg->num_keep_alive_pattern; 12411 resource_cfg->keep_alive_pattern_size = 12412 tgt_res_cfg->keep_alive_pattern_size; 12413 resource_cfg->max_tdls_concurrent_sleep_sta = 12414 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 12415 resource_cfg->max_tdls_concurrent_buffer_sta = 12416 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 12417 resource_cfg->wmi_send_separate = 12418 tgt_res_cfg->wmi_send_separate; 12419 resource_cfg->num_ocb_vdevs = 12420 tgt_res_cfg->num_ocb_vdevs; 12421 resource_cfg->num_ocb_channels = 12422 tgt_res_cfg->num_ocb_channels; 12423 resource_cfg->num_ocb_schedules = 12424 tgt_res_cfg->num_ocb_schedules; 12425 resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size; 12426 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 12427 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 12428 resource_cfg->max_num_dbs_scan_duty_cycle = 12429 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 12430 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 12431 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 12432 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 12433 12434 if (tgt_res_cfg->atf_config) 12435 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 12436 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 12437 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 12438 resource_cfg->flag1, 1); 12439 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 12440 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 12441 resource_cfg->flag1, 1); 12442 if (tgt_res_cfg->cce_disable) 12443 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 12444 12445 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 12446 } 12447 12448 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 12449 * @wmi_handle: pointer to wmi handle 12450 * @buf_ptr: pointer to current position in init command buffer 12451 * @len: pointer to length. This will be updated with current length of cmd 12452 * @param: point host parameters for init command 12453 * 12454 * Return: Updated pointer of buf_ptr. 12455 */ 12456 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 12457 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 12458 { 12459 uint16_t idx; 12460 12461 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 12462 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 12463 wmi_pdev_band_to_mac *band_to_mac; 12464 12465 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 12466 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 12467 sizeof(wmi_resource_config) + 12468 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 12469 sizeof(wlan_host_memory_chunk))); 12470 12471 WMITLV_SET_HDR(&hw_mode->tlv_header, 12472 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 12473 (WMITLV_GET_STRUCT_TLVLEN 12474 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 12475 12476 hw_mode->hw_mode_index = param->hw_mode_id; 12477 hw_mode->num_band_to_mac = param->num_band_to_mac; 12478 12479 buf_ptr = (uint8_t *) (hw_mode + 1); 12480 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 12481 WMI_TLV_HDR_SIZE); 12482 for (idx = 0; idx < param->num_band_to_mac; idx++) { 12483 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 12484 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 12485 WMITLV_GET_STRUCT_TLVLEN 12486 (wmi_pdev_band_to_mac)); 12487 band_to_mac[idx].pdev_id = 12488 wmi_handle->ops->convert_pdev_id_host_to_target( 12489 param->band_to_mac[idx].pdev_id); 12490 band_to_mac[idx].start_freq = 12491 param->band_to_mac[idx].start_freq; 12492 band_to_mac[idx].end_freq = 12493 param->band_to_mac[idx].end_freq; 12494 } 12495 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12496 (param->num_band_to_mac * 12497 sizeof(wmi_pdev_band_to_mac)) + 12498 WMI_TLV_HDR_SIZE; 12499 12500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12501 (param->num_band_to_mac * 12502 sizeof(wmi_pdev_band_to_mac))); 12503 } 12504 12505 return buf_ptr; 12506 } 12507 12508 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 12509 wmi_init_cmd_fixed_param *cmd) 12510 { 12511 int num_whitelist; 12512 wmi_abi_version my_vers; 12513 12514 num_whitelist = sizeof(version_whitelist) / 12515 sizeof(wmi_whitelist_version_info); 12516 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 12517 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 12518 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 12519 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 12520 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 12521 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 12522 12523 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 12524 &my_vers, 12525 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 12526 &cmd->host_abi_vers); 12527 12528 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 12529 __func__, 12530 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 12531 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 12532 cmd->host_abi_vers.abi_version_ns_0, 12533 cmd->host_abi_vers.abi_version_ns_1, 12534 cmd->host_abi_vers.abi_version_ns_2, 12535 cmd->host_abi_vers.abi_version_ns_3); 12536 12537 /* Save version sent from host - 12538 * Will be used to check ready event 12539 */ 12540 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 12541 sizeof(wmi_abi_version)); 12542 } 12543 12544 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12545 { 12546 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12547 wmi_service_ready_event_fixed_param *ev; 12548 12549 12550 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12551 12552 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12553 if (!ev) 12554 return QDF_STATUS_E_FAILURE; 12555 12556 /*Save fw version from service ready message */ 12557 /*This will be used while sending INIT message */ 12558 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12559 sizeof(wmi_handle->fw_abi_version)); 12560 12561 return QDF_STATUS_SUCCESS; 12562 } 12563 12564 /** 12565 * wmi_unified_save_fw_version_cmd() - save fw version 12566 * @wmi_handle: pointer to wmi handle 12567 * @res_cfg: resource config 12568 * @num_mem_chunks: no of mem chunck 12569 * @mem_chunk: pointer to mem chunck structure 12570 * 12571 * This function sends IE information to firmware 12572 * 12573 * Return: QDF_STATUS_SUCCESS for success otherwise failure 12574 * 12575 */ 12576 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 12577 void *evt_buf) 12578 { 12579 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12580 wmi_ready_event_fixed_param *ev = NULL; 12581 12582 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12583 ev = param_buf->fixed_param; 12584 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 12585 &wmi_handle->final_abi_vers, 12586 &ev->fw_abi_vers)) { 12587 /* 12588 * Error: Our host version and the given firmware version 12589 * are incompatible. 12590 **/ 12591 WMI_LOGD("%s: Error: Incompatible WMI version." 12592 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 12593 __func__, 12594 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 12595 abi_version_0), 12596 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 12597 abi_version_0), 12598 wmi_handle->final_abi_vers.abi_version_ns_0, 12599 wmi_handle->final_abi_vers.abi_version_ns_1, 12600 wmi_handle->final_abi_vers.abi_version_ns_2, 12601 wmi_handle->final_abi_vers.abi_version_ns_3, 12602 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 12603 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 12604 ev->fw_abi_vers.abi_version_ns_0, 12605 ev->fw_abi_vers.abi_version_ns_1, 12606 ev->fw_abi_vers.abi_version_ns_2, 12607 ev->fw_abi_vers.abi_version_ns_3); 12608 12609 return QDF_STATUS_E_FAILURE; 12610 } 12611 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 12612 sizeof(wmi_abi_version)); 12613 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12614 sizeof(wmi_abi_version)); 12615 12616 return QDF_STATUS_SUCCESS; 12617 } 12618 12619 /** 12620 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 12621 * @wmi_handle: wmi handle 12622 * @custom_addr: base mac address 12623 * 12624 * Return: QDF_STATUS_SUCCESS for success or error code 12625 */ 12626 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 12627 uint8_t *custom_addr) 12628 { 12629 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 12630 wmi_buf_t buf; 12631 int err; 12632 12633 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 12634 if (!buf) { 12635 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 12636 return QDF_STATUS_E_NOMEM; 12637 } 12638 12639 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 12640 qdf_mem_zero(cmd, sizeof(*cmd)); 12641 12642 WMITLV_SET_HDR(&cmd->tlv_header, 12643 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 12644 WMITLV_GET_STRUCT_TLVLEN 12645 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 12646 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 12647 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12648 WMI_HOST_PDEV_ID_SOC); 12649 err = wmi_unified_cmd_send(wmi_handle, buf, 12650 sizeof(*cmd), 12651 WMI_PDEV_SET_BASE_MACADDR_CMDID); 12652 if (err) { 12653 WMI_LOGE("Failed to send set_base_macaddr cmd"); 12654 wmi_buf_free(buf); 12655 return QDF_STATUS_E_FAILURE; 12656 } 12657 12658 return 0; 12659 } 12660 12661 /** 12662 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 12663 * @handle: wmi handle 12664 * @event: Event received from FW 12665 * @len: Length of the event 12666 * 12667 * Enables the low frequency events and disables the high frequency 12668 * events. Bit 17 indicates if the event if low/high frequency. 12669 * 1 - high frequency, 0 - low frequency 12670 * 12671 * Return: 0 on successfully enabling/disabling the events 12672 */ 12673 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 12674 uint8_t *event, 12675 uint32_t len) 12676 { 12677 uint32_t num_of_diag_events_logs; 12678 wmi_diag_event_log_config_fixed_param *cmd; 12679 wmi_buf_t buf; 12680 uint8_t *buf_ptr; 12681 uint32_t *cmd_args, *evt_args; 12682 uint32_t buf_len, i; 12683 12684 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 12685 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 12686 12687 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 12688 12689 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 12690 if (!param_buf) { 12691 WMI_LOGE("Invalid log supported event buffer"); 12692 return QDF_STATUS_E_INVAL; 12693 } 12694 wmi_event = param_buf->fixed_param; 12695 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 12696 12697 if (num_of_diag_events_logs > 12698 param_buf->num_diag_events_logs_list) { 12699 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 12700 num_of_diag_events_logs, 12701 param_buf->num_diag_events_logs_list); 12702 return QDF_STATUS_E_INVAL; 12703 } 12704 12705 evt_args = param_buf->diag_events_logs_list; 12706 if (!evt_args) { 12707 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 12708 __func__, num_of_diag_events_logs); 12709 return QDF_STATUS_E_INVAL; 12710 } 12711 12712 WMI_LOGD("%s: num_of_diag_events_logs=%d", 12713 __func__, num_of_diag_events_logs); 12714 12715 /* Free any previous allocation */ 12716 if (wmi_handle->events_logs_list) 12717 qdf_mem_free(wmi_handle->events_logs_list); 12718 12719 if (num_of_diag_events_logs > 12720 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 12721 WMI_LOGE("%s: excess num of logs:%d", __func__, 12722 num_of_diag_events_logs); 12723 QDF_ASSERT(0); 12724 return QDF_STATUS_E_INVAL; 12725 } 12726 /* Store the event list for run time enable/disable */ 12727 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 12728 sizeof(uint32_t)); 12729 if (!wmi_handle->events_logs_list) { 12730 WMI_LOGE("%s: event log list memory allocation failed", 12731 __func__); 12732 return QDF_STATUS_E_NOMEM; 12733 } 12734 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 12735 12736 /* Prepare the send buffer */ 12737 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12738 (num_of_diag_events_logs * sizeof(uint32_t)); 12739 12740 buf = wmi_buf_alloc(wmi_handle, buf_len); 12741 if (!buf) { 12742 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12743 qdf_mem_free(wmi_handle->events_logs_list); 12744 wmi_handle->events_logs_list = NULL; 12745 return QDF_STATUS_E_NOMEM; 12746 } 12747 12748 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 12749 buf_ptr = (uint8_t *) cmd; 12750 12751 WMITLV_SET_HDR(&cmd->tlv_header, 12752 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 12753 WMITLV_GET_STRUCT_TLVLEN( 12754 wmi_diag_event_log_config_fixed_param)); 12755 12756 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 12757 12758 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 12759 12760 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12761 (num_of_diag_events_logs * sizeof(uint32_t))); 12762 12763 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 12764 12765 /* Populate the events */ 12766 for (i = 0; i < num_of_diag_events_logs; i++) { 12767 /* Low freq (0) - Enable (1) the event 12768 * High freq (1) - Disable (0) the event 12769 */ 12770 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 12771 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 12772 /* Set the event ID */ 12773 WMI_DIAG_ID_SET(cmd_args[i], 12774 WMI_DIAG_ID_GET(evt_args[i])); 12775 /* Set the type */ 12776 WMI_DIAG_TYPE_SET(cmd_args[i], 12777 WMI_DIAG_TYPE_GET(evt_args[i])); 12778 /* Storing the event/log list in WMI */ 12779 wmi_handle->events_logs_list[i] = evt_args[i]; 12780 } 12781 12782 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 12783 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 12784 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 12785 __func__); 12786 wmi_buf_free(buf); 12787 /* Not clearing events_logs_list, though wmi cmd failed. 12788 * Host can still have this list 12789 */ 12790 return QDF_STATUS_E_INVAL; 12791 } 12792 12793 return 0; 12794 } 12795 12796 /** 12797 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 12798 * @wmi_handle: wmi handle 12799 * @start_log: Start logging related parameters 12800 * 12801 * Send the command to the FW based on which specific logging of diag 12802 * event/log id can be started/stopped 12803 * 12804 * Return: None 12805 */ 12806 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 12807 struct wmi_wifi_start_log *start_log) 12808 { 12809 wmi_diag_event_log_config_fixed_param *cmd; 12810 wmi_buf_t buf; 12811 uint8_t *buf_ptr; 12812 uint32_t len, count, log_level, i; 12813 uint32_t *cmd_args; 12814 uint32_t total_len; 12815 count = 0; 12816 12817 if (!wmi_handle->events_logs_list) { 12818 WMI_LOGE("%s: Not received event/log list from FW, yet", 12819 __func__); 12820 return QDF_STATUS_E_NOMEM; 12821 } 12822 /* total_len stores the number of events where BITS 17 and 18 are set. 12823 * i.e., events of high frequency (17) and for extended debugging (18) 12824 */ 12825 total_len = 0; 12826 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 12827 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 12828 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 12829 total_len++; 12830 } 12831 12832 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12833 (total_len * sizeof(uint32_t)); 12834 12835 buf = wmi_buf_alloc(wmi_handle, len); 12836 if (!buf) { 12837 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12838 return QDF_STATUS_E_NOMEM; 12839 } 12840 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 12841 buf_ptr = (uint8_t *) cmd; 12842 12843 WMITLV_SET_HDR(&cmd->tlv_header, 12844 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 12845 WMITLV_GET_STRUCT_TLVLEN( 12846 wmi_diag_event_log_config_fixed_param)); 12847 12848 cmd->num_of_diag_events_logs = total_len; 12849 12850 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 12851 12852 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12853 (total_len * sizeof(uint32_t))); 12854 12855 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 12856 12857 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 12858 log_level = 1; 12859 else 12860 log_level = 0; 12861 12862 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 12863 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 12864 uint32_t val = wmi_handle->events_logs_list[i]; 12865 if ((WMI_DIAG_FREQUENCY_GET(val)) && 12866 (WMI_DIAG_EXT_FEATURE_GET(val))) { 12867 12868 WMI_DIAG_ID_SET(cmd_args[count], 12869 WMI_DIAG_ID_GET(val)); 12870 WMI_DIAG_TYPE_SET(cmd_args[count], 12871 WMI_DIAG_TYPE_GET(val)); 12872 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 12873 log_level); 12874 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 12875 count++; 12876 } 12877 } 12878 12879 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12880 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 12881 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 12882 __func__); 12883 wmi_buf_free(buf); 12884 return QDF_STATUS_E_INVAL; 12885 } 12886 12887 return QDF_STATUS_SUCCESS; 12888 } 12889 12890 /** 12891 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 12892 * @wmi_handle: WMI handle 12893 * 12894 * This function is used to send the flush command to the FW, 12895 * that will flush the fw logs that are residue in the FW 12896 * 12897 * Return: None 12898 */ 12899 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 12900 { 12901 wmi_debug_mesg_flush_fixed_param *cmd; 12902 wmi_buf_t buf; 12903 int len = sizeof(*cmd); 12904 QDF_STATUS ret; 12905 12906 buf = wmi_buf_alloc(wmi_handle, len); 12907 if (!buf) { 12908 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 12909 return QDF_STATUS_E_NOMEM; 12910 } 12911 12912 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 12913 WMITLV_SET_HDR(&cmd->tlv_header, 12914 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 12915 WMITLV_GET_STRUCT_TLVLEN( 12916 wmi_debug_mesg_flush_fixed_param)); 12917 cmd->reserved0 = 0; 12918 12919 ret = wmi_unified_cmd_send(wmi_handle, 12920 buf, 12921 len, 12922 WMI_DEBUG_MESG_FLUSH_CMDID); 12923 if (QDF_IS_STATUS_ERROR(ret)) { 12924 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 12925 wmi_buf_free(buf); 12926 return QDF_STATUS_E_INVAL; 12927 } 12928 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 12929 12930 return ret; 12931 } 12932 12933 /** 12934 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 12935 * @wmi_handle: wmi handle 12936 * @msg: PCL structure containing the PCL and the number of channels 12937 * 12938 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 12939 * firmware. The DBS Manager is the consumer of this information in the WLAN 12940 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 12941 * to migrate to a new channel without host driver involvement. An example of 12942 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 12943 * manage the channel selection without firmware involvement. 12944 * 12945 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 12946 * channel list. The weights corresponds to the channels sent in 12947 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 12948 * weightage compared to the non PCL channels. 12949 * 12950 * Return: Success if the cmd is sent successfully to the firmware 12951 */ 12952 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 12953 struct wmi_pcl_chan_weights *msg) 12954 { 12955 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 12956 wmi_buf_t buf; 12957 uint8_t *buf_ptr; 12958 uint32_t *cmd_args, i, len; 12959 uint32_t chan_len; 12960 12961 chan_len = msg->saved_num_chan; 12962 12963 len = sizeof(*cmd) + 12964 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 12965 12966 buf = wmi_buf_alloc(wmi_handle, len); 12967 if (!buf) { 12968 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12969 return QDF_STATUS_E_NOMEM; 12970 } 12971 12972 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 12973 buf_ptr = (uint8_t *) cmd; 12974 WMITLV_SET_HDR(&cmd->tlv_header, 12975 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 12976 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 12977 12978 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12979 WMI_HOST_PDEV_ID_SOC); 12980 cmd->num_chan = chan_len; 12981 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 12982 12983 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 12984 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12985 (chan_len * sizeof(uint32_t))); 12986 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 12987 for (i = 0; i < chan_len ; i++) { 12988 cmd_args[i] = msg->weighed_valid_list[i]; 12989 WMI_LOGD("%s: chan:%d weight:%d", __func__, 12990 msg->saved_chan_list[i], cmd_args[i]); 12991 } 12992 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12993 WMI_PDEV_SET_PCL_CMDID)) { 12994 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 12995 wmi_buf_free(buf); 12996 return QDF_STATUS_E_FAILURE; 12997 } 12998 return QDF_STATUS_SUCCESS; 12999 } 13000 13001 /** 13002 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13003 * @wmi_handle: wmi handle 13004 * @msg: Structure containing the following parameters 13005 * 13006 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13007 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13008 * 13009 * Provides notification to the WLAN firmware that host driver is requesting a 13010 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13011 * configurations that include the Dual Band Simultaneous (DBS) feature. 13012 * 13013 * Return: Success if the cmd is sent successfully to the firmware 13014 */ 13015 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13016 uint32_t hw_mode_index) 13017 { 13018 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13019 wmi_buf_t buf; 13020 uint32_t len; 13021 13022 len = sizeof(*cmd); 13023 13024 buf = wmi_buf_alloc(wmi_handle, len); 13025 if (!buf) { 13026 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13027 return QDF_STATUS_E_NOMEM; 13028 } 13029 13030 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13031 WMITLV_SET_HDR(&cmd->tlv_header, 13032 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13033 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13034 13035 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13036 WMI_HOST_PDEV_ID_SOC); 13037 cmd->hw_mode_index = hw_mode_index; 13038 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13039 13040 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13041 WMI_PDEV_SET_HW_MODE_CMDID)) { 13042 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13043 __func__); 13044 wmi_buf_free(buf); 13045 return QDF_STATUS_E_FAILURE; 13046 } 13047 13048 return QDF_STATUS_SUCCESS; 13049 } 13050 13051 #ifdef WLAN_POLICY_MGR_ENABLE 13052 /** 13053 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13054 * @wmi_handle: wmi handle 13055 * @msg: Dual MAC config parameters 13056 * 13057 * Configures WLAN firmware with the dual MAC features 13058 * 13059 * Return: QDF_STATUS. 0 on success. 13060 */ 13061 static 13062 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13063 struct policy_mgr_dual_mac_config *msg) 13064 { 13065 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13066 wmi_buf_t buf; 13067 uint32_t len; 13068 13069 len = sizeof(*cmd); 13070 13071 buf = wmi_buf_alloc(wmi_handle, len); 13072 if (!buf) { 13073 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13074 return QDF_STATUS_E_FAILURE; 13075 } 13076 13077 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13078 WMITLV_SET_HDR(&cmd->tlv_header, 13079 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13080 WMITLV_GET_STRUCT_TLVLEN( 13081 wmi_pdev_set_mac_config_cmd_fixed_param)); 13082 13083 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13084 WMI_HOST_PDEV_ID_SOC); 13085 cmd->concurrent_scan_config_bits = msg->scan_config; 13086 cmd->fw_mode_config_bits = msg->fw_mode_config; 13087 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 13088 __func__, msg->scan_config, msg->fw_mode_config); 13089 13090 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13091 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13092 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13093 __func__); 13094 wmi_buf_free(buf); 13095 } 13096 return QDF_STATUS_SUCCESS; 13097 } 13098 #endif 13099 13100 #ifdef BIG_ENDIAN_HOST 13101 /** 13102 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13103 * @param data_len - data length 13104 * @param data - pointer to data 13105 * 13106 * Return: QDF_STATUS - success or error status 13107 */ 13108 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13109 struct fips_params *param) 13110 { 13111 unsigned char *key_unaligned, *data_unaligned; 13112 int c; 13113 u_int8_t *key_aligned = NULL; 13114 u_int8_t *data_aligned = NULL; 13115 13116 /* Assigning unaligned space to copy the key */ 13117 key_unaligned = qdf_mem_malloc( 13118 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 13119 data_unaligned = qdf_mem_malloc( 13120 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 13121 13122 /* Checking if kmalloc is successful to allocate space */ 13123 if (key_unaligned == NULL) 13124 return QDF_STATUS_SUCCESS; 13125 /* Checking if space is aligned */ 13126 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 13127 /* align to 4 */ 13128 key_aligned = 13129 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 13130 FIPS_ALIGN); 13131 } else { 13132 key_aligned = (u_int8_t *)key_unaligned; 13133 } 13134 13135 /* memset and copy content from key to key aligned */ 13136 OS_MEMSET(key_aligned, 0, param->key_len); 13137 OS_MEMCPY(key_aligned, param->key, param->key_len); 13138 13139 /* print a hexdump for host debug */ 13140 print_hex_dump(KERN_DEBUG, 13141 "\t Aligned and Copied Key:@@@@ ", 13142 DUMP_PREFIX_NONE, 13143 16, 1, key_aligned, param->key_len, true); 13144 13145 /* Checking if kmalloc is successful to allocate space */ 13146 if (data_unaligned == NULL) 13147 return QDF_STATUS_SUCCESS; 13148 /* Checking of space is aligned */ 13149 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13150 /* align to 4 */ 13151 data_aligned = 13152 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 13153 FIPS_ALIGN); 13154 } else { 13155 data_aligned = (u_int8_t *)data_unaligned; 13156 } 13157 13158 /* memset and copy content from data to data aligned */ 13159 OS_MEMSET(data_aligned, 0, param->data_len); 13160 OS_MEMCPY(data_aligned, param->data, param->data_len); 13161 13162 /* print a hexdump for host debug */ 13163 print_hex_dump(KERN_DEBUG, 13164 "\t Properly Aligned and Copied Data:@@@@ ", 13165 DUMP_PREFIX_NONE, 13166 16, 1, data_aligned, param->data_len, true); 13167 13168 /* converting to little Endian both key_aligned and 13169 * data_aligned*/ 13170 for (c = 0; c < param->key_len/4; c++) { 13171 *((u_int32_t *)key_aligned+c) = 13172 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 13173 } 13174 for (c = 0; c < param->data_len/4; c++) { 13175 *((u_int32_t *)data_aligned+c) = 13176 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 13177 } 13178 13179 /* update endian data to key and data vectors */ 13180 OS_MEMCPY(param->key, key_aligned, param->key_len); 13181 OS_MEMCPY(param->data, data_aligned, param->data_len); 13182 13183 /* clean up allocated spaces */ 13184 qdf_mem_free(key_unaligned); 13185 key_unaligned = NULL; 13186 key_aligned = NULL; 13187 13188 qdf_mem_free(data_unaligned); 13189 data_unaligned = NULL; 13190 data_aligned = NULL; 13191 13192 return QDF_STATUS_SUCCESS; 13193 } 13194 #else 13195 /** 13196 * fips_align_data_be() - DUMMY for LE platform 13197 * 13198 * Return: QDF_STATUS - success 13199 */ 13200 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13201 struct fips_params *param) 13202 { 13203 return QDF_STATUS_SUCCESS; 13204 } 13205 #endif 13206 13207 13208 /** 13209 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 13210 * @wmi_handle: wmi handle 13211 * @param: pointer to hold pdev fips param 13212 * 13213 * Return: 0 for success or error code 13214 */ 13215 static QDF_STATUS 13216 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 13217 struct fips_params *param) 13218 { 13219 wmi_pdev_fips_cmd_fixed_param *cmd; 13220 wmi_buf_t buf; 13221 uint8_t *buf_ptr; 13222 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 13223 QDF_STATUS retval = QDF_STATUS_SUCCESS; 13224 13225 /* Length TLV placeholder for array of bytes */ 13226 len += WMI_TLV_HDR_SIZE; 13227 if (param->data_len) 13228 len += (param->data_len*sizeof(uint8_t)); 13229 13230 /* 13231 * Data length must be multiples of 16 bytes - checked against 0xF - 13232 * and must be less than WMI_SVC_MSG_SIZE - static size of 13233 * wmi_pdev_fips_cmd structure 13234 */ 13235 13236 /* do sanity on the input */ 13237 if (!(((param->data_len & 0xF) == 0) && 13238 ((param->data_len > 0) && 13239 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 13240 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 13241 return QDF_STATUS_E_INVAL; 13242 } 13243 13244 buf = wmi_buf_alloc(wmi_handle, len); 13245 if (!buf) { 13246 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 13247 return QDF_STATUS_E_FAILURE; 13248 } 13249 13250 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13251 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 13252 WMITLV_SET_HDR(&cmd->tlv_header, 13253 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 13254 WMITLV_GET_STRUCT_TLVLEN 13255 (wmi_pdev_fips_cmd_fixed_param)); 13256 13257 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13258 param->pdev_id); 13259 if (param->key != NULL && param->data != NULL) { 13260 cmd->key_len = param->key_len; 13261 cmd->data_len = param->data_len; 13262 cmd->fips_cmd = !!(param->op); 13263 13264 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 13265 return QDF_STATUS_E_FAILURE; 13266 13267 qdf_mem_copy(cmd->key, param->key, param->key_len); 13268 13269 if (param->mode == FIPS_ENGINE_AES_CTR || 13270 param->mode == FIPS_ENGINE_AES_MIC) { 13271 cmd->mode = param->mode; 13272 } else { 13273 cmd->mode = FIPS_ENGINE_AES_CTR; 13274 } 13275 qdf_print(KERN_ERR "Key len = %d, Data len = %d\n", 13276 cmd->key_len, cmd->data_len); 13277 13278 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 13279 cmd->key, cmd->key_len, true); 13280 buf_ptr += sizeof(*cmd); 13281 13282 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 13283 13284 buf_ptr += WMI_TLV_HDR_SIZE; 13285 if (param->data_len) 13286 qdf_mem_copy(buf_ptr, 13287 (uint8_t *) param->data, param->data_len); 13288 13289 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 13290 16, 1, buf_ptr, cmd->data_len, true); 13291 13292 buf_ptr += param->data_len; 13293 13294 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 13295 WMI_PDEV_FIPS_CMDID); 13296 qdf_print("%s return value %d\n", __func__, retval); 13297 } else { 13298 qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__); 13299 wmi_buf_free(buf); 13300 retval = -QDF_STATUS_E_BADMSG; 13301 } 13302 13303 return retval; 13304 } 13305 13306 #ifdef WLAN_PMO_ENABLE 13307 /** 13308 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 13309 * @wmi_handle: wmi handle 13310 * @vdev_id: vdev id 13311 * @bitmap: Event bitmap 13312 * @enable: enable/disable 13313 * 13314 * Return: CDF status 13315 */ 13316 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 13317 uint32_t vdev_id, 13318 uint32_t *bitmap, 13319 bool enable) 13320 { 13321 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 13322 uint16_t len; 13323 wmi_buf_t buf; 13324 int ret; 13325 13326 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 13327 buf = wmi_buf_alloc(wmi_handle, len); 13328 if (!buf) { 13329 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13330 return QDF_STATUS_E_NOMEM; 13331 } 13332 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 13333 WMITLV_SET_HDR(&cmd->tlv_header, 13334 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 13335 WMITLV_GET_STRUCT_TLVLEN 13336 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 13337 cmd->vdev_id = vdev_id; 13338 cmd->is_add = enable; 13339 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 13340 WMI_WOW_MAX_EVENT_BM_LEN); 13341 13342 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 13343 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 13344 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 13345 13346 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13347 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 13348 if (ret) { 13349 WMI_LOGE("Failed to config wow wakeup event"); 13350 wmi_buf_free(buf); 13351 return QDF_STATUS_E_FAILURE; 13352 } 13353 13354 return QDF_STATUS_SUCCESS; 13355 } 13356 13357 /** 13358 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 13359 * @wmi_handle: wmi handle 13360 * @vdev_id: vdev id 13361 * @ptrn_id: pattern id 13362 * @ptrn: pattern 13363 * @ptrn_len: pattern length 13364 * @ptrn_offset: pattern offset 13365 * @mask: mask 13366 * @mask_len: mask length 13367 * @user: true for user configured pattern and false for default pattern 13368 * @default_patterns: default patterns 13369 * 13370 * Return: CDF status 13371 */ 13372 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 13373 uint8_t vdev_id, uint8_t ptrn_id, 13374 const uint8_t *ptrn, uint8_t ptrn_len, 13375 uint8_t ptrn_offset, const uint8_t *mask, 13376 uint8_t mask_len, bool user, 13377 uint8_t default_patterns) 13378 { 13379 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13380 WOW_BITMAP_PATTERN_T *bitmap_pattern; 13381 wmi_buf_t buf; 13382 uint8_t *buf_ptr; 13383 int32_t len; 13384 int ret; 13385 13386 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13387 WMI_TLV_HDR_SIZE + 13388 1 * sizeof(WOW_BITMAP_PATTERN_T) + 13389 WMI_TLV_HDR_SIZE + 13390 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13391 WMI_TLV_HDR_SIZE + 13392 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13393 WMI_TLV_HDR_SIZE + 13394 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13395 WMI_TLV_HDR_SIZE + 13396 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13397 13398 buf = wmi_buf_alloc(wmi_handle, len); 13399 if (!buf) { 13400 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13401 return QDF_STATUS_E_NOMEM; 13402 } 13403 13404 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13405 buf_ptr = (uint8_t *) cmd; 13406 13407 WMITLV_SET_HDR(&cmd->tlv_header, 13408 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13409 WMITLV_GET_STRUCT_TLVLEN 13410 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13411 cmd->vdev_id = vdev_id; 13412 cmd->pattern_id = ptrn_id; 13413 13414 cmd->pattern_type = WOW_BITMAP_PATTERN; 13415 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13416 13417 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13418 sizeof(WOW_BITMAP_PATTERN_T)); 13419 buf_ptr += WMI_TLV_HDR_SIZE; 13420 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 13421 13422 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 13423 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 13424 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 13425 13426 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 13427 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 13428 13429 bitmap_pattern->pattern_offset = ptrn_offset; 13430 bitmap_pattern->pattern_len = ptrn_len; 13431 13432 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 13433 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 13434 13435 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 13436 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 13437 13438 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 13439 bitmap_pattern->pattern_id = ptrn_id; 13440 13441 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 13442 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 13443 bitmap_pattern->pattern_offset, user); 13444 WMI_LOGI("Pattern : "); 13445 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13446 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 13447 13448 WMI_LOGI("Mask : "); 13449 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13450 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 13451 13452 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 13453 13454 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 13455 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13456 buf_ptr += WMI_TLV_HDR_SIZE; 13457 13458 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 13459 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13460 buf_ptr += WMI_TLV_HDR_SIZE; 13461 13462 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 13463 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13464 buf_ptr += WMI_TLV_HDR_SIZE; 13465 13466 /* Fill TLV for pattern_info_timeout but no data. */ 13467 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 13468 buf_ptr += WMI_TLV_HDR_SIZE; 13469 13470 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 13471 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 13472 buf_ptr += WMI_TLV_HDR_SIZE; 13473 *(uint32_t *) buf_ptr = 0; 13474 13475 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13476 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 13477 if (ret) { 13478 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 13479 wmi_buf_free(buf); 13480 return QDF_STATUS_E_FAILURE; 13481 } 13482 13483 return QDF_STATUS_SUCCESS; 13484 } 13485 13486 /** 13487 * fill_arp_offload_params_tlv() - Fill ARP offload data 13488 * @wmi_handle: wmi handle 13489 * @offload_req: offload request 13490 * @buf_ptr: buffer pointer 13491 * 13492 * To fill ARP offload data to firmware 13493 * when target goes to wow mode. 13494 * 13495 * Return: None 13496 */ 13497 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 13498 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 13499 { 13500 13501 int i; 13502 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 13503 bool enable_or_disable = offload_req->enable; 13504 13505 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13506 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 13507 *buf_ptr += WMI_TLV_HDR_SIZE; 13508 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 13509 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 13510 WMITLV_SET_HDR(&arp_tuple->tlv_header, 13511 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 13512 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 13513 13514 /* Fill data for ARP and NS in the first tupple for LA */ 13515 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 13516 /* Copy the target ip addr and flags */ 13517 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 13518 qdf_mem_copy(&arp_tuple->target_ipaddr, 13519 offload_req->host_ipv4_addr, 13520 WMI_IPV4_ADDR_LEN); 13521 WMI_LOGD("ARPOffload IP4 address: %pI4", 13522 offload_req->host_ipv4_addr); 13523 } 13524 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 13525 } 13526 } 13527 13528 #ifdef WLAN_NS_OFFLOAD 13529 /** 13530 * fill_ns_offload_params_tlv() - Fill NS offload data 13531 * @wmi|_handle: wmi handle 13532 * @offload_req: offload request 13533 * @buf_ptr: buffer pointer 13534 * 13535 * To fill NS offload data to firmware 13536 * when target goes to wow mode. 13537 * 13538 * Return: None 13539 */ 13540 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13541 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13542 { 13543 13544 int i; 13545 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13546 13547 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13548 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13549 *buf_ptr += WMI_TLV_HDR_SIZE; 13550 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 13551 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13552 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13553 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13554 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 13555 13556 /* 13557 * Fill data only for NS offload in the first ARP tuple for LA 13558 */ 13559 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13560 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13561 /* Copy the target/solicitation/remote ip addr */ 13562 if (ns_req->target_ipv6_addr_valid[i]) 13563 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13564 &ns_req->target_ipv6_addr[i], 13565 sizeof(WMI_IPV6_ADDR)); 13566 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13567 &ns_req->self_ipv6_addr[i], 13568 sizeof(WMI_IPV6_ADDR)); 13569 if (ns_req->target_ipv6_addr_ac_type[i]) { 13570 ns_tuple->flags |= 13571 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13572 } 13573 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13574 i, &ns_req->self_ipv6_addr[i], 13575 &ns_req->target_ipv6_addr[i]); 13576 13577 /* target MAC is optional, check if it is valid, 13578 * if this is not valid, the target will use the known 13579 * local MAC address rather than the tuple 13580 */ 13581 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13582 ns_req->self_macaddr.bytes, 13583 &ns_tuple->target_mac); 13584 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13585 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13586 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13587 } 13588 } 13589 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13590 } 13591 } 13592 13593 13594 /** 13595 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 13596 * @wmi: wmi handle 13597 * @offload_req: offload request 13598 * @buf_ptr: buffer pointer 13599 * 13600 * To fill extended NS offload extended data to firmware 13601 * when target goes to wow mode. 13602 * 13603 * Return: None 13604 */ 13605 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13606 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13607 { 13608 int i; 13609 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13610 uint32_t count, num_ns_ext_tuples; 13611 13612 count = ns_req->num_ns_offload_count; 13613 num_ns_ext_tuples = ns_req->num_ns_offload_count - 13614 WMI_MAX_NS_OFFLOADS; 13615 13616 /* Populate extended NS offload tuples */ 13617 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13618 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13619 *buf_ptr += WMI_TLV_HDR_SIZE; 13620 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 13621 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13622 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13623 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13624 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 13625 13626 /* 13627 * Fill data only for NS offload in the first ARP tuple for LA 13628 */ 13629 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13630 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13631 /* Copy the target/solicitation/remote ip addr */ 13632 if (ns_req->target_ipv6_addr_valid[i]) 13633 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13634 &ns_req->target_ipv6_addr[i], 13635 sizeof(WMI_IPV6_ADDR)); 13636 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13637 &ns_req->self_ipv6_addr[i], 13638 sizeof(WMI_IPV6_ADDR)); 13639 if (ns_req->target_ipv6_addr_ac_type[i]) { 13640 ns_tuple->flags |= 13641 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13642 } 13643 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13644 i, &ns_req->self_ipv6_addr[i], 13645 &ns_req->target_ipv6_addr[i]); 13646 13647 /* target MAC is optional, check if it is valid, 13648 * if this is not valid, the target will use the 13649 * known local MAC address rather than the tuple 13650 */ 13651 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13652 ns_req->self_macaddr.bytes, 13653 &ns_tuple->target_mac); 13654 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13655 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13656 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13657 } 13658 } 13659 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13660 } 13661 } 13662 #else 13663 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13664 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13665 { 13666 } 13667 13668 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13669 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13670 { 13671 } 13672 #endif 13673 13674 /** 13675 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 13676 * @wma: wmi handle 13677 * @arp_offload_req: arp offload request 13678 * @ns_offload_req: ns offload request 13679 * @arp_only: flag 13680 * 13681 * To configure ARP NS off load data to firmware 13682 * when target goes to wow mode. 13683 * 13684 * Return: QDF Status 13685 */ 13686 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 13687 struct pmo_arp_offload_params *arp_offload_req, 13688 struct pmo_ns_offload_params *ns_offload_req, 13689 uint8_t vdev_id) 13690 { 13691 int32_t res; 13692 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 13693 uint8_t *buf_ptr; 13694 wmi_buf_t buf; 13695 int32_t len; 13696 uint32_t count = 0, num_ns_ext_tuples = 0; 13697 13698 count = ns_offload_req->num_ns_offload_count; 13699 13700 /* 13701 * TLV place holder size for array of NS tuples 13702 * TLV place holder size for array of ARP tuples 13703 */ 13704 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 13705 WMI_TLV_HDR_SIZE + 13706 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 13707 WMI_TLV_HDR_SIZE + 13708 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 13709 13710 /* 13711 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 13712 * extra length for extended NS offload tuples which follows ARP offload 13713 * tuples. Host needs to fill this structure in following format: 13714 * 2 NS ofload tuples 13715 * 2 ARP offload tuples 13716 * N numbers of extended NS offload tuples if HDD has given more than 13717 * 2 NS offload addresses 13718 */ 13719 if (count > WMI_MAX_NS_OFFLOADS) { 13720 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 13721 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 13722 * sizeof(WMI_NS_OFFLOAD_TUPLE); 13723 } 13724 13725 buf = wmi_buf_alloc(wmi_handle, len); 13726 if (!buf) { 13727 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13728 return QDF_STATUS_E_NOMEM; 13729 } 13730 13731 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13732 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 13733 WMITLV_SET_HDR(&cmd->tlv_header, 13734 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 13735 WMITLV_GET_STRUCT_TLVLEN 13736 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 13737 cmd->flags = 0; 13738 cmd->vdev_id = vdev_id; 13739 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 13740 13741 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 13742 13743 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 13744 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13745 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 13746 if (num_ns_ext_tuples) 13747 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13748 13749 res = wmi_unified_cmd_send(wmi_handle, buf, len, 13750 WMI_SET_ARP_NS_OFFLOAD_CMDID); 13751 if (res) { 13752 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 13753 wmi_buf_free(buf); 13754 return QDF_STATUS_E_FAILURE; 13755 } 13756 13757 return QDF_STATUS_SUCCESS; 13758 } 13759 13760 /** 13761 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 13762 * @wmi_handle: wmi handle 13763 * @vdev_id: vdev id 13764 * @action: true for enable else false 13765 * 13766 * To enable enhance multicast offload to firmware 13767 * when target goes to wow mode. 13768 * 13769 * Return: QDF Status 13770 */ 13771 13772 static 13773 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 13774 wmi_unified_t wmi_handle, 13775 uint8_t vdev_id, bool action) 13776 { 13777 QDF_STATUS status; 13778 wmi_buf_t buf; 13779 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 13780 13781 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13782 if (!buf) { 13783 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 13784 return QDF_STATUS_E_NOMEM; 13785 } 13786 13787 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 13788 wmi_buf_data(buf); 13789 13790 WMITLV_SET_HDR(&cmd->tlv_header, 13791 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 13792 WMITLV_GET_STRUCT_TLVLEN( 13793 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 13794 13795 cmd->vdev_id = vdev_id; 13796 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 13797 ENHANCED_MCAST_FILTER_ENABLED); 13798 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 13799 __func__, action, vdev_id); 13800 status = wmi_unified_cmd_send(wmi_handle, buf, 13801 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 13802 if (status != QDF_STATUS_SUCCESS) { 13803 qdf_nbuf_free(buf); 13804 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 13805 __func__); 13806 } 13807 13808 return status; 13809 } 13810 13811 /** 13812 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 13813 * @wmi_handle: wmi handle 13814 * @param evt_buf: pointer to event buffer 13815 * @param hdr: Pointer to hold header 13816 * @param bufp: Pointer to hold pointer to rx param buffer 13817 * 13818 * Return: QDF_STATUS_SUCCESS for success or error code 13819 */ 13820 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 13821 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 13822 { 13823 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 13824 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 13825 13826 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 13827 if (!param_buf) { 13828 WMI_LOGE("gtk param_buf is NULL"); 13829 return QDF_STATUS_E_INVAL; 13830 } 13831 13832 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 13833 WMI_LOGE("Invalid length for GTK status"); 13834 return QDF_STATUS_E_INVAL; 13835 } 13836 13837 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 13838 param_buf->fixed_param; 13839 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 13840 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 13841 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 13842 qdf_mem_copy(>k_rsp_param->replay_counter, 13843 &fixed_param->replay_counter, 13844 GTK_REPLAY_COUNTER_BYTES); 13845 13846 return QDF_STATUS_SUCCESS; 13847 13848 } 13849 13850 #ifdef FEATURE_WLAN_RA_FILTERING 13851 /** 13852 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 13853 * @wmi_handle: wmi handle 13854 * @vdev_id: vdev id 13855 * 13856 * Return: CDF status 13857 */ 13858 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 13859 uint8_t vdev_id, uint8_t default_pattern, 13860 uint16_t rate_limit_interval) 13861 { 13862 13863 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13864 wmi_buf_t buf; 13865 uint8_t *buf_ptr; 13866 int32_t len; 13867 int ret; 13868 13869 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13870 WMI_TLV_HDR_SIZE + 13871 0 * sizeof(WOW_BITMAP_PATTERN_T) + 13872 WMI_TLV_HDR_SIZE + 13873 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13874 WMI_TLV_HDR_SIZE + 13875 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13876 WMI_TLV_HDR_SIZE + 13877 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13878 WMI_TLV_HDR_SIZE + 13879 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13880 13881 buf = wmi_buf_alloc(wmi_handle, len); 13882 if (!buf) { 13883 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13884 return QDF_STATUS_E_NOMEM; 13885 } 13886 13887 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13888 buf_ptr = (uint8_t *) cmd; 13889 13890 WMITLV_SET_HDR(&cmd->tlv_header, 13891 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13892 WMITLV_GET_STRUCT_TLVLEN 13893 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13894 cmd->vdev_id = vdev_id; 13895 cmd->pattern_id = default_pattern, 13896 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 13897 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13898 13899 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 13900 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13901 buf_ptr += WMI_TLV_HDR_SIZE; 13902 13903 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 13904 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13905 buf_ptr += WMI_TLV_HDR_SIZE; 13906 13907 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 13908 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13909 buf_ptr += WMI_TLV_HDR_SIZE; 13910 13911 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 13912 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13913 buf_ptr += WMI_TLV_HDR_SIZE; 13914 13915 /* Fill TLV for pattern_info_timeout but no data. */ 13916 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 13917 buf_ptr += WMI_TLV_HDR_SIZE; 13918 13919 /* Fill TLV for ra_ratelimit_interval. */ 13920 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 13921 buf_ptr += WMI_TLV_HDR_SIZE; 13922 13923 *((uint32_t *) buf_ptr) = rate_limit_interval; 13924 13925 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 13926 rate_limit_interval, vdev_id); 13927 13928 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13929 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 13930 if (ret) { 13931 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 13932 wmi_buf_free(buf); 13933 return QDF_STATUS_E_FAILURE; 13934 } 13935 13936 return QDF_STATUS_SUCCESS; 13937 13938 } 13939 #endif /* FEATURE_WLAN_RA_FILTERING */ 13940 13941 /** 13942 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 13943 * @wmi_handle: wmi handle 13944 * @vdev_id: vdev id 13945 * @multicastAddr: mcast address 13946 * @clearList: clear list flag 13947 * 13948 * Return: QDF_STATUS_SUCCESS for success or error code 13949 */ 13950 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 13951 uint8_t vdev_id, 13952 struct qdf_mac_addr multicast_addr, 13953 bool clearList) 13954 { 13955 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 13956 wmi_buf_t buf; 13957 int err; 13958 13959 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13960 if (!buf) { 13961 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 13962 return QDF_STATUS_E_NOMEM; 13963 } 13964 13965 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 13966 qdf_mem_zero(cmd, sizeof(*cmd)); 13967 13968 WMITLV_SET_HDR(&cmd->tlv_header, 13969 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 13970 WMITLV_GET_STRUCT_TLVLEN 13971 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 13972 cmd->action = 13973 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 13974 cmd->vdev_id = vdev_id; 13975 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 13976 13977 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 13978 cmd->action, vdev_id, clearList, multicast_addr.bytes); 13979 13980 err = wmi_unified_cmd_send(wmi_handle, buf, 13981 sizeof(*cmd), 13982 WMI_SET_MCASTBCAST_FILTER_CMDID); 13983 if (err) { 13984 WMI_LOGE("Failed to send set_param cmd"); 13985 wmi_buf_free(buf); 13986 return QDF_STATUS_E_FAILURE; 13987 } 13988 13989 return QDF_STATUS_SUCCESS; 13990 } 13991 13992 /** 13993 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 13994 * command to fw 13995 * @wmi_handle: wmi handle 13996 * @vdev_id: vdev id 13997 * @mcast_filter_params: mcast filter params 13998 * 13999 * Return: QDF_STATUS_SUCCESS for success or error code 14000 */ 14001 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14002 wmi_unified_t wmi_handle, 14003 uint8_t vdev_id, 14004 struct pmo_mcast_filter_params *filter_param) 14005 14006 { 14007 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14008 uint8_t *buf_ptr; 14009 wmi_buf_t buf; 14010 int err; 14011 int i; 14012 uint8_t *mac_addr_src_ptr = NULL; 14013 wmi_mac_addr *mac_addr_dst_ptr; 14014 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14015 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14016 14017 buf = wmi_buf_alloc(wmi_handle, len); 14018 if (!buf) { 14019 WMI_LOGE("Failed to allocate memory"); 14020 return QDF_STATUS_E_NOMEM; 14021 } 14022 14023 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14024 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14025 wmi_buf_data(buf); 14026 qdf_mem_zero(cmd, sizeof(*cmd)); 14027 14028 WMITLV_SET_HDR(&cmd->tlv_header, 14029 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14030 WMITLV_GET_STRUCT_TLVLEN 14031 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14032 cmd->operation = 14033 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14034 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14035 cmd->vdev_id = vdev_id; 14036 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14037 14038 buf_ptr += sizeof(*cmd); 14039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14040 sizeof(wmi_mac_addr) * 14041 filter_param->multicast_addr_cnt); 14042 14043 if (filter_param->multicast_addr_cnt == 0) 14044 goto send_cmd; 14045 14046 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14047 mac_addr_dst_ptr = (wmi_mac_addr *) 14048 (buf_ptr + WMI_TLV_HDR_SIZE); 14049 14050 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14051 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14052 mac_addr_src_ptr += ATH_MAC_LEN; 14053 mac_addr_dst_ptr++; 14054 } 14055 14056 send_cmd: 14057 err = wmi_unified_cmd_send(wmi_handle, buf, 14058 len, 14059 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14060 if (err) { 14061 WMI_LOGE("Failed to send set_param cmd"); 14062 wmi_buf_free(buf); 14063 return QDF_STATUS_E_FAILURE; 14064 } 14065 14066 return QDF_STATUS_SUCCESS; 14067 } 14068 14069 14070 /** 14071 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14072 * @wmi_handle: wmi handle 14073 * @vdev_id: vdev id 14074 * @params: GTK offload parameters 14075 * 14076 * Return: CDF status 14077 */ 14078 static 14079 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14080 struct pmo_gtk_req *params, 14081 bool enable_offload, 14082 uint32_t gtk_offload_opcode) 14083 { 14084 int len; 14085 wmi_buf_t buf; 14086 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14087 wmi_gtk_offload_fils_tlv_param *ext_param; 14088 QDF_STATUS status = QDF_STATUS_SUCCESS; 14089 uint8_t *buf_ptr; 14090 14091 WMI_LOGD("%s Enter", __func__); 14092 14093 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param); 14094 14095 /* alloc wmi buffer */ 14096 buf = wmi_buf_alloc(wmi_handle, len); 14097 if (!buf) { 14098 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14099 status = QDF_STATUS_E_NOMEM; 14100 goto out; 14101 } 14102 14103 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14104 buf_ptr = (uint8_t *)cmd; 14105 WMITLV_SET_HDR(&cmd->tlv_header, 14106 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14107 WMITLV_GET_STRUCT_TLVLEN 14108 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14109 14110 cmd->vdev_id = vdev_id; 14111 14112 /* Request target to enable GTK offload */ 14113 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 14114 cmd->flags = gtk_offload_opcode; 14115 14116 /* Copy the keys and replay counter */ 14117 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 14118 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 14119 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 14120 GTK_REPLAY_COUNTER_BYTES); 14121 } else { 14122 cmd->flags = gtk_offload_opcode; 14123 } 14124 14125 buf_ptr += sizeof(*cmd); 14126 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param)); 14127 buf_ptr += WMI_TLV_HDR_SIZE; 14128 14129 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 14130 WMITLV_SET_HDR(&ext_param->tlv_header, 14131 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 14132 WMITLV_GET_STRUCT_TLVLEN( 14133 wmi_gtk_offload_fils_tlv_param)); 14134 ext_param->vdev_id = vdev_id; 14135 ext_param->flags = cmd->flags; 14136 ext_param->kek_len = params->kek_len; 14137 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 14138 qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES); 14139 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 14140 GTK_REPLAY_COUNTER_BYTES); 14141 14142 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 14143 /* send the wmi command */ 14144 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14145 WMI_GTK_OFFLOAD_CMDID)) { 14146 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 14147 wmi_buf_free(buf); 14148 status = QDF_STATUS_E_FAILURE; 14149 } 14150 14151 out: 14152 WMI_LOGD("%s Exit", __func__); 14153 return status; 14154 } 14155 14156 /** 14157 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 14158 * @wmi_handle: wmi handle 14159 * @params: GTK offload params 14160 * 14161 * Return: CDF status 14162 */ 14163 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 14164 wmi_unified_t wmi_handle, 14165 uint8_t vdev_id, 14166 uint64_t offload_req_opcode) 14167 { 14168 int len; 14169 wmi_buf_t buf; 14170 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14171 QDF_STATUS status = QDF_STATUS_SUCCESS; 14172 14173 len = sizeof(*cmd); 14174 14175 /* alloc wmi buffer */ 14176 buf = wmi_buf_alloc(wmi_handle, len); 14177 if (!buf) { 14178 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14179 status = QDF_STATUS_E_NOMEM; 14180 goto out; 14181 } 14182 14183 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14184 WMITLV_SET_HDR(&cmd->tlv_header, 14185 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14186 WMITLV_GET_STRUCT_TLVLEN 14187 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14188 14189 /* Request for GTK offload status */ 14190 cmd->flags = offload_req_opcode; 14191 cmd->vdev_id = vdev_id; 14192 14193 /* send the wmi command */ 14194 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14195 WMI_GTK_OFFLOAD_CMDID)) { 14196 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 14197 wmi_buf_free(buf); 14198 status = QDF_STATUS_E_FAILURE; 14199 } 14200 14201 out: 14202 return status; 14203 } 14204 14205 /** 14206 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 14207 * @wmi_handle: wmi handler 14208 * @action_params: pointer to action_params 14209 * 14210 * Return: 0 for success, otherwise appropriate error code 14211 */ 14212 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 14213 struct pmo_action_wakeup_set_params *action_params) 14214 { 14215 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 14216 wmi_buf_t buf; 14217 int i; 14218 int32_t err; 14219 uint32_t len = 0, *cmd_args; 14220 uint8_t *buf_ptr; 14221 14222 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 14223 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 14224 buf = wmi_buf_alloc(wmi_handle, len); 14225 if (!buf) { 14226 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 14227 return QDF_STATUS_E_NOMEM; 14228 } 14229 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 14230 buf_ptr = (uint8_t *)cmd; 14231 WMITLV_SET_HDR(&cmd->tlv_header, 14232 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 14233 WMITLV_GET_STRUCT_TLVLEN( 14234 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 14235 14236 cmd->vdev_id = action_params->vdev_id; 14237 cmd->operation = action_params->operation; 14238 14239 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 14240 cmd->action_category_map[i] = 14241 action_params->action_category_map[i]; 14242 14243 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 14244 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14245 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 14246 buf_ptr += WMI_TLV_HDR_SIZE; 14247 cmd_args = (uint32_t *) buf_ptr; 14248 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 14249 cmd_args[i] = action_params->action_per_category[i]; 14250 14251 err = wmi_unified_cmd_send(wmi_handle, buf, 14252 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 14253 if (err) { 14254 WMI_LOGE("Failed to send ap_ps_egap cmd"); 14255 wmi_buf_free(buf); 14256 return QDF_STATUS_E_FAILURE; 14257 } 14258 14259 return QDF_STATUS_SUCCESS; 14260 } 14261 14262 #ifdef FEATURE_WLAN_LPHB 14263 14264 /** 14265 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 14266 * @wmi_handle: wmi handle 14267 * @lphb_conf_req: configuration info 14268 * 14269 * Return: CDF status 14270 */ 14271 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 14272 wmi_hb_set_enable_cmd_fixed_param *params) 14273 { 14274 QDF_STATUS status; 14275 wmi_buf_t buf = NULL; 14276 uint8_t *buf_ptr; 14277 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 14278 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 14279 14280 14281 buf = wmi_buf_alloc(wmi_handle, len); 14282 if (!buf) { 14283 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14284 return QDF_STATUS_E_NOMEM; 14285 } 14286 14287 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14288 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 14289 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 14290 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 14291 WMITLV_GET_STRUCT_TLVLEN 14292 (wmi_hb_set_enable_cmd_fixed_param)); 14293 14294 /* fill in values */ 14295 hb_enable_fp->vdev_id = params->session; 14296 hb_enable_fp->enable = params->enable; 14297 hb_enable_fp->item = params->item; 14298 hb_enable_fp->session = params->session; 14299 14300 status = wmi_unified_cmd_send(wmi_handle, buf, 14301 len, WMI_HB_SET_ENABLE_CMDID); 14302 if (QDF_IS_STATUS_ERROR(status)) { 14303 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 14304 status); 14305 wmi_buf_free(buf); 14306 } 14307 14308 return status; 14309 } 14310 14311 /** 14312 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 14313 * @wmi_handle: wmi handle 14314 * @lphb_conf_req: lphb config request 14315 * 14316 * Return: CDF status 14317 */ 14318 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 14319 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 14320 { 14321 QDF_STATUS status; 14322 wmi_buf_t buf = NULL; 14323 uint8_t *buf_ptr; 14324 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 14325 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 14326 14327 buf = wmi_buf_alloc(wmi_handle, len); 14328 if (!buf) { 14329 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14330 return QDF_STATUS_E_NOMEM; 14331 } 14332 14333 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14334 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 14335 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 14336 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 14337 WMITLV_GET_STRUCT_TLVLEN 14338 (wmi_hb_set_tcp_params_cmd_fixed_param)); 14339 14340 /* fill in values */ 14341 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14342 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14343 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14344 hb_tcp_params_fp->seq = lphb_conf_req->seq; 14345 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 14346 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 14347 hb_tcp_params_fp->interval = lphb_conf_req->interval; 14348 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 14349 hb_tcp_params_fp->session = lphb_conf_req->session; 14350 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 14351 &lphb_conf_req->gateway_mac, 14352 sizeof(hb_tcp_params_fp->gateway_mac)); 14353 14354 status = wmi_unified_cmd_send(wmi_handle, buf, 14355 len, WMI_HB_SET_TCP_PARAMS_CMDID); 14356 if (QDF_IS_STATUS_ERROR(status)) { 14357 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 14358 status); 14359 wmi_buf_free(buf); 14360 } 14361 14362 return status; 14363 } 14364 14365 /** 14366 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 14367 * @wmi_handle: wmi handle 14368 * @lphb_conf_req: lphb config request 14369 * 14370 * Return: CDF status 14371 */ 14372 static 14373 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14374 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 14375 { 14376 QDF_STATUS status; 14377 wmi_buf_t buf = NULL; 14378 uint8_t *buf_ptr; 14379 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 14380 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 14381 14382 buf = wmi_buf_alloc(wmi_handle, len); 14383 if (!buf) { 14384 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14385 return QDF_STATUS_E_NOMEM; 14386 } 14387 14388 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14389 hb_tcp_filter_fp = 14390 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 14391 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 14392 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 14393 WMITLV_GET_STRUCT_TLVLEN 14394 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 14395 14396 /* fill in values */ 14397 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 14398 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 14399 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 14400 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 14401 memcpy((void *)&hb_tcp_filter_fp->filter, 14402 (void *)&g_hb_tcp_filter_fp->filter, 14403 WMI_WLAN_HB_MAX_FILTER_SIZE); 14404 14405 status = wmi_unified_cmd_send(wmi_handle, buf, 14406 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 14407 if (QDF_IS_STATUS_ERROR(status)) { 14408 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 14409 status); 14410 wmi_buf_free(buf); 14411 } 14412 14413 return status; 14414 } 14415 14416 /** 14417 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 14418 * @wmi_handle: wmi handle 14419 * @lphb_conf_req: lphb config request 14420 * 14421 * Return: CDF status 14422 */ 14423 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 14424 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 14425 { 14426 QDF_STATUS status; 14427 wmi_buf_t buf = NULL; 14428 uint8_t *buf_ptr; 14429 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 14430 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 14431 14432 buf = wmi_buf_alloc(wmi_handle, len); 14433 if (!buf) { 14434 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14435 return QDF_STATUS_E_NOMEM; 14436 } 14437 14438 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14439 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 14440 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 14441 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 14442 WMITLV_GET_STRUCT_TLVLEN 14443 (wmi_hb_set_udp_params_cmd_fixed_param)); 14444 14445 /* fill in values */ 14446 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14447 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14448 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14449 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 14450 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 14451 hb_udp_params_fp->interval = lphb_conf_req->interval; 14452 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 14453 hb_udp_params_fp->session = lphb_conf_req->session; 14454 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 14455 &lphb_conf_req->gateway_mac, 14456 sizeof(lphb_conf_req->gateway_mac)); 14457 14458 status = wmi_unified_cmd_send(wmi_handle, buf, 14459 len, WMI_HB_SET_UDP_PARAMS_CMDID); 14460 if (QDF_IS_STATUS_ERROR(status)) { 14461 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 14462 status); 14463 wmi_buf_free(buf); 14464 } 14465 14466 return status; 14467 } 14468 14469 /** 14470 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 14471 * @wmi_handle: wmi handle 14472 * @lphb_conf_req: lphb config request 14473 * 14474 * Return: CDF status 14475 */ 14476 static 14477 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14478 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 14479 { 14480 QDF_STATUS status; 14481 wmi_buf_t buf = NULL; 14482 uint8_t *buf_ptr; 14483 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 14484 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 14485 14486 buf = wmi_buf_alloc(wmi_handle, len); 14487 if (!buf) { 14488 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14489 return QDF_STATUS_E_NOMEM; 14490 } 14491 14492 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14493 hb_udp_filter_fp = 14494 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 14495 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 14496 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 14497 WMITLV_GET_STRUCT_TLVLEN 14498 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 14499 14500 /* fill in values */ 14501 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 14502 hb_udp_filter_fp->length = lphb_conf_req->length; 14503 hb_udp_filter_fp->offset = lphb_conf_req->offset; 14504 hb_udp_filter_fp->session = lphb_conf_req->session; 14505 memcpy((void *)&hb_udp_filter_fp->filter, 14506 (void *)&lphb_conf_req->filter, 14507 WMI_WLAN_HB_MAX_FILTER_SIZE); 14508 14509 status = wmi_unified_cmd_send(wmi_handle, buf, 14510 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 14511 if (QDF_IS_STATUS_ERROR(status)) { 14512 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 14513 status); 14514 wmi_buf_free(buf); 14515 } 14516 14517 return status; 14518 } 14519 #endif /* FEATURE_WLAN_LPHB */ 14520 14521 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 14522 struct pmo_hw_filter_params *req) 14523 { 14524 QDF_STATUS status; 14525 wmi_hw_data_filter_cmd_fixed_param *cmd; 14526 wmi_buf_t wmi_buf; 14527 14528 if (!req) { 14529 WMI_LOGE("req is null"); 14530 return QDF_STATUS_E_INVAL; 14531 } 14532 14533 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 14534 if (!wmi_buf) { 14535 WMI_LOGE(FL("Out of memory")); 14536 return QDF_STATUS_E_NOMEM; 14537 } 14538 14539 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 14540 WMITLV_SET_HDR(&cmd->tlv_header, 14541 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 14542 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 14543 cmd->vdev_id = req->vdev_id; 14544 cmd->enable = req->mode != PMO_HW_FILTER_DISABLED; 14545 cmd->hw_filter_bitmap = req->mode; 14546 14547 WMI_LOGD("configure hw filter (vdev_id: %d, mode: %d)", 14548 req->vdev_id, req->mode); 14549 14550 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 14551 WMI_HW_DATA_FILTER_CMDID); 14552 if (QDF_IS_STATUS_ERROR(status)) { 14553 WMI_LOGE("Failed to configure hw filter"); 14554 wmi_buf_free(wmi_buf); 14555 } 14556 14557 return status; 14558 } 14559 14560 /** 14561 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 14562 * @wmi_handle: wmi handle 14563 * @vdev_id: vdev id 14564 * @enable: Flag to enable/disable packet filter 14565 * 14566 * Return: QDF_STATUS_SUCCESS for success or error code 14567 */ 14568 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 14569 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 14570 { 14571 int32_t len; 14572 int ret = 0; 14573 wmi_buf_t buf; 14574 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 14575 14576 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 14577 14578 buf = wmi_buf_alloc(wmi_handle, len); 14579 if (!buf) { 14580 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14581 return QDF_STATUS_E_NOMEM; 14582 } 14583 14584 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 14585 WMITLV_SET_HDR(&cmd->tlv_header, 14586 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 14587 WMITLV_GET_STRUCT_TLVLEN( 14588 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 14589 14590 cmd->vdev_id = vdev_id; 14591 if (enable) 14592 cmd->enable = PACKET_FILTER_SET_ENABLE; 14593 else 14594 cmd->enable = PACKET_FILTER_SET_DISABLE; 14595 14596 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 14597 __func__, cmd->enable, vdev_id); 14598 14599 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14600 WMI_PACKET_FILTER_ENABLE_CMDID); 14601 if (ret) { 14602 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 14603 wmi_buf_free(buf); 14604 } 14605 14606 return ret; 14607 } 14608 14609 /** 14610 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 14611 * @wmi_handle: wmi handle 14612 * @vdev_id: vdev id 14613 * @rcv_filter_param: Packet filter parameters 14614 * @filter_id: Filter id 14615 * @enable: Flag to add/delete packet filter configuration 14616 * 14617 * Return: QDF_STATUS_SUCCESS for success or error code 14618 */ 14619 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 14620 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 14621 uint8_t filter_id, bool enable) 14622 { 14623 int len, i; 14624 int err = 0; 14625 wmi_buf_t buf; 14626 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 14627 14628 14629 /* allocate the memory */ 14630 len = sizeof(*cmd); 14631 buf = wmi_buf_alloc(wmi_handle, len); 14632 if (!buf) { 14633 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14634 return QDF_STATUS_E_NOMEM; 14635 } 14636 14637 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 14638 WMITLV_SET_HDR(&cmd->tlv_header, 14639 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 14640 WMITLV_GET_STRUCT_TLVLEN 14641 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 14642 14643 cmd->vdev_id = vdev_id; 14644 cmd->filter_id = filter_id; 14645 if (enable) 14646 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 14647 else 14648 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 14649 14650 if (enable) { 14651 cmd->num_params = QDF_MIN( 14652 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 14653 rcv_filter_param->num_params); 14654 cmd->filter_type = rcv_filter_param->filter_type; 14655 cmd->coalesce_time = rcv_filter_param->coalesce_time; 14656 14657 for (i = 0; i < cmd->num_params; i++) { 14658 cmd->paramsData[i].proto_type = 14659 rcv_filter_param->params_data[i].protocol_layer; 14660 cmd->paramsData[i].cmp_type = 14661 rcv_filter_param->params_data[i].compare_flag; 14662 cmd->paramsData[i].data_length = 14663 rcv_filter_param->params_data[i].data_length; 14664 cmd->paramsData[i].data_offset = 14665 rcv_filter_param->params_data[i].data_offset; 14666 memcpy(&cmd->paramsData[i].compareData, 14667 rcv_filter_param->params_data[i].compare_data, 14668 sizeof(cmd->paramsData[i].compareData)); 14669 memcpy(&cmd->paramsData[i].dataMask, 14670 rcv_filter_param->params_data[i].data_mask, 14671 sizeof(cmd->paramsData[i].dataMask)); 14672 } 14673 } 14674 14675 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 14676 cmd->filter_action, cmd->filter_id, cmd->num_params); 14677 /* send the command along with data */ 14678 err = wmi_unified_cmd_send(wmi_handle, buf, len, 14679 WMI_PACKET_FILTER_CONFIG_CMDID); 14680 if (err) { 14681 WMI_LOGE("Failed to send pkt_filter cmd"); 14682 wmi_buf_free(buf); 14683 return QDF_STATUS_E_FAILURE; 14684 } 14685 14686 return QDF_STATUS_SUCCESS; 14687 } 14688 #endif /* End of WLAN_PMO_ENABLE */ 14689 14690 /** 14691 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 14692 * @wmi_handle: wmi handle 14693 * @request: SSID hotlist set request 14694 * 14695 * Return: QDF_STATUS enumeration 14696 */ 14697 static QDF_STATUS 14698 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 14699 struct ssid_hotlist_request_params *request) 14700 { 14701 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 14702 wmi_buf_t wmi_buf; 14703 uint32_t len; 14704 uint32_t array_size; 14705 uint8_t *buf_ptr; 14706 14707 /* length of fixed portion */ 14708 len = sizeof(*cmd); 14709 14710 /* length of variable portion */ 14711 array_size = 14712 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 14713 len += WMI_TLV_HDR_SIZE + array_size; 14714 14715 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14716 if (!wmi_buf) { 14717 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14718 return QDF_STATUS_E_NOMEM; 14719 } 14720 14721 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 14722 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 14723 buf_ptr; 14724 WMITLV_SET_HDR 14725 (&cmd->tlv_header, 14726 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 14727 WMITLV_GET_STRUCT_TLVLEN 14728 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 14729 14730 cmd->request_id = request->request_id; 14731 cmd->requestor_id = 0; 14732 cmd->vdev_id = request->session_id; 14733 cmd->table_id = 0; 14734 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 14735 cmd->total_entries = request->ssid_count; 14736 cmd->num_entries_in_page = request->ssid_count; 14737 cmd->first_entry_index = 0; 14738 14739 buf_ptr += sizeof(*cmd); 14740 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 14741 14742 if (request->ssid_count) { 14743 wmi_extscan_hotlist_ssid_entry *entry; 14744 int i; 14745 14746 buf_ptr += WMI_TLV_HDR_SIZE; 14747 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 14748 for (i = 0; i < request->ssid_count; i++) { 14749 WMITLV_SET_HDR 14750 (entry, 14751 WMITLV_TAG_ARRAY_STRUC, 14752 WMITLV_GET_STRUCT_TLVLEN 14753 (wmi_extscan_hotlist_ssid_entry)); 14754 entry->ssid.ssid_len = request->ssids[i].ssid.length; 14755 qdf_mem_copy(entry->ssid.ssid, 14756 request->ssids[i].ssid.mac_ssid, 14757 request->ssids[i].ssid.length); 14758 entry->band = request->ssids[i].band; 14759 entry->min_rssi = request->ssids[i].rssi_low; 14760 entry->max_rssi = request->ssids[i].rssi_high; 14761 entry++; 14762 } 14763 cmd->mode = WMI_EXTSCAN_MODE_START; 14764 } else { 14765 cmd->mode = WMI_EXTSCAN_MODE_STOP; 14766 } 14767 14768 if (wmi_unified_cmd_send 14769 (wmi_handle, wmi_buf, len, 14770 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 14771 WMI_LOGE("%s: failed to send command", __func__); 14772 wmi_buf_free(wmi_buf); 14773 return QDF_STATUS_E_FAILURE; 14774 } 14775 14776 return QDF_STATUS_SUCCESS; 14777 } 14778 14779 /** 14780 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 14781 * @wmi_handle: wmi handle 14782 * @vdev_id: vdev id 14783 * 14784 * This function sends roam synch complete event to fw. 14785 * 14786 * Return: CDF STATUS 14787 */ 14788 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 14789 uint8_t vdev_id) 14790 { 14791 wmi_roam_synch_complete_fixed_param *cmd; 14792 wmi_buf_t wmi_buf; 14793 uint8_t *buf_ptr; 14794 uint16_t len; 14795 len = sizeof(wmi_roam_synch_complete_fixed_param); 14796 14797 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14798 if (!wmi_buf) { 14799 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14800 return QDF_STATUS_E_NOMEM; 14801 } 14802 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 14803 buf_ptr = (uint8_t *) cmd; 14804 WMITLV_SET_HDR(&cmd->tlv_header, 14805 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 14806 WMITLV_GET_STRUCT_TLVLEN 14807 (wmi_roam_synch_complete_fixed_param)); 14808 cmd->vdev_id = vdev_id; 14809 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 14810 WMI_ROAM_SYNCH_COMPLETE)) { 14811 WMI_LOGP("%s: failed to send roam synch confirmation", 14812 __func__); 14813 wmi_buf_free(wmi_buf); 14814 return QDF_STATUS_E_FAILURE; 14815 } 14816 14817 return QDF_STATUS_SUCCESS; 14818 } 14819 14820 /** 14821 * send_fw_test_cmd_tlv() - send fw test command to fw. 14822 * @wmi_handle: wmi handle 14823 * @wmi_fwtest: fw test command 14824 * 14825 * This function sends fw test command to fw. 14826 * 14827 * Return: CDF STATUS 14828 */ 14829 static 14830 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 14831 struct set_fwtest_params *wmi_fwtest) 14832 { 14833 wmi_fwtest_set_param_cmd_fixed_param *cmd; 14834 wmi_buf_t wmi_buf; 14835 uint16_t len; 14836 14837 len = sizeof(*cmd); 14838 14839 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14840 if (!wmi_buf) { 14841 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 14842 return QDF_STATUS_E_NOMEM; 14843 } 14844 14845 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 14846 WMITLV_SET_HDR(&cmd->tlv_header, 14847 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 14848 WMITLV_GET_STRUCT_TLVLEN( 14849 wmi_fwtest_set_param_cmd_fixed_param)); 14850 cmd->param_id = wmi_fwtest->arg; 14851 cmd->param_value = wmi_fwtest->value; 14852 14853 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 14854 WMI_FWTEST_CMDID)) { 14855 WMI_LOGP("%s: failed to send fw test command", __func__); 14856 qdf_nbuf_free(wmi_buf); 14857 return QDF_STATUS_E_FAILURE; 14858 } 14859 14860 return QDF_STATUS_SUCCESS; 14861 } 14862 14863 /** 14864 * send_unit_test_cmd_tlv() - send unit test command to fw. 14865 * @wmi_handle: wmi handle 14866 * @wmi_utest: unit test command 14867 * 14868 * This function send unit test command to fw. 14869 * 14870 * Return: CDF STATUS 14871 */ 14872 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 14873 struct wmi_unit_test_cmd *wmi_utest) 14874 { 14875 wmi_unit_test_cmd_fixed_param *cmd; 14876 wmi_buf_t wmi_buf; 14877 uint8_t *buf_ptr; 14878 int i; 14879 uint16_t len, args_tlv_len; 14880 uint32_t *unit_test_cmd_args; 14881 14882 args_tlv_len = 14883 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 14884 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 14885 14886 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14887 if (!wmi_buf) { 14888 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 14889 return QDF_STATUS_E_NOMEM; 14890 } 14891 14892 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 14893 buf_ptr = (uint8_t *) cmd; 14894 WMITLV_SET_HDR(&cmd->tlv_header, 14895 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 14896 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 14897 cmd->vdev_id = wmi_utest->vdev_id; 14898 cmd->module_id = wmi_utest->module_id; 14899 cmd->num_args = wmi_utest->num_args; 14900 cmd->diag_token = wmi_utest->diag_token; 14901 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 14902 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14903 (wmi_utest->num_args * sizeof(uint32_t))); 14904 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 14905 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 14906 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 14907 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 14908 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 14909 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 14910 unit_test_cmd_args[i] = wmi_utest->args[i]; 14911 WMI_LOGI("%d,", wmi_utest->args[i]); 14912 } 14913 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 14914 WMI_UNIT_TEST_CMDID)) { 14915 WMI_LOGP("%s: failed to send unit test command", __func__); 14916 wmi_buf_free(wmi_buf); 14917 return QDF_STATUS_E_FAILURE; 14918 } 14919 14920 return QDF_STATUS_SUCCESS; 14921 } 14922 14923 /** 14924 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 14925 * @wmi_handle: wma handle 14926 * @roaminvoke: roam invoke command 14927 * 14928 * Send roam invoke command to fw for fastreassoc. 14929 * 14930 * Return: CDF STATUS 14931 */ 14932 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 14933 struct wmi_roam_invoke_cmd *roaminvoke, 14934 uint32_t ch_hz) 14935 { 14936 wmi_roam_invoke_cmd_fixed_param *cmd; 14937 wmi_buf_t wmi_buf; 14938 u_int8_t *buf_ptr; 14939 u_int16_t len, args_tlv_len; 14940 uint32_t *channel_list; 14941 wmi_mac_addr *bssid_list; 14942 wmi_tlv_buf_len_param *buf_len_tlv; 14943 14944 /* Host sends only one channel and one bssid */ 14945 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 14946 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 14947 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 14948 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 14949 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14950 if (!wmi_buf) { 14951 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 14952 return QDF_STATUS_E_NOMEM; 14953 } 14954 14955 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 14956 buf_ptr = (u_int8_t *) cmd; 14957 WMITLV_SET_HDR(&cmd->tlv_header, 14958 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 14959 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 14960 cmd->vdev_id = roaminvoke->vdev_id; 14961 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 14962 if (roaminvoke->is_same_bssid) 14963 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 14964 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 14965 14966 if (roaminvoke->frame_len) { 14967 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 14968 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 14969 cmd->num_buf = 1; 14970 } else { 14971 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 14972 cmd->num_buf = 0; 14973 } 14974 14975 cmd->roam_ap_sel_mode = 0; 14976 cmd->roam_delay = 0; 14977 cmd->num_chan = 1; 14978 cmd->num_bssid = 1; 14979 14980 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 14981 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14982 (sizeof(u_int32_t))); 14983 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 14984 *channel_list = ch_hz; 14985 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 14986 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14987 (sizeof(wmi_mac_addr))); 14988 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 14989 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 14990 14991 /* move to next tlv i.e. bcn_prb_buf_list */ 14992 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 14993 14994 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14995 sizeof(wmi_tlv_buf_len_param)); 14996 14997 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 14998 buf_len_tlv->buf_len = roaminvoke->frame_len; 14999 15000 /* move to next tlv i.e. bcn_prb_frm */ 15001 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15002 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15003 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15004 15005 /* copy frame after the header */ 15006 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15007 roaminvoke->frame_buf, 15008 roaminvoke->frame_len); 15009 15010 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15011 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 15012 buf_ptr + WMI_TLV_HDR_SIZE, 15013 roaminvoke->frame_len); 15014 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15015 cmd->flags, cmd->roam_scan_mode, 15016 cmd->roam_ap_sel_mode, cmd->roam_delay, 15017 cmd->num_chan, cmd->num_bssid); 15018 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15019 15020 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15021 WMI_ROAM_INVOKE_CMDID)) { 15022 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15023 wmi_buf_free(wmi_buf); 15024 return QDF_STATUS_E_FAILURE; 15025 } 15026 15027 return QDF_STATUS_SUCCESS; 15028 } 15029 15030 /** 15031 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15032 * @wmi_handle: wmi handle 15033 * @command: command 15034 * @vdev_id: vdev id 15035 * 15036 * This function set roam offload command to fw. 15037 * 15038 * Return: CDF status 15039 */ 15040 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15041 uint32_t command, uint32_t vdev_id) 15042 { 15043 QDF_STATUS status; 15044 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15045 wmi_buf_t buf = NULL; 15046 int len; 15047 uint8_t *buf_ptr; 15048 15049 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15050 buf = wmi_buf_alloc(wmi_handle, len); 15051 if (!buf) { 15052 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15053 return QDF_STATUS_E_NOMEM; 15054 } 15055 15056 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15057 15058 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15059 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15060 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15061 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15062 cmd_fp->vdev_id = vdev_id; 15063 cmd_fp->command_arg = command; 15064 15065 status = wmi_unified_cmd_send(wmi_handle, buf, 15066 len, WMI_ROAM_SCAN_CMD); 15067 if (QDF_IS_STATUS_ERROR(status)) { 15068 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15069 status); 15070 goto error; 15071 } 15072 15073 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15074 return QDF_STATUS_SUCCESS; 15075 15076 error: 15077 wmi_buf_free(buf); 15078 15079 return status; 15080 } 15081 15082 /** 15083 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15084 * @wmi_handle: wmi handle 15085 * @ap_profile_p: ap profile 15086 * @vdev_id: vdev id 15087 * 15088 * Send WMI_ROAM_AP_PROFILE to firmware 15089 * 15090 * Return: CDF status 15091 */ 15092 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15093 struct ap_profile_params *ap_profile) 15094 { 15095 wmi_buf_t buf = NULL; 15096 QDF_STATUS status; 15097 int len; 15098 uint8_t *buf_ptr; 15099 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 15100 wmi_roam_cnd_scoring_param *score_param; 15101 wmi_ap_profile *profile; 15102 15103 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 15104 len += sizeof(*score_param); 15105 buf = wmi_buf_alloc(wmi_handle, len); 15106 if (!buf) { 15107 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15108 return QDF_STATUS_E_NOMEM; 15109 } 15110 15111 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15112 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 15113 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 15114 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 15115 WMITLV_GET_STRUCT_TLVLEN 15116 (wmi_roam_ap_profile_fixed_param)); 15117 /* fill in threshold values */ 15118 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 15119 roam_ap_profile_fp->id = 0; 15120 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 15121 15122 profile = (wmi_ap_profile *)buf_ptr; 15123 WMITLV_SET_HDR(&profile->tlv_header, 15124 WMITLV_TAG_STRUC_wmi_ap_profile, 15125 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 15126 profile->flags = ap_profile->profile.flags; 15127 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 15128 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 15129 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 15130 profile->ssid.ssid_len); 15131 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 15132 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 15133 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 15134 profile->rsn_mcastmgmtcipherset = 15135 ap_profile->profile.rsn_mcastmgmtcipherset; 15136 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 15137 15138 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", 15139 profile->flags, profile->rssi_threshold, 15140 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 15141 profile->rsn_authmode, profile->rsn_ucastcipherset, 15142 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 15143 profile->rssi_abs_thresh); 15144 15145 buf_ptr += sizeof(wmi_ap_profile); 15146 15147 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 15148 WMITLV_SET_HDR(&score_param->tlv_header, 15149 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 15150 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 15151 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 15152 score_param->rssi_weightage_pcnt = 15153 ap_profile->param.rssi_weightage; 15154 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 15155 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 15156 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 15157 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 15158 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 15159 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 15160 score_param->esp_qbss_weightage_pcnt = 15161 ap_profile->param.esp_qbss_weightage; 15162 score_param->beamforming_weightage_pcnt = 15163 ap_profile->param.beamforming_weightage; 15164 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 15165 score_param->oce_wan_weightage_pcnt = 15166 ap_profile->param.oce_wan_weightage; 15167 15168 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", 15169 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 15170 score_param->ht_weightage_pcnt, 15171 score_param->vht_weightage_pcnt, 15172 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 15173 score_param->band_weightage_pcnt, 15174 score_param->nss_weightage_pcnt, 15175 score_param->esp_qbss_weightage_pcnt, 15176 score_param->beamforming_weightage_pcnt, 15177 score_param->pcl_weightage_pcnt, 15178 score_param->oce_wan_weightage_pcnt); 15179 15180 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 15181 score_param->band_scoring.score_pcnt = 15182 ap_profile->param.band_index_score; 15183 score_param->nss_scoring.score_pcnt = 15184 ap_profile->param.nss_index_score; 15185 15186 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 15187 score_param->bw_scoring.score_pcnt, 15188 score_param->band_scoring.score_pcnt, 15189 score_param->nss_scoring.score_pcnt); 15190 15191 score_param->rssi_scoring.best_rssi_threshold = 15192 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 15193 score_param->rssi_scoring.good_rssi_threshold = 15194 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 15195 score_param->rssi_scoring.bad_rssi_threshold = 15196 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 15197 score_param->rssi_scoring.good_rssi_pcnt = 15198 ap_profile->param.rssi_scoring.good_rssi_pcnt; 15199 score_param->rssi_scoring.bad_rssi_pcnt = 15200 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 15201 score_param->rssi_scoring.good_bucket_size = 15202 ap_profile->param.rssi_scoring.good_bucket_size; 15203 score_param->rssi_scoring.bad_bucket_size = 15204 ap_profile->param.rssi_scoring.bad_bucket_size; 15205 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 15206 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 15207 15208 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 15209 score_param->rssi_scoring.best_rssi_threshold, 15210 score_param->rssi_scoring.good_rssi_threshold, 15211 score_param->rssi_scoring.bad_rssi_threshold, 15212 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 15213 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 15214 score_param->rssi_scoring.good_rssi_pcnt, 15215 score_param->rssi_scoring.bad_rssi_pcnt, 15216 score_param->rssi_scoring.good_bucket_size, 15217 score_param->rssi_scoring.bad_bucket_size); 15218 15219 score_param->esp_qbss_scoring.num_slot = 15220 ap_profile->param.esp_qbss_scoring.num_slot; 15221 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 15222 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 15223 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 15224 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 15225 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 15226 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 15227 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 15228 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 15229 15230 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15231 score_param->esp_qbss_scoring.num_slot, 15232 score_param->esp_qbss_scoring.score_pcnt3_to_0, 15233 score_param->esp_qbss_scoring.score_pcnt7_to_4, 15234 score_param->esp_qbss_scoring.score_pcnt11_to_8, 15235 score_param->esp_qbss_scoring.score_pcnt15_to_12); 15236 15237 score_param->oce_wan_scoring.num_slot = 15238 ap_profile->param.oce_wan_scoring.num_slot; 15239 score_param->oce_wan_scoring.score_pcnt3_to_0 = 15240 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 15241 score_param->oce_wan_scoring.score_pcnt7_to_4 = 15242 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 15243 score_param->oce_wan_scoring.score_pcnt11_to_8 = 15244 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 15245 score_param->oce_wan_scoring.score_pcnt15_to_12 = 15246 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 15247 15248 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15249 score_param->oce_wan_scoring.num_slot, 15250 score_param->oce_wan_scoring.score_pcnt3_to_0, 15251 score_param->oce_wan_scoring.score_pcnt7_to_4, 15252 score_param->oce_wan_scoring.score_pcnt11_to_8, 15253 score_param->oce_wan_scoring.score_pcnt15_to_12); 15254 15255 status = wmi_unified_cmd_send(wmi_handle, buf, 15256 len, WMI_ROAM_AP_PROFILE); 15257 if (QDF_IS_STATUS_ERROR(status)) { 15258 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 15259 status); 15260 wmi_buf_free(buf); 15261 } 15262 15263 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 15264 15265 return status; 15266 } 15267 15268 /** 15269 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 15270 * @wmi_handle: wmi handle 15271 * @scan_period: scan period 15272 * @scan_age: scan age 15273 * @vdev_id: vdev id 15274 * 15275 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 15276 * 15277 * Return: CDF status 15278 */ 15279 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 15280 uint32_t scan_period, 15281 uint32_t scan_age, 15282 uint32_t vdev_id) 15283 { 15284 QDF_STATUS status; 15285 wmi_buf_t buf = NULL; 15286 int len; 15287 uint8_t *buf_ptr; 15288 wmi_roam_scan_period_fixed_param *scan_period_fp; 15289 15290 /* Send scan period values */ 15291 len = sizeof(wmi_roam_scan_period_fixed_param); 15292 buf = wmi_buf_alloc(wmi_handle, len); 15293 if (!buf) { 15294 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15295 return QDF_STATUS_E_NOMEM; 15296 } 15297 15298 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15299 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 15300 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 15301 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 15302 WMITLV_GET_STRUCT_TLVLEN 15303 (wmi_roam_scan_period_fixed_param)); 15304 /* fill in scan period values */ 15305 scan_period_fp->vdev_id = vdev_id; 15306 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 15307 scan_period_fp->roam_scan_age = scan_age; 15308 15309 status = wmi_unified_cmd_send(wmi_handle, buf, 15310 len, WMI_ROAM_SCAN_PERIOD); 15311 if (QDF_IS_STATUS_ERROR(status)) { 15312 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 15313 status); 15314 goto error; 15315 } 15316 15317 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 15318 __func__, scan_period, scan_age); 15319 return QDF_STATUS_SUCCESS; 15320 error: 15321 wmi_buf_free(buf); 15322 15323 return status; 15324 } 15325 15326 /** 15327 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 15328 * @wmi_handle: wmi handle 15329 * @chan_count: channel count 15330 * @chan_list: channel list 15331 * @list_type: list type 15332 * @vdev_id: vdev id 15333 * 15334 * Set roam offload channel list. 15335 * 15336 * Return: CDF status 15337 */ 15338 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 15339 uint8_t chan_count, 15340 uint32_t *chan_list, 15341 uint8_t list_type, uint32_t vdev_id) 15342 { 15343 wmi_buf_t buf = NULL; 15344 QDF_STATUS status; 15345 int len, list_tlv_len; 15346 int i; 15347 uint8_t *buf_ptr; 15348 wmi_roam_chan_list_fixed_param *chan_list_fp; 15349 uint32_t *roam_chan_list_array; 15350 15351 if (chan_count == 0) { 15352 WMI_LOGD("%s : invalid number of channels %d", __func__, 15353 chan_count); 15354 return QDF_STATUS_E_EMPTY; 15355 } 15356 /* Channel list is a table of 2 TLV's */ 15357 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 15358 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 15359 buf = wmi_buf_alloc(wmi_handle, len); 15360 if (!buf) { 15361 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15362 return QDF_STATUS_E_NOMEM; 15363 } 15364 15365 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15366 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 15367 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 15368 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 15369 WMITLV_GET_STRUCT_TLVLEN 15370 (wmi_roam_chan_list_fixed_param)); 15371 chan_list_fp->vdev_id = vdev_id; 15372 chan_list_fp->num_chan = chan_count; 15373 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 15374 /* external app is controlling channel list */ 15375 chan_list_fp->chan_list_type = 15376 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 15377 } else { 15378 /* umac supplied occupied channel list in LFR */ 15379 chan_list_fp->chan_list_type = 15380 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 15381 } 15382 15383 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 15384 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15385 (chan_list_fp->num_chan * sizeof(uint32_t))); 15386 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15387 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 15388 for (i = 0; ((i < chan_list_fp->num_chan) && 15389 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 15390 roam_chan_list_array[i] = chan_list[i]; 15391 WMI_LOGI("%d,", roam_chan_list_array[i]); 15392 } 15393 15394 status = wmi_unified_cmd_send(wmi_handle, buf, 15395 len, WMI_ROAM_CHAN_LIST); 15396 if (QDF_IS_STATUS_ERROR(status)) { 15397 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 15398 status); 15399 goto error; 15400 } 15401 15402 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 15403 return QDF_STATUS_SUCCESS; 15404 error: 15405 wmi_buf_free(buf); 15406 15407 return status; 15408 } 15409 15410 /** 15411 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 15412 * @wmi_handle: wmi handle 15413 * @req_buf: per roam config buffer 15414 * 15415 * Return: QDF status 15416 */ 15417 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 15418 struct wmi_per_roam_config_req *req_buf) 15419 { 15420 wmi_buf_t buf = NULL; 15421 QDF_STATUS status; 15422 int len; 15423 uint8_t *buf_ptr; 15424 wmi_roam_per_config_fixed_param *wmi_per_config; 15425 15426 len = sizeof(wmi_roam_per_config_fixed_param); 15427 buf = wmi_buf_alloc(wmi_handle, len); 15428 if (!buf) { 15429 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15430 return QDF_STATUS_E_NOMEM; 15431 } 15432 15433 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15434 wmi_per_config = 15435 (wmi_roam_per_config_fixed_param *) buf_ptr; 15436 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 15437 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 15438 WMITLV_GET_STRUCT_TLVLEN 15439 (wmi_roam_per_config_fixed_param)); 15440 15441 /* fill in per roam config values */ 15442 wmi_per_config->vdev_id = req_buf->vdev_id; 15443 15444 wmi_per_config->enable = req_buf->per_config.enable; 15445 wmi_per_config->high_rate_thresh = 15446 (req_buf->per_config.tx_high_rate_thresh << 16) | 15447 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 15448 wmi_per_config->low_rate_thresh = 15449 (req_buf->per_config.tx_low_rate_thresh << 16) | 15450 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 15451 wmi_per_config->pkt_err_rate_thresh_pct = 15452 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 15453 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 15454 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 15455 wmi_per_config->pkt_err_rate_mon_time = 15456 (req_buf->per_config.tx_per_mon_time << 16) | 15457 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 15458 wmi_per_config->min_candidate_rssi = 15459 req_buf->per_config.min_candidate_rssi; 15460 15461 /* Send per roam config parameters */ 15462 status = wmi_unified_cmd_send(wmi_handle, buf, 15463 len, WMI_ROAM_PER_CONFIG_CMDID); 15464 if (QDF_IS_STATUS_ERROR(status)) { 15465 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 15466 status); 15467 wmi_buf_free(buf); 15468 return status; 15469 } 15470 15471 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 15472 req_buf->per_config.enable, req_buf->vdev_id); 15473 return QDF_STATUS_SUCCESS; 15474 } 15475 15476 /** 15477 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 15478 * @wmi_handle: wmi handle 15479 * @rssi_change_thresh: RSSI Change threshold 15480 * @bcn_rssi_weight: beacon RSSI weight 15481 * @vdev_id: vdev id 15482 * 15483 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 15484 * 15485 * Return: CDF status 15486 */ 15487 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 15488 uint32_t vdev_id, 15489 int32_t rssi_change_thresh, 15490 uint32_t bcn_rssi_weight, 15491 uint32_t hirssi_delay_btw_scans) 15492 { 15493 wmi_buf_t buf = NULL; 15494 QDF_STATUS status; 15495 int len; 15496 uint8_t *buf_ptr; 15497 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 15498 15499 /* Send rssi change parameters */ 15500 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 15501 buf = wmi_buf_alloc(wmi_handle, len); 15502 if (!buf) { 15503 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15504 return QDF_STATUS_E_NOMEM; 15505 } 15506 15507 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15508 rssi_change_fp = 15509 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 15510 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 15511 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 15512 WMITLV_GET_STRUCT_TLVLEN 15513 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 15514 /* fill in rssi change threshold (hysteresis) values */ 15515 rssi_change_fp->vdev_id = vdev_id; 15516 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 15517 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 15518 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 15519 15520 status = wmi_unified_cmd_send(wmi_handle, buf, 15521 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 15522 if (QDF_IS_STATUS_ERROR(status)) { 15523 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 15524 status); 15525 goto error; 15526 } 15527 15528 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 15529 rssi_change_thresh, bcn_rssi_weight); 15530 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 15531 return QDF_STATUS_SUCCESS; 15532 error: 15533 wmi_buf_free(buf); 15534 15535 return status; 15536 } 15537 15538 /** 15539 * send_set_active_bpf_mode_cmd_tlv() - configure active BPF mode in FW 15540 * @wmi_handle: the WMI handle 15541 * @vdev_id: the Id of the vdev to apply the configuration to 15542 * @ucast_mode: the active BPF mode to configure for unicast packets 15543 * @mcast_bcast_mode: the active BPF mode to configure for multicast/broadcast 15544 * packets 15545 * 15546 * Return: QDF status 15547 */ 15548 static QDF_STATUS send_set_active_bpf_mode_cmd_tlv(wmi_unified_t wmi_handle, 15549 uint8_t vdev_id, 15550 enum wmi_host_active_bpf_mode ucast_mode, 15551 enum wmi_host_active_bpf_mode mcast_bcast_mode) 15552 { 15553 const WMITLV_TAG_ID tag_id = 15554 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param; 15555 const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN( 15556 wmi_bpf_set_vdev_active_mode_cmd_fixed_param); 15557 QDF_STATUS status; 15558 wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd; 15559 wmi_buf_t buf; 15560 15561 WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)", 15562 vdev_id, ucast_mode, mcast_bcast_mode); 15563 15564 /* allocate command buffer */ 15565 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 15566 if (!buf) { 15567 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15568 return QDF_STATUS_E_NOMEM; 15569 } 15570 15571 /* set TLV header */ 15572 cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf); 15573 WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len); 15574 15575 /* populate data */ 15576 cmd->vdev_id = vdev_id; 15577 cmd->uc_mode = ucast_mode; 15578 cmd->mcbc_mode = mcast_bcast_mode; 15579 15580 /* send to FW */ 15581 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 15582 WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID); 15583 if (QDF_IS_STATUS_ERROR(status)) { 15584 WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d", 15585 status); 15586 wmi_buf_free(buf); 15587 return status; 15588 } 15589 15590 WMI_LOGD("Sent WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID successfully"); 15591 15592 return QDF_STATUS_SUCCESS; 15593 } 15594 15595 /** 15596 * send_power_dbg_cmd_tlv() - send power debug commands 15597 * @wmi_handle: wmi handle 15598 * @param: wmi power debug parameter 15599 * 15600 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 15601 * 15602 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15603 */ 15604 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 15605 struct wmi_power_dbg_params *param) 15606 { 15607 wmi_buf_t buf = NULL; 15608 QDF_STATUS status; 15609 int len, args_tlv_len; 15610 uint8_t *buf_ptr; 15611 uint8_t i; 15612 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 15613 uint32_t *cmd_args; 15614 15615 /* Prepare and send power debug cmd parameters */ 15616 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 15617 len = sizeof(*cmd) + args_tlv_len; 15618 buf = wmi_buf_alloc(wmi_handle, len); 15619 if (!buf) { 15620 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15621 return QDF_STATUS_E_NOMEM; 15622 } 15623 15624 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15625 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 15626 WMITLV_SET_HDR(&cmd->tlv_header, 15627 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 15628 WMITLV_GET_STRUCT_TLVLEN 15629 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 15630 15631 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15632 param->pdev_id); 15633 cmd->module_id = param->module_id; 15634 cmd->num_args = param->num_args; 15635 buf_ptr += sizeof(*cmd); 15636 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15637 (param->num_args * sizeof(uint32_t))); 15638 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15639 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 15640 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 15641 cmd_args[i] = param->args[i]; 15642 WMI_LOGI("%d,", param->args[i]); 15643 } 15644 15645 status = wmi_unified_cmd_send(wmi_handle, buf, 15646 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 15647 if (QDF_IS_STATUS_ERROR(status)) { 15648 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 15649 status); 15650 goto error; 15651 } 15652 15653 return QDF_STATUS_SUCCESS; 15654 error: 15655 wmi_buf_free(buf); 15656 15657 return status; 15658 } 15659 15660 /** 15661 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 15662 * @wmi_handle: wmi handle 15663 * @param: wmi multiple vdev restart req param 15664 * 15665 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 15666 * 15667 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15668 */ 15669 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 15670 wmi_unified_t wmi_handle, 15671 struct multiple_vdev_restart_params *param) 15672 { 15673 wmi_buf_t buf; 15674 QDF_STATUS qdf_status; 15675 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 15676 int i; 15677 uint8_t *buf_ptr; 15678 uint32_t *vdev_ids; 15679 wmi_channel *chan_info; 15680 struct channel_param *tchan_info; 15681 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 15682 15683 len += sizeof(wmi_channel); 15684 if (param->num_vdevs) 15685 len += sizeof(uint32_t) * param->num_vdevs; 15686 15687 buf = wmi_buf_alloc(wmi_handle, len); 15688 if (!buf) { 15689 WMI_LOGE("Failed to allocate memory\n"); 15690 qdf_status = QDF_STATUS_E_NOMEM; 15691 goto end; 15692 } 15693 15694 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15695 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 15696 buf_ptr; 15697 15698 WMITLV_SET_HDR(&cmd->tlv_header, 15699 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 15700 WMITLV_GET_STRUCT_TLVLEN 15701 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 15702 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15703 param->pdev_id); 15704 cmd->requestor_id = param->requestor_id; 15705 cmd->disable_hw_ack = param->disable_hw_ack; 15706 cmd->cac_duration_ms = param->cac_duration_ms; 15707 cmd->num_vdevs = param->num_vdevs; 15708 15709 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 15710 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 15711 " cmd->num_vdevs: %d ", 15712 __func__, cmd->pdev_id, cmd->requestor_id, 15713 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 15714 buf_ptr += sizeof(*cmd); 15715 15716 WMITLV_SET_HDR(buf_ptr, 15717 WMITLV_TAG_ARRAY_UINT32, 15718 sizeof(uint32_t) * param->num_vdevs); 15719 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15720 for (i = 0; i < param->num_vdevs; i++) { 15721 vdev_ids[i] = param->vdev_ids[i]; 15722 } 15723 15724 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 15725 15726 WMITLV_SET_HDR(buf_ptr, 15727 WMITLV_TAG_STRUC_wmi_channel, 15728 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 15729 chan_info = (wmi_channel *)buf_ptr; 15730 tchan_info = &(param->ch_param); 15731 chan_info->mhz = tchan_info->mhz; 15732 chan_info->band_center_freq1 = tchan_info->cfreq1; 15733 chan_info->band_center_freq2 = tchan_info->cfreq2; 15734 if (tchan_info->is_chan_passive) 15735 WMI_SET_CHANNEL_FLAG(chan_info, 15736 WMI_CHAN_FLAG_PASSIVE); 15737 if (tchan_info->dfs_set) 15738 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 15739 15740 if (tchan_info->allow_vht) 15741 WMI_SET_CHANNEL_FLAG(chan_info, 15742 WMI_CHAN_FLAG_ALLOW_VHT); 15743 else if (tchan_info->allow_ht) 15744 WMI_SET_CHANNEL_FLAG(chan_info, 15745 WMI_CHAN_FLAG_ALLOW_HT); 15746 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 15747 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 15748 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 15749 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 15750 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 15751 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 15752 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 15753 15754 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 15755 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 15756 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 15757 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 15758 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 15759 "tchan_info->reg_class_id: %d ," 15760 "tchan_info->maxregpower : %d ", __func__, 15761 tchan_info->is_chan_passive, tchan_info->dfs_set, 15762 tchan_info->allow_vht, tchan_info->allow_ht, 15763 tchan_info->antennamax, tchan_info->phy_mode, 15764 tchan_info->minpower, tchan_info->maxpower, 15765 tchan_info->maxregpower, tchan_info->reg_class_id, 15766 tchan_info->maxregpower); 15767 15768 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 15769 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 15770 15771 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15772 WMI_LOGE("%s: Failed to send\n", __func__); 15773 wmi_buf_free(buf); 15774 } 15775 15776 end: 15777 return qdf_status; 15778 } 15779 15780 /** 15781 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 15782 * @wmi_handle: wmi handle 15783 * @pdev_id: pdev id 15784 * 15785 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 15786 * 15787 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15788 */ 15789 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 15790 uint32_t pdev_id) 15791 { 15792 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 15793 wmi_buf_t buf; 15794 uint16_t len; 15795 QDF_STATUS ret; 15796 15797 len = sizeof(*cmd); 15798 buf = wmi_buf_alloc(wmi_handle, len); 15799 15800 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 15801 15802 if (!buf) { 15803 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15804 return QDF_STATUS_E_NOMEM; 15805 } 15806 15807 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 15808 wmi_buf_data(buf); 15809 15810 WMITLV_SET_HDR(&cmd->tlv_header, 15811 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 15812 WMITLV_GET_STRUCT_TLVLEN( 15813 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 15814 15815 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 15816 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15817 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 15818 if (QDF_IS_STATUS_ERROR(ret)) { 15819 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 15820 __func__, ret, pdev_id); 15821 wmi_buf_free(buf); 15822 return QDF_STATUS_E_FAILURE; 15823 } 15824 15825 return QDF_STATUS_SUCCESS; 15826 } 15827 15828 /** 15829 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 15830 * @wmi_handle: wmi handle 15831 * @pdev_id: pdev id 15832 * 15833 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 15834 * 15835 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15836 */ 15837 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 15838 uint32_t pdev_id) 15839 { 15840 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 15841 wmi_buf_t buf; 15842 uint16_t len; 15843 QDF_STATUS ret; 15844 15845 len = sizeof(*cmd); 15846 buf = wmi_buf_alloc(wmi_handle, len); 15847 15848 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 15849 15850 if (!buf) { 15851 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15852 return QDF_STATUS_E_NOMEM; 15853 } 15854 15855 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 15856 wmi_buf_data(buf); 15857 15858 WMITLV_SET_HDR(&cmd->tlv_header, 15859 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 15860 WMITLV_GET_STRUCT_TLVLEN( 15861 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 15862 15863 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 15864 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15865 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 15866 if (QDF_IS_STATUS_ERROR(ret)) { 15867 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 15868 __func__, ret, pdev_id); 15869 wmi_buf_free(buf); 15870 return QDF_STATUS_E_FAILURE; 15871 } 15872 15873 return QDF_STATUS_SUCCESS; 15874 } 15875 15876 /** 15877 * init_cmd_send_tlv() - send initialization cmd to fw 15878 * @wmi_handle: wmi handle 15879 * @param param: pointer to wmi init param 15880 * 15881 * Return: QDF_STATUS_SUCCESS for success or error code 15882 */ 15883 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 15884 struct wmi_init_cmd_param *param) 15885 { 15886 wmi_buf_t buf; 15887 wmi_init_cmd_fixed_param *cmd; 15888 uint8_t *buf_ptr; 15889 wmi_resource_config *resource_cfg; 15890 wlan_host_memory_chunk *host_mem_chunks; 15891 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 15892 uint16_t idx; 15893 int len; 15894 QDF_STATUS ret; 15895 15896 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 15897 WMI_TLV_HDR_SIZE; 15898 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 15899 15900 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 15901 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 15902 WMI_TLV_HDR_SIZE + 15903 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 15904 15905 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 15906 if (!buf) { 15907 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 15908 return QDF_STATUS_E_FAILURE; 15909 } 15910 15911 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15912 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 15913 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 15914 15915 host_mem_chunks = (wlan_host_memory_chunk *) 15916 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 15917 + WMI_TLV_HDR_SIZE); 15918 15919 WMITLV_SET_HDR(&cmd->tlv_header, 15920 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 15921 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 15922 15923 wmi_copy_resource_config(resource_cfg, param->res_cfg); 15924 WMITLV_SET_HDR(&resource_cfg->tlv_header, 15925 WMITLV_TAG_STRUC_wmi_resource_config, 15926 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 15927 15928 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 15929 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 15930 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 15931 WMITLV_GET_STRUCT_TLVLEN 15932 (wlan_host_memory_chunk)); 15933 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 15934 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 15935 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 15936 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 15937 "chunk %d len %d requested ,ptr 0x%x ", 15938 idx, host_mem_chunks[idx].size, 15939 host_mem_chunks[idx].ptr); 15940 } 15941 cmd->num_host_mem_chunks = param->num_mem_chunks; 15942 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 15943 15944 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 15945 WMITLV_TAG_ARRAY_STRUC, 15946 (sizeof(wlan_host_memory_chunk) * 15947 param->num_mem_chunks)); 15948 15949 /* Fill hw mode id config */ 15950 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 15951 15952 /* Fill fw_abi_vers */ 15953 copy_fw_abi_version_tlv(wmi_handle, cmd); 15954 15955 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 15956 if (QDF_IS_STATUS_ERROR(ret)) { 15957 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 15958 ret); 15959 wmi_buf_free(buf); 15960 } 15961 15962 return ret; 15963 15964 } 15965 15966 /** 15967 * send_addba_send_cmd_tlv() - send addba send command to fw 15968 * @wmi_handle: wmi handle 15969 * @param: pointer to delba send params 15970 * @macaddr: peer mac address 15971 * 15972 * Send WMI_ADDBA_SEND_CMDID command to firmware 15973 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 15974 */ 15975 static QDF_STATUS 15976 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 15977 uint8_t macaddr[IEEE80211_ADDR_LEN], 15978 struct addba_send_params *param) 15979 { 15980 wmi_addba_send_cmd_fixed_param *cmd; 15981 wmi_buf_t buf; 15982 uint16_t len; 15983 QDF_STATUS ret; 15984 15985 len = sizeof(*cmd); 15986 15987 buf = wmi_buf_alloc(wmi_handle, len); 15988 if (!buf) { 15989 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15990 return QDF_STATUS_E_NOMEM; 15991 } 15992 15993 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 15994 15995 WMITLV_SET_HDR(&cmd->tlv_header, 15996 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 15997 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 15998 15999 cmd->vdev_id = param->vdev_id; 16000 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16001 cmd->tid = param->tidno; 16002 cmd->buffersize = param->buffersize; 16003 16004 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 16005 if (QDF_IS_STATUS_ERROR(ret)) { 16006 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16007 wmi_buf_free(buf); 16008 return QDF_STATUS_E_FAILURE; 16009 } 16010 16011 return QDF_STATUS_SUCCESS; 16012 } 16013 16014 /** 16015 * send_delba_send_cmd_tlv() - send delba send command to fw 16016 * @wmi_handle: wmi handle 16017 * @param: pointer to delba send params 16018 * @macaddr: peer mac address 16019 * 16020 * Send WMI_DELBA_SEND_CMDID command to firmware 16021 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16022 */ 16023 static QDF_STATUS 16024 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 16025 uint8_t macaddr[IEEE80211_ADDR_LEN], 16026 struct delba_send_params *param) 16027 { 16028 wmi_delba_send_cmd_fixed_param *cmd; 16029 wmi_buf_t buf; 16030 uint16_t len; 16031 QDF_STATUS ret; 16032 16033 len = sizeof(*cmd); 16034 16035 buf = wmi_buf_alloc(wmi_handle, len); 16036 if (!buf) { 16037 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16038 return QDF_STATUS_E_NOMEM; 16039 } 16040 16041 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 16042 16043 WMITLV_SET_HDR(&cmd->tlv_header, 16044 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 16045 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 16046 16047 cmd->vdev_id = param->vdev_id; 16048 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16049 cmd->tid = param->tidno; 16050 cmd->initiator = param->initiator; 16051 cmd->reasoncode = param->reasoncode; 16052 16053 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 16054 if (QDF_IS_STATUS_ERROR(ret)) { 16055 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16056 wmi_buf_free(buf); 16057 return QDF_STATUS_E_FAILURE; 16058 } 16059 16060 return QDF_STATUS_SUCCESS; 16061 } 16062 16063 /** 16064 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 16065 * to fw 16066 * @wmi_handle: wmi handle 16067 * @param: pointer to addba clearresp params 16068 * @macaddr: peer mac address 16069 * Return: 0 for success or error code 16070 */ 16071 static QDF_STATUS 16072 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 16073 uint8_t macaddr[IEEE80211_ADDR_LEN], 16074 struct addba_clearresponse_params *param) 16075 { 16076 wmi_addba_clear_resp_cmd_fixed_param *cmd; 16077 wmi_buf_t buf; 16078 uint16_t len; 16079 QDF_STATUS ret; 16080 16081 len = sizeof(*cmd); 16082 16083 buf = wmi_buf_alloc(wmi_handle, len); 16084 if (!buf) { 16085 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 16086 return QDF_STATUS_E_FAILURE; 16087 } 16088 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 16089 16090 WMITLV_SET_HDR(&cmd->tlv_header, 16091 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 16092 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 16093 16094 cmd->vdev_id = param->vdev_id; 16095 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16096 16097 ret = wmi_unified_cmd_send(wmi_handle, 16098 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 16099 if (QDF_IS_STATUS_ERROR(ret)) { 16100 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16101 wmi_buf_free(buf); 16102 return QDF_STATUS_E_FAILURE; 16103 } 16104 16105 return QDF_STATUS_SUCCESS; 16106 } 16107 16108 /** 16109 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 16110 * @wmi_handle: wmi handle 16111 * @bcn_ctrl_param: pointer to bcn_offload_control param 16112 * 16113 * Return: QDF_STATUS_SUCCESS for success or error code 16114 */ 16115 static 16116 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 16117 struct bcn_offload_control *bcn_ctrl_param) 16118 { 16119 wmi_buf_t buf; 16120 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 16121 QDF_STATUS ret; 16122 uint32_t len; 16123 16124 len = sizeof(*cmd); 16125 16126 buf = wmi_buf_alloc(wmi_handle, len); 16127 if (!buf) { 16128 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16129 return QDF_STATUS_E_FAILURE; 16130 } 16131 16132 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 16133 WMITLV_SET_HDR(&cmd->tlv_header, 16134 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 16135 WMITLV_GET_STRUCT_TLVLEN 16136 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 16137 cmd->vdev_id = bcn_ctrl_param->vdev_id; 16138 switch (bcn_ctrl_param->bcn_ctrl_op) { 16139 case BCN_OFFLD_CTRL_TX_DISABLE: 16140 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 16141 break; 16142 case BCN_OFFLD_CTRL_TX_ENABLE: 16143 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 16144 break; 16145 case BCN_OFFLD_CTRL_SWBA_DISABLE: 16146 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 16147 break; 16148 case BCN_OFFLD_CTRL_SWBA_ENABLE: 16149 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 16150 break; 16151 default: 16152 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 16153 bcn_ctrl_param->bcn_ctrl_op); 16154 wmi_buf_free(buf); 16155 return QDF_STATUS_E_FAILURE; 16156 break; 16157 } 16158 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16159 WMI_BCN_OFFLOAD_CTRL_CMDID); 16160 16161 if (QDF_IS_STATUS_ERROR(ret)) { 16162 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 16163 ret); 16164 wmi_buf_free(buf); 16165 } 16166 16167 return ret; 16168 } 16169 16170 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 16171 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 16172 struct nan_datapath_initiator_req *ndp_req) 16173 { 16174 uint16_t len; 16175 wmi_buf_t buf; 16176 uint8_t *tlv_ptr; 16177 QDF_STATUS status; 16178 wmi_channel *ch_tlv; 16179 wmi_ndp_initiator_req_fixed_param *cmd; 16180 uint32_t passphrase_len, service_name_len; 16181 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 16182 16183 /* 16184 * WMI command expects 4 byte alligned len: 16185 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16186 */ 16187 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 16188 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 16189 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 16190 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 16191 service_name_len = 16192 qdf_roundup(ndp_req->service_name.service_name_len, 4); 16193 /* allocated memory for fixed params as well as variable size data */ 16194 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 16195 + ndp_cfg_len + ndp_app_info_len + pmk_len 16196 + passphrase_len + service_name_len; 16197 16198 buf = wmi_buf_alloc(wmi_handle, len); 16199 if (!buf) { 16200 WMI_LOGE("wmi_buf_alloc failed"); 16201 return QDF_STATUS_E_NOMEM; 16202 } 16203 16204 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 16205 WMITLV_SET_HDR(&cmd->tlv_header, 16206 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 16207 WMITLV_GET_STRUCT_TLVLEN( 16208 wmi_ndp_initiator_req_fixed_param)); 16209 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 16210 cmd->transaction_id = ndp_req->transaction_id; 16211 cmd->service_instance_id = ndp_req->service_instance_id; 16212 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 16213 &cmd->peer_discovery_mac_addr); 16214 16215 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 16216 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 16217 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 16218 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 16219 cmd->nan_csid = ndp_req->ncs_sk_type; 16220 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 16221 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 16222 16223 ch_tlv = (wmi_channel *)&cmd[1]; 16224 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 16225 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16226 ch_tlv->mhz = ndp_req->channel; 16227 tlv_ptr = (uint8_t *)&ch_tlv[1]; 16228 16229 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16230 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16231 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16232 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16233 16234 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16235 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16236 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 16237 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16238 16239 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16240 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 16241 cmd->nan_pmk_len); 16242 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16243 16244 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16245 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 16246 cmd->nan_passphrase_len); 16247 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16248 16249 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16250 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16251 ndp_req->service_name.service_name, 16252 cmd->nan_servicename_len); 16253 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16254 16255 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 16256 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 16257 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 16258 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16259 cmd->peer_discovery_mac_addr.mac_addr31to0, 16260 cmd->peer_discovery_mac_addr.mac_addr47to32); 16261 16262 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 16263 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16264 ndp_req->ndp_config.ndp_cfg, 16265 ndp_req->ndp_config.ndp_cfg_len); 16266 16267 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 16268 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16269 ndp_req->ndp_info.ndp_app_info, 16270 ndp_req->ndp_info.ndp_app_info_len); 16271 16272 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16273 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16274 ndp_req->pmk.pmk, cmd->nan_pmk_len); 16275 16276 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16277 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16278 ndp_req->passphrase.passphrase, 16279 cmd->nan_passphrase_len); 16280 16281 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16282 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16283 ndp_req->service_name.service_name, 16284 cmd->nan_servicename_len); 16285 16286 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 16287 WMI_NDP_INITIATOR_REQ_CMDID); 16288 16289 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16290 WMI_NDP_INITIATOR_REQ_CMDID); 16291 if (QDF_IS_STATUS_ERROR(status)) { 16292 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 16293 wmi_buf_free(buf); 16294 } 16295 16296 return status; 16297 } 16298 16299 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 16300 struct nan_datapath_responder_req *req) 16301 { 16302 uint16_t len; 16303 wmi_buf_t buf; 16304 uint8_t *tlv_ptr; 16305 QDF_STATUS status; 16306 wmi_ndp_responder_req_fixed_param *cmd; 16307 uint32_t passphrase_len, service_name_len; 16308 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 16309 16310 vdev_id = wlan_vdev_get_id(req->vdev); 16311 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 16312 vdev_id, req->transaction_id, 16313 req->ndp_rsp, 16314 req->ndp_instance_id, 16315 req->ndp_info.ndp_app_info_len); 16316 16317 /* 16318 * WMI command expects 4 byte alligned len: 16319 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16320 */ 16321 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 16322 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 16323 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 16324 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 16325 service_name_len = 16326 qdf_roundup(req->service_name.service_name_len, 4); 16327 16328 /* allocated memory for fixed params as well as variable size data */ 16329 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 16330 + pmk_len + passphrase_len + service_name_len; 16331 16332 buf = wmi_buf_alloc(wmi_handle, len); 16333 if (!buf) { 16334 WMI_LOGE("wmi_buf_alloc failed"); 16335 return QDF_STATUS_E_NOMEM; 16336 } 16337 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 16338 WMITLV_SET_HDR(&cmd->tlv_header, 16339 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 16340 WMITLV_GET_STRUCT_TLVLEN( 16341 wmi_ndp_responder_req_fixed_param)); 16342 cmd->vdev_id = vdev_id; 16343 cmd->transaction_id = req->transaction_id; 16344 cmd->ndp_instance_id = req->ndp_instance_id; 16345 cmd->rsp_code = req->ndp_rsp; 16346 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 16347 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 16348 cmd->nan_pmk_len = req->pmk.pmk_len; 16349 cmd->nan_csid = req->ncs_sk_type; 16350 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 16351 cmd->nan_servicename_len = req->service_name.service_name_len; 16352 16353 tlv_ptr = (uint8_t *)&cmd[1]; 16354 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16355 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16356 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16357 16358 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16359 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16360 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16361 req->ndp_info.ndp_app_info, 16362 req->ndp_info.ndp_app_info_len); 16363 16364 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16365 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16366 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 16367 cmd->nan_pmk_len); 16368 16369 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16370 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16371 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16372 req->passphrase.passphrase, 16373 cmd->nan_passphrase_len); 16374 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16375 16376 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16377 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16378 req->service_name.service_name, 16379 cmd->nan_servicename_len); 16380 16381 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16382 16383 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 16384 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 16385 16386 WMI_LOGD("ndp_config len: %d", 16387 req->ndp_config.ndp_cfg_len); 16388 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16389 req->ndp_config.ndp_cfg, 16390 req->ndp_config.ndp_cfg_len); 16391 16392 WMI_LOGD("ndp_app_info len: %d", 16393 req->ndp_info.ndp_app_info_len); 16394 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16395 req->ndp_info.ndp_app_info, 16396 req->ndp_info.ndp_app_info_len); 16397 16398 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16399 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16400 req->pmk.pmk, cmd->nan_pmk_len); 16401 16402 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16403 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16404 req->passphrase.passphrase, 16405 cmd->nan_passphrase_len); 16406 16407 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16408 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16409 req->service_name.service_name, 16410 cmd->nan_servicename_len); 16411 16412 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 16413 WMI_NDP_RESPONDER_REQ_CMDID); 16414 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16415 WMI_NDP_RESPONDER_REQ_CMDID); 16416 if (QDF_IS_STATUS_ERROR(status)) { 16417 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 16418 wmi_buf_free(buf); 16419 } 16420 return status; 16421 } 16422 16423 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 16424 struct nan_datapath_end_req *req) 16425 { 16426 uint16_t len; 16427 wmi_buf_t buf; 16428 QDF_STATUS status; 16429 uint32_t ndp_end_req_len, i; 16430 wmi_ndp_end_req *ndp_end_req_lst; 16431 wmi_ndp_end_req_fixed_param *cmd; 16432 16433 /* len of tlv following fixed param */ 16434 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 16435 /* above comes out to 4 byte alligned already, no need of padding */ 16436 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 16437 buf = wmi_buf_alloc(wmi_handle, len); 16438 if (!buf) { 16439 WMI_LOGE("Malloc failed"); 16440 return QDF_STATUS_E_NOMEM; 16441 } 16442 16443 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 16444 WMITLV_SET_HDR(&cmd->tlv_header, 16445 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 16446 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 16447 16448 cmd->transaction_id = req->transaction_id; 16449 16450 /* set tlv pointer to end of fixed param */ 16451 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 16452 ndp_end_req_len); 16453 16454 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 16455 WMI_TLV_HDR_SIZE); 16456 for (i = 0; i < req->num_ndp_instances; i++) { 16457 WMITLV_SET_HDR(&ndp_end_req_lst[i], 16458 WMITLV_TAG_ARRAY_FIXED_STRUC, 16459 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 16460 16461 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 16462 } 16463 16464 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 16465 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16466 WMI_NDP_END_REQ_CMDID); 16467 if (QDF_IS_STATUS_ERROR(status)) { 16468 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 16469 wmi_buf_free(buf); 16470 } 16471 16472 return status; 16473 } 16474 16475 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 16476 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 16477 { 16478 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 16479 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 16480 16481 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 16482 fixed_params = event->fixed_param; 16483 16484 rsp->vdev = 16485 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16486 fixed_params->vdev_id, 16487 WLAN_NAN_ID); 16488 if (!rsp->vdev) { 16489 WMI_LOGE("vdev is null"); 16490 return QDF_STATUS_E_INVAL; 16491 } 16492 16493 rsp->transaction_id = fixed_params->transaction_id; 16494 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16495 rsp->status = fixed_params->rsp_status; 16496 rsp->reason = fixed_params->reason_code; 16497 16498 return QDF_STATUS_SUCCESS; 16499 } 16500 16501 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 16502 uint8_t *data, struct nan_datapath_indication_event *rsp) 16503 { 16504 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 16505 wmi_ndp_indication_event_fixed_param *fixed_params; 16506 16507 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 16508 fixed_params = 16509 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 16510 16511 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16512 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16513 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16514 return QDF_STATUS_E_INVAL; 16515 } 16516 16517 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16518 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16519 fixed_params->ndp_app_info_len, 16520 event->num_ndp_app_info); 16521 return QDF_STATUS_E_INVAL; 16522 } 16523 16524 rsp->vdev = 16525 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16526 fixed_params->vdev_id, 16527 WLAN_NAN_ID); 16528 if (!rsp->vdev) { 16529 WMI_LOGE("vdev is null"); 16530 return QDF_STATUS_E_INVAL; 16531 } 16532 rsp->service_instance_id = fixed_params->service_instance_id; 16533 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16534 rsp->role = fixed_params->self_ndp_role; 16535 rsp->policy = fixed_params->accept_policy; 16536 16537 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16538 rsp->peer_mac_addr.bytes); 16539 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 16540 rsp->peer_discovery_mac_addr.bytes); 16541 16542 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 16543 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 16544 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 16545 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 16546 fixed_params->service_instance_id, 16547 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 16548 fixed_params->accept_policy, 16549 fixed_params->nan_csid, fixed_params->nan_scid_len, 16550 rsp->peer_mac_addr.bytes, 16551 rsp->peer_discovery_mac_addr.bytes); 16552 16553 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16554 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16555 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16556 16557 WMI_LOGD("ndp_app_info - %d bytes", 16558 fixed_params->ndp_app_info_len); 16559 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16560 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16561 16562 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 16563 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16564 rsp->ncs_sk_type = fixed_params->nan_csid; 16565 rsp->scid.scid_len = fixed_params->nan_scid_len; 16566 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 16567 rsp->ndp_config.ndp_cfg_len); 16568 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16569 rsp->ndp_info.ndp_app_info_len); 16570 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 16571 WMI_LOGD("scid hex dump:"); 16572 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16573 rsp->scid.scid, rsp->scid.scid_len); 16574 16575 return QDF_STATUS_SUCCESS; 16576 } 16577 16578 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 16579 uint8_t *data, struct nan_datapath_confirm_event *rsp) 16580 { 16581 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 16582 wmi_ndp_confirm_event_fixed_param *fixed_params; 16583 16584 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 16585 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 16586 WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) received. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d", 16587 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 16588 fixed_params->ndp_instance_id, fixed_params->rsp_code, 16589 fixed_params->reason_code, 16590 fixed_params->num_active_ndps_on_peer); 16591 16592 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16593 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16594 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16595 return QDF_STATUS_E_INVAL; 16596 } 16597 16598 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16599 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16600 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16601 16602 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16603 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16604 fixed_params->ndp_app_info_len, 16605 event->num_ndp_app_info); 16606 return QDF_STATUS_E_INVAL; 16607 } 16608 16609 WMI_LOGD("ndp_app_info - %d bytes", 16610 fixed_params->ndp_app_info_len); 16611 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 16612 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16613 16614 rsp->vdev = 16615 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16616 fixed_params->vdev_id, 16617 WLAN_NAN_ID); 16618 if (!rsp->vdev) { 16619 WMI_LOGE("vdev is null"); 16620 return QDF_STATUS_E_INVAL; 16621 } 16622 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16623 rsp->rsp_code = fixed_params->rsp_code; 16624 rsp->reason_code = fixed_params->reason_code; 16625 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 16626 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16627 rsp->peer_ndi_mac_addr.bytes); 16628 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16629 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16630 rsp->ndp_info.ndp_app_info_len); 16631 16632 return QDF_STATUS_SUCCESS; 16633 } 16634 16635 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 16636 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 16637 { 16638 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 16639 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 16640 16641 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 16642 fixed_params = event->fixed_param; 16643 16644 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", 16645 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 16646 rsp->peer_mac_addr.bytes, rsp->transaction_id, 16647 rsp->status, rsp->reason, rsp->create_peer); 16648 16649 rsp->vdev = 16650 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16651 fixed_params->vdev_id, 16652 WLAN_NAN_ID); 16653 if (!rsp->vdev) { 16654 WMI_LOGE("vdev is null"); 16655 return QDF_STATUS_E_INVAL; 16656 } 16657 rsp->transaction_id = fixed_params->transaction_id; 16658 rsp->reason = fixed_params->reason_code; 16659 rsp->status = fixed_params->rsp_status; 16660 rsp->create_peer = fixed_params->create_peer; 16661 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16662 rsp->peer_mac_addr.bytes); 16663 16664 return QDF_STATUS_SUCCESS; 16665 } 16666 16667 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 16668 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 16669 { 16670 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 16671 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 16672 16673 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 16674 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 16675 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 16676 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 16677 fixed_params->rsp_status, fixed_params->reason_code); 16678 16679 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 16680 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 16681 if (!rsp->vdev) { 16682 WMI_LOGE("vdev is null"); 16683 return QDF_STATUS_E_INVAL; 16684 } 16685 rsp->transaction_id = fixed_params->transaction_id; 16686 rsp->reason = fixed_params->reason_code; 16687 rsp->status = fixed_params->rsp_status; 16688 16689 return QDF_STATUS_SUCCESS; 16690 } 16691 16692 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 16693 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 16694 { 16695 uint32_t i, buf_size; 16696 wmi_ndp_end_indication *ind; 16697 struct qdf_mac_addr peer_addr; 16698 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 16699 16700 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 16701 ind = event->ndp_end_indication_list; 16702 16703 if (event->num_ndp_end_indication_list == 0) { 16704 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 16705 return QDF_STATUS_E_INVAL; 16706 } 16707 16708 WMI_LOGD("number of ndp instances = %d", 16709 event->num_ndp_end_indication_list); 16710 16711 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 16712 sizeof((*rsp)->ndp_map[0]))) { 16713 WMI_LOGE("num_ndp_end_ind_list %d too large", 16714 event->num_ndp_end_indication_list); 16715 return QDF_STATUS_E_INVAL; 16716 } 16717 16718 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 16719 sizeof((*rsp)->ndp_map[0]); 16720 *rsp = qdf_mem_malloc(buf_size); 16721 if (!(*rsp)) { 16722 WMI_LOGE("Failed to allocate memory"); 16723 return QDF_STATUS_E_NOMEM; 16724 } 16725 16726 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 16727 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 16728 if (!(*rsp)->vdev) { 16729 WMI_LOGE("vdev is null"); 16730 qdf_mem_free(*rsp); 16731 *rsp = NULL; 16732 return QDF_STATUS_E_INVAL; 16733 } 16734 16735 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 16736 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 16737 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 16738 peer_addr.bytes); 16739 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 16740 i, ind[i].type, ind[i].reason_code, 16741 ind[i].ndp_instance_id, 16742 ind[i].num_active_ndps_on_peer); 16743 /* Add each instance entry to the list */ 16744 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 16745 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 16746 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 16747 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 16748 (*rsp)->ndp_map[i].num_active_ndp_sessions = 16749 ind[i].num_active_ndps_on_peer; 16750 (*rsp)->ndp_map[i].type = ind[i].type; 16751 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 16752 } 16753 16754 return QDF_STATUS_SUCCESS; 16755 } 16756 16757 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 16758 uint8_t *data, struct nan_datapath_sch_update_event *ind) 16759 { 16760 uint8_t i; 16761 WMI_HOST_WLAN_PHY_MODE ch_mode; 16762 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 16763 wmi_ndl_schedule_update_fixed_param *fixed_params; 16764 16765 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 16766 fixed_params = event->fixed_param; 16767 16768 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 16769 fixed_params->flags, fixed_params->num_channels, 16770 fixed_params->num_ndp_instances); 16771 16772 ind->vdev = 16773 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16774 fixed_params->vdev_id, 16775 WLAN_NAN_ID); 16776 if (!ind->vdev) { 16777 WMI_LOGE("vdev is null"); 16778 return QDF_STATUS_E_INVAL; 16779 } 16780 16781 ind->flags = fixed_params->flags; 16782 ind->num_channels = fixed_params->num_channels; 16783 ind->num_ndp_instances = fixed_params->num_ndp_instances; 16784 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 16785 ind->peer_addr.bytes); 16786 16787 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 16788 WMI_LOGE(FL("uint32 overflow")); 16789 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 16790 return QDF_STATUS_E_INVAL; 16791 } 16792 16793 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 16794 sizeof(uint32_t) * ind->num_ndp_instances); 16795 16796 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 16797 WMI_LOGE(FL("too many channels")); 16798 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 16799 } 16800 for (i = 0; i < ind->num_channels; i++) { 16801 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 16802 ind->ch[i].nss = event->nss_list[i]; 16803 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 16804 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 16805 ch_mode); 16806 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 16807 ind->ch[i].channel, 16808 ind->ch[i].ch_width, 16809 ind->ch[i].nss); 16810 } 16811 16812 for (i = 0; i < fixed_params->num_ndp_instances; i++) 16813 WMI_LOGD(FL("instance_id[%d]: %d"), 16814 i, event->ndp_instance_list[i]); 16815 16816 return QDF_STATUS_SUCCESS; 16817 } 16818 16819 #endif 16820 16821 #ifdef QCA_SUPPORT_CP_STATS 16822 /** 16823 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 16824 * @wmi_handle: wma handle 16825 * @evt_buf: event buffer 16826 * @out_buff: buffer to populated after stats extraction 16827 * 16828 * Return: status of operation 16829 */ 16830 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 16831 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 16832 { 16833 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 16834 wmi_congestion_stats *congestion_stats; 16835 16836 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 16837 congestion_stats = param_buf->congestion_stats; 16838 if (!congestion_stats) { 16839 WMI_LOGD("%s: no cca stats in event buffer", __func__); 16840 return QDF_STATUS_E_INVAL; 16841 } 16842 16843 out_buff->vdev_id = congestion_stats->vdev_id; 16844 out_buff->congestion = congestion_stats->congestion; 16845 16846 WMI_LOGD("%s: cca stats event processed", __func__); 16847 return QDF_STATUS_SUCCESS; 16848 } 16849 #endif /* QCA_SUPPORT_CP_STATS */ 16850 16851 /** 16852 * save_service_bitmap_tlv() - save service bitmap 16853 * @wmi_handle: wmi handle 16854 * @param evt_buf: pointer to event buffer 16855 * @param bitmap_buf: bitmap buffer, for converged legacy support 16856 * 16857 * Return: QDF_STATUS 16858 */ 16859 static 16860 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16861 void *bitmap_buf) 16862 { 16863 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 16864 struct wmi_soc *soc = wmi_handle->soc; 16865 16866 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 16867 16868 /* If it is already allocated, use that buffer. This can happen 16869 * during target stop/start scenarios where host allocation is skipped. 16870 */ 16871 if (!soc->wmi_service_bitmap) { 16872 soc->wmi_service_bitmap = 16873 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 16874 if (!soc->wmi_service_bitmap) { 16875 WMI_LOGE("Failed memory allocation for service bitmap"); 16876 return QDF_STATUS_E_NOMEM; 16877 } 16878 } 16879 16880 qdf_mem_copy(soc->wmi_service_bitmap, 16881 param_buf->wmi_service_bitmap, 16882 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 16883 16884 if (bitmap_buf) 16885 qdf_mem_copy(bitmap_buf, 16886 param_buf->wmi_service_bitmap, 16887 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 16888 16889 return QDF_STATUS_SUCCESS; 16890 } 16891 16892 /** 16893 * save_ext_service_bitmap_tlv() - save extendend service bitmap 16894 * @wmi_handle: wmi handle 16895 * @param evt_buf: pointer to event buffer 16896 * @param bitmap_buf: bitmap buffer, for converged legacy support 16897 * 16898 * Return: QDF_STATUS 16899 */ 16900 static 16901 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16902 void *bitmap_buf) 16903 { 16904 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 16905 wmi_service_available_event_fixed_param *ev; 16906 struct wmi_soc *soc = wmi_handle->soc; 16907 16908 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 16909 16910 ev = param_buf->fixed_param; 16911 16912 /* If it is already allocated, use that buffer. This can happen 16913 * during target stop/start scenarios where host allocation is skipped. 16914 */ 16915 if (!soc->wmi_ext_service_bitmap) { 16916 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 16917 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 16918 if (!soc->wmi_ext_service_bitmap) { 16919 WMI_LOGE("Failed memory allocation for service bitmap"); 16920 return QDF_STATUS_E_NOMEM; 16921 } 16922 } 16923 16924 qdf_mem_copy(soc->wmi_ext_service_bitmap, 16925 ev->wmi_service_segment_bitmap, 16926 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 16927 16928 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 16929 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 16930 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 16931 16932 if (bitmap_buf) 16933 qdf_mem_copy(bitmap_buf, 16934 soc->wmi_ext_service_bitmap, 16935 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 16936 16937 return QDF_STATUS_SUCCESS; 16938 } 16939 /** 16940 * is_service_enabled_tlv() - Check if service enabled 16941 * @param wmi_handle: wmi handle 16942 * @param service_id: service identifier 16943 * 16944 * Return: 1 enabled, 0 disabled 16945 */ 16946 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 16947 uint32_t service_id) 16948 { 16949 struct wmi_soc *soc = wmi_handle->soc; 16950 16951 if (!soc->wmi_service_bitmap) { 16952 WMI_LOGE("WMI service bit map is not saved yet\n"); 16953 return false; 16954 } 16955 16956 /* if wmi_service_enabled was received with extended bitmap, 16957 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 16958 */ 16959 if (soc->wmi_ext_service_bitmap) 16960 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 16961 soc->wmi_ext_service_bitmap, 16962 service_id); 16963 16964 if (service_id >= WMI_MAX_SERVICE) { 16965 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 16966 service_id); 16967 return false; 16968 } 16969 16970 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 16971 service_id); 16972 } 16973 16974 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 16975 struct wlan_psoc_target_capability_info *cap) 16976 { 16977 /* except LDPC all flags are common betwen legacy and here 16978 * also IBFEER is not defined for TLV 16979 */ 16980 cap->ht_cap_info |= ev_target_cap & ( 16981 WMI_HT_CAP_ENABLED 16982 | WMI_HT_CAP_HT20_SGI 16983 | WMI_HT_CAP_DYNAMIC_SMPS 16984 | WMI_HT_CAP_TX_STBC 16985 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 16986 | WMI_HT_CAP_RX_STBC 16987 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 16988 | WMI_HT_CAP_LDPC 16989 | WMI_HT_CAP_L_SIG_TXOP_PROT 16990 | WMI_HT_CAP_MPDU_DENSITY 16991 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 16992 | WMI_HT_CAP_HT40_SGI); 16993 if (ev_target_cap & WMI_HT_CAP_LDPC) 16994 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 16995 WMI_HOST_HT_CAP_TX_LDPC; 16996 } 16997 /** 16998 * extract_service_ready_tlv() - extract service ready event 16999 * @wmi_handle: wmi handle 17000 * @param evt_buf: pointer to received event buffer 17001 * @param cap: pointer to hold target capability information extracted from even 17002 * 17003 * Return: QDF_STATUS_SUCCESS for success or error code 17004 */ 17005 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17006 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17007 { 17008 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17009 wmi_service_ready_event_fixed_param *ev; 17010 17011 17012 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17013 17014 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17015 if (!ev) { 17016 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17017 return QDF_STATUS_E_FAILURE; 17018 } 17019 17020 cap->phy_capability = ev->phy_capability; 17021 cap->max_frag_entry = ev->max_frag_entry; 17022 cap->num_rf_chains = ev->num_rf_chains; 17023 copy_ht_cap_info(ev->ht_cap_info, cap); 17024 cap->vht_cap_info = ev->vht_cap_info; 17025 cap->vht_supp_mcs = ev->vht_supp_mcs; 17026 cap->hw_min_tx_power = ev->hw_min_tx_power; 17027 cap->hw_max_tx_power = ev->hw_max_tx_power; 17028 cap->sys_cap_info = ev->sys_cap_info; 17029 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17030 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17031 cap->max_num_scan_channels = ev->max_num_scan_channels; 17032 cap->max_supported_macs = ev->max_supported_macs; 17033 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17034 cap->txrx_chainmask = ev->txrx_chainmask; 17035 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17036 cap->num_msdu_desc = ev->num_msdu_desc; 17037 cap->fw_version = ev->fw_build_vers; 17038 /* fw_version_1 is not available in TLV. */ 17039 cap->fw_version_1 = 0; 17040 17041 return QDF_STATUS_SUCCESS; 17042 } 17043 17044 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 17045 * to host internal WMI_HOST_REGDMN_MODE values. 17046 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 17047 * host currently. Add this in the future if required. 17048 * 11AX (Phase II) : 11ax related values are not currently 17049 * advertised separately by FW. As part of phase II regulatory bring-up, 17050 * finalize the advertisement mechanism. 17051 * @target_wireless_mode: target wireless mode received in message 17052 * 17053 * Return: returns the host internal wireless mode. 17054 */ 17055 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 17056 { 17057 17058 uint32_t wireless_modes = 0; 17059 17060 if (target_wireless_mode & REGDMN_MODE_11A) 17061 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 17062 17063 if (target_wireless_mode & REGDMN_MODE_TURBO) 17064 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 17065 17066 if (target_wireless_mode & REGDMN_MODE_11B) 17067 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 17068 17069 if (target_wireless_mode & REGDMN_MODE_PUREG) 17070 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 17071 17072 if (target_wireless_mode & REGDMN_MODE_11G) 17073 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 17074 17075 if (target_wireless_mode & REGDMN_MODE_108G) 17076 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 17077 17078 if (target_wireless_mode & REGDMN_MODE_108A) 17079 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 17080 17081 if (target_wireless_mode & REGDMN_MODE_XR) 17082 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 17083 17084 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 17085 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 17086 17087 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 17088 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 17089 17090 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 17091 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 17092 17093 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 17094 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 17095 17096 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 17097 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 17098 17099 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 17100 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 17101 17102 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 17103 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 17104 17105 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 17106 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 17107 17108 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 17109 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 17110 17111 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 17112 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 17113 17114 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 17115 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 17116 17117 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 17118 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 17119 17120 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 17121 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 17122 17123 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 17124 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 17125 17126 return wireless_modes; 17127 } 17128 17129 /** 17130 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 17131 * @wmi_handle: wmi handle 17132 * @param evt_buf: Pointer to event buffer 17133 * @param cap: pointer to hold HAL reg capabilities 17134 * 17135 * Return: QDF_STATUS_SUCCESS for success or error code 17136 */ 17137 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 17138 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 17139 { 17140 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17141 17142 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17143 17144 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 17145 sizeof(uint32_t)), 17146 sizeof(struct wlan_psoc_hal_reg_capability)); 17147 17148 cap->wireless_modes = convert_wireless_modes_tlv( 17149 param_buf->hal_reg_capabilities->wireless_modes); 17150 17151 return QDF_STATUS_SUCCESS; 17152 } 17153 17154 /** 17155 * extract_host_mem_req_tlv() - Extract host memory request event 17156 * @wmi_handle: wmi handle 17157 * @param evt_buf: pointer to event buffer 17158 * @param num_entries: pointer to hold number of entries requested 17159 * 17160 * Return: Number of entries requested 17161 */ 17162 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 17163 void *evt_buf, uint8_t *num_entries) 17164 { 17165 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17166 wmi_service_ready_event_fixed_param *ev; 17167 17168 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17169 17170 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17171 if (!ev) { 17172 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17173 return NULL; 17174 } 17175 17176 *num_entries = ev->num_mem_reqs; 17177 17178 return (host_mem_req *)param_buf->mem_reqs; 17179 } 17180 17181 /** 17182 * save_fw_version_in_service_ready_tlv() - Save fw version in service 17183 * ready function 17184 * @wmi_handle: wmi handle 17185 * @param evt_buf: pointer to event buffer 17186 * 17187 * Return: QDF_STATUS_SUCCESS for success or error code 17188 */ 17189 static QDF_STATUS 17190 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 17191 { 17192 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17193 wmi_service_ready_event_fixed_param *ev; 17194 17195 17196 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17197 17198 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17199 if (!ev) { 17200 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17201 return QDF_STATUS_E_FAILURE; 17202 } 17203 17204 /*Save fw version from service ready message */ 17205 /*This will be used while sending INIT message */ 17206 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 17207 sizeof(wmi_handle->fw_abi_version)); 17208 17209 return QDF_STATUS_SUCCESS; 17210 } 17211 17212 /** 17213 * ready_extract_init_status_tlv() - Extract init status from ready event 17214 * @wmi_handle: wmi handle 17215 * @param evt_buf: Pointer to event buffer 17216 * 17217 * Return: ready status 17218 */ 17219 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 17220 void *evt_buf) 17221 { 17222 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17223 wmi_ready_event_fixed_param *ev = NULL; 17224 17225 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17226 ev = param_buf->fixed_param; 17227 17228 qdf_print("%s:%d\n", __func__, ev->status); 17229 17230 return ev->status; 17231 } 17232 17233 /** 17234 * ready_extract_mac_addr_tlv() - extract mac address from ready event 17235 * @wmi_handle: wmi handle 17236 * @param evt_buf: pointer to event buffer 17237 * @param macaddr: Pointer to hold MAC address 17238 * 17239 * Return: QDF_STATUS_SUCCESS for success or error code 17240 */ 17241 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 17242 void *evt_buf, uint8_t *macaddr) 17243 { 17244 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17245 wmi_ready_event_fixed_param *ev = NULL; 17246 17247 17248 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17249 ev = param_buf->fixed_param; 17250 17251 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 17252 17253 return QDF_STATUS_SUCCESS; 17254 } 17255 17256 /** 17257 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 17258 * @wmi_handle: wmi handle 17259 * @param evt_buf: pointer to event buffer 17260 * @param macaddr: Pointer to hold number of MAC addresses 17261 * 17262 * Return: Pointer to addr list 17263 */ 17264 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 17265 void *evt_buf, uint8_t *num_mac) 17266 { 17267 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17268 wmi_ready_event_fixed_param *ev = NULL; 17269 17270 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17271 ev = param_buf->fixed_param; 17272 17273 *num_mac = ev->num_extra_mac_addr; 17274 17275 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 17276 } 17277 17278 /** 17279 * extract_ready_params_tlv() - Extract data from ready event apart from 17280 * status, macaddr and version. 17281 * @wmi_handle: Pointer to WMI handle. 17282 * @evt_buf: Pointer to Ready event buffer. 17283 * @ev_param: Pointer to host defined struct to copy the data from event. 17284 * 17285 * Return: QDF_STATUS_SUCCESS on success. 17286 */ 17287 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 17288 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 17289 { 17290 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17291 wmi_ready_event_fixed_param *ev = NULL; 17292 17293 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17294 ev = param_buf->fixed_param; 17295 17296 ev_param->status = ev->status; 17297 ev_param->num_dscp_table = ev->num_dscp_table; 17298 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 17299 ev_param->num_total_peer = ev->num_total_peers; 17300 ev_param->num_extra_peer = ev->num_extra_peers; 17301 /* Agile_cap in ready event is not supported in TLV target */ 17302 ev_param->agile_capability = false; 17303 17304 return QDF_STATUS_SUCCESS; 17305 } 17306 17307 /** 17308 * extract_dbglog_data_len_tlv() - extract debuglog data length 17309 * @wmi_handle: wmi handle 17310 * @param evt_buf: pointer to event buffer 17311 * 17312 * Return: length 17313 */ 17314 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 17315 void *evt_buf, uint32_t *len) 17316 { 17317 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 17318 17319 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 17320 17321 *len = param_buf->num_bufp; 17322 17323 return param_buf->bufp; 17324 } 17325 17326 /** 17327 * extract_vdev_start_resp_tlv() - extract vdev start response 17328 * @wmi_handle: wmi handle 17329 * @param evt_buf: pointer to event buffer 17330 * @param vdev_rsp: Pointer to hold vdev response 17331 * 17332 * Return: QDF_STATUS_SUCCESS for success or error code 17333 */ 17334 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 17335 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 17336 { 17337 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 17338 wmi_vdev_start_response_event_fixed_param *ev; 17339 17340 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 17341 if (!param_buf) { 17342 qdf_print("Invalid start response event buffer\n"); 17343 return QDF_STATUS_E_INVAL; 17344 } 17345 17346 ev = param_buf->fixed_param; 17347 if (!ev) { 17348 qdf_print("Invalid start response event buffer\n"); 17349 return QDF_STATUS_E_INVAL; 17350 } 17351 17352 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 17353 17354 vdev_rsp->vdev_id = ev->vdev_id; 17355 vdev_rsp->requestor_id = ev->requestor_id; 17356 switch (ev->resp_type) { 17357 case WMI_VDEV_START_RESP_EVENT: 17358 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 17359 break; 17360 case WMI_VDEV_RESTART_RESP_EVENT: 17361 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 17362 break; 17363 default: 17364 qdf_print("Invalid start response event buffer\n"); 17365 break; 17366 }; 17367 vdev_rsp->status = ev->status; 17368 vdev_rsp->chain_mask = ev->chain_mask; 17369 vdev_rsp->smps_mode = ev->smps_mode; 17370 vdev_rsp->mac_id = ev->mac_id; 17371 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 17372 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 17373 17374 return QDF_STATUS_SUCCESS; 17375 } 17376 17377 /** 17378 * extract_vdev_delete_resp_tlv() - extract vdev delete response 17379 * @wmi_handle: wmi handle 17380 * @param evt_buf: pointer to event buffer 17381 * @param delete_rsp: Pointer to hold vdev delete response 17382 * 17383 * Return: QDF_STATUS_SUCCESS for success or error code 17384 */ 17385 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 17386 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 17387 { 17388 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 17389 wmi_vdev_delete_resp_event_fixed_param *ev; 17390 17391 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 17392 if (!param_buf) { 17393 WMI_LOGE("Invalid vdev delete response event buffer\n"); 17394 return QDF_STATUS_E_INVAL; 17395 } 17396 17397 ev = param_buf->fixed_param; 17398 if (!ev) { 17399 WMI_LOGE("Invalid vdev delete response event\n"); 17400 return QDF_STATUS_E_INVAL; 17401 } 17402 17403 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 17404 delete_rsp->vdev_id = ev->vdev_id; 17405 17406 return QDF_STATUS_SUCCESS; 17407 } 17408 17409 17410 /** 17411 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 17412 * @wmi_handle: wmi handle 17413 * @param evt_buf: pointer to event buffer 17414 * @param num_vdevs: Pointer to hold num vdev 17415 * 17416 * Return: QDF_STATUS_SUCCESS for success or error code 17417 */ 17418 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17419 void *evt_buf, uint32_t *num_vdevs) 17420 { 17421 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17422 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17423 uint32_t vdev_map; 17424 17425 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 17426 if (!param_buf) { 17427 qdf_print("Invalid tbtt update ext event buffer\n"); 17428 return QDF_STATUS_E_INVAL; 17429 } 17430 tbtt_offset_event = param_buf->fixed_param; 17431 vdev_map = tbtt_offset_event->vdev_map; 17432 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 17433 17434 return QDF_STATUS_SUCCESS; 17435 } 17436 17437 /** 17438 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 17439 * @wmi_handle: wmi handle 17440 * @param evt_buf: pointer to event buffer 17441 * @param num_vdevs: Pointer to hold num vdev 17442 * 17443 * Return: QDF_STATUS_SUCCESS for success or error code 17444 */ 17445 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17446 void *evt_buf, uint32_t *num_vdevs) 17447 { 17448 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17449 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 17450 17451 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17452 if (!param_buf) { 17453 qdf_print("Invalid tbtt update ext event buffer\n"); 17454 return QDF_STATUS_E_INVAL; 17455 } 17456 tbtt_offset_ext_event = param_buf->fixed_param; 17457 17458 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 17459 17460 return QDF_STATUS_SUCCESS; 17461 } 17462 17463 /** 17464 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 17465 * @wmi_handle: wmi handle 17466 * @param evt_buf: pointer to event buffer 17467 * @param idx: Index referring to a vdev 17468 * @param tbtt_param: Pointer to tbttoffset event param 17469 * 17470 * Return: QDF_STATUS_SUCCESS for success or error code 17471 */ 17472 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 17473 void *evt_buf, uint8_t idx, 17474 struct tbttoffset_params *tbtt_param) 17475 { 17476 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17477 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17478 uint32_t vdev_map; 17479 17480 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 17481 if (!param_buf) { 17482 qdf_print("Invalid tbtt update event buffer\n"); 17483 return QDF_STATUS_E_INVAL; 17484 } 17485 17486 tbtt_offset_event = param_buf->fixed_param; 17487 vdev_map = tbtt_offset_event->vdev_map; 17488 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 17489 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 17490 return QDF_STATUS_E_INVAL; 17491 tbtt_param->tbttoffset = 17492 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 17493 17494 return QDF_STATUS_SUCCESS; 17495 } 17496 17497 /** 17498 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 17499 * @wmi_handle: wmi handle 17500 * @param evt_buf: pointer to event buffer 17501 * @param idx: Index referring to a vdev 17502 * @param tbtt_param: Pointer to tbttoffset event param 17503 * 17504 * Return: QDF_STATUS_SUCCESS for success or error code 17505 */ 17506 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 17507 void *evt_buf, uint8_t idx, 17508 struct tbttoffset_params *tbtt_param) 17509 { 17510 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17511 wmi_tbtt_offset_info *tbtt_offset_info; 17512 17513 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17514 if (!param_buf) { 17515 qdf_print("Invalid tbtt update event buffer\n"); 17516 return QDF_STATUS_E_INVAL; 17517 } 17518 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 17519 17520 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 17521 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 17522 17523 return QDF_STATUS_SUCCESS; 17524 } 17525 17526 /** 17527 * extract_mgmt_rx_params_tlv() - extract management rx params from event 17528 * @wmi_handle: wmi handle 17529 * @param evt_buf: pointer to event buffer 17530 * @param hdr: Pointer to hold header 17531 * @param bufp: Pointer to hold pointer to rx param buffer 17532 * 17533 * Return: QDF_STATUS_SUCCESS for success or error code 17534 */ 17535 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 17536 void *evt_buf, struct mgmt_rx_event_params *hdr, 17537 uint8_t **bufp) 17538 { 17539 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 17540 wmi_mgmt_rx_hdr *ev_hdr = NULL; 17541 int i; 17542 17543 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 17544 if (!param_tlvs) { 17545 WMI_LOGE("Get NULL point message from FW"); 17546 return QDF_STATUS_E_INVAL; 17547 } 17548 17549 ev_hdr = param_tlvs->hdr; 17550 if (!hdr) { 17551 WMI_LOGE("Rx event is NULL"); 17552 return QDF_STATUS_E_INVAL; 17553 } 17554 17555 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17556 ev_hdr->pdev_id); 17557 17558 hdr->channel = ev_hdr->channel; 17559 hdr->snr = ev_hdr->snr; 17560 hdr->rate = ev_hdr->rate; 17561 hdr->phy_mode = ev_hdr->phy_mode; 17562 hdr->buf_len = ev_hdr->buf_len; 17563 hdr->status = ev_hdr->status; 17564 hdr->flags = ev_hdr->flags; 17565 hdr->rssi = ev_hdr->rssi; 17566 hdr->tsf_delta = ev_hdr->tsf_delta; 17567 for (i = 0; i < ATH_MAX_ANTENNA; i++) 17568 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 17569 17570 *bufp = param_tlvs->bufp; 17571 17572 return QDF_STATUS_SUCCESS; 17573 } 17574 17575 /** 17576 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 17577 * @wmi_handle: wmi handle 17578 * @param evt_buf: pointer to event buffer 17579 * @param vdev_id: Pointer to hold vdev identifier 17580 * 17581 * Return: QDF_STATUS_SUCCESS for success or error code 17582 */ 17583 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 17584 void *evt_buf, uint32_t *vdev_id) 17585 { 17586 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 17587 wmi_vdev_stopped_event_fixed_param *resp_event; 17588 17589 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 17590 if (!param_buf) { 17591 WMI_LOGE("Invalid event buffer"); 17592 return QDF_STATUS_E_INVAL; 17593 } 17594 resp_event = param_buf->fixed_param; 17595 *vdev_id = resp_event->vdev_id; 17596 17597 return QDF_STATUS_SUCCESS; 17598 } 17599 17600 /** 17601 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 17602 * @wmi_handle: wmi handle 17603 * @param evt_buf: pointer to event buffer 17604 * @param param: Pointer to hold roam param 17605 * 17606 * Return: QDF_STATUS_SUCCESS for success or error code 17607 */ 17608 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 17609 void *evt_buf, wmi_host_roam_event *param) 17610 { 17611 WMI_ROAM_EVENTID_param_tlvs *param_buf; 17612 wmi_roam_event_fixed_param *evt; 17613 17614 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 17615 if (!param_buf) { 17616 WMI_LOGE("Invalid roam event buffer"); 17617 return QDF_STATUS_E_INVAL; 17618 } 17619 17620 evt = param_buf->fixed_param; 17621 qdf_mem_zero(param, sizeof(*param)); 17622 17623 param->vdev_id = evt->vdev_id; 17624 param->reason = evt->reason; 17625 param->rssi = evt->rssi; 17626 17627 return QDF_STATUS_SUCCESS; 17628 } 17629 17630 /** 17631 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 17632 * @wmi_handle: wmi handle 17633 * @param evt_buf: pointer to event buffer 17634 * @param param: Pointer to hold vdev scan param 17635 * 17636 * Return: QDF_STATUS_SUCCESS for success or error code 17637 */ 17638 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 17639 void *evt_buf, struct scan_event *param) 17640 { 17641 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 17642 wmi_scan_event_fixed_param *evt = NULL; 17643 17644 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 17645 evt = param_buf->fixed_param; 17646 17647 qdf_mem_zero(param, sizeof(*param)); 17648 17649 switch (evt->event) { 17650 case WMI_SCAN_EVENT_STARTED: 17651 param->type = SCAN_EVENT_TYPE_STARTED; 17652 break; 17653 case WMI_SCAN_EVENT_COMPLETED: 17654 param->type = SCAN_EVENT_TYPE_COMPLETED; 17655 break; 17656 case WMI_SCAN_EVENT_BSS_CHANNEL: 17657 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 17658 break; 17659 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 17660 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 17661 break; 17662 case WMI_SCAN_EVENT_DEQUEUED: 17663 param->type = SCAN_EVENT_TYPE_DEQUEUED; 17664 break; 17665 case WMI_SCAN_EVENT_PREEMPTED: 17666 param->type = SCAN_EVENT_TYPE_PREEMPTED; 17667 break; 17668 case WMI_SCAN_EVENT_START_FAILED: 17669 param->type = SCAN_EVENT_TYPE_START_FAILED; 17670 break; 17671 case WMI_SCAN_EVENT_RESTARTED: 17672 param->type = SCAN_EVENT_TYPE_RESTARTED; 17673 break; 17674 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 17675 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 17676 break; 17677 case WMI_SCAN_EVENT_MAX: 17678 default: 17679 param->type = SCAN_EVENT_TYPE_MAX; 17680 break; 17681 }; 17682 17683 switch (evt->reason) { 17684 case WMI_SCAN_REASON_NONE: 17685 param->reason = SCAN_REASON_NONE; 17686 break; 17687 case WMI_SCAN_REASON_COMPLETED: 17688 param->reason = SCAN_REASON_COMPLETED; 17689 break; 17690 case WMI_SCAN_REASON_CANCELLED: 17691 param->reason = SCAN_REASON_CANCELLED; 17692 break; 17693 case WMI_SCAN_REASON_PREEMPTED: 17694 param->reason = SCAN_REASON_PREEMPTED; 17695 break; 17696 case WMI_SCAN_REASON_TIMEDOUT: 17697 param->reason = SCAN_REASON_TIMEDOUT; 17698 break; 17699 case WMI_SCAN_REASON_INTERNAL_FAILURE: 17700 param->reason = SCAN_REASON_INTERNAL_FAILURE; 17701 break; 17702 case WMI_SCAN_REASON_SUSPENDED: 17703 param->reason = SCAN_REASON_SUSPENDED; 17704 break; 17705 case WMI_SCAN_REASON_MAX: 17706 param->reason = SCAN_REASON_MAX; 17707 break; 17708 default: 17709 param->reason = SCAN_REASON_MAX; 17710 break; 17711 }; 17712 17713 param->chan_freq = evt->channel_freq; 17714 param->requester = evt->requestor; 17715 param->scan_id = evt->scan_id; 17716 param->vdev_id = evt->vdev_id; 17717 param->timestamp = evt->tsf_timestamp; 17718 17719 return QDF_STATUS_SUCCESS; 17720 } 17721 17722 #ifdef CONVERGED_TDLS_ENABLE 17723 /** 17724 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 17725 * @wmi_handle: wmi handle 17726 * @param evt_buf: pointer to event buffer 17727 * @param param: Pointer to hold vdev tdls param 17728 * 17729 * Return: QDF_STATUS_SUCCESS for success or error code 17730 */ 17731 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 17732 void *evt_buf, struct tdls_event_info *param) 17733 { 17734 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 17735 wmi_tdls_peer_event_fixed_param *evt; 17736 17737 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 17738 if (!param_buf) { 17739 WMI_LOGE("%s: NULL param_buf", __func__); 17740 return QDF_STATUS_E_NULL_VALUE; 17741 } 17742 17743 evt = param_buf->fixed_param; 17744 17745 qdf_mem_zero(param, sizeof(*param)); 17746 17747 param->vdev_id = evt->vdev_id; 17748 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 17749 param->peermac.bytes); 17750 switch (evt->peer_status) { 17751 case WMI_TDLS_SHOULD_DISCOVER: 17752 param->message_type = TDLS_SHOULD_DISCOVER; 17753 break; 17754 case WMI_TDLS_SHOULD_TEARDOWN: 17755 param->message_type = TDLS_SHOULD_TEARDOWN; 17756 break; 17757 case WMI_TDLS_PEER_DISCONNECTED: 17758 param->message_type = TDLS_PEER_DISCONNECTED; 17759 break; 17760 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 17761 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 17762 break; 17763 default: 17764 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 17765 __func__, evt->peer_status); 17766 return QDF_STATUS_E_INVAL; 17767 }; 17768 17769 switch (evt->peer_reason) { 17770 case WMI_TDLS_TEARDOWN_REASON_TX: 17771 param->peer_reason = TDLS_TEARDOWN_TX; 17772 break; 17773 case WMI_TDLS_TEARDOWN_REASON_RSSI: 17774 param->peer_reason = TDLS_TEARDOWN_RSSI; 17775 break; 17776 case WMI_TDLS_TEARDOWN_REASON_SCAN: 17777 param->peer_reason = TDLS_TEARDOWN_SCAN; 17778 break; 17779 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 17780 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 17781 break; 17782 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 17783 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 17784 break; 17785 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 17786 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 17787 break; 17788 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 17789 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 17790 break; 17791 case WMI_TDLS_ENTER_BUF_STA: 17792 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 17793 break; 17794 case WMI_TDLS_EXIT_BUF_STA: 17795 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 17796 break; 17797 case WMI_TDLS_ENTER_BT_BUSY_MODE: 17798 param->peer_reason = TDLS_ENTER_BT_BUSY; 17799 break; 17800 case WMI_TDLS_EXIT_BT_BUSY_MODE: 17801 param->peer_reason = TDLS_EXIT_BT_BUSY; 17802 break; 17803 case WMI_TDLS_SCAN_STARTED_EVENT: 17804 param->peer_reason = TDLS_SCAN_STARTED; 17805 break; 17806 case WMI_TDLS_SCAN_COMPLETED_EVENT: 17807 param->peer_reason = TDLS_SCAN_COMPLETED; 17808 break; 17809 17810 default: 17811 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 17812 __func__, evt->peer_reason, evt->peer_status); 17813 return QDF_STATUS_E_INVAL; 17814 }; 17815 17816 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 17817 __func__, param->peermac.bytes, param->message_type, 17818 param->peer_reason, param->vdev_id); 17819 17820 return QDF_STATUS_SUCCESS; 17821 } 17822 #endif 17823 17824 /** 17825 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 17826 * @wmi_handle: wmi handle 17827 * @param evt_buf: pointer to event buffer 17828 * @param param: Pointer to hold MGMT TX completion params 17829 * 17830 * Return: QDF_STATUS_SUCCESS for success or error code 17831 */ 17832 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 17833 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 17834 { 17835 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 17836 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 17837 17838 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 17839 evt_buf; 17840 if (!param_buf) { 17841 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 17842 return QDF_STATUS_E_INVAL; 17843 } 17844 cmpl_params = param_buf->fixed_param; 17845 17846 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17847 cmpl_params->pdev_id); 17848 param->desc_id = cmpl_params->desc_id; 17849 param->status = cmpl_params->status; 17850 param->ppdu_id = cmpl_params->ppdu_id; 17851 17852 return QDF_STATUS_SUCCESS; 17853 } 17854 17855 /** 17856 * extract_offchan_data_tx_compl_param_tlv() - 17857 * extract Offchan data tx completion event params 17858 * @wmi_handle: wmi handle 17859 * @param evt_buf: pointer to event buffer 17860 * @param param: Pointer to hold offchan data TX completion params 17861 * 17862 * Return: QDF_STATUS_SUCCESS for success or error code 17863 */ 17864 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 17865 wmi_unified_t wmi_handle, void *evt_buf, 17866 struct wmi_host_offchan_data_tx_compl_event *param) 17867 { 17868 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 17869 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 17870 17871 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 17872 evt_buf; 17873 if (!param_buf) { 17874 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 17875 return QDF_STATUS_E_INVAL; 17876 } 17877 cmpl_params = param_buf->fixed_param; 17878 17879 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17880 cmpl_params->pdev_id); 17881 param->desc_id = cmpl_params->desc_id; 17882 param->status = cmpl_params->status; 17883 17884 return QDF_STATUS_SUCCESS; 17885 } 17886 17887 /** 17888 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 17889 * status tlv 17890 * @wmi_handle: wmi handle 17891 * @param evt_buf: pointer to event buffer 17892 * @param param: Pointer to hold csa switch count status event param 17893 * 17894 * Return: QDF_STATUS_SUCCESS for success or error code 17895 */ 17896 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 17897 wmi_unified_t wmi_handle, 17898 void *evt_buf, 17899 struct pdev_csa_switch_count_status *param) 17900 { 17901 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 17902 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 17903 17904 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 17905 evt_buf; 17906 if (!param_buf) { 17907 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 17908 return QDF_STATUS_E_INVAL; 17909 } 17910 17911 csa_status = param_buf->fixed_param; 17912 17913 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17914 csa_status->pdev_id); 17915 param->current_switch_count = csa_status->current_switch_count; 17916 param->num_vdevs = csa_status->num_vdevs; 17917 param->vdev_ids = param_buf->vdev_ids; 17918 17919 return QDF_STATUS_SUCCESS; 17920 } 17921 17922 /** 17923 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 17924 * param from event 17925 * @wmi_handle: wmi handle 17926 * @param evt_buf: pointer to event buffer 17927 * @param param: Pointer to hold tpc configuration 17928 * 17929 * Return: 0 for success or error code 17930 */ 17931 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 17932 void *evt_buf, 17933 wmi_host_pdev_tpc_config_event *param) 17934 { 17935 wmi_pdev_tpc_config_event_fixed_param *event = 17936 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 17937 17938 if (!event) { 17939 WMI_LOGE("Invalid event buffer"); 17940 return QDF_STATUS_E_INVAL; 17941 } 17942 17943 param->pdev_id = event->pdev_id; 17944 param->regDomain = event->regDomain; 17945 param->chanFreq = event->chanFreq; 17946 param->phyMode = event->phyMode; 17947 param->twiceAntennaReduction = event->twiceAntennaReduction; 17948 param->twiceMaxRDPower = event->twiceMaxRDPower; 17949 param->powerLimit = event->powerLimit; 17950 param->rateMax = event->rateMax; 17951 param->numTxChain = event->numTxChain; 17952 param->ctl = event->ctl; 17953 param->flags = event->flags; 17954 17955 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 17956 sizeof(param->maxRegAllowedPower)); 17957 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 17958 event->maxRegAllowedPowerAGCDD, 17959 sizeof(param->maxRegAllowedPowerAGCDD)); 17960 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 17961 event->maxRegAllowedPowerAGSTBC, 17962 sizeof(param->maxRegAllowedPowerAGSTBC)); 17963 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 17964 event->maxRegAllowedPowerAGTXBF, 17965 sizeof(param->maxRegAllowedPowerAGTXBF)); 17966 WMI_LOGD("%s:extract success", __func__); 17967 17968 return QDF_STATUS_SUCCESS; 17969 } 17970 17971 /** 17972 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 17973 * @wmi_handle: wmi handle 17974 * @param evt_buf: pointer to event buffer 17975 * @param num_vdevs: Pointer to hold num vdevs 17976 * 17977 * Return: QDF_STATUS_SUCCESS for success or error code 17978 */ 17979 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 17980 void *evt_buf, uint32_t *num_vdevs) 17981 { 17982 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 17983 wmi_host_swba_event_fixed_param *swba_event; 17984 uint32_t vdev_map; 17985 17986 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 17987 if (!param_buf) { 17988 WMI_LOGE("Invalid swba event buffer"); 17989 return QDF_STATUS_E_INVAL; 17990 } 17991 17992 swba_event = param_buf->fixed_param; 17993 *num_vdevs = swba_event->num_vdevs; 17994 if (!(*num_vdevs)) { 17995 vdev_map = swba_event->vdev_map; 17996 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 17997 } 17998 17999 return QDF_STATUS_SUCCESS; 18000 } 18001 18002 /** 18003 * extract_swba_tim_info_tlv() - extract swba tim info from event 18004 * @wmi_handle: wmi handle 18005 * @param evt_buf: pointer to event buffer 18006 * @param idx: Index to bcn info 18007 * @param tim_info: Pointer to hold tim info 18008 * 18009 * Return: QDF_STATUS_SUCCESS for success or error code 18010 */ 18011 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18012 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18013 { 18014 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18015 wmi_tim_info *tim_info_ev; 18016 18017 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18018 if (!param_buf) { 18019 WMI_LOGE("Invalid swba event buffer"); 18020 return QDF_STATUS_E_INVAL; 18021 } 18022 18023 tim_info_ev = ¶m_buf->tim_info[idx]; 18024 18025 tim_info->tim_len = tim_info_ev->tim_len; 18026 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18027 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18028 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18029 tim_info->tim_changed = tim_info_ev->tim_changed; 18030 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18031 tim_info->vdev_id = tim_info_ev->vdev_id; 18032 18033 return QDF_STATUS_SUCCESS; 18034 } 18035 18036 /** 18037 * extract_swba_noa_info_tlv() - extract swba NoA information from event 18038 * @wmi_handle: wmi handle 18039 * @param evt_buf: pointer to event buffer 18040 * @param idx: Index to bcn info 18041 * @param p2p_desc: Pointer to hold p2p NoA info 18042 * 18043 * Return: QDF_STATUS_SUCCESS for success or error code 18044 */ 18045 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 18046 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 18047 { 18048 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18049 wmi_p2p_noa_info *p2p_noa_info; 18050 uint8_t i = 0; 18051 18052 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18053 if (!param_buf) { 18054 WMI_LOGE("Invalid swba event buffer"); 18055 return QDF_STATUS_E_INVAL; 18056 } 18057 18058 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 18059 18060 p2p_desc->modified = false; 18061 p2p_desc->num_descriptors = 0; 18062 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 18063 p2p_desc->modified = true; 18064 p2p_desc->index = 18065 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 18066 p2p_desc->oppPS = 18067 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 18068 p2p_desc->ctwindow = 18069 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 18070 p2p_desc->num_descriptors = 18071 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 18072 (p2p_noa_info); 18073 for (i = 0; i < p2p_desc->num_descriptors; i++) { 18074 p2p_desc->noa_descriptors[i].type_count = 18075 (uint8_t) p2p_noa_info->noa_descriptors[i]. 18076 type_count; 18077 p2p_desc->noa_descriptors[i].duration = 18078 p2p_noa_info->noa_descriptors[i].duration; 18079 p2p_desc->noa_descriptors[i].interval = 18080 p2p_noa_info->noa_descriptors[i].interval; 18081 p2p_desc->noa_descriptors[i].start_time = 18082 p2p_noa_info->noa_descriptors[i].start_time; 18083 } 18084 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 18085 } 18086 18087 return QDF_STATUS_SUCCESS; 18088 } 18089 18090 #ifdef CONVERGED_P2P_ENABLE 18091 /** 18092 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 18093 * @wmi_handle: wmi handle 18094 * @param evt_buf: pointer to event buffer 18095 * @param param: Pointer to hold p2p noa info 18096 * 18097 * Return: QDF_STATUS_SUCCESS for success or error code 18098 */ 18099 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 18100 wmi_unified_t wmi_handle, void *evt_buf, 18101 struct p2p_noa_info *param) 18102 { 18103 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 18104 wmi_p2p_noa_event_fixed_param *fixed_param; 18105 uint8_t i; 18106 wmi_p2p_noa_info *wmi_noa_info; 18107 uint8_t *buf_ptr; 18108 uint32_t descriptors; 18109 18110 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 18111 if (!param_tlvs) { 18112 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 18113 return QDF_STATUS_E_INVAL; 18114 } 18115 18116 if (!param) { 18117 WMI_LOGE("noa information param is null"); 18118 return QDF_STATUS_E_INVAL; 18119 } 18120 18121 fixed_param = param_tlvs->fixed_param; 18122 buf_ptr = (uint8_t *) fixed_param; 18123 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 18124 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 18125 18126 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 18127 WMI_LOGE("%s: noa attr is not modified", __func__); 18128 return QDF_STATUS_E_INVAL; 18129 } 18130 18131 param->vdev_id = fixed_param->vdev_id; 18132 param->index = 18133 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 18134 param->opps_ps = 18135 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 18136 param->ct_window = 18137 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 18138 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 18139 param->num_desc = (uint8_t) descriptors; 18140 18141 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 18142 param->index, param->opps_ps, param->ct_window, 18143 param->num_desc); 18144 for (i = 0; i < param->num_desc; i++) { 18145 param->noa_desc[i].type_count = 18146 (uint8_t) wmi_noa_info->noa_descriptors[i]. 18147 type_count; 18148 param->noa_desc[i].duration = 18149 wmi_noa_info->noa_descriptors[i].duration; 18150 param->noa_desc[i].interval = 18151 wmi_noa_info->noa_descriptors[i].interval; 18152 param->noa_desc[i].start_time = 18153 wmi_noa_info->noa_descriptors[i].start_time; 18154 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 18155 __func__, i, param->noa_desc[i].type_count, 18156 param->noa_desc[i].duration, 18157 param->noa_desc[i].interval, 18158 param->noa_desc[i].start_time); 18159 } 18160 18161 return QDF_STATUS_SUCCESS; 18162 } 18163 18164 /** 18165 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 18166 * information from event 18167 * @wmi_handle: wmi handle 18168 * @param evt_buf: pointer to event buffer 18169 * @param param: Pointer to hold p2p lo stop event information 18170 * 18171 * Return: QDF_STATUS_SUCCESS for success or error code 18172 */ 18173 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 18174 wmi_unified_t wmi_handle, void *evt_buf, 18175 struct p2p_lo_event *param) 18176 { 18177 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 18178 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 18179 18180 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 18181 evt_buf; 18182 if (!param_tlvs) { 18183 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 18184 return QDF_STATUS_E_INVAL; 18185 } 18186 18187 if (!param) { 18188 WMI_LOGE("lo stop event param is null"); 18189 return QDF_STATUS_E_INVAL; 18190 } 18191 18192 lo_param = param_tlvs->fixed_param; 18193 param->vdev_id = lo_param->vdev_id; 18194 param->reason_code = lo_param->reason; 18195 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 18196 param->vdev_id, param->reason_code); 18197 18198 return QDF_STATUS_SUCCESS; 18199 } 18200 #endif /* End of CONVERGED_P2P_ENABLE */ 18201 18202 /** 18203 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 18204 * @wmi_handle: wmi handle 18205 * @param evt_buf: pointer to event buffer 18206 * @param ev: Pointer to hold peer param 18207 * 18208 * Return: QDF_STATUS_SUCCESS for success or error code 18209 */ 18210 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 18211 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 18212 { 18213 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 18214 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 18215 18216 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 18217 kickout_event = param_buf->fixed_param; 18218 18219 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 18220 ev->peer_macaddr); 18221 18222 ev->reason = kickout_event->reason; 18223 ev->rssi = kickout_event->rssi; 18224 18225 return QDF_STATUS_SUCCESS; 18226 } 18227 18228 /** 18229 * extract_all_stats_counts_tlv() - extract all stats count from event 18230 * @wmi_handle: wmi handle 18231 * @param evt_buf: pointer to event buffer 18232 * @param stats_param: Pointer to hold stats count 18233 * 18234 * Return: QDF_STATUS_SUCCESS for success or error code 18235 */ 18236 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 18237 void *evt_buf, wmi_host_stats_event *stats_param) 18238 { 18239 wmi_stats_event_fixed_param *ev; 18240 wmi_per_chain_rssi_stats *rssi_event; 18241 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18242 18243 qdf_mem_zero(stats_param, sizeof(*stats_param)); 18244 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18245 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18246 rssi_event = param_buf->chain_stats; 18247 if (!ev) { 18248 WMI_LOGE("%s: event fixed param NULL\n", __func__); 18249 return QDF_STATUS_E_FAILURE; 18250 } 18251 18252 switch (ev->stats_id) { 18253 case WMI_REQUEST_PEER_STAT: 18254 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 18255 break; 18256 18257 case WMI_REQUEST_AP_STAT: 18258 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 18259 break; 18260 18261 case WMI_REQUEST_PDEV_STAT: 18262 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 18263 break; 18264 18265 case WMI_REQUEST_VDEV_STAT: 18266 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 18267 break; 18268 18269 case WMI_REQUEST_BCNFLT_STAT: 18270 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 18271 break; 18272 18273 case WMI_REQUEST_VDEV_RATE_STAT: 18274 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 18275 break; 18276 18277 case WMI_REQUEST_BCN_STAT: 18278 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 18279 break; 18280 18281 default: 18282 stats_param->stats_id = 0; 18283 break; 18284 18285 } 18286 18287 stats_param->num_pdev_stats = ev->num_pdev_stats; 18288 stats_param->num_pdev_ext_stats = 0; 18289 stats_param->num_vdev_stats = ev->num_vdev_stats; 18290 stats_param->num_peer_stats = ev->num_peer_stats; 18291 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 18292 stats_param->num_chan_stats = ev->num_chan_stats; 18293 stats_param->num_bcn_stats = ev->num_bcn_stats; 18294 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18295 ev->pdev_id); 18296 18297 /* if chain_stats is not populated */ 18298 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 18299 return QDF_STATUS_SUCCESS; 18300 18301 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 18302 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 18303 return QDF_STATUS_SUCCESS; 18304 18305 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 18306 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 18307 return QDF_STATUS_SUCCESS; 18308 18309 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 18310 18311 return QDF_STATUS_SUCCESS; 18312 } 18313 18314 /** 18315 * extract_pdev_tx_stats() - extract pdev tx stats from event 18316 */ 18317 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 18318 { 18319 /* Tx Stats */ 18320 tx->comp_queued = tx_stats->comp_queued; 18321 tx->comp_delivered = tx_stats->comp_delivered; 18322 tx->msdu_enqued = tx_stats->msdu_enqued; 18323 tx->mpdu_enqued = tx_stats->mpdu_enqued; 18324 tx->wmm_drop = tx_stats->wmm_drop; 18325 tx->local_enqued = tx_stats->local_enqued; 18326 tx->local_freed = tx_stats->local_freed; 18327 tx->hw_queued = tx_stats->hw_queued; 18328 tx->hw_reaped = tx_stats->hw_reaped; 18329 tx->underrun = tx_stats->underrun; 18330 tx->tx_abort = tx_stats->tx_abort; 18331 tx->mpdus_requed = tx_stats->mpdus_requed; 18332 tx->data_rc = tx_stats->data_rc; 18333 tx->self_triggers = tx_stats->self_triggers; 18334 tx->sw_retry_failure = tx_stats->sw_retry_failure; 18335 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 18336 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 18337 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 18338 tx->pdev_resets = tx_stats->pdev_resets; 18339 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 18340 tx->phy_underrun = tx_stats->phy_underrun; 18341 tx->txop_ovf = tx_stats->txop_ovf; 18342 18343 return; 18344 } 18345 18346 18347 /** 18348 * extract_pdev_rx_stats() - extract pdev rx stats from event 18349 */ 18350 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 18351 { 18352 /* Rx Stats */ 18353 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 18354 rx->status_rcvd = rx_stats->status_rcvd; 18355 rx->r0_frags = rx_stats->r0_frags; 18356 rx->r1_frags = rx_stats->r1_frags; 18357 rx->r2_frags = rx_stats->r2_frags; 18358 /* Only TLV */ 18359 rx->r3_frags = 0; 18360 rx->htt_msdus = rx_stats->htt_msdus; 18361 rx->htt_mpdus = rx_stats->htt_mpdus; 18362 rx->loc_msdus = rx_stats->loc_msdus; 18363 rx->loc_mpdus = rx_stats->loc_mpdus; 18364 rx->oversize_amsdu = rx_stats->oversize_amsdu; 18365 rx->phy_errs = rx_stats->phy_errs; 18366 rx->phy_err_drop = rx_stats->phy_err_drop; 18367 rx->mpdu_errs = rx_stats->mpdu_errs; 18368 18369 return; 18370 } 18371 18372 /** 18373 * extract_pdev_stats_tlv() - extract pdev stats from event 18374 * @wmi_handle: wmi handle 18375 * @param evt_buf: pointer to event buffer 18376 * @param index: Index into pdev stats 18377 * @param pdev_stats: Pointer to hold pdev stats 18378 * 18379 * Return: QDF_STATUS_SUCCESS for success or error code 18380 */ 18381 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 18382 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 18383 { 18384 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18385 wmi_stats_event_fixed_param *ev_param; 18386 uint8_t *data; 18387 18388 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18389 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18390 18391 data = param_buf->data; 18392 18393 if (index < ev_param->num_pdev_stats) { 18394 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 18395 (index * sizeof(wmi_pdev_stats))); 18396 18397 pdev_stats->chan_nf = ev->chan_nf; 18398 pdev_stats->tx_frame_count = ev->tx_frame_count; 18399 pdev_stats->rx_frame_count = ev->rx_frame_count; 18400 pdev_stats->rx_clear_count = ev->rx_clear_count; 18401 pdev_stats->cycle_count = ev->cycle_count; 18402 pdev_stats->phy_err_count = ev->phy_err_count; 18403 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 18404 18405 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 18406 &(ev->pdev_stats.tx)); 18407 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 18408 &(ev->pdev_stats.rx)); 18409 } 18410 18411 return QDF_STATUS_SUCCESS; 18412 } 18413 18414 /** 18415 * extract_unit_test_tlv() - extract unit test data 18416 * @wmi_handle: wmi handle 18417 * @param evt_buf: pointer to event buffer 18418 * @param unit_test: pointer to hold unit test data 18419 * @param maxspace: Amount of space in evt_buf 18420 * 18421 * Return: QDF_STATUS_SUCCESS for success or error code 18422 */ 18423 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 18424 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 18425 { 18426 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 18427 wmi_unit_test_event_fixed_param *ev_param; 18428 uint32_t num_bufp; 18429 uint32_t copy_size; 18430 uint8_t *bufp; 18431 18432 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 18433 ev_param = param_buf->fixed_param; 18434 bufp = param_buf->bufp; 18435 num_bufp = param_buf->num_bufp; 18436 unit_test->vdev_id = ev_param->vdev_id; 18437 unit_test->module_id = ev_param->module_id; 18438 unit_test->diag_token = ev_param->diag_token; 18439 unit_test->flag = ev_param->flag; 18440 unit_test->payload_len = ev_param->payload_len; 18441 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 18442 ev_param->vdev_id, 18443 ev_param->module_id, 18444 ev_param->diag_token, 18445 ev_param->flag); 18446 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 18447 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 18448 bufp, num_bufp); 18449 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 18450 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 18451 unit_test->buffer_len = copy_size; 18452 18453 return QDF_STATUS_SUCCESS; 18454 } 18455 18456 /** 18457 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 18458 * @wmi_handle: wmi handle 18459 * @param evt_buf: pointer to event buffer 18460 * @param index: Index into extended pdev stats 18461 * @param pdev_ext_stats: Pointer to hold extended pdev stats 18462 * 18463 * Return: QDF_STATUS_SUCCESS for success or error code 18464 */ 18465 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 18466 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 18467 { 18468 return QDF_STATUS_SUCCESS; 18469 } 18470 18471 /** 18472 * extract_vdev_stats_tlv() - extract vdev stats from event 18473 * @wmi_handle: wmi handle 18474 * @param evt_buf: pointer to event buffer 18475 * @param index: Index into vdev stats 18476 * @param vdev_stats: Pointer to hold vdev stats 18477 * 18478 * Return: QDF_STATUS_SUCCESS for success or error code 18479 */ 18480 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 18481 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 18482 { 18483 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18484 wmi_stats_event_fixed_param *ev_param; 18485 uint8_t *data; 18486 18487 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18488 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18489 data = (uint8_t *) param_buf->data; 18490 18491 if (index < ev_param->num_vdev_stats) { 18492 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 18493 ((ev_param->num_pdev_stats) * 18494 sizeof(wmi_pdev_stats)) + 18495 (index * sizeof(wmi_vdev_stats))); 18496 18497 vdev_stats->vdev_id = ev->vdev_id; 18498 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 18499 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 18500 18501 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 18502 sizeof(ev->tx_frm_cnt)); 18503 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 18504 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 18505 ev->multiple_retry_cnt, 18506 sizeof(ev->multiple_retry_cnt)); 18507 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 18508 sizeof(ev->fail_cnt)); 18509 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 18510 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 18511 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 18512 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 18513 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 18514 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 18515 sizeof(ev->tx_rate_history)); 18516 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 18517 sizeof(ev->bcn_rssi_history)); 18518 18519 } 18520 18521 return QDF_STATUS_SUCCESS; 18522 } 18523 18524 /** 18525 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 18526 * buffer 18527 * @wmi_handle: wmi handle 18528 * @evt_buf: pointer to event buffer 18529 * @index: Index into vdev stats 18530 * @rssi_stats: Pointer to hold rssi stats 18531 * 18532 * Return: QDF_STATUS_SUCCESS for success or error code 18533 */ 18534 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 18535 void *evt_buf, uint32_t index, 18536 struct wmi_host_per_chain_rssi_stats *rssi_stats) 18537 { 18538 uint8_t *data; 18539 wmi_rssi_stats *fw_rssi_stats; 18540 wmi_per_chain_rssi_stats *rssi_event; 18541 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18542 18543 if (!evt_buf) { 18544 WMI_LOGE("evt_buf is null"); 18545 return QDF_STATUS_E_NULL_VALUE; 18546 } 18547 18548 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18549 rssi_event = param_buf->chain_stats; 18550 18551 if (index >= rssi_event->num_per_chain_rssi_stats) { 18552 WMI_LOGE("invalid index"); 18553 return QDF_STATUS_E_INVAL; 18554 } 18555 18556 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 18557 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 18558 18559 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 18560 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 18561 fw_rssi_stats->rssi_avg_beacon, 18562 sizeof(fw_rssi_stats->rssi_avg_beacon)); 18563 qdf_mem_copy(rssi_stats->rssi_avg_data, 18564 fw_rssi_stats->rssi_avg_data, 18565 sizeof(fw_rssi_stats->rssi_avg_data)); 18566 qdf_mem_copy(&rssi_stats->peer_macaddr, 18567 &fw_rssi_stats->peer_macaddr, 18568 sizeof(fw_rssi_stats->peer_macaddr)); 18569 18570 return QDF_STATUS_SUCCESS; 18571 } 18572 18573 18574 18575 /** 18576 * extract_bcn_stats_tlv() - extract bcn stats from event 18577 * @wmi_handle: wmi handle 18578 * @param evt_buf: pointer to event buffer 18579 * @param index: Index into vdev stats 18580 * @param bcn_stats: Pointer to hold bcn stats 18581 * 18582 * Return: QDF_STATUS_SUCCESS for success or error code 18583 */ 18584 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 18585 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 18586 { 18587 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18588 wmi_stats_event_fixed_param *ev_param; 18589 uint8_t *data; 18590 18591 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18592 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18593 data = (uint8_t *) param_buf->data; 18594 18595 if (index < ev_param->num_bcn_stats) { 18596 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 18597 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18598 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18599 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 18600 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 18601 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 18602 (index * sizeof(wmi_bcn_stats))); 18603 18604 bcn_stats->vdev_id = ev->vdev_id; 18605 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 18606 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 18607 } 18608 18609 return QDF_STATUS_SUCCESS; 18610 } 18611 18612 /** 18613 * extract_peer_stats_tlv() - extract peer stats from event 18614 * @wmi_handle: wmi handle 18615 * @param evt_buf: pointer to event buffer 18616 * @param index: Index into peer stats 18617 * @param peer_stats: Pointer to hold peer stats 18618 * 18619 * Return: QDF_STATUS_SUCCESS for success or error code 18620 */ 18621 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 18622 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 18623 { 18624 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18625 wmi_stats_event_fixed_param *ev_param; 18626 uint8_t *data; 18627 18628 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18629 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18630 data = (uint8_t *) param_buf->data; 18631 18632 if (index < ev_param->num_peer_stats) { 18633 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 18634 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18635 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18636 (index * sizeof(wmi_peer_stats))); 18637 18638 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 18639 18640 OS_MEMCPY(&(peer_stats->peer_macaddr), 18641 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 18642 18643 peer_stats->peer_rssi = ev->peer_rssi; 18644 peer_stats->peer_tx_rate = ev->peer_tx_rate; 18645 peer_stats->peer_rx_rate = ev->peer_rx_rate; 18646 } 18647 18648 return QDF_STATUS_SUCCESS; 18649 } 18650 18651 /** 18652 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 18653 * @wmi_handle: wmi handle 18654 * @param evt_buf: pointer to event buffer 18655 * @param index: Index into bcn fault stats 18656 * @param bcnflt_stats: Pointer to hold bcn fault stats 18657 * 18658 * Return: QDF_STATUS_SUCCESS for success or error code 18659 */ 18660 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 18661 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 18662 { 18663 return QDF_STATUS_SUCCESS; 18664 } 18665 18666 /** 18667 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 18668 * @wmi_handle: wmi handle 18669 * @param evt_buf: pointer to event buffer 18670 * @param index: Index into extended peer stats 18671 * @param peer_extd_stats: Pointer to hold extended peer stats 18672 * 18673 * Return: QDF_STATUS_SUCCESS for success or error code 18674 */ 18675 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 18676 void *evt_buf, uint32_t index, 18677 wmi_host_peer_extd_stats *peer_extd_stats) 18678 { 18679 return QDF_STATUS_SUCCESS; 18680 } 18681 18682 /** 18683 * extract_chan_stats_tlv() - extract chan stats from event 18684 * @wmi_handle: wmi handle 18685 * @param evt_buf: pointer to event buffer 18686 * @param index: Index into chan stats 18687 * @param vdev_extd_stats: Pointer to hold chan stats 18688 * 18689 * Return: QDF_STATUS_SUCCESS for success or error code 18690 */ 18691 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 18692 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 18693 { 18694 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18695 wmi_stats_event_fixed_param *ev_param; 18696 uint8_t *data; 18697 18698 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18699 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18700 data = (uint8_t *) param_buf->data; 18701 18702 if (index < ev_param->num_chan_stats) { 18703 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 18704 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18705 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18706 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 18707 (index * sizeof(wmi_chan_stats))); 18708 18709 18710 /* Non-TLV doesn't have num_chan_stats */ 18711 chan_stats->chan_mhz = ev->chan_mhz; 18712 chan_stats->sampling_period_us = ev->sampling_period_us; 18713 chan_stats->rx_clear_count = ev->rx_clear_count; 18714 chan_stats->tx_duration_us = ev->tx_duration_us; 18715 chan_stats->rx_duration_us = ev->rx_duration_us; 18716 } 18717 18718 return QDF_STATUS_SUCCESS; 18719 } 18720 18721 /** 18722 * extract_profile_ctx_tlv() - extract profile context from event 18723 * @wmi_handle: wmi handle 18724 * @param evt_buf: pointer to event buffer 18725 * @idx: profile stats index to extract 18726 * @param profile_ctx: Pointer to hold profile context 18727 * 18728 * Return: QDF_STATUS_SUCCESS for success or error code 18729 */ 18730 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 18731 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 18732 { 18733 return QDF_STATUS_SUCCESS; 18734 } 18735 18736 /** 18737 * extract_profile_data_tlv() - extract profile data from event 18738 * @wmi_handle: wmi handle 18739 * @param evt_buf: pointer to event buffer 18740 * @param profile_data: Pointer to hold profile data 18741 * 18742 * Return: QDF_STATUS_SUCCESS for success or error code 18743 */ 18744 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 18745 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 18746 { 18747 18748 return QDF_STATUS_SUCCESS; 18749 } 18750 18751 /** 18752 * extract_chan_info_event_tlv() - extract chan information from event 18753 * @wmi_handle: wmi handle 18754 * @param evt_buf: pointer to event buffer 18755 * @param chan_info: Pointer to hold chan information 18756 * 18757 * Return: QDF_STATUS_SUCCESS for success or error code 18758 */ 18759 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 18760 void *evt_buf, wmi_host_chan_info_event *chan_info) 18761 { 18762 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 18763 wmi_chan_info_event_fixed_param *ev; 18764 18765 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 18766 18767 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 18768 if (!ev) { 18769 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 18770 return QDF_STATUS_E_FAILURE; 18771 } 18772 18773 chan_info->err_code = ev->err_code; 18774 chan_info->freq = ev->freq; 18775 chan_info->cmd_flags = ev->cmd_flags; 18776 chan_info->noise_floor = ev->noise_floor; 18777 chan_info->rx_clear_count = ev->rx_clear_count; 18778 chan_info->cycle_count = ev->cycle_count; 18779 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 18780 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 18781 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 18782 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 18783 ev->vdev_id, WLAN_SCAN_ID); 18784 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 18785 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 18786 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 18787 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 18788 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 18789 chan_info->rx_frame_count = ev->rx_frame_count; 18790 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 18791 chan_info->vdev_id = ev->vdev_id; 18792 18793 return QDF_STATUS_SUCCESS; 18794 } 18795 18796 /** 18797 * extract_pdev_utf_event_tlv() - extract UTF data info from event 18798 * @wmi_handle: WMI handle 18799 * @param evt_buf: Pointer to event buffer 18800 * @param param: Pointer to hold data 18801 * 18802 * Return : QDF_STATUS_SUCCESS for success or error code 18803 */ 18804 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 18805 uint8_t *evt_buf, 18806 struct wmi_host_pdev_utf_event *event) 18807 { 18808 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 18809 struct wmi_host_utf_seg_header_info *seg_hdr; 18810 18811 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 18812 event->data = param_buf->data; 18813 event->datalen = param_buf->num_data; 18814 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 18815 /* Set pdev_id=1 until FW adds support to include pdev_id */ 18816 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18817 seg_hdr->pdev_id); 18818 18819 return QDF_STATUS_SUCCESS; 18820 } 18821 18822 /** 18823 * extract_chainmask_tables_tlv() - extract chain mask tables from event 18824 * @wmi_handle: wmi handle 18825 * @param evt_buf: pointer to event buffer 18826 * @param param: Pointer to hold evt buf 18827 * 18828 * Return: QDF_STATUS_SUCCESS for success or error code 18829 */ 18830 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 18831 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 18832 { 18833 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 18834 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 18835 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 18836 uint8_t i = 0, j = 0; 18837 18838 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 18839 if (!param_buf) 18840 return QDF_STATUS_E_INVAL; 18841 18842 hw_caps = param_buf->soc_hw_mode_caps; 18843 if (!hw_caps) 18844 return QDF_STATUS_E_INVAL; 18845 18846 if (!hw_caps->num_chainmask_tables) 18847 return QDF_STATUS_E_INVAL; 18848 18849 chainmask_caps = param_buf->mac_phy_chainmask_caps; 18850 18851 if (chainmask_caps == NULL) 18852 return QDF_STATUS_E_INVAL; 18853 18854 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 18855 18856 qdf_print("Dumping chain mask combo data for table : %d\n", i); 18857 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 18858 18859 chainmask_table[i].cap_list[j].chainmask = 18860 chainmask_caps->chainmask; 18861 18862 chainmask_table[i].cap_list[j].supports_chan_width_20 = 18863 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 18864 18865 chainmask_table[i].cap_list[j].supports_chan_width_40 = 18866 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 18867 18868 chainmask_table[i].cap_list[j].supports_chan_width_80 = 18869 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 18870 18871 chainmask_table[i].cap_list[j].supports_chan_width_160 = 18872 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 18873 18874 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 18875 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 18876 18877 chainmask_table[i].cap_list[j].chain_mask_2G = 18878 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 18879 18880 chainmask_table[i].cap_list[j].chain_mask_5G = 18881 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 18882 18883 chainmask_table[i].cap_list[j].chain_mask_tx = 18884 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 18885 18886 chainmask_table[i].cap_list[j].chain_mask_rx = 18887 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 18888 18889 chainmask_table[i].cap_list[j].supports_aDFS = 18890 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 18891 18892 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x\n", 18893 chainmask_caps->supported_flags, 18894 chainmask_caps->chainmask 18895 ); 18896 chainmask_caps++; 18897 } 18898 } 18899 18900 return QDF_STATUS_SUCCESS; 18901 } 18902 18903 /** 18904 * extract_service_ready_ext_tlv() - extract basic extended service ready params 18905 * from event 18906 * @wmi_handle: wmi handle 18907 * @param evt_buf: pointer to event buffer 18908 * @param param: Pointer to hold evt buf 18909 * 18910 * Return: QDF_STATUS_SUCCESS for success or error code 18911 */ 18912 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 18913 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 18914 { 18915 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 18916 wmi_service_ready_ext_event_fixed_param *ev; 18917 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 18918 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 18919 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 18920 uint8_t i = 0; 18921 18922 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 18923 if (!param_buf) 18924 return QDF_STATUS_E_INVAL; 18925 18926 ev = param_buf->fixed_param; 18927 if (!ev) 18928 return QDF_STATUS_E_INVAL; 18929 18930 /* Move this to host based bitmap */ 18931 param->default_conc_scan_config_bits = 18932 ev->default_conc_scan_config_bits; 18933 param->default_fw_config_bits = ev->default_fw_config_bits; 18934 param->he_cap_info = ev->he_cap_info; 18935 param->mpdu_density = ev->mpdu_density; 18936 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 18937 param->fw_build_vers_ext = ev->fw_build_vers_ext; 18938 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 18939 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 18940 18941 hw_caps = param_buf->soc_hw_mode_caps; 18942 if (hw_caps) 18943 param->num_hw_modes = hw_caps->num_hw_modes; 18944 else 18945 param->num_hw_modes = 0; 18946 18947 reg_caps = param_buf->soc_hal_reg_caps; 18948 if (reg_caps) 18949 param->num_phy = reg_caps->num_phy; 18950 else 18951 param->num_phy = 0; 18952 18953 if (hw_caps) { 18954 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 18955 qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables); 18956 } else 18957 param->num_chainmask_tables = 0; 18958 18959 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 18960 18961 if (chain_mask_combo == NULL) 18962 return QDF_STATUS_SUCCESS; 18963 18964 qdf_print("Dumping chain mask combo data\n"); 18965 18966 for (i = 0; i < param->num_chainmask_tables; i++) { 18967 18968 qdf_print("table_id : %d Num valid chainmasks: %d\n", 18969 chain_mask_combo->chainmask_table_id, 18970 chain_mask_combo->num_valid_chainmask 18971 ); 18972 18973 param->chainmask_table[i].table_id = 18974 chain_mask_combo->chainmask_table_id; 18975 param->chainmask_table[i].num_valid_chainmasks = 18976 chain_mask_combo->num_valid_chainmask; 18977 chain_mask_combo++; 18978 } 18979 qdf_print("chain mask combo end\n"); 18980 18981 return QDF_STATUS_SUCCESS; 18982 } 18983 18984 /** 18985 * extract_hw_mode_cap_service_ready_ext_tlv() - 18986 * extract HW mode cap from service ready event 18987 * @wmi_handle: wmi handle 18988 * @param evt_buf: pointer to event buffer 18989 * @param param: Pointer to hold evt buf 18990 * @param hw_mode_idx: hw mode idx should be less than num_mode 18991 * 18992 * Return: QDF_STATUS_SUCCESS for success or error code 18993 */ 18994 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 18995 wmi_unified_t wmi_handle, 18996 uint8_t *event, uint8_t hw_mode_idx, 18997 struct wlan_psoc_host_hw_mode_caps *param) 18998 { 18999 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19000 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19001 19002 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19003 if (!param_buf) 19004 return QDF_STATUS_E_INVAL; 19005 19006 hw_caps = param_buf->soc_hw_mode_caps; 19007 if (!hw_caps) 19008 return QDF_STATUS_E_INVAL; 19009 19010 if (hw_mode_idx >= hw_caps->num_hw_modes) 19011 return QDF_STATUS_E_INVAL; 19012 19013 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19014 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19015 19016 param->hw_mode_config_type = 19017 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19018 19019 return QDF_STATUS_SUCCESS; 19020 } 19021 19022 /** 19023 * extract_mac_phy_cap_service_ready_ext_tlv() - 19024 * extract MAC phy cap from service ready event 19025 * @wmi_handle: wmi handle 19026 * @param evt_buf: pointer to event buffer 19027 * @param param: Pointer to hold evt buf 19028 * @param hw_mode_idx: hw mode idx should be less than num_mode 19029 * @param phy_id: phy id within hw_mode 19030 * 19031 * Return: QDF_STATUS_SUCCESS for success or error code 19032 */ 19033 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19034 wmi_unified_t wmi_handle, 19035 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19036 struct wlan_psoc_host_mac_phy_caps *param) 19037 { 19038 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19039 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19040 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19041 uint32_t phy_map; 19042 uint8_t hw_idx, phy_idx = 0; 19043 19044 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19045 if (!param_buf) 19046 return QDF_STATUS_E_INVAL; 19047 19048 hw_caps = param_buf->soc_hw_mode_caps; 19049 if (!hw_caps) 19050 return QDF_STATUS_E_INVAL; 19051 19052 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19053 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19054 break; 19055 19056 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19057 while (phy_map) { 19058 phy_map >>= 1; 19059 phy_idx++; 19060 } 19061 } 19062 19063 if (hw_idx == hw_caps->num_hw_modes) 19064 return QDF_STATUS_E_INVAL; 19065 19066 phy_idx += phy_id; 19067 if (phy_idx >= param_buf->num_mac_phy_caps) 19068 return QDF_STATUS_E_INVAL; 19069 19070 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19071 19072 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19073 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19074 mac_phy_caps->pdev_id); 19075 param->phy_id = mac_phy_caps->phy_id; 19076 param->supports_11b = 19077 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19078 param->supports_11g = 19079 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19080 param->supports_11a = 19081 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19082 param->supports_11n = 19083 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19084 param->supports_11ac = 19085 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19086 param->supports_11ax = 19087 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19088 19089 param->supported_bands = mac_phy_caps->supported_bands; 19090 param->ampdu_density = mac_phy_caps->ampdu_density; 19091 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19092 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19093 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19094 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19095 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 19096 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19097 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19098 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19099 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19100 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19101 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19102 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19103 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 19104 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 19105 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 19106 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 19107 qdf_mem_copy(¶m->he_cap_phy_info_2G, 19108 &mac_phy_caps->he_cap_phy_info_2G, 19109 sizeof(param->he_cap_phy_info_2G)); 19110 qdf_mem_copy(¶m->he_cap_phy_info_5G, 19111 &mac_phy_caps->he_cap_phy_info_5G, 19112 sizeof(param->he_cap_phy_info_5G)); 19113 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 19114 sizeof(param->he_ppet2G)); 19115 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 19116 sizeof(param->he_ppet5G)); 19117 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 19118 19119 return QDF_STATUS_SUCCESS; 19120 } 19121 19122 /** 19123 * extract_reg_cap_service_ready_ext_tlv() - 19124 * extract REG cap from service ready event 19125 * @wmi_handle: wmi handle 19126 * @param evt_buf: pointer to event buffer 19127 * @param param: Pointer to hold evt buf 19128 * @param phy_idx: phy idx should be less than num_mode 19129 * 19130 * Return: QDF_STATUS_SUCCESS for success or error code 19131 */ 19132 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 19133 wmi_unified_t wmi_handle, 19134 uint8_t *event, uint8_t phy_idx, 19135 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 19136 { 19137 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19138 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19139 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 19140 19141 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19142 if (!param_buf) 19143 return QDF_STATUS_E_INVAL; 19144 19145 reg_caps = param_buf->soc_hal_reg_caps; 19146 if (!reg_caps) 19147 return QDF_STATUS_E_INVAL; 19148 19149 if (phy_idx >= reg_caps->num_phy) 19150 return QDF_STATUS_E_INVAL; 19151 19152 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 19153 19154 param->phy_id = ext_reg_cap->phy_id; 19155 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 19156 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 19157 param->regcap1 = ext_reg_cap->regcap1; 19158 param->regcap2 = ext_reg_cap->regcap2; 19159 param->wireless_modes = convert_wireless_modes_tlv( 19160 ext_reg_cap->wireless_modes); 19161 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 19162 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 19163 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 19164 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 19165 19166 return QDF_STATUS_SUCCESS; 19167 } 19168 19169 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 19170 wmi_unified_t wmi_handle, 19171 uint8_t *event, uint8_t idx, 19172 struct wlan_psoc_host_dbr_ring_caps *param) 19173 { 19174 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19175 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 19176 19177 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19178 if (!param_buf) 19179 return QDF_STATUS_E_INVAL; 19180 19181 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 19182 19183 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19184 dbr_ring_caps->pdev_id); 19185 param->mod_id = dbr_ring_caps->mod_id; 19186 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 19187 param->min_buf_size = dbr_ring_caps->min_buf_size; 19188 param->min_buf_align = dbr_ring_caps->min_buf_align; 19189 19190 return QDF_STATUS_SUCCESS; 19191 } 19192 19193 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 19194 uint8_t *event, struct direct_buf_rx_rsp *param) 19195 { 19196 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19197 wmi_dma_buf_release_fixed_param *ev; 19198 19199 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19200 if (!param_buf) 19201 return QDF_STATUS_E_INVAL; 19202 19203 ev = param_buf->fixed_param; 19204 if (!ev) 19205 return QDF_STATUS_E_INVAL; 19206 19207 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19208 ev->pdev_id); 19209 param->mod_id = ev->mod_id; 19210 param->num_buf_release_entry = ev->num_buf_release_entry; 19211 param->num_meta_data_entry = ev->num_meta_data_entry; 19212 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 19213 param->pdev_id, param->mod_id, param->num_buf_release_entry); 19214 19215 return QDF_STATUS_SUCCESS; 19216 } 19217 19218 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 19219 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 19220 { 19221 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19222 wmi_dma_buf_release_entry *entry; 19223 19224 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19225 if (!param_buf) 19226 return QDF_STATUS_E_INVAL; 19227 19228 entry = ¶m_buf->entries[idx]; 19229 19230 if (!entry) { 19231 WMI_LOGE("%s: Entry is NULL\n", __func__); 19232 return QDF_STATUS_E_FAILURE; 19233 } 19234 19235 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 19236 19237 param->paddr_lo = entry->paddr_lo; 19238 param->paddr_hi = entry->paddr_hi; 19239 19240 return QDF_STATUS_SUCCESS; 19241 } 19242 19243 static QDF_STATUS extract_dbr_buf_metadata_tlv( 19244 wmi_unified_t wmi_handle, uint8_t *event, 19245 uint8_t idx, struct direct_buf_rx_metadata *param) 19246 { 19247 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19248 wmi_dma_buf_release_spectral_meta_data *entry; 19249 19250 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19251 if (!param_buf) 19252 return QDF_STATUS_E_INVAL; 19253 19254 entry = ¶m_buf->meta_data[idx]; 19255 19256 if (!entry) { 19257 WMI_LOGE("%s: Entry is NULL\n", __func__); 19258 return QDF_STATUS_E_FAILURE; 19259 } 19260 19261 qdf_mem_copy(param->noisefloor, entry->noise_floor, 19262 sizeof(entry->noise_floor)); 19263 return QDF_STATUS_SUCCESS; 19264 } 19265 19266 /** 19267 * extract_dcs_interference_type_tlv() - extract dcs interference type 19268 * from event 19269 * @wmi_handle: wmi handle 19270 * @param evt_buf: pointer to event buffer 19271 * @param param: Pointer to hold dcs interference param 19272 * 19273 * Return: 0 for success or error code 19274 */ 19275 static QDF_STATUS extract_dcs_interference_type_tlv( 19276 wmi_unified_t wmi_handle, 19277 void *evt_buf, struct wmi_host_dcs_interference_param *param) 19278 { 19279 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19280 19281 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19282 if (!param_buf) 19283 return QDF_STATUS_E_INVAL; 19284 19285 param->interference_type = param_buf->fixed_param->interference_type; 19286 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19287 param_buf->fixed_param->pdev_id); 19288 19289 return QDF_STATUS_SUCCESS; 19290 } 19291 19292 /* 19293 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 19294 * @wmi_handle: wmi handle 19295 * @param evt_buf: pointer to event buffer 19296 * @param cw_int: Pointer to hold cw interference 19297 * 19298 * Return: 0 for success or error code 19299 */ 19300 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 19301 void *evt_buf, 19302 wmi_host_ath_dcs_cw_int *cw_int) 19303 { 19304 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19305 wlan_dcs_cw_int *ev; 19306 19307 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19308 if (!param_buf) 19309 return QDF_STATUS_E_INVAL; 19310 19311 ev = param_buf->cw_int; 19312 19313 cw_int->channel = ev->channel; 19314 19315 return QDF_STATUS_SUCCESS; 19316 } 19317 19318 /** 19319 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 19320 * @wmi_handle: wmi handle 19321 * @param evt_buf: pointer to event buffer 19322 * @param wlan_stat: Pointer to hold wlan stats 19323 * 19324 * Return: 0 for success or error code 19325 */ 19326 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 19327 void *evt_buf, 19328 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 19329 { 19330 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19331 wlan_dcs_im_tgt_stats_t *ev; 19332 19333 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19334 if (!param_buf) 19335 return QDF_STATUS_E_INVAL; 19336 19337 ev = param_buf->wlan_stat; 19338 wlan_stat->reg_tsf32 = ev->reg_tsf32; 19339 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 19340 wlan_stat->tx_waste_time = ev->tx_waste_time; 19341 wlan_stat->rx_time = ev->rx_time; 19342 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 19343 wlan_stat->mib_stats.listen_time = ev->listen_time; 19344 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 19345 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 19346 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 19347 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 19348 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 19349 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 19350 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 19351 wlan_stat->chan_nf = ev->chan_nf; 19352 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19353 19354 return QDF_STATUS_SUCCESS; 19355 } 19356 19357 /** 19358 * extract_thermal_stats_tlv() - extract thermal stats from event 19359 * @wmi_handle: wmi handle 19360 * @param evt_buf: Pointer to event buffer 19361 * @param temp: Pointer to hold extracted temperature 19362 * @param level: Pointer to hold extracted level 19363 * 19364 * Return: 0 for success or error code 19365 */ 19366 static QDF_STATUS 19367 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 19368 void *evt_buf, uint32_t *temp, 19369 uint32_t *level, uint32_t *pdev_id) 19370 { 19371 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19372 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 19373 19374 param_buf = 19375 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19376 if (!param_buf) 19377 return QDF_STATUS_E_INVAL; 19378 19379 tt_stats_event = param_buf->fixed_param; 19380 19381 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19382 tt_stats_event->pdev_id); 19383 *temp = tt_stats_event->temp; 19384 *level = tt_stats_event->level; 19385 19386 return QDF_STATUS_SUCCESS; 19387 } 19388 19389 /** 19390 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 19391 * @wmi_handle: wmi handle 19392 * @param evt_buf: pointer to event buffer 19393 * @param idx: Index to level stats 19394 * @param levelcount: Pointer to hold levelcount 19395 * @param dccount: Pointer to hold dccount 19396 * 19397 * Return: 0 for success or error code 19398 */ 19399 static QDF_STATUS 19400 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 19401 void *evt_buf, uint8_t idx, uint32_t *levelcount, 19402 uint32_t *dccount) 19403 { 19404 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19405 wmi_therm_throt_level_stats_info *tt_level_info; 19406 19407 param_buf = 19408 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19409 if (!param_buf) 19410 return QDF_STATUS_E_INVAL; 19411 19412 tt_level_info = param_buf->therm_throt_level_stats_info; 19413 19414 if (idx < THERMAL_LEVELS) { 19415 *levelcount = tt_level_info[idx].level_count; 19416 *dccount = tt_level_info[idx].dc_count; 19417 return QDF_STATUS_SUCCESS; 19418 } 19419 19420 return QDF_STATUS_E_FAILURE; 19421 } 19422 #ifdef BIG_ENDIAN_HOST 19423 /** 19424 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 19425 * @param data_len - data length 19426 * @param data - pointer to data 19427 * 19428 * Return: QDF_STATUS - success or error status 19429 */ 19430 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19431 { 19432 uint8_t *data_aligned = NULL; 19433 int c; 19434 unsigned char *data_unaligned; 19435 19436 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 19437 FIPS_ALIGN)); 19438 /* Assigning unaligned space to copy the data */ 19439 /* Checking if kmalloc does successful allocation */ 19440 if (data_unaligned == NULL) 19441 return QDF_STATUS_E_FAILURE; 19442 19443 /* Checking if space is alligned */ 19444 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 19445 /* align the data space */ 19446 data_aligned = 19447 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 19448 } else { 19449 data_aligned = (u_int8_t *)data_unaligned; 19450 } 19451 19452 /* memset and copy content from data to data aligned */ 19453 OS_MEMSET(data_aligned, 0, data_len); 19454 OS_MEMCPY(data_aligned, data, data_len); 19455 /* Endianness to LE */ 19456 for (c = 0; c < data_len/4; c++) { 19457 *((u_int32_t *)data_aligned + c) = 19458 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 19459 } 19460 19461 /* Copy content to event->data */ 19462 OS_MEMCPY(data, data_aligned, data_len); 19463 19464 /* clean up allocated space */ 19465 qdf_mem_free(data_unaligned); 19466 data_aligned = NULL; 19467 data_unaligned = NULL; 19468 19469 /*************************************************************/ 19470 19471 return QDF_STATUS_SUCCESS; 19472 } 19473 #else 19474 /** 19475 * fips_conv_data_be() - DUMMY for LE platform 19476 * 19477 * Return: QDF_STATUS - success 19478 */ 19479 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19480 { 19481 return QDF_STATUS_SUCCESS; 19482 } 19483 #endif 19484 19485 /** 19486 * extract_fips_event_data_tlv() - extract fips event data 19487 * @wmi_handle: wmi handle 19488 * @param evt_buf: pointer to event buffer 19489 * @param param: pointer FIPS event params 19490 * 19491 * Return: 0 for success or error code 19492 */ 19493 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 19494 void *evt_buf, struct wmi_host_fips_event_param *param) 19495 { 19496 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 19497 wmi_pdev_fips_event_fixed_param *event; 19498 19499 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 19500 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 19501 19502 if (fips_conv_data_be(event->data_len, param_buf->data) != 19503 QDF_STATUS_SUCCESS) 19504 return QDF_STATUS_E_FAILURE; 19505 19506 param->data = (uint32_t *)param_buf->data; 19507 param->data_len = event->data_len; 19508 param->error_status = event->error_status; 19509 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19510 event->pdev_id); 19511 19512 return QDF_STATUS_SUCCESS; 19513 } 19514 19515 /* 19516 * extract_peer_delete_response_event_tlv() - extract peer delete response event 19517 * @wmi_handle: wmi handle 19518 * @param evt_buf: pointer to event buffer 19519 * @param vdev_id: Pointer to hold vdev_id 19520 * @param mac_addr: Pointer to hold peer mac address 19521 * 19522 * Return: QDF_STATUS_SUCCESS for success or error code 19523 */ 19524 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 19525 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 19526 { 19527 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 19528 wmi_peer_delete_resp_event_fixed_param *ev; 19529 19530 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 19531 19532 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 19533 if (!ev) { 19534 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 19535 return QDF_STATUS_E_FAILURE; 19536 } 19537 19538 param->vdev_id = ev->vdev_id; 19539 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 19540 ¶m->mac_address.bytes[0]); 19541 19542 return QDF_STATUS_SUCCESS; 19543 } 19544 19545 static bool is_management_record_tlv(uint32_t cmd_id) 19546 { 19547 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 19548 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 19549 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 19550 return true; 19551 } 19552 19553 return false; 19554 } 19555 19556 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19557 { 19558 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 19559 19560 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 19561 19562 switch (set_cmd->param_id) { 19563 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 19564 case WMI_VDEV_PARAM_DTIM_POLICY: 19565 return HTC_TX_PACKET_TAG_AUTO_PM; 19566 default: 19567 break; 19568 } 19569 19570 return 0; 19571 } 19572 19573 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19574 { 19575 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 19576 19577 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 19578 19579 switch (ps_cmd->param) { 19580 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 19581 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 19582 case WMI_STA_PS_ENABLE_QPOWER: 19583 return HTC_TX_PACKET_TAG_AUTO_PM; 19584 default: 19585 break; 19586 } 19587 19588 return 0; 19589 } 19590 19591 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 19592 uint32_t cmd_id) 19593 { 19594 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 19595 return 0; 19596 19597 switch (cmd_id) { 19598 case WMI_VDEV_SET_PARAM_CMDID: 19599 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 19600 case WMI_STA_POWERSAVE_PARAM_CMDID: 19601 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 19602 default: 19603 break; 19604 } 19605 19606 return 0; 19607 } 19608 19609 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 19610 { 19611 uint16_t tag = 0; 19612 19613 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 19614 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 19615 __func__); 19616 return tag; 19617 } 19618 19619 if (wmi_handle->tag_crash_inject) 19620 tag = HTC_TX_PACKET_TAG_AUTO_PM; 19621 19622 wmi_handle->tag_crash_inject = false; 19623 return tag; 19624 } 19625 19626 /** 19627 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 19628 * @wmi_handle: WMI handle 19629 * @buf: WMI buffer 19630 * @cmd_id: WMI command Id 19631 * 19632 * Return htc_tx_tag 19633 */ 19634 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 19635 wmi_buf_t buf, 19636 uint32_t cmd_id) 19637 { 19638 uint16_t htc_tx_tag = 0; 19639 19640 switch (cmd_id) { 19641 case WMI_WOW_ENABLE_CMDID: 19642 case WMI_PDEV_SUSPEND_CMDID: 19643 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 19644 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 19645 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 19646 case WMI_PDEV_RESUME_CMDID: 19647 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 19648 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 19649 #ifdef FEATURE_WLAN_D0WOW 19650 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 19651 #endif 19652 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 19653 break; 19654 case WMI_FORCE_FW_HANG_CMDID: 19655 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 19656 break; 19657 case WMI_VDEV_SET_PARAM_CMDID: 19658 case WMI_STA_POWERSAVE_PARAM_CMDID: 19659 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 19660 default: 19661 break; 19662 } 19663 19664 return htc_tx_tag; 19665 } 19666 19667 /** 19668 * extract_channel_hopping_event_tlv() - extract channel hopping param 19669 * from event 19670 * @wmi_handle: wmi handle 19671 * @param evt_buf: pointer to event buffer 19672 * @param ch_hopping: Pointer to hold channel hopping param 19673 * 19674 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 19675 */ 19676 static QDF_STATUS extract_channel_hopping_event_tlv( 19677 wmi_unified_t wmi_handle, void *evt_buf, 19678 wmi_host_pdev_channel_hopping_event *ch_hopping) 19679 { 19680 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 19681 wmi_pdev_channel_hopping_event_fixed_param *event; 19682 19683 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 19684 event = (wmi_pdev_channel_hopping_event_fixed_param *) 19685 param_buf->fixed_param; 19686 19687 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 19688 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 19689 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19690 event->pdev_id); 19691 19692 return QDF_STATUS_SUCCESS; 19693 } 19694 19695 /** 19696 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 19697 * @wmi_handle: wmi handle 19698 * @param evt_buf: pointer to event buffer 19699 * @param param: Pointer to hold tpc param 19700 * 19701 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 19702 */ 19703 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 19704 void *evt_buf, 19705 wmi_host_pdev_tpc_event *param) 19706 { 19707 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 19708 wmi_pdev_tpc_event_fixed_param *event; 19709 19710 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 19711 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 19712 19713 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19714 event->pdev_id); 19715 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 19716 19717 return QDF_STATUS_SUCCESS; 19718 } 19719 19720 /** 19721 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 19722 * power param from event 19723 * @wmi_handle: wmi handle 19724 * @param evt_buf: pointer to event buffer 19725 * @param param: Pointer to hold nf cal power param 19726 * 19727 * Return: 0 for success or error code 19728 */ 19729 static QDF_STATUS 19730 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 19731 void *evt_buf, 19732 wmi_host_pdev_nfcal_power_all_channels_event *param) 19733 { 19734 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 19735 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 19736 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 19737 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 19738 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 19739 uint32_t i; 19740 19741 param_buf = 19742 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 19743 event = param_buf->fixed_param; 19744 ch_nfdbr = param_buf->nfdbr; 19745 ch_nfdbm = param_buf->nfdbm; 19746 ch_freqnum = param_buf->freqnum; 19747 19748 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 19749 event->pdev_id, param_buf->num_nfdbr, 19750 param_buf->num_nfdbm, param_buf->num_freqnum); 19751 19752 if (param_buf->num_nfdbr > 19753 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 19754 WMI_LOGE("invalid number of nfdBr"); 19755 return QDF_STATUS_E_FAILURE; 19756 } 19757 19758 if (param_buf->num_nfdbm > 19759 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 19760 WMI_LOGE("invalid number of nfdBm"); 19761 return QDF_STATUS_E_FAILURE; 19762 } 19763 19764 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 19765 WMI_LOGE("invalid number of freqNum"); 19766 return QDF_STATUS_E_FAILURE; 19767 } 19768 19769 for (i = 0; i < param_buf->num_nfdbr; i++) { 19770 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 19771 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 19772 ch_nfdbr++; 19773 ch_nfdbm++; 19774 } 19775 19776 for (i = 0; i < param_buf->num_freqnum; i++) { 19777 param->freqnum[i] = ch_freqnum->freqNum; 19778 ch_freqnum++; 19779 } 19780 19781 param->pdev_id = wmi_handle->ops-> 19782 convert_pdev_id_target_to_host(event->pdev_id); 19783 19784 return QDF_STATUS_SUCCESS; 19785 } 19786 19787 19788 #ifdef BIG_ENDIAN_HOST 19789 /** 19790 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 19791 * @param data_len - data length 19792 * @param data - pointer to data 19793 * 19794 * Return: QDF_STATUS - success or error status 19795 */ 19796 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 19797 { 19798 uint8_t *datap = (uint8_t *)ev; 19799 int i; 19800 /* Skip swapping the first word */ 19801 datap += sizeof(uint32_t); 19802 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 19803 i++, datap += sizeof(uint32_t)) { 19804 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 19805 } 19806 19807 return QDF_STATUS_SUCCESS; 19808 } 19809 #else 19810 /** 19811 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 19812 * @param data_len - data length 19813 * @param data - pointer to data 19814 * 19815 * Return: QDF_STATUS - success or error status 19816 */ 19817 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 19818 { 19819 return QDF_STATUS_SUCCESS; 19820 } 19821 #endif 19822 19823 /** 19824 * extract_wds_addr_event_tlv() - extract wds address from event 19825 * @wmi_handle: wmi handle 19826 * @param evt_buf: pointer to event buffer 19827 * @param wds_ev: Pointer to hold wds address 19828 * 19829 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 19830 */ 19831 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 19832 void *evt_buf, 19833 uint16_t len, wds_addr_event_t *wds_ev) 19834 { 19835 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 19836 wmi_wds_addr_event_fixed_param *ev; 19837 int i; 19838 19839 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 19840 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 19841 19842 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 19843 return QDF_STATUS_E_FAILURE; 19844 19845 qdf_mem_copy(wds_ev->event_type, ev->event_type, 19846 sizeof(wds_ev->event_type)); 19847 for (i = 0; i < 4; i++) { 19848 wds_ev->peer_mac[i] = 19849 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 19850 wds_ev->dest_mac[i] = 19851 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 19852 } 19853 for (i = 0; i < 2; i++) { 19854 wds_ev->peer_mac[4+i] = 19855 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 19856 wds_ev->dest_mac[4+i] = 19857 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 19858 } 19859 return QDF_STATUS_SUCCESS; 19860 } 19861 19862 /** 19863 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 19864 * from event 19865 * @wmi_handle: wmi handle 19866 * @param evt_buf: pointer to event buffer 19867 * @param ev: Pointer to hold peer param and ps state 19868 * 19869 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 19870 */ 19871 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 19872 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 19873 { 19874 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 19875 wmi_peer_sta_ps_statechange_event_fixed_param *event; 19876 19877 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 19878 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 19879 param_buf->fixed_param; 19880 19881 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 19882 ev->peer_ps_state = event->peer_ps_state; 19883 19884 return QDF_STATUS_SUCCESS; 19885 } 19886 19887 /** 19888 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 19889 * @wmi_handle: wmi handle 19890 * @param evt_buf: pointer to event buffer 19891 * @param inst_rssi_resp: Pointer to hold inst rssi response 19892 * 19893 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 19894 */ 19895 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 19896 wmi_unified_t wmi_handle, void *evt_buf, 19897 wmi_host_inst_stats_resp *inst_rssi_resp) 19898 { 19899 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 19900 wmi_inst_rssi_stats_resp_fixed_param *event; 19901 19902 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 19903 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 19904 19905 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 19906 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 19907 inst_rssi_resp->iRSSI = event->iRSSI; 19908 19909 return QDF_STATUS_SUCCESS; 19910 } 19911 19912 static struct cur_reg_rule 19913 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 19914 wmi_regulatory_rule_struct *wmi_reg_rule) 19915 { 19916 struct cur_reg_rule *reg_rule_ptr; 19917 uint32_t count; 19918 19919 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 19920 19921 if (NULL == reg_rule_ptr) { 19922 WMI_LOGE("memory allocation failure"); 19923 return NULL; 19924 } 19925 19926 for (count = 0; count < num_reg_rules; count++) { 19927 reg_rule_ptr[count].start_freq = 19928 WMI_REG_RULE_START_FREQ_GET( 19929 wmi_reg_rule[count].freq_info); 19930 reg_rule_ptr[count].end_freq = 19931 WMI_REG_RULE_END_FREQ_GET( 19932 wmi_reg_rule[count].freq_info); 19933 reg_rule_ptr[count].max_bw = 19934 WMI_REG_RULE_MAX_BW_GET( 19935 wmi_reg_rule[count].bw_pwr_info); 19936 reg_rule_ptr[count].reg_power = 19937 WMI_REG_RULE_REG_POWER_GET( 19938 wmi_reg_rule[count].bw_pwr_info); 19939 reg_rule_ptr[count].ant_gain = 19940 WMI_REG_RULE_ANTENNA_GAIN_GET( 19941 wmi_reg_rule[count].bw_pwr_info); 19942 reg_rule_ptr[count].flags = 19943 WMI_REG_RULE_FLAGS_GET( 19944 wmi_reg_rule[count].flag_info); 19945 } 19946 19947 return reg_rule_ptr; 19948 } 19949 19950 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 19951 wmi_unified_t wmi_handle, uint8_t *evt_buf, 19952 struct cur_regulatory_info *reg_info, uint32_t len) 19953 { 19954 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 19955 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 19956 wmi_regulatory_rule_struct *wmi_reg_rule; 19957 uint32_t num_2g_reg_rules, num_5g_reg_rules; 19958 19959 WMI_LOGD("processing regulatory channel list"); 19960 19961 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 19962 if (!param_buf) { 19963 WMI_LOGE("invalid channel list event buf"); 19964 return QDF_STATUS_E_FAILURE; 19965 } 19966 19967 chan_list_event_hdr = param_buf->fixed_param; 19968 19969 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 19970 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 19971 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 19972 REG_ALPHA2_LEN); 19973 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 19974 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 19975 reg_info->offload_enabled = true; 19976 reg_info->num_phy = chan_list_event_hdr->num_phy; 19977 reg_info->phy_id = chan_list_event_hdr->phy_id; 19978 reg_info->ctry_code = chan_list_event_hdr->country_id; 19979 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 19980 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 19981 reg_info->status_code = REG_SET_CC_STATUS_PASS; 19982 else if (chan_list_event_hdr->status_code == 19983 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 19984 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 19985 else if (chan_list_event_hdr->status_code == 19986 WMI_REG_INIT_ALPHA2_NOT_FOUND) 19987 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 19988 else if (chan_list_event_hdr->status_code == 19989 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 19990 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 19991 else if (chan_list_event_hdr->status_code == 19992 WMI_REG_SET_CC_STATUS_NO_MEMORY) 19993 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 19994 else if (chan_list_event_hdr->status_code == 19995 WMI_REG_SET_CC_STATUS_FAIL) 19996 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 19997 19998 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 19999 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20000 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20001 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20002 20003 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20004 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20005 20006 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20007 __func__, reg_info->alpha2, reg_info->dfs_region, 20008 reg_info->min_bw_2g, reg_info->max_bw_2g, 20009 reg_info->min_bw_5g, reg_info->max_bw_5g); 20010 20011 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20012 num_2g_reg_rules, num_5g_reg_rules); 20013 wmi_reg_rule = 20014 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20015 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20016 + WMI_TLV_HDR_SIZE); 20017 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20018 wmi_reg_rule); 20019 wmi_reg_rule += num_2g_reg_rules; 20020 20021 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20022 wmi_reg_rule); 20023 20024 WMI_LOGD("processed regulatory channel list"); 20025 20026 return QDF_STATUS_SUCCESS; 20027 } 20028 20029 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20030 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20031 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20032 { 20033 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20034 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20035 20036 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20037 if (!param_buf) { 20038 WMI_LOGE("invalid 11d country event buf"); 20039 return QDF_STATUS_E_FAILURE; 20040 } 20041 20042 reg_11d_country_event = param_buf->fixed_param; 20043 20044 qdf_mem_copy(reg_11d_country->alpha2, 20045 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20046 20047 WMI_LOGD("processed 11d country event, new cc %s", 20048 reg_11d_country->alpha2); 20049 20050 return QDF_STATUS_SUCCESS; 20051 } 20052 20053 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20054 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20055 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20056 { 20057 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20058 wmi_avoid_freq_range_desc *afr_desc; 20059 uint32_t num_freq_ranges, freq_range_idx; 20060 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20061 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20062 20063 if (!param_buf) { 20064 WMI_LOGE("Invalid channel avoid event buffer"); 20065 return QDF_STATUS_E_INVAL; 20066 } 20067 20068 afr_fixed_param = param_buf->fixed_param; 20069 if (!afr_fixed_param) { 20070 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20071 return QDF_STATUS_E_INVAL; 20072 } 20073 20074 if (!ch_avoid_ind) { 20075 WMI_LOGE("Invalid channel avoid indication buffer"); 20076 return QDF_STATUS_E_INVAL; 20077 } 20078 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20079 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20080 afr_fixed_param->num_freq_ranges; 20081 20082 WMI_LOGD("Channel avoid event received with %d ranges", 20083 num_freq_ranges); 20084 20085 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20086 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20087 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20088 freq_range_idx++) { 20089 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20090 afr_desc->start_freq; 20091 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20092 afr_desc->end_freq; 20093 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20094 freq_range_idx, afr_desc->tlv_header, 20095 afr_desc->start_freq, afr_desc->end_freq); 20096 afr_desc++; 20097 } 20098 20099 return QDF_STATUS_SUCCESS; 20100 } 20101 #ifdef DFS_COMPONENT_ENABLE 20102 /** 20103 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20104 * @wmi_handle: wma handle 20105 * @evt_buf: event buffer 20106 * @vdev_id: vdev id 20107 * @len: length of buffer 20108 * 20109 * Return: 0 for success or error code 20110 */ 20111 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20112 uint8_t *evt_buf, 20113 uint32_t *vdev_id, 20114 uint32_t len) 20115 { 20116 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20117 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20118 20119 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20120 if (!param_tlvs) { 20121 WMI_LOGE("invalid cac complete event buf"); 20122 return QDF_STATUS_E_FAILURE; 20123 } 20124 20125 cac_event = param_tlvs->fixed_param; 20126 *vdev_id = cac_event->vdev_id; 20127 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20128 20129 return QDF_STATUS_SUCCESS; 20130 } 20131 20132 /** 20133 * extract_dfs_radar_detection_event_tlv() - extract radar found event 20134 * @wmi_handle: wma handle 20135 * @evt_buf: event buffer 20136 * @radar_found: radar found event info 20137 * @len: length of buffer 20138 * 20139 * Return: 0 for success or error code 20140 */ 20141 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 20142 wmi_unified_t wmi_handle, 20143 uint8_t *evt_buf, 20144 struct radar_found_info *radar_found, 20145 uint32_t len) 20146 { 20147 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 20148 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 20149 20150 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 20151 if (!param_tlv) { 20152 WMI_LOGE("invalid radar detection event buf"); 20153 return QDF_STATUS_E_FAILURE; 20154 } 20155 20156 radar_event = param_tlv->fixed_param; 20157 radar_found->pdev_id = wmi_handle->ops-> 20158 convert_pdev_id_target_to_host(radar_event->pdev_id); 20159 radar_found->detection_mode = radar_event->detection_mode; 20160 radar_found->chan_freq = radar_event->chan_freq; 20161 radar_found->chan_width = radar_event->chan_width; 20162 radar_found->detector_id = radar_event->detector_id; 20163 radar_found->segment_id = radar_event->segment_id; 20164 radar_found->timestamp = radar_event->timestamp; 20165 radar_found->is_chirp = radar_event->is_chirp; 20166 radar_found->freq_offset = radar_event->freq_offset; 20167 radar_found->sidx = radar_event->sidx; 20168 20169 WMI_LOGI("processed radar found event pdev %d," 20170 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 20171 "chan_width (RSSI) %d,detector_id (false_radar) %d," 20172 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 20173 "is_chirp %d,detection mode %d\n", 20174 radar_event->pdev_id, radar_event->pdev_id, 20175 radar_event->timestamp, radar_event->chan_freq, 20176 radar_event->chan_width, radar_event->detector_id, 20177 radar_event->freq_offset, radar_event->segment_id, 20178 radar_event->sidx, radar_event->is_chirp, 20179 radar_event->detection_mode); 20180 20181 return QDF_STATUS_SUCCESS; 20182 } 20183 20184 #ifdef QCA_MCL_DFS_SUPPORT 20185 /** 20186 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 20187 * @wmi_handle: wma handle 20188 * @evt_buf: event buffer 20189 * @wlan_radar_event: Pointer to struct radar_event_info 20190 * @len: length of buffer 20191 * 20192 * Return: QDF_STATUS 20193 */ 20194 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20195 wmi_unified_t wmi_handle, 20196 uint8_t *evt_buf, 20197 struct radar_event_info *wlan_radar_event, 20198 uint32_t len) 20199 { 20200 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 20201 wmi_dfs_radar_event_fixed_param *radar_event; 20202 20203 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 20204 if (!param_tlv) { 20205 WMI_LOGE("invalid wlan radar event buf"); 20206 return QDF_STATUS_E_FAILURE; 20207 } 20208 20209 radar_event = param_tlv->fixed_param; 20210 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 20211 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 20212 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 20213 wlan_radar_event->rssi = radar_event->rssi; 20214 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 20215 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 20216 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 20217 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 20218 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 20219 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 20220 if (radar_event->pulse_flags & 20221 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 20222 wlan_radar_event->is_psidx_diff_valid = true; 20223 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 20224 } else { 20225 wlan_radar_event->is_psidx_diff_valid = false; 20226 } 20227 20228 wlan_radar_event->pdev_id = radar_event->pdev_id; 20229 20230 return QDF_STATUS_SUCCESS; 20231 } 20232 #else 20233 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20234 wmi_unified_t wmi_handle, 20235 uint8_t *evt_buf, 20236 struct radar_event_info *wlan_radar_event, 20237 uint32_t len) 20238 { 20239 return QDF_STATUS_SUCCESS; 20240 } 20241 #endif 20242 #endif 20243 20244 /** 20245 * send_get_rcpi_cmd_tlv() - send request for rcpi value 20246 * @wmi_handle: wmi handle 20247 * @get_rcpi_param: rcpi params 20248 * 20249 * Return: QDF status 20250 */ 20251 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 20252 struct rcpi_req *get_rcpi_param) 20253 { 20254 wmi_buf_t buf; 20255 wmi_request_rcpi_cmd_fixed_param *cmd; 20256 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 20257 20258 buf = wmi_buf_alloc(wmi_handle, len); 20259 if (!buf) { 20260 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 20261 return QDF_STATUS_E_NOMEM; 20262 } 20263 20264 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 20265 WMITLV_SET_HDR(&cmd->tlv_header, 20266 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 20267 WMITLV_GET_STRUCT_TLVLEN 20268 (wmi_request_rcpi_cmd_fixed_param)); 20269 20270 cmd->vdev_id = get_rcpi_param->vdev_id; 20271 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 20272 &cmd->peer_macaddr); 20273 20274 switch (get_rcpi_param->measurement_type) { 20275 20276 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20277 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20278 break; 20279 20280 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 20281 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 20282 break; 20283 20284 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20285 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20286 break; 20287 20288 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 20289 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 20290 break; 20291 20292 default: 20293 /* 20294 * invalid rcpi measurement type, fall back to 20295 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 20296 */ 20297 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20298 break; 20299 } 20300 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 20301 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20302 WMI_REQUEST_RCPI_CMDID)) { 20303 20304 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 20305 __func__); 20306 wmi_buf_free(buf); 20307 return QDF_STATUS_E_FAILURE; 20308 } 20309 20310 return QDF_STATUS_SUCCESS; 20311 } 20312 20313 /** 20314 * extract_rcpi_response_event_tlv() - Extract RCPI event params 20315 * @wmi_handle: wmi handle 20316 * @evt_buf: pointer to event buffer 20317 * @res: pointer to hold rcpi response from firmware 20318 * 20319 * Return: QDF_STATUS_SUCCESS for successful event parse 20320 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 20321 */ 20322 static QDF_STATUS 20323 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 20324 void *evt_buf, struct rcpi_res *res) 20325 { 20326 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 20327 wmi_update_rcpi_event_fixed_param *event; 20328 20329 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 20330 if (!param_buf) { 20331 WMI_LOGE(FL("Invalid rcpi event")); 20332 return QDF_STATUS_E_INVAL; 20333 } 20334 20335 event = param_buf->fixed_param; 20336 res->vdev_id = event->vdev_id; 20337 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 20338 20339 switch (event->measurement_type) { 20340 20341 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20342 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20343 break; 20344 20345 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 20346 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 20347 break; 20348 20349 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20350 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20351 break; 20352 20353 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 20354 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 20355 break; 20356 20357 default: 20358 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 20359 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 20360 return QDF_STATUS_E_FAILURE; 20361 } 20362 20363 if (event->status) 20364 return QDF_STATUS_E_FAILURE; 20365 else 20366 return QDF_STATUS_SUCCESS; 20367 } 20368 20369 /** 20370 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 20371 * host to target defines. For legacy there is not conversion 20372 * required. Just return pdev_id as it is. 20373 * @param pdev_id: host pdev_id to be converted. 20374 * Return: target pdev_id after conversion. 20375 */ 20376 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 20377 uint32_t pdev_id) 20378 { 20379 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 20380 return WMI_PDEV_ID_SOC; 20381 20382 /*No conversion required*/ 20383 return pdev_id; 20384 } 20385 20386 /** 20387 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 20388 * target to host defines. For legacy there is not conversion 20389 * required. Just return pdev_id as it is. 20390 * @param pdev_id: target pdev_id to be converted. 20391 * Return: host pdev_id after conversion. 20392 */ 20393 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 20394 uint32_t pdev_id) 20395 { 20396 /*No conversion required*/ 20397 return pdev_id; 20398 } 20399 20400 /** 20401 * send_set_country_cmd_tlv() - WMI scan channel list function 20402 * @param wmi_handle : handle to WMI. 20403 * @param param : pointer to hold scan channel list parameter 20404 * 20405 * Return: 0 on success and -ve on failure. 20406 */ 20407 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 20408 struct set_country *params) 20409 { 20410 wmi_buf_t buf; 20411 QDF_STATUS qdf_status; 20412 wmi_set_current_country_cmd_fixed_param *cmd; 20413 uint16_t len = sizeof(*cmd); 20414 20415 buf = wmi_buf_alloc(wmi_handle, len); 20416 if (!buf) { 20417 WMI_LOGE("Failed to allocate memory"); 20418 qdf_status = QDF_STATUS_E_NOMEM; 20419 goto end; 20420 } 20421 20422 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 20423 WMITLV_SET_HDR(&cmd->tlv_header, 20424 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 20425 WMITLV_GET_STRUCT_TLVLEN 20426 (wmi_set_current_country_cmd_fixed_param)); 20427 20428 WMI_LOGD("setting cuurnet country to %s", params->country); 20429 20430 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 20431 20432 cmd->pdev_id = params->pdev_id; 20433 20434 qdf_status = wmi_unified_cmd_send(wmi_handle, 20435 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 20436 20437 if (QDF_IS_STATUS_ERROR(qdf_status)) { 20438 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 20439 wmi_buf_free(buf); 20440 } 20441 20442 end: 20443 return qdf_status; 20444 } 20445 20446 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 20447 WMI_SET_BITS(alpha, 0, 8, val0); \ 20448 WMI_SET_BITS(alpha, 8, 8, val1); \ 20449 WMI_SET_BITS(alpha, 16, 8, val2); \ 20450 } while (0) 20451 20452 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 20453 uint8_t pdev_id, struct cc_regdmn_s *rd) 20454 { 20455 wmi_set_init_country_cmd_fixed_param *cmd; 20456 uint16_t len; 20457 wmi_buf_t buf; 20458 int ret; 20459 20460 len = sizeof(wmi_set_init_country_cmd_fixed_param); 20461 buf = wmi_buf_alloc(wmi_handle, len); 20462 if (!buf) { 20463 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 20464 return QDF_STATUS_E_NOMEM; 20465 } 20466 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 20467 WMITLV_SET_HDR(&cmd->tlv_header, 20468 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 20469 WMITLV_GET_STRUCT_TLVLEN 20470 (wmi_set_init_country_cmd_fixed_param)); 20471 20472 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 20473 20474 if (rd->flags == CC_IS_SET) { 20475 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 20476 cmd->country_code.country_id = rd->cc.country_code; 20477 } else if (rd->flags == ALPHA_IS_SET) { 20478 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 20479 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 20480 rd->cc.alpha[0], 20481 rd->cc.alpha[1], 20482 rd->cc.alpha[2]); 20483 } else if (rd->flags == REGDMN_IS_SET) { 20484 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 20485 cmd->country_code.domain_code = rd->cc.regdmn_id; 20486 } 20487 20488 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20489 WMI_SET_INIT_COUNTRY_CMDID); 20490 if (ret) { 20491 WMI_LOGE("Failed to config wow wakeup event"); 20492 wmi_buf_free(buf); 20493 return QDF_STATUS_E_FAILURE; 20494 } 20495 20496 return QDF_STATUS_SUCCESS; 20497 } 20498 20499 /** 20500 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 20501 * configuration params 20502 * @wmi_handle: wmi handler 20503 * @limit_off_chan_param: pointer to wmi_off_chan_param 20504 * 20505 * Return: 0 for success and non zero for failure 20506 */ 20507 static 20508 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 20509 struct wmi_limit_off_chan_param *limit_off_chan_param) 20510 { 20511 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 20512 wmi_buf_t buf; 20513 uint32_t len = sizeof(*cmd); 20514 int err; 20515 20516 buf = wmi_buf_alloc(wmi_handle, len); 20517 if (!buf) { 20518 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 20519 __func__); 20520 return QDF_STATUS_E_NOMEM; 20521 } 20522 20523 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 20524 20525 WMITLV_SET_HDR(&cmd->tlv_header, 20526 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 20527 WMITLV_GET_STRUCT_TLVLEN( 20528 wmi_vdev_limit_offchan_cmd_fixed_param)); 20529 20530 cmd->vdev_id = limit_off_chan_param->vdev_id; 20531 20532 cmd->flags &= 0; 20533 if (limit_off_chan_param->status) 20534 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 20535 if (limit_off_chan_param->skip_dfs_chans) 20536 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 20537 20538 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 20539 cmd->rest_time = limit_off_chan_param->rest_time; 20540 20541 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 20542 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 20543 cmd->rest_time); 20544 20545 err = wmi_unified_cmd_send(wmi_handle, buf, 20546 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 20547 if (QDF_IS_STATUS_ERROR(err)) { 20548 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 20549 wmi_buf_free(buf); 20550 return QDF_STATUS_E_FAILURE; 20551 } 20552 20553 return QDF_STATUS_SUCCESS; 20554 } 20555 20556 /** 20557 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 20558 * @wmi_handle: wmi handler 20559 * @req_buf: set arp stats request buffer 20560 * 20561 * Return: 0 for success and non zero for failure 20562 */ 20563 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20564 struct set_arp_stats *req_buf) 20565 { 20566 wmi_buf_t buf = NULL; 20567 QDF_STATUS status; 20568 int len; 20569 uint8_t *buf_ptr; 20570 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 20571 20572 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20573 if (req_buf->pkt_type_bitmap) { 20574 len += WMI_TLV_HDR_SIZE; 20575 len += sizeof(wmi_vdev_set_connectivity_check_stats); 20576 } 20577 buf = wmi_buf_alloc(wmi_handle, len); 20578 if (!buf) { 20579 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 20580 return QDF_STATUS_E_NOMEM; 20581 } 20582 20583 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20584 wmi_set_arp = 20585 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 20586 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 20587 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 20588 WMITLV_GET_STRUCT_TLVLEN 20589 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 20590 20591 /* fill in per roam config values */ 20592 wmi_set_arp->vdev_id = req_buf->vdev_id; 20593 20594 wmi_set_arp->set_clr = req_buf->flag; 20595 wmi_set_arp->pkt_type = req_buf->pkt_type; 20596 wmi_set_arp->ipv4 = req_buf->ip_addr; 20597 20598 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 20599 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 20600 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 20601 20602 /* 20603 * pkt_type_bitmap should be non-zero to ensure 20604 * presence of additional stats. 20605 */ 20606 if (req_buf->pkt_type_bitmap) { 20607 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 20608 20609 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20610 WMITLV_SET_HDR(buf_ptr, 20611 WMITLV_TAG_ARRAY_STRUC, 20612 sizeof(wmi_vdev_set_connectivity_check_stats)); 20613 buf_ptr += WMI_TLV_HDR_SIZE; 20614 wmi_set_connect_stats = 20615 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 20616 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 20617 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 20618 WMITLV_GET_STRUCT_TLVLEN( 20619 wmi_vdev_set_connectivity_check_stats)); 20620 wmi_set_connect_stats->pkt_type_bitmap = 20621 req_buf->pkt_type_bitmap; 20622 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 20623 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 20624 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 20625 20626 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 20627 wmi_set_connect_stats->pkt_type_bitmap, 20628 wmi_set_connect_stats->tcp_src_port, 20629 wmi_set_connect_stats->tcp_dst_port, 20630 wmi_set_connect_stats->icmp_ipv4); 20631 } 20632 20633 /* Send per roam config parameters */ 20634 status = wmi_unified_cmd_send(wmi_handle, buf, 20635 len, WMI_VDEV_SET_ARP_STAT_CMDID); 20636 if (QDF_IS_STATUS_ERROR(status)) { 20637 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 20638 status); 20639 goto error; 20640 } 20641 20642 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 20643 req_buf->flag, req_buf->vdev_id); 20644 return QDF_STATUS_SUCCESS; 20645 error: 20646 wmi_buf_free(buf); 20647 20648 return status; 20649 } 20650 20651 /** 20652 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 20653 * @wmi_handle: wmi handler 20654 * @req_buf: get arp stats request buffer 20655 * 20656 * Return: 0 for success and non zero for failure 20657 */ 20658 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20659 struct get_arp_stats *req_buf) 20660 { 20661 wmi_buf_t buf = NULL; 20662 QDF_STATUS status; 20663 int len; 20664 uint8_t *buf_ptr; 20665 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 20666 20667 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 20668 buf = wmi_buf_alloc(wmi_handle, len); 20669 if (!buf) { 20670 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 20671 return QDF_STATUS_E_NOMEM; 20672 } 20673 20674 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20675 get_arp_stats = 20676 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 20677 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 20678 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 20679 WMITLV_GET_STRUCT_TLVLEN 20680 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 20681 20682 /* fill in arp stats req cmd values */ 20683 get_arp_stats->vdev_id = req_buf->vdev_id; 20684 20685 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 20686 /* Send per roam config parameters */ 20687 status = wmi_unified_cmd_send(wmi_handle, buf, 20688 len, WMI_VDEV_GET_ARP_STAT_CMDID); 20689 if (QDF_IS_STATUS_ERROR(status)) { 20690 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 20691 status); 20692 goto error; 20693 } 20694 20695 return QDF_STATUS_SUCCESS; 20696 error: 20697 wmi_buf_free(buf); 20698 20699 return status; 20700 } 20701 20702 /** 20703 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 20704 * @wmi_handle: wmi handler 20705 * @pmk_info: pointer to PMK cache entry 20706 * @vdev_id: vdev id 20707 * 20708 * Return: 0 for success and non zero for failure 20709 */ 20710 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 20711 struct wmi_unified_pmk_cache *pmk_info) 20712 { 20713 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 20714 wmi_buf_t buf; 20715 QDF_STATUS status; 20716 uint8_t *buf_ptr; 20717 wmi_pmk_cache *pmksa; 20718 uint32_t len = sizeof(*cmd); 20719 20720 if (pmk_info->pmk_len) 20721 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 20722 20723 buf = wmi_buf_alloc(wmi_handle, len); 20724 if (!buf) { 20725 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 20726 __func__); 20727 return QDF_STATUS_E_NOMEM; 20728 } 20729 20730 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20731 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 20732 20733 WMITLV_SET_HDR(&cmd->tlv_header, 20734 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 20735 WMITLV_GET_STRUCT_TLVLEN( 20736 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 20737 20738 cmd->vdev_id = pmk_info->session_id; 20739 20740 /* If pmk_info->pmk_len is 0, this is a flush request */ 20741 if (!pmk_info->pmk_len) { 20742 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 20743 cmd->num_cache = 0; 20744 goto send_cmd; 20745 } 20746 20747 cmd->num_cache = 1; 20748 buf_ptr += sizeof(*cmd); 20749 20750 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20751 sizeof(*pmksa)); 20752 buf_ptr += WMI_TLV_HDR_SIZE; 20753 20754 pmksa = (wmi_pmk_cache *)buf_ptr; 20755 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 20756 WMITLV_GET_STRUCT_TLVLEN 20757 (wmi_pmk_cache)); 20758 pmksa->pmk_len = pmk_info->pmk_len; 20759 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 20760 pmksa->pmkid_len = pmk_info->pmkid_len; 20761 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 20762 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 20763 pmksa->ssid.ssid_len = pmk_info->ssid.length; 20764 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 20765 pmksa->ssid.ssid_len); 20766 pmksa->cache_id = pmk_info->cache_id; 20767 pmksa->cat_flag = pmk_info->cat_flag; 20768 pmksa->action_flag = pmk_info->action_flag; 20769 20770 send_cmd: 20771 status = wmi_unified_cmd_send(wmi_handle, buf, len, 20772 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 20773 if (status != QDF_STATUS_SUCCESS) { 20774 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 20775 __func__, status); 20776 wmi_buf_free(buf); 20777 } 20778 20779 return status; 20780 } 20781 20782 /** 20783 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 20784 * @wmi_handle: wmi handle 20785 * @param: reserved param 20786 * 20787 * Return: 0 for success or error code 20788 */ 20789 static QDF_STATUS 20790 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 20791 uint32_t param) 20792 { 20793 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 20794 wmi_buf_t buf; 20795 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 20796 20797 buf = wmi_buf_alloc(wmi_handle, len); 20798 if (!buf) { 20799 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 20800 return QDF_STATUS_E_FAILURE; 20801 } 20802 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 20803 WMITLV_SET_HDR(&cmd->tlv_header, 20804 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 20805 WMITLV_GET_STRUCT_TLVLEN 20806 (wmi_pdev_check_cal_version_cmd_fixed_param)); 20807 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 20808 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20809 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 20810 wmi_buf_free(buf); 20811 return QDF_STATUS_E_FAILURE; 20812 } 20813 20814 return QDF_STATUS_SUCCESS; 20815 } 20816 20817 /** 20818 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 20819 * host to target defines. 20820 * @param pdev_id: host pdev_id to be converted. 20821 * Return: target pdev_id after conversion. 20822 */ 20823 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 20824 { 20825 switch (pdev_id) { 20826 case WMI_HOST_PDEV_ID_SOC: 20827 return WMI_PDEV_ID_SOC; 20828 case WMI_HOST_PDEV_ID_0: 20829 return WMI_PDEV_ID_1ST; 20830 case WMI_HOST_PDEV_ID_1: 20831 return WMI_PDEV_ID_2ND; 20832 case WMI_HOST_PDEV_ID_2: 20833 return WMI_PDEV_ID_3RD; 20834 } 20835 20836 QDF_ASSERT(0); 20837 20838 return WMI_PDEV_ID_SOC; 20839 } 20840 20841 /** 20842 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 20843 * target to host defines. 20844 * @param pdev_id: target pdev_id to be converted. 20845 * Return: host pdev_id after conversion. 20846 */ 20847 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 20848 { 20849 switch (pdev_id) { 20850 case WMI_PDEV_ID_SOC: 20851 return WMI_HOST_PDEV_ID_SOC; 20852 case WMI_PDEV_ID_1ST: 20853 return WMI_HOST_PDEV_ID_0; 20854 case WMI_PDEV_ID_2ND: 20855 return WMI_HOST_PDEV_ID_1; 20856 case WMI_PDEV_ID_3RD: 20857 return WMI_HOST_PDEV_ID_2; 20858 } 20859 20860 QDF_ASSERT(0); 20861 20862 return WMI_HOST_PDEV_ID_SOC; 20863 } 20864 20865 /** 20866 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 20867 * 20868 * Return None. 20869 */ 20870 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 20871 { 20872 wmi_handle->ops->convert_pdev_id_host_to_target = 20873 convert_host_pdev_id_to_target_pdev_id; 20874 wmi_handle->ops->convert_pdev_id_target_to_host = 20875 convert_target_pdev_id_to_host_pdev_id; 20876 } 20877 20878 /** 20879 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 20880 * @wmi_handle: wmi handle 20881 * @param evt_buf: pointer to event buffer 20882 * @param param: Pointer to hold peer caldata version data 20883 * 20884 * Return: 0 for success or error code 20885 */ 20886 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 20887 wmi_unified_t wmi_handle, 20888 void *evt_buf, 20889 wmi_host_pdev_check_cal_version_event *param) 20890 { 20891 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 20892 wmi_pdev_check_cal_version_event_fixed_param *event; 20893 20894 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 20895 if (!param_tlvs) { 20896 WMI_LOGE("invalid cal version event buf"); 20897 return QDF_STATUS_E_FAILURE; 20898 } 20899 event = param_tlvs->fixed_param; 20900 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 20901 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 20902 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 20903 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 20904 20905 param->software_cal_version = event->software_cal_version; 20906 param->board_cal_version = event->board_cal_version; 20907 param->cal_ok = event->cal_status; 20908 20909 return QDF_STATUS_SUCCESS; 20910 } 20911 20912 /* 20913 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 20914 * @wmi_handle: wmi handle 20915 * @params: pointer to wmi_btm_config 20916 * 20917 * Return: QDF_STATUS 20918 */ 20919 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 20920 struct wmi_btm_config *params) 20921 { 20922 20923 wmi_btm_config_fixed_param *cmd; 20924 wmi_buf_t buf; 20925 uint32_t len; 20926 20927 len = sizeof(*cmd); 20928 buf = wmi_buf_alloc(wmi_handle, len); 20929 if (!buf) { 20930 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 20931 return QDF_STATUS_E_NOMEM; 20932 } 20933 20934 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 20935 WMITLV_SET_HDR(&cmd->tlv_header, 20936 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 20937 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 20938 cmd->vdev_id = params->vdev_id; 20939 cmd->flags = params->btm_offload_config; 20940 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 20941 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 20942 cmd->stick_time_seconds = params->btm_sticky_time; 20943 20944 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20945 WMI_ROAM_BTM_CONFIG_CMDID)) { 20946 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 20947 __func__); 20948 wmi_buf_free(buf); 20949 return QDF_STATUS_E_FAILURE; 20950 } 20951 20952 return QDF_STATUS_SUCCESS; 20953 } 20954 20955 /** 20956 * send_obss_detection_cfg_cmd_tlv() - send obss detection 20957 * configurations to firmware. 20958 * @wmi_handle: wmi handle 20959 * @obss_cfg_param: obss detection configurations 20960 * 20961 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 20962 * 20963 * Return: QDF_STATUS 20964 */ 20965 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 20966 struct wmi_obss_detection_cfg_param *obss_cfg_param) 20967 { 20968 wmi_buf_t buf; 20969 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 20970 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 20971 20972 buf = wmi_buf_alloc(wmi_handle, len); 20973 if (!buf) { 20974 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 20975 return QDF_STATUS_E_NOMEM; 20976 } 20977 20978 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 20979 WMITLV_SET_HDR(&cmd->tlv_header, 20980 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 20981 WMITLV_GET_STRUCT_TLVLEN 20982 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 20983 20984 cmd->vdev_id = obss_cfg_param->vdev_id; 20985 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 20986 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 20987 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 20988 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 20989 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 20990 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 20991 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 20992 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 20993 20994 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20995 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 20996 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 20997 wmi_buf_free(buf); 20998 return QDF_STATUS_E_FAILURE; 20999 } 21000 21001 return QDF_STATUS_SUCCESS; 21002 } 21003 21004 /** 21005 * extract_obss_detection_info_tlv() - Extract obss detection info 21006 * received from firmware. 21007 * @evt_buf: pointer to event buffer 21008 * @obss_detection: Pointer to hold obss detection info 21009 * 21010 * Return: QDF_STATUS 21011 */ 21012 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21013 struct wmi_obss_detect_info 21014 *obss_detection) 21015 { 21016 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21017 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21018 21019 if (!obss_detection) { 21020 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21021 return QDF_STATUS_E_INVAL; 21022 } 21023 21024 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21025 if (!param_buf) { 21026 WMI_LOGE("%s: Invalid evt_buf", __func__); 21027 return QDF_STATUS_E_INVAL; 21028 } 21029 21030 fix_param = param_buf->fixed_param; 21031 obss_detection->vdev_id = fix_param->vdev_id; 21032 obss_detection->matched_detection_masks = 21033 fix_param->matched_detection_masks; 21034 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21035 &obss_detection->matched_bssid_addr[0]); 21036 switch (fix_param->reason) { 21037 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21038 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21039 break; 21040 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21041 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21042 break; 21043 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21044 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21045 break; 21046 default: 21047 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21048 return QDF_STATUS_E_INVAL; 21049 } 21050 21051 return QDF_STATUS_SUCCESS; 21052 } 21053 21054 /** 21055 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 21056 * @wmi_handle: wmi handler 21057 * @params: pointer to 11k offload params 21058 * 21059 * Return: 0 for success and non zero for failure 21060 */ 21061 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 21062 struct wmi_11k_offload_params *params) 21063 { 21064 wmi_11k_offload_report_fixed_param *cmd; 21065 wmi_buf_t buf; 21066 QDF_STATUS status; 21067 uint8_t *buf_ptr; 21068 wmi_neighbor_report_11k_offload_tlv_param 21069 *neighbor_report_offload_params; 21070 wmi_neighbor_report_offload *neighbor_report_offload; 21071 21072 uint32_t len = sizeof(*cmd); 21073 21074 if (params->offload_11k_bitmask & 21075 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 21076 len += WMI_TLV_HDR_SIZE + 21077 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 21078 21079 buf = wmi_buf_alloc(wmi_handle, len); 21080 if (!buf) { 21081 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 21082 __func__); 21083 return QDF_STATUS_E_NOMEM; 21084 } 21085 21086 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21087 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 21088 21089 WMITLV_SET_HDR(&cmd->tlv_header, 21090 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 21091 WMITLV_GET_STRUCT_TLVLEN( 21092 wmi_11k_offload_report_fixed_param)); 21093 21094 cmd->vdev_id = params->vdev_id; 21095 cmd->offload_11k = params->offload_11k_bitmask; 21096 21097 if (params->offload_11k_bitmask & 21098 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 21099 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 21100 21101 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21102 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 21103 buf_ptr += WMI_TLV_HDR_SIZE; 21104 21105 neighbor_report_offload_params = 21106 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 21107 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 21108 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 21109 WMITLV_GET_STRUCT_TLVLEN( 21110 wmi_neighbor_report_11k_offload_tlv_param)); 21111 21112 neighbor_report_offload = &neighbor_report_offload_params-> 21113 neighbor_rep_ofld_params; 21114 21115 neighbor_report_offload->time_offset = 21116 params->neighbor_report_params.time_offset; 21117 neighbor_report_offload->low_rssi_offset = 21118 params->neighbor_report_params.low_rssi_offset; 21119 neighbor_report_offload->bmiss_count_trigger = 21120 params->neighbor_report_params.bmiss_count_trigger; 21121 neighbor_report_offload->per_threshold_offset = 21122 params->neighbor_report_params.per_threshold_offset; 21123 neighbor_report_offload->neighbor_report_cache_timeout = 21124 params->neighbor_report_params. 21125 neighbor_report_cache_timeout; 21126 neighbor_report_offload->max_neighbor_report_req_cap = 21127 params->neighbor_report_params. 21128 max_neighbor_report_req_cap; 21129 neighbor_report_offload->ssid.ssid_len = 21130 params->neighbor_report_params.ssid.length; 21131 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 21132 ¶ms->neighbor_report_params.ssid.mac_ssid, 21133 neighbor_report_offload->ssid.ssid_len); 21134 } 21135 21136 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21137 WMI_11K_OFFLOAD_REPORT_CMDID); 21138 if (status != QDF_STATUS_SUCCESS) { 21139 WMI_LOGE("%s: failed to send 11k offload command %d", 21140 __func__, status); 21141 wmi_buf_free(buf); 21142 } 21143 21144 return status; 21145 } 21146 21147 /** 21148 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 21149 * command 21150 * @wmi_handle: wmi handler 21151 * @params: pointer to neighbor report invoke params 21152 * 21153 * Return: 0 for success and non zero for failure 21154 */ 21155 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 21156 struct wmi_invoke_neighbor_report_params *params) 21157 { 21158 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 21159 wmi_buf_t buf; 21160 QDF_STATUS status; 21161 uint8_t *buf_ptr; 21162 uint32_t len = sizeof(*cmd); 21163 21164 buf = wmi_buf_alloc(wmi_handle, len); 21165 if (!buf) { 21166 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 21167 __func__); 21168 return QDF_STATUS_E_NOMEM; 21169 } 21170 21171 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21172 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 21173 21174 WMITLV_SET_HDR(&cmd->tlv_header, 21175 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 21176 WMITLV_GET_STRUCT_TLVLEN( 21177 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 21178 21179 cmd->vdev_id = params->vdev_id; 21180 cmd->flags = params->send_resp_to_host; 21181 21182 cmd->ssid.ssid_len = params->ssid.length; 21183 qdf_mem_copy(cmd->ssid.ssid, 21184 ¶ms->ssid.mac_ssid, 21185 cmd->ssid.ssid_len); 21186 21187 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21188 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 21189 if (status != QDF_STATUS_SUCCESS) { 21190 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 21191 __func__, status); 21192 wmi_buf_free(buf); 21193 } 21194 21195 return status; 21196 } 21197 21198 #ifdef WLAN_SUPPORT_GREEN_AP 21199 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 21200 uint8_t *evt_buf, 21201 struct wlan_green_ap_egap_status_info *egap_status_info_params) 21202 { 21203 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 21204 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 21205 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 21206 21207 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 21208 if (!param_buf) { 21209 WMI_LOGE("Invalid EGAP Info status event buffer"); 21210 return QDF_STATUS_E_INVAL; 21211 } 21212 21213 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 21214 param_buf->fixed_param; 21215 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 21216 param_buf->chainmask_list; 21217 21218 egap_status_info_params->status = egap_info_event->status; 21219 egap_status_info_params->mac_id = chainmask_event->mac_id; 21220 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 21221 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 21222 21223 return QDF_STATUS_SUCCESS; 21224 } 21225 #endif 21226 21227 /* 21228 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 21229 * updating bss color change within firmware when AP announces bss color change. 21230 * @wmi_handle: wmi handle 21231 * @vdev_id: vdev ID 21232 * @enable: enable bss color change within firmware 21233 * 21234 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 21235 * 21236 * Return: QDF_STATUS 21237 */ 21238 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 21239 uint32_t vdev_id, 21240 bool enable) 21241 { 21242 wmi_buf_t buf; 21243 wmi_bss_color_change_enable_fixed_param *cmd; 21244 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 21245 21246 buf = wmi_buf_alloc(wmi_handle, len); 21247 if (!buf) { 21248 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21249 return QDF_STATUS_E_NOMEM; 21250 } 21251 21252 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 21253 WMITLV_SET_HDR(&cmd->tlv_header, 21254 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 21255 WMITLV_GET_STRUCT_TLVLEN 21256 (wmi_bss_color_change_enable_fixed_param)); 21257 cmd->vdev_id = vdev_id; 21258 cmd->enable = enable; 21259 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21260 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 21261 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 21262 wmi_buf_free(buf); 21263 return QDF_STATUS_E_FAILURE; 21264 } 21265 21266 return QDF_STATUS_SUCCESS; 21267 } 21268 21269 /** 21270 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 21271 * configurations to firmware. 21272 * @wmi_handle: wmi handle 21273 * @cfg_param: obss detection configurations 21274 * 21275 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 21276 * 21277 * Return: QDF_STATUS 21278 */ 21279 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 21280 wmi_unified_t wmi_handle, 21281 struct wmi_obss_color_collision_cfg_param *cfg_param) 21282 { 21283 wmi_buf_t buf; 21284 wmi_obss_color_collision_det_config_fixed_param *cmd; 21285 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 21286 21287 buf = wmi_buf_alloc(wmi_handle, len); 21288 if (!buf) { 21289 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21290 return QDF_STATUS_E_NOMEM; 21291 } 21292 21293 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 21294 buf); 21295 WMITLV_SET_HDR(&cmd->tlv_header, 21296 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 21297 WMITLV_GET_STRUCT_TLVLEN 21298 (wmi_obss_color_collision_det_config_fixed_param)); 21299 cmd->vdev_id = cfg_param->vdev_id; 21300 cmd->flags = cfg_param->flags; 21301 cmd->current_bss_color = cfg_param->current_bss_color; 21302 cmd->detection_period_ms = cfg_param->detection_period_ms; 21303 cmd->scan_period_ms = cfg_param->scan_period_ms; 21304 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 21305 21306 switch (cfg_param->evt_type) { 21307 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 21308 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 21309 break; 21310 case OBSS_COLOR_COLLISION_DETECTION: 21311 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 21312 break; 21313 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21314 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21315 break; 21316 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 21317 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 21318 break; 21319 default: 21320 WMI_LOGE("%s: invalid event type: %d", 21321 __func__, cfg_param->evt_type); 21322 wmi_buf_free(buf); 21323 return QDF_STATUS_E_FAILURE; 21324 } 21325 21326 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21327 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 21328 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 21329 __func__, cfg_param->vdev_id); 21330 wmi_buf_free(buf); 21331 return QDF_STATUS_E_FAILURE; 21332 } 21333 21334 return QDF_STATUS_SUCCESS; 21335 } 21336 21337 /** 21338 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 21339 * received from firmware. 21340 * @evt_buf: pointer to event buffer 21341 * @info: Pointer to hold bss collision info 21342 * 21343 * Return: QDF_STATUS 21344 */ 21345 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 21346 struct wmi_obss_color_collision_info *info) 21347 { 21348 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 21349 wmi_obss_color_collision_evt_fixed_param *fix_param; 21350 21351 if (!info) { 21352 WMI_LOGE("%s: Invalid obss color buffer", __func__); 21353 return QDF_STATUS_E_INVAL; 21354 } 21355 21356 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 21357 evt_buf; 21358 if (!param_buf) { 21359 WMI_LOGE("%s: Invalid evt_buf", __func__); 21360 return QDF_STATUS_E_INVAL; 21361 } 21362 21363 fix_param = param_buf->fixed_param; 21364 info->vdev_id = fix_param->vdev_id; 21365 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 21366 info->obss_color_bitmap_bit32to63 = 21367 fix_param->bss_color_bitmap_bit32to63; 21368 21369 switch (fix_param->evt_type) { 21370 case WMI_BSS_COLOR_COLLISION_DISABLE: 21371 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 21372 break; 21373 case WMI_BSS_COLOR_COLLISION_DETECTION: 21374 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 21375 break; 21376 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21377 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21378 break; 21379 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 21380 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 21381 break; 21382 default: 21383 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 21384 __func__, fix_param->evt_type, fix_param->vdev_id); 21385 return QDF_STATUS_E_FAILURE; 21386 } 21387 21388 return QDF_STATUS_SUCCESS; 21389 } 21390 21391 /* 21392 * extract_comb_phyerr_tlv() - extract comb phy error from event 21393 * @wmi_handle: wmi handle 21394 * @evt_buf: pointer to event buffer 21395 * @datalen: data length of event buffer 21396 * @buf_offset: Pointer to hold value of current event buffer offset 21397 * post extraction 21398 * @phyerr: Pointer to hold phyerr 21399 * 21400 * Return: QDF_STATUS 21401 */ 21402 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 21403 void *evt_buf, 21404 uint16_t datalen, 21405 uint16_t *buf_offset, 21406 wmi_host_phyerr_t *phyerr) 21407 { 21408 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 21409 wmi_comb_phyerr_rx_hdr *pe_hdr; 21410 21411 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 21412 if (!param_tlvs) { 21413 WMI_LOGD("%s: Received null data from FW", __func__); 21414 return QDF_STATUS_E_FAILURE; 21415 } 21416 21417 pe_hdr = param_tlvs->hdr; 21418 if (!pe_hdr) { 21419 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 21420 return QDF_STATUS_E_FAILURE; 21421 } 21422 21423 /* Ensure it's at least the size of the header */ 21424 if (datalen < sizeof(*pe_hdr)) { 21425 WMI_LOGD("%s: Expected minimum size %zu, received %d", 21426 __func__, sizeof(*pe_hdr), datalen); 21427 return QDF_STATUS_E_FAILURE; 21428 } 21429 21430 phyerr->pdev_id = wmi_handle->ops-> 21431 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 21432 phyerr->tsf64 = pe_hdr->tsf_l32; 21433 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 21434 phyerr->bufp = param_tlvs->bufp; 21435 phyerr->buf_len = pe_hdr->buf_len; 21436 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 21437 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 21438 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 21439 21440 return QDF_STATUS_SUCCESS; 21441 } 21442 21443 /** 21444 * extract_single_phyerr_tlv() - extract single phy error from event 21445 * @wmi_handle: wmi handle 21446 * @evt_buf: pointer to event buffer 21447 * @datalen: data length of event buffer 21448 * @buf_offset: Pointer to hold value of current event buffer offset 21449 * post extraction 21450 * @phyerr: Pointer to hold phyerr 21451 * 21452 * Return: QDF_STATUS 21453 */ 21454 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 21455 void *evt_buf, 21456 uint16_t datalen, 21457 uint16_t *buf_offset, 21458 wmi_host_phyerr_t *phyerr) 21459 { 21460 wmi_single_phyerr_rx_event *ev; 21461 uint16_t n = *buf_offset; 21462 uint8_t *data = (uint8_t *)evt_buf; 21463 21464 if (n < datalen) { 21465 if ((datalen - n) < sizeof(ev->hdr)) { 21466 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 21467 __func__, datalen, n, sizeof(ev->hdr)); 21468 return QDF_STATUS_E_FAILURE; 21469 } 21470 21471 /* 21472 * Obtain a pointer to the beginning of the current event. 21473 * data[0] is the beginning of the WMI payload. 21474 */ 21475 ev = (wmi_single_phyerr_rx_event *)&data[n]; 21476 21477 /* 21478 * Sanity check the buffer length of the event against 21479 * what we currently have. 21480 * 21481 * Since buf_len is 32 bits, we check if it overflows 21482 * a large 32 bit value. It's not 0x7fffffff because 21483 * we increase n by (buf_len + sizeof(hdr)), which would 21484 * in itself cause n to overflow. 21485 * 21486 * If "int" is 64 bits then this becomes a moot point. 21487 */ 21488 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 21489 WMI_LOGD("%s: buf_len is garbage 0x%x", 21490 __func__, ev->hdr.buf_len); 21491 return QDF_STATUS_E_FAILURE; 21492 } 21493 21494 if ((n + ev->hdr.buf_len) > datalen) { 21495 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 21496 __func__, n, ev->hdr.buf_len, datalen); 21497 return QDF_STATUS_E_FAILURE; 21498 } 21499 21500 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 21501 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 21502 phyerr->bufp = &ev->bufp[0]; 21503 phyerr->buf_len = ev->hdr.buf_len; 21504 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 21505 21506 /* 21507 * Advance the buffer pointer to the next PHY error. 21508 * buflen is the length of this payload, so we need to 21509 * advance past the current header _AND_ the payload. 21510 */ 21511 n += sizeof(*ev) + ev->hdr.buf_len; 21512 } 21513 *buf_offset = n; 21514 21515 return QDF_STATUS_SUCCESS; 21516 } 21517 21518 struct wmi_ops tlv_ops = { 21519 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21520 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21521 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21522 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21523 .send_hidden_ssid_vdev_restart_cmd = 21524 send_hidden_ssid_vdev_restart_cmd_tlv, 21525 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21526 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21527 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21528 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21529 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21530 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21531 .send_peer_rx_reorder_queue_setup_cmd = 21532 send_peer_rx_reorder_queue_setup_cmd_tlv, 21533 .send_peer_rx_reorder_queue_remove_cmd = 21534 send_peer_rx_reorder_queue_remove_cmd_tlv, 21535 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 21536 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 21537 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 21538 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21539 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21540 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 21541 .send_suspend_cmd = send_suspend_cmd_tlv, 21542 .send_resume_cmd = send_resume_cmd_tlv, 21543 #ifdef FEATURE_WLAN_D0WOW 21544 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 21545 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 21546 #endif 21547 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21548 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21549 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21550 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21551 #ifdef FEATURE_FW_LOG_PARSING 21552 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21553 #endif 21554 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21555 .send_stats_request_cmd = send_stats_request_cmd_tlv, 21556 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21557 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21558 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21559 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 21560 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21561 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21562 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21563 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21564 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21565 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21566 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21567 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21568 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21569 .send_set_sta_uapsd_auto_trig_cmd = 21570 send_set_sta_uapsd_auto_trig_cmd_tlv, 21571 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21572 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 21573 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 21574 #ifdef CONVERGED_P2P_ENABLE 21575 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 21576 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 21577 #endif 21578 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21579 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21580 #ifdef WLAN_FEATURE_DSRC 21581 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 21582 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 21583 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 21584 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 21585 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 21586 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 21587 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 21588 .send_ocb_start_timing_advert_cmd = 21589 send_ocb_start_timing_advert_cmd_tlv, 21590 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 21591 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 21592 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 21593 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 21594 #endif 21595 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 21596 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 21597 .send_set_mcc_channel_time_latency_cmd = 21598 send_set_mcc_channel_time_latency_cmd_tlv, 21599 .send_set_mcc_channel_time_quota_cmd = 21600 send_set_mcc_channel_time_quota_cmd_tlv, 21601 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21602 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21603 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21604 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 21605 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 21606 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 21607 .send_probe_rsp_tmpl_send_cmd = 21608 send_probe_rsp_tmpl_send_cmd_tlv, 21609 .send_p2p_go_set_beacon_ie_cmd = 21610 send_p2p_go_set_beacon_ie_cmd_tlv, 21611 .send_setup_install_key_cmd = 21612 send_setup_install_key_cmd_tlv, 21613 .send_set_gateway_params_cmd = 21614 send_set_gateway_params_cmd_tlv, 21615 .send_set_rssi_monitoring_cmd = 21616 send_set_rssi_monitoring_cmd_tlv, 21617 .send_scan_probe_setoui_cmd = 21618 send_scan_probe_setoui_cmd_tlv, 21619 .send_roam_scan_offload_rssi_thresh_cmd = 21620 send_roam_scan_offload_rssi_thresh_cmd_tlv, 21621 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 21622 .send_roam_scan_filter_cmd = 21623 send_roam_scan_filter_cmd_tlv, 21624 #ifdef IPA_OFFLOAD 21625 .send_ipa_offload_control_cmd = 21626 send_ipa_offload_control_cmd_tlv, 21627 #endif 21628 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 21629 .send_plm_start_cmd = send_plm_start_cmd_tlv, 21630 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21631 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21632 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21633 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 21634 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21635 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21636 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21637 .send_congestion_cmd = send_congestion_cmd_tlv, 21638 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21639 .send_snr_cmd = send_snr_cmd_tlv, 21640 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21641 #ifdef WLAN_PMO_ENABLE 21642 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 21643 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 21644 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 21645 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 21646 .send_multiple_add_clear_mcbc_filter_cmd = 21647 send_multiple_add_clear_mcbc_filter_cmd_tlv, 21648 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 21649 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 21650 .send_process_gtk_offload_getinfo_cmd = 21651 send_process_gtk_offload_getinfo_cmd_tlv, 21652 .send_enable_enhance_multicast_offload_cmd = 21653 send_enable_enhance_multicast_offload_tlv, 21654 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 21655 #ifdef FEATURE_WLAN_RA_FILTERING 21656 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 21657 #endif 21658 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 21659 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 21660 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 21661 .send_lphb_config_tcp_pkt_filter_cmd = 21662 send_lphb_config_tcp_pkt_filter_cmd_tlv, 21663 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 21664 .send_lphb_config_udp_pkt_filter_cmd = 21665 send_lphb_config_udp_pkt_filter_cmd_tlv, 21666 .send_enable_disable_packet_filter_cmd = 21667 send_enable_disable_packet_filter_cmd_tlv, 21668 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 21669 #endif /* End of WLAN_PMO_ENABLE */ 21670 #ifdef CONFIG_MCL 21671 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 21672 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 21673 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 21674 .send_roam_scan_offload_mode_cmd = 21675 send_roam_scan_offload_mode_cmd_tlv, 21676 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21677 .send_roam_scan_offload_ap_profile_cmd = 21678 send_roam_scan_offload_ap_profile_cmd_tlv, 21679 #endif 21680 #ifdef WLAN_SUPPORT_GREEN_AP 21681 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21682 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21683 .extract_green_ap_egap_status_info = 21684 extract_green_ap_egap_status_info_tlv, 21685 #endif 21686 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 21687 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21688 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 21689 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 21690 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21691 #ifdef WLAN_FEATURE_CIF_CFR 21692 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21693 #endif 21694 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 21695 .send_dfs_phyerr_filter_offload_en_cmd = 21696 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21697 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 21698 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 21699 .send_del_ts_cmd = send_del_ts_cmd_tlv, 21700 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 21701 .send_add_ts_cmd = send_add_ts_cmd_tlv, 21702 .send_process_add_periodic_tx_ptrn_cmd = 21703 send_process_add_periodic_tx_ptrn_cmd_tlv, 21704 .send_process_del_periodic_tx_ptrn_cmd = 21705 send_process_del_periodic_tx_ptrn_cmd_tlv, 21706 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21707 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 21708 .send_set_app_type2_params_in_fw_cmd = 21709 send_set_app_type2_params_in_fw_cmd_tlv, 21710 .send_set_auto_shutdown_timer_cmd = 21711 send_set_auto_shutdown_timer_cmd_tlv, 21712 .send_nan_req_cmd = send_nan_req_cmd_tlv, 21713 .send_process_dhcpserver_offload_cmd = 21714 send_process_dhcpserver_offload_cmd_tlv, 21715 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 21716 .send_process_ch_avoid_update_cmd = 21717 send_process_ch_avoid_update_cmd_tlv, 21718 .send_pdev_set_regdomain_cmd = 21719 send_pdev_set_regdomain_cmd_tlv, 21720 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21721 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 21722 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 21723 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 21724 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 21725 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21726 .check_and_update_fw_version = 21727 check_and_update_fw_version_cmd_tlv, 21728 .send_set_base_macaddr_indicate_cmd = 21729 send_set_base_macaddr_indicate_cmd_tlv, 21730 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21731 .send_enable_specific_fw_logs_cmd = 21732 send_enable_specific_fw_logs_cmd_tlv, 21733 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21734 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 21735 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21736 #ifdef WLAN_POLICY_MGR_ENABLE 21737 .send_pdev_set_dual_mac_config_cmd = 21738 send_pdev_set_dual_mac_config_cmd_tlv, 21739 #endif 21740 .send_app_type1_params_in_fw_cmd = 21741 send_app_type1_params_in_fw_cmd_tlv, 21742 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 21743 .send_process_roam_synch_complete_cmd = 21744 send_process_roam_synch_complete_cmd_tlv, 21745 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21746 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 21747 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 21748 .send_roam_scan_offload_scan_period_cmd = 21749 send_roam_scan_offload_scan_period_cmd_tlv, 21750 .send_roam_scan_offload_chan_list_cmd = 21751 send_roam_scan_offload_chan_list_cmd_tlv, 21752 .send_roam_scan_offload_rssi_change_cmd = 21753 send_roam_scan_offload_rssi_change_cmd_tlv, 21754 .send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv, 21755 .send_adapt_dwelltime_params_cmd = 21756 send_adapt_dwelltime_params_cmd_tlv, 21757 .send_dbs_scan_sel_params_cmd = 21758 send_dbs_scan_sel_params_cmd_tlv, 21759 .init_cmd_send = init_cmd_send_tlv, 21760 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 21761 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 21762 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 21763 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 21764 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 21765 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 21766 .send_vdev_set_custom_aggr_size_cmd = 21767 send_vdev_set_custom_aggr_size_cmd_tlv, 21768 .send_vdev_set_qdepth_thresh_cmd = 21769 send_vdev_set_qdepth_thresh_cmd_tlv, 21770 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21771 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 21772 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 21773 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 21774 .send_smart_ant_set_training_info_cmd = 21775 send_smart_ant_set_training_info_cmd_tlv, 21776 .send_smart_ant_set_node_config_cmd = 21777 send_smart_ant_set_node_config_cmd_tlv, 21778 .send_set_atf_cmd = send_set_atf_cmd_tlv, 21779 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21780 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 21781 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 21782 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 21783 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21784 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21785 .send_periodic_chan_stats_config_cmd = 21786 send_periodic_chan_stats_config_cmd_tlv, 21787 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 21788 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 21789 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 21790 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 21791 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 21792 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 21793 .send_vdev_spectral_configure_cmd = 21794 send_vdev_spectral_configure_cmd_tlv, 21795 .send_vdev_spectral_enable_cmd = 21796 send_vdev_spectral_enable_cmd_tlv, 21797 .send_thermal_mitigation_param_cmd = 21798 send_thermal_mitigation_param_cmd_tlv, 21799 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 21800 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 21801 .send_process_update_edca_param_cmd = 21802 send_process_update_edca_param_cmd_tlv, 21803 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21804 .send_set_country_cmd = send_set_country_cmd_tlv, 21805 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 21806 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21807 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21808 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21809 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21810 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21811 .extract_host_mem_req = extract_host_mem_req_tlv, 21812 .save_service_bitmap = save_service_bitmap_tlv, 21813 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21814 .is_service_enabled = is_service_enabled_tlv, 21815 .save_fw_version = save_fw_version_in_service_ready_tlv, 21816 .ready_extract_init_status = ready_extract_init_status_tlv, 21817 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21818 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21819 .extract_ready_event_params = extract_ready_event_params_tlv, 21820 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21821 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 21822 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 21823 .extract_tbttoffset_update_params = 21824 extract_tbttoffset_update_params_tlv, 21825 .extract_ext_tbttoffset_update_params = 21826 extract_ext_tbttoffset_update_params_tlv, 21827 .extract_tbttoffset_num_vdevs = 21828 extract_tbttoffset_num_vdevs_tlv, 21829 .extract_ext_tbttoffset_num_vdevs = 21830 extract_ext_tbttoffset_num_vdevs_tlv, 21831 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21832 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 21833 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21834 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21835 #ifdef CONVERGED_TDLS_ENABLE 21836 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 21837 #endif 21838 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 21839 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 21840 .extract_swba_tim_info = extract_swba_tim_info_tlv, 21841 .extract_swba_noa_info = extract_swba_noa_info_tlv, 21842 #ifdef CONVERGED_P2P_ENABLE 21843 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 21844 .extract_p2p_lo_stop_ev_param = 21845 extract_p2p_lo_stop_ev_param_tlv, 21846 #endif 21847 .extract_offchan_data_tx_compl_param = 21848 extract_offchan_data_tx_compl_param_tlv, 21849 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 21850 .extract_all_stats_count = extract_all_stats_counts_tlv, 21851 .extract_pdev_stats = extract_pdev_stats_tlv, 21852 .extract_unit_test = extract_unit_test_tlv, 21853 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21854 .extract_vdev_stats = extract_vdev_stats_tlv, 21855 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 21856 .extract_peer_stats = extract_peer_stats_tlv, 21857 .extract_bcn_stats = extract_bcn_stats_tlv, 21858 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21859 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 21860 .extract_chan_stats = extract_chan_stats_tlv, 21861 .extract_profile_ctx = extract_profile_ctx_tlv, 21862 .extract_profile_data = extract_profile_data_tlv, 21863 .extract_chan_info_event = extract_chan_info_event_tlv, 21864 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 21865 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21866 #ifdef WLAN_FEATURE_DISA 21867 .send_encrypt_decrypt_send_cmd = 21868 send_encrypt_decrypt_send_cmd_tlv, 21869 .extract_encrypt_decrypt_resp_event = 21870 extract_encrypt_decrypt_resp_event_tlv, 21871 #endif 21872 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 21873 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 21874 .extract_sar_limit_event = extract_sar_limit_event_tlv, 21875 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21876 .send_multiple_vdev_restart_req_cmd = 21877 send_multiple_vdev_restart_req_cmd_tlv, 21878 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21879 .extract_hw_mode_cap_service_ready_ext = 21880 extract_hw_mode_cap_service_ready_ext_tlv, 21881 .extract_mac_phy_cap_service_ready_ext = 21882 extract_mac_phy_cap_service_ready_ext_tlv, 21883 .extract_reg_cap_service_ready_ext = 21884 extract_reg_cap_service_ready_ext_tlv, 21885 .extract_dbr_ring_cap_service_ready_ext = 21886 extract_dbr_ring_cap_service_ready_ext_tlv, 21887 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 21888 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 21889 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 21890 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21891 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21892 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 21893 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 21894 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 21895 .extract_fips_event_data = extract_fips_event_data_tlv, 21896 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21897 .extract_peer_delete_response_event = 21898 extract_peer_delete_response_event_tlv, 21899 .is_management_record = is_management_record_tlv, 21900 .extract_pdev_csa_switch_count_status = 21901 extract_pdev_csa_switch_count_status_tlv, 21902 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 21903 .extract_pdev_tpc_config_ev_param = 21904 extract_pdev_tpc_config_ev_param_tlv, 21905 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 21906 .extract_wds_addr_event = extract_wds_addr_event_tlv, 21907 .extract_peer_sta_ps_statechange_ev = 21908 extract_peer_sta_ps_statechange_ev_tlv, 21909 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 21910 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 21911 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21912 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21913 .extract_reg_chan_list_update_event = 21914 extract_reg_chan_list_update_event_tlv, 21915 .extract_chainmask_tables = 21916 extract_chainmask_tables_tlv, 21917 .extract_thermal_stats = extract_thermal_stats_tlv, 21918 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21919 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21920 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21921 #ifdef DFS_COMPONENT_ENABLE 21922 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21923 .extract_dfs_radar_detection_event = 21924 extract_dfs_radar_detection_event_tlv, 21925 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21926 #endif 21927 .convert_pdev_id_host_to_target = 21928 convert_host_pdev_id_to_target_pdev_id_legacy, 21929 .convert_pdev_id_target_to_host = 21930 convert_target_pdev_id_to_host_pdev_id_legacy, 21931 21932 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21933 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21934 .extract_reg_11d_new_country_event = 21935 extract_reg_11d_new_country_event_tlv, 21936 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21937 .send_limit_off_chan_cmd = 21938 send_limit_off_chan_cmd_tlv, 21939 .extract_reg_ch_avoid_event = 21940 extract_reg_ch_avoid_event_tlv, 21941 .send_pdev_caldata_version_check_cmd = 21942 send_pdev_caldata_version_check_cmd_tlv, 21943 .extract_pdev_caldata_version_check_ev_param = 21944 extract_pdev_caldata_version_check_ev_param_tlv, 21945 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 21946 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 21947 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 21948 #if defined(WLAN_FEATURE_FILS_SK) 21949 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 21950 #endif 21951 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 21952 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 21953 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 21954 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 21955 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 21956 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 21957 .extract_ndp_ind = extract_ndp_ind_tlv, 21958 .extract_ndp_confirm = extract_ndp_confirm_tlv, 21959 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 21960 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 21961 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 21962 .extract_ndp_sch_update = extract_ndp_sch_update_tlv, 21963 #endif 21964 .send_btm_config = send_btm_config_cmd_tlv, 21965 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21966 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21967 #ifdef WLAN_SUPPORT_FILS 21968 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 21969 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 21970 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 21971 #endif /* WLAN_SUPPORT_FILS */ 21972 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 21973 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 21974 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21975 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21976 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21977 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21978 .send_bss_color_change_enable_cmd = 21979 send_bss_color_change_enable_cmd_tlv, 21980 .send_obss_color_collision_cfg_cmd = 21981 send_obss_color_collision_cfg_cmd_tlv, 21982 .extract_obss_color_collision_info = 21983 extract_obss_color_collision_info_tlv, 21984 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21985 .extract_single_phyerr = extract_single_phyerr_tlv, 21986 #ifdef QCA_SUPPORT_CP_STATS 21987 .extract_cca_stats = extract_cca_stats_tlv, 21988 #endif 21989 }; 21990 21991 /** 21992 * populate_tlv_event_id() - populates wmi event ids 21993 * 21994 * @param event_ids: Pointer to hold event ids 21995 * Return: None 21996 */ 21997 static void populate_tlv_events_id(uint32_t *event_ids) 21998 { 21999 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22000 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22001 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22002 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22003 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22004 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22005 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22006 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22007 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22008 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22009 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22010 event_ids[wmi_service_ready_ext_event_id] = 22011 WMI_SERVICE_READY_EXT_EVENTID; 22012 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22013 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22014 event_ids[wmi_vdev_install_key_complete_event_id] = 22015 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22016 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22017 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22018 22019 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22020 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22021 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22022 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22023 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22024 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22025 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22026 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22027 event_ids[wmi_peer_delete_response_event_id] = 22028 WMI_PEER_DELETE_RESP_EVENTID; 22029 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22030 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22031 event_ids[wmi_tbttoffset_update_event_id] = 22032 WMI_TBTTOFFSET_UPDATE_EVENTID; 22033 event_ids[wmi_ext_tbttoffset_update_event_id] = 22034 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22035 event_ids[wmi_offload_bcn_tx_status_event_id] = 22036 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22037 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22038 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22039 event_ids[wmi_mgmt_tx_completion_event_id] = 22040 WMI_MGMT_TX_COMPLETION_EVENTID; 22041 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22042 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22043 event_ids[wmi_tx_delba_complete_event_id] = 22044 WMI_TX_DELBA_COMPLETE_EVENTID; 22045 event_ids[wmi_tx_addba_complete_event_id] = 22046 WMI_TX_ADDBA_COMPLETE_EVENTID; 22047 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22048 22049 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22050 22051 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22052 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22053 22054 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22055 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22056 22057 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22058 22059 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22060 event_ids[wmi_p2p_lo_stop_event_id] = 22061 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22062 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22063 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22064 event_ids[wmi_d0_wow_disable_ack_event_id] = 22065 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22066 event_ids[wmi_wow_initial_wakeup_event_id] = 22067 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22068 22069 event_ids[wmi_rtt_meas_report_event_id] = 22070 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22071 event_ids[wmi_tsf_meas_report_event_id] = 22072 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22073 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22074 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22075 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22076 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22077 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22078 event_ids[wmi_diag_event_id_log_supported_event_id] = 22079 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22080 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22081 event_ids[wmi_nlo_scan_complete_event_id] = 22082 WMI_NLO_SCAN_COMPLETE_EVENTID; 22083 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22084 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22085 22086 event_ids[wmi_gtk_offload_status_event_id] = 22087 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22088 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22089 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22090 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22091 22092 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22093 22094 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22095 22096 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22097 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22098 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22099 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22100 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22101 event_ids[wmi_wlan_profile_data_event_id] = 22102 WMI_WLAN_PROFILE_DATA_EVENTID; 22103 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22104 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22105 event_ids[wmi_vdev_get_keepalive_event_id] = 22106 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22107 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22108 22109 event_ids[wmi_diag_container_event_id] = 22110 WMI_DIAG_DATA_CONTAINER_EVENTID; 22111 22112 event_ids[wmi_host_auto_shutdown_event_id] = 22113 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22114 22115 event_ids[wmi_update_whal_mib_stats_event_id] = 22116 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22117 22118 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22119 event_ids[wmi_update_vdev_rate_stats_event_id] = 22120 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22121 22122 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22123 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22124 22125 /** Set OCB Sched Response, deprecated */ 22126 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22127 22128 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22129 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22130 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22131 22132 /* GPIO Event */ 22133 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22134 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22135 22136 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22137 event_ids[wmi_rfkill_state_change_event_id] = 22138 WMI_RFKILL_STATE_CHANGE_EVENTID; 22139 22140 /* TDLS Event */ 22141 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22142 22143 event_ids[wmi_batch_scan_enabled_event_id] = 22144 WMI_BATCH_SCAN_ENABLED_EVENTID; 22145 event_ids[wmi_batch_scan_result_event_id] = 22146 WMI_BATCH_SCAN_RESULT_EVENTID; 22147 /* OEM Event */ 22148 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22149 event_ids[wmi_oem_meas_report_event_id] = 22150 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22151 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22152 22153 /* NAN Event */ 22154 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22155 22156 /* LPI Event */ 22157 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22158 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22159 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22160 22161 /* ExtScan events */ 22162 event_ids[wmi_extscan_start_stop_event_id] = 22163 WMI_EXTSCAN_START_STOP_EVENTID; 22164 event_ids[wmi_extscan_operation_event_id] = 22165 WMI_EXTSCAN_OPERATION_EVENTID; 22166 event_ids[wmi_extscan_table_usage_event_id] = 22167 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22168 event_ids[wmi_extscan_cached_results_event_id] = 22169 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22170 event_ids[wmi_extscan_wlan_change_results_event_id] = 22171 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22172 event_ids[wmi_extscan_hotlist_match_event_id] = 22173 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22174 event_ids[wmi_extscan_capabilities_event_id] = 22175 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22176 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22177 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22178 22179 /* mDNS offload events */ 22180 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22181 22182 /* SAP Authentication offload events */ 22183 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22184 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22185 22186 /** Out-of-context-of-bss (OCB) events */ 22187 event_ids[wmi_ocb_set_config_resp_event_id] = 22188 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22189 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22190 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22191 event_ids[wmi_dcc_get_stats_resp_event_id] = 22192 WMI_DCC_GET_STATS_RESP_EVENTID; 22193 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22194 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22195 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22196 /* System-On-Chip events */ 22197 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22198 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22199 event_ids[wmi_soc_hw_mode_transition_event_id] = 22200 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22201 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22202 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22203 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22204 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22205 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22206 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22207 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22208 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22209 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22210 WMI_PEER_STA_PS_STATECHG_EVENTID; 22211 event_ids[wmi_pdev_channel_hopping_event_id] = 22212 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22213 event_ids[wmi_offchan_data_tx_completion_event] = 22214 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22215 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22216 event_ids[wmi_dfs_radar_detection_event_id] = 22217 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22218 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22219 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22220 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22221 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22222 event_ids[wmi_service_available_event_id] = 22223 WMI_SERVICE_AVAILABLE_EVENTID; 22224 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22225 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22226 /* NDP events */ 22227 event_ids[wmi_ndp_initiator_rsp_event_id] = 22228 WMI_NDP_INITIATOR_RSP_EVENTID; 22229 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22230 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22231 event_ids[wmi_ndp_responder_rsp_event_id] = 22232 WMI_NDP_RESPONDER_RSP_EVENTID; 22233 event_ids[wmi_ndp_end_indication_event_id] = 22234 WMI_NDP_END_INDICATION_EVENTID; 22235 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22236 event_ids[wmi_ndl_schedule_update_event_id] = 22237 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22238 22239 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22240 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22241 event_ids[wmi_pdev_chip_power_stats_event_id] = 22242 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22243 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22244 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22245 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22246 event_ids[wmi_bpf_capability_info_event_id] = 22247 WMI_BPF_CAPABILIY_INFO_EVENTID; 22248 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22249 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22250 event_ids[wmi_report_rx_aggr_failure_event_id] = 22251 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22252 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22253 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22254 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22255 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22256 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22257 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22258 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22259 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22260 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22261 event_ids[wmi_coex_bt_activity_event_id] = 22262 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22263 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22264 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22265 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22266 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22267 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22268 event_ids[wmi_dma_buf_release_event_id] = 22269 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22270 event_ids[wmi_sap_obss_detection_report_event_id] = 22271 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22272 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22273 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22274 event_ids[wmi_obss_color_collision_report_event_id] = 22275 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22276 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22277 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22278 event_ids[wmi_twt_enable_complete_event_id] = 22279 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22280 } 22281 22282 /** 22283 * populate_tlv_service() - populates wmi services 22284 * 22285 * @param wmi_service: Pointer to hold wmi_service 22286 * Return: None 22287 */ 22288 static void populate_tlv_service(uint32_t *wmi_service) 22289 { 22290 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22291 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22292 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22293 wmi_service[wmi_service_roam_scan_offload] = 22294 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22295 wmi_service[wmi_service_bcn_miss_offload] = 22296 WMI_SERVICE_BCN_MISS_OFFLOAD; 22297 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22298 wmi_service[wmi_service_sta_advanced_pwrsave] = 22299 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22300 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22301 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22302 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22303 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22304 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22305 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22306 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22307 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22308 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22309 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22310 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22311 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22312 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22313 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22314 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22315 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22316 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22317 wmi_service[wmi_service_packet_power_save] = 22318 WMI_SERVICE_PACKET_POWER_SAVE; 22319 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22320 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22321 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22322 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22323 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22324 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22325 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22326 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22327 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22328 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22329 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22330 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22331 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22332 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22333 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22334 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22335 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22336 wmi_service[wmi_service_mcc_bcn_interval_change] = 22337 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22338 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22339 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22340 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22341 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22342 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22343 wmi_service[wmi_service_lte_ant_share_support] = 22344 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22345 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22346 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22347 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22348 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22349 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22350 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22351 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22352 wmi_service[wmi_service_bcn_txrate_override] = 22353 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22354 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22355 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22356 wmi_service[wmi_service_estimate_linkspeed] = 22357 WMI_SERVICE_ESTIMATE_LINKSPEED; 22358 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22359 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22360 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22361 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22362 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22363 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22364 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22365 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22366 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22367 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22368 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22369 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22370 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22371 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22372 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22373 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22374 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22375 wmi_service[wmi_service_sap_auth_offload] = 22376 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22377 wmi_service[wmi_service_dual_band_simultaneous_support] = 22378 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22379 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22380 wmi_service[wmi_service_ap_arpns_offload] = 22381 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22382 wmi_service[wmi_service_per_band_chainmask_support] = 22383 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22384 wmi_service[wmi_service_packet_filter_offload] = 22385 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22386 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22387 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22388 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22389 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22390 wmi_service[wmi_service_multiple_vdev_restart] = 22391 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22392 22393 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22394 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22395 wmi_service[wmi_service_smart_antenna_sw_support] = 22396 WMI_SERVICE_UNAVAILABLE; 22397 wmi_service[wmi_service_smart_antenna_hw_support] = 22398 WMI_SERVICE_UNAVAILABLE; 22399 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22400 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22401 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22402 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22403 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22404 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22405 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22406 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22407 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22408 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22409 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22410 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22411 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22412 wmi_service[wmi_service_periodic_chan_stat_support] = 22413 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22414 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22415 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22416 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22417 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22418 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22419 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22420 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22421 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22422 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22423 wmi_service[wmi_service_unified_wow_capability] = 22424 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22425 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22426 wmi_service[wmi_service_bpf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22427 wmi_service[wmi_service_sync_delete_cmds] = 22428 WMI_SERVICE_SYNC_DELETE_CMDS; 22429 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22430 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22431 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22432 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22433 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22434 wmi_service[wmi_service_deprecated_replace] = 22435 WMI_SERVICE_DEPRECATED_REPLACE; 22436 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22437 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22438 wmi_service[wmi_service_enhanced_mcast_filter] = 22439 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22440 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22441 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22442 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22443 wmi_service[wmi_service_p2p_listen_offload_support] = 22444 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22445 wmi_service[wmi_service_mark_first_wakeup_packet] = 22446 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22447 wmi_service[wmi_service_multiple_mcast_filter_set] = 22448 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22449 wmi_service[wmi_service_host_managed_rx_reorder] = 22450 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22451 wmi_service[wmi_service_flash_rdwr_support] = 22452 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22453 wmi_service[wmi_service_wlan_stats_report] = 22454 WMI_SERVICE_WLAN_STATS_REPORT; 22455 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22456 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22457 wmi_service[wmi_service_dfs_phyerr_offload] = 22458 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22459 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22460 wmi_service[wmi_service_fw_mem_dump_support] = 22461 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22462 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22463 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22464 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22465 wmi_service[wmi_service_hw_data_filtering] = 22466 WMI_SERVICE_HW_DATA_FILTERING; 22467 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22468 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22469 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22470 wmi_service[wmi_service_extended_nss_support] = 22471 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22472 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22473 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22474 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22475 wmi_service[wmi_service_offchan_data_tid_support] = 22476 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22477 wmi_service[wmi_service_support_dma] = 22478 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22479 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22480 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22481 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22482 wmi_service[wmi_service_11k_neighbour_report_support] = 22483 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22484 wmi_service[wmi_service_ap_obss_detection_offload] = 22485 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22486 wmi_service[wmi_service_bss_color_offload] = 22487 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22488 wmi_service[wmi_service_gmac_offload_support] = 22489 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22490 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22491 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22492 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22493 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22494 22495 } 22496 22497 #ifndef CONFIG_MCL 22498 22499 /** 22500 * populate_pdev_param_tlv() - populates pdev params 22501 * 22502 * @param pdev_param: Pointer to hold pdev params 22503 * Return: None 22504 */ 22505 static void populate_pdev_param_tlv(uint32_t *pdev_param) 22506 { 22507 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 22508 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 22509 pdev_param[wmi_pdev_param_txpower_limit2g] = 22510 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 22511 pdev_param[wmi_pdev_param_txpower_limit5g] = 22512 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 22513 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 22514 pdev_param[wmi_pdev_param_beacon_gen_mode] = 22515 WMI_PDEV_PARAM_BEACON_GEN_MODE; 22516 pdev_param[wmi_pdev_param_beacon_tx_mode] = 22517 WMI_PDEV_PARAM_BEACON_TX_MODE; 22518 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 22519 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 22520 pdev_param[wmi_pdev_param_protection_mode] = 22521 WMI_PDEV_PARAM_PROTECTION_MODE; 22522 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 22523 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 22524 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 22525 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 22526 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 22527 pdev_param[wmi_pdev_param_sta_kickout_th] = 22528 WMI_PDEV_PARAM_STA_KICKOUT_TH; 22529 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 22530 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 22531 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 22532 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 22533 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 22534 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 22535 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 22536 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 22537 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 22538 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 22539 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 22540 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 22541 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 22542 pdev_param[wmi_pdev_param_ltr_sleep_override] = 22543 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 22544 pdev_param[wmi_pdev_param_ltr_rx_override] = 22545 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 22546 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 22547 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 22548 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 22549 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 22550 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 22551 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 22552 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 22553 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 22554 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 22555 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 22556 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 22557 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 22558 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 22559 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 22560 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 22561 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 22562 pdev_param[wmi_pdev_param_peer_stats_update_period] = 22563 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 22564 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 22565 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 22566 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 22567 pdev_param[wmi_pdev_param_arp_ac_override] = 22568 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 22569 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 22570 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 22571 pdev_param[wmi_pdev_param_ani_poll_period] = 22572 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 22573 pdev_param[wmi_pdev_param_ani_listen_period] = 22574 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 22575 pdev_param[wmi_pdev_param_ani_ofdm_level] = 22576 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 22577 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 22578 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 22579 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 22580 pdev_param[wmi_pdev_param_idle_ps_config] = 22581 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 22582 pdev_param[wmi_pdev_param_power_gating_sleep] = 22583 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 22584 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 22585 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 22586 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 22587 pdev_param[wmi_pdev_param_hw_rfkill_config] = 22588 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 22589 pdev_param[wmi_pdev_param_low_power_rf_enable] = 22590 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 22591 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 22592 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 22593 pdev_param[wmi_pdev_param_power_collapse_enable] = 22594 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 22595 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 22596 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 22597 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 22598 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 22599 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 22600 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 22601 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 22602 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 22603 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 22604 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 22605 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 22606 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 22607 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 22608 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 22609 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 22610 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 22611 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 22612 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 22613 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 22614 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 22615 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 22616 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 22617 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 22618 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 22619 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 22620 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 22621 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 22622 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 22623 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 22624 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 22625 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 22626 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 22627 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 22628 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 22629 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 22630 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 22631 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 22632 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 22633 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 22634 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 22635 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 22636 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 22637 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 22638 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 22639 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 22640 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 22641 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 22642 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 22643 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 22644 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 22645 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 22646 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 22647 pdev_param[wmi_pdev_param_proxy_sta_mode] = 22648 WMI_PDEV_PARAM_PROXY_STA_MODE; 22649 pdev_param[wmi_pdev_param_mu_group_policy] = 22650 WMI_PDEV_PARAM_MU_GROUP_POLICY; 22651 pdev_param[wmi_pdev_param_noise_detection] = 22652 WMI_PDEV_PARAM_NOISE_DETECTION; 22653 pdev_param[wmi_pdev_param_noise_threshold] = 22654 WMI_PDEV_PARAM_NOISE_THRESHOLD; 22655 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 22656 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 22657 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 22658 pdev_param[wmi_pdev_param_atf_strict_sch] = 22659 WMI_PDEV_PARAM_ATF_STRICT_SCH; 22660 pdev_param[wmi_pdev_param_atf_sched_duration] = 22661 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 22662 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 22663 pdev_param[wmi_pdev_param_sensitivity_level] = 22664 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 22665 pdev_param[wmi_pdev_param_signed_txpower_2g] = 22666 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 22667 pdev_param[wmi_pdev_param_signed_txpower_5g] = 22668 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 22669 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 22670 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 22671 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 22672 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 22673 pdev_param[wmi_pdev_param_cca_threshold] = 22674 WMI_PDEV_PARAM_CCA_THRESHOLD; 22675 pdev_param[wmi_pdev_param_rts_fixed_rate] = 22676 WMI_PDEV_PARAM_RTS_FIXED_RATE; 22677 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 22678 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 22679 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 22680 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 22681 pdev_param[wmi_pdev_param_arp_srcaddr] = 22682 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 22683 pdev_param[wmi_pdev_param_arp_dstaddr] = 22684 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 22685 pdev_param[wmi_pdev_param_txpower_decr_db] = 22686 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 22687 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 22688 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 22689 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 22690 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 22691 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 22692 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 22693 pdev_param[wmi_pdev_param_cust_txpower_scale] = 22694 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 22695 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 22696 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 22697 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 22698 WMI_UNAVAILABLE_PARAM; 22699 pdev_param[wmi_pdev_param_igmpmld_override] = WMI_UNAVAILABLE_PARAM; 22700 pdev_param[wmi_pdev_param_igmpmld_tid] = WMI_UNAVAILABLE_PARAM; 22701 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 22702 pdev_param[wmi_pdev_param_block_interbss] = 22703 WMI_PDEV_PARAM_BLOCK_INTERBSS; 22704 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 22705 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 22706 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 22707 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 22708 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 22709 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 22710 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 22711 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 22712 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 22713 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 22714 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 22715 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 22716 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 22717 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 22718 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 22719 pdev_param[wmi_pdev_param_igmpmld_ac_override] = 22720 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 22721 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 22722 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 22723 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 22724 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 22725 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 22726 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 22727 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 22728 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 22729 pdev_param[wmi_pdev_param_fast_channel_reset] = 22730 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 22731 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 22732 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 22733 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 22734 } 22735 22736 /** 22737 * populate_vdev_param_tlv() - populates vdev params 22738 * 22739 * @param vdev_param: Pointer to hold vdev params 22740 * Return: None 22741 */ 22742 static void populate_vdev_param_tlv(uint32_t *vdev_param) 22743 { 22744 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 22745 vdev_param[wmi_vdev_param_fragmentation_threshold] = 22746 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 22747 vdev_param[wmi_vdev_param_beacon_interval] = 22748 WMI_VDEV_PARAM_BEACON_INTERVAL; 22749 vdev_param[wmi_vdev_param_listen_interval] = 22750 WMI_VDEV_PARAM_LISTEN_INTERVAL; 22751 vdev_param[wmi_vdev_param_multicast_rate] = 22752 WMI_VDEV_PARAM_MULTICAST_RATE; 22753 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 22754 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 22755 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 22756 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 22757 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 22758 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 22759 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 22760 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 22761 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 22762 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 22763 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 22764 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 22765 vdev_param[wmi_vdev_param_bmiss_count_max] = 22766 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 22767 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 22768 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 22769 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 22770 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 22771 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 22772 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 22773 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 22774 vdev_param[wmi_vdev_param_disable_htprotection] = 22775 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 22776 vdev_param[wmi_vdev_param_sta_quickkickout] = 22777 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 22778 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 22779 vdev_param[wmi_vdev_param_protection_mode] = 22780 WMI_VDEV_PARAM_PROTECTION_MODE; 22781 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 22782 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 22783 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 22784 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 22785 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 22786 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 22787 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 22788 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 22789 vdev_param[wmi_vdev_param_bcast_data_rate] = 22790 WMI_VDEV_PARAM_BCAST_DATA_RATE; 22791 vdev_param[wmi_vdev_param_mcast_data_rate] = 22792 WMI_VDEV_PARAM_MCAST_DATA_RATE; 22793 vdev_param[wmi_vdev_param_mcast_indicate] = 22794 WMI_VDEV_PARAM_MCAST_INDICATE; 22795 vdev_param[wmi_vdev_param_dhcp_indicate] = 22796 WMI_VDEV_PARAM_DHCP_INDICATE; 22797 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 22798 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 22799 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 22800 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 22801 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 22802 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 22803 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 22804 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 22805 vdev_param[wmi_vdev_param_ap_enable_nawds] = 22806 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 22807 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 22808 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 22809 vdev_param[wmi_vdev_param_packet_powersave] = 22810 WMI_VDEV_PARAM_PACKET_POWERSAVE; 22811 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 22812 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 22813 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 22814 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 22815 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 22816 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 22817 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 22818 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 22819 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 22820 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 22821 vdev_param[wmi_vdev_param_early_rx_slop_step] = 22822 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 22823 vdev_param[wmi_vdev_param_early_rx_init_slop] = 22824 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 22825 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 22826 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 22827 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 22828 vdev_param[wmi_vdev_param_snr_num_for_cal] = 22829 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 22830 vdev_param[wmi_vdev_param_roam_fw_offload] = 22831 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 22832 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 22833 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 22834 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 22835 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 22836 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 22837 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 22838 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 22839 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 22840 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 22841 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 22842 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 22843 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 22844 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 22845 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 22846 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 22847 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 22848 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 22849 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 22850 vdev_param[wmi_vdev_param_inactivity_cnt] = 22851 WMI_VDEV_PARAM_INACTIVITY_CNT; 22852 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 22853 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 22854 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 22855 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 22856 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 22857 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 22858 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 22859 vdev_param[wmi_vdev_param_rx_leak_window] = 22860 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 22861 vdev_param[wmi_vdev_param_stats_avg_factor] = 22862 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 22863 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 22864 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 22865 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 22866 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 22867 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 22868 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 22869 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 22870 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 22871 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 22872 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 22873 vdev_param[wmi_vdev_param_he_range_ext_enable] = 22874 WMI_VDEV_PARAM_HE_RANGE_EXT; 22875 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 22876 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 22877 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 22878 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 22879 vdev_param[wmi_vdev_param_dtim_enable_cts] = 22880 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 22881 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 22882 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 22883 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 22884 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 22885 vdev_param[wmi_vdev_param_mcast2ucast_set] = 22886 WMI_VDEV_PARAM_MCAST2UCAST_SET; 22887 vdev_param[wmi_vdev_param_rc_num_retries] = 22888 WMI_VDEV_PARAM_RC_NUM_RETRIES; 22889 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 22890 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 22891 vdev_param[wmi_vdev_param_rts_fixed_rate] = 22892 WMI_VDEV_PARAM_RTS_FIXED_RATE; 22893 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 22894 vdev_param[wmi_vdev_param_vht80_ratemask] = 22895 WMI_VDEV_PARAM_VHT80_RATEMASK; 22896 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 22897 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 22898 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 22899 vdev_param[wmi_vdev_param_set_he_ltf] = 22900 WMI_VDEV_PARAM_HE_LTF; 22901 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 22902 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 22903 vdev_param[wmi_vdev_param_set_ba_mode] = 22904 WMI_VDEV_PARAM_BA_MODE; 22905 vdev_param[wmi_vdev_param_capabilities] = 22906 WMI_VDEV_PARAM_CAPABILITIES; 22907 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 22908 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 22909 } 22910 #endif 22911 22912 /** 22913 * populate_target_defines_tlv() - Populate target defines and params 22914 * @wmi_handle: pointer to wmi handle 22915 * 22916 * Return: None 22917 */ 22918 #ifndef CONFIG_MCL 22919 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 22920 { 22921 populate_pdev_param_tlv(wmi_handle->pdev_param); 22922 populate_vdev_param_tlv(wmi_handle->vdev_param); 22923 } 22924 #else 22925 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 22926 { } 22927 #endif 22928 22929 /** 22930 * wmi_ocb_ut_attach() - Attach OCB test framework 22931 * @wmi_handle: wmi handle 22932 * 22933 * Return: None 22934 */ 22935 #ifdef WLAN_OCB_UT 22936 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 22937 #else 22938 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 22939 { 22940 return; 22941 } 22942 #endif 22943 22944 /** 22945 * wmi_tlv_attach() - Attach TLV APIs 22946 * 22947 * Return: None 22948 */ 22949 void wmi_tlv_attach(wmi_unified_t wmi_handle) 22950 { 22951 wmi_handle->ops = &tlv_ops; 22952 wmi_ocb_ut_attach(wmi_handle); 22953 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 22954 #ifdef WMI_INTERFACE_EVENT_LOGGING 22955 /* Skip saving WMI_CMD_HDR and TLV HDR */ 22956 wmi_handle->log_info.buf_offset_command = 8; 22957 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 22958 wmi_handle->log_info.buf_offset_event = 4; 22959 #endif 22960 populate_tlv_events_id(wmi_handle->wmi_events); 22961 populate_tlv_service(wmi_handle->services); 22962 populate_target_defines_tlv(wmi_handle); 22963 wmi_twt_attach_tlv(wmi_handle); 22964 wmi_extscan_attach_tlv(wmi_handle); 22965 } 22966 qdf_export_symbol(wmi_tlv_attach); 22967 22968 /** 22969 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 22970 * 22971 * Return: None 22972 */ 22973 void wmi_tlv_init(void) 22974 { 22975 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 22976 } 22977