1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 #include "wmi_unified_api.h" 29 #include "wmi.h" 30 #include "wmi_version.h" 31 #include "wmi_unified_priv.h" 32 #include "wmi_version_whitelist.h" 33 #include <wlan_defs.h> 34 #include <htc_services.h> 35 36 #ifdef CONVERGED_P2P_ENABLE 37 #include "wlan_p2p_public_struct.h" 38 #endif 39 #ifdef WLAN_PMO_ENABLE 40 #include "wlan_pmo_hw_filter_public_struct.h" 41 #endif 42 #include <wlan_utility.h> 43 #ifdef WLAN_SUPPORT_GREEN_AP 44 #include "wlan_green_ap_api.h" 45 #endif 46 47 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 48 #include "nan_public_structs.h" 49 #endif 50 51 /* HTC service ids for WMI for multi-radio */ 52 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 53 WMI_CONTROL_SVC_WMAC1, 54 WMI_CONTROL_SVC_WMAC2}; 55 56 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 57 * buffer. 58 * @wmi_handle: pointer to wmi_handle 59 * @cmd: pointer target vdev create command buffer 60 * @param: pointer host params for vdev create 61 * 62 * Return: None 63 */ 64 #ifdef CONFIG_MCL 65 static inline void copy_vdev_create_pdev_id( 66 struct wmi_unified *wmi_handle, 67 wmi_vdev_create_cmd_fixed_param * cmd, 68 struct vdev_create_params *param) 69 { 70 cmd->pdev_id = WMI_PDEV_ID_SOC; 71 } 72 #else 73 static inline void copy_vdev_create_pdev_id( 74 struct wmi_unified *wmi_handle, 75 wmi_vdev_create_cmd_fixed_param * cmd, 76 struct vdev_create_params *param) 77 { 78 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 79 param->pdev_id); 80 } 81 #endif 82 83 /** 84 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 85 * @wmi_handle: wmi handle 86 * @param: pointer to hold vdev create parameter 87 * @macaddr: vdev mac address 88 * 89 * Return: QDF_STATUS_SUCCESS for success or error code 90 */ 91 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 92 uint8_t macaddr[IEEE80211_ADDR_LEN], 93 struct vdev_create_params *param) 94 { 95 wmi_vdev_create_cmd_fixed_param *cmd; 96 wmi_buf_t buf; 97 int32_t len = sizeof(*cmd); 98 QDF_STATUS ret; 99 int num_bands = 2; 100 uint8_t *buf_ptr; 101 wmi_vdev_txrx_streams *txrx_streams; 102 103 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 104 buf = wmi_buf_alloc(wmi_handle, len); 105 if (!buf) { 106 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 107 return QDF_STATUS_E_NOMEM; 108 } 109 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 110 WMITLV_SET_HDR(&cmd->tlv_header, 111 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 112 WMITLV_GET_STRUCT_TLVLEN 113 (wmi_vdev_create_cmd_fixed_param)); 114 cmd->vdev_id = param->if_id; 115 cmd->vdev_type = param->type; 116 cmd->vdev_subtype = param->subtype; 117 cmd->num_cfg_txrx_streams = num_bands; 118 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 119 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 120 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 121 __func__, param->if_id, cmd->pdev_id, 122 macaddr[0], macaddr[1], macaddr[2], 123 macaddr[3], macaddr[4], macaddr[5]); 124 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 126 (num_bands * sizeof(wmi_vdev_txrx_streams))); 127 buf_ptr += WMI_TLV_HDR_SIZE; 128 129 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 130 param->type, param->subtype, 131 param->nss_2g, param->nss_5g); 132 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 133 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 134 txrx_streams->supported_tx_streams = param->nss_2g; 135 txrx_streams->supported_rx_streams = param->nss_2g; 136 WMITLV_SET_HDR(&txrx_streams->tlv_header, 137 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 138 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 139 140 txrx_streams++; 141 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 142 txrx_streams->supported_tx_streams = param->nss_5g; 143 txrx_streams->supported_rx_streams = param->nss_5g; 144 WMITLV_SET_HDR(&txrx_streams->tlv_header, 145 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 146 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 147 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 148 if (QDF_IS_STATUS_ERROR(ret)) { 149 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 150 wmi_buf_free(buf); 151 } 152 153 return ret; 154 } 155 156 /** 157 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 158 * @wmi_handle: wmi handle 159 * @if_id: vdev id 160 * 161 * Return: QDF_STATUS_SUCCESS for success or error code 162 */ 163 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 164 uint8_t if_id) 165 { 166 wmi_vdev_delete_cmd_fixed_param *cmd; 167 wmi_buf_t buf; 168 QDF_STATUS ret; 169 170 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 171 if (!buf) { 172 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 173 return QDF_STATUS_E_NOMEM; 174 } 175 176 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 177 WMITLV_SET_HDR(&cmd->tlv_header, 178 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 179 WMITLV_GET_STRUCT_TLVLEN 180 (wmi_vdev_delete_cmd_fixed_param)); 181 cmd->vdev_id = if_id; 182 ret = wmi_unified_cmd_send(wmi_handle, buf, 183 sizeof(wmi_vdev_delete_cmd_fixed_param), 184 WMI_VDEV_DELETE_CMDID); 185 if (QDF_IS_STATUS_ERROR(ret)) { 186 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 187 wmi_buf_free(buf); 188 } 189 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 190 191 return ret; 192 } 193 194 /** 195 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 196 * @wmi: wmi handle 197 * @vdev_id: vdev id 198 * 199 * Return: QDF_STATUS_SUCCESS for success or erro code 200 */ 201 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 202 uint8_t vdev_id) 203 { 204 wmi_vdev_stop_cmd_fixed_param *cmd; 205 wmi_buf_t buf; 206 int32_t len = sizeof(*cmd); 207 208 buf = wmi_buf_alloc(wmi, len); 209 if (!buf) { 210 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 211 return QDF_STATUS_E_NOMEM; 212 } 213 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 214 WMITLV_SET_HDR(&cmd->tlv_header, 215 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 216 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 217 cmd->vdev_id = vdev_id; 218 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 219 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 220 wmi_buf_free(buf); 221 return QDF_STATUS_E_FAILURE; 222 } 223 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 224 225 return 0; 226 } 227 228 /** 229 * send_vdev_down_cmd_tlv() - send vdev down command to fw 230 * @wmi: wmi handle 231 * @vdev_id: vdev id 232 * 233 * Return: QDF_STATUS_SUCCESS for success or error code 234 */ 235 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 236 { 237 wmi_vdev_down_cmd_fixed_param *cmd; 238 wmi_buf_t buf; 239 int32_t len = sizeof(*cmd); 240 241 buf = wmi_buf_alloc(wmi, len); 242 if (!buf) { 243 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 244 return QDF_STATUS_E_NOMEM; 245 } 246 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 247 WMITLV_SET_HDR(&cmd->tlv_header, 248 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 249 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 250 cmd->vdev_id = vdev_id; 251 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 252 WMI_LOGP("%s: Failed to send vdev down", __func__); 253 wmi_buf_free(buf); 254 return QDF_STATUS_E_FAILURE; 255 } 256 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 257 258 return 0; 259 } 260 261 #ifdef CONFIG_MCL 262 static inline void copy_channel_info( 263 wmi_vdev_start_request_cmd_fixed_param * cmd, 264 wmi_channel *chan, 265 struct vdev_start_params *req) 266 { 267 chan->mhz = req->chan_freq; 268 269 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 270 271 chan->band_center_freq1 = req->band_center_freq1; 272 chan->band_center_freq2 = req->band_center_freq2; 273 274 if (req->is_half_rate) 275 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 276 else if (req->is_quarter_rate) 277 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 278 279 if (req->is_dfs && req->flag_dfs) { 280 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 281 cmd->disable_hw_ack = req->dis_hw_ack; 282 } 283 284 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 285 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 286 287 } 288 #else 289 static inline void copy_channel_info( 290 wmi_vdev_start_request_cmd_fixed_param * cmd, 291 wmi_channel *chan, 292 struct vdev_start_params *req) 293 { 294 chan->mhz = req->channel.mhz; 295 296 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 297 298 chan->band_center_freq1 = req->channel.cfreq1; 299 chan->band_center_freq2 = req->channel.cfreq2; 300 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 301 302 if (req->channel.half_rate) 303 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 304 else if (req->channel.quarter_rate) 305 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 306 307 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 308 309 if (req->channel.dfs_set) { 310 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 311 cmd->disable_hw_ack = req->disable_hw_ack; 312 } 313 314 if (req->channel.dfs_set_cfreq2) 315 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 316 317 /* According to firmware both reg power and max tx power 318 * on set channel power is used and set it to max reg 319 * power from regulatory. 320 */ 321 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 322 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 323 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 324 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 325 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 326 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 327 328 } 329 #endif 330 /** 331 * send_vdev_start_cmd_tlv() - send vdev start request to fw 332 * @wmi_handle: wmi handle 333 * @req: vdev start params 334 * 335 * Return: QDF status 336 */ 337 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 338 struct vdev_start_params *req) 339 { 340 wmi_vdev_start_request_cmd_fixed_param *cmd; 341 wmi_buf_t buf; 342 wmi_channel *chan; 343 int32_t len, ret; 344 uint8_t *buf_ptr; 345 346 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 347 buf = wmi_buf_alloc(wmi_handle, len); 348 if (!buf) { 349 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 350 return QDF_STATUS_E_NOMEM; 351 } 352 buf_ptr = (uint8_t *) wmi_buf_data(buf); 353 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 354 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 355 WMITLV_SET_HDR(&cmd->tlv_header, 356 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 357 WMITLV_GET_STRUCT_TLVLEN 358 (wmi_vdev_start_request_cmd_fixed_param)); 359 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 360 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 361 cmd->vdev_id = req->vdev_id; 362 363 /* Fill channel info */ 364 copy_channel_info(cmd, chan, req); 365 366 cmd->beacon_interval = req->beacon_intval; 367 cmd->dtim_period = req->dtim_period; 368 369 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 370 if (req->bcn_tx_rate_code) 371 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 372 373 if (!req->is_restart) { 374 cmd->beacon_interval = req->beacon_intval; 375 cmd->dtim_period = req->dtim_period; 376 377 /* Copy the SSID */ 378 if (req->ssid.length) { 379 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 380 cmd->ssid.ssid_len = req->ssid.length; 381 else 382 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 383 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 384 cmd->ssid.ssid_len); 385 } 386 387 if (req->hidden_ssid) 388 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 389 390 if (req->pmf_enabled) 391 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 392 } 393 394 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 395 cmd->num_noa_descriptors = req->num_noa_descriptors; 396 cmd->preferred_rx_streams = req->preferred_rx_streams; 397 cmd->preferred_tx_streams = req->preferred_tx_streams; 398 cmd->cac_duration_ms = req->cac_duration_ms; 399 cmd->regdomain = req->regdomain; 400 cmd->he_ops = req->he_ops; 401 402 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 403 sizeof(wmi_channel)); 404 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 405 cmd->num_noa_descriptors * 406 sizeof(wmi_p2p_noa_descriptor)); 407 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 408 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 409 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 410 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 411 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 412 chan->mhz, req->chan_mode, chan->info, 413 req->is_dfs, req->beacon_intval, cmd->dtim_period, 414 chan->band_center_freq1, chan->band_center_freq2, 415 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 416 req->preferred_tx_streams, req->preferred_rx_streams, 417 req->ldpc_rx_enabled, req->cac_duration_ms, 418 req->regdomain, req->he_ops, 419 req->dis_hw_ack); 420 421 if (req->is_restart) 422 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 423 WMI_VDEV_RESTART_REQUEST_CMDID); 424 else 425 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 426 WMI_VDEV_START_REQUEST_CMDID); 427 if (ret) { 428 WMI_LOGP("%s: Failed to send vdev start command", __func__); 429 wmi_buf_free(buf); 430 return QDF_STATUS_E_FAILURE; 431 } 432 433 return QDF_STATUS_SUCCESS; 434 } 435 436 /** 437 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 438 * @wmi_handle: wmi handle 439 * @restart_params: vdev restart params 440 * 441 * Return: QDF_STATUS_SUCCESS for success or error code 442 */ 443 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 444 struct hidden_ssid_vdev_restart_params *restart_params) 445 { 446 wmi_vdev_start_request_cmd_fixed_param *cmd; 447 wmi_buf_t buf; 448 wmi_channel *chan; 449 int32_t len; 450 uint8_t *buf_ptr; 451 QDF_STATUS ret = 0; 452 453 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 454 buf = wmi_buf_alloc(wmi_handle, len); 455 if (!buf) { 456 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 457 return QDF_STATUS_E_NOMEM; 458 } 459 buf_ptr = (uint8_t *) wmi_buf_data(buf); 460 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 461 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 462 463 WMITLV_SET_HDR(&cmd->tlv_header, 464 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 465 WMITLV_GET_STRUCT_TLVLEN 466 (wmi_vdev_start_request_cmd_fixed_param)); 467 468 WMITLV_SET_HDR(&chan->tlv_header, 469 WMITLV_TAG_STRUC_wmi_channel, 470 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 471 472 cmd->vdev_id = restart_params->session_id; 473 cmd->ssid.ssid_len = restart_params->ssid_len; 474 qdf_mem_copy(cmd->ssid.ssid, 475 restart_params->ssid, 476 cmd->ssid.ssid_len); 477 cmd->flags = restart_params->flags; 478 cmd->requestor_id = restart_params->requestor_id; 479 cmd->disable_hw_ack = restart_params->disable_hw_ack; 480 481 chan->mhz = restart_params->mhz; 482 chan->band_center_freq1 = 483 restart_params->band_center_freq1; 484 chan->band_center_freq2 = 485 restart_params->band_center_freq2; 486 chan->info = restart_params->info; 487 chan->reg_info_1 = restart_params->reg_info_1; 488 chan->reg_info_2 = restart_params->reg_info_2; 489 490 cmd->num_noa_descriptors = 0; 491 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 492 sizeof(wmi_channel)); 493 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 494 cmd->num_noa_descriptors * 495 sizeof(wmi_p2p_noa_descriptor)); 496 497 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 498 WMI_VDEV_RESTART_REQUEST_CMDID); 499 if (QDF_IS_STATUS_ERROR(ret)) { 500 wmi_buf_free(buf); 501 return QDF_STATUS_E_FAILURE; 502 } 503 return QDF_STATUS_SUCCESS; 504 } 505 506 507 /** 508 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 509 * @wmi: wmi handle 510 * @peer_addr: peer mac address 511 * @param: pointer to hold peer flush tid parameter 512 * 513 * Return: 0 for sucess or error code 514 */ 515 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 516 uint8_t peer_addr[IEEE80211_ADDR_LEN], 517 struct peer_flush_params *param) 518 { 519 wmi_peer_flush_tids_cmd_fixed_param *cmd; 520 wmi_buf_t buf; 521 int32_t len = sizeof(*cmd); 522 523 buf = wmi_buf_alloc(wmi, len); 524 if (!buf) { 525 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 526 return QDF_STATUS_E_NOMEM; 527 } 528 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 529 WMITLV_SET_HDR(&cmd->tlv_header, 530 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 531 WMITLV_GET_STRUCT_TLVLEN 532 (wmi_peer_flush_tids_cmd_fixed_param)); 533 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 534 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 535 cmd->vdev_id = param->vdev_id; 536 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 537 peer_addr, param->vdev_id, 538 param->peer_tid_bitmap); 539 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 540 WMI_LOGP("%s: Failed to send flush tid command", __func__); 541 wmi_buf_free(buf); 542 return QDF_STATUS_E_FAILURE; 543 } 544 545 return 0; 546 } 547 548 /** 549 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 550 * @wmi: wmi handle 551 * @peer_addr: peer mac addr 552 * @vdev_id: vdev id 553 * 554 * Return: QDF_STATUS_SUCCESS for success or error code 555 */ 556 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 557 uint8_t peer_addr[IEEE80211_ADDR_LEN], 558 uint8_t vdev_id) 559 { 560 wmi_peer_delete_cmd_fixed_param *cmd; 561 wmi_buf_t buf; 562 int32_t len = sizeof(*cmd); 563 buf = wmi_buf_alloc(wmi, len); 564 if (!buf) { 565 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 566 return QDF_STATUS_E_NOMEM; 567 } 568 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 569 WMITLV_SET_HDR(&cmd->tlv_header, 570 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 571 WMITLV_GET_STRUCT_TLVLEN 572 (wmi_peer_delete_cmd_fixed_param)); 573 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 574 cmd->vdev_id = vdev_id; 575 576 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 577 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 578 WMI_LOGP("%s: Failed to send peer delete command", __func__); 579 wmi_buf_free(buf); 580 return QDF_STATUS_E_FAILURE; 581 } 582 583 return 0; 584 } 585 586 /** 587 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 588 * to target id. 589 * @targ_paramid: Target parameter id to hold the result. 590 * @peer_param_id: host param id. 591 * 592 * Return: QDF_STATUS_SUCCESS for success 593 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 594 */ 595 #ifdef CONFIG_MCL 596 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 597 uint32_t *targ_paramid, 598 uint32_t peer_param_id) 599 { 600 *targ_paramid = peer_param_id; 601 return QDF_STATUS_SUCCESS; 602 } 603 #else 604 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 605 uint32_t *targ_paramid, 606 uint32_t peer_param_id) 607 { 608 switch (peer_param_id) { 609 case WMI_HOST_PEER_MIMO_PS_STATE: 610 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 611 break; 612 case WMI_HOST_PEER_AMPDU: 613 *targ_paramid = WMI_PEER_AMPDU; 614 break; 615 case WMI_HOST_PEER_AUTHORIZE: 616 *targ_paramid = WMI_PEER_AUTHORIZE; 617 break; 618 case WMI_HOST_PEER_CHWIDTH: 619 *targ_paramid = WMI_PEER_CHWIDTH; 620 break; 621 case WMI_HOST_PEER_NSS: 622 *targ_paramid = WMI_PEER_NSS; 623 break; 624 case WMI_HOST_PEER_USE_4ADDR: 625 *targ_paramid = WMI_PEER_USE_4ADDR; 626 break; 627 case WMI_HOST_PEER_MEMBERSHIP: 628 *targ_paramid = WMI_PEER_MEMBERSHIP; 629 break; 630 case WMI_HOST_PEER_USERPOS: 631 *targ_paramid = WMI_PEER_USERPOS; 632 break; 633 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 634 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 635 break; 636 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 637 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 638 break; 639 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 640 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 641 break; 642 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 643 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 644 break; 645 case WMI_HOST_PEER_PHYMODE: 646 *targ_paramid = WMI_PEER_PHYMODE; 647 break; 648 case WMI_HOST_PEER_USE_FIXED_PWR: 649 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 650 break; 651 case WMI_HOST_PEER_PARAM_FIXED_RATE: 652 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 653 break; 654 case WMI_HOST_PEER_SET_MU_WHITELIST: 655 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 656 break; 657 case WMI_HOST_PEER_SET_MAC_TX_RATE: 658 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 659 break; 660 case WMI_HOST_PEER_SET_MIN_TX_RATE: 661 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 662 break; 663 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 664 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 665 break; 666 case WMI_HOST_PEER_NSS_VHT160: 667 *targ_paramid = WMI_PEER_NSS_VHT160; 668 break; 669 case WMI_HOST_PEER_NSS_VHT80_80: 670 *targ_paramid = WMI_PEER_NSS_VHT80_80; 671 break; 672 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 673 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 674 break; 675 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 676 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 677 break; 678 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 679 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 680 break; 681 case WMI_HOST_PEER_PARAM_MU_ENABLE: 682 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 683 break; 684 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 685 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 686 break; 687 default: 688 return QDF_STATUS_E_NOSUPPORT; 689 } 690 691 return QDF_STATUS_SUCCESS; 692 } 693 #endif 694 /** 695 * send_peer_param_cmd_tlv() - set peer parameter in fw 696 * @wmi: wmi handle 697 * @peer_addr: peer mac address 698 * @param : pointer to hold peer set parameter 699 * 700 * Return: QDF_STATUS_SUCCESS for success or error code 701 */ 702 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 703 uint8_t peer_addr[IEEE80211_ADDR_LEN], 704 struct peer_set_params *param) 705 { 706 wmi_peer_set_param_cmd_fixed_param *cmd; 707 wmi_buf_t buf; 708 int32_t err; 709 uint32_t param_id; 710 711 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 712 param->param_id) != QDF_STATUS_SUCCESS) 713 return QDF_STATUS_E_NOSUPPORT; 714 715 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 716 if (!buf) { 717 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 718 return QDF_STATUS_E_NOMEM; 719 } 720 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 721 WMITLV_SET_HDR(&cmd->tlv_header, 722 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 723 WMITLV_GET_STRUCT_TLVLEN 724 (wmi_peer_set_param_cmd_fixed_param)); 725 cmd->vdev_id = param->vdev_id; 726 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 727 cmd->param_id = param_id; 728 cmd->param_value = param->param_value; 729 err = wmi_unified_cmd_send(wmi, buf, 730 sizeof(wmi_peer_set_param_cmd_fixed_param), 731 WMI_PEER_SET_PARAM_CMDID); 732 if (err) { 733 WMI_LOGE("Failed to send set_param cmd"); 734 wmi_buf_free(buf); 735 return QDF_STATUS_E_FAILURE; 736 } 737 738 return 0; 739 } 740 741 /** 742 * send_vdev_up_cmd_tlv() - send vdev up command in fw 743 * @wmi: wmi handle 744 * @bssid: bssid 745 * @vdev_up_params: pointer to hold vdev up parameter 746 * 747 * Return: QDF_STATUS_SUCCESS for success or error code 748 */ 749 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 750 uint8_t bssid[IEEE80211_ADDR_LEN], 751 struct vdev_up_params *params) 752 { 753 wmi_vdev_up_cmd_fixed_param *cmd; 754 wmi_buf_t buf; 755 int32_t len = sizeof(*cmd); 756 757 WMI_LOGD("%s: VDEV_UP", __func__); 758 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 759 params->vdev_id, params->assoc_id, bssid); 760 buf = wmi_buf_alloc(wmi, len); 761 if (!buf) { 762 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 763 return QDF_STATUS_E_NOMEM; 764 } 765 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 766 WMITLV_SET_HDR(&cmd->tlv_header, 767 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 768 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 769 cmd->vdev_id = params->vdev_id; 770 cmd->vdev_assoc_id = params->assoc_id; 771 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 772 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 773 WMI_LOGP("%s: Failed to send vdev up command", __func__); 774 wmi_buf_free(buf); 775 return QDF_STATUS_E_FAILURE; 776 } 777 778 return 0; 779 } 780 781 /** 782 * send_peer_create_cmd_tlv() - send peer create command to fw 783 * @wmi: wmi handle 784 * @peer_addr: peer mac address 785 * @peer_type: peer type 786 * @vdev_id: vdev id 787 * 788 * Return: QDF_STATUS_SUCCESS for success or error code 789 */ 790 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 791 struct peer_create_params *param) 792 { 793 wmi_peer_create_cmd_fixed_param *cmd; 794 wmi_buf_t buf; 795 int32_t len = sizeof(*cmd); 796 797 buf = wmi_buf_alloc(wmi, len); 798 if (!buf) { 799 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 800 return QDF_STATUS_E_NOMEM; 801 } 802 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 803 WMITLV_SET_HDR(&cmd->tlv_header, 804 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 805 WMITLV_GET_STRUCT_TLVLEN 806 (wmi_peer_create_cmd_fixed_param)); 807 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 808 cmd->peer_type = param->peer_type; 809 cmd->vdev_id = param->vdev_id; 810 811 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 812 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 813 wmi_buf_free(buf); 814 return QDF_STATUS_E_FAILURE; 815 } 816 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 817 param->vdev_id); 818 819 return 0; 820 } 821 822 /** 823 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 824 * command to fw 825 * @wmi: wmi handle 826 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 827 * 828 * Return: 0 for success or error code 829 */ 830 static 831 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 832 struct rx_reorder_queue_setup_params *param) 833 { 834 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 835 wmi_buf_t buf; 836 int32_t len = sizeof(*cmd); 837 838 buf = wmi_buf_alloc(wmi, len); 839 if (!buf) { 840 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 841 return QDF_STATUS_E_NOMEM; 842 } 843 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 844 WMITLV_SET_HDR(&cmd->tlv_header, 845 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 846 WMITLV_GET_STRUCT_TLVLEN 847 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 848 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 849 cmd->vdev_id = param->vdev_id; 850 cmd->tid = param->tid; 851 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 852 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 853 cmd->queue_no = param->queue_no; 854 855 if (wmi_unified_cmd_send(wmi, buf, len, 856 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 857 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 858 __func__); 859 qdf_nbuf_free(buf); 860 return QDF_STATUS_E_FAILURE; 861 } 862 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 863 param->peer_macaddr, param->vdev_id, param->tid); 864 865 return QDF_STATUS_SUCCESS; 866 } 867 868 /** 869 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 870 * command to fw 871 * @wmi: wmi handle 872 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 873 * 874 * Return: 0 for success or error code 875 */ 876 static 877 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 878 struct rx_reorder_queue_remove_params *param) 879 { 880 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 881 wmi_buf_t buf; 882 int32_t len = sizeof(*cmd); 883 884 buf = wmi_buf_alloc(wmi, len); 885 if (!buf) { 886 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 887 return QDF_STATUS_E_NOMEM; 888 } 889 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 890 wmi_buf_data(buf); 891 WMITLV_SET_HDR(&cmd->tlv_header, 892 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 893 WMITLV_GET_STRUCT_TLVLEN 894 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 895 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 896 cmd->vdev_id = param->vdev_id; 897 cmd->tid_mask = param->peer_tid_bitmap; 898 899 if (wmi_unified_cmd_send(wmi, buf, len, 900 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 901 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 902 __func__); 903 qdf_nbuf_free(buf); 904 return QDF_STATUS_E_FAILURE; 905 } 906 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 907 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 908 909 return QDF_STATUS_SUCCESS; 910 } 911 912 /** 913 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 914 * @wmi_handle: wmi handle 915 * @param: pointer holding peer details 916 * 917 * Return: 0 for success or error code 918 */ 919 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 920 struct peer_add_wds_entry_params *param) 921 { 922 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 923 wmi_buf_t buf; 924 int len = sizeof(*cmd); 925 926 buf = wmi_buf_alloc(wmi_handle, len); 927 if (!buf) { 928 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 929 return QDF_STATUS_E_FAILURE; 930 } 931 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 932 WMITLV_SET_HDR(&cmd->tlv_header, 933 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 934 WMITLV_GET_STRUCT_TLVLEN 935 (wmi_peer_add_wds_entry_cmd_fixed_param)); 936 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 937 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 938 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 939 cmd->vdev_id = param->vdev_id; 940 941 return wmi_unified_cmd_send(wmi_handle, buf, len, 942 WMI_PEER_ADD_WDS_ENTRY_CMDID); 943 } 944 945 /** 946 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 947 * @wmi_handle: wmi handle 948 * @param: pointer holding peer details 949 * 950 * Return: 0 for success or error code 951 */ 952 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 953 struct peer_del_wds_entry_params *param) 954 { 955 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 956 wmi_buf_t buf; 957 int len = sizeof(*cmd); 958 959 buf = wmi_buf_alloc(wmi_handle, len); 960 if (!buf) { 961 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 962 return QDF_STATUS_E_NOMEM; 963 } 964 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 965 WMITLV_SET_HDR(&cmd->tlv_header, 966 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 967 WMITLV_GET_STRUCT_TLVLEN 968 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 969 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 970 cmd->vdev_id = param->vdev_id; 971 return wmi_unified_cmd_send(wmi_handle, buf, len, 972 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 973 } 974 975 /** 976 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 977 * @wmi_handle: wmi handle 978 * @param: pointer holding peer details 979 * 980 * Return: 0 for success or error code 981 */ 982 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 983 struct peer_update_wds_entry_params *param) 984 { 985 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 986 wmi_buf_t buf; 987 int len = sizeof(*cmd); 988 989 buf = wmi_buf_alloc(wmi_handle, len); 990 if (!buf) { 991 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 992 return QDF_STATUS_E_NOMEM; 993 } 994 995 /* wmi_buf_alloc returns zeroed command buffer */ 996 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 997 WMITLV_SET_HDR(&cmd->tlv_header, 998 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 999 WMITLV_GET_STRUCT_TLVLEN 1000 (wmi_peer_update_wds_entry_cmd_fixed_param)); 1001 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1002 cmd->vdev_id = param->vdev_id; 1003 if (param->wds_macaddr) 1004 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1005 &cmd->wds_macaddr); 1006 if (param->peer_macaddr) 1007 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1008 &cmd->peer_macaddr); 1009 return wmi_unified_cmd_send(wmi_handle, buf, len, 1010 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1011 } 1012 1013 /** 1014 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1015 * @wmi_handle: wmi handle 1016 * @param: pointer to get tpc config params 1017 * 1018 * Return: 0 for success or error code 1019 */ 1020 static QDF_STATUS 1021 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1022 uint32_t param) 1023 { 1024 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1025 wmi_buf_t buf; 1026 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1027 1028 buf = wmi_buf_alloc(wmi_handle, len); 1029 if (!buf) { 1030 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1031 return QDF_STATUS_E_NOMEM; 1032 } 1033 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1034 WMITLV_SET_HDR(&cmd->tlv_header, 1035 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1036 WMITLV_GET_STRUCT_TLVLEN 1037 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1038 1039 cmd->param = param; 1040 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1041 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1042 WMI_LOGE("Send pdev get tpc config cmd failed"); 1043 wmi_buf_free(buf); 1044 return QDF_STATUS_E_FAILURE; 1045 1046 } 1047 WMI_LOGD("%s:send success", __func__); 1048 1049 return QDF_STATUS_SUCCESS; 1050 } 1051 1052 #ifdef WLAN_SUPPORT_GREEN_AP 1053 /** 1054 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1055 * @wmi_handle: wmi handle 1056 * @value: value 1057 * @pdev_id: pdev id to have radio context 1058 * 1059 * Return: QDF_STATUS_SUCCESS for success or error code 1060 */ 1061 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1062 uint32_t value, uint8_t pdev_id) 1063 { 1064 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1065 wmi_buf_t buf; 1066 int32_t len = sizeof(*cmd); 1067 1068 WMI_LOGD("Set Green AP PS val %d", value); 1069 1070 buf = wmi_buf_alloc(wmi_handle, len); 1071 if (!buf) { 1072 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1073 return QDF_STATUS_E_NOMEM; 1074 } 1075 1076 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1077 WMITLV_SET_HDR(&cmd->tlv_header, 1078 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1079 WMITLV_GET_STRUCT_TLVLEN 1080 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1081 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1082 cmd->enable = value; 1083 1084 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1085 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1086 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1087 wmi_buf_free(buf); 1088 return QDF_STATUS_E_FAILURE; 1089 } 1090 1091 return 0; 1092 } 1093 #endif 1094 1095 /** 1096 * send_pdev_utf_cmd_tlv() - send utf command to fw 1097 * @wmi_handle: wmi handle 1098 * @param: pointer to pdev_utf_params 1099 * @mac_id: mac id to have radio context 1100 * 1101 * Return: QDF_STATUS_SUCCESS for success or error code 1102 */ 1103 static QDF_STATUS 1104 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1105 struct pdev_utf_params *param, 1106 uint8_t mac_id) 1107 { 1108 wmi_buf_t buf; 1109 uint8_t *cmd; 1110 /* if param->len is 0 no data is sent, return error */ 1111 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1112 static uint8_t msgref = 1; 1113 uint8_t segNumber = 0, segInfo, numSegments; 1114 uint16_t chunk_len, total_bytes; 1115 uint8_t *bufpos; 1116 struct seg_hdr_info segHdrInfo; 1117 1118 bufpos = param->utf_payload; 1119 total_bytes = param->len; 1120 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1121 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1122 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1123 1124 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1125 numSegments++; 1126 1127 while (param->len) { 1128 if (param->len > MAX_WMI_UTF_LEN) 1129 chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */ 1130 else 1131 chunk_len = param->len; 1132 1133 buf = wmi_buf_alloc(wmi_handle, 1134 (chunk_len + sizeof(segHdrInfo) + 1135 WMI_TLV_HDR_SIZE)); 1136 if (!buf) { 1137 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1138 return QDF_STATUS_E_NOMEM; 1139 } 1140 1141 cmd = (uint8_t *) wmi_buf_data(buf); 1142 1143 segHdrInfo.len = total_bytes; 1144 segHdrInfo.msgref = msgref; 1145 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1146 segHdrInfo.segmentInfo = segInfo; 1147 segHdrInfo.pad = 0; 1148 1149 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1150 " segHdrInfo.segmentInfo = %d", 1151 __func__, segHdrInfo.len, segHdrInfo.msgref, 1152 segHdrInfo.segmentInfo); 1153 1154 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1155 "chunk len %d", __func__, total_bytes, segNumber, 1156 numSegments, chunk_len); 1157 1158 segNumber++; 1159 1160 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1161 (chunk_len + sizeof(segHdrInfo))); 1162 cmd += WMI_TLV_HDR_SIZE; 1163 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1164 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1165 1166 ret = wmi_unified_cmd_send(wmi_handle, buf, 1167 (chunk_len + sizeof(segHdrInfo) + 1168 WMI_TLV_HDR_SIZE), 1169 WMI_PDEV_UTF_CMDID); 1170 1171 if (QDF_IS_STATUS_ERROR(ret)) { 1172 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1173 wmi_buf_free(buf); 1174 break; 1175 } 1176 1177 param->len -= chunk_len; 1178 bufpos += chunk_len; 1179 } 1180 1181 msgref++; 1182 1183 return ret; 1184 } 1185 #ifdef CONFIG_MCL 1186 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1187 uint32_t host_param) 1188 { 1189 return host_param; 1190 } 1191 #else 1192 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1193 uint32_t host_param) 1194 { 1195 if (host_param < wmi_pdev_param_max) 1196 return wmi_handle->pdev_param[host_param]; 1197 1198 return WMI_UNAVAILABLE_PARAM; 1199 } 1200 #endif 1201 /** 1202 * send_pdev_param_cmd_tlv() - set pdev parameters 1203 * @wmi_handle: wmi handle 1204 * @param: pointer to pdev parameter 1205 * @mac_id: radio context 1206 * 1207 * Return: 0 on success, errno on failure 1208 */ 1209 static QDF_STATUS 1210 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1211 struct pdev_params *param, 1212 uint8_t mac_id) 1213 { 1214 QDF_STATUS ret; 1215 wmi_pdev_set_param_cmd_fixed_param *cmd; 1216 wmi_buf_t buf; 1217 uint16_t len = sizeof(*cmd); 1218 uint32_t pdev_param; 1219 1220 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1221 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1222 WMI_LOGW("%s: Unavailable param %d\n", 1223 __func__, param->param_id); 1224 return QDF_STATUS_E_INVAL; 1225 } 1226 1227 buf = wmi_buf_alloc(wmi_handle, len); 1228 if (!buf) { 1229 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1230 return QDF_STATUS_E_NOMEM; 1231 } 1232 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1233 WMITLV_SET_HDR(&cmd->tlv_header, 1234 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1235 WMITLV_GET_STRUCT_TLVLEN 1236 (wmi_pdev_set_param_cmd_fixed_param)); 1237 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1238 cmd->param_id = pdev_param; 1239 cmd->param_value = param->param_value; 1240 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1241 param->param_value); 1242 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1243 WMI_PDEV_SET_PARAM_CMDID); 1244 if (QDF_IS_STATUS_ERROR(ret)) { 1245 WMI_LOGE("Failed to send set param command ret = %d", ret); 1246 wmi_buf_free(buf); 1247 } 1248 return ret; 1249 } 1250 1251 /** 1252 * send_suspend_cmd_tlv() - WMI suspend function 1253 * @param wmi_handle : handle to WMI. 1254 * @param param : pointer to hold suspend parameter 1255 * @mac_id: radio context 1256 * 1257 * Return 0 on success and -ve on failure. 1258 */ 1259 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1260 struct suspend_params *param, 1261 uint8_t mac_id) 1262 { 1263 wmi_pdev_suspend_cmd_fixed_param *cmd; 1264 wmi_buf_t wmibuf; 1265 uint32_t len = sizeof(*cmd); 1266 int32_t ret; 1267 1268 /* 1269 * send the comand to Target to ignore the 1270 * PCIE reset so as to ensure that Host and target 1271 * states are in sync 1272 */ 1273 wmibuf = wmi_buf_alloc(wmi_handle, len); 1274 if (wmibuf == NULL) 1275 return QDF_STATUS_E_NOMEM; 1276 1277 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1278 WMITLV_SET_HDR(&cmd->tlv_header, 1279 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1280 WMITLV_GET_STRUCT_TLVLEN 1281 (wmi_pdev_suspend_cmd_fixed_param)); 1282 if (param->disable_target_intr) 1283 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1284 else 1285 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1286 1287 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1288 1289 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1290 WMI_PDEV_SUSPEND_CMDID); 1291 if (ret) { 1292 wmi_buf_free(wmibuf); 1293 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1294 } 1295 1296 return ret; 1297 } 1298 1299 /** 1300 * send_resume_cmd_tlv() - WMI resume function 1301 * @param wmi_handle : handle to WMI. 1302 * @mac_id: radio context 1303 * 1304 * Return: 0 on success and -ve on failure. 1305 */ 1306 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1307 uint8_t mac_id) 1308 { 1309 wmi_buf_t wmibuf; 1310 wmi_pdev_resume_cmd_fixed_param *cmd; 1311 QDF_STATUS ret; 1312 1313 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1314 if (wmibuf == NULL) 1315 return QDF_STATUS_E_NOMEM; 1316 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1317 WMITLV_SET_HDR(&cmd->tlv_header, 1318 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1319 WMITLV_GET_STRUCT_TLVLEN 1320 (wmi_pdev_resume_cmd_fixed_param)); 1321 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1322 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1323 WMI_PDEV_RESUME_CMDID); 1324 if (QDF_IS_STATUS_ERROR(ret)) { 1325 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1326 wmi_buf_free(wmibuf); 1327 } 1328 1329 return ret; 1330 } 1331 1332 #ifdef FEATURE_WLAN_D0WOW 1333 /** 1334 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1335 * @param wmi_handle: handle to WMI. 1336 * @mac_id: radio context 1337 * 1338 * Return: 0 on success and error code on failure. 1339 */ 1340 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1341 uint8_t mac_id) 1342 { 1343 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1344 wmi_buf_t buf; 1345 int32_t len; 1346 QDF_STATUS status; 1347 1348 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1349 1350 buf = wmi_buf_alloc(wmi_handle, len); 1351 if (!buf) { 1352 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1353 return QDF_STATUS_E_NOMEM; 1354 } 1355 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1356 WMITLV_SET_HDR(&cmd->tlv_header, 1357 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1358 WMITLV_GET_STRUCT_TLVLEN 1359 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1360 1361 cmd->enable = true; 1362 1363 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1364 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1365 if (QDF_IS_STATUS_ERROR(status)) 1366 wmi_buf_free(buf); 1367 1368 return status; 1369 } 1370 1371 /** 1372 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1373 * @param wmi_handle: handle to WMI. 1374 * @mac_id: radio context 1375 * 1376 * Return: 0 on success and error code on failure. 1377 */ 1378 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1379 uint8_t mac_id) 1380 { 1381 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1382 wmi_buf_t buf; 1383 int32_t len; 1384 QDF_STATUS status; 1385 1386 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1387 1388 buf = wmi_buf_alloc(wmi_handle, len); 1389 if (!buf) { 1390 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1391 return QDF_STATUS_E_NOMEM; 1392 } 1393 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1394 WMITLV_SET_HDR(&cmd->tlv_header, 1395 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1396 WMITLV_GET_STRUCT_TLVLEN 1397 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1398 1399 cmd->enable = false; 1400 1401 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1402 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1403 if (QDF_IS_STATUS_ERROR(status)) 1404 wmi_buf_free(buf); 1405 1406 return status; 1407 } 1408 #endif 1409 1410 /** 1411 * send_wow_enable_cmd_tlv() - WMI wow enable function 1412 * @param wmi_handle : handle to WMI. 1413 * @param param : pointer to hold wow enable parameter 1414 * @mac_id: radio context 1415 * 1416 * Return: 0 on success and -ve on failure. 1417 */ 1418 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1419 struct wow_cmd_params *param, 1420 uint8_t mac_id) 1421 { 1422 wmi_wow_enable_cmd_fixed_param *cmd; 1423 wmi_buf_t buf; 1424 int32_t len; 1425 int32_t ret; 1426 1427 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1428 1429 buf = wmi_buf_alloc(wmi_handle, len); 1430 if (!buf) { 1431 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1432 return QDF_STATUS_E_NOMEM; 1433 } 1434 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1435 WMITLV_SET_HDR(&cmd->tlv_header, 1436 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1437 WMITLV_GET_STRUCT_TLVLEN 1438 (wmi_wow_enable_cmd_fixed_param)); 1439 cmd->enable = param->enable; 1440 if (param->can_suspend_link) 1441 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1442 else 1443 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1444 cmd->flags = param->flags; 1445 1446 WMI_LOGI("suspend type: %s", 1447 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1448 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1449 1450 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1451 WMI_WOW_ENABLE_CMDID); 1452 if (ret) 1453 wmi_buf_free(buf); 1454 1455 return ret; 1456 } 1457 1458 /** 1459 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1460 * @wmi_handle: wmi handle 1461 * @peer_addr: peer mac address 1462 * @param: pointer to ap_ps parameter structure 1463 * 1464 * Return: QDF_STATUS_SUCCESS for success or error code 1465 */ 1466 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1467 uint8_t *peer_addr, 1468 struct ap_ps_params *param) 1469 { 1470 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1471 wmi_buf_t buf; 1472 int32_t err; 1473 1474 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1475 if (!buf) { 1476 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1477 return QDF_STATUS_E_NOMEM; 1478 } 1479 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1480 WMITLV_SET_HDR(&cmd->tlv_header, 1481 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1482 WMITLV_GET_STRUCT_TLVLEN 1483 (wmi_ap_ps_peer_cmd_fixed_param)); 1484 cmd->vdev_id = param->vdev_id; 1485 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1486 cmd->param = param->param; 1487 cmd->value = param->value; 1488 err = wmi_unified_cmd_send(wmi_handle, buf, 1489 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1490 if (err) { 1491 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1492 wmi_buf_free(buf); 1493 return QDF_STATUS_E_FAILURE; 1494 } 1495 1496 return 0; 1497 } 1498 1499 /** 1500 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1501 * @wmi_handle: wmi handle 1502 * @peer_addr: peer mac address 1503 * @param: pointer to sta_ps parameter structure 1504 * 1505 * Return: QDF_STATUS_SUCCESS for success or error code 1506 */ 1507 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1508 struct sta_ps_params *param) 1509 { 1510 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1511 wmi_buf_t buf; 1512 int32_t len = sizeof(*cmd); 1513 1514 buf = wmi_buf_alloc(wmi_handle, len); 1515 if (!buf) { 1516 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1517 return QDF_STATUS_E_NOMEM; 1518 } 1519 1520 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1521 WMITLV_SET_HDR(&cmd->tlv_header, 1522 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1523 WMITLV_GET_STRUCT_TLVLEN 1524 (wmi_sta_powersave_param_cmd_fixed_param)); 1525 cmd->vdev_id = param->vdev_id; 1526 cmd->param = param->param; 1527 cmd->value = param->value; 1528 1529 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1530 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1531 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1532 param->vdev_id, param->param, param->value); 1533 wmi_buf_free(buf); 1534 return QDF_STATUS_E_FAILURE; 1535 } 1536 1537 return 0; 1538 } 1539 1540 /** 1541 * send_crash_inject_cmd_tlv() - inject fw crash 1542 * @wmi_handle: wmi handle 1543 * @param: ponirt to crash inject paramter structure 1544 * 1545 * Return: QDF_STATUS_SUCCESS for success or return error 1546 */ 1547 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1548 struct crash_inject *param) 1549 { 1550 int32_t ret = 0; 1551 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1552 uint16_t len = sizeof(*cmd); 1553 wmi_buf_t buf; 1554 1555 buf = wmi_buf_alloc(wmi_handle, len); 1556 if (!buf) { 1557 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1558 return QDF_STATUS_E_NOMEM; 1559 } 1560 1561 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1562 WMITLV_SET_HDR(&cmd->tlv_header, 1563 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1564 WMITLV_GET_STRUCT_TLVLEN 1565 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1566 cmd->type = param->type; 1567 cmd->delay_time_ms = param->delay_time_ms; 1568 1569 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1570 WMI_FORCE_FW_HANG_CMDID); 1571 if (ret) { 1572 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1573 __func__, ret); 1574 wmi_buf_free(buf); 1575 } 1576 1577 return ret; 1578 } 1579 1580 /** 1581 * send_dbglog_cmd_tlv() - set debug log level 1582 * @param wmi_handle : handle to WMI. 1583 * @param param : pointer to hold dbglog level parameter 1584 * 1585 * Return: 0 on success and -ve on failure. 1586 */ 1587 static QDF_STATUS 1588 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1589 struct dbglog_params *dbglog_param) 1590 { 1591 wmi_buf_t buf; 1592 wmi_debug_log_config_cmd_fixed_param *configmsg; 1593 QDF_STATUS status; 1594 int32_t i; 1595 int32_t len; 1596 int8_t *buf_ptr; 1597 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1598 1599 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1600 1601 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1602 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1603 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1604 buf = wmi_buf_alloc(wmi_handle, len); 1605 if (buf == NULL) 1606 return QDF_STATUS_E_NOMEM; 1607 1608 configmsg = 1609 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1610 buf_ptr = (int8_t *) configmsg; 1611 WMITLV_SET_HDR(&configmsg->tlv_header, 1612 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1613 WMITLV_GET_STRUCT_TLVLEN 1614 (wmi_debug_log_config_cmd_fixed_param)); 1615 configmsg->dbg_log_param = dbglog_param->param; 1616 configmsg->value = dbglog_param->val; 1617 /* Filling in the data part of second tlv -- should 1618 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1619 module_id_bitmap_array = (A_UINT32 *) (buf_ptr + 1620 sizeof 1621 (wmi_debug_log_config_cmd_fixed_param) 1622 + WMI_TLV_HDR_SIZE); 1623 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1624 WMITLV_TAG_ARRAY_UINT32, 1625 sizeof(A_UINT32) * MAX_MODULE_ID_BITMAP_WORDS); 1626 if (dbglog_param->module_id_bitmap) { 1627 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1628 module_id_bitmap_array[i] = 1629 dbglog_param->module_id_bitmap[i]; 1630 } 1631 } 1632 1633 status = wmi_unified_cmd_send(wmi_handle, buf, 1634 len, WMI_DBGLOG_CFG_CMDID); 1635 1636 if (status != QDF_STATUS_SUCCESS) 1637 wmi_buf_free(buf); 1638 1639 return status; 1640 } 1641 1642 #ifdef CONFIG_MCL 1643 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1644 uint32_t host_param) 1645 { 1646 return host_param; 1647 } 1648 #else 1649 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1650 uint32_t host_param) 1651 { 1652 if (host_param < wmi_vdev_param_max) 1653 return wmi_handle->vdev_param[host_param]; 1654 1655 return WMI_UNAVAILABLE_PARAM; 1656 } 1657 #endif 1658 /** 1659 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1660 * @param wmi_handle : handle to WMI. 1661 * @param macaddr : MAC address 1662 * @param param : pointer to hold vdev set parameter 1663 * 1664 * Return: 0 on success and -ve on failure. 1665 */ 1666 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1667 struct vdev_set_params *param) 1668 { 1669 QDF_STATUS ret; 1670 wmi_vdev_set_param_cmd_fixed_param *cmd; 1671 wmi_buf_t buf; 1672 uint16_t len = sizeof(*cmd); 1673 uint32_t vdev_param; 1674 1675 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1676 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1677 WMI_LOGW("%s:Vdev param %d not available", __func__, 1678 param->param_id); 1679 return QDF_STATUS_E_INVAL; 1680 1681 } 1682 1683 buf = wmi_buf_alloc(wmi_handle, len); 1684 if (!buf) { 1685 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1686 return QDF_STATUS_E_NOMEM; 1687 } 1688 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1689 WMITLV_SET_HDR(&cmd->tlv_header, 1690 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1691 WMITLV_GET_STRUCT_TLVLEN 1692 (wmi_vdev_set_param_cmd_fixed_param)); 1693 cmd->vdev_id = param->if_id; 1694 cmd->param_id = vdev_param; 1695 cmd->param_value = param->param_value; 1696 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1697 param->if_id, param->param_id, param->param_value); 1698 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1699 WMI_VDEV_SET_PARAM_CMDID); 1700 if (QDF_IS_STATUS_ERROR(ret)) { 1701 WMI_LOGE("Failed to send set param command ret = %d", ret); 1702 wmi_buf_free(buf); 1703 } 1704 1705 return ret; 1706 } 1707 1708 /** 1709 * send_stats_request_cmd_tlv() - WMI request stats function 1710 * @param wmi_handle : handle to WMI. 1711 * @param macaddr : MAC address 1712 * @param param : pointer to hold stats request parameter 1713 * 1714 * Return: 0 on success and -ve on failure. 1715 */ 1716 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1717 uint8_t macaddr[IEEE80211_ADDR_LEN], 1718 struct stats_request_params *param) 1719 { 1720 int32_t ret; 1721 wmi_request_stats_cmd_fixed_param *cmd; 1722 wmi_buf_t buf; 1723 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1724 1725 buf = wmi_buf_alloc(wmi_handle, len); 1726 if (!buf) { 1727 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1728 return -QDF_STATUS_E_NOMEM; 1729 } 1730 1731 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1732 WMITLV_SET_HDR(&cmd->tlv_header, 1733 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1734 WMITLV_GET_STRUCT_TLVLEN 1735 (wmi_request_stats_cmd_fixed_param)); 1736 cmd->stats_id = param->stats_id; 1737 cmd->vdev_id = param->vdev_id; 1738 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1739 param->pdev_id); 1740 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1741 1742 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1743 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1744 1745 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1746 WMI_REQUEST_STATS_CMDID); 1747 1748 if (ret) { 1749 WMI_LOGE("Failed to send status request to fw =%d", ret); 1750 wmi_buf_free(buf); 1751 } 1752 1753 return ret; 1754 } 1755 1756 #ifdef CONFIG_WIN 1757 /** 1758 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1759 * @param wmi_handle : handle to WMI. 1760 * @param PKTLOG_EVENT : packet log event 1761 * @mac_id: mac id to have radio context 1762 * 1763 * Return: 0 on success and -ve on failure. 1764 */ 1765 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1766 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1767 { 1768 int32_t ret; 1769 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1770 wmi_buf_t buf; 1771 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1772 1773 buf = wmi_buf_alloc(wmi_handle, len); 1774 if (!buf) { 1775 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1776 return -QDF_STATUS_E_NOMEM; 1777 } 1778 1779 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1780 WMITLV_SET_HDR(&cmd->tlv_header, 1781 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1782 WMITLV_GET_STRUCT_TLVLEN 1783 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1784 cmd->evlist = PKTLOG_EVENT; 1785 cmd->pdev_id = mac_id; 1786 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1787 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1788 if (ret) { 1789 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1790 wmi_buf_free(buf); 1791 } 1792 1793 return ret; 1794 } 1795 1796 /** 1797 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1798 * @param wmi_handle : handle to WMI. 1799 * @mac_id: mac id to have radio context 1800 * 1801 * Return: 0 on success and -ve on failure. 1802 */ 1803 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1804 uint8_t mac_id) 1805 { 1806 int32_t ret; 1807 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1808 wmi_buf_t buf; 1809 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1810 1811 buf = wmi_buf_alloc(wmi_handle, len); 1812 if (!buf) { 1813 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1814 return -QDF_STATUS_E_NOMEM; 1815 } 1816 1817 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1818 WMITLV_SET_HDR(&cmd->tlv_header, 1819 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1820 WMITLV_GET_STRUCT_TLVLEN 1821 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1822 cmd->pdev_id = mac_id; 1823 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1824 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1825 if (ret) { 1826 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1827 wmi_buf_free(buf); 1828 } 1829 1830 return ret; 1831 } 1832 #else 1833 /** 1834 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1835 * packet-log 1836 * @param wmi_handle : handle to WMI. 1837 * @param macaddr : MAC address 1838 * @param param : pointer to hold stats request parameter 1839 * 1840 * Return: 0 on success and -ve on failure. 1841 */ 1842 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1843 uint8_t macaddr[IEEE80211_ADDR_LEN], 1844 struct packet_enable_params *param) 1845 { 1846 return 0; 1847 } 1848 /** 1849 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1850 * packet-log 1851 * @param wmi_handle : handle to WMI. 1852 * @mac_id: mac id to have radio context 1853 * 1854 * Return: 0 on success and -ve on failure. 1855 */ 1856 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1857 uint8_t mac_id) 1858 { 1859 return 0; 1860 } 1861 #endif 1862 1863 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1864 /** 1865 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1866 * sync time between bwtween host and firmware 1867 * @param wmi_handle : handle to WMI. 1868 * 1869 * Return: None 1870 */ 1871 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1872 { 1873 wmi_buf_t buf; 1874 A_STATUS status = A_OK; 1875 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1876 int32_t len; 1877 qdf_time_t time_ms; 1878 1879 len = sizeof(*time_stamp); 1880 buf = wmi_buf_alloc(wmi_handle, len); 1881 1882 if (!buf) { 1883 WMI_LOGP(FL("wmi_buf_alloc failed")); 1884 return; 1885 } 1886 time_stamp = 1887 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1888 (wmi_buf_data(buf)); 1889 WMITLV_SET_HDR(&time_stamp->tlv_header, 1890 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1891 WMITLV_GET_STRUCT_TLVLEN( 1892 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1893 1894 time_ms = qdf_get_time_of_the_day_ms(); 1895 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1896 time_stamp->time_stamp_low = time_ms & 1897 WMI_FW_TIME_STAMP_LOW_MASK; 1898 /* 1899 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1900 * wont exceed 27 bit 1901 */ 1902 time_stamp->time_stamp_high = 0; 1903 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1904 time_stamp->mode, time_stamp->time_stamp_low, 1905 time_stamp->time_stamp_high); 1906 1907 status = wmi_unified_cmd_send(wmi_handle, buf, 1908 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1909 if (status) { 1910 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1911 wmi_buf_free(buf); 1912 } 1913 1914 } 1915 1916 #ifdef WLAN_SUPPORT_FILS 1917 /** 1918 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 1919 * @wmi_handle: wmi handle 1920 * @evt_buf: pointer to event buffer 1921 * @vdev_id: pointer to hold vdev id 1922 * 1923 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 1924 */ 1925 static QDF_STATUS 1926 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 1927 void *evt_buf, uint32_t *vdev_id) 1928 { 1929 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 1930 wmi_host_swfda_event_fixed_param *swfda_event; 1931 1932 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 1933 if (!param_buf) { 1934 WMI_LOGE("Invalid swfda event buffer"); 1935 return QDF_STATUS_E_INVAL; 1936 } 1937 swfda_event = param_buf->fixed_param; 1938 *vdev_id = swfda_event->vdev_id; 1939 1940 return QDF_STATUS_SUCCESS; 1941 } 1942 1943 /** 1944 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 1945 * @wmi_handle: wmi handle 1946 * @param: pointer to hold FILS discovery enable param 1947 * 1948 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 1949 */ 1950 static QDF_STATUS 1951 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 1952 struct config_fils_params *param) 1953 { 1954 wmi_enable_fils_cmd_fixed_param *cmd; 1955 wmi_buf_t buf; 1956 QDF_STATUS status; 1957 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 1958 1959 buf = wmi_buf_alloc(wmi_handle, len); 1960 if (!buf) { 1961 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 1962 return QDF_STATUS_E_NOMEM; 1963 } 1964 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 1965 WMITLV_SET_HDR(&cmd->tlv_header, 1966 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 1967 WMITLV_GET_STRUCT_TLVLEN( 1968 wmi_enable_fils_cmd_fixed_param)); 1969 cmd->vdev_id = param->vdev_id; 1970 cmd->fd_period = param->fd_period; 1971 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 1972 param->fd_period, param->vdev_id); 1973 1974 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1975 WMI_ENABLE_FILS_CMDID); 1976 if (status != QDF_STATUS_SUCCESS) { 1977 wmi_buf_free(buf); 1978 return QDF_STATUS_E_FAILURE; 1979 } 1980 1981 return QDF_STATUS_SUCCESS; 1982 } 1983 1984 /** 1985 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 1986 * @wmi_handle: wmi handle 1987 * @param: pointer to hold FD send cmd parameter 1988 * 1989 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 1990 */ 1991 static QDF_STATUS 1992 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 1993 struct fd_params *param) 1994 { 1995 QDF_STATUS ret; 1996 wmi_fd_send_from_host_cmd_fixed_param *cmd; 1997 wmi_buf_t wmi_buf; 1998 qdf_dma_addr_t dma_addr; 1999 2000 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2001 if (!wmi_buf) { 2002 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2003 return QDF_STATUS_E_NOMEM; 2004 } 2005 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2006 WMITLV_SET_HDR(&cmd->tlv_header, 2007 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2008 WMITLV_GET_STRUCT_TLVLEN( 2009 wmi_fd_send_from_host_cmd_fixed_param)); 2010 cmd->vdev_id = param->vdev_id; 2011 cmd->data_len = qdf_nbuf_len(param->wbuf); 2012 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2013 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2014 cmd->frame_ctrl = param->frame_ctrl; 2015 2016 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2017 WMI_PDEV_SEND_FD_CMDID); 2018 if (ret != QDF_STATUS_SUCCESS) { 2019 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2020 __func__, ret); 2021 wmi_buf_free(wmi_buf); 2022 } 2023 2024 return ret; 2025 } 2026 #endif /* WLAN_SUPPORT_FILS */ 2027 2028 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2029 struct beacon_params *param) 2030 { 2031 QDF_STATUS ret; 2032 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2033 wmi_buf_t wmi_buf; 2034 qdf_dma_addr_t dma_addr; 2035 uint32_t dtim_flag = 0; 2036 2037 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2038 if (!wmi_buf) { 2039 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2040 return QDF_STATUS_E_NOMEM; 2041 } 2042 if (param->is_dtim_count_zero) { 2043 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2044 if (param->is_bitctl_reqd) { 2045 /* deliver CAB traffic in next DTIM beacon */ 2046 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2047 } 2048 } 2049 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2050 WMITLV_SET_HDR(&cmd->tlv_header, 2051 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2052 WMITLV_GET_STRUCT_TLVLEN 2053 (wmi_bcn_send_from_host_cmd_fixed_param)); 2054 cmd->vdev_id = param->vdev_id; 2055 cmd->data_len = qdf_nbuf_len(param->wbuf); 2056 cmd->frame_ctrl = param->frame_ctrl; 2057 cmd->dtim_flag = dtim_flag; 2058 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2059 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2060 #if defined(HTT_PADDR64) 2061 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2062 #endif 2063 cmd->bcn_antenna = param->bcn_txant; 2064 2065 ret = wmi_unified_cmd_send(wmi_handle, 2066 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2067 if (ret != QDF_STATUS_SUCCESS) { 2068 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2069 wmi_buf_free(wmi_buf); 2070 } 2071 2072 return ret; 2073 } 2074 2075 /** 2076 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2077 * @param wmi_handle : handle to WMI. 2078 * @param param : pointer to hold beacon send cmd parameter 2079 * 2080 * Return: 0 on success and -ve on failure. 2081 */ 2082 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2083 struct beacon_tmpl_params *param) 2084 { 2085 int32_t ret; 2086 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2087 wmi_bcn_prb_info *bcn_prb_info; 2088 wmi_buf_t wmi_buf; 2089 uint8_t *buf_ptr; 2090 uint32_t wmi_buf_len; 2091 2092 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2093 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2094 param->tmpl_len_aligned; 2095 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2096 if (!wmi_buf) { 2097 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2098 return QDF_STATUS_E_NOMEM; 2099 } 2100 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2101 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2102 WMITLV_SET_HDR(&cmd->tlv_header, 2103 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2104 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2105 cmd->vdev_id = param->vdev_id; 2106 cmd->tim_ie_offset = param->tim_ie_offset; 2107 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2108 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2109 cmd->buf_len = param->tmpl_len; 2110 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2111 2112 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2113 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2114 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2115 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2116 bcn_prb_info->caps = 0; 2117 bcn_prb_info->erp = 0; 2118 buf_ptr += sizeof(wmi_bcn_prb_info); 2119 2120 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2121 buf_ptr += WMI_TLV_HDR_SIZE; 2122 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2123 2124 ret = wmi_unified_cmd_send(wmi_handle, 2125 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2126 if (ret) { 2127 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2128 wmi_buf_free(wmi_buf); 2129 } 2130 2131 return 0; 2132 } 2133 2134 #ifdef CONFIG_MCL 2135 static inline void copy_peer_flags_tlv( 2136 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2137 struct peer_assoc_params *param) 2138 { 2139 cmd->peer_flags = param->peer_flags; 2140 } 2141 #else 2142 static inline void copy_peer_flags_tlv( 2143 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2144 struct peer_assoc_params *param) 2145 { 2146 /* 2147 * The target only needs a subset of the flags maintained in the host. 2148 * Just populate those flags and send it down 2149 */ 2150 cmd->peer_flags = 0; 2151 2152 /* 2153 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2154 */ 2155 if (param->is_wme_set) { 2156 2157 if (param->qos_flag) 2158 cmd->peer_flags |= WMI_PEER_QOS; 2159 if (param->apsd_flag) 2160 cmd->peer_flags |= WMI_PEER_APSD; 2161 if (param->ht_flag) 2162 cmd->peer_flags |= WMI_PEER_HT; 2163 if (param->bw_40) 2164 cmd->peer_flags |= WMI_PEER_40MHZ; 2165 if (param->bw_80) 2166 cmd->peer_flags |= WMI_PEER_80MHZ; 2167 if (param->bw_160) 2168 cmd->peer_flags |= WMI_PEER_160MHZ; 2169 2170 /* Typically if STBC is enabled for VHT it should be enabled 2171 * for HT as well 2172 **/ 2173 if (param->stbc_flag) 2174 cmd->peer_flags |= WMI_PEER_STBC; 2175 2176 /* Typically if LDPC is enabled for VHT it should be enabled 2177 * for HT as well 2178 **/ 2179 if (param->ldpc_flag) 2180 cmd->peer_flags |= WMI_PEER_LDPC; 2181 2182 if (param->static_mimops_flag) 2183 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2184 if (param->dynamic_mimops_flag) 2185 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2186 if (param->spatial_mux_flag) 2187 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2188 if (param->vht_flag) 2189 cmd->peer_flags |= WMI_PEER_VHT; 2190 if (param->he_flag) 2191 cmd->peer_flags |= WMI_PEER_HE; 2192 } 2193 2194 if (param->is_pmf_enabled) 2195 cmd->peer_flags |= WMI_PEER_PMF; 2196 /* 2197 * Suppress authorization for all AUTH modes that need 4-way handshake 2198 * (during re-association). 2199 * Authorization will be done for these modes on key installation. 2200 */ 2201 if (param->auth_flag) 2202 cmd->peer_flags |= WMI_PEER_AUTH; 2203 if (param->need_ptk_4_way) 2204 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2205 else 2206 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2207 if (param->need_gtk_2_way) 2208 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2209 /* safe mode bypass the 4-way handshake */ 2210 if (param->safe_mode_enabled) 2211 cmd->peer_flags &= 2212 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2213 /* Disable AMSDU for station transmit, if user configures it */ 2214 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2215 * it 2216 * if (param->amsdu_disable) Add after FW support 2217 **/ 2218 2219 /* Target asserts if node is marked HT and all MCS is set to 0. 2220 * Mark the node as non-HT if all the mcs rates are disabled through 2221 * iwpriv 2222 **/ 2223 if (param->peer_ht_rates.num_rates == 0) 2224 cmd->peer_flags &= ~WMI_PEER_HT; 2225 } 2226 #endif 2227 2228 #ifdef CONFIG_MCL 2229 static inline void copy_peer_mac_addr_tlv( 2230 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2231 struct peer_assoc_params *param) 2232 { 2233 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2234 sizeof(param->peer_macaddr)); 2235 } 2236 #else 2237 static inline void copy_peer_mac_addr_tlv( 2238 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2239 struct peer_assoc_params *param) 2240 { 2241 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2242 } 2243 #endif 2244 2245 /** 2246 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2247 * @param wmi_handle : handle to WMI. 2248 * @param param : pointer to peer assoc parameter 2249 * 2250 * Return: 0 on success and -ve on failure. 2251 */ 2252 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2253 struct peer_assoc_params *param) 2254 { 2255 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2256 wmi_vht_rate_set *mcs; 2257 wmi_he_rate_set *he_mcs; 2258 wmi_buf_t buf; 2259 int32_t len; 2260 uint8_t *buf_ptr; 2261 QDF_STATUS ret; 2262 uint32_t peer_legacy_rates_align; 2263 uint32_t peer_ht_rates_align; 2264 int32_t i; 2265 2266 2267 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2268 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2269 2270 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2271 (peer_legacy_rates_align * sizeof(uint8_t)) + 2272 WMI_TLV_HDR_SIZE + 2273 (peer_ht_rates_align * sizeof(uint8_t)) + 2274 sizeof(wmi_vht_rate_set) + 2275 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2276 + WMI_TLV_HDR_SIZE); 2277 2278 buf = wmi_buf_alloc(wmi_handle, len); 2279 if (!buf) { 2280 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2281 return QDF_STATUS_E_NOMEM; 2282 } 2283 2284 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2285 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2286 WMITLV_SET_HDR(&cmd->tlv_header, 2287 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2288 WMITLV_GET_STRUCT_TLVLEN 2289 (wmi_peer_assoc_complete_cmd_fixed_param)); 2290 2291 cmd->vdev_id = param->vdev_id; 2292 2293 cmd->peer_new_assoc = param->peer_new_assoc; 2294 cmd->peer_associd = param->peer_associd; 2295 2296 copy_peer_flags_tlv(cmd, param); 2297 copy_peer_mac_addr_tlv(cmd, param); 2298 2299 cmd->peer_rate_caps = param->peer_rate_caps; 2300 cmd->peer_caps = param->peer_caps; 2301 cmd->peer_listen_intval = param->peer_listen_intval; 2302 cmd->peer_ht_caps = param->peer_ht_caps; 2303 cmd->peer_max_mpdu = param->peer_max_mpdu; 2304 cmd->peer_mpdu_density = param->peer_mpdu_density; 2305 cmd->peer_vht_caps = param->peer_vht_caps; 2306 cmd->peer_phymode = param->peer_phymode; 2307 2308 /* Update 11ax capabilities */ 2309 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2310 cmd->peer_he_ops = param->peer_he_ops; 2311 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2312 sizeof(param->peer_he_cap_phyinfo)); 2313 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2314 sizeof(param->peer_ppet)); 2315 2316 /* Update peer legacy rate information */ 2317 buf_ptr += sizeof(*cmd); 2318 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2319 peer_legacy_rates_align); 2320 buf_ptr += WMI_TLV_HDR_SIZE; 2321 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2322 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2323 param->peer_legacy_rates.num_rates); 2324 2325 /* Update peer HT rate information */ 2326 buf_ptr += peer_legacy_rates_align; 2327 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2328 peer_ht_rates_align); 2329 buf_ptr += WMI_TLV_HDR_SIZE; 2330 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2331 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2332 param->peer_ht_rates.num_rates); 2333 2334 /* VHT Rates */ 2335 buf_ptr += peer_ht_rates_align; 2336 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2337 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2338 2339 cmd->peer_nss = param->peer_nss; 2340 2341 /* Update bandwidth-NSS mapping */ 2342 cmd->peer_bw_rxnss_override = 0; 2343 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2344 2345 mcs = (wmi_vht_rate_set *) buf_ptr; 2346 if (param->vht_capable) { 2347 mcs->rx_max_rate = param->rx_max_rate; 2348 mcs->rx_mcs_set = param->rx_mcs_set; 2349 mcs->tx_max_rate = param->tx_max_rate; 2350 mcs->tx_mcs_set = param->tx_mcs_set; 2351 } 2352 2353 /* HE Rates */ 2354 cmd->peer_he_mcs = param->peer_he_mcs_count; 2355 buf_ptr += sizeof(wmi_vht_rate_set); 2356 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2357 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2358 buf_ptr += WMI_TLV_HDR_SIZE; 2359 2360 /* Loop through the HE rate set */ 2361 for (i = 0; i < param->peer_he_mcs_count; i++) { 2362 he_mcs = (wmi_he_rate_set *) buf_ptr; 2363 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2364 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2365 2366 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2367 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2368 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2369 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2370 buf_ptr += sizeof(wmi_he_rate_set); 2371 } 2372 2373 2374 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2375 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2376 "nss %d phymode %d peer_mpdu_density %d " 2377 "cmd->peer_vht_caps %x " 2378 "HE cap_info %x ops %x " 2379 "HE phy %x %x %x " 2380 "peer_bw_rxnss_override %x", __func__, 2381 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2382 cmd->peer_rate_caps, cmd->peer_caps, 2383 cmd->peer_listen_intval, cmd->peer_ht_caps, 2384 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2385 cmd->peer_mpdu_density, 2386 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2387 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2388 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2389 cmd->peer_bw_rxnss_override); 2390 2391 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2392 WMI_PEER_ASSOC_CMDID); 2393 if (QDF_IS_STATUS_ERROR(ret)) { 2394 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2395 __func__, ret); 2396 wmi_buf_free(buf); 2397 } 2398 2399 return ret; 2400 } 2401 2402 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2403 */ 2404 static inline void copy_scan_event_cntrl_flags( 2405 wmi_start_scan_cmd_fixed_param * cmd, 2406 struct scan_req_params *param) 2407 { 2408 2409 /* Scan events subscription */ 2410 if (param->scan_ev_started) 2411 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2412 if (param->scan_ev_completed) 2413 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2414 if (param->scan_ev_bss_chan) 2415 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2416 if (param->scan_ev_foreign_chan) 2417 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2418 if (param->scan_ev_dequeued) 2419 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2420 if (param->scan_ev_preempted) 2421 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2422 if (param->scan_ev_start_failed) 2423 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2424 if (param->scan_ev_restarted) 2425 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2426 if (param->scan_ev_foreign_chn_exit) 2427 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2428 if (param->scan_ev_suspended) 2429 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2430 if (param->scan_ev_resumed) 2431 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2432 2433 /** Set scan control flags */ 2434 cmd->scan_ctrl_flags = 0; 2435 if (param->scan_f_passive) 2436 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2437 if (param->scan_f_strict_passive_pch) 2438 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2439 if (param->scan_f_promisc_mode) 2440 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2441 if (param->scan_f_capture_phy_err) 2442 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2443 if (param->scan_f_half_rate) 2444 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2445 if (param->scan_f_quarter_rate) 2446 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2447 if (param->scan_f_cck_rates) 2448 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2449 if (param->scan_f_ofdm_rates) 2450 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2451 if (param->scan_f_chan_stat_evnt) 2452 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2453 if (param->scan_f_filter_prb_req) 2454 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2455 if (param->scan_f_bcast_probe) 2456 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2457 if (param->scan_f_offchan_mgmt_tx) 2458 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2459 if (param->scan_f_offchan_data_tx) 2460 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2461 if (param->scan_f_force_active_dfs_chn) 2462 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2463 if (param->scan_f_add_tpc_ie_in_probe) 2464 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2465 if (param->scan_f_add_ds_ie_in_probe) 2466 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2467 if (param->scan_f_add_spoofed_mac_in_probe) 2468 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2469 if (param->scan_f_add_rand_seq_in_probe) 2470 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2471 if (param->scan_f_en_ie_whitelist_in_probe) 2472 cmd->scan_ctrl_flags |= 2473 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2474 2475 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2476 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2477 param->adaptive_dwell_time_mode); 2478 } 2479 2480 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2481 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2482 struct scan_req_params *params) 2483 { 2484 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2485 } 2486 2487 /* 2488 * get_pdev_wmi_handle() - Helper func to derive pdev wmi handle from vdev_id 2489 * @param wmi_handle : Handle to WMI 2490 * @param vdev_id : vdev identifier 2491 * 2492 * Return : void * 2493 */ 2494 static inline void *get_pdev_wmi_handle(wmi_unified_t wmi_handle, uint8_t vdev_id) 2495 { 2496 struct wlan_objmgr_vdev *vdev = NULL; 2497 struct wlan_objmgr_pdev *pdev = NULL; 2498 uint8_t pdev_id = 0; 2499 2500 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 2501 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 2502 vdev_id, WLAN_SCAN_ID); 2503 if (vdev) { 2504 wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID); 2505 pdev = wlan_vdev_get_pdev(vdev); 2506 if (pdev) 2507 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 2508 else { 2509 qdf_print("%s : Invalid PDEV, forcing pdev_id to 0\n", __func__); 2510 } 2511 } else { 2512 qdf_print("%s : Invalid VDEV, forcing pdev_id to 0\n", __func__); 2513 } 2514 2515 return wmi_unified_get_pdev_handle(wmi_handle->soc, pdev_id); 2516 } 2517 2518 /** 2519 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2520 * @mac: random mac addr 2521 * @mask: random mac mask 2522 * @mac_addr: wmi random mac 2523 * @mac_mask: wmi random mac mask 2524 * 2525 * Return None. 2526 */ 2527 static inline 2528 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2529 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2530 { 2531 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2532 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2533 } 2534 2535 /* 2536 * wmi_fill_vendor_oui() - fill vendor OUIs 2537 * @buf_ptr: pointer to wmi tlv buffer 2538 * @num_vendor_oui: number of vendor OUIs to be filled 2539 * @param_voui: pointer to OUI buffer 2540 * 2541 * This function populates the wmi tlv buffer when vendor specific OUIs are 2542 * present. 2543 * 2544 * Return: None 2545 */ 2546 static inline 2547 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2548 uint32_t *pvoui) 2549 { 2550 wmi_vendor_oui *voui = NULL; 2551 uint32_t i; 2552 2553 voui = (wmi_vendor_oui *)buf_ptr; 2554 2555 for (i = 0; i < num_vendor_oui; i++) { 2556 WMITLV_SET_HDR(&voui[i].tlv_header, 2557 WMITLV_TAG_STRUC_wmi_vendor_oui, 2558 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2559 voui[i].oui_type_subtype = pvoui[i]; 2560 } 2561 } 2562 2563 /* 2564 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2565 * @ie_bitmap: output pointer to ie bit map in cmd 2566 * @num_vendor_oui: output pointer to num vendor OUIs 2567 * @ie_whitelist: input parameter 2568 * 2569 * This function populates the IE whitelist attrs of scan, pno and 2570 * scan oui commands for ie_whitelist parameter. 2571 * 2572 * Return: None 2573 */ 2574 static inline 2575 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2576 uint32_t *num_vendor_oui, 2577 struct probe_req_whitelist_attr *ie_whitelist) 2578 { 2579 uint32_t i = 0; 2580 2581 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2582 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2583 2584 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2585 } 2586 2587 /** 2588 * send_scan_start_cmd_tlv() - WMI scan start function 2589 * @param wmi_handle : handle to WMI. 2590 * @param param : pointer to hold scan start cmd parameter 2591 * 2592 * Return: 0 on success and -ve on failure. 2593 */ 2594 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2595 struct scan_req_params *params) 2596 { 2597 int32_t ret = 0; 2598 int32_t i; 2599 wmi_buf_t wmi_buf; 2600 wmi_start_scan_cmd_fixed_param *cmd; 2601 uint8_t *buf_ptr; 2602 uint32_t *tmp_ptr; 2603 wmi_ssid *ssid = NULL; 2604 wmi_mac_addr *bssid; 2605 int len = sizeof(*cmd); 2606 uint8_t extraie_len_with_pad = 0; 2607 uint8_t phymode_roundup = 0; 2608 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2609 wmi_unified_t pdev_wmi_handle; 2610 2611 /* Length TLV placeholder for array of uint32_t */ 2612 len += WMI_TLV_HDR_SIZE; 2613 /* calculate the length of buffer required */ 2614 if (params->chan_list.num_chan) 2615 len += params->chan_list.num_chan * sizeof(uint32_t); 2616 2617 /* Length TLV placeholder for array of wmi_ssid structures */ 2618 len += WMI_TLV_HDR_SIZE; 2619 if (params->num_ssids) 2620 len += params->num_ssids * sizeof(wmi_ssid); 2621 2622 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2623 len += WMI_TLV_HDR_SIZE; 2624 if (params->num_bssid) 2625 len += sizeof(wmi_mac_addr) * params->num_bssid; 2626 2627 /* Length TLV placeholder for array of bytes */ 2628 len += WMI_TLV_HDR_SIZE; 2629 if (params->extraie.len) 2630 extraie_len_with_pad = 2631 roundup(params->extraie.len, sizeof(uint32_t)); 2632 len += extraie_len_with_pad; 2633 2634 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2635 if (ie_whitelist->num_vendor_oui) 2636 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2637 2638 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2639 if (params->scan_f_wide_band) 2640 phymode_roundup = 2641 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2642 sizeof(uint32_t)); 2643 len += phymode_roundup; 2644 2645 /* Allocate the memory */ 2646 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2647 if (!wmi_buf) { 2648 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2649 __func__); 2650 return QDF_STATUS_E_FAILURE; 2651 } 2652 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2653 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2654 WMITLV_SET_HDR(&cmd->tlv_header, 2655 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2656 WMITLV_GET_STRUCT_TLVLEN 2657 (wmi_start_scan_cmd_fixed_param)); 2658 2659 cmd->scan_id = params->scan_id; 2660 cmd->scan_req_id = params->scan_req_id; 2661 cmd->vdev_id = params->vdev_id; 2662 cmd->scan_priority = params->scan_priority; 2663 2664 copy_scan_event_cntrl_flags(cmd, params); 2665 2666 cmd->dwell_time_active = params->dwell_time_active; 2667 cmd->dwell_time_passive = params->dwell_time_passive; 2668 cmd->min_rest_time = params->min_rest_time; 2669 cmd->max_rest_time = params->max_rest_time; 2670 cmd->repeat_probe_time = params->repeat_probe_time; 2671 cmd->probe_spacing_time = params->probe_spacing_time; 2672 cmd->idle_time = params->idle_time; 2673 cmd->max_scan_time = params->max_scan_time; 2674 cmd->probe_delay = params->probe_delay; 2675 cmd->burst_duration = params->burst_duration; 2676 cmd->num_chan = params->chan_list.num_chan; 2677 cmd->num_bssid = params->num_bssid; 2678 cmd->num_ssids = params->num_ssids; 2679 cmd->ie_len = params->extraie.len; 2680 cmd->n_probes = params->n_probes; 2681 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2682 2683 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2684 2685 if (params->scan_random.randomize) 2686 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2687 params->scan_random.mac_mask, 2688 &cmd->mac_addr, 2689 &cmd->mac_mask); 2690 2691 if (ie_whitelist->white_list) 2692 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2693 &cmd->num_vendor_oui, 2694 ie_whitelist); 2695 2696 buf_ptr += sizeof(*cmd); 2697 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2698 for (i = 0; i < params->chan_list.num_chan; ++i) 2699 tmp_ptr[i] = params->chan_list.chan[i].freq; 2700 2701 WMITLV_SET_HDR(buf_ptr, 2702 WMITLV_TAG_ARRAY_UINT32, 2703 (params->chan_list.num_chan * sizeof(uint32_t))); 2704 buf_ptr += WMI_TLV_HDR_SIZE + 2705 (params->chan_list.num_chan * sizeof(uint32_t)); 2706 2707 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2708 WMI_LOGE("Invalid value for numSsid"); 2709 goto error; 2710 } 2711 2712 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2713 (params->num_ssids * sizeof(wmi_ssid))); 2714 2715 if (params->num_ssids) { 2716 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2717 for (i = 0; i < params->num_ssids; ++i) { 2718 ssid->ssid_len = params->ssid[i].length; 2719 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2720 params->ssid[i].length); 2721 ssid++; 2722 } 2723 } 2724 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2725 2726 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2727 (params->num_bssid * sizeof(wmi_mac_addr))); 2728 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2729 2730 if (params->num_bssid) { 2731 for (i = 0; i < params->num_bssid; ++i) { 2732 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2733 ¶ms->bssid_list[i].bytes[0], bssid); 2734 bssid++; 2735 } 2736 } 2737 2738 buf_ptr += WMI_TLV_HDR_SIZE + 2739 (params->num_bssid * sizeof(wmi_mac_addr)); 2740 2741 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2742 if (params->extraie.len) 2743 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2744 params); 2745 2746 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2747 2748 /* probe req ie whitelisting */ 2749 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2750 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2751 2752 buf_ptr += WMI_TLV_HDR_SIZE; 2753 2754 if (cmd->num_vendor_oui) { 2755 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2756 ie_whitelist->voui); 2757 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2758 } 2759 2760 /* Add phy mode TLV if it's a wide band scan */ 2761 if (params->scan_f_wide_band) { 2762 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2763 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2764 for (i = 0; i < params->chan_list.num_chan; ++i) 2765 buf_ptr[i] = 2766 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2767 buf_ptr += phymode_roundup; 2768 } else { 2769 /* Add ZERO legth phy mode TLV */ 2770 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2771 } 2772 2773 pdev_wmi_handle = get_pdev_wmi_handle(wmi_handle, cmd->vdev_id); 2774 if (pdev_wmi_handle == NULL) { 2775 WMI_LOGE("%s: Invalid PDEV WMI handle", __func__); 2776 goto error; 2777 } 2778 2779 ret = wmi_unified_cmd_send(pdev_wmi_handle, wmi_buf, 2780 len, WMI_START_SCAN_CMDID); 2781 if (ret) { 2782 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2783 wmi_buf_free(wmi_buf); 2784 } 2785 return ret; 2786 error: 2787 wmi_buf_free(wmi_buf); 2788 return QDF_STATUS_E_FAILURE; 2789 } 2790 2791 /** 2792 * send_scan_stop_cmd_tlv() - WMI scan start function 2793 * @param wmi_handle : handle to WMI. 2794 * @param param : pointer to hold scan cancel cmd parameter 2795 * 2796 * Return: 0 on success and -ve on failure. 2797 */ 2798 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2799 struct scan_cancel_param *param) 2800 { 2801 wmi_stop_scan_cmd_fixed_param *cmd; 2802 int ret; 2803 int len = sizeof(*cmd); 2804 wmi_buf_t wmi_buf; 2805 wmi_unified_t pdev_wmi_handle; 2806 2807 /* Allocate the memory */ 2808 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2809 if (!wmi_buf) { 2810 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2811 __func__); 2812 ret = QDF_STATUS_E_NOMEM; 2813 goto error; 2814 } 2815 2816 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2817 WMITLV_SET_HDR(&cmd->tlv_header, 2818 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2819 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2820 cmd->vdev_id = param->vdev_id; 2821 cmd->requestor = param->requester; 2822 cmd->scan_id = param->scan_id; 2823 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2824 param->pdev_id); 2825 /* stop the scan with the corresponding scan_id */ 2826 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2827 /* Cancelling all scans */ 2828 cmd->req_type = WMI_SCAN_STOP_ALL; 2829 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2830 /* Cancelling VAP scans */ 2831 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2832 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2833 /* Cancelling specific scan */ 2834 cmd->req_type = WMI_SCAN_STOP_ONE; 2835 } else { 2836 WMI_LOGE("%s: Invalid Command : ", __func__); 2837 wmi_buf_free(wmi_buf); 2838 return QDF_STATUS_E_INVAL; 2839 } 2840 2841 pdev_wmi_handle = get_pdev_wmi_handle(wmi_handle, cmd->vdev_id); 2842 if (pdev_wmi_handle == NULL) { 2843 WMI_LOGE("%s: Invalid PDEV WMI handle", __func__); 2844 wmi_buf_free(wmi_buf); 2845 return QDF_STATUS_E_NULL_VALUE; 2846 } 2847 2848 ret = wmi_unified_cmd_send(pdev_wmi_handle, wmi_buf, 2849 len, WMI_STOP_SCAN_CMDID); 2850 if (ret) { 2851 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2852 wmi_buf_free(wmi_buf); 2853 } 2854 2855 error: 2856 return ret; 2857 } 2858 2859 #ifdef CONFIG_MCL 2860 /** 2861 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2862 * @param wmi_handle : handle to WMI. 2863 * @param param : pointer to hold scan channel list parameter 2864 * 2865 * Return: 0 on success and -ve on failure. 2866 */ 2867 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2868 struct scan_chan_list_params *chan_list) 2869 { 2870 wmi_buf_t buf; 2871 QDF_STATUS qdf_status; 2872 wmi_scan_chan_list_cmd_fixed_param *cmd; 2873 int i; 2874 uint8_t *buf_ptr; 2875 wmi_channel_param *chan_info, *tchan_info; 2876 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2877 2878 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2879 buf = wmi_buf_alloc(wmi_handle, len); 2880 if (!buf) { 2881 WMI_LOGE("Failed to allocate memory"); 2882 qdf_status = QDF_STATUS_E_NOMEM; 2883 goto end; 2884 } 2885 2886 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2887 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2888 WMITLV_SET_HDR(&cmd->tlv_header, 2889 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2890 WMITLV_GET_STRUCT_TLVLEN 2891 (wmi_scan_chan_list_cmd_fixed_param)); 2892 2893 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2894 2895 cmd->num_scan_chans = chan_list->num_scan_chans; 2896 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2897 WMITLV_TAG_ARRAY_STRUC, 2898 sizeof(wmi_channel) * chan_list->num_scan_chans); 2899 chan_info = (wmi_channel_param *) 2900 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2901 tchan_info = chan_list->chan_info; 2902 2903 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2904 WMITLV_SET_HDR(&chan_info->tlv_header, 2905 WMITLV_TAG_STRUC_wmi_channel, 2906 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2907 chan_info->mhz = tchan_info->mhz; 2908 chan_info->band_center_freq1 = 2909 tchan_info->band_center_freq1; 2910 chan_info->band_center_freq2 = 2911 tchan_info->band_center_freq2; 2912 chan_info->info = tchan_info->info; 2913 chan_info->reg_info_1 = tchan_info->reg_info_1; 2914 chan_info->reg_info_2 = tchan_info->reg_info_2; 2915 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2916 2917 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2918 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2919 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2920 tchan_info++; 2921 chan_info++; 2922 } 2923 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2924 chan_list->pdev_id); 2925 2926 qdf_status = wmi_unified_cmd_send(wmi_handle, 2927 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2928 2929 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2930 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2931 wmi_buf_free(buf); 2932 } 2933 2934 end: 2935 return qdf_status; 2936 } 2937 #else 2938 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2939 struct scan_chan_list_params *chan_list) 2940 { 2941 wmi_buf_t buf; 2942 QDF_STATUS qdf_status; 2943 wmi_scan_chan_list_cmd_fixed_param *cmd; 2944 int i; 2945 uint8_t *buf_ptr; 2946 wmi_channel *chan_info; 2947 struct channel_param *tchan_info; 2948 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2949 2950 len += sizeof(wmi_channel) * chan_list->nallchans; 2951 buf = wmi_buf_alloc(wmi_handle, len); 2952 if (!buf) { 2953 WMI_LOGE("Failed to allocate memory"); 2954 qdf_status = QDF_STATUS_E_NOMEM; 2955 goto end; 2956 } 2957 2958 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2959 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2960 WMITLV_SET_HDR(&cmd->tlv_header, 2961 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2962 WMITLV_GET_STRUCT_TLVLEN 2963 (wmi_scan_chan_list_cmd_fixed_param)); 2964 2965 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2966 2967 if (chan_list->append) 2968 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2969 2970 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2971 chan_list->pdev_id); 2972 cmd->num_scan_chans = chan_list->nallchans; 2973 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2974 WMITLV_TAG_ARRAY_STRUC, 2975 sizeof(wmi_channel) * chan_list->nallchans); 2976 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2977 tchan_info = &(chan_list->ch_param[0]); 2978 2979 for (i = 0; i < chan_list->nallchans; ++i) { 2980 WMITLV_SET_HDR(&chan_info->tlv_header, 2981 WMITLV_TAG_STRUC_wmi_channel, 2982 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2983 chan_info->mhz = tchan_info->mhz; 2984 chan_info->band_center_freq1 = 2985 tchan_info->cfreq1; 2986 chan_info->band_center_freq2 = 2987 tchan_info->cfreq2; 2988 2989 if (tchan_info->is_chan_passive) 2990 WMI_SET_CHANNEL_FLAG(chan_info, 2991 WMI_CHAN_FLAG_PASSIVE); 2992 2993 if (tchan_info->allow_vht) 2994 WMI_SET_CHANNEL_FLAG(chan_info, 2995 WMI_CHAN_FLAG_ALLOW_VHT); 2996 else if (tchan_info->allow_ht) 2997 WMI_SET_CHANNEL_FLAG(chan_info, 2998 WMI_CHAN_FLAG_ALLOW_HT); 2999 WMI_SET_CHANNEL_MODE(chan_info, 3000 tchan_info->phy_mode); 3001 3002 /* Add tchan_info->half_rate and tchan_info->quarter_rate later 3003 * after FW support 3004 */ 3005 3006 /* also fill in power information */ 3007 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3008 tchan_info->minpower); 3009 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3010 tchan_info->maxpower); 3011 WMI_SET_CHANNEL_REG_POWER(chan_info, 3012 tchan_info->maxregpower); 3013 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3014 tchan_info->antennamax); 3015 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3016 tchan_info->reg_class_id); 3017 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3018 tchan_info->maxregpower); 3019 3020 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 3021 3022 tchan_info++; 3023 chan_info++; 3024 } 3025 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3026 chan_list->pdev_id); 3027 3028 qdf_status = wmi_unified_cmd_send( 3029 wmi_handle, 3030 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3031 3032 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3033 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3034 wmi_buf_free(buf); 3035 } 3036 3037 end: 3038 return qdf_status; 3039 } 3040 #endif 3041 3042 /** 3043 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3044 * 3045 * @bufp: Pointer to buffer 3046 * @param: Pointer to tx param 3047 * 3048 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3049 */ 3050 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3051 struct tx_send_params param) 3052 { 3053 wmi_tx_send_params *tx_param; 3054 QDF_STATUS status = QDF_STATUS_SUCCESS; 3055 3056 if (!bufp) { 3057 status = QDF_STATUS_E_FAILURE; 3058 return status; 3059 } 3060 tx_param = (wmi_tx_send_params *)bufp; 3061 WMITLV_SET_HDR(&tx_param->tlv_header, 3062 WMITLV_TAG_STRUC_wmi_tx_send_params, 3063 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3064 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3065 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3066 param.mcs_mask); 3067 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3068 param.nss_mask); 3069 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3070 param.retry_limit); 3071 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3072 param.chain_mask); 3073 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3074 param.bw_mask); 3075 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3076 param.preamble_type); 3077 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3078 param.frame_type); 3079 3080 return status; 3081 } 3082 3083 /** 3084 * send_mgmt_cmd_tlv() - WMI scan start function 3085 * @wmi_handle : handle to WMI. 3086 * @param : pointer to hold mgmt cmd parameter 3087 * 3088 * Return: 0 on success and -ve on failure. 3089 */ 3090 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3091 struct wmi_mgmt_params *param) 3092 { 3093 wmi_buf_t buf; 3094 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3095 int32_t cmd_len; 3096 uint64_t dma_addr; 3097 void *qdf_ctx = param->qdf_ctx; 3098 uint8_t *bufp; 3099 QDF_STATUS status = QDF_STATUS_SUCCESS; 3100 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3101 mgmt_tx_dl_frm_len; 3102 3103 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3104 WMI_TLV_HDR_SIZE + 3105 roundup(bufp_len, sizeof(uint32_t)); 3106 3107 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3108 if (!buf) { 3109 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3110 return QDF_STATUS_E_NOMEM; 3111 } 3112 3113 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3114 bufp = (uint8_t *) cmd; 3115 WMITLV_SET_HDR(&cmd->tlv_header, 3116 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3117 WMITLV_GET_STRUCT_TLVLEN 3118 (wmi_mgmt_tx_send_cmd_fixed_param)); 3119 3120 cmd->vdev_id = param->vdev_id; 3121 3122 cmd->desc_id = param->desc_id; 3123 cmd->chanfreq = param->chanfreq; 3124 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3125 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3126 sizeof(uint32_t))); 3127 bufp += WMI_TLV_HDR_SIZE; 3128 qdf_mem_copy(bufp, param->pdata, bufp_len); 3129 3130 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3131 QDF_DMA_TO_DEVICE); 3132 if (status != QDF_STATUS_SUCCESS) { 3133 WMI_LOGE("%s: wmi buf map failed", __func__); 3134 goto free_buf; 3135 } 3136 3137 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3138 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3139 #if defined(HTT_PADDR64) 3140 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3141 #endif 3142 cmd->frame_len = param->frm_len; 3143 cmd->buf_len = bufp_len; 3144 cmd->tx_params_valid = param->tx_params_valid; 3145 3146 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3147 bufp, cmd->vdev_id, cmd->chanfreq); 3148 3149 bufp += roundup(bufp_len, sizeof(uint32_t)); 3150 if (param->tx_params_valid) { 3151 status = populate_tx_send_params(bufp, param->tx_param); 3152 if (status != QDF_STATUS_SUCCESS) { 3153 WMI_LOGE("%s: Populate TX send params failed", 3154 __func__); 3155 goto unmap_tx_frame; 3156 } 3157 cmd_len += sizeof(wmi_tx_send_params); 3158 } 3159 3160 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3161 WMI_MGMT_TX_SEND_CMDID)) { 3162 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3163 goto unmap_tx_frame; 3164 } 3165 return QDF_STATUS_SUCCESS; 3166 3167 unmap_tx_frame: 3168 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3169 QDF_DMA_TO_DEVICE); 3170 free_buf: 3171 wmi_buf_free(buf); 3172 return QDF_STATUS_E_FAILURE; 3173 } 3174 3175 /** 3176 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3177 * @wmi_handle : handle to WMI. 3178 * @param : pointer to offchan data tx cmd parameter 3179 * 3180 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3181 */ 3182 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3183 struct wmi_offchan_data_tx_params *param) 3184 { 3185 wmi_buf_t buf; 3186 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3187 int32_t cmd_len; 3188 uint64_t dma_addr; 3189 void *qdf_ctx = param->qdf_ctx; 3190 uint8_t *bufp; 3191 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3192 param->frm_len : mgmt_tx_dl_frm_len; 3193 QDF_STATUS status = QDF_STATUS_SUCCESS; 3194 3195 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3196 WMI_TLV_HDR_SIZE + 3197 roundup(bufp_len, sizeof(uint32_t)); 3198 3199 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3200 if (!buf) { 3201 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3202 return QDF_STATUS_E_NOMEM; 3203 } 3204 3205 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3206 bufp = (uint8_t *) cmd; 3207 WMITLV_SET_HDR(&cmd->tlv_header, 3208 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3209 WMITLV_GET_STRUCT_TLVLEN 3210 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3211 3212 cmd->vdev_id = param->vdev_id; 3213 3214 cmd->desc_id = param->desc_id; 3215 cmd->chanfreq = param->chanfreq; 3216 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3217 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3218 sizeof(uint32_t))); 3219 bufp += WMI_TLV_HDR_SIZE; 3220 qdf_mem_copy(bufp, param->pdata, bufp_len); 3221 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3222 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3223 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3224 #if defined(HTT_PADDR64) 3225 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3226 #endif 3227 cmd->frame_len = param->frm_len; 3228 cmd->buf_len = bufp_len; 3229 cmd->tx_params_valid = param->tx_params_valid; 3230 3231 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3232 bufp, cmd->vdev_id, cmd->chanfreq); 3233 3234 bufp += roundup(bufp_len, sizeof(uint32_t)); 3235 if (param->tx_params_valid) { 3236 status = populate_tx_send_params(bufp, param->tx_param); 3237 if (status != QDF_STATUS_SUCCESS) { 3238 WMI_LOGE("%s: Populate TX send params failed", 3239 __func__); 3240 goto err1; 3241 } 3242 cmd_len += sizeof(wmi_tx_send_params); 3243 } 3244 3245 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3246 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3247 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3248 goto err1; 3249 } 3250 3251 return QDF_STATUS_SUCCESS; 3252 3253 err1: 3254 wmi_buf_free(buf); 3255 return QDF_STATUS_E_FAILURE; 3256 } 3257 3258 /** 3259 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3260 * @wmi_handle: wmi handle 3261 * @param_value: parameter value 3262 * 3263 * Return: QDF_STATUS_SUCCESS for success or error code 3264 */ 3265 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3266 uint32_t param_value) 3267 { 3268 QDF_STATUS ret; 3269 wmi_modem_power_state_cmd_param *cmd; 3270 wmi_buf_t buf; 3271 uint16_t len = sizeof(*cmd); 3272 3273 buf = wmi_buf_alloc(wmi_handle, len); 3274 if (!buf) { 3275 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3276 return QDF_STATUS_E_NOMEM; 3277 } 3278 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3279 WMITLV_SET_HDR(&cmd->tlv_header, 3280 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3281 WMITLV_GET_STRUCT_TLVLEN 3282 (wmi_modem_power_state_cmd_param)); 3283 cmd->modem_power_state = param_value; 3284 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3285 param_value); 3286 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3287 WMI_MODEM_POWER_STATE_CMDID); 3288 if (QDF_IS_STATUS_ERROR(ret)) { 3289 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3290 wmi_buf_free(buf); 3291 } 3292 3293 return ret; 3294 } 3295 3296 /** 3297 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3298 * @wmi_handle: wmi handle 3299 * @vdev_id: vdev id 3300 * @val: value 3301 * 3302 * Return: QDF_STATUS_SUCCESS for success or error code. 3303 */ 3304 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3305 uint32_t vdev_id, uint8_t val) 3306 { 3307 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3308 wmi_buf_t buf; 3309 int32_t len = sizeof(*cmd); 3310 3311 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3312 3313 buf = wmi_buf_alloc(wmi_handle, len); 3314 if (!buf) { 3315 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3316 return QDF_STATUS_E_NOMEM; 3317 } 3318 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3319 WMITLV_SET_HDR(&cmd->tlv_header, 3320 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3321 WMITLV_GET_STRUCT_TLVLEN 3322 (wmi_sta_powersave_mode_cmd_fixed_param)); 3323 cmd->vdev_id = vdev_id; 3324 if (val) 3325 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3326 else 3327 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3328 3329 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3330 WMI_STA_POWERSAVE_MODE_CMDID)) { 3331 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3332 vdev_id, val); 3333 wmi_buf_free(buf); 3334 return QDF_STATUS_E_FAILURE; 3335 } 3336 return 0; 3337 } 3338 3339 /** 3340 * send_set_mimops_cmd_tlv() - set MIMO powersave 3341 * @wmi_handle: wmi handle 3342 * @vdev_id: vdev id 3343 * @value: value 3344 * 3345 * Return: QDF_STATUS_SUCCESS for success or error code. 3346 */ 3347 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3348 uint8_t vdev_id, int value) 3349 { 3350 QDF_STATUS ret; 3351 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3352 wmi_buf_t buf; 3353 uint16_t len = sizeof(*cmd); 3354 3355 buf = wmi_buf_alloc(wmi_handle, len); 3356 if (!buf) { 3357 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3358 return QDF_STATUS_E_NOMEM; 3359 } 3360 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3361 WMITLV_SET_HDR(&cmd->tlv_header, 3362 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3363 WMITLV_GET_STRUCT_TLVLEN 3364 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3365 3366 cmd->vdev_id = vdev_id; 3367 3368 /* WMI_SMPS_FORCED_MODE values do not directly map 3369 * to SM power save values defined in the specification. 3370 * Make sure to send the right mapping. 3371 */ 3372 switch (value) { 3373 case 0: 3374 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3375 break; 3376 case 1: 3377 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3378 break; 3379 case 2: 3380 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3381 break; 3382 case 3: 3383 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3384 break; 3385 default: 3386 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3387 return QDF_STATUS_E_FAILURE; 3388 } 3389 3390 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3391 3392 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3393 WMI_STA_SMPS_FORCE_MODE_CMDID); 3394 if (QDF_IS_STATUS_ERROR(ret)) { 3395 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3396 wmi_buf_free(buf); 3397 } 3398 3399 return ret; 3400 } 3401 3402 /** 3403 * send_set_smps_params_cmd_tlv() - set smps params 3404 * @wmi_handle: wmi handle 3405 * @vdev_id: vdev id 3406 * @value: value 3407 * 3408 * Return: QDF_STATUS_SUCCESS for success or error code. 3409 */ 3410 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3411 int value) 3412 { 3413 QDF_STATUS ret; 3414 wmi_sta_smps_param_cmd_fixed_param *cmd; 3415 wmi_buf_t buf; 3416 uint16_t len = sizeof(*cmd); 3417 3418 buf = wmi_buf_alloc(wmi_handle, len); 3419 if (!buf) { 3420 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3421 return QDF_STATUS_E_NOMEM; 3422 } 3423 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3424 WMITLV_SET_HDR(&cmd->tlv_header, 3425 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3426 WMITLV_GET_STRUCT_TLVLEN 3427 (wmi_sta_smps_param_cmd_fixed_param)); 3428 3429 cmd->vdev_id = vdev_id; 3430 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3431 cmd->param = 3432 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3433 3434 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3435 cmd->param); 3436 3437 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3438 WMI_STA_SMPS_PARAM_CMDID); 3439 if (QDF_IS_STATUS_ERROR(ret)) { 3440 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3441 wmi_buf_free(buf); 3442 } 3443 3444 return ret; 3445 } 3446 3447 /** 3448 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3449 * @wmi_handle: wmi handle 3450 * @noa: p2p power save parameters 3451 * 3452 * Return: CDF status 3453 */ 3454 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3455 struct p2p_ps_params *noa) 3456 { 3457 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3458 wmi_p2p_noa_descriptor *noa_discriptor; 3459 wmi_buf_t buf; 3460 uint8_t *buf_ptr; 3461 uint16_t len; 3462 QDF_STATUS status; 3463 uint32_t duration; 3464 3465 WMI_LOGD("%s: Enter", __func__); 3466 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3467 buf = wmi_buf_alloc(wmi_handle, len); 3468 if (!buf) { 3469 WMI_LOGE("Failed to allocate memory"); 3470 status = QDF_STATUS_E_FAILURE; 3471 goto end; 3472 } 3473 3474 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3475 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3476 WMITLV_SET_HDR(&cmd->tlv_header, 3477 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3478 WMITLV_GET_STRUCT_TLVLEN 3479 (wmi_p2p_set_noa_cmd_fixed_param)); 3480 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3481 cmd->vdev_id = noa->session_id; 3482 cmd->enable = (duration) ? true : false; 3483 cmd->num_noa = 1; 3484 3485 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3486 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3487 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3488 sizeof 3489 (wmi_p2p_set_noa_cmd_fixed_param) 3490 + WMI_TLV_HDR_SIZE); 3491 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3492 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3493 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3494 noa_discriptor->type_count = noa->count; 3495 noa_discriptor->duration = duration; 3496 noa_discriptor->interval = noa->interval; 3497 noa_discriptor->start_time = 0; 3498 3499 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3500 cmd->vdev_id, noa->count, noa_discriptor->duration, 3501 noa->interval); 3502 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3503 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3504 if (QDF_IS_STATUS_ERROR(status)) { 3505 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3506 wmi_buf_free(buf); 3507 } 3508 3509 end: 3510 WMI_LOGD("%s: Exit", __func__); 3511 return status; 3512 } 3513 3514 3515 /** 3516 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3517 * @wmi_handle: wmi handle 3518 * @noa: p2p opp power save parameters 3519 * 3520 * Return: CDF status 3521 */ 3522 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3523 struct p2p_ps_params *oppps) 3524 { 3525 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3526 wmi_buf_t buf; 3527 QDF_STATUS status; 3528 3529 WMI_LOGD("%s: Enter", __func__); 3530 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3531 if (!buf) { 3532 WMI_LOGE("Failed to allocate memory"); 3533 status = QDF_STATUS_E_FAILURE; 3534 goto end; 3535 } 3536 3537 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3538 WMITLV_SET_HDR(&cmd->tlv_header, 3539 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3540 WMITLV_GET_STRUCT_TLVLEN 3541 (wmi_p2p_set_oppps_cmd_fixed_param)); 3542 cmd->vdev_id = oppps->session_id; 3543 if (oppps->ctwindow) 3544 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3545 3546 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3547 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3548 cmd->vdev_id, oppps->ctwindow); 3549 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3550 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3551 if (QDF_IS_STATUS_ERROR(status)) { 3552 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3553 wmi_buf_free(buf); 3554 } 3555 3556 end: 3557 WMI_LOGD("%s: Exit", __func__); 3558 return status; 3559 } 3560 3561 #ifdef CONVERGED_P2P_ENABLE 3562 /** 3563 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3564 * @wmi_handle: wmi handle 3565 * @param: p2p listen offload start parameters 3566 * 3567 * Return: QDF status 3568 */ 3569 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3570 struct p2p_lo_start *param) 3571 { 3572 wmi_buf_t buf; 3573 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3574 int32_t len = sizeof(*cmd); 3575 uint8_t *buf_ptr; 3576 QDF_STATUS status; 3577 int device_types_len_aligned; 3578 int probe_resp_len_aligned; 3579 3580 if (!param) { 3581 WMI_LOGE("lo start param is null"); 3582 return QDF_STATUS_E_INVAL; 3583 } 3584 3585 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3586 3587 device_types_len_aligned = 3588 qdf_roundup(param->dev_types_len, 3589 sizeof(A_UINT32)); 3590 probe_resp_len_aligned = 3591 qdf_roundup(param->probe_resp_len, 3592 sizeof(A_UINT32)); 3593 3594 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3595 probe_resp_len_aligned; 3596 3597 buf = wmi_buf_alloc(wmi_handle, len); 3598 if (!buf) { 3599 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3600 __func__); 3601 return QDF_STATUS_E_NOMEM; 3602 } 3603 3604 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3605 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3606 3607 WMITLV_SET_HDR(&cmd->tlv_header, 3608 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3609 WMITLV_GET_STRUCT_TLVLEN( 3610 wmi_p2p_lo_start_cmd_fixed_param)); 3611 3612 cmd->vdev_id = param->vdev_id; 3613 cmd->ctl_flags = param->ctl_flags; 3614 cmd->channel = param->freq; 3615 cmd->period = param->period; 3616 cmd->interval = param->interval; 3617 cmd->count = param->count; 3618 cmd->device_types_len = param->dev_types_len; 3619 cmd->prob_resp_len = param->probe_resp_len; 3620 3621 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3622 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3623 device_types_len_aligned); 3624 buf_ptr += WMI_TLV_HDR_SIZE; 3625 qdf_mem_copy(buf_ptr, param->device_types, 3626 param->dev_types_len); 3627 3628 buf_ptr += device_types_len_aligned; 3629 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3630 probe_resp_len_aligned); 3631 buf_ptr += WMI_TLV_HDR_SIZE; 3632 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3633 param->probe_resp_len); 3634 3635 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3636 cmd->channel, cmd->period, cmd->interval, cmd->count); 3637 3638 status = wmi_unified_cmd_send(wmi_handle, 3639 buf, len, 3640 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3641 if (status != QDF_STATUS_SUCCESS) { 3642 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3643 __func__, status); 3644 wmi_buf_free(buf); 3645 return status; 3646 } 3647 3648 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3649 3650 return QDF_STATUS_SUCCESS; 3651 } 3652 3653 /** 3654 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3655 * @wmi_handle: wmi handle 3656 * @param: p2p listen offload stop parameters 3657 * 3658 * Return: QDF status 3659 */ 3660 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3661 uint8_t vdev_id) 3662 { 3663 wmi_buf_t buf; 3664 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3665 int32_t len; 3666 QDF_STATUS status; 3667 3668 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3669 3670 len = sizeof(*cmd); 3671 buf = wmi_buf_alloc(wmi_handle, len); 3672 if (!buf) { 3673 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3674 __func__); 3675 return QDF_STATUS_E_NOMEM; 3676 } 3677 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3678 3679 WMITLV_SET_HDR(&cmd->tlv_header, 3680 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3681 WMITLV_GET_STRUCT_TLVLEN( 3682 wmi_p2p_lo_stop_cmd_fixed_param)); 3683 3684 cmd->vdev_id = vdev_id; 3685 3686 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3687 3688 status = wmi_unified_cmd_send(wmi_handle, 3689 buf, len, 3690 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3691 if (status != QDF_STATUS_SUCCESS) { 3692 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3693 __func__, status); 3694 wmi_buf_free(buf); 3695 return status; 3696 } 3697 3698 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3699 3700 return QDF_STATUS_SUCCESS; 3701 } 3702 #endif /* End of CONVERGED_P2P_ENABLE */ 3703 3704 /** 3705 * send_get_temperature_cmd_tlv() - get pdev temperature req 3706 * @wmi_handle: wmi handle 3707 * 3708 * Return: QDF_STATUS_SUCCESS for success or error code. 3709 */ 3710 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3711 { 3712 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3713 wmi_buf_t wmi_buf; 3714 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3715 uint8_t *buf_ptr; 3716 3717 if (!wmi_handle) { 3718 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3719 return QDF_STATUS_E_INVAL; 3720 } 3721 3722 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3723 if (!wmi_buf) { 3724 WMI_LOGE(FL("wmi_buf_alloc failed")); 3725 return QDF_STATUS_E_NOMEM; 3726 } 3727 3728 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3729 3730 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3731 WMITLV_SET_HDR(&cmd->tlv_header, 3732 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3733 WMITLV_GET_STRUCT_TLVLEN 3734 (wmi_pdev_get_temperature_cmd_fixed_param)); 3735 3736 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3737 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3738 WMI_LOGE(FL("failed to send get temperature command")); 3739 wmi_buf_free(wmi_buf); 3740 return QDF_STATUS_E_FAILURE; 3741 } 3742 3743 return QDF_STATUS_SUCCESS; 3744 } 3745 3746 /** 3747 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3748 * @wmi_handle: wmi handle 3749 * @vdevid: vdev id 3750 * @peer_addr: peer mac address 3751 * @auto_triggerparam: auto trigger parameters 3752 * @num_ac: number of access category 3753 * 3754 * This function sets the trigger 3755 * uapsd params such as service interval, delay interval 3756 * and suspend interval which will be used by the firmware 3757 * to send trigger frames periodically when there is no 3758 * traffic on the transmit side. 3759 * 3760 * Return: QDF_STATUS_SUCCESS for success or error code. 3761 */ 3762 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3763 struct sta_uapsd_trig_params *param) 3764 { 3765 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3766 QDF_STATUS ret; 3767 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3768 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3769 uint32_t i; 3770 wmi_buf_t buf; 3771 uint8_t *buf_ptr; 3772 struct sta_uapsd_params *uapsd_param; 3773 wmi_sta_uapsd_auto_trig_param *trig_param; 3774 3775 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3776 if (!buf) { 3777 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3778 return QDF_STATUS_E_NOMEM; 3779 } 3780 3781 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3782 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3783 WMITLV_SET_HDR(&cmd->tlv_header, 3784 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3785 WMITLV_GET_STRUCT_TLVLEN 3786 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3787 cmd->vdev_id = param->vdevid; 3788 cmd->num_ac = param->num_ac; 3789 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3790 3791 /* TLV indicating array of structures to follow */ 3792 buf_ptr += sizeof(*cmd); 3793 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3794 3795 buf_ptr += WMI_TLV_HDR_SIZE; 3796 3797 /* 3798 * Update tag and length for uapsd auto trigger params (this will take 3799 * care of updating tag and length if it is not pre-filled by caller). 3800 */ 3801 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3802 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3803 for (i = 0; i < param->num_ac; i++) { 3804 WMITLV_SET_HDR((buf_ptr + 3805 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3806 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3807 WMITLV_GET_STRUCT_TLVLEN 3808 (wmi_sta_uapsd_auto_trig_param)); 3809 trig_param->wmm_ac = uapsd_param->wmm_ac; 3810 trig_param->user_priority = uapsd_param->user_priority; 3811 trig_param->service_interval = uapsd_param->service_interval; 3812 trig_param->suspend_interval = uapsd_param->suspend_interval; 3813 trig_param->delay_interval = uapsd_param->delay_interval; 3814 trig_param++; 3815 uapsd_param++; 3816 } 3817 3818 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3819 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3820 if (QDF_IS_STATUS_ERROR(ret)) { 3821 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3822 wmi_buf_free(buf); 3823 } 3824 3825 return ret; 3826 } 3827 3828 #ifdef WLAN_FEATURE_DSRC 3829 /** 3830 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3831 * @wmi_handle: pointer to the wmi handle 3832 * @utc: pointer to the UTC time struct 3833 * 3834 * Return: 0 on succes 3835 */ 3836 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3837 struct ocb_utc_param *utc) 3838 { 3839 QDF_STATUS ret; 3840 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3841 uint8_t *buf_ptr; 3842 uint32_t len, i; 3843 wmi_buf_t buf; 3844 3845 len = sizeof(*cmd); 3846 buf = wmi_buf_alloc(wmi_handle, len); 3847 if (!buf) { 3848 WMI_LOGE(FL("wmi_buf_alloc failed")); 3849 return QDF_STATUS_E_NOMEM; 3850 } 3851 3852 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3853 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3854 WMITLV_SET_HDR(&cmd->tlv_header, 3855 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3856 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3857 cmd->vdev_id = utc->vdev_id; 3858 3859 for (i = 0; i < SIZE_UTC_TIME; i++) 3860 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 3861 3862 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 3863 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 3864 3865 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3866 WMI_OCB_SET_UTC_TIME_CMDID); 3867 if (QDF_IS_STATUS_ERROR(ret)) { 3868 WMI_LOGE(FL("Failed to set OCB UTC time")); 3869 wmi_buf_free(buf); 3870 } 3871 3872 return ret; 3873 } 3874 3875 /** 3876 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 3877 * frames on a channel 3878 * @wmi_handle: pointer to the wmi handle 3879 * @timing_advert: pointer to the timing advertisement struct 3880 * 3881 * Return: 0 on succes 3882 */ 3883 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3884 struct ocb_timing_advert_param *timing_advert) 3885 { 3886 QDF_STATUS ret; 3887 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 3888 uint8_t *buf_ptr; 3889 uint32_t len, len_template; 3890 wmi_buf_t buf; 3891 3892 len = sizeof(*cmd) + 3893 WMI_TLV_HDR_SIZE; 3894 3895 len_template = timing_advert->template_length; 3896 /* Add padding to the template if needed */ 3897 if (len_template % 4 != 0) 3898 len_template += 4 - (len_template % 4); 3899 len += len_template; 3900 3901 buf = wmi_buf_alloc(wmi_handle, len); 3902 if (!buf) { 3903 WMI_LOGE(FL("wmi_buf_alloc failed")); 3904 return QDF_STATUS_E_NOMEM; 3905 } 3906 3907 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3908 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 3909 WMITLV_SET_HDR(&cmd->tlv_header, 3910 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 3911 WMITLV_GET_STRUCT_TLVLEN( 3912 wmi_ocb_start_timing_advert_cmd_fixed_param)); 3913 cmd->vdev_id = timing_advert->vdev_id; 3914 cmd->repeat_rate = timing_advert->repeat_rate; 3915 cmd->channel_freq = timing_advert->chan_freq; 3916 cmd->timestamp_offset = timing_advert->timestamp_offset; 3917 cmd->time_value_offset = timing_advert->time_value_offset; 3918 cmd->timing_advert_template_length = timing_advert->template_length; 3919 buf_ptr += sizeof(*cmd); 3920 3921 /* Add the timing advert template */ 3922 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3923 len_template); 3924 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 3925 (uint8_t *)timing_advert->template_value, 3926 timing_advert->template_length); 3927 3928 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3929 WMI_OCB_START_TIMING_ADVERT_CMDID); 3930 if (QDF_IS_STATUS_ERROR(ret)) { 3931 WMI_LOGE(FL("Failed to start OCB timing advert")); 3932 wmi_buf_free(buf); 3933 } 3934 3935 return ret; 3936 } 3937 3938 /** 3939 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 3940 * on a channel 3941 * @wmi_handle: pointer to the wmi handle 3942 * @timing_advert: pointer to the timing advertisement struct 3943 * 3944 * Return: 0 on succes 3945 */ 3946 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3947 struct ocb_timing_advert_param *timing_advert) 3948 { 3949 QDF_STATUS ret; 3950 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 3951 uint8_t *buf_ptr; 3952 uint32_t len; 3953 wmi_buf_t buf; 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 3962 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3963 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 3964 WMITLV_SET_HDR(&cmd->tlv_header, 3965 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 3966 WMITLV_GET_STRUCT_TLVLEN( 3967 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 3968 cmd->vdev_id = timing_advert->vdev_id; 3969 cmd->channel_freq = timing_advert->chan_freq; 3970 3971 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3972 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 3973 if (QDF_IS_STATUS_ERROR(ret)) { 3974 WMI_LOGE(FL("Failed to stop OCB timing advert")); 3975 wmi_buf_free(buf); 3976 } 3977 3978 return ret; 3979 } 3980 3981 /** 3982 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 3983 * @wmi_handle: pointer to the wmi handle 3984 * @request: pointer to the request 3985 * 3986 * Return: 0 on succes 3987 */ 3988 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 3989 uint8_t vdev_id) 3990 { 3991 QDF_STATUS ret; 3992 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 3993 uint8_t *buf_ptr; 3994 wmi_buf_t buf; 3995 int32_t len; 3996 3997 len = sizeof(*cmd); 3998 buf = wmi_buf_alloc(wmi_handle, len); 3999 if (!buf) { 4000 WMI_LOGE(FL("wmi_buf_alloc failed")); 4001 return QDF_STATUS_E_NOMEM; 4002 } 4003 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4004 4005 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 4006 qdf_mem_zero(cmd, len); 4007 WMITLV_SET_HDR(&cmd->tlv_header, 4008 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 4009 WMITLV_GET_STRUCT_TLVLEN( 4010 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 4011 cmd->vdev_id = vdev_id; 4012 4013 /* Send the WMI command */ 4014 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4015 WMI_OCB_GET_TSF_TIMER_CMDID); 4016 /* If there is an error, set the completion event */ 4017 if (QDF_IS_STATUS_ERROR(ret)) { 4018 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4019 wmi_buf_free(buf); 4020 } 4021 4022 return ret; 4023 } 4024 4025 /** 4026 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 4027 * @wmi_handle: pointer to the wmi handle 4028 * @get_stats_param: pointer to the dcc stats 4029 * 4030 * Return: 0 on succes 4031 */ 4032 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 4033 struct ocb_dcc_get_stats_param *get_stats_param) 4034 { 4035 QDF_STATUS ret; 4036 wmi_dcc_get_stats_cmd_fixed_param *cmd; 4037 wmi_dcc_channel_stats_request *channel_stats_array; 4038 wmi_buf_t buf; 4039 uint8_t *buf_ptr; 4040 uint32_t len; 4041 uint32_t i; 4042 4043 /* Validate the input */ 4044 if (get_stats_param->request_array_len != 4045 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4046 WMI_LOGE(FL("Invalid parameter")); 4047 return QDF_STATUS_E_INVAL; 4048 } 4049 4050 /* Allocate memory for the WMI command */ 4051 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4052 get_stats_param->request_array_len; 4053 4054 buf = wmi_buf_alloc(wmi_handle, len); 4055 if (!buf) { 4056 WMI_LOGE(FL("wmi_buf_alloc failed")); 4057 return QDF_STATUS_E_NOMEM; 4058 } 4059 4060 buf_ptr = wmi_buf_data(buf); 4061 qdf_mem_zero(buf_ptr, len); 4062 4063 /* Populate the WMI command */ 4064 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4065 buf_ptr += sizeof(*cmd); 4066 4067 WMITLV_SET_HDR(&cmd->tlv_header, 4068 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4069 WMITLV_GET_STRUCT_TLVLEN( 4070 wmi_dcc_get_stats_cmd_fixed_param)); 4071 cmd->vdev_id = get_stats_param->vdev_id; 4072 cmd->num_channels = get_stats_param->channel_count; 4073 4074 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4075 get_stats_param->request_array_len); 4076 buf_ptr += WMI_TLV_HDR_SIZE; 4077 4078 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4079 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4080 get_stats_param->request_array_len); 4081 for (i = 0; i < cmd->num_channels; i++) 4082 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4083 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4084 WMITLV_GET_STRUCT_TLVLEN( 4085 wmi_dcc_channel_stats_request)); 4086 4087 /* Send the WMI command */ 4088 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4089 WMI_DCC_GET_STATS_CMDID); 4090 4091 if (QDF_IS_STATUS_ERROR(ret)) { 4092 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4093 wmi_buf_free(buf); 4094 } 4095 4096 return ret; 4097 } 4098 4099 /** 4100 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4101 * @wmi_handle: pointer to the wmi handle 4102 * @vdev_id: vdev id 4103 * @dcc_stats_bitmap: dcc status bitmap 4104 * 4105 * Return: 0 on succes 4106 */ 4107 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4108 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4109 { 4110 QDF_STATUS ret; 4111 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4112 wmi_buf_t buf; 4113 uint8_t *buf_ptr; 4114 uint32_t len; 4115 4116 /* Allocate memory for the WMI command */ 4117 len = sizeof(*cmd); 4118 4119 buf = wmi_buf_alloc(wmi_handle, len); 4120 if (!buf) { 4121 WMI_LOGE(FL("wmi_buf_alloc failed")); 4122 return QDF_STATUS_E_NOMEM; 4123 } 4124 4125 buf_ptr = wmi_buf_data(buf); 4126 qdf_mem_zero(buf_ptr, len); 4127 4128 /* Populate the WMI command */ 4129 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4130 4131 WMITLV_SET_HDR(&cmd->tlv_header, 4132 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4133 WMITLV_GET_STRUCT_TLVLEN( 4134 wmi_dcc_clear_stats_cmd_fixed_param)); 4135 cmd->vdev_id = vdev_id; 4136 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4137 4138 /* Send the WMI command */ 4139 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4140 WMI_DCC_CLEAR_STATS_CMDID); 4141 if (QDF_IS_STATUS_ERROR(ret)) { 4142 WMI_LOGE(FL("Failed to send the WMI command")); 4143 wmi_buf_free(buf); 4144 } 4145 4146 return ret; 4147 } 4148 4149 /** 4150 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4151 * @wmi_handle: pointer to the wmi handle 4152 * @update_ndl_param: pointer to the request parameters 4153 * 4154 * Return: 0 on success 4155 */ 4156 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4157 struct ocb_dcc_update_ndl_param *update_ndl_param) 4158 { 4159 QDF_STATUS qdf_status; 4160 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4161 wmi_dcc_ndl_chan *ndl_chan_array; 4162 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4163 uint32_t active_state_count; 4164 wmi_buf_t buf; 4165 uint8_t *buf_ptr; 4166 uint32_t len; 4167 uint32_t i; 4168 4169 /* validate the input */ 4170 if (update_ndl_param->dcc_ndl_chan_list_len != 4171 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4172 WMI_LOGE(FL("Invalid parameter")); 4173 return QDF_STATUS_E_INVAL; 4174 } 4175 active_state_count = 0; 4176 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4177 for (i = 0; i < update_ndl_param->channel_count; i++) 4178 active_state_count += 4179 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4180 if (update_ndl_param->dcc_ndl_active_state_list_len != 4181 active_state_count * sizeof(*ndl_active_state_array)) { 4182 WMI_LOGE(FL("Invalid parameter")); 4183 return QDF_STATUS_E_INVAL; 4184 } 4185 4186 /* Allocate memory for the WMI command */ 4187 len = sizeof(*cmd) + 4188 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4189 WMI_TLV_HDR_SIZE + 4190 update_ndl_param->dcc_ndl_active_state_list_len; 4191 4192 buf = wmi_buf_alloc(wmi_handle, len); 4193 if (!buf) { 4194 WMI_LOGE(FL("wmi_buf_alloc failed")); 4195 return QDF_STATUS_E_NOMEM; 4196 } 4197 4198 buf_ptr = wmi_buf_data(buf); 4199 qdf_mem_zero(buf_ptr, len); 4200 4201 /* Populate the WMI command */ 4202 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4203 buf_ptr += sizeof(*cmd); 4204 4205 WMITLV_SET_HDR(&cmd->tlv_header, 4206 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4207 WMITLV_GET_STRUCT_TLVLEN( 4208 wmi_dcc_update_ndl_cmd_fixed_param)); 4209 cmd->vdev_id = update_ndl_param->vdev_id; 4210 cmd->num_channel = update_ndl_param->channel_count; 4211 4212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4213 update_ndl_param->dcc_ndl_chan_list_len); 4214 buf_ptr += WMI_TLV_HDR_SIZE; 4215 4216 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4217 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4218 update_ndl_param->dcc_ndl_chan_list_len); 4219 for (i = 0; i < cmd->num_channel; i++) 4220 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4221 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4222 WMITLV_GET_STRUCT_TLVLEN( 4223 wmi_dcc_ndl_chan)); 4224 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4225 4226 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4227 update_ndl_param->dcc_ndl_active_state_list_len); 4228 buf_ptr += WMI_TLV_HDR_SIZE; 4229 4230 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4231 qdf_mem_copy(ndl_active_state_array, 4232 update_ndl_param->dcc_ndl_active_state_list, 4233 update_ndl_param->dcc_ndl_active_state_list_len); 4234 for (i = 0; i < active_state_count; i++) { 4235 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4236 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4237 WMITLV_GET_STRUCT_TLVLEN( 4238 wmi_dcc_ndl_active_state_config)); 4239 } 4240 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4241 4242 /* Send the WMI command */ 4243 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4244 WMI_DCC_UPDATE_NDL_CMDID); 4245 /* If there is an error, set the completion event */ 4246 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4247 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4248 wmi_buf_free(buf); 4249 } 4250 4251 return qdf_status; 4252 } 4253 4254 /** 4255 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4256 * @wmi_handle: pointer to the wmi handle 4257 * @config: the OCB configuration 4258 * 4259 * Return: 0 on success 4260 */ 4261 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4262 struct ocb_config *config) 4263 { 4264 QDF_STATUS ret; 4265 wmi_ocb_set_config_cmd_fixed_param *cmd; 4266 wmi_channel *chan; 4267 wmi_ocb_channel *ocb_chan; 4268 wmi_qos_parameter *qos_param; 4269 wmi_dcc_ndl_chan *ndl_chan; 4270 wmi_dcc_ndl_active_state_config *ndl_active_config; 4271 wmi_ocb_schedule_element *sched_elem; 4272 uint8_t *buf_ptr; 4273 wmi_buf_t buf; 4274 int32_t len; 4275 int32_t i, j, active_state_count; 4276 4277 /* 4278 * Validate the dcc_ndl_chan_list_len and count the number of active 4279 * states. Validate dcc_ndl_active_state_list_len. 4280 */ 4281 active_state_count = 0; 4282 if (config->dcc_ndl_chan_list_len) { 4283 if (!config->dcc_ndl_chan_list || 4284 config->dcc_ndl_chan_list_len != 4285 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4286 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4287 config->dcc_ndl_chan_list_len); 4288 return QDF_STATUS_E_INVAL; 4289 } 4290 4291 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4292 i < config->channel_count; ++i, ++ndl_chan) 4293 active_state_count += 4294 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4295 4296 if (active_state_count) { 4297 if (!config->dcc_ndl_active_state_list || 4298 config->dcc_ndl_active_state_list_len != 4299 active_state_count * 4300 sizeof(wmi_dcc_ndl_active_state_config)) { 4301 WMI_LOGE(FL("NDL active state is invalid.")); 4302 return QDF_STATUS_E_INVAL; 4303 } 4304 } 4305 } 4306 4307 len = sizeof(*cmd) + 4308 WMI_TLV_HDR_SIZE + config->channel_count * 4309 sizeof(wmi_channel) + 4310 WMI_TLV_HDR_SIZE + config->channel_count * 4311 sizeof(wmi_ocb_channel) + 4312 WMI_TLV_HDR_SIZE + config->channel_count * 4313 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4314 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4315 WMI_TLV_HDR_SIZE + active_state_count * 4316 sizeof(wmi_dcc_ndl_active_state_config) + 4317 WMI_TLV_HDR_SIZE + config->schedule_size * 4318 sizeof(wmi_ocb_schedule_element); 4319 buf = wmi_buf_alloc(wmi_handle, len); 4320 if (!buf) { 4321 WMI_LOGE(FL("wmi_buf_alloc failed")); 4322 return QDF_STATUS_E_NOMEM; 4323 } 4324 4325 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4326 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4327 WMITLV_SET_HDR(&cmd->tlv_header, 4328 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4329 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4330 cmd->vdev_id = config->vdev_id; 4331 cmd->channel_count = config->channel_count; 4332 cmd->schedule_size = config->schedule_size; 4333 cmd->flags = config->flags; 4334 buf_ptr += sizeof(*cmd); 4335 4336 /* Add the wmi_channel info */ 4337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4338 config->channel_count*sizeof(wmi_channel)); 4339 buf_ptr += WMI_TLV_HDR_SIZE; 4340 for (i = 0; i < config->channel_count; i++) { 4341 chan = (wmi_channel *)buf_ptr; 4342 WMITLV_SET_HDR(&chan->tlv_header, 4343 WMITLV_TAG_STRUC_wmi_channel, 4344 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4345 chan->mhz = config->channels[i].chan_freq; 4346 chan->band_center_freq1 = config->channels[i].chan_freq; 4347 chan->band_center_freq2 = 0; 4348 chan->info = 0; 4349 4350 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4351 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4352 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4353 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4354 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4355 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4356 config->channels[i].antenna_max); 4357 4358 if (config->channels[i].bandwidth < 10) 4359 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4360 else if (config->channels[i].bandwidth < 20) 4361 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4362 buf_ptr += sizeof(*chan); 4363 } 4364 4365 /* Add the wmi_ocb_channel info */ 4366 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4367 config->channel_count*sizeof(wmi_ocb_channel)); 4368 buf_ptr += WMI_TLV_HDR_SIZE; 4369 for (i = 0; i < config->channel_count; i++) { 4370 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4371 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4372 WMITLV_TAG_STRUC_wmi_ocb_channel, 4373 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4374 ocb_chan->bandwidth = config->channels[i].bandwidth; 4375 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4376 config->channels[i].mac_address.bytes, 4377 &ocb_chan->mac_address); 4378 buf_ptr += sizeof(*ocb_chan); 4379 } 4380 4381 /* Add the wmi_qos_parameter info */ 4382 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4383 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4384 buf_ptr += WMI_TLV_HDR_SIZE; 4385 /* WMI_MAX_NUM_AC parameters for each channel */ 4386 for (i = 0; i < config->channel_count; i++) { 4387 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4388 qos_param = (wmi_qos_parameter *)buf_ptr; 4389 WMITLV_SET_HDR(&qos_param->tlv_header, 4390 WMITLV_TAG_STRUC_wmi_qos_parameter, 4391 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4392 qos_param->aifsn = 4393 config->channels[i].qos_params[j].aifsn; 4394 qos_param->cwmin = 4395 config->channels[i].qos_params[j].cwmin; 4396 qos_param->cwmax = 4397 config->channels[i].qos_params[j].cwmax; 4398 buf_ptr += sizeof(*qos_param); 4399 } 4400 } 4401 4402 /* Add the wmi_dcc_ndl_chan (per channel) */ 4403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4404 config->dcc_ndl_chan_list_len); 4405 buf_ptr += WMI_TLV_HDR_SIZE; 4406 if (config->dcc_ndl_chan_list_len) { 4407 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4408 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4409 config->dcc_ndl_chan_list_len); 4410 for (i = 0; i < config->channel_count; i++) 4411 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4412 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4413 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4414 buf_ptr += config->dcc_ndl_chan_list_len; 4415 } 4416 4417 /* Add the wmi_dcc_ndl_active_state_config */ 4418 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4419 sizeof(wmi_dcc_ndl_active_state_config)); 4420 buf_ptr += WMI_TLV_HDR_SIZE; 4421 if (active_state_count) { 4422 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4423 qdf_mem_copy(ndl_active_config, 4424 config->dcc_ndl_active_state_list, 4425 active_state_count * sizeof(*ndl_active_config)); 4426 for (i = 0; i < active_state_count; ++i) 4427 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4428 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4429 WMITLV_GET_STRUCT_TLVLEN( 4430 wmi_dcc_ndl_active_state_config)); 4431 buf_ptr += active_state_count * 4432 sizeof(*ndl_active_config); 4433 } 4434 4435 /* Add the wmi_ocb_schedule_element info */ 4436 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4437 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4438 buf_ptr += WMI_TLV_HDR_SIZE; 4439 for (i = 0; i < config->schedule_size; i++) { 4440 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4441 WMITLV_SET_HDR(&sched_elem->tlv_header, 4442 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4443 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4444 sched_elem->channel_freq = config->schedule[i].chan_freq; 4445 sched_elem->total_duration = config->schedule[i].total_duration; 4446 sched_elem->guard_interval = config->schedule[i].guard_interval; 4447 buf_ptr += sizeof(*sched_elem); 4448 } 4449 4450 4451 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4452 WMI_OCB_SET_CONFIG_CMDID); 4453 if (QDF_IS_STATUS_ERROR(ret)) { 4454 WMI_LOGE("Failed to set OCB config"); 4455 wmi_buf_free(buf); 4456 } 4457 4458 return ret; 4459 } 4460 4461 /** 4462 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4463 * @wmi_handle: wmi handle 4464 * @evt_buf: wmi event buffer 4465 * @status: status buffer 4466 * 4467 * Return: QDF_STATUS_SUCCESS on success 4468 */ 4469 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4470 void *evt_buf, 4471 uint32_t *status) 4472 { 4473 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4474 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4475 4476 param_tlvs = evt_buf; 4477 fix_param = param_tlvs->fixed_param; 4478 4479 *status = fix_param->status; 4480 return QDF_STATUS_SUCCESS; 4481 } 4482 4483 /** 4484 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4485 * @wmi_handle: wmi handle 4486 * @evt_buf: wmi event buffer 4487 * @resp: response buffer 4488 * 4489 * Return: QDF_STATUS_SUCCESS on success 4490 */ 4491 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4492 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4493 { 4494 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4495 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4496 4497 param_tlvs = evt_buf; 4498 fix_param = param_tlvs->fixed_param; 4499 resp->vdev_id = fix_param->vdev_id; 4500 resp->timer_high = fix_param->tsf_timer_high; 4501 resp->timer_low = fix_param->tsf_timer_low; 4502 4503 return QDF_STATUS_SUCCESS; 4504 } 4505 4506 /** 4507 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4508 * @wmi_handle: wmi handle 4509 * @evt_buf: wmi event buffer 4510 * @resp: response buffer 4511 * 4512 * Return: QDF_STATUS_SUCCESS on success 4513 */ 4514 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4515 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4516 { 4517 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4518 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4519 4520 param_tlvs = evt_buf; 4521 fix_param = param_tlvs->fixed_param; 4522 resp->vdev_id = fix_param->vdev_id; 4523 resp->status = fix_param->status; 4524 return QDF_STATUS_SUCCESS; 4525 } 4526 4527 /** 4528 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4529 * @wmi_handle: wmi handle 4530 * @evt_buf: wmi event buffer 4531 * @resp: response buffer 4532 * 4533 * Since length of stats is variable, buffer for DCC stats will be allocated 4534 * in this function. The caller must free the buffer. 4535 * 4536 * Return: QDF_STATUS_SUCCESS on success 4537 */ 4538 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4539 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4540 { 4541 struct ocb_dcc_get_stats_response *response; 4542 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4543 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4544 4545 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4546 fix_param = param_tlvs->fixed_param; 4547 4548 /* Allocate and populate the response */ 4549 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4550 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4551 WMI_LOGE("%s: too many channels:%d", __func__, 4552 fix_param->num_channels); 4553 QDF_ASSERT(0); 4554 *resp = NULL; 4555 return QDF_STATUS_E_INVAL; 4556 } 4557 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4558 sizeof(wmi_dcc_ndl_stats_per_channel)); 4559 *resp = response; 4560 if (!response) 4561 return QDF_STATUS_E_NOMEM; 4562 4563 response->vdev_id = fix_param->vdev_id; 4564 response->num_channels = fix_param->num_channels; 4565 response->channel_stats_array_len = 4566 fix_param->num_channels * 4567 sizeof(wmi_dcc_ndl_stats_per_channel); 4568 response->channel_stats_array = ((uint8_t *)response) + 4569 sizeof(*response); 4570 qdf_mem_copy(response->channel_stats_array, 4571 param_tlvs->stats_per_channel_list, 4572 response->channel_stats_array_len); 4573 4574 return QDF_STATUS_SUCCESS; 4575 } 4576 #endif 4577 4578 /** 4579 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4580 * @wmi_handle: wmi handle 4581 * @mcc_adaptive_scheduler: enable/disable 4582 * 4583 * This function enable/disable mcc adaptive scheduler in fw. 4584 * 4585 * Return: QDF_STATUS_SUCCESS for sucess or error code 4586 */ 4587 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4588 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4589 uint32_t pdev_id) 4590 { 4591 QDF_STATUS ret; 4592 wmi_buf_t buf = 0; 4593 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4594 uint16_t len = 4595 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4596 4597 buf = wmi_buf_alloc(wmi_handle, len); 4598 if (!buf) { 4599 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4600 return QDF_STATUS_E_NOMEM; 4601 } 4602 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4603 wmi_buf_data(buf); 4604 4605 WMITLV_SET_HDR(&cmd->tlv_header, 4606 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4607 WMITLV_GET_STRUCT_TLVLEN 4608 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4609 cmd->enable = mcc_adaptive_scheduler; 4610 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4611 4612 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4613 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4614 if (QDF_IS_STATUS_ERROR(ret)) { 4615 WMI_LOGP("%s: Failed to send enable/disable MCC" 4616 " adaptive scheduler command", __func__); 4617 wmi_buf_free(buf); 4618 } 4619 4620 return ret; 4621 } 4622 4623 /** 4624 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4625 * @wmi: wmi handle 4626 * @mcc_channel: mcc channel 4627 * @mcc_channel_time_latency: MCC channel time latency. 4628 * 4629 * Currently used to set time latency for an MCC vdev/adapter using operating 4630 * channel of it and channel number. The info is provided run time using 4631 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4632 * 4633 * Return: CDF status 4634 */ 4635 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4636 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4637 { 4638 QDF_STATUS ret; 4639 wmi_buf_t buf = 0; 4640 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4641 uint16_t len = 0; 4642 uint8_t *buf_ptr = NULL; 4643 wmi_resmgr_chan_latency chan_latency; 4644 /* Note: we only support MCC time latency for a single channel */ 4645 uint32_t num_channels = 1; 4646 uint32_t chan1_freq = mcc_channel_freq; 4647 uint32_t latency_chan1 = mcc_channel_time_latency; 4648 4649 4650 /* If 0ms latency is provided, then FW will set to a default. 4651 * Otherwise, latency must be at least 30ms. 4652 */ 4653 if ((latency_chan1 > 0) && 4654 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4655 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4656 "Minimum is 30ms (or 0 to use default value by " 4657 "firmware)", __func__, latency_chan1); 4658 return QDF_STATUS_E_INVAL; 4659 } 4660 4661 /* Set WMI CMD for channel time latency here */ 4662 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4663 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4664 num_channels * sizeof(wmi_resmgr_chan_latency); 4665 buf = wmi_buf_alloc(wmi_handle, len); 4666 if (!buf) { 4667 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4668 return QDF_STATUS_E_NOMEM; 4669 } 4670 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4671 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4672 wmi_buf_data(buf); 4673 WMITLV_SET_HDR(&cmdTL->tlv_header, 4674 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4675 WMITLV_GET_STRUCT_TLVLEN 4676 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4677 cmdTL->num_chans = num_channels; 4678 /* Update channel time latency information for home channel(s) */ 4679 buf_ptr += sizeof(*cmdTL); 4680 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4681 num_channels * sizeof(wmi_resmgr_chan_latency)); 4682 buf_ptr += WMI_TLV_HDR_SIZE; 4683 chan_latency.chan_mhz = chan1_freq; 4684 chan_latency.latency = latency_chan1; 4685 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4686 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4687 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4688 if (QDF_IS_STATUS_ERROR(ret)) { 4689 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4690 __func__); 4691 wmi_buf_free(buf); 4692 QDF_ASSERT(0); 4693 } 4694 4695 return ret; 4696 } 4697 4698 /** 4699 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4700 * @wmi: wmi handle 4701 * @adapter_1_chan_number: adapter 1 channel number 4702 * @adapter_1_quota: adapter 1 quota 4703 * @adapter_2_chan_number: adapter 2 channel number 4704 * 4705 * Return: CDF status 4706 */ 4707 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4708 uint32_t adapter_1_chan_freq, 4709 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4710 { 4711 QDF_STATUS ret; 4712 wmi_buf_t buf = 0; 4713 uint16_t len = 0; 4714 uint8_t *buf_ptr = NULL; 4715 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4716 wmi_resmgr_chan_time_quota chan_quota; 4717 uint32_t quota_chan1 = adapter_1_quota; 4718 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4719 uint32_t quota_chan2 = 100 - quota_chan1; 4720 /* Note: setting time quota for MCC requires info for 2 channels */ 4721 uint32_t num_channels = 2; 4722 uint32_t chan1_freq = adapter_1_chan_freq; 4723 uint32_t chan2_freq = adapter_2_chan_freq; 4724 4725 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4726 "freq2:%dMHz, Quota2:%dms", __func__, 4727 chan1_freq, quota_chan1, chan2_freq, 4728 quota_chan2); 4729 4730 /* 4731 * Perform sanity check on time quota values provided. 4732 */ 4733 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4734 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4735 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4736 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4737 return QDF_STATUS_E_INVAL; 4738 } 4739 /* Set WMI CMD for channel time quota here */ 4740 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4741 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4742 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4743 buf = wmi_buf_alloc(wmi_handle, len); 4744 if (!buf) { 4745 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4746 QDF_ASSERT(0); 4747 return QDF_STATUS_E_NOMEM; 4748 } 4749 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4750 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4751 wmi_buf_data(buf); 4752 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4753 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4754 WMITLV_GET_STRUCT_TLVLEN 4755 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4756 cmdTQ->num_chans = num_channels; 4757 4758 /* Update channel time quota information for home channel(s) */ 4759 buf_ptr += sizeof(*cmdTQ); 4760 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4761 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4762 buf_ptr += WMI_TLV_HDR_SIZE; 4763 chan_quota.chan_mhz = chan1_freq; 4764 chan_quota.channel_time_quota = quota_chan1; 4765 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4766 /* Construct channel and quota record for the 2nd MCC mode. */ 4767 buf_ptr += sizeof(chan_quota); 4768 chan_quota.chan_mhz = chan2_freq; 4769 chan_quota.channel_time_quota = quota_chan2; 4770 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4771 4772 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4773 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4774 if (QDF_IS_STATUS_ERROR(ret)) { 4775 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4776 wmi_buf_free(buf); 4777 QDF_ASSERT(0); 4778 } 4779 4780 return ret; 4781 } 4782 4783 /** 4784 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4785 * @wmi_handle: Pointer to wmi handle 4786 * @thermal_info: Thermal command information 4787 * 4788 * This function sends the thermal management command 4789 * to the firmware 4790 * 4791 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4792 */ 4793 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4794 struct thermal_cmd_params *thermal_info) 4795 { 4796 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4797 wmi_buf_t buf = NULL; 4798 QDF_STATUS status; 4799 uint32_t len = 0; 4800 4801 len = sizeof(*cmd); 4802 4803 buf = wmi_buf_alloc(wmi_handle, len); 4804 if (!buf) { 4805 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4806 return QDF_STATUS_E_FAILURE; 4807 } 4808 4809 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4810 4811 WMITLV_SET_HDR(&cmd->tlv_header, 4812 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4813 WMITLV_GET_STRUCT_TLVLEN 4814 (wmi_thermal_mgmt_cmd_fixed_param)); 4815 4816 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4817 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4818 cmd->enable = thermal_info->thermal_enable; 4819 4820 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4821 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4822 4823 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4824 WMI_THERMAL_MGMT_CMDID); 4825 if (QDF_IS_STATUS_ERROR(status)) { 4826 wmi_buf_free(buf); 4827 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4828 } 4829 4830 return status; 4831 } 4832 4833 4834 /** 4835 * send_lro_config_cmd_tlv() - process the LRO config command 4836 * @wmi_handle: Pointer to WMI handle 4837 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4838 * 4839 * This function sends down the LRO configuration parameters to 4840 * the firmware to enable LRO, sets the TCP flags and sets the 4841 * seed values for the toeplitz hash generation 4842 * 4843 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4844 */ 4845 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4846 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4847 { 4848 wmi_lro_info_cmd_fixed_param *cmd; 4849 wmi_buf_t buf; 4850 QDF_STATUS status; 4851 4852 4853 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4854 if (!buf) { 4855 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4856 return QDF_STATUS_E_FAILURE; 4857 } 4858 4859 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4860 4861 WMITLV_SET_HDR(&cmd->tlv_header, 4862 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4863 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4864 4865 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4866 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4867 wmi_lro_cmd->tcp_flag); 4868 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4869 wmi_lro_cmd->tcp_flag_mask); 4870 cmd->toeplitz_hash_ipv4_0_3 = 4871 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4872 cmd->toeplitz_hash_ipv4_4_7 = 4873 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4874 cmd->toeplitz_hash_ipv4_8_11 = 4875 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4876 cmd->toeplitz_hash_ipv4_12_15 = 4877 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4878 cmd->toeplitz_hash_ipv4_16 = 4879 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4880 4881 cmd->toeplitz_hash_ipv6_0_3 = 4882 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4883 cmd->toeplitz_hash_ipv6_4_7 = 4884 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4885 cmd->toeplitz_hash_ipv6_8_11 = 4886 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4887 cmd->toeplitz_hash_ipv6_12_15 = 4888 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4889 cmd->toeplitz_hash_ipv6_16_19 = 4890 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4891 cmd->toeplitz_hash_ipv6_20_23 = 4892 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4893 cmd->toeplitz_hash_ipv6_24_27 = 4894 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4895 cmd->toeplitz_hash_ipv6_28_31 = 4896 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4897 cmd->toeplitz_hash_ipv6_32_35 = 4898 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4899 cmd->toeplitz_hash_ipv6_36_39 = 4900 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4901 cmd->toeplitz_hash_ipv6_40 = 4902 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4903 4904 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 4905 cmd->lro_enable, cmd->tcp_flag_u32); 4906 4907 status = wmi_unified_cmd_send(wmi_handle, buf, 4908 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4909 if (QDF_IS_STATUS_ERROR(status)) { 4910 wmi_buf_free(buf); 4911 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4912 } 4913 4914 return status; 4915 } 4916 4917 /** 4918 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4919 * @wmi_handle: Pointer to wmi handle 4920 * @rate_report_params: Pointer to peer rate report parameters 4921 * 4922 * 4923 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4924 */ 4925 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4926 struct wmi_peer_rate_report_params *rate_report_params) 4927 { 4928 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4929 wmi_buf_t buf = NULL; 4930 QDF_STATUS status = 0; 4931 uint32_t len = 0; 4932 uint32_t i, j; 4933 4934 len = sizeof(*cmd); 4935 4936 buf = wmi_buf_alloc(wmi_handle, len); 4937 if (!buf) { 4938 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 4939 return QDF_STATUS_E_FAILURE; 4940 } 4941 4942 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4943 wmi_buf_data(buf); 4944 4945 WMITLV_SET_HDR( 4946 &cmd->tlv_header, 4947 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4948 WMITLV_GET_STRUCT_TLVLEN( 4949 wmi_peer_set_rate_report_condition_fixed_param)); 4950 4951 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4952 cmd->report_backoff_time = rate_report_params->backoff_time; 4953 cmd->report_timer_period = rate_report_params->timer_period; 4954 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4955 cmd->cond_per_phy[i].val_cond_flags = 4956 rate_report_params->report_per_phy[i].cond_flags; 4957 cmd->cond_per_phy[i].rate_delta.min_delta = 4958 rate_report_params->report_per_phy[i].delta.delta_min; 4959 cmd->cond_per_phy[i].rate_delta.percentage = 4960 rate_report_params->report_per_phy[i].delta.percent; 4961 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4962 cmd->cond_per_phy[i].rate_threshold[j] = 4963 rate_report_params->report_per_phy[i]. 4964 report_rate_threshold[j]; 4965 } 4966 } 4967 4968 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 4969 cmd->enable_rate_report, 4970 cmd->report_backoff_time, cmd->report_timer_period); 4971 4972 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4973 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4974 if (QDF_IS_STATUS_ERROR(status)) { 4975 wmi_buf_free(buf); 4976 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4977 __func__); 4978 } 4979 return status; 4980 } 4981 4982 /** 4983 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 4984 * @wmi_handle: wmi handle 4985 * @param: bcn ll cmd parameter 4986 * 4987 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4988 */ 4989 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 4990 wmi_bcn_send_from_host_cmd_fixed_param *param) 4991 { 4992 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 4993 wmi_buf_t wmi_buf; 4994 QDF_STATUS ret; 4995 4996 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4997 if (!wmi_buf) { 4998 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 4999 return QDF_STATUS_E_FAILURE; 5000 } 5001 5002 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 5003 WMITLV_SET_HDR(&cmd->tlv_header, 5004 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 5005 WMITLV_GET_STRUCT_TLVLEN 5006 (wmi_bcn_send_from_host_cmd_fixed_param)); 5007 cmd->vdev_id = param->vdev_id; 5008 cmd->data_len = param->data_len; 5009 cmd->frame_ctrl = param->frame_ctrl; 5010 cmd->frag_ptr = param->frag_ptr; 5011 cmd->dtim_flag = param->dtim_flag; 5012 5013 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 5014 WMI_PDEV_SEND_BCN_CMDID); 5015 5016 if (QDF_IS_STATUS_ERROR(ret)) { 5017 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 5018 wmi_buf_free(wmi_buf); 5019 } 5020 5021 return ret; 5022 } 5023 5024 /** 5025 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 5026 * @wmi_handle: wmi handle 5027 * @vdev_id: vdev id 5028 * @max_retries: max retries 5029 * @retry_interval: retry interval 5030 * This function sets sta query related parameters in fw. 5031 * 5032 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5033 */ 5034 5035 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 5036 uint8_t vdev_id, uint32_t max_retries, 5037 uint32_t retry_interval) 5038 { 5039 wmi_buf_t buf; 5040 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 5041 int len; 5042 5043 len = sizeof(*cmd); 5044 buf = wmi_buf_alloc(wmi_handle, len); 5045 if (!buf) { 5046 WMI_LOGE(FL("wmi_buf_alloc failed")); 5047 return QDF_STATUS_E_FAILURE; 5048 } 5049 5050 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5051 WMITLV_SET_HDR(&cmd->tlv_header, 5052 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5053 WMITLV_GET_STRUCT_TLVLEN 5054 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5055 5056 5057 cmd->vdev_id = vdev_id; 5058 cmd->sa_query_max_retry_count = max_retries; 5059 cmd->sa_query_retry_interval = retry_interval; 5060 5061 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5062 vdev_id, retry_interval, max_retries); 5063 5064 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5065 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5066 WMI_LOGE(FL("Failed to offload STA SA Query")); 5067 wmi_buf_free(buf); 5068 return QDF_STATUS_E_FAILURE; 5069 } 5070 5071 WMI_LOGD(FL("Exit :")); 5072 return 0; 5073 } 5074 5075 /** 5076 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5077 * @wmi_handle: wmi handle 5078 * @params: sta keep alive parameter 5079 * 5080 * This function sets keep alive related parameters in fw. 5081 * 5082 * Return: CDF status 5083 */ 5084 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5085 struct sta_params *params) 5086 { 5087 wmi_buf_t buf; 5088 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5089 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5090 uint8_t *buf_ptr; 5091 int len; 5092 QDF_STATUS ret; 5093 5094 WMI_LOGD("%s: Enter", __func__); 5095 5096 len = sizeof(*cmd) + sizeof(*arp_rsp); 5097 buf = wmi_buf_alloc(wmi_handle, len); 5098 if (!buf) { 5099 WMI_LOGE("wmi_buf_alloc failed"); 5100 return QDF_STATUS_E_FAILURE; 5101 } 5102 5103 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5104 buf_ptr = (uint8_t *) cmd; 5105 WMITLV_SET_HDR(&cmd->tlv_header, 5106 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5107 WMITLV_GET_STRUCT_TLVLEN 5108 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5109 cmd->interval = params->timeperiod; 5110 cmd->enable = (params->timeperiod) ? 1 : 0; 5111 cmd->vdev_id = params->vdev_id; 5112 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5113 params->timeperiod, params->method); 5114 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5115 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5116 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5117 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5118 5119 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5120 (params->method == 5121 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5122 if ((NULL == params->hostv4addr) || 5123 (NULL == params->destv4addr) || 5124 (NULL == params->destmac)) { 5125 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5126 "destv4addr:%pK destmac:%pK ", __func__, 5127 params->hostv4addr, params->destv4addr, params->destmac); 5128 wmi_buf_free(buf); 5129 return QDF_STATUS_E_FAILURE; 5130 } 5131 cmd->method = params->method; 5132 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5133 WMI_IPV4_ADDR_LEN); 5134 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5135 WMI_IPV4_ADDR_LEN); 5136 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5137 } else { 5138 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5139 } 5140 5141 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5142 WMI_STA_KEEPALIVE_CMDID); 5143 if (QDF_IS_STATUS_ERROR(ret)) { 5144 WMI_LOGE("Failed to set KeepAlive"); 5145 wmi_buf_free(buf); 5146 } 5147 5148 WMI_LOGD("%s: Exit", __func__); 5149 return ret; 5150 } 5151 5152 /** 5153 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5154 * @wmi_handle: wmi handle 5155 * @if_id: vdev id 5156 * @gtx_info: GTX config params 5157 * 5158 * This function set GTX related params in firmware. 5159 * 5160 * Return: QDF_STATUS_SUCCESS for success or error code 5161 */ 5162 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5163 struct wmi_gtx_config *gtx_info) 5164 { 5165 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5166 wmi_buf_t buf; 5167 QDF_STATUS ret; 5168 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5169 5170 buf = wmi_buf_alloc(wmi_handle, len); 5171 if (!buf) { 5172 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5173 return QDF_STATUS_E_NOMEM; 5174 } 5175 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5176 WMITLV_SET_HDR(&cmd->tlv_header, 5177 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5178 WMITLV_GET_STRUCT_TLVLEN 5179 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5180 cmd->vdev_id = if_id; 5181 5182 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5183 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5184 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5185 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5186 cmd->gtxPERMargin = gtx_info->gtx_margin; 5187 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5188 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5189 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5190 5191 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5192 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5193 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5194 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5195 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5196 5197 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5198 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5199 if (QDF_IS_STATUS_ERROR(ret)) { 5200 WMI_LOGE("Failed to set GTX PARAMS"); 5201 wmi_buf_free(buf); 5202 } 5203 return ret; 5204 } 5205 5206 /** 5207 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5208 * @wmi_handle: wmi handle 5209 * @vdev_id: vdev id. 5210 * @wmm_vparams: edca parameters 5211 * 5212 * This function updates EDCA parameters to the target 5213 * 5214 * Return: CDF Status 5215 */ 5216 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5217 uint8_t vdev_id, 5218 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5219 { 5220 uint8_t *buf_ptr; 5221 wmi_buf_t buf; 5222 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5223 wmi_wmm_vparams *wmm_param; 5224 struct wmi_host_wme_vparams *twmm_param; 5225 int len = sizeof(*cmd); 5226 int ac; 5227 5228 buf = wmi_buf_alloc(wmi_handle, len); 5229 5230 if (!buf) { 5231 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5232 return QDF_STATUS_E_NOMEM; 5233 } 5234 5235 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5236 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5237 WMITLV_SET_HDR(&cmd->tlv_header, 5238 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5239 WMITLV_GET_STRUCT_TLVLEN 5240 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5241 cmd->vdev_id = vdev_id; 5242 5243 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5244 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5245 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5246 WMITLV_SET_HDR(&wmm_param->tlv_header, 5247 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5248 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5249 wmm_param->cwmin = twmm_param->cwmin; 5250 wmm_param->cwmax = twmm_param->cwmax; 5251 wmm_param->aifs = twmm_param->aifs; 5252 wmm_param->txoplimit = twmm_param->txoplimit; 5253 wmm_param->acm = twmm_param->acm; 5254 wmm_param->no_ack = twmm_param->noackpolicy; 5255 } 5256 5257 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5258 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5259 goto fail; 5260 5261 return QDF_STATUS_SUCCESS; 5262 5263 fail: 5264 wmi_buf_free(buf); 5265 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5266 return QDF_STATUS_E_FAILURE; 5267 } 5268 5269 /** 5270 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5271 * @wmi_handle: wmi handle 5272 * @vdev_id: vdev id 5273 * @probe_rsp_info: probe response info 5274 * 5275 * Return: QDF_STATUS_SUCCESS for success or error code 5276 */ 5277 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5278 uint8_t vdev_id, 5279 struct wmi_probe_resp_params *probe_rsp_info) 5280 { 5281 wmi_prb_tmpl_cmd_fixed_param *cmd; 5282 wmi_bcn_prb_info *bcn_prb_info; 5283 wmi_buf_t wmi_buf; 5284 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5285 uint8_t *buf_ptr; 5286 QDF_STATUS ret; 5287 5288 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5289 5290 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5291 tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32)); 5292 5293 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5294 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5295 tmpl_len_aligned; 5296 5297 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5298 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5299 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5300 return QDF_STATUS_E_INVAL; 5301 } 5302 5303 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5304 if (!wmi_buf) { 5305 WMI_LOGE(FL("wmi_buf_alloc failed")); 5306 return QDF_STATUS_E_NOMEM; 5307 } 5308 5309 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5310 5311 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5312 WMITLV_SET_HDR(&cmd->tlv_header, 5313 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5314 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5315 cmd->vdev_id = vdev_id; 5316 cmd->buf_len = tmpl_len; 5317 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5318 5319 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5320 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5321 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5322 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5323 bcn_prb_info->caps = 0; 5324 bcn_prb_info->erp = 0; 5325 buf_ptr += sizeof(wmi_bcn_prb_info); 5326 5327 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5328 buf_ptr += WMI_TLV_HDR_SIZE; 5329 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5330 5331 ret = wmi_unified_cmd_send(wmi_handle, 5332 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5333 if (QDF_IS_STATUS_ERROR(ret)) { 5334 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5335 wmi_buf_free(wmi_buf); 5336 } 5337 5338 return ret; 5339 } 5340 5341 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5342 #define WPI_IV_LEN 16 5343 5344 /** 5345 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5346 * 5347 * @dest_tx: destination address of tsc key counter 5348 * @src_tx: source address of tsc key counter 5349 * @dest_rx: destination address of rsc key counter 5350 * @src_rx: source address of rsc key counter 5351 * 5352 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5353 * 5354 * Return: None 5355 * 5356 */ 5357 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5358 uint8_t *dest_rx, uint8_t *src_rx) 5359 { 5360 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5361 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5362 } 5363 #else 5364 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5365 uint8_t *dest_rx, uint8_t *src_rx) 5366 { 5367 return; 5368 } 5369 #endif 5370 5371 /** 5372 * send_setup_install_key_cmd_tlv() - set key parameters 5373 * @wmi_handle: wmi handle 5374 * @key_params: key parameters 5375 * 5376 * This function fills structure from information 5377 * passed in key_params. 5378 * 5379 * Return: QDF_STATUS_SUCCESS - success 5380 * QDF_STATUS_E_FAILURE - failure 5381 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5382 */ 5383 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5384 struct set_key_params *key_params) 5385 { 5386 wmi_vdev_install_key_cmd_fixed_param *cmd; 5387 wmi_buf_t buf; 5388 uint8_t *buf_ptr; 5389 uint32_t len; 5390 uint8_t *key_data; 5391 QDF_STATUS status; 5392 5393 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5394 WMI_TLV_HDR_SIZE; 5395 5396 buf = wmi_buf_alloc(wmi_handle, len); 5397 if (!buf) { 5398 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5399 return QDF_STATUS_E_NOMEM; 5400 } 5401 5402 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5403 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5404 WMITLV_SET_HDR(&cmd->tlv_header, 5405 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5406 WMITLV_GET_STRUCT_TLVLEN 5407 (wmi_vdev_install_key_cmd_fixed_param)); 5408 cmd->vdev_id = key_params->vdev_id; 5409 cmd->key_ix = key_params->key_idx; 5410 5411 5412 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5413 cmd->key_flags |= key_params->key_flags; 5414 cmd->key_cipher = key_params->key_cipher; 5415 if ((key_params->key_txmic_len) && 5416 (key_params->key_rxmic_len)) { 5417 cmd->key_txmic_len = key_params->key_txmic_len; 5418 cmd->key_rxmic_len = key_params->key_rxmic_len; 5419 } 5420 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5421 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5422 key_params->tx_iv, 5423 cmd->wpi_key_rsc_counter, 5424 key_params->rx_iv); 5425 #endif 5426 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5427 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5428 roundup(key_params->key_len, sizeof(uint32_t))); 5429 key_data = (A_UINT8 *) (buf_ptr + WMI_TLV_HDR_SIZE); 5430 qdf_mem_copy((void *)key_data, 5431 (const void *)key_params->key_data, key_params->key_len); 5432 if (key_params->key_rsc_counter) 5433 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5434 sizeof(wmi_key_seq_counter)); 5435 cmd->key_len = key_params->key_len; 5436 5437 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5438 WMI_VDEV_INSTALL_KEY_CMDID); 5439 if (QDF_IS_STATUS_ERROR(status)) 5440 wmi_buf_free(buf); 5441 5442 return status; 5443 } 5444 5445 /** 5446 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5447 * @wmi_handle: wmi handle 5448 * @params: sar limit params 5449 * 5450 * Return: QDF_STATUS_SUCCESS for success or error code 5451 */ 5452 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5453 struct sar_limit_cmd_params *sar_limit_params) 5454 { 5455 wmi_buf_t buf; 5456 QDF_STATUS qdf_status; 5457 wmi_sar_limits_cmd_fixed_param *cmd; 5458 int i; 5459 uint8_t *buf_ptr; 5460 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5461 struct sar_limit_cmd_row *sar_rows_list; 5462 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5463 5464 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5465 buf = wmi_buf_alloc(wmi_handle, len); 5466 if (!buf) { 5467 WMI_LOGE("Failed to allocate memory"); 5468 qdf_status = QDF_STATUS_E_NOMEM; 5469 goto end; 5470 } 5471 5472 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5473 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5474 WMITLV_SET_HDR(&cmd->tlv_header, 5475 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5476 WMITLV_GET_STRUCT_TLVLEN 5477 (wmi_sar_limits_cmd_fixed_param)); 5478 cmd->sar_enable = sar_limit_params->sar_enable; 5479 cmd->commit_limits = sar_limit_params->commit_limits; 5480 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5481 5482 WMI_LOGD("no of sar rows = %d, len = %d", 5483 sar_limit_params->num_limit_rows, len); 5484 buf_ptr += sizeof(*cmd); 5485 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5486 sizeof(wmi_sar_limit_cmd_row) * 5487 sar_limit_params->num_limit_rows); 5488 if (cmd->num_limit_rows == 0) 5489 goto send_sar_limits; 5490 5491 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5492 (buf_ptr + WMI_TLV_HDR_SIZE); 5493 sar_rows_list = sar_limit_params->sar_limit_row_list; 5494 5495 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5496 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5497 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5498 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5499 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5500 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5501 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5502 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5503 wmi_sar_rows_list->validity_bitmap = 5504 sar_rows_list->validity_bitmap; 5505 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5506 i, wmi_sar_rows_list->band_id, 5507 wmi_sar_rows_list->chain_id, 5508 wmi_sar_rows_list->mod_id, 5509 wmi_sar_rows_list->limit_value, 5510 wmi_sar_rows_list->validity_bitmap); 5511 sar_rows_list++; 5512 wmi_sar_rows_list++; 5513 } 5514 send_sar_limits: 5515 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5516 WMI_SAR_LIMITS_CMDID); 5517 5518 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5519 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5520 wmi_buf_free(buf); 5521 } 5522 5523 end: 5524 return qdf_status; 5525 } 5526 5527 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5528 { 5529 wmi_sar_get_limits_cmd_fixed_param *cmd; 5530 wmi_buf_t wmi_buf; 5531 uint32_t len; 5532 QDF_STATUS status; 5533 5534 WMI_LOGD(FL("Enter")); 5535 5536 len = sizeof(*cmd); 5537 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5538 if (!wmi_buf) { 5539 WMI_LOGP(FL("failed to allocate memory for msg")); 5540 return QDF_STATUS_E_NOMEM; 5541 } 5542 5543 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5544 5545 WMITLV_SET_HDR(&cmd->tlv_header, 5546 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5547 WMITLV_GET_STRUCT_TLVLEN 5548 (wmi_sar_get_limits_cmd_fixed_param)); 5549 5550 cmd->reserved = 0; 5551 5552 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5553 WMI_SAR_GET_LIMITS_CMDID); 5554 if (QDF_IS_STATUS_ERROR(status)) { 5555 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5556 wmi_buf_free(wmi_buf); 5557 } 5558 5559 WMI_LOGD(FL("Exit")); 5560 5561 return status; 5562 } 5563 5564 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5565 uint8_t *evt_buf, 5566 struct sar_limit_event *event) 5567 { 5568 wmi_sar_get_limits_event_fixed_param *fixed_param; 5569 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5570 wmi_sar_get_limit_event_row *row_in; 5571 struct sar_limit_event_row *row_out; 5572 uint32_t row; 5573 5574 if (!evt_buf) { 5575 WMI_LOGE(FL("input event is NULL")); 5576 return QDF_STATUS_E_INVAL; 5577 } 5578 if (!event) { 5579 WMI_LOGE(FL("output event is NULL")); 5580 return QDF_STATUS_E_INVAL; 5581 } 5582 5583 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5584 5585 fixed_param = param_buf->fixed_param; 5586 if (!fixed_param) { 5587 WMI_LOGE(FL("Invalid fixed param")); 5588 return QDF_STATUS_E_INVAL; 5589 } 5590 5591 event->sar_enable = fixed_param->sar_enable; 5592 event->num_limit_rows = fixed_param->num_limit_rows; 5593 5594 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5595 QDF_ASSERT(0); 5596 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5597 event->num_limit_rows, 5598 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5599 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5600 } 5601 5602 row_in = param_buf->sar_get_limits; 5603 row_out = &event->sar_limit_row[0]; 5604 for (row = 0; row < event->num_limit_rows; row++) { 5605 row_out->band_id = row_in->band_id; 5606 row_out->chain_id = row_in->chain_id; 5607 row_out->mod_id = row_in->mod_id; 5608 row_out->limit_value = row_in->limit_value; 5609 row_out++; 5610 row_in++; 5611 } 5612 5613 return QDF_STATUS_SUCCESS; 5614 } 5615 5616 #ifdef WLAN_FEATURE_DISA 5617 /** 5618 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5619 * @wmi_handle: wmi handle 5620 * @params: encrypt/decrypt params 5621 * 5622 * Return: QDF_STATUS_SUCCESS for success or error code 5623 */ 5624 static 5625 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5626 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5627 { 5628 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5629 wmi_buf_t wmi_buf; 5630 uint8_t *buf_ptr; 5631 QDF_STATUS ret; 5632 uint32_t len; 5633 5634 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5635 5636 len = sizeof(*cmd) + 5637 roundup(encrypt_decrypt_params->data_len, sizeof(A_UINT32)) + 5638 WMI_TLV_HDR_SIZE; 5639 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5640 if (!wmi_buf) { 5641 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5642 __func__); 5643 return QDF_STATUS_E_NOMEM; 5644 } 5645 5646 buf_ptr = wmi_buf_data(wmi_buf); 5647 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5648 5649 WMITLV_SET_HDR(&cmd->tlv_header, 5650 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5651 WMITLV_GET_STRUCT_TLVLEN( 5652 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5653 5654 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5655 cmd->key_flag = encrypt_decrypt_params->key_flag; 5656 cmd->key_idx = encrypt_decrypt_params->key_idx; 5657 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5658 cmd->key_len = encrypt_decrypt_params->key_len; 5659 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5660 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5661 5662 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5663 encrypt_decrypt_params->key_len); 5664 5665 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5666 MAX_MAC_HEADER_LEN); 5667 5668 cmd->data_len = encrypt_decrypt_params->data_len; 5669 5670 if (cmd->data_len) { 5671 buf_ptr += sizeof(*cmd); 5672 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5673 roundup(encrypt_decrypt_params->data_len, 5674 sizeof(A_UINT32))); 5675 buf_ptr += WMI_TLV_HDR_SIZE; 5676 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5677 encrypt_decrypt_params->data_len); 5678 } 5679 5680 /* This conversion is to facilitate data to FW in little endian */ 5681 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5682 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5683 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5684 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5685 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5686 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5687 5688 ret = wmi_unified_cmd_send(wmi_handle, 5689 wmi_buf, len, 5690 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5691 if (QDF_IS_STATUS_ERROR(ret)) { 5692 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5693 wmi_buf_free(wmi_buf); 5694 } 5695 5696 return ret; 5697 } 5698 5699 /** 5700 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5701 * params from event 5702 * @wmi_handle: wmi handle 5703 * @evt_buf: pointer to event buffer 5704 * @resp: Pointer to hold resp parameters 5705 * 5706 * Return: QDF_STATUS_SUCCESS for success or error code 5707 */ 5708 static 5709 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5710 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5711 { 5712 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5713 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5714 5715 param_buf = evt_buf; 5716 if (!param_buf) { 5717 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5718 return QDF_STATUS_E_INVAL; 5719 } 5720 5721 data_event = param_buf->fixed_param; 5722 5723 resp->vdev_id = data_event->vdev_id; 5724 resp->status = data_event->status; 5725 5726 if (data_event->data_length > param_buf->num_enc80211_frame) { 5727 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5728 data_event->data_length, 5729 param_buf->num_enc80211_frame); 5730 return QDF_STATUS_E_INVAL; 5731 } 5732 5733 resp->data_len = data_event->data_length; 5734 5735 if (resp->data_len) 5736 resp->data = (uint8_t *)param_buf->enc80211_frame; 5737 5738 return QDF_STATUS_SUCCESS; 5739 } 5740 #endif 5741 5742 /** 5743 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5744 * @wmi_handle: wmi handle 5745 * @vdev_id: vdev id 5746 * @p2p_ie: p2p IE 5747 * 5748 * Return: QDF_STATUS_SUCCESS for success or error code 5749 */ 5750 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5751 A_UINT32 vdev_id, uint8_t *p2p_ie) 5752 { 5753 QDF_STATUS ret; 5754 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5755 wmi_buf_t wmi_buf; 5756 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5757 uint8_t *buf_ptr; 5758 5759 ie_len = (uint32_t) (p2p_ie[1] + 2); 5760 5761 /* More than one P2P IE may be included in a single frame. 5762 If multiple P2P IEs are present, the complete P2P attribute 5763 data consists of the concatenation of the P2P Attribute 5764 fields of the P2P IEs. The P2P Attributes field of each 5765 P2P IE may be any length up to the maximum (251 octets). 5766 In this case host sends one P2P IE to firmware so the length 5767 should not exceed more than 251 bytes 5768 */ 5769 if (ie_len > 251) { 5770 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5771 return QDF_STATUS_E_INVAL; 5772 } 5773 5774 ie_len_aligned = roundup(ie_len, sizeof(A_UINT32)); 5775 5776 wmi_buf_len = 5777 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5778 WMI_TLV_HDR_SIZE; 5779 5780 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5781 if (!wmi_buf) { 5782 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5783 return QDF_STATUS_E_NOMEM; 5784 } 5785 5786 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5787 5788 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5789 WMITLV_SET_HDR(&cmd->tlv_header, 5790 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5791 WMITLV_GET_STRUCT_TLVLEN 5792 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5793 cmd->vdev_id = vdev_id; 5794 cmd->ie_buf_len = ie_len; 5795 5796 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5797 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5798 buf_ptr += WMI_TLV_HDR_SIZE; 5799 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5800 5801 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 5802 5803 ret = wmi_unified_cmd_send(wmi_handle, 5804 wmi_buf, wmi_buf_len, 5805 WMI_P2P_GO_SET_BEACON_IE); 5806 if (QDF_IS_STATUS_ERROR(ret)) { 5807 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 5808 wmi_buf_free(wmi_buf); 5809 } 5810 5811 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 5812 return ret; 5813 } 5814 5815 /** 5816 * send_set_gateway_params_cmd_tlv() - set gateway parameters 5817 * @wmi_handle: wmi handle 5818 * @req: gateway parameter update request structure 5819 * 5820 * This function reads the incoming @req and fill in the destination 5821 * WMI structure and sends down the gateway configs down to the firmware 5822 * 5823 * Return: QDF_STATUS 5824 */ 5825 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 5826 struct gateway_update_req_param *req) 5827 { 5828 wmi_roam_subnet_change_config_fixed_param *cmd; 5829 wmi_buf_t buf; 5830 QDF_STATUS ret; 5831 int len = sizeof(*cmd); 5832 5833 buf = wmi_buf_alloc(wmi_handle, len); 5834 if (!buf) { 5835 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5836 return QDF_STATUS_E_NOMEM; 5837 } 5838 5839 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 5840 WMITLV_SET_HDR(&cmd->tlv_header, 5841 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 5842 WMITLV_GET_STRUCT_TLVLEN( 5843 wmi_roam_subnet_change_config_fixed_param)); 5844 5845 cmd->vdev_id = req->session_id; 5846 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 5847 QDF_IPV4_ADDR_SIZE); 5848 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 5849 QDF_IPV6_ADDR_SIZE); 5850 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 5851 &cmd->inet_gw_mac_addr); 5852 cmd->max_retries = req->max_retries; 5853 cmd->timeout = req->timeout; 5854 cmd->num_skip_subnet_change_detection_bssid_list = 0; 5855 cmd->flag = 0; 5856 if (req->ipv4_addr_type) 5857 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 5858 5859 if (req->ipv6_addr_type) 5860 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 5861 5862 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5863 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 5864 if (QDF_IS_STATUS_ERROR(ret)) { 5865 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 5866 ret); 5867 wmi_buf_free(buf); 5868 } 5869 5870 return ret; 5871 } 5872 5873 /** 5874 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 5875 * @wmi_handle: wmi handle 5876 * @req: rssi monitoring request structure 5877 * 5878 * This function reads the incoming @req and fill in the destination 5879 * WMI structure and send down the rssi monitoring configs down to the firmware 5880 * 5881 * Return: 0 on success; error number otherwise 5882 */ 5883 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 5884 struct rssi_monitor_param *req) 5885 { 5886 wmi_rssi_breach_monitor_config_fixed_param *cmd; 5887 wmi_buf_t buf; 5888 QDF_STATUS ret; 5889 uint32_t len = sizeof(*cmd); 5890 5891 buf = wmi_buf_alloc(wmi_handle, len); 5892 if (!buf) { 5893 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5894 return QDF_STATUS_E_NOMEM; 5895 } 5896 5897 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 5898 WMITLV_SET_HDR(&cmd->tlv_header, 5899 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 5900 WMITLV_GET_STRUCT_TLVLEN( 5901 wmi_rssi_breach_monitor_config_fixed_param)); 5902 5903 cmd->vdev_id = req->session_id; 5904 cmd->request_id = req->request_id; 5905 cmd->lo_rssi_reenable_hysteresis = 0; 5906 cmd->hi_rssi_reenable_histeresis = 0; 5907 cmd->min_report_interval = 0; 5908 cmd->max_num_report = 1; 5909 if (req->control) { 5910 /* enable one threshold for each min/max */ 5911 cmd->enabled_bitmap = 0x09; 5912 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 5913 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 5914 } else { 5915 cmd->enabled_bitmap = 0; 5916 cmd->low_rssi_breach_threshold[0] = 0; 5917 cmd->hi_rssi_breach_threshold[0] = 0; 5918 } 5919 5920 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5921 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 5922 if (QDF_IS_STATUS_ERROR(ret)) { 5923 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 5924 wmi_buf_free(buf); 5925 } 5926 5927 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 5928 5929 return ret; 5930 } 5931 5932 /** 5933 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5934 * @wmi_handle: wmi handle 5935 * @psetoui: OUI parameters 5936 * 5937 * set scan probe OUI parameters in firmware 5938 * 5939 * Return: CDF status 5940 */ 5941 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5942 struct scan_mac_oui *psetoui) 5943 { 5944 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5945 wmi_buf_t wmi_buf; 5946 uint32_t len; 5947 uint8_t *buf_ptr; 5948 uint32_t *oui_buf; 5949 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 5950 5951 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5952 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 5953 5954 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5955 if (!wmi_buf) { 5956 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5957 return QDF_STATUS_E_NOMEM; 5958 } 5959 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5960 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5961 WMITLV_SET_HDR(&cmd->tlv_header, 5962 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5963 WMITLV_GET_STRUCT_TLVLEN 5964 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5965 5966 oui_buf = &cmd->prob_req_oui; 5967 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5968 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5969 | psetoui->oui[2]; 5970 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 5971 cmd->prob_req_oui); 5972 5973 cmd->vdev_id = psetoui->vdev_id; 5974 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5975 if (psetoui->enb_probe_req_sno_randomization) 5976 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5977 5978 if (ie_whitelist->white_list) { 5979 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5980 &cmd->num_vendor_oui, 5981 ie_whitelist); 5982 cmd->flags |= 5983 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5984 } 5985 5986 buf_ptr += sizeof(*cmd); 5987 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5988 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5989 buf_ptr += WMI_TLV_HDR_SIZE; 5990 5991 if (cmd->num_vendor_oui != 0) { 5992 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5993 ie_whitelist->voui); 5994 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5995 } 5996 5997 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5998 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5999 WMI_LOGE("%s: failed to send command", __func__); 6000 wmi_buf_free(wmi_buf); 6001 return QDF_STATUS_E_FAILURE; 6002 } 6003 return QDF_STATUS_SUCCESS; 6004 } 6005 6006 /** 6007 * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list 6008 * @wmi_handle: wmi handle 6009 * @req: passpoint network request structure 6010 * 6011 * This function sends down WMI command with network id set to wildcard id. 6012 * firmware shall clear all the config entries 6013 * 6014 * Return: QDF_STATUS enumeration 6015 */ 6016 static QDF_STATUS send_reset_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 6017 struct wifi_passpoint_req_param *req) 6018 { 6019 wmi_passpoint_config_cmd_fixed_param *cmd; 6020 wmi_buf_t buf; 6021 uint32_t len; 6022 int ret; 6023 6024 len = sizeof(*cmd); 6025 buf = wmi_buf_alloc(wmi_handle, len); 6026 if (!buf) { 6027 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 6028 return QDF_STATUS_E_NOMEM; 6029 } 6030 6031 cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf); 6032 6033 WMITLV_SET_HDR(&cmd->tlv_header, 6034 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 6035 WMITLV_GET_STRUCT_TLVLEN( 6036 wmi_passpoint_config_cmd_fixed_param)); 6037 cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD; 6038 6039 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6040 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6041 if (ret) { 6042 WMI_LOGE("%s: Failed to send reset passpoint network list wmi cmd", 6043 __func__); 6044 wmi_buf_free(buf); 6045 return QDF_STATUS_E_FAILURE; 6046 } 6047 6048 return QDF_STATUS_SUCCESS; 6049 } 6050 6051 /** 6052 * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list 6053 * @wmi_handle: wmi handle 6054 * @req: passpoint network request structure 6055 * 6056 * This function reads the incoming @req and fill in the destination 6057 * WMI structure and send down the passpoint configs down to the firmware 6058 * 6059 * Return: QDF_STATUS enumeration 6060 */ 6061 static QDF_STATUS send_set_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 6062 struct wifi_passpoint_req_param *req) 6063 { 6064 wmi_passpoint_config_cmd_fixed_param *cmd; 6065 u_int8_t i, j, *bytes; 6066 wmi_buf_t buf; 6067 uint32_t len; 6068 int ret; 6069 6070 len = sizeof(*cmd); 6071 for (i = 0; i < req->num_networks; i++) { 6072 buf = wmi_buf_alloc(wmi_handle, len); 6073 if (!buf) { 6074 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 6075 return QDF_STATUS_E_NOMEM; 6076 } 6077 6078 cmd = (wmi_passpoint_config_cmd_fixed_param *) 6079 wmi_buf_data(buf); 6080 6081 WMITLV_SET_HDR(&cmd->tlv_header, 6082 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 6083 WMITLV_GET_STRUCT_TLVLEN( 6084 wmi_passpoint_config_cmd_fixed_param)); 6085 cmd->id = req->networks[i].id; 6086 WMI_LOGD("%s: network id: %u", __func__, cmd->id); 6087 qdf_mem_copy(cmd->realm, req->networks[i].realm, 6088 strlen(req->networks[i].realm) + 1); 6089 WMI_LOGD("%s: realm: %s", __func__, cmd->realm); 6090 for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) { 6091 bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j]; 6092 WMI_LOGD("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x", 6093 j, bytes[0], bytes[1], bytes[2], bytes[3], 6094 bytes[4], bytes[5], bytes[6], bytes[7]); 6095 6096 qdf_mem_copy(&cmd->roaming_consortium_ids[j], 6097 &req->networks[i].roaming_consortium_ids[j], 6098 PASSPOINT_ROAMING_CONSORTIUM_ID_LEN); 6099 } 6100 qdf_mem_copy(cmd->plmn, req->networks[i].plmn, 6101 PASSPOINT_PLMN_ID_LEN); 6102 WMI_LOGD("%s: plmn: %02x:%02x:%02x", __func__, 6103 cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]); 6104 6105 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6106 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6107 if (ret) { 6108 WMI_LOGE("%s: Failed to send set passpoint network list wmi cmd", 6109 __func__); 6110 wmi_buf_free(buf); 6111 return QDF_STATUS_E_FAILURE; 6112 } 6113 } 6114 6115 return QDF_STATUS_SUCCESS; 6116 } 6117 6118 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6119 /** 6120 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6121 * @wmi_handle: wmi handle 6122 * @roam_req: Roam scan offload params 6123 * @buf_ptr: command buffer to send 6124 * @fils_tlv_len: fils tlv length 6125 * 6126 * Return: Updated buffer pointer 6127 */ 6128 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6129 struct roam_offload_scan_params *roam_req, 6130 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6131 { 6132 wmi_roam_fils_offload_tlv_param *fils_tlv; 6133 wmi_erp_info *erp_info; 6134 struct roam_fils_params *roam_fils_params; 6135 6136 if (!roam_req->add_fils_tlv) 6137 return buf_ptr; 6138 6139 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6140 sizeof(*fils_tlv)); 6141 buf_ptr += WMI_TLV_HDR_SIZE; 6142 6143 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6144 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6145 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6146 WMITLV_GET_STRUCT_TLVLEN 6147 (wmi_roam_fils_offload_tlv_param)); 6148 6149 roam_fils_params = &roam_req->roam_fils_params; 6150 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6151 6152 erp_info->username_length = roam_fils_params->username_length; 6153 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6154 erp_info->username_length); 6155 6156 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6157 6158 erp_info->rRk_length = roam_fils_params->rrk_length; 6159 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6160 erp_info->rRk_length); 6161 6162 erp_info->rIk_length = roam_fils_params->rik_length; 6163 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6164 erp_info->rIk_length); 6165 6166 erp_info->realm_len = roam_fils_params->realm_len; 6167 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6168 erp_info->realm_len); 6169 6170 buf_ptr += sizeof(*fils_tlv); 6171 return buf_ptr; 6172 } 6173 #else 6174 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6175 struct roam_offload_scan_params *roam_req, 6176 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6177 { 6178 return buf_ptr; 6179 } 6180 #endif 6181 /** 6182 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6183 * @wmi_handle: wmi handle 6184 * @scan_cmd_fp: start scan command ptr 6185 * @roam_req: roam request param 6186 * 6187 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6188 * of WMI_ROAM_SCAN_MODE. 6189 * 6190 * Return: QDF status 6191 */ 6192 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6193 wmi_start_scan_cmd_fixed_param * 6194 scan_cmd_fp, 6195 struct roam_offload_scan_params *roam_req) 6196 { 6197 wmi_buf_t buf = NULL; 6198 QDF_STATUS status; 6199 int len; 6200 uint8_t *buf_ptr; 6201 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6202 6203 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6204 int auth_mode = roam_req->auth_mode; 6205 wmi_roam_offload_tlv_param *roam_offload_params; 6206 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6207 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6208 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6209 wmi_tlv_buf_len_param *assoc_ies; 6210 uint32_t fils_tlv_len = 0; 6211 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6212 /* Need to create a buf with roam_scan command at 6213 * front and piggyback with scan command */ 6214 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6215 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6216 (2 * WMI_TLV_HDR_SIZE) + 6217 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6218 sizeof(wmi_start_scan_cmd_fixed_param); 6219 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6220 WMI_LOGD("auth_mode = %d", auth_mode); 6221 if (roam_req->is_roam_req_valid && 6222 roam_req->roam_offload_enabled) { 6223 len += sizeof(wmi_roam_offload_tlv_param); 6224 len += WMI_TLV_HDR_SIZE; 6225 if ((auth_mode != WMI_AUTH_NONE) && 6226 ((auth_mode != WMI_AUTH_OPEN) || 6227 (auth_mode == WMI_AUTH_OPEN && 6228 roam_req->mdid.mdie_present) || 6229 roam_req->is_ese_assoc)) { 6230 len += WMI_TLV_HDR_SIZE; 6231 if (roam_req->is_ese_assoc) 6232 len += 6233 sizeof(wmi_roam_ese_offload_tlv_param); 6234 else if (auth_mode == WMI_AUTH_FT_RSNA || 6235 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6236 (auth_mode == WMI_AUTH_OPEN && 6237 roam_req->mdid.mdie_present)) 6238 len += 6239 sizeof(wmi_roam_11r_offload_tlv_param); 6240 else 6241 len += 6242 sizeof(wmi_roam_11i_offload_tlv_param); 6243 } else { 6244 len += WMI_TLV_HDR_SIZE; 6245 } 6246 6247 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6248 + roundup(roam_req->assoc_ie_length, 6249 sizeof(uint32_t))); 6250 6251 if (roam_req->add_fils_tlv) { 6252 fils_tlv_len = sizeof( 6253 wmi_roam_fils_offload_tlv_param); 6254 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6255 } 6256 } else { 6257 if (roam_req->is_roam_req_valid) 6258 WMI_LOGD("%s : roam offload = %d", 6259 __func__, roam_req->roam_offload_enabled); 6260 else 6261 WMI_LOGD("%s : roam_req is NULL", __func__); 6262 len += (4 * WMI_TLV_HDR_SIZE); 6263 } 6264 if (roam_req->is_roam_req_valid && 6265 roam_req->roam_offload_enabled) { 6266 roam_req->mode = roam_req->mode | 6267 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6268 } 6269 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6270 6271 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6272 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6273 len = sizeof(wmi_roam_scan_mode_fixed_param); 6274 6275 buf = wmi_buf_alloc(wmi_handle, len); 6276 if (!buf) { 6277 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6278 return QDF_STATUS_E_NOMEM; 6279 } 6280 6281 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6282 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6283 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6284 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6285 WMITLV_GET_STRUCT_TLVLEN 6286 (wmi_roam_scan_mode_fixed_param)); 6287 6288 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6289 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6290 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6291 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6292 roam_scan_mode_fp->flags |= 6293 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6294 goto send_roam_scan_mode_cmd; 6295 } 6296 6297 /* Fill in scan parameters suitable for roaming scan */ 6298 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6299 6300 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6301 sizeof(wmi_start_scan_cmd_fixed_param)); 6302 /* Ensure there is no additional IEs */ 6303 scan_cmd_fp->ie_len = 0; 6304 WMITLV_SET_HDR(buf_ptr, 6305 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6306 WMITLV_GET_STRUCT_TLVLEN 6307 (wmi_start_scan_cmd_fixed_param)); 6308 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6309 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6310 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6311 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6312 sizeof(wmi_roam_offload_tlv_param)); 6313 buf_ptr += WMI_TLV_HDR_SIZE; 6314 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6315 WMITLV_SET_HDR(buf_ptr, 6316 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6317 WMITLV_GET_STRUCT_TLVLEN 6318 (wmi_roam_offload_tlv_param)); 6319 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6320 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6321 roam_offload_params->select_5g_margin = 6322 roam_req->select_5ghz_margin; 6323 roam_offload_params->reassoc_failure_timeout = 6324 roam_req->reassoc_failure_timeout; 6325 6326 /* Fill the capabilities */ 6327 roam_offload_params->capability = 6328 roam_req->roam_offload_params.capability; 6329 roam_offload_params->ht_caps_info = 6330 roam_req->roam_offload_params.ht_caps_info; 6331 roam_offload_params->ampdu_param = 6332 roam_req->roam_offload_params.ampdu_param; 6333 roam_offload_params->ht_ext_cap = 6334 roam_req->roam_offload_params.ht_ext_cap; 6335 roam_offload_params->ht_txbf = 6336 roam_req->roam_offload_params.ht_txbf; 6337 roam_offload_params->asel_cap = 6338 roam_req->roam_offload_params.asel_cap; 6339 roam_offload_params->qos_caps = 6340 roam_req->roam_offload_params.qos_caps; 6341 roam_offload_params->qos_enabled = 6342 roam_req->roam_offload_params.qos_enabled; 6343 roam_offload_params->wmm_caps = 6344 roam_req->roam_offload_params.wmm_caps; 6345 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6346 (uint8_t *)roam_req->roam_offload_params.mcsset, 6347 ROAM_OFFLOAD_NUM_MCS_SET); 6348 6349 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6350 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6351 * they are filled in the same order.Depending on the 6352 * authentication type, the other mode TLV's are nullified 6353 * and only headers are filled.*/ 6354 if ((auth_mode != WMI_AUTH_NONE) && 6355 ((auth_mode != WMI_AUTH_OPEN) || 6356 (auth_mode == WMI_AUTH_OPEN 6357 && roam_req->mdid.mdie_present) || 6358 roam_req->is_ese_assoc)) { 6359 if (roam_req->is_ese_assoc) { 6360 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6361 WMITLV_GET_STRUCT_TLVLEN(0)); 6362 buf_ptr += WMI_TLV_HDR_SIZE; 6363 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6364 WMITLV_GET_STRUCT_TLVLEN(0)); 6365 buf_ptr += WMI_TLV_HDR_SIZE; 6366 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6367 sizeof(wmi_roam_ese_offload_tlv_param)); 6368 buf_ptr += WMI_TLV_HDR_SIZE; 6369 roam_offload_ese = 6370 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6371 qdf_mem_copy(roam_offload_ese->krk, 6372 roam_req->krk, 6373 sizeof(roam_req->krk)); 6374 qdf_mem_copy(roam_offload_ese->btk, 6375 roam_req->btk, 6376 sizeof(roam_req->btk)); 6377 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6378 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6379 WMITLV_GET_STRUCT_TLVLEN 6380 (wmi_roam_ese_offload_tlv_param)); 6381 buf_ptr += 6382 sizeof(wmi_roam_ese_offload_tlv_param); 6383 } else if (auth_mode == WMI_AUTH_FT_RSNA 6384 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6385 || (auth_mode == WMI_AUTH_OPEN 6386 && roam_req->mdid.mdie_present)) { 6387 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6388 0); 6389 buf_ptr += WMI_TLV_HDR_SIZE; 6390 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6391 sizeof(wmi_roam_11r_offload_tlv_param)); 6392 buf_ptr += WMI_TLV_HDR_SIZE; 6393 roam_offload_11r = 6394 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6395 roam_offload_11r->r0kh_id_len = 6396 roam_req->rokh_id_length; 6397 qdf_mem_copy(roam_offload_11r->r0kh_id, 6398 roam_req->rokh_id, 6399 roam_offload_11r->r0kh_id_len); 6400 qdf_mem_copy(roam_offload_11r->psk_msk, 6401 roam_req->psk_pmk, 6402 sizeof(roam_req->psk_pmk)); 6403 roam_offload_11r->psk_msk_len = 6404 roam_req->pmk_len; 6405 roam_offload_11r->mdie_present = 6406 roam_req->mdid.mdie_present; 6407 roam_offload_11r->mdid = 6408 roam_req->mdid.mobility_domain; 6409 if (auth_mode == WMI_AUTH_OPEN) { 6410 /* If FT-Open ensure pmk length 6411 and r0khid len are zero */ 6412 roam_offload_11r->r0kh_id_len = 0; 6413 roam_offload_11r->psk_msk_len = 0; 6414 } 6415 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6416 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6417 WMITLV_GET_STRUCT_TLVLEN 6418 (wmi_roam_11r_offload_tlv_param)); 6419 buf_ptr += 6420 sizeof(wmi_roam_11r_offload_tlv_param); 6421 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6422 WMITLV_GET_STRUCT_TLVLEN(0)); 6423 buf_ptr += WMI_TLV_HDR_SIZE; 6424 WMI_LOGD("psk_msk_len = %d", 6425 roam_offload_11r->psk_msk_len); 6426 if (roam_offload_11r->psk_msk_len) 6427 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6428 QDF_TRACE_LEVEL_DEBUG, 6429 roam_offload_11r->psk_msk, 6430 roam_offload_11r->psk_msk_len); 6431 } else { 6432 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6433 sizeof(wmi_roam_11i_offload_tlv_param)); 6434 buf_ptr += WMI_TLV_HDR_SIZE; 6435 roam_offload_11i = 6436 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6437 6438 if (roam_req->roam_key_mgmt_offload_enabled && 6439 roam_req->fw_okc) { 6440 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6441 (roam_offload_11i->flags); 6442 WMI_LOGI("LFR3:OKC enabled"); 6443 } else { 6444 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6445 (roam_offload_11i->flags); 6446 WMI_LOGI("LFR3:OKC disabled"); 6447 } 6448 if (roam_req->roam_key_mgmt_offload_enabled && 6449 roam_req->fw_pmksa_cache) { 6450 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6451 (roam_offload_11i->flags); 6452 WMI_LOGI("LFR3:PMKSA caching enabled"); 6453 } else { 6454 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6455 (roam_offload_11i->flags); 6456 WMI_LOGI("LFR3:PMKSA caching disabled"); 6457 } 6458 6459 qdf_mem_copy(roam_offload_11i->pmk, 6460 roam_req->psk_pmk, 6461 sizeof(roam_req->psk_pmk)); 6462 roam_offload_11i->pmk_len = roam_req->pmk_len; 6463 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6464 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6465 WMITLV_GET_STRUCT_TLVLEN 6466 (wmi_roam_11i_offload_tlv_param)); 6467 buf_ptr += 6468 sizeof(wmi_roam_11i_offload_tlv_param); 6469 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6470 0); 6471 buf_ptr += WMI_TLV_HDR_SIZE; 6472 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6473 0); 6474 buf_ptr += WMI_TLV_HDR_SIZE; 6475 WMI_LOGD("pmk_len = %d", 6476 roam_offload_11i->pmk_len); 6477 if (roam_offload_11i->pmk_len) 6478 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6479 QDF_TRACE_LEVEL_DEBUG, 6480 roam_offload_11i->pmk, 6481 roam_offload_11i->pmk_len); 6482 } 6483 } else { 6484 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6485 WMITLV_GET_STRUCT_TLVLEN(0)); 6486 buf_ptr += WMI_TLV_HDR_SIZE; 6487 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6488 WMITLV_GET_STRUCT_TLVLEN(0)); 6489 buf_ptr += WMI_TLV_HDR_SIZE; 6490 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6491 WMITLV_GET_STRUCT_TLVLEN(0)); 6492 buf_ptr += WMI_TLV_HDR_SIZE; 6493 } 6494 6495 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6496 sizeof(*assoc_ies)); 6497 buf_ptr += WMI_TLV_HDR_SIZE; 6498 6499 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6500 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6501 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6502 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6503 assoc_ies->buf_len = roam_req->assoc_ie_length; 6504 6505 buf_ptr += sizeof(*assoc_ies); 6506 6507 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6508 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6509 buf_ptr += WMI_TLV_HDR_SIZE; 6510 6511 if (assoc_ies->buf_len != 0) { 6512 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6513 assoc_ies->buf_len); 6514 } 6515 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6516 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6517 buf_ptr, fils_tlv_len); 6518 } else { 6519 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6520 WMITLV_GET_STRUCT_TLVLEN(0)); 6521 buf_ptr += WMI_TLV_HDR_SIZE; 6522 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6523 WMITLV_GET_STRUCT_TLVLEN(0)); 6524 buf_ptr += WMI_TLV_HDR_SIZE; 6525 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6526 WMITLV_GET_STRUCT_TLVLEN(0)); 6527 buf_ptr += WMI_TLV_HDR_SIZE; 6528 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6529 WMITLV_GET_STRUCT_TLVLEN(0)); 6530 buf_ptr += WMI_TLV_HDR_SIZE; 6531 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6532 WMITLV_GET_STRUCT_TLVLEN(0)); 6533 buf_ptr += WMI_TLV_HDR_SIZE; 6534 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6535 WMITLV_GET_STRUCT_TLVLEN(0)); 6536 } 6537 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6538 6539 send_roam_scan_mode_cmd: 6540 status = wmi_unified_cmd_send(wmi_handle, buf, 6541 len, WMI_ROAM_SCAN_MODE); 6542 if (QDF_IS_STATUS_ERROR(status)) { 6543 WMI_LOGE( 6544 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6545 status); 6546 wmi_buf_free(buf); 6547 } 6548 6549 return status; 6550 } 6551 6552 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6553 struct wmi_mawc_roam_params *params) 6554 { 6555 wmi_buf_t buf = NULL; 6556 QDF_STATUS status; 6557 int len; 6558 uint8_t *buf_ptr; 6559 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6560 6561 len = sizeof(*wmi_roam_mawc_params); 6562 buf = wmi_buf_alloc(wmi_handle, len); 6563 if (!buf) { 6564 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6565 return QDF_STATUS_E_NOMEM; 6566 } 6567 6568 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6569 wmi_roam_mawc_params = 6570 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6571 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6572 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6573 WMITLV_GET_STRUCT_TLVLEN 6574 (wmi_roam_configure_mawc_cmd_fixed_param)); 6575 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6576 if (params->enable) 6577 wmi_roam_mawc_params->enable = 1; 6578 else 6579 wmi_roam_mawc_params->enable = 0; 6580 wmi_roam_mawc_params->traffic_load_threshold = 6581 params->traffic_load_threshold; 6582 wmi_roam_mawc_params->best_ap_rssi_threshold = 6583 params->best_ap_rssi_threshold; 6584 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6585 params->rssi_stationary_high_adjust; 6586 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6587 params->rssi_stationary_low_adjust; 6588 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6589 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6590 wmi_roam_mawc_params->traffic_load_threshold, 6591 wmi_roam_mawc_params->best_ap_rssi_threshold, 6592 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6593 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6594 6595 status = wmi_unified_cmd_send(wmi_handle, buf, 6596 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6597 if (QDF_IS_STATUS_ERROR(status)) { 6598 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6599 status); 6600 wmi_buf_free(buf); 6601 return status; 6602 } 6603 6604 return QDF_STATUS_SUCCESS; 6605 } 6606 6607 /** 6608 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6609 * rssi threashold 6610 * @wmi_handle: wmi handle 6611 * @roam_req: Roaming request buffer 6612 * 6613 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6614 * 6615 * Return: QDF status 6616 */ 6617 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6618 struct roam_offload_scan_rssi_params *roam_req) 6619 { 6620 wmi_buf_t buf = NULL; 6621 QDF_STATUS status; 6622 int len; 6623 uint8_t *buf_ptr; 6624 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6625 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6626 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6627 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6628 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6629 6630 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6631 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6632 len += sizeof(wmi_roam_scan_extended_threshold_param); 6633 len += WMI_TLV_HDR_SIZE; 6634 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6635 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6636 len += sizeof(wmi_roam_dense_thres_param); 6637 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6638 len += sizeof(wmi_roam_bg_scan_roaming_param); 6639 buf = wmi_buf_alloc(wmi_handle, len); 6640 if (!buf) { 6641 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6642 return QDF_STATUS_E_NOMEM; 6643 } 6644 6645 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6646 rssi_threshold_fp = 6647 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6648 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6649 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6650 WMITLV_GET_STRUCT_TLVLEN 6651 (wmi_roam_scan_rssi_threshold_fixed_param)); 6652 /* fill in threshold values */ 6653 rssi_threshold_fp->vdev_id = roam_req->session_id; 6654 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6655 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6656 rssi_threshold_fp->hirssi_scan_max_count = 6657 roam_req->hi_rssi_scan_max_count; 6658 rssi_threshold_fp->hirssi_scan_delta = 6659 roam_req->hi_rssi_scan_rssi_delta; 6660 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6661 rssi_threshold_fp->rssi_thresh_offset_5g = 6662 roam_req->rssi_thresh_offset_5g; 6663 6664 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6665 WMITLV_SET_HDR(buf_ptr, 6666 WMITLV_TAG_ARRAY_STRUC, 6667 sizeof(wmi_roam_scan_extended_threshold_param)); 6668 buf_ptr += WMI_TLV_HDR_SIZE; 6669 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6670 6671 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6672 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6673 ext_thresholds->boost_threshold_5g = 6674 roam_req->boost_threshold_5g; 6675 6676 ext_thresholds->boost_algorithm_5g = 6677 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6678 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6679 ext_thresholds->penalty_algorithm_5g = 6680 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6681 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6682 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6683 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6684 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6685 6686 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6687 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6688 WMITLV_GET_STRUCT_TLVLEN 6689 (wmi_roam_scan_extended_threshold_param)); 6690 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6691 WMITLV_SET_HDR(buf_ptr, 6692 WMITLV_TAG_ARRAY_STRUC, 6693 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6694 buf_ptr += WMI_TLV_HDR_SIZE; 6695 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6696 early_stop_thresholds->roam_earlystop_thres_min = 6697 roam_req->roam_earlystop_thres_min; 6698 early_stop_thresholds->roam_earlystop_thres_max = 6699 roam_req->roam_earlystop_thres_max; 6700 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6701 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6702 WMITLV_GET_STRUCT_TLVLEN 6703 (wmi_roam_earlystop_rssi_thres_param)); 6704 6705 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6707 sizeof(wmi_roam_dense_thres_param)); 6708 buf_ptr += WMI_TLV_HDR_SIZE; 6709 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6710 dense_thresholds->roam_dense_rssi_thres_offset = 6711 roam_req->dense_rssi_thresh_offset; 6712 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6713 dense_thresholds->roam_dense_traffic_thres = 6714 roam_req->traffic_threshold; 6715 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6716 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6717 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6718 WMITLV_GET_STRUCT_TLVLEN 6719 (wmi_roam_dense_thres_param)); 6720 6721 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6722 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6723 sizeof(wmi_roam_bg_scan_roaming_param)); 6724 buf_ptr += WMI_TLV_HDR_SIZE; 6725 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6726 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6727 roam_req->bg_scan_bad_rssi_thresh; 6728 bg_scan_params->roam_bg_scan_client_bitmap = 6729 roam_req->bg_scan_client_bitmap; 6730 bg_scan_params->bad_rssi_thresh_offset_2g = 6731 roam_req->roam_bad_rssi_thresh_offset_2g; 6732 bg_scan_params->flags = roam_req->flags; 6733 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6734 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6735 WMITLV_GET_STRUCT_TLVLEN 6736 (wmi_roam_bg_scan_roaming_param)); 6737 6738 status = wmi_unified_cmd_send(wmi_handle, buf, 6739 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6740 if (QDF_IS_STATUS_ERROR(status)) { 6741 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6742 status); 6743 wmi_buf_free(buf); 6744 } 6745 6746 return status; 6747 } 6748 6749 /** 6750 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6751 * configuration params 6752 * @wma_handle: wma handler 6753 * @dwelltime_params: pointer to dwelltime_params 6754 * 6755 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6756 */ 6757 static 6758 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6759 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6760 { 6761 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6762 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6763 wmi_buf_t buf; 6764 uint8_t *buf_ptr; 6765 int32_t err; 6766 int len; 6767 6768 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6769 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6770 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6771 buf = wmi_buf_alloc(wmi_handle, len); 6772 if (!buf) { 6773 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6774 __func__); 6775 return QDF_STATUS_E_NOMEM; 6776 } 6777 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6778 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6779 WMITLV_SET_HDR(&dwell_param->tlv_header, 6780 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6781 WMITLV_GET_STRUCT_TLVLEN 6782 (wmi_scan_adaptive_dwell_config_fixed_param)); 6783 6784 dwell_param->enable = dwelltime_params->is_enabled; 6785 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6786 WMITLV_SET_HDR(buf_ptr, 6787 WMITLV_TAG_ARRAY_STRUC, 6788 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6789 buf_ptr += WMI_TLV_HDR_SIZE; 6790 6791 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6792 WMITLV_SET_HDR(&cmd->tlv_header, 6793 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6794 WMITLV_GET_STRUCT_TLVLEN( 6795 wmi_scan_adaptive_dwell_parameters_tlv)); 6796 6797 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6798 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6799 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6800 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6801 err = wmi_unified_cmd_send(wmi_handle, buf, 6802 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6803 if (err) { 6804 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6805 wmi_buf_free(buf); 6806 return QDF_STATUS_E_FAILURE; 6807 } 6808 6809 return QDF_STATUS_SUCCESS; 6810 } 6811 6812 /** 6813 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6814 * configuration params 6815 * @wmi_handle: wmi handler 6816 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6817 * 6818 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6819 */ 6820 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6821 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6822 { 6823 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6824 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6825 wmi_buf_t buf; 6826 uint8_t *buf_ptr; 6827 QDF_STATUS err; 6828 uint32_t i; 6829 int len; 6830 6831 len = sizeof(*dbs_scan_param); 6832 len += WMI_TLV_HDR_SIZE; 6833 len += dbs_scan_params->num_clients * sizeof(*cmd); 6834 6835 buf = wmi_buf_alloc(wmi_handle, len); 6836 if (!buf) { 6837 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6838 return QDF_STATUS_E_NOMEM; 6839 } 6840 6841 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6842 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6843 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6844 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6845 WMITLV_GET_STRUCT_TLVLEN 6846 (wmi_scan_dbs_duty_cycle_fixed_param)); 6847 6848 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6849 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6850 buf_ptr += sizeof(*dbs_scan_param); 6851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6852 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6853 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6854 6855 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6856 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6857 WMITLV_SET_HDR(&cmd->tlv_header, 6858 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6859 WMITLV_GET_STRUCT_TLVLEN( 6860 wmi_scan_dbs_duty_cycle_tlv_param)); 6861 cmd->module_id = dbs_scan_params->module_id[i]; 6862 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6863 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6864 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6865 } 6866 6867 err = wmi_unified_cmd_send(wmi_handle, buf, 6868 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6869 if (QDF_IS_STATUS_ERROR(err)) { 6870 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6871 wmi_buf_free(buf); 6872 return QDF_STATUS_E_FAILURE; 6873 } 6874 6875 return QDF_STATUS_SUCCESS; 6876 } 6877 6878 /** 6879 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6880 * @wmi_handle: wmi handle 6881 * @roam_req: Request which contains the filters 6882 * 6883 * There are filters such as whitelist, blacklist and preferred 6884 * list that need to be applied to the scan results to form the 6885 * probable candidates for roaming. 6886 * 6887 * Return: Return success upon succesfully passing the 6888 * parameters to the firmware, otherwise failure. 6889 */ 6890 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6891 struct roam_scan_filter_params *roam_req) 6892 { 6893 wmi_buf_t buf = NULL; 6894 QDF_STATUS status; 6895 uint32_t i; 6896 uint32_t len, blist_len = 0; 6897 uint8_t *buf_ptr; 6898 wmi_roam_filter_fixed_param *roam_filter; 6899 uint8_t *bssid_src_ptr = NULL; 6900 wmi_mac_addr *bssid_dst_ptr = NULL; 6901 wmi_ssid *ssid_ptr = NULL; 6902 uint32_t *bssid_preferred_factor_ptr = NULL; 6903 wmi_roam_lca_disallow_config_tlv_param *blist_param; 6904 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 6905 6906 len = sizeof(wmi_roam_filter_fixed_param); 6907 6908 len += WMI_TLV_HDR_SIZE; 6909 if (roam_req->num_bssid_black_list) 6910 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 6911 len += WMI_TLV_HDR_SIZE; 6912 if (roam_req->num_ssid_white_list) 6913 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 6914 len += 2 * WMI_TLV_HDR_SIZE; 6915 if (roam_req->num_bssid_preferred_list) { 6916 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 6917 len += roam_req->num_bssid_preferred_list * sizeof(A_UINT32); 6918 } 6919 len += WMI_TLV_HDR_SIZE; 6920 if (roam_req->lca_disallow_config_present) { 6921 len += sizeof(*blist_param); 6922 blist_len = sizeof(*blist_param); 6923 } 6924 6925 len += WMI_TLV_HDR_SIZE; 6926 if (roam_req->num_rssi_rejection_ap) 6927 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 6928 6929 buf = wmi_buf_alloc(wmi_handle, len); 6930 if (!buf) { 6931 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6932 return QDF_STATUS_E_NOMEM; 6933 } 6934 6935 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 6936 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 6937 WMITLV_SET_HDR(&roam_filter->tlv_header, 6938 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 6939 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 6940 /* fill in fixed values */ 6941 roam_filter->vdev_id = roam_req->session_id; 6942 roam_filter->flags = 0; 6943 roam_filter->op_bitmap = roam_req->op_bitmap; 6944 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 6945 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 6946 roam_filter->num_bssid_preferred_list = 6947 roam_req->num_bssid_preferred_list; 6948 roam_filter->num_rssi_rejection_ap = 6949 roam_req->num_rssi_rejection_ap; 6950 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 6951 6952 WMITLV_SET_HDR((buf_ptr), 6953 WMITLV_TAG_ARRAY_FIXED_STRUC, 6954 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 6955 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 6956 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6957 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 6958 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 6959 bssid_src_ptr += ATH_MAC_LEN; 6960 bssid_dst_ptr++; 6961 } 6962 buf_ptr += WMI_TLV_HDR_SIZE + 6963 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 6964 WMITLV_SET_HDR((buf_ptr), 6965 WMITLV_TAG_ARRAY_FIXED_STRUC, 6966 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 6967 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 6968 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 6969 qdf_mem_copy(&ssid_ptr->ssid, 6970 &roam_req->ssid_allowed_list[i].mac_ssid, 6971 roam_req->ssid_allowed_list[i].length); 6972 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 6973 ssid_ptr++; 6974 } 6975 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 6976 sizeof(wmi_ssid)); 6977 WMITLV_SET_HDR((buf_ptr), 6978 WMITLV_TAG_ARRAY_FIXED_STRUC, 6979 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 6980 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 6981 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6982 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6983 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 6984 (wmi_mac_addr *)bssid_dst_ptr); 6985 bssid_src_ptr += ATH_MAC_LEN; 6986 bssid_dst_ptr++; 6987 } 6988 buf_ptr += WMI_TLV_HDR_SIZE + 6989 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 6990 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6991 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 6992 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 6993 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6994 *bssid_preferred_factor_ptr = 6995 roam_req->bssid_favored_factor[i]; 6996 bssid_preferred_factor_ptr++; 6997 } 6998 buf_ptr += WMI_TLV_HDR_SIZE + 6999 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 7000 7001 WMITLV_SET_HDR(buf_ptr, 7002 WMITLV_TAG_ARRAY_STRUC, blist_len); 7003 buf_ptr += WMI_TLV_HDR_SIZE; 7004 if (roam_req->lca_disallow_config_present) { 7005 blist_param = 7006 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 7007 WMITLV_SET_HDR(&blist_param->tlv_header, 7008 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 7009 WMITLV_GET_STRUCT_TLVLEN( 7010 wmi_roam_lca_disallow_config_tlv_param)); 7011 7012 blist_param->disallow_duration = roam_req->disallow_duration; 7013 blist_param->rssi_channel_penalization = 7014 roam_req->rssi_channel_penalization; 7015 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 7016 blist_param->disallow_lca_enable_source_bitmap = 7017 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 7018 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 7019 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 7020 } 7021 7022 WMITLV_SET_HDR(buf_ptr, 7023 WMITLV_TAG_ARRAY_STRUC, 7024 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 7025 buf_ptr += WMI_TLV_HDR_SIZE; 7026 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 7027 rssi_rej = 7028 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 7029 WMITLV_SET_HDR(&rssi_rej->tlv_header, 7030 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7031 WMITLV_GET_STRUCT_TLVLEN( 7032 wmi_roam_rssi_rejection_oce_config_param)); 7033 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7034 roam_req->rssi_rejection_ap[i].bssid.bytes, 7035 &rssi_rej->bssid); 7036 rssi_rej->remaining_disallow_duration = 7037 roam_req->rssi_rejection_ap[i].remaining_duration; 7038 rssi_rej->requested_rssi = 7039 (A_INT32)roam_req->rssi_rejection_ap[i].expected_rssi; 7040 buf_ptr += 7041 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7042 } 7043 7044 status = wmi_unified_cmd_send(wmi_handle, buf, 7045 len, WMI_ROAM_FILTER_CMDID); 7046 if (QDF_IS_STATUS_ERROR(status)) { 7047 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7048 status); 7049 wmi_buf_free(buf); 7050 } 7051 7052 return status; 7053 } 7054 7055 #if defined(WLAN_FEATURE_FILS_SK) 7056 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7057 struct hlp_params *params) 7058 { 7059 uint32_t len; 7060 uint8_t *buf_ptr; 7061 wmi_buf_t buf = NULL; 7062 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7063 7064 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7065 len += WMI_TLV_HDR_SIZE; 7066 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7067 7068 buf = wmi_buf_alloc(wmi_handle, len); 7069 if (!buf) { 7070 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7071 return QDF_STATUS_E_NOMEM; 7072 } 7073 7074 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7075 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7076 WMITLV_SET_HDR(&hlp_params->tlv_header, 7077 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7078 WMITLV_GET_STRUCT_TLVLEN( 7079 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7080 7081 hlp_params->vdev_id = params->vdev_id; 7082 hlp_params->size = params->hlp_ie_len; 7083 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7084 7085 buf_ptr += sizeof(*hlp_params); 7086 7087 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7088 round_up(params->hlp_ie_len, 7089 sizeof(uint32_t))); 7090 buf_ptr += WMI_TLV_HDR_SIZE; 7091 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7092 7093 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7094 hlp_params->vdev_id, hlp_params->size); 7095 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7096 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7097 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7098 wmi_buf_free(buf); 7099 return QDF_STATUS_E_FAILURE; 7100 } 7101 7102 return QDF_STATUS_SUCCESS; 7103 } 7104 #endif 7105 7106 /** send_set_epno_network_list_cmd_tlv() - set epno network list 7107 * @wmi_handle: wmi handle 7108 * @req: epno config params request structure 7109 * 7110 * This function reads the incoming epno config request structure 7111 * and constructs the WMI message to the firmware. 7112 * 7113 * Returns: 0 on success, error number otherwise 7114 */ 7115 static QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle, 7116 struct wifi_enhanched_pno_params *req) 7117 { 7118 wmi_nlo_config_cmd_fixed_param *cmd; 7119 nlo_configured_parameters *nlo_list; 7120 enlo_candidate_score_params *cand_score_params; 7121 u_int8_t i, *buf_ptr; 7122 wmi_buf_t buf; 7123 uint32_t len; 7124 QDF_STATUS ret; 7125 7126 /* Fixed Params */ 7127 len = sizeof(*cmd); 7128 if (req->num_networks) { 7129 /* TLV place holder for array of structures 7130 * then each nlo_configured_parameters(nlo_list) TLV. 7131 */ 7132 len += WMI_TLV_HDR_SIZE; 7133 len += (sizeof(nlo_configured_parameters) 7134 * QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS)); 7135 /* TLV for array of uint32 channel_list */ 7136 len += WMI_TLV_HDR_SIZE; 7137 /* TLV for nlo_channel_prediction_cfg */ 7138 len += WMI_TLV_HDR_SIZE; 7139 /* TLV for candidate score params */ 7140 len += sizeof(enlo_candidate_score_params); 7141 } 7142 7143 buf = wmi_buf_alloc(wmi_handle, len); 7144 if (!buf) { 7145 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7146 return QDF_STATUS_E_NOMEM; 7147 } 7148 7149 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7150 7151 buf_ptr = (u_int8_t *) cmd; 7152 WMITLV_SET_HDR(&cmd->tlv_header, 7153 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7154 WMITLV_GET_STRUCT_TLVLEN( 7155 wmi_nlo_config_cmd_fixed_param)); 7156 cmd->vdev_id = req->session_id; 7157 7158 /* set flag to reset if num of networks are 0 */ 7159 cmd->flags = (req->num_networks == 0 ? 7160 WMI_NLO_CONFIG_ENLO_RESET : WMI_NLO_CONFIG_ENLO); 7161 7162 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7163 7164 cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS); 7165 WMI_LOGD("SSID count: %d flags: %d", 7166 cmd->no_of_ssids, cmd->flags); 7167 7168 /* Fill nlo_config only when num_networks are non zero */ 7169 if (cmd->no_of_ssids) { 7170 /* Fill networks */ 7171 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7172 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7173 buf_ptr += WMI_TLV_HDR_SIZE; 7174 7175 nlo_list = (nlo_configured_parameters *) buf_ptr; 7176 for (i = 0; i < cmd->no_of_ssids; i++) { 7177 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7178 WMITLV_TAG_ARRAY_BYTE, 7179 WMITLV_GET_STRUCT_TLVLEN( 7180 nlo_configured_parameters)); 7181 /* Copy ssid and it's length */ 7182 nlo_list[i].ssid.valid = true; 7183 nlo_list[i].ssid.ssid.ssid_len = 7184 req->networks[i].ssid.length; 7185 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7186 req->networks[i].ssid.mac_ssid, 7187 nlo_list[i].ssid.ssid.ssid_len); 7188 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7189 nlo_list[i].ssid.ssid.ssid_len, 7190 (char *) nlo_list[i].ssid.ssid.ssid, 7191 nlo_list[i].ssid.ssid.ssid_len); 7192 7193 /* Copy pno flags */ 7194 nlo_list[i].bcast_nw_type.valid = true; 7195 nlo_list[i].bcast_nw_type.bcast_nw_type = 7196 req->networks[i].flags; 7197 WMI_LOGD("PNO flags (%u)", 7198 nlo_list[i].bcast_nw_type.bcast_nw_type); 7199 7200 /* Copy auth bit field */ 7201 nlo_list[i].auth_type.valid = true; 7202 nlo_list[i].auth_type.auth_type = 7203 req->networks[i].auth_bit_field; 7204 WMI_LOGD("Auth bit field (%u)", 7205 nlo_list[i].auth_type.auth_type); 7206 } 7207 7208 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7209 /* Fill the channel list */ 7210 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7211 buf_ptr += WMI_TLV_HDR_SIZE; 7212 7213 /* Fill prediction_param */ 7214 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7215 buf_ptr += WMI_TLV_HDR_SIZE; 7216 7217 /* Fill epno candidate score params */ 7218 cand_score_params = (enlo_candidate_score_params *) buf_ptr; 7219 WMITLV_SET_HDR(buf_ptr, 7220 WMITLV_TAG_STRUC_enlo_candidate_score_param, 7221 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7222 cand_score_params->min5GHz_rssi = 7223 req->min_5ghz_rssi; 7224 cand_score_params->min24GHz_rssi = 7225 req->min_24ghz_rssi; 7226 cand_score_params->initial_score_max = 7227 req->initial_score_max; 7228 cand_score_params->current_connection_bonus = 7229 req->current_connection_bonus; 7230 cand_score_params->same_network_bonus = 7231 req->same_network_bonus; 7232 cand_score_params->secure_bonus = 7233 req->secure_bonus; 7234 cand_score_params->band5GHz_bonus = 7235 req->band_5ghz_bonus; 7236 buf_ptr += sizeof(enlo_candidate_score_params); 7237 } 7238 7239 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7240 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7241 if (QDF_IS_STATUS_ERROR(ret)) { 7242 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7243 wmi_buf_free(buf); 7244 return QDF_STATUS_E_INVAL; 7245 } 7246 7247 WMI_LOGD("set ePNO list request sent successfully for vdev %d", 7248 req->session_id); 7249 7250 return ret; 7251 } 7252 7253 7254 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7255 * @wmi_handle: wmi handle 7256 * @ipa_offload: ipa offload control parameter 7257 * 7258 * Returns: 0 on success, error number otherwise 7259 */ 7260 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7261 struct ipa_offload_control_params *ipa_offload) 7262 { 7263 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7264 wmi_buf_t wmi_buf; 7265 uint32_t len; 7266 u_int8_t *buf_ptr; 7267 7268 len = sizeof(*cmd); 7269 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7270 if (!wmi_buf) { 7271 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7272 return QDF_STATUS_E_NOMEM; 7273 } 7274 7275 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7276 ipa_offload->offload_type, ipa_offload->enable); 7277 7278 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7279 7280 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7281 WMITLV_SET_HDR(&cmd->tlv_header, 7282 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7283 WMITLV_GET_STRUCT_TLVLEN( 7284 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7285 7286 cmd->offload_type = ipa_offload->offload_type; 7287 cmd->vdev_id = ipa_offload->vdev_id; 7288 cmd->enable = ipa_offload->enable; 7289 7290 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7291 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7292 WMI_LOGE("%s: failed to command", __func__); 7293 wmi_buf_free(wmi_buf); 7294 return QDF_STATUS_E_FAILURE; 7295 } 7296 7297 return QDF_STATUS_SUCCESS; 7298 } 7299 7300 /** 7301 * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities 7302 * @wmi_handle: wmi handle 7303 * @pgetcapab: get capabilities params 7304 * 7305 * This function send request to fw to get extscan capabilities. 7306 * 7307 * Return: CDF status 7308 */ 7309 static QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle, 7310 struct extscan_capabilities_params *pgetcapab) 7311 { 7312 wmi_extscan_get_capabilities_cmd_fixed_param *cmd; 7313 wmi_buf_t wmi_buf; 7314 uint32_t len; 7315 uint8_t *buf_ptr; 7316 7317 len = sizeof(*cmd); 7318 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7319 if (!wmi_buf) { 7320 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7321 return QDF_STATUS_E_NOMEM; 7322 } 7323 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7324 7325 cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr; 7326 WMITLV_SET_HDR(&cmd->tlv_header, 7327 WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, 7328 WMITLV_GET_STRUCT_TLVLEN 7329 (wmi_extscan_get_capabilities_cmd_fixed_param)); 7330 7331 cmd->request_id = pgetcapab->request_id; 7332 7333 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7334 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) { 7335 WMI_LOGE("%s: failed to command", __func__); 7336 wmi_buf_free(wmi_buf); 7337 return QDF_STATUS_E_FAILURE; 7338 } 7339 return QDF_STATUS_SUCCESS; 7340 } 7341 7342 /** 7343 * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results 7344 * @wmi_handle: wmi handle 7345 * @pcached_results: cached results parameters 7346 * 7347 * This function send request to fw to get cached results. 7348 * 7349 * Return: CDF status 7350 */ 7351 static QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle, 7352 struct extscan_cached_result_params *pcached_results) 7353 { 7354 wmi_extscan_get_cached_results_cmd_fixed_param *cmd; 7355 wmi_buf_t wmi_buf; 7356 uint32_t len; 7357 uint8_t *buf_ptr; 7358 7359 len = sizeof(*cmd); 7360 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7361 if (!wmi_buf) { 7362 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7363 return QDF_STATUS_E_NOMEM; 7364 } 7365 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7366 7367 cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr; 7368 WMITLV_SET_HDR(&cmd->tlv_header, 7369 WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, 7370 WMITLV_GET_STRUCT_TLVLEN 7371 (wmi_extscan_get_cached_results_cmd_fixed_param)); 7372 7373 cmd->request_id = pcached_results->request_id; 7374 cmd->vdev_id = pcached_results->session_id; 7375 cmd->control_flags = pcached_results->flush; 7376 7377 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7378 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) { 7379 WMI_LOGE("%s: failed to command", __func__); 7380 wmi_buf_free(wmi_buf); 7381 return QDF_STATUS_E_FAILURE; 7382 } 7383 return QDF_STATUS_SUCCESS; 7384 } 7385 7386 /** 7387 * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd 7388 * @wmi_handle: wmi handle 7389 * @reset_req: Reset change request params 7390 * 7391 * This function sends stop change monitor request to fw. 7392 * 7393 * Return: CDF status 7394 */ 7395 static QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7396 struct extscan_capabilities_reset_params *reset_req) 7397 { 7398 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7399 wmi_buf_t wmi_buf; 7400 uint32_t len; 7401 uint8_t *buf_ptr; 7402 int change_list = 0; 7403 7404 len = sizeof(*cmd); 7405 7406 /* reset significant change tlv is set to 0 */ 7407 len += WMI_TLV_HDR_SIZE; 7408 len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param); 7409 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7410 if (!wmi_buf) { 7411 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7412 return QDF_STATUS_E_NOMEM; 7413 } 7414 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7415 7416 cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7417 buf_ptr; 7418 WMITLV_SET_HDR(&cmd->tlv_header, 7419 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7420 WMITLV_GET_STRUCT_TLVLEN 7421 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7422 7423 cmd->request_id = reset_req->request_id; 7424 cmd->vdev_id = reset_req->session_id; 7425 cmd->mode = 0; 7426 7427 buf_ptr += sizeof(*cmd); 7428 WMITLV_SET_HDR(buf_ptr, 7429 WMITLV_TAG_ARRAY_STRUC, 7430 change_list * 7431 sizeof(wmi_extscan_wlan_change_bssid_param)); 7432 buf_ptr += WMI_TLV_HDR_SIZE + (change_list * 7433 sizeof 7434 (wmi_extscan_wlan_change_bssid_param)); 7435 7436 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7437 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7438 WMI_LOGE("%s: failed to command", __func__); 7439 wmi_buf_free(wmi_buf); 7440 return QDF_STATUS_E_FAILURE; 7441 } 7442 return QDF_STATUS_SUCCESS; 7443 } 7444 7445 /** 7446 * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request 7447 * @wmi_handle: wmi handle 7448 * @psigchange: change monitor request params 7449 * @buf: wmi buffer 7450 * @buf_len: buffer length 7451 * 7452 * This function fills elements of change monitor request buffer. 7453 * 7454 * Return: CDF status 7455 */ 7456 static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd(wmi_unified_t wmi_handle, 7457 struct extscan_set_sig_changereq_params 7458 *psigchange, wmi_buf_t *buf, int *buf_len) 7459 { 7460 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7461 wmi_extscan_wlan_change_bssid_param *dest_chglist; 7462 uint8_t *buf_ptr; 7463 int j; 7464 int len = sizeof(*cmd); 7465 uint32_t numap = psigchange->num_ap; 7466 struct ap_threshold_params *src_ap = psigchange->ap; 7467 7468 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) { 7469 WMI_LOGE("%s: Invalid number of bssid's", __func__); 7470 return QDF_STATUS_E_INVAL; 7471 } 7472 len += WMI_TLV_HDR_SIZE; 7473 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param); 7474 7475 *buf = wmi_buf_alloc(wmi_handle, len); 7476 if (!*buf) { 7477 WMI_LOGP("%s: failed to allocate memory for change monitor cmd", 7478 __func__); 7479 return QDF_STATUS_E_FAILURE; 7480 } 7481 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7482 cmd = 7483 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7484 buf_ptr; 7485 WMITLV_SET_HDR(&cmd->tlv_header, 7486 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7487 WMITLV_GET_STRUCT_TLVLEN 7488 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7489 7490 cmd->request_id = psigchange->request_id; 7491 cmd->vdev_id = psigchange->session_id; 7492 cmd->total_entries = numap; 7493 cmd->mode = 1; 7494 cmd->num_entries_in_page = numap; 7495 cmd->lost_ap_scan_count = psigchange->lostap_sample_size; 7496 cmd->max_rssi_samples = psigchange->rssi_sample_size; 7497 cmd->rssi_averaging_samples = psigchange->rssi_sample_size; 7498 cmd->max_out_of_range_count = psigchange->min_breaching; 7499 7500 buf_ptr += sizeof(*cmd); 7501 WMITLV_SET_HDR(buf_ptr, 7502 WMITLV_TAG_ARRAY_STRUC, 7503 numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7504 dest_chglist = (wmi_extscan_wlan_change_bssid_param *) 7505 (buf_ptr + WMI_TLV_HDR_SIZE); 7506 7507 for (j = 0; j < numap; j++) { 7508 WMITLV_SET_HDR(dest_chglist, 7509 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7510 WMITLV_GET_STRUCT_TLVLEN 7511 (wmi_extscan_wlan_change_bssid_param)); 7512 7513 dest_chglist->lower_rssi_limit = src_ap->low; 7514 dest_chglist->upper_rssi_limit = src_ap->high; 7515 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 7516 &dest_chglist->bssid); 7517 7518 WMI_LOGD("%s: min_rssi %d", __func__, 7519 dest_chglist->lower_rssi_limit); 7520 dest_chglist++; 7521 src_ap++; 7522 } 7523 buf_ptr += WMI_TLV_HDR_SIZE + 7524 (numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7525 *buf_len = len; 7526 return QDF_STATUS_SUCCESS; 7527 } 7528 7529 /** 7530 * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd 7531 * @wmi_handle: wmi handle 7532 * @psigchange: change monitor request params 7533 * 7534 * This function sends start change monitor request to fw. 7535 * 7536 * Return: CDF status 7537 */ 7538 static QDF_STATUS send_extscan_start_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7539 struct extscan_set_sig_changereq_params * 7540 psigchange) 7541 { 7542 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7543 wmi_buf_t buf; 7544 int len; 7545 7546 7547 qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle, 7548 psigchange, &buf, 7549 &len); 7550 if (qdf_status != QDF_STATUS_SUCCESS) { 7551 WMI_LOGE("%s: Failed to get buffer for change monitor cmd", 7552 __func__); 7553 return QDF_STATUS_E_FAILURE; 7554 } 7555 if (!buf) { 7556 WMI_LOGE("%s: Failed to get buffer", __func__); 7557 return QDF_STATUS_E_FAILURE; 7558 } 7559 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7560 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7561 WMI_LOGE("%s: failed to send command", __func__); 7562 wmi_buf_free(buf); 7563 return QDF_STATUS_E_FAILURE; 7564 } 7565 return QDF_STATUS_SUCCESS; 7566 } 7567 7568 /** 7569 * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor 7570 * @wmi_handle: wmi handle 7571 * @photlist_reset: hotlist reset params 7572 * 7573 * This function configures hotlist monitor to stop in fw. 7574 * 7575 * Return: CDF status 7576 */ 7577 static QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7578 struct extscan_bssid_hotlist_reset_params *photlist_reset) 7579 { 7580 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; 7581 wmi_buf_t wmi_buf; 7582 uint32_t len; 7583 uint8_t *buf_ptr; 7584 int hotlist_entries = 0; 7585 7586 len = sizeof(*cmd); 7587 7588 /* reset bssid hotlist with tlv set to 0 */ 7589 len += WMI_TLV_HDR_SIZE; 7590 len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry); 7591 7592 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7593 if (!wmi_buf) { 7594 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7595 return QDF_STATUS_E_NOMEM; 7596 } 7597 7598 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7599 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 7600 buf_ptr; 7601 WMITLV_SET_HDR(&cmd->tlv_header, 7602 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 7603 WMITLV_GET_STRUCT_TLVLEN 7604 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 7605 7606 cmd->request_id = photlist_reset->request_id; 7607 cmd->vdev_id = photlist_reset->session_id; 7608 cmd->mode = 0; 7609 7610 buf_ptr += sizeof(*cmd); 7611 WMITLV_SET_HDR(buf_ptr, 7612 WMITLV_TAG_ARRAY_STRUC, 7613 hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7614 buf_ptr += WMI_TLV_HDR_SIZE + 7615 (hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7616 7617 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7618 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 7619 WMI_LOGE("%s: failed to command", __func__); 7620 wmi_buf_free(wmi_buf); 7621 return QDF_STATUS_E_FAILURE; 7622 } 7623 return QDF_STATUS_SUCCESS; 7624 } 7625 7626 /** 7627 * send_stop_extscan_cmd_tlv() - stop extscan command to fw. 7628 * @wmi_handle: wmi handle 7629 * @pstopcmd: stop scan command request params 7630 * 7631 * This function sends stop extscan request to fw. 7632 * 7633 * Return: CDF Status. 7634 */ 7635 static QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7636 struct extscan_stop_req_params *pstopcmd) 7637 { 7638 wmi_extscan_stop_cmd_fixed_param *cmd; 7639 wmi_buf_t wmi_buf; 7640 uint32_t len; 7641 uint8_t *buf_ptr; 7642 7643 len = sizeof(*cmd); 7644 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7645 if (!wmi_buf) { 7646 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7647 return QDF_STATUS_E_NOMEM; 7648 } 7649 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7650 cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr; 7651 WMITLV_SET_HDR(&cmd->tlv_header, 7652 WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, 7653 WMITLV_GET_STRUCT_TLVLEN 7654 (wmi_extscan_stop_cmd_fixed_param)); 7655 7656 cmd->request_id = pstopcmd->request_id; 7657 cmd->vdev_id = pstopcmd->session_id; 7658 7659 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7660 WMI_EXTSCAN_STOP_CMDID)) { 7661 WMI_LOGE("%s: failed to command", __func__); 7662 wmi_buf_free(wmi_buf); 7663 return QDF_STATUS_E_FAILURE; 7664 } 7665 7666 return QDF_STATUS_SUCCESS; 7667 } 7668 7669 /** 7670 * wmi_get_buf_extscan_start_cmd() - Fill extscan start request 7671 * @wmi_handle: wmi handle 7672 * @pstart: scan command request params 7673 * @buf: event buffer 7674 * @buf_len: length of buffer 7675 * 7676 * This function fills individual elements of extscan request and 7677 * TLV for buckets, channel list. 7678 * 7679 * Return: CDF Status. 7680 */ 7681 static 7682 QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle, 7683 struct wifi_scan_cmd_req_params *pstart, 7684 wmi_buf_t *buf, int *buf_len) 7685 { 7686 wmi_extscan_start_cmd_fixed_param *cmd; 7687 wmi_extscan_bucket *dest_blist; 7688 wmi_extscan_bucket_channel *dest_clist; 7689 struct wifi_scan_bucket_params *src_bucket = pstart->buckets; 7690 struct wifi_scan_channelspec_params *src_channel = src_bucket->channels; 7691 struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS]; 7692 7693 uint8_t *buf_ptr; 7694 int i, k, count = 0; 7695 int len = sizeof(*cmd); 7696 int nbuckets = pstart->numBuckets; 7697 int nchannels = 0; 7698 7699 /* These TLV's are are NULL by default */ 7700 uint32_t ie_len_with_pad = 0; 7701 int num_ssid = 0; 7702 int num_bssid = 0; 7703 int ie_len = 0; 7704 7705 uint32_t base_period = pstart->basePeriod; 7706 7707 /* TLV placeholder for ssid_list (NULL) */ 7708 len += WMI_TLV_HDR_SIZE; 7709 len += num_ssid * sizeof(wmi_ssid); 7710 7711 /* TLV placeholder for bssid_list (NULL) */ 7712 len += WMI_TLV_HDR_SIZE; 7713 len += num_bssid * sizeof(wmi_mac_addr); 7714 7715 /* TLV placeholder for ie_data (NULL) */ 7716 len += WMI_TLV_HDR_SIZE; 7717 len += ie_len * sizeof(uint32_t); 7718 7719 /* TLV placeholder for bucket */ 7720 len += WMI_TLV_HDR_SIZE; 7721 len += nbuckets * sizeof(wmi_extscan_bucket); 7722 7723 /* TLV channel placeholder */ 7724 len += WMI_TLV_HDR_SIZE; 7725 for (i = 0; i < nbuckets; i++) { 7726 nchannels += src_bucket->numChannels; 7727 src_bucket++; 7728 } 7729 7730 WMI_LOGD("%s: Total buckets: %d total #of channels is %d", 7731 __func__, nbuckets, nchannels); 7732 len += nchannels * sizeof(wmi_extscan_bucket_channel); 7733 /* Allocate the memory */ 7734 *buf = wmi_buf_alloc(wmi_handle, len); 7735 if (!*buf) { 7736 WMI_LOGP("%s: failed to allocate memory" 7737 " for start extscan cmd", __func__); 7738 return QDF_STATUS_E_NOMEM; 7739 } 7740 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7741 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr; 7742 WMITLV_SET_HDR(&cmd->tlv_header, 7743 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, 7744 WMITLV_GET_STRUCT_TLVLEN 7745 (wmi_extscan_start_cmd_fixed_param)); 7746 7747 cmd->request_id = pstart->requestId; 7748 cmd->vdev_id = pstart->sessionId; 7749 cmd->base_period = pstart->basePeriod; 7750 cmd->num_buckets = nbuckets; 7751 cmd->configuration_flags = 0; 7752 if (pstart->configuration_flags & WMI_EXTSCAN_LP_EXTENDED_BATCHING) 7753 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN; 7754 WMI_LOGI("%s: configuration_flags: 0x%x", __func__, 7755 cmd->configuration_flags); 7756 #ifdef FEATURE_WLAN_EXTSCAN 7757 cmd->min_rest_time = WMI_EXTSCAN_REST_TIME; 7758 cmd->max_rest_time = WMI_EXTSCAN_REST_TIME; 7759 cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME; 7760 cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION; 7761 #endif 7762 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7763 7764 /* The max dwell time is retrieved from the first channel 7765 * of the first bucket and kept common for all channels. 7766 */ 7767 cmd->min_dwell_time_active = pstart->min_dwell_time_active; 7768 cmd->max_dwell_time_active = pstart->max_dwell_time_active; 7769 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive; 7770 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive; 7771 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7772 cmd->max_table_usage = pstart->report_threshold_percent; 7773 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans; 7774 7775 cmd->repeat_probe_time = cmd->max_dwell_time_active / 7776 WMI_SCAN_NPROBES_DEFAULT; 7777 cmd->probe_delay = 0; 7778 cmd->probe_spacing_time = 0; 7779 cmd->idle_time = 0; 7780 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ | 7781 WMI_SCAN_ADD_CCK_RATES | 7782 WMI_SCAN_ADD_OFDM_RATES | 7783 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ | 7784 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 7785 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 7786 pstart->extscan_adaptive_dwell_mode); 7787 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_LOW; 7788 cmd->num_ssids = 0; 7789 cmd->num_bssid = 0; 7790 cmd->ie_len = 0; 7791 cmd->n_probes = (cmd->repeat_probe_time > 0) ? 7792 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0; 7793 7794 buf_ptr += sizeof(*cmd); 7795 WMITLV_SET_HDR(buf_ptr, 7796 WMITLV_TAG_ARRAY_FIXED_STRUC, 7797 num_ssid * sizeof(wmi_ssid)); 7798 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid)); 7799 7800 WMITLV_SET_HDR(buf_ptr, 7801 WMITLV_TAG_ARRAY_FIXED_STRUC, 7802 num_bssid * sizeof(wmi_mac_addr)); 7803 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr)); 7804 7805 ie_len_with_pad = 0; 7806 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7807 ie_len_with_pad); 7808 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; 7809 7810 WMITLV_SET_HDR(buf_ptr, 7811 WMITLV_TAG_ARRAY_STRUC, 7812 nbuckets * sizeof(wmi_extscan_bucket)); 7813 dest_blist = (wmi_extscan_bucket *) 7814 (buf_ptr + WMI_TLV_HDR_SIZE); 7815 src_bucket = pstart->buckets; 7816 7817 /* Retrieve scanning information from each bucket and 7818 * channels and send it to the target 7819 */ 7820 for (i = 0; i < nbuckets; i++) { 7821 WMITLV_SET_HDR(dest_blist, 7822 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7823 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket)); 7824 7825 dest_blist->bucket_id = src_bucket->bucket; 7826 dest_blist->base_period_multiplier = 7827 src_bucket->period / base_period; 7828 dest_blist->min_period = src_bucket->period; 7829 dest_blist->max_period = src_bucket->max_period; 7830 dest_blist->exp_backoff = src_bucket->exponent; 7831 dest_blist->exp_max_step_count = src_bucket->step_count; 7832 dest_blist->channel_band = src_bucket->band; 7833 dest_blist->num_channels = src_bucket->numChannels; 7834 dest_blist->notify_extscan_events = 0; 7835 7836 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN) 7837 dest_blist->notify_extscan_events = 7838 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | 7839 WMI_EXTSCAN_CYCLE_STARTED_EVENT; 7840 7841 if (src_bucket->reportEvents & 7842 WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) { 7843 dest_blist->forwarding_flags = 7844 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; 7845 dest_blist->notify_extscan_events |= 7846 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT | 7847 WMI_EXTSCAN_CYCLE_STARTED_EVENT | 7848 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT; 7849 } else { 7850 dest_blist->forwarding_flags = 7851 WMI_EXTSCAN_NO_FORWARDING; 7852 } 7853 7854 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH) 7855 dest_blist->configuration_flags = 0; 7856 else 7857 dest_blist->configuration_flags = 7858 WMI_EXTSCAN_BUCKET_CACHE_RESULTS; 7859 7860 WMI_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u", 7861 __func__, dest_blist->notify_extscan_events, 7862 dest_blist->configuration_flags, 7863 dest_blist->forwarding_flags); 7864 7865 dest_blist->min_dwell_time_active = 7866 src_bucket->min_dwell_time_active; 7867 dest_blist->max_dwell_time_active = 7868 src_bucket->max_dwell_time_active; 7869 dest_blist->min_dwell_time_passive = 7870 src_bucket->min_dwell_time_passive; 7871 dest_blist->max_dwell_time_passive = 7872 src_bucket->max_dwell_time_passive; 7873 src_channel = src_bucket->channels; 7874 7875 /* save the channel info to later populate 7876 * the channel TLV 7877 */ 7878 for (k = 0; k < src_bucket->numChannels; k++) { 7879 save_channel[count++].channel = src_channel->channel; 7880 src_channel++; 7881 } 7882 dest_blist++; 7883 src_bucket++; 7884 } 7885 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket)); 7886 WMITLV_SET_HDR(buf_ptr, 7887 WMITLV_TAG_ARRAY_STRUC, 7888 nchannels * sizeof(wmi_extscan_bucket_channel)); 7889 dest_clist = (wmi_extscan_bucket_channel *) 7890 (buf_ptr + WMI_TLV_HDR_SIZE); 7891 7892 /* Active or passive scan is based on the bucket dwell time 7893 * and channel specific active,passive scans are not 7894 * supported yet 7895 */ 7896 for (i = 0; i < nchannels; i++) { 7897 WMITLV_SET_HDR(dest_clist, 7898 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, 7899 WMITLV_GET_STRUCT_TLVLEN 7900 (wmi_extscan_bucket_channel)); 7901 dest_clist->channel = save_channel[i].channel; 7902 dest_clist++; 7903 } 7904 buf_ptr += WMI_TLV_HDR_SIZE + 7905 (nchannels * sizeof(wmi_extscan_bucket_channel)); 7906 *buf_len = len; 7907 return QDF_STATUS_SUCCESS; 7908 } 7909 7910 /** 7911 * send_start_extscan_cmd_tlv() - start extscan command to fw. 7912 * @wmi_handle: wmi handle 7913 * @pstart: scan command request params 7914 * 7915 * This function sends start extscan request to fw. 7916 * 7917 * Return: CDF Status. 7918 */ 7919 static QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7920 struct wifi_scan_cmd_req_params *pstart) 7921 { 7922 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7923 wmi_buf_t buf; 7924 int len; 7925 7926 /* Fill individual elements of extscan request and 7927 * TLV for buckets, channel list. 7928 */ 7929 qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle, 7930 pstart, &buf, &len); 7931 if (qdf_status != QDF_STATUS_SUCCESS) { 7932 WMI_LOGE("%s: Failed to get buffer for ext scan cmd", __func__); 7933 return QDF_STATUS_E_FAILURE; 7934 } 7935 if (!buf) { 7936 WMI_LOGE("%s:Failed to get buffer" 7937 "for current extscan info", __func__); 7938 return QDF_STATUS_E_FAILURE; 7939 } 7940 if (wmi_unified_cmd_send(wmi_handle, buf, 7941 len, WMI_EXTSCAN_START_CMDID)) { 7942 WMI_LOGE("%s: failed to send command", __func__); 7943 wmi_buf_free(buf); 7944 return QDF_STATUS_E_FAILURE; 7945 } 7946 7947 return QDF_STATUS_SUCCESS; 7948 } 7949 7950 /** 7951 * send_plm_stop_cmd_tlv() - plm stop request 7952 * @wmi_handle: wmi handle 7953 * @plm: plm request parameters 7954 * 7955 * This function request FW to stop PLM. 7956 * 7957 * Return: CDF status 7958 */ 7959 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7960 const struct plm_req_params *plm) 7961 { 7962 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7963 int32_t len; 7964 wmi_buf_t buf; 7965 uint8_t *buf_ptr; 7966 int ret; 7967 7968 len = sizeof(*cmd); 7969 buf = wmi_buf_alloc(wmi_handle, len); 7970 if (!buf) { 7971 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7972 return QDF_STATUS_E_NOMEM; 7973 } 7974 7975 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7976 7977 buf_ptr = (uint8_t *) cmd; 7978 7979 WMITLV_SET_HDR(&cmd->tlv_header, 7980 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7981 WMITLV_GET_STRUCT_TLVLEN 7982 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7983 7984 cmd->vdev_id = plm->session_id; 7985 7986 cmd->meas_token = plm->meas_token; 7987 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7988 7989 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7990 WMI_VDEV_PLMREQ_STOP_CMDID); 7991 if (ret) { 7992 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7993 wmi_buf_free(buf); 7994 return QDF_STATUS_E_FAILURE; 7995 } 7996 7997 return QDF_STATUS_SUCCESS; 7998 } 7999 8000 /** 8001 * send_plm_start_cmd_tlv() - plm start request 8002 * @wmi_handle: wmi handle 8003 * @plm: plm request parameters 8004 * 8005 * This function request FW to start PLM. 8006 * 8007 * Return: CDF status 8008 */ 8009 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 8010 const struct plm_req_params *plm, 8011 uint32_t *gchannel_list) 8012 { 8013 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 8014 uint32_t *channel_list; 8015 int32_t len; 8016 wmi_buf_t buf; 8017 uint8_t *buf_ptr; 8018 uint8_t count; 8019 int ret; 8020 8021 /* TLV place holder for channel_list */ 8022 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8023 len += sizeof(uint32_t) * plm->plm_num_ch; 8024 8025 buf = wmi_buf_alloc(wmi_handle, len); 8026 if (!buf) { 8027 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8028 return QDF_STATUS_E_NOMEM; 8029 } 8030 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 8031 8032 buf_ptr = (uint8_t *) cmd; 8033 8034 WMITLV_SET_HDR(&cmd->tlv_header, 8035 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 8036 WMITLV_GET_STRUCT_TLVLEN 8037 (wmi_vdev_plmreq_start_cmd_fixed_param)); 8038 8039 cmd->vdev_id = plm->session_id; 8040 8041 cmd->meas_token = plm->meas_token; 8042 cmd->dialog_token = plm->diag_token; 8043 cmd->number_bursts = plm->num_bursts; 8044 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 8045 cmd->off_duration = plm->meas_duration; 8046 cmd->burst_cycle = plm->burst_len; 8047 cmd->tx_power = plm->desired_tx_pwr; 8048 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 8049 cmd->num_chans = plm->plm_num_ch; 8050 8051 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 8052 8053 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 8054 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 8055 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 8056 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 8057 WMI_LOGD("off_duration: %d", cmd->off_duration); 8058 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 8059 WMI_LOGD("tx_power: %d", cmd->tx_power); 8060 WMI_LOGD("Number of channels : %d", cmd->num_chans); 8061 8062 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8063 (cmd->num_chans * sizeof(uint32_t))); 8064 8065 buf_ptr += WMI_TLV_HDR_SIZE; 8066 if (cmd->num_chans) { 8067 channel_list = (uint32_t *) buf_ptr; 8068 for (count = 0; count < cmd->num_chans; count++) { 8069 channel_list[count] = plm->plm_ch_list[count]; 8070 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 8071 channel_list[count] = 8072 gchannel_list[count]; 8073 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 8074 } 8075 buf_ptr += cmd->num_chans * sizeof(uint32_t); 8076 } 8077 8078 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8079 WMI_VDEV_PLMREQ_START_CMDID); 8080 if (ret) { 8081 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 8082 wmi_buf_free(buf); 8083 return QDF_STATUS_E_FAILURE; 8084 } 8085 8086 return QDF_STATUS_SUCCESS; 8087 } 8088 8089 /** 8090 * send_pno_stop_cmd_tlv() - PNO stop request 8091 * @wmi_handle: wmi handle 8092 * @vdev_id: vdev id 8093 * 8094 * This function request FW to stop ongoing PNO operation. 8095 * 8096 * Return: CDF status 8097 */ 8098 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8099 { 8100 wmi_nlo_config_cmd_fixed_param *cmd; 8101 int32_t len = sizeof(*cmd); 8102 wmi_buf_t buf; 8103 uint8_t *buf_ptr; 8104 int ret; 8105 8106 /* 8107 * TLV place holder for array of structures nlo_configured_parameters 8108 * TLV place holder for array of uint32_t channel_list 8109 * TLV place holder for chnl prediction cfg 8110 */ 8111 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8112 buf = wmi_buf_alloc(wmi_handle, len); 8113 if (!buf) { 8114 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8115 return QDF_STATUS_E_NOMEM; 8116 } 8117 8118 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8119 buf_ptr = (uint8_t *) cmd; 8120 8121 WMITLV_SET_HDR(&cmd->tlv_header, 8122 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8123 WMITLV_GET_STRUCT_TLVLEN 8124 (wmi_nlo_config_cmd_fixed_param)); 8125 8126 cmd->vdev_id = vdev_id; 8127 cmd->flags = WMI_NLO_CONFIG_STOP; 8128 buf_ptr += sizeof(*cmd); 8129 8130 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8131 buf_ptr += WMI_TLV_HDR_SIZE; 8132 8133 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 8134 buf_ptr += WMI_TLV_HDR_SIZE; 8135 8136 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8137 buf_ptr += WMI_TLV_HDR_SIZE; 8138 8139 8140 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8141 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8142 if (ret) { 8143 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8144 wmi_buf_free(buf); 8145 return QDF_STATUS_E_FAILURE; 8146 } 8147 8148 return QDF_STATUS_SUCCESS; 8149 } 8150 8151 /** 8152 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 8153 * @buf_ptr: Buffer passed by upper layers 8154 * @pno: Buffer to be sent to the firmware 8155 * 8156 * Copy the PNO Channel prediction configuration parameters 8157 * passed by the upper layers to a WMI format TLV and send it 8158 * down to the firmware. 8159 * 8160 * Return: None 8161 */ 8162 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 8163 struct pno_scan_req_params *pno) 8164 { 8165 nlo_channel_prediction_cfg *channel_prediction_cfg = 8166 (nlo_channel_prediction_cfg *) buf_ptr; 8167 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 8168 WMITLV_TAG_ARRAY_BYTE, 8169 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 8170 #ifdef FEATURE_WLAN_SCAN_PNO 8171 channel_prediction_cfg->enable = pno->pno_channel_prediction; 8172 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 8173 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 8174 channel_prediction_cfg->full_scan_period_ms = 8175 pno->channel_prediction_full_scan; 8176 #endif 8177 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8178 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 8179 channel_prediction_cfg->enable, 8180 channel_prediction_cfg->top_k_num, 8181 channel_prediction_cfg->stationary_threshold, 8182 channel_prediction_cfg->full_scan_period_ms); 8183 } 8184 8185 /** 8186 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 8187 * @wmi_handle: wmi handle 8188 * @params: configuration parameters 8189 * 8190 * Return: QDF_STATUS 8191 */ 8192 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 8193 struct nlo_mawc_params *params) 8194 { 8195 wmi_buf_t buf = NULL; 8196 QDF_STATUS status; 8197 int len; 8198 uint8_t *buf_ptr; 8199 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 8200 8201 len = sizeof(*wmi_nlo_mawc_params); 8202 buf = wmi_buf_alloc(wmi_handle, len); 8203 if (!buf) { 8204 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8205 return QDF_STATUS_E_NOMEM; 8206 } 8207 8208 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8209 wmi_nlo_mawc_params = 8210 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 8211 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 8212 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 8213 WMITLV_GET_STRUCT_TLVLEN 8214 (wmi_nlo_configure_mawc_cmd_fixed_param)); 8215 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 8216 if (params->enable) 8217 wmi_nlo_mawc_params->enable = 1; 8218 else 8219 wmi_nlo_mawc_params->enable = 0; 8220 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 8221 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 8222 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 8223 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 8224 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 8225 wmi_nlo_mawc_params->exp_backoff_ratio, 8226 wmi_nlo_mawc_params->init_scan_interval, 8227 wmi_nlo_mawc_params->max_scan_interval); 8228 8229 status = wmi_unified_cmd_send(wmi_handle, buf, 8230 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 8231 if (QDF_IS_STATUS_ERROR(status)) { 8232 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 8233 status); 8234 wmi_buf_free(buf); 8235 return QDF_STATUS_E_FAILURE; 8236 } 8237 8238 return QDF_STATUS_SUCCESS; 8239 } 8240 8241 /** 8242 * send_pno_start_cmd_tlv() - PNO start request 8243 * @wmi_handle: wmi handle 8244 * @pno: PNO request 8245 * 8246 * This function request FW to start PNO request. 8247 * Request: CDF status 8248 */ 8249 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 8250 struct pno_scan_req_params *pno) 8251 { 8252 wmi_nlo_config_cmd_fixed_param *cmd; 8253 nlo_configured_parameters *nlo_list; 8254 uint32_t *channel_list; 8255 int32_t len; 8256 wmi_buf_t buf; 8257 uint8_t *buf_ptr; 8258 uint8_t i; 8259 int ret; 8260 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 8261 connected_nlo_rssi_params *nlo_relative_rssi; 8262 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 8263 8264 /* 8265 * TLV place holder for array nlo_configured_parameters(nlo_list) 8266 * TLV place holder for array of uint32_t channel_list 8267 * TLV place holder for chnnl prediction cfg 8268 * TLV place holder for array of wmi_vendor_oui 8269 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 8270 */ 8271 len = sizeof(*cmd) + 8272 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 8273 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8274 8275 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 8276 WMI_NLO_MAX_CHAN); 8277 len += sizeof(nlo_configured_parameters) * 8278 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8279 len += sizeof(nlo_channel_prediction_cfg); 8280 len += sizeof(enlo_candidate_score_params); 8281 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 8282 len += sizeof(connected_nlo_rssi_params); 8283 len += sizeof(connected_nlo_bss_band_rssi_pref); 8284 8285 buf = wmi_buf_alloc(wmi_handle, len); 8286 if (!buf) { 8287 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8288 return QDF_STATUS_E_NOMEM; 8289 } 8290 8291 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8292 8293 buf_ptr = (uint8_t *) cmd; 8294 WMITLV_SET_HDR(&cmd->tlv_header, 8295 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8296 WMITLV_GET_STRUCT_TLVLEN 8297 (wmi_nlo_config_cmd_fixed_param)); 8298 cmd->vdev_id = pno->vdev_id; 8299 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 8300 8301 #ifdef FEATURE_WLAN_SCAN_PNO 8302 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 8303 pno->adaptive_dwell_mode); 8304 #endif 8305 /* Current FW does not support min-max range for dwell time */ 8306 cmd->active_dwell_time = pno->active_dwell_time; 8307 cmd->passive_dwell_time = pno->passive_dwell_time; 8308 8309 if (pno->do_passive_scan) 8310 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 8311 /* Copy scan interval */ 8312 cmd->fast_scan_period = pno->fast_scan_period; 8313 cmd->slow_scan_period = pno->slow_scan_period; 8314 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 8315 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 8316 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 8317 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 8318 cmd->fast_scan_period, cmd->slow_scan_period); 8319 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 8320 8321 /* mac randomization attributes */ 8322 if (pno->scan_random.randomize) { 8323 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 8324 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 8325 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 8326 pno->scan_random.mac_mask, 8327 &cmd->mac_addr, 8328 &cmd->mac_mask); 8329 } 8330 8331 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 8332 8333 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8334 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 8335 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8336 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 8337 buf_ptr += WMI_TLV_HDR_SIZE; 8338 8339 nlo_list = (nlo_configured_parameters *) buf_ptr; 8340 for (i = 0; i < cmd->no_of_ssids; i++) { 8341 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 8342 WMITLV_TAG_ARRAY_BYTE, 8343 WMITLV_GET_STRUCT_TLVLEN 8344 (nlo_configured_parameters)); 8345 /* Copy ssid and it's length */ 8346 nlo_list[i].ssid.valid = true; 8347 nlo_list[i].ssid.ssid.ssid_len = 8348 pno->networks_list[i].ssid.length; 8349 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 8350 pno->networks_list[i].ssid.ssid, 8351 nlo_list[i].ssid.ssid.ssid_len); 8352 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 8353 nlo_list[i].ssid.ssid.ssid_len, 8354 (char *)nlo_list[i].ssid.ssid.ssid, 8355 nlo_list[i].ssid.ssid.ssid_len); 8356 8357 /* Copy rssi threshold */ 8358 if (pno->networks_list[i].rssi_thresh && 8359 pno->networks_list[i].rssi_thresh > 8360 WMI_RSSI_THOLD_DEFAULT) { 8361 nlo_list[i].rssi_cond.valid = true; 8362 nlo_list[i].rssi_cond.rssi = 8363 pno->networks_list[i].rssi_thresh; 8364 WMI_LOGD("RSSI threshold : %d dBm", 8365 nlo_list[i].rssi_cond.rssi); 8366 } 8367 nlo_list[i].bcast_nw_type.valid = true; 8368 nlo_list[i].bcast_nw_type.bcast_nw_type = 8369 pno->networks_list[i].bc_new_type; 8370 WMI_LOGD("Broadcast NW type (%u)", 8371 nlo_list[i].bcast_nw_type.bcast_nw_type); 8372 } 8373 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 8374 8375 /* Copy channel info */ 8376 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 8377 WMI_NLO_MAX_CHAN); 8378 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 8379 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8380 (cmd->num_of_channels * sizeof(uint32_t))); 8381 buf_ptr += WMI_TLV_HDR_SIZE; 8382 8383 channel_list = (uint32_t *) buf_ptr; 8384 for (i = 0; i < cmd->num_of_channels; i++) { 8385 channel_list[i] = pno->networks_list[0].channels[i]; 8386 8387 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 8388 channel_list[i] = 8389 wlan_chan_to_freq(pno-> 8390 networks_list[0].channels[i]); 8391 8392 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 8393 } 8394 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 8395 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8396 sizeof(nlo_channel_prediction_cfg)); 8397 buf_ptr += WMI_TLV_HDR_SIZE; 8398 wmi_set_pno_channel_prediction(buf_ptr, pno); 8399 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8400 /** TODO: Discrete firmware doesn't have command/option to configure 8401 * App IE which comes from wpa_supplicant as of part PNO start request. 8402 */ 8403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 8404 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 8405 buf_ptr += sizeof(enlo_candidate_score_params); 8406 8407 if (ie_whitelist->white_list) { 8408 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 8409 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 8410 &cmd->num_vendor_oui, 8411 ie_whitelist); 8412 } 8413 8414 /* ie white list */ 8415 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8416 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 8417 buf_ptr += WMI_TLV_HDR_SIZE; 8418 if (cmd->num_vendor_oui != 0) { 8419 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 8420 ie_whitelist->voui); 8421 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 8422 } 8423 8424 if (pno->relative_rssi_set) 8425 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 8426 8427 /* 8428 * Firmware calculation using connected PNO params: 8429 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 8430 * deduction of rssi_pref for chosen band_pref and 8431 * addition of rssi_pref for remaining bands (other than chosen band). 8432 */ 8433 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 8434 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 8435 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 8436 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 8437 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 8438 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 8439 buf_ptr += sizeof(*nlo_relative_rssi); 8440 8441 /* 8442 * As of now Kernel and Host supports one band and rssi preference. 8443 * Firmware supports array of band and rssi preferences 8444 */ 8445 cmd->num_cnlo_band_pref = 1; 8446 WMITLV_SET_HDR(buf_ptr, 8447 WMITLV_TAG_ARRAY_STRUC, 8448 cmd->num_cnlo_band_pref * 8449 sizeof(connected_nlo_bss_band_rssi_pref)); 8450 buf_ptr += WMI_TLV_HDR_SIZE; 8451 8452 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 8453 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 8454 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 8455 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 8456 WMITLV_GET_STRUCT_TLVLEN( 8457 connected_nlo_bss_band_rssi_pref)); 8458 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 8459 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 8460 WMI_LOGI("band_pref %d, rssi_pref %d", 8461 nlo_band_rssi[i].band, 8462 nlo_band_rssi[i].rssi_pref); 8463 } 8464 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 8465 8466 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8467 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8468 if (ret) { 8469 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8470 wmi_buf_free(buf); 8471 return QDF_STATUS_E_FAILURE; 8472 } 8473 8474 return QDF_STATUS_SUCCESS; 8475 } 8476 8477 /* send_set_ric_req_cmd_tlv() - set ric request element 8478 * @wmi_handle: wmi handle 8479 * @msg: message 8480 * @is_add_ts: is addts required 8481 * 8482 * This function sets ric request element for 11r roaming. 8483 * 8484 * Return: CDF status 8485 */ 8486 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 8487 void *msg, uint8_t is_add_ts) 8488 { 8489 wmi_ric_request_fixed_param *cmd; 8490 wmi_ric_tspec *tspec_param; 8491 wmi_buf_t buf; 8492 uint8_t *buf_ptr; 8493 struct mac_tspec_ie *ptspecIE = NULL; 8494 int32_t len = sizeof(wmi_ric_request_fixed_param) + 8495 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 8496 8497 buf = wmi_buf_alloc(wmi_handle, len); 8498 if (!buf) { 8499 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8500 return QDF_STATUS_E_NOMEM; 8501 } 8502 8503 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8504 8505 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 8506 WMITLV_SET_HDR(&cmd->tlv_header, 8507 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 8508 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 8509 if (is_add_ts) 8510 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 8511 else 8512 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 8513 cmd->num_ric_request = 1; 8514 cmd->is_add_ric = is_add_ts; 8515 8516 buf_ptr += sizeof(wmi_ric_request_fixed_param); 8517 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 8518 8519 buf_ptr += WMI_TLV_HDR_SIZE; 8520 tspec_param = (wmi_ric_tspec *) buf_ptr; 8521 WMITLV_SET_HDR(&tspec_param->tlv_header, 8522 WMITLV_TAG_STRUC_wmi_ric_tspec, 8523 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 8524 8525 if (is_add_ts) 8526 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 8527 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 8528 else 8529 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 8530 #endif 8531 if (ptspecIE) { 8532 /* Fill the tsinfo in the format expected by firmware */ 8533 #ifndef ANI_LITTLE_BIT_ENDIAN 8534 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 8535 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8536 #else 8537 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 8538 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8539 #endif /* ANI_LITTLE_BIT_ENDIAN */ 8540 8541 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 8542 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 8543 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 8544 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 8545 tspec_param->inactivity_interval = ptspecIE->inactInterval; 8546 tspec_param->suspension_interval = ptspecIE->suspendInterval; 8547 tspec_param->svc_start_time = ptspecIE->svcStartTime; 8548 tspec_param->min_data_rate = ptspecIE->minDataRate; 8549 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 8550 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 8551 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 8552 tspec_param->delay_bound = ptspecIE->delayBound; 8553 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 8554 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 8555 tspec_param->medium_time = 0; 8556 } 8557 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 8558 8559 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8560 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 8561 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 8562 __func__); 8563 if (is_add_ts) 8564 ((struct add_ts_param *) msg)->status = 8565 QDF_STATUS_E_FAILURE; 8566 wmi_buf_free(buf); 8567 return QDF_STATUS_E_FAILURE; 8568 } 8569 8570 return QDF_STATUS_SUCCESS; 8571 } 8572 8573 /** 8574 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 8575 * @wmi_handle: wmi handle 8576 * @clear_req: ll stats clear request command params 8577 * 8578 * Return: QDF_STATUS_SUCCESS for success or error code 8579 */ 8580 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 8581 const struct ll_stats_clear_params *clear_req, 8582 uint8_t addr[IEEE80211_ADDR_LEN]) 8583 { 8584 wmi_clear_link_stats_cmd_fixed_param *cmd; 8585 int32_t len; 8586 wmi_buf_t buf; 8587 uint8_t *buf_ptr; 8588 int ret; 8589 8590 len = sizeof(*cmd); 8591 buf = wmi_buf_alloc(wmi_handle, len); 8592 8593 if (!buf) { 8594 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8595 return QDF_STATUS_E_NOMEM; 8596 } 8597 8598 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8599 qdf_mem_zero(buf_ptr, len); 8600 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 8601 8602 WMITLV_SET_HDR(&cmd->tlv_header, 8603 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 8604 WMITLV_GET_STRUCT_TLVLEN 8605 (wmi_clear_link_stats_cmd_fixed_param)); 8606 8607 cmd->stop_stats_collection_req = clear_req->stop_req; 8608 cmd->vdev_id = clear_req->sta_id; 8609 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 8610 8611 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8612 &cmd->peer_macaddr); 8613 8614 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 8615 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 8616 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 8617 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 8618 /* WMI_LOGD("Peer MAC Addr : %pM", 8619 cmd->peer_macaddr); */ 8620 8621 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8622 WMI_CLEAR_LINK_STATS_CMDID); 8623 if (ret) { 8624 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 8625 wmi_buf_free(buf); 8626 return QDF_STATUS_E_FAILURE; 8627 } 8628 8629 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 8630 return QDF_STATUS_SUCCESS; 8631 } 8632 8633 /** 8634 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 8635 * @wmi_handle: wmi handle 8636 * @setReq: ll stats set request command params 8637 * 8638 * Return: QDF_STATUS_SUCCESS for success or error code 8639 */ 8640 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 8641 const struct ll_stats_set_params *set_req) 8642 { 8643 wmi_start_link_stats_cmd_fixed_param *cmd; 8644 int32_t len; 8645 wmi_buf_t buf; 8646 uint8_t *buf_ptr; 8647 int ret; 8648 8649 len = sizeof(*cmd); 8650 buf = wmi_buf_alloc(wmi_handle, len); 8651 8652 if (!buf) { 8653 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8654 return QDF_STATUS_E_NOMEM; 8655 } 8656 8657 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8658 qdf_mem_zero(buf_ptr, len); 8659 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 8660 8661 WMITLV_SET_HDR(&cmd->tlv_header, 8662 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 8663 WMITLV_GET_STRUCT_TLVLEN 8664 (wmi_start_link_stats_cmd_fixed_param)); 8665 8666 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 8667 cmd->aggressive_statistics_gathering = 8668 set_req->aggressive_statistics_gathering; 8669 8670 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 8671 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 8672 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 8673 8674 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8675 WMI_START_LINK_STATS_CMDID); 8676 if (ret) { 8677 WMI_LOGE("%s: Failed to send set link stats request", __func__); 8678 wmi_buf_free(buf); 8679 return QDF_STATUS_E_FAILURE; 8680 } 8681 8682 return QDF_STATUS_SUCCESS; 8683 } 8684 8685 /** 8686 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 8687 * @wmi_handle:wmi handle 8688 * @get_req:ll stats get request command params 8689 * @addr: mac address 8690 * 8691 * Return: QDF_STATUS_SUCCESS for success or error code 8692 */ 8693 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 8694 const struct ll_stats_get_params *get_req, 8695 uint8_t addr[IEEE80211_ADDR_LEN]) 8696 { 8697 wmi_request_link_stats_cmd_fixed_param *cmd; 8698 int32_t len; 8699 wmi_buf_t buf; 8700 uint8_t *buf_ptr; 8701 int ret; 8702 8703 len = sizeof(*cmd); 8704 buf = wmi_buf_alloc(wmi_handle, len); 8705 8706 if (!buf) { 8707 WMI_LOGE("%s: buf allocation failed", __func__); 8708 return QDF_STATUS_E_NOMEM; 8709 } 8710 8711 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8712 qdf_mem_zero(buf_ptr, len); 8713 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 8714 8715 WMITLV_SET_HDR(&cmd->tlv_header, 8716 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 8717 WMITLV_GET_STRUCT_TLVLEN 8718 (wmi_request_link_stats_cmd_fixed_param)); 8719 8720 cmd->request_id = get_req->req_id; 8721 cmd->stats_type = get_req->param_id_mask; 8722 cmd->vdev_id = get_req->sta_id; 8723 8724 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8725 &cmd->peer_macaddr); 8726 8727 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 8728 WMI_LOGD("Request ID : %u", cmd->request_id); 8729 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 8730 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 8731 WMI_LOGD("Peer MAC Addr : %pM", addr); 8732 8733 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8734 WMI_REQUEST_LINK_STATS_CMDID); 8735 if (ret) { 8736 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8737 wmi_buf_free(buf); 8738 return QDF_STATUS_E_FAILURE; 8739 } 8740 8741 return QDF_STATUS_SUCCESS; 8742 } 8743 8744 8745 /** 8746 * send_congestion_cmd_tlv() - send request to fw to get CCA 8747 * @wmi_handle: wmi handle 8748 * @vdev_id: vdev id 8749 * 8750 * Return: CDF status 8751 */ 8752 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8753 A_UINT8 vdev_id) 8754 { 8755 wmi_buf_t buf; 8756 wmi_request_stats_cmd_fixed_param *cmd; 8757 uint8_t len; 8758 uint8_t *buf_ptr; 8759 8760 len = sizeof(*cmd); 8761 buf = wmi_buf_alloc(wmi_handle, len); 8762 if (!buf) { 8763 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8764 return QDF_STATUS_E_FAILURE; 8765 } 8766 8767 buf_ptr = wmi_buf_data(buf); 8768 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8769 WMITLV_SET_HDR(&cmd->tlv_header, 8770 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8771 WMITLV_GET_STRUCT_TLVLEN 8772 (wmi_request_stats_cmd_fixed_param)); 8773 8774 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8775 cmd->vdev_id = vdev_id; 8776 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8777 cmd->vdev_id, cmd->stats_id); 8778 8779 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8780 WMI_REQUEST_STATS_CMDID)) { 8781 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8782 __func__); 8783 wmi_buf_free(buf); 8784 return QDF_STATUS_E_FAILURE; 8785 } 8786 8787 return QDF_STATUS_SUCCESS; 8788 } 8789 8790 /** 8791 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8792 * @wmi_handle: wmi handle 8793 * @rssi_req: get RSSI request 8794 * 8795 * Return: CDF status 8796 */ 8797 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8798 { 8799 wmi_buf_t buf; 8800 wmi_request_stats_cmd_fixed_param *cmd; 8801 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8802 8803 buf = wmi_buf_alloc(wmi_handle, len); 8804 if (!buf) { 8805 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8806 return QDF_STATUS_E_FAILURE; 8807 } 8808 8809 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8810 WMITLV_SET_HDR(&cmd->tlv_header, 8811 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8812 WMITLV_GET_STRUCT_TLVLEN 8813 (wmi_request_stats_cmd_fixed_param)); 8814 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8815 if (wmi_unified_cmd_send 8816 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8817 WMI_LOGE("Failed to send host stats request to fw"); 8818 wmi_buf_free(buf); 8819 return QDF_STATUS_E_FAILURE; 8820 } 8821 8822 return QDF_STATUS_SUCCESS; 8823 } 8824 8825 /** 8826 * send_snr_cmd_tlv() - get RSSI from fw 8827 * @wmi_handle: wmi handle 8828 * @vdev_id: vdev id 8829 * 8830 * Return: CDF status 8831 */ 8832 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8833 { 8834 wmi_buf_t buf; 8835 wmi_request_stats_cmd_fixed_param *cmd; 8836 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8837 8838 buf = wmi_buf_alloc(wmi_handle, len); 8839 if (!buf) { 8840 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8841 return QDF_STATUS_E_FAILURE; 8842 } 8843 8844 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8845 cmd->vdev_id = vdev_id; 8846 8847 WMITLV_SET_HDR(&cmd->tlv_header, 8848 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8849 WMITLV_GET_STRUCT_TLVLEN 8850 (wmi_request_stats_cmd_fixed_param)); 8851 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8852 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8853 WMI_REQUEST_STATS_CMDID)) { 8854 WMI_LOGE("Failed to send host stats request to fw"); 8855 wmi_buf_free(buf); 8856 return QDF_STATUS_E_FAILURE; 8857 } 8858 8859 return QDF_STATUS_SUCCESS; 8860 } 8861 8862 /** 8863 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8864 * @wmi_handle: wmi handle 8865 * @link_status: get link params 8866 * 8867 * Return: CDF status 8868 */ 8869 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8870 struct link_status_params *link_status) 8871 { 8872 wmi_buf_t buf; 8873 wmi_request_stats_cmd_fixed_param *cmd; 8874 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8875 8876 buf = wmi_buf_alloc(wmi_handle, len); 8877 if (!buf) { 8878 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8879 return QDF_STATUS_E_FAILURE; 8880 } 8881 8882 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8883 WMITLV_SET_HDR(&cmd->tlv_header, 8884 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8885 WMITLV_GET_STRUCT_TLVLEN 8886 (wmi_request_stats_cmd_fixed_param)); 8887 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8888 cmd->vdev_id = link_status->session_id; 8889 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8890 WMI_REQUEST_STATS_CMDID)) { 8891 WMI_LOGE("Failed to send WMI link status request to fw"); 8892 wmi_buf_free(buf); 8893 return QDF_STATUS_E_FAILURE; 8894 } 8895 8896 return QDF_STATUS_SUCCESS; 8897 } 8898 8899 /** 8900 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8901 * @wmi_handle: wmi handle 8902 * @ta_dhcp_ind: DHCP indication parameter 8903 * 8904 * Return: CDF Status 8905 */ 8906 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8907 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8908 { 8909 QDF_STATUS status; 8910 wmi_buf_t buf = NULL; 8911 uint8_t *buf_ptr; 8912 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8913 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8914 8915 8916 buf = wmi_buf_alloc(wmi_handle, len); 8917 if (!buf) { 8918 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8919 return QDF_STATUS_E_NOMEM; 8920 } 8921 8922 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8923 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8924 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8925 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8926 WMITLV_GET_STRUCT_TLVLEN 8927 (wmi_peer_set_param_cmd_fixed_param)); 8928 8929 /* fill in values */ 8930 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8931 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8932 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8933 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8934 &ta_dhcp_ind->peer_macaddr, 8935 sizeof(ta_dhcp_ind->peer_macaddr)); 8936 8937 status = wmi_unified_cmd_send(wmi_handle, buf, 8938 len, WMI_PEER_SET_PARAM_CMDID); 8939 if (QDF_IS_STATUS_ERROR(status)) { 8940 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8941 " returned Error %d", __func__, status); 8942 wmi_buf_free(buf); 8943 } 8944 8945 return status; 8946 } 8947 8948 /** 8949 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8950 * @wmi_handle: wmi handle 8951 * @pLinkSpeed: link speed info 8952 * 8953 * Return: CDF status 8954 */ 8955 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8956 wmi_mac_addr peer_macaddr) 8957 { 8958 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8959 wmi_buf_t wmi_buf; 8960 uint32_t len; 8961 uint8_t *buf_ptr; 8962 8963 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8964 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8965 if (!wmi_buf) { 8966 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8967 return QDF_STATUS_E_NOMEM; 8968 } 8969 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8970 8971 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8972 WMITLV_SET_HDR(&cmd->tlv_header, 8973 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8974 WMITLV_GET_STRUCT_TLVLEN 8975 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8976 8977 /* Copy the peer macaddress to the wma buffer */ 8978 qdf_mem_copy(&cmd->peer_macaddr, 8979 &peer_macaddr, 8980 sizeof(peer_macaddr)); 8981 8982 8983 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8984 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8985 WMI_LOGE("%s: failed to send link speed command", __func__); 8986 wmi_buf_free(wmi_buf); 8987 return QDF_STATUS_E_FAILURE; 8988 } 8989 return QDF_STATUS_SUCCESS; 8990 } 8991 8992 #ifdef WLAN_SUPPORT_GREEN_AP 8993 /** 8994 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8995 * @wmi_handle: wmi handler 8996 * @egap_params: pointer to egap_params 8997 * 8998 * Return: 0 for success, otherwise appropriate error code 8999 */ 9000 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 9001 struct wlan_green_ap_egap_params *egap_params) 9002 { 9003 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 9004 wmi_buf_t buf; 9005 int32_t err; 9006 9007 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9008 if (!buf) { 9009 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 9010 return QDF_STATUS_E_NOMEM; 9011 } 9012 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 9013 WMITLV_SET_HDR(&cmd->tlv_header, 9014 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 9015 WMITLV_GET_STRUCT_TLVLEN( 9016 wmi_ap_ps_egap_param_cmd_fixed_param)); 9017 9018 cmd->enable = egap_params->host_enable_egap; 9019 cmd->inactivity_time = egap_params->egap_inactivity_time; 9020 cmd->wait_time = egap_params->egap_wait_time; 9021 cmd->flags = egap_params->egap_feature_flags; 9022 err = wmi_unified_cmd_send(wmi_handle, buf, 9023 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 9024 if (err) { 9025 WMI_LOGE("Failed to send ap_ps_egap cmd"); 9026 wmi_buf_free(buf); 9027 return QDF_STATUS_E_FAILURE; 9028 } 9029 9030 return QDF_STATUS_SUCCESS; 9031 } 9032 #endif 9033 9034 /** 9035 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 9036 * @wmi_handl: wmi handle 9037 * @cmd: Profiling command index 9038 * @value1: parameter1 value 9039 * @value2: parameter2 value 9040 * 9041 * Return: QDF_STATUS_SUCCESS for success else error code 9042 */ 9043 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 9044 uint32_t cmd, uint32_t value1, uint32_t value2) 9045 { 9046 wmi_buf_t buf; 9047 int32_t len = 0; 9048 int ret; 9049 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 9050 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9051 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 9052 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 9053 9054 switch (cmd) { 9055 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 9056 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 9057 buf = wmi_buf_alloc(wmi_handle, len); 9058 if (!buf) { 9059 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9060 return QDF_STATUS_E_NOMEM; 9061 } 9062 prof_trig_cmd = 9063 (wmi_wlan_profile_trigger_cmd_fixed_param *) 9064 wmi_buf_data(buf); 9065 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 9066 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 9067 WMITLV_GET_STRUCT_TLVLEN 9068 (wmi_wlan_profile_trigger_cmd_fixed_param)); 9069 prof_trig_cmd->enable = value1; 9070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9071 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9072 if (ret) { 9073 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 9074 value1); 9075 wmi_buf_free(buf); 9076 return ret; 9077 } 9078 break; 9079 9080 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 9081 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 9082 buf = wmi_buf_alloc(wmi_handle, len); 9083 if (!buf) { 9084 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9085 return QDF_STATUS_E_NOMEM; 9086 } 9087 profile_getdata_cmd = 9088 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 9089 wmi_buf_data(buf); 9090 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 9091 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 9092 WMITLV_GET_STRUCT_TLVLEN 9093 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 9094 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9095 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 9096 if (ret) { 9097 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 9098 value1, value2); 9099 wmi_buf_free(buf); 9100 return ret; 9101 } 9102 break; 9103 9104 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 9105 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9106 buf = wmi_buf_alloc(wmi_handle, len); 9107 if (!buf) { 9108 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9109 return QDF_STATUS_E_NOMEM; 9110 } 9111 hist_intvl_cmd = 9112 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9113 wmi_buf_data(buf); 9114 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9115 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9116 WMITLV_GET_STRUCT_TLVLEN 9117 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9118 hist_intvl_cmd->profile_id = value1; 9119 hist_intvl_cmd->value = value2; 9120 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9121 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9122 if (ret) { 9123 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 9124 value1, value2); 9125 wmi_buf_free(buf); 9126 return ret; 9127 } 9128 break; 9129 9130 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 9131 len = 9132 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 9133 buf = wmi_buf_alloc(wmi_handle, len); 9134 if (!buf) { 9135 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9136 return QDF_STATUS_E_NOMEM; 9137 } 9138 profile_enable_cmd = 9139 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 9140 wmi_buf_data(buf); 9141 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 9142 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 9143 WMITLV_GET_STRUCT_TLVLEN 9144 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 9145 profile_enable_cmd->profile_id = value1; 9146 profile_enable_cmd->enable = value2; 9147 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9148 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 9149 if (ret) { 9150 WMI_LOGE("enable cmd Failed for id %d value %d", 9151 value1, value2); 9152 wmi_buf_free(buf); 9153 return ret; 9154 } 9155 break; 9156 9157 default: 9158 WMI_LOGD("%s: invalid profiling command", __func__); 9159 break; 9160 } 9161 9162 return 0; 9163 } 9164 9165 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 9166 struct wlm_latency_level_param *params) 9167 { 9168 wmi_wlm_config_cmd_fixed_param *cmd; 9169 wmi_buf_t buf; 9170 uint32_t len = sizeof(*cmd); 9171 static uint32_t ll[4] = {100, 60, 40, 20}; 9172 9173 buf = wmi_buf_alloc(wmi_handle, len); 9174 if (!buf) { 9175 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9176 return QDF_STATUS_E_NOMEM; 9177 } 9178 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 9179 WMITLV_SET_HDR(&cmd->tlv_header, 9180 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 9181 WMITLV_GET_STRUCT_TLVLEN 9182 (wmi_wlm_config_cmd_fixed_param)); 9183 cmd->vdev_id = params->vdev_id; 9184 cmd->latency_level = params->wlm_latency_level; 9185 cmd->ul_latency = ll[params->wlm_latency_level]; 9186 cmd->dl_latency = ll[params->wlm_latency_level]; 9187 cmd->flags = params->wlm_latency_flags; 9188 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9189 WMI_WLM_CONFIG_CMDID)) { 9190 WMI_LOGE("%s: Failed to send setting latency config command", 9191 __func__); 9192 wmi_buf_free(buf); 9193 return QDF_STATUS_E_FAILURE; 9194 } 9195 9196 return 0; 9197 } 9198 /** 9199 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 9200 * @wmi_handle: wmi handle 9201 * @vdev_id: vdev id 9202 * 9203 * Return: QDF_STATUS_SUCCESS for success or error code 9204 */ 9205 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 9206 { 9207 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 9208 wmi_buf_t buf; 9209 int32_t len = sizeof(*cmd); 9210 9211 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9212 buf = wmi_buf_alloc(wmi_handle, len); 9213 if (!buf) { 9214 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9215 return QDF_STATUS_E_NOMEM; 9216 } 9217 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 9218 wmi_buf_data(buf); 9219 WMITLV_SET_HDR(&cmd->tlv_header, 9220 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 9221 WMITLV_GET_STRUCT_TLVLEN 9222 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 9223 cmd->vdev_id = vdev_id; 9224 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 9225 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9226 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 9227 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 9228 __func__); 9229 wmi_buf_free(buf); 9230 return QDF_STATUS_E_FAILURE; 9231 } 9232 9233 return 0; 9234 } 9235 9236 /** 9237 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 9238 * @wmi_handle: wmi handle 9239 * @vdev_id: vdev id 9240 * 9241 * Return: QDF_STATUS_SUCCESS for success or error code 9242 */ 9243 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 9244 uint8_t vdev_id) 9245 { 9246 wmi_csa_offload_enable_cmd_fixed_param *cmd; 9247 wmi_buf_t buf; 9248 int32_t len = sizeof(*cmd); 9249 9250 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9251 buf = wmi_buf_alloc(wmi_handle, len); 9252 if (!buf) { 9253 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9254 return QDF_STATUS_E_NOMEM; 9255 } 9256 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 9257 WMITLV_SET_HDR(&cmd->tlv_header, 9258 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 9259 WMITLV_GET_STRUCT_TLVLEN 9260 (wmi_csa_offload_enable_cmd_fixed_param)); 9261 cmd->vdev_id = vdev_id; 9262 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 9263 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9264 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 9265 WMI_LOGP("%s: Failed to send CSA offload enable command", 9266 __func__); 9267 wmi_buf_free(buf); 9268 return QDF_STATUS_E_FAILURE; 9269 } 9270 9271 return 0; 9272 } 9273 9274 #ifdef WLAN_FEATURE_CIF_CFR 9275 /** 9276 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 9277 * @wmi_handle: wmi handle 9278 * @data_len: len of dma cfg req 9279 * @data: dma cfg req 9280 * 9281 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9282 */ 9283 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9284 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 9285 { 9286 wmi_buf_t buf; 9287 uint8_t *cmd; 9288 QDF_STATUS ret; 9289 9290 WMITLV_SET_HDR(cfg, 9291 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 9292 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 9293 9294 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 9295 if (!buf) { 9296 WMI_LOGE(FL("wmi_buf_alloc failed")); 9297 return QDF_STATUS_E_FAILURE; 9298 } 9299 9300 cmd = (uint8_t *) wmi_buf_data(buf); 9301 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 9302 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 9303 sizeof(*cfg)); 9304 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 9305 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 9306 if (QDF_IS_STATUS_ERROR(ret)) { 9307 WMI_LOGE(FL(":wmi cmd send failed")); 9308 wmi_buf_free(buf); 9309 } 9310 9311 return ret; 9312 } 9313 #endif 9314 9315 /** 9316 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 9317 * @wmi_handle: wmi handle 9318 * @data_len: len of dma cfg req 9319 * @data: dma cfg req 9320 * 9321 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9322 */ 9323 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9324 struct direct_buf_rx_cfg_req *cfg) 9325 { 9326 wmi_buf_t buf; 9327 wmi_dma_ring_cfg_req_fixed_param *cmd; 9328 QDF_STATUS ret; 9329 int32_t len = sizeof(*cmd); 9330 9331 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9332 if (!buf) { 9333 WMI_LOGE(FL("wmi_buf_alloc failed")); 9334 return QDF_STATUS_E_FAILURE; 9335 } 9336 9337 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 9338 9339 WMITLV_SET_HDR(&cmd->tlv_header, 9340 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 9341 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 9342 9343 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9344 cfg->pdev_id); 9345 cmd->mod_id = cfg->mod_id; 9346 cmd->base_paddr_lo = cfg->base_paddr_lo; 9347 cmd->base_paddr_hi = cfg->base_paddr_hi; 9348 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 9349 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 9350 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 9351 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 9352 cmd->num_elems = cfg->num_elems; 9353 cmd->buf_size = cfg->buf_size; 9354 cmd->num_resp_per_event = cfg->num_resp_per_event; 9355 cmd->event_timeout_ms = cfg->event_timeout_ms; 9356 9357 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 9358 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 9359 "head idx paddr hi %x tail idx paddr lo %x" 9360 "tail idx addr hi %x num elems %d buf size %d num resp %d" 9361 "event timeout %d\n", __func__, cmd->pdev_id, 9362 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 9363 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 9364 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 9365 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 9366 cmd->event_timeout_ms); 9367 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9368 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 9369 if (QDF_IS_STATUS_ERROR(ret)) { 9370 WMI_LOGE(FL(":wmi cmd send failed")); 9371 wmi_buf_free(buf); 9372 } 9373 9374 return ret; 9375 } 9376 9377 /** 9378 * send_start_11d_scan_cmd_tlv() - start 11d scan request 9379 * @wmi_handle: wmi handle 9380 * @start_11d_scan: 11d scan start request parameters 9381 * 9382 * This function request FW to start 11d scan. 9383 * 9384 * Return: QDF status 9385 */ 9386 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9387 struct reg_start_11d_scan_req *start_11d_scan) 9388 { 9389 wmi_11d_scan_start_cmd_fixed_param *cmd; 9390 int32_t len; 9391 wmi_buf_t buf; 9392 int ret; 9393 9394 len = sizeof(*cmd); 9395 buf = wmi_buf_alloc(wmi_handle, len); 9396 if (!buf) { 9397 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9398 return QDF_STATUS_E_NOMEM; 9399 } 9400 9401 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 9402 9403 WMITLV_SET_HDR(&cmd->tlv_header, 9404 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 9405 WMITLV_GET_STRUCT_TLVLEN 9406 (wmi_11d_scan_start_cmd_fixed_param)); 9407 9408 cmd->vdev_id = start_11d_scan->vdev_id; 9409 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 9410 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 9411 9412 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 9413 9414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9415 WMI_11D_SCAN_START_CMDID); 9416 if (ret) { 9417 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 9418 wmi_buf_free(buf); 9419 return QDF_STATUS_E_FAILURE; 9420 } 9421 9422 return QDF_STATUS_SUCCESS; 9423 } 9424 9425 /** 9426 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 9427 * @wmi_handle: wmi handle 9428 * @start_11d_scan: 11d scan stop request parameters 9429 * 9430 * This function request FW to stop 11d scan. 9431 * 9432 * Return: QDF status 9433 */ 9434 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9435 struct reg_stop_11d_scan_req *stop_11d_scan) 9436 { 9437 wmi_11d_scan_stop_cmd_fixed_param *cmd; 9438 int32_t len; 9439 wmi_buf_t buf; 9440 int ret; 9441 9442 len = sizeof(*cmd); 9443 buf = wmi_buf_alloc(wmi_handle, len); 9444 if (!buf) { 9445 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9446 return QDF_STATUS_E_NOMEM; 9447 } 9448 9449 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 9450 9451 WMITLV_SET_HDR(&cmd->tlv_header, 9452 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 9453 WMITLV_GET_STRUCT_TLVLEN 9454 (wmi_11d_scan_stop_cmd_fixed_param)); 9455 9456 cmd->vdev_id = stop_11d_scan->vdev_id; 9457 9458 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 9459 9460 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9461 WMI_11D_SCAN_STOP_CMDID); 9462 if (ret) { 9463 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 9464 wmi_buf_free(buf); 9465 return QDF_STATUS_E_FAILURE; 9466 } 9467 9468 return QDF_STATUS_SUCCESS; 9469 } 9470 9471 /** 9472 * send_start_oem_data_cmd_tlv() - start OEM data request to target 9473 * @wmi_handle: wmi handle 9474 * @startOemDataReq: start request params 9475 * 9476 * Return: CDF status 9477 */ 9478 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 9479 uint32_t data_len, 9480 uint8_t *data) 9481 { 9482 wmi_buf_t buf; 9483 uint8_t *cmd; 9484 QDF_STATUS ret; 9485 9486 buf = wmi_buf_alloc(wmi_handle, 9487 (data_len + WMI_TLV_HDR_SIZE)); 9488 if (!buf) { 9489 WMI_LOGE(FL("wmi_buf_alloc failed")); 9490 return QDF_STATUS_E_FAILURE; 9491 } 9492 9493 cmd = (uint8_t *) wmi_buf_data(buf); 9494 9495 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 9496 cmd += WMI_TLV_HDR_SIZE; 9497 qdf_mem_copy(cmd, data, 9498 data_len); 9499 9500 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 9501 data_len); 9502 9503 ret = wmi_unified_cmd_send(wmi_handle, buf, 9504 (data_len + 9505 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 9506 9507 if (QDF_IS_STATUS_ERROR(ret)) { 9508 WMI_LOGE(FL(":wmi cmd send failed")); 9509 wmi_buf_free(buf); 9510 } 9511 9512 return ret; 9513 } 9514 9515 /** 9516 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 9517 * @wmi_handle: wmi handle 9518 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 9519 * 9520 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 9521 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 9522 * to firmware based on phyerr filtering 9523 * offload status. 9524 * 9525 * Return: 1 success, 0 failure 9526 */ 9527 static QDF_STATUS 9528 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9529 bool dfs_phyerr_filter_offload) 9530 { 9531 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 9532 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 9533 wmi_buf_t buf; 9534 uint16_t len; 9535 QDF_STATUS ret; 9536 9537 9538 if (false == dfs_phyerr_filter_offload) { 9539 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 9540 __func__); 9541 len = sizeof(*disable_phyerr_offload_cmd); 9542 buf = wmi_buf_alloc(wmi_handle, len); 9543 if (!buf) { 9544 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9545 return 0; 9546 } 9547 disable_phyerr_offload_cmd = 9548 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 9549 wmi_buf_data(buf); 9550 9551 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 9552 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 9553 WMITLV_GET_STRUCT_TLVLEN 9554 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 9555 9556 /* 9557 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 9558 * to the firmware to disable the phyerror 9559 * filtering offload. 9560 */ 9561 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9562 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 9563 if (QDF_IS_STATUS_ERROR(ret)) { 9564 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 9565 __func__, ret); 9566 wmi_buf_free(buf); 9567 return QDF_STATUS_E_FAILURE; 9568 } 9569 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 9570 __func__); 9571 } else { 9572 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 9573 __func__); 9574 9575 len = sizeof(*enable_phyerr_offload_cmd); 9576 buf = wmi_buf_alloc(wmi_handle, len); 9577 if (!buf) { 9578 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9579 return QDF_STATUS_E_FAILURE; 9580 } 9581 9582 enable_phyerr_offload_cmd = 9583 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 9584 wmi_buf_data(buf); 9585 9586 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 9587 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 9588 WMITLV_GET_STRUCT_TLVLEN 9589 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 9590 9591 /* 9592 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 9593 * to the firmware to enable the phyerror 9594 * filtering offload. 9595 */ 9596 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9597 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 9598 9599 if (QDF_IS_STATUS_ERROR(ret)) { 9600 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 9601 __func__, ret); 9602 wmi_buf_free(buf); 9603 return QDF_STATUS_E_FAILURE; 9604 } 9605 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 9606 __func__); 9607 } 9608 9609 return QDF_STATUS_SUCCESS; 9610 } 9611 9612 /** 9613 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 9614 * will wake up host after specified time is elapsed 9615 * @wmi_handle: wmi handle 9616 * @vdev_id: vdev id 9617 * @cookie: value to identify reason why host set up wake call. 9618 * @time: time in ms 9619 * 9620 * Return: QDF status 9621 */ 9622 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9623 uint8_t vdev_id, uint32_t cookie, uint32_t time) 9624 { 9625 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 9626 wmi_buf_t buf; 9627 uint8_t *buf_ptr; 9628 int32_t len; 9629 int ret; 9630 9631 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 9632 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 9633 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 9634 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 9635 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 9636 WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32) + 9637 WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32); 9638 9639 buf = wmi_buf_alloc(wmi_handle, len); 9640 if (!buf) { 9641 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9642 return QDF_STATUS_E_NOMEM; 9643 } 9644 9645 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9646 buf_ptr = (uint8_t *) cmd; 9647 9648 WMITLV_SET_HDR(&cmd->tlv_header, 9649 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 9650 WMITLV_GET_STRUCT_TLVLEN 9651 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 9652 cmd->vdev_id = vdev_id; 9653 cmd->pattern_id = cookie, 9654 cmd->pattern_type = WOW_TIMER_PATTERN; 9655 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 9656 9657 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 9658 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9659 buf_ptr += WMI_TLV_HDR_SIZE; 9660 9661 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 9662 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9663 buf_ptr += WMI_TLV_HDR_SIZE; 9664 9665 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 9666 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9667 buf_ptr += WMI_TLV_HDR_SIZE; 9668 9669 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 9670 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9671 buf_ptr += WMI_TLV_HDR_SIZE; 9672 9673 /* Fill TLV for pattern_info_timeout, and time value */ 9674 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32)); 9675 buf_ptr += WMI_TLV_HDR_SIZE; 9676 *((A_UINT32 *) buf_ptr) = time; 9677 buf_ptr += sizeof(A_UINT32); 9678 9679 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 9680 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32)); 9681 buf_ptr += WMI_TLV_HDR_SIZE; 9682 *((A_UINT32 *) buf_ptr) = 0; 9683 9684 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 9685 __func__, time, vdev_id); 9686 9687 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9688 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 9689 if (ret) { 9690 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 9691 __func__); 9692 wmi_buf_free(buf); 9693 return QDF_STATUS_E_FAILURE; 9694 } 9695 9696 return QDF_STATUS_SUCCESS; 9697 } 9698 9699 #if !defined(REMOVE_PKT_LOG) 9700 /** 9701 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 9702 * @wmi_handle: wmi handle 9703 * @pktlog_event: pktlog event 9704 * @cmd_id: pktlog cmd id 9705 * 9706 * Return: CDF status 9707 */ 9708 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 9709 WMI_PKTLOG_EVENT pktlog_event, 9710 WMI_CMD_ID cmd_id, uint8_t user_triggered) 9711 { 9712 WMI_PKTLOG_EVENT PKTLOG_EVENT; 9713 WMI_CMD_ID CMD_ID; 9714 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 9715 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 9716 int len = 0; 9717 wmi_buf_t buf; 9718 9719 PKTLOG_EVENT = pktlog_event; 9720 CMD_ID = cmd_id; 9721 9722 switch (CMD_ID) { 9723 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 9724 len = sizeof(*cmd); 9725 buf = wmi_buf_alloc(wmi_handle, len); 9726 if (!buf) { 9727 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9728 return QDF_STATUS_E_NOMEM; 9729 } 9730 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 9731 wmi_buf_data(buf); 9732 WMITLV_SET_HDR(&cmd->tlv_header, 9733 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9734 WMITLV_GET_STRUCT_TLVLEN 9735 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9736 cmd->evlist = PKTLOG_EVENT; 9737 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9738 : WMI_PKTLOG_ENABLE_AUTO; 9739 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9740 WMI_HOST_PDEV_ID_SOC); 9741 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9742 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9743 WMI_LOGE("failed to send pktlog enable cmdid"); 9744 goto wmi_send_failed; 9745 } 9746 break; 9747 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9748 len = sizeof(*disable_cmd); 9749 buf = wmi_buf_alloc(wmi_handle, len); 9750 if (!buf) { 9751 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9752 return QDF_STATUS_E_NOMEM; 9753 } 9754 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9755 wmi_buf_data(buf); 9756 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9757 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9758 WMITLV_GET_STRUCT_TLVLEN 9759 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9760 disable_cmd->pdev_id = 9761 wmi_handle->ops->convert_pdev_id_host_to_target( 9762 WMI_HOST_PDEV_ID_SOC); 9763 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9764 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9765 WMI_LOGE("failed to send pktlog disable cmdid"); 9766 goto wmi_send_failed; 9767 } 9768 break; 9769 default: 9770 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9771 break; 9772 } 9773 9774 return QDF_STATUS_SUCCESS; 9775 9776 wmi_send_failed: 9777 wmi_buf_free(buf); 9778 return QDF_STATUS_E_FAILURE; 9779 } 9780 #endif /* REMOVE_PKT_LOG */ 9781 9782 /** 9783 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9784 * @wmi_handle: wmi handle 9785 * @ptrn_id: pattern id 9786 * @vdev_id: vdev id 9787 * 9788 * Return: CDF status 9789 */ 9790 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9791 uint8_t ptrn_id, uint8_t vdev_id) 9792 { 9793 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9794 wmi_buf_t buf; 9795 int32_t len; 9796 int ret; 9797 9798 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9799 9800 9801 buf = wmi_buf_alloc(wmi_handle, len); 9802 if (!buf) { 9803 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9804 return QDF_STATUS_E_NOMEM; 9805 } 9806 9807 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9808 9809 WMITLV_SET_HDR(&cmd->tlv_header, 9810 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9811 WMITLV_GET_STRUCT_TLVLEN( 9812 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9813 cmd->vdev_id = vdev_id; 9814 cmd->pattern_id = ptrn_id; 9815 cmd->pattern_type = WOW_BITMAP_PATTERN; 9816 9817 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9818 cmd->pattern_id, vdev_id); 9819 9820 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9821 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9822 if (ret) { 9823 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9824 wmi_buf_free(buf); 9825 return QDF_STATUS_E_FAILURE; 9826 } 9827 9828 return QDF_STATUS_SUCCESS; 9829 } 9830 9831 /** 9832 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9833 * @wmi_handle: wmi handle 9834 * 9835 * Sends host wakeup indication to FW. On receiving this indication, 9836 * FW will come out of WOW. 9837 * 9838 * Return: CDF status 9839 */ 9840 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9841 { 9842 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9843 wmi_buf_t buf; 9844 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9845 int32_t len; 9846 int ret; 9847 9848 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9849 9850 buf = wmi_buf_alloc(wmi_handle, len); 9851 if (!buf) { 9852 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9853 return QDF_STATUS_E_NOMEM; 9854 } 9855 9856 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9857 wmi_buf_data(buf); 9858 WMITLV_SET_HDR(&cmd->tlv_header, 9859 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9860 WMITLV_GET_STRUCT_TLVLEN 9861 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9862 9863 9864 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9865 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9866 if (ret) { 9867 WMI_LOGE("Failed to send host wakeup indication to fw"); 9868 wmi_buf_free(buf); 9869 return QDF_STATUS_E_FAILURE; 9870 } 9871 9872 return qdf_status; 9873 } 9874 9875 /** 9876 * send_del_ts_cmd_tlv() - send DELTS request to fw 9877 * @wmi_handle: wmi handle 9878 * @msg: delts params 9879 * 9880 * Return: CDF status 9881 */ 9882 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9883 uint8_t ac) 9884 { 9885 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9886 wmi_buf_t buf; 9887 int32_t len = sizeof(*cmd); 9888 9889 buf = wmi_buf_alloc(wmi_handle, len); 9890 if (!buf) { 9891 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9892 return QDF_STATUS_E_NOMEM; 9893 } 9894 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9895 WMITLV_SET_HDR(&cmd->tlv_header, 9896 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9897 WMITLV_GET_STRUCT_TLVLEN 9898 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9899 cmd->vdev_id = vdev_id; 9900 cmd->ac = ac; 9901 9902 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9903 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9904 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9905 WMI_VDEV_WMM_DELTS_CMDID)) { 9906 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9907 wmi_buf_free(buf); 9908 return QDF_STATUS_E_FAILURE; 9909 } 9910 9911 return QDF_STATUS_SUCCESS; 9912 } 9913 9914 /** 9915 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9916 * @wmi_handle: handle to wmi 9917 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9918 * 9919 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9920 * ADD_TS requestes to firmware in loop for all the ACs with 9921 * active flow. 9922 * 9923 * Return: CDF status 9924 */ 9925 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9926 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9927 { 9928 int i = 0; 9929 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9930 wmi_buf_t buf; 9931 int32_t len = sizeof(*cmd); 9932 9933 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9934 /* if flow in this AC is active */ 9935 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9936 /* 9937 * as per implementation of wma_add_ts_req() we 9938 * are not waiting any response from firmware so 9939 * apart from sending ADDTS to firmware just send 9940 * success to upper layers 9941 */ 9942 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9943 9944 buf = wmi_buf_alloc(wmi_handle, len); 9945 if (!buf) { 9946 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9947 return QDF_STATUS_E_NOMEM; 9948 } 9949 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9950 wmi_buf_data(buf); 9951 WMITLV_SET_HDR(&cmd->tlv_header, 9952 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9953 WMITLV_GET_STRUCT_TLVLEN 9954 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9955 cmd->vdev_id = aggr_qos_rsp_msg->sessionId; 9956 cmd->ac = 9957 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9958 traffic.userPrio); 9959 cmd->medium_time_us = 9960 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9961 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9962 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9963 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9964 cmd->medium_time_us, cmd->downgrade_type); 9965 if (wmi_unified_cmd_send 9966 (wmi_handle, buf, len, 9967 WMI_VDEV_WMM_ADDTS_CMDID)) { 9968 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9969 __func__); 9970 aggr_qos_rsp_msg->status[i] = 9971 QDF_STATUS_E_FAILURE; 9972 wmi_buf_free(buf); 9973 return QDF_STATUS_E_FAILURE; 9974 } 9975 } 9976 } 9977 9978 return QDF_STATUS_SUCCESS; 9979 } 9980 9981 /** 9982 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9983 * @wmi_handle: wmi handle 9984 * @msg: ADDTS params 9985 * 9986 * Return: CDF status 9987 */ 9988 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9989 struct add_ts_param *msg) 9990 { 9991 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9992 wmi_buf_t buf; 9993 int32_t len = sizeof(*cmd); 9994 9995 msg->status = QDF_STATUS_SUCCESS; 9996 9997 buf = wmi_buf_alloc(wmi_handle, len); 9998 if (!buf) { 9999 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10000 return QDF_STATUS_E_NOMEM; 10001 } 10002 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 10003 WMITLV_SET_HDR(&cmd->tlv_header, 10004 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 10005 WMITLV_GET_STRUCT_TLVLEN 10006 (wmi_vdev_wmm_addts_cmd_fixed_param)); 10007 cmd->vdev_id = msg->sme_session_id; 10008 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 10009 cmd->medium_time_us = msg->tspec.mediumTime * 32; 10010 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 10011 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 10012 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 10013 cmd->downgrade_type, __func__, __LINE__); 10014 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10015 WMI_VDEV_WMM_ADDTS_CMDID)) { 10016 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 10017 msg->status = QDF_STATUS_E_FAILURE; 10018 wmi_buf_free(buf); 10019 return QDF_STATUS_E_FAILURE; 10020 } 10021 10022 return QDF_STATUS_SUCCESS; 10023 } 10024 10025 /** 10026 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 10027 * @wmi_handle: wmi handle 10028 * @pAddPeriodicTxPtrnParams: tx ptrn params 10029 * 10030 * Retrun: CDF status 10031 */ 10032 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10033 struct periodic_tx_pattern * 10034 pAddPeriodicTxPtrnParams, 10035 uint8_t vdev_id) 10036 { 10037 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10038 wmi_buf_t wmi_buf; 10039 uint32_t len; 10040 uint8_t *buf_ptr; 10041 uint32_t ptrn_len, ptrn_len_aligned; 10042 int j; 10043 10044 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 10045 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 10046 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 10047 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 10048 10049 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10050 if (!wmi_buf) { 10051 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10052 return QDF_STATUS_E_NOMEM; 10053 } 10054 10055 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10056 10057 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 10058 WMITLV_SET_HDR(&cmd->tlv_header, 10059 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10060 WMITLV_GET_STRUCT_TLVLEN 10061 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10062 10063 /* Pass the pattern id to delete for the corresponding vdev id */ 10064 cmd->vdev_id = vdev_id; 10065 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 10066 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 10067 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 10068 10069 /* Pattern info */ 10070 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 10072 buf_ptr += WMI_TLV_HDR_SIZE; 10073 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 10074 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 10075 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 10076 10077 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 10078 __func__, cmd->pattern_id, cmd->vdev_id); 10079 10080 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10081 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10082 WMI_LOGE("%s: failed to add pattern set state command", 10083 __func__); 10084 wmi_buf_free(wmi_buf); 10085 return QDF_STATUS_E_FAILURE; 10086 } 10087 return QDF_STATUS_SUCCESS; 10088 } 10089 10090 /** 10091 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 10092 * @wmi_handle: wmi handle 10093 * @vdev_id: vdev id 10094 * @pattern_id: pattern id 10095 * 10096 * Retrun: CDF status 10097 */ 10098 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10099 uint8_t vdev_id, 10100 uint8_t pattern_id) 10101 { 10102 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10103 wmi_buf_t wmi_buf; 10104 uint32_t len = 10105 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10106 10107 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10108 if (!wmi_buf) { 10109 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10110 return QDF_STATUS_E_NOMEM; 10111 } 10112 10113 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 10114 wmi_buf_data(wmi_buf); 10115 WMITLV_SET_HDR(&cmd->tlv_header, 10116 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10117 WMITLV_GET_STRUCT_TLVLEN 10118 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10119 10120 /* Pass the pattern id to delete for the corresponding vdev id */ 10121 cmd->vdev_id = vdev_id; 10122 cmd->pattern_id = pattern_id; 10123 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 10124 __func__, cmd->pattern_id, cmd->vdev_id); 10125 10126 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10127 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10128 WMI_LOGE("%s: failed to send del pattern command", __func__); 10129 wmi_buf_free(wmi_buf); 10130 return QDF_STATUS_E_FAILURE; 10131 } 10132 return QDF_STATUS_SUCCESS; 10133 } 10134 10135 /** 10136 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 10137 * @wmi_handle: wmi handle 10138 * @preq: stats ext params 10139 * 10140 * Return: CDF status 10141 */ 10142 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 10143 struct stats_ext_params *preq) 10144 { 10145 QDF_STATUS ret; 10146 wmi_req_stats_ext_cmd_fixed_param *cmd; 10147 wmi_buf_t buf; 10148 uint16_t len; 10149 uint8_t *buf_ptr; 10150 10151 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 10152 10153 buf = wmi_buf_alloc(wmi_handle, len); 10154 if (!buf) { 10155 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10156 return QDF_STATUS_E_NOMEM; 10157 } 10158 10159 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10160 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 10161 10162 WMITLV_SET_HDR(&cmd->tlv_header, 10163 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 10164 WMITLV_GET_STRUCT_TLVLEN 10165 (wmi_req_stats_ext_cmd_fixed_param)); 10166 cmd->vdev_id = preq->vdev_id; 10167 cmd->data_len = preq->request_data_len; 10168 10169 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 10170 __func__, preq->request_data_len, preq->vdev_id); 10171 10172 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 10173 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 10174 10175 buf_ptr += WMI_TLV_HDR_SIZE; 10176 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 10177 10178 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10179 WMI_REQUEST_STATS_EXT_CMDID); 10180 if (QDF_IS_STATUS_ERROR(ret)) { 10181 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 10182 ret); 10183 wmi_buf_free(buf); 10184 } 10185 10186 return ret; 10187 } 10188 10189 /** 10190 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 10191 * @wmi_handle: wmi handle 10192 * @params: ext wow params 10193 * 10194 * Return:0 for success or error code 10195 */ 10196 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 10197 struct ext_wow_params *params) 10198 { 10199 wmi_extwow_enable_cmd_fixed_param *cmd; 10200 wmi_buf_t buf; 10201 int32_t len; 10202 int ret; 10203 10204 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 10205 buf = wmi_buf_alloc(wmi_handle, len); 10206 if (!buf) { 10207 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10208 return QDF_STATUS_E_NOMEM; 10209 } 10210 10211 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 10212 10213 WMITLV_SET_HDR(&cmd->tlv_header, 10214 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 10215 WMITLV_GET_STRUCT_TLVLEN 10216 (wmi_extwow_enable_cmd_fixed_param)); 10217 10218 cmd->vdev_id = params->vdev_id; 10219 cmd->type = params->type; 10220 cmd->wakeup_pin_num = params->wakeup_pin_num; 10221 10222 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 10223 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 10224 10225 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10226 WMI_EXTWOW_ENABLE_CMDID); 10227 if (ret) { 10228 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 10229 wmi_buf_free(buf); 10230 return QDF_STATUS_E_FAILURE; 10231 } 10232 10233 return QDF_STATUS_SUCCESS; 10234 10235 } 10236 10237 /** 10238 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 10239 * @wmi_handle: wmi handle 10240 * @app_type1_params: app type1 params 10241 * 10242 * Return: CDF status 10243 */ 10244 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10245 struct app_type1_params *app_type1_params) 10246 { 10247 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 10248 wmi_buf_t buf; 10249 int32_t len; 10250 int ret; 10251 10252 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 10253 buf = wmi_buf_alloc(wmi_handle, len); 10254 if (!buf) { 10255 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10256 return QDF_STATUS_E_NOMEM; 10257 } 10258 10259 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 10260 wmi_buf_data(buf); 10261 10262 WMITLV_SET_HDR(&cmd->tlv_header, 10263 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 10264 WMITLV_GET_STRUCT_TLVLEN 10265 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 10266 10267 cmd->vdev_id = app_type1_params->vdev_id; 10268 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 10269 &cmd->wakee_mac); 10270 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 10271 cmd->ident_len = app_type1_params->id_length; 10272 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 10273 cmd->passwd_len = app_type1_params->pass_length; 10274 10275 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 10276 "identification_id %.8s id_length %u " 10277 "password %.16s pass_length %u", 10278 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 10279 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 10280 10281 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10282 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 10283 if (ret) { 10284 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 10285 wmi_buf_free(buf); 10286 return QDF_STATUS_E_FAILURE; 10287 } 10288 10289 return QDF_STATUS_SUCCESS; 10290 } 10291 10292 /** 10293 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 10294 * @wmi_handle: wmi handle 10295 * @appType2Params: app type2 params 10296 * 10297 * Return: CDF status 10298 */ 10299 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10300 struct app_type2_params *appType2Params) 10301 { 10302 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 10303 wmi_buf_t buf; 10304 int32_t len; 10305 int ret; 10306 10307 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 10308 buf = wmi_buf_alloc(wmi_handle, len); 10309 if (!buf) { 10310 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10311 return QDF_STATUS_E_NOMEM; 10312 } 10313 10314 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 10315 wmi_buf_data(buf); 10316 10317 WMITLV_SET_HDR(&cmd->tlv_header, 10318 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 10319 WMITLV_GET_STRUCT_TLVLEN 10320 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 10321 10322 cmd->vdev_id = appType2Params->vdev_id; 10323 10324 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 10325 cmd->rc4_key_len = appType2Params->rc4_key_len; 10326 10327 cmd->ip_id = appType2Params->ip_id; 10328 cmd->ip_device_ip = appType2Params->ip_device_ip; 10329 cmd->ip_server_ip = appType2Params->ip_server_ip; 10330 10331 cmd->tcp_src_port = appType2Params->tcp_src_port; 10332 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 10333 cmd->tcp_seq = appType2Params->tcp_seq; 10334 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 10335 10336 cmd->keepalive_init = appType2Params->keepalive_init; 10337 cmd->keepalive_min = appType2Params->keepalive_min; 10338 cmd->keepalive_max = appType2Params->keepalive_max; 10339 cmd->keepalive_inc = appType2Params->keepalive_inc; 10340 10341 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 10342 &cmd->gateway_mac); 10343 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 10344 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 10345 10346 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 10347 "rc4_key %.16s rc4_key_len %u " 10348 "ip_id %x ip_device_ip %x ip_server_ip %x " 10349 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 10350 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 10351 "keepalive_max %u keepalive_inc %u " 10352 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 10353 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 10354 cmd->rc4_key, cmd->rc4_key_len, 10355 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 10356 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 10357 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 10358 cmd->keepalive_max, cmd->keepalive_inc, 10359 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 10360 10361 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10362 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 10363 if (ret) { 10364 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 10365 wmi_buf_free(buf); 10366 return QDF_STATUS_E_FAILURE; 10367 } 10368 10369 return QDF_STATUS_SUCCESS; 10370 10371 } 10372 10373 /** 10374 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 10375 * @wmi_handle: wmi handle 10376 * @timer_val: auto shutdown timer value 10377 * 10378 * Return: CDF status 10379 */ 10380 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 10381 uint32_t timer_val) 10382 { 10383 QDF_STATUS status; 10384 wmi_buf_t buf = NULL; 10385 uint8_t *buf_ptr; 10386 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 10387 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 10388 10389 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 10390 __func__, timer_val); 10391 10392 buf = wmi_buf_alloc(wmi_handle, len); 10393 if (!buf) { 10394 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10395 return QDF_STATUS_E_NOMEM; 10396 } 10397 10398 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10399 wmi_auto_sh_cmd = 10400 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 10401 wmi_auto_sh_cmd->timer_value = timer_val; 10402 10403 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 10404 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 10405 WMITLV_GET_STRUCT_TLVLEN 10406 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 10407 10408 status = wmi_unified_cmd_send(wmi_handle, buf, 10409 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 10410 if (QDF_IS_STATUS_ERROR(status)) { 10411 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 10412 __func__, status); 10413 wmi_buf_free(buf); 10414 } 10415 10416 return status; 10417 } 10418 10419 /** 10420 * send_nan_req_cmd_tlv() - to send nan request to target 10421 * @wmi_handle: wmi handle 10422 * @nan_req: request data which will be non-null 10423 * 10424 * Return: CDF status 10425 */ 10426 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 10427 struct nan_req_params *nan_req) 10428 { 10429 QDF_STATUS ret; 10430 wmi_nan_cmd_param *cmd; 10431 wmi_buf_t buf; 10432 uint16_t len = sizeof(*cmd); 10433 uint16_t nan_data_len, nan_data_len_aligned; 10434 uint8_t *buf_ptr; 10435 10436 /* 10437 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 10438 * +------------+----------+-----------------------+--------------+ 10439 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 10440 * +------------+----------+-----------------------+--------------+ 10441 */ 10442 if (!nan_req) { 10443 WMI_LOGE("%s:nan req is not valid", __func__); 10444 return QDF_STATUS_E_FAILURE; 10445 } 10446 nan_data_len = nan_req->request_data_len; 10447 nan_data_len_aligned = roundup(nan_req->request_data_len, 10448 sizeof(uint32_t)); 10449 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 10450 buf = wmi_buf_alloc(wmi_handle, len); 10451 if (!buf) { 10452 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10453 return QDF_STATUS_E_NOMEM; 10454 } 10455 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10456 cmd = (wmi_nan_cmd_param *) buf_ptr; 10457 WMITLV_SET_HDR(&cmd->tlv_header, 10458 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 10459 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 10460 cmd->data_len = nan_req->request_data_len; 10461 WMI_LOGD("%s: The data len value is %u", 10462 __func__, nan_req->request_data_len); 10463 buf_ptr += sizeof(wmi_nan_cmd_param); 10464 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 10465 buf_ptr += WMI_TLV_HDR_SIZE; 10466 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 10467 10468 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10469 WMI_NAN_CMDID); 10470 if (QDF_IS_STATUS_ERROR(ret)) { 10471 WMI_LOGE("%s Failed to send set param command ret = %d", 10472 __func__, ret); 10473 wmi_buf_free(buf); 10474 } 10475 10476 return ret; 10477 } 10478 10479 /** 10480 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 10481 * @wmi_handle: wmi handle 10482 * @params: DHCP server offload info 10483 * 10484 * Return: QDF_STATUS_SUCCESS for success or error code 10485 */ 10486 static QDF_STATUS 10487 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 10488 struct dhcp_offload_info_params *params) 10489 { 10490 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 10491 wmi_buf_t buf; 10492 QDF_STATUS status; 10493 10494 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 10495 if (!buf) { 10496 WMI_LOGE("Failed to allocate buffer to send " 10497 "set_dhcp_server_offload cmd"); 10498 return QDF_STATUS_E_NOMEM; 10499 } 10500 10501 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 10502 10503 WMITLV_SET_HDR(&cmd->tlv_header, 10504 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 10505 WMITLV_GET_STRUCT_TLVLEN 10506 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 10507 cmd->vdev_id = params->vdev_id; 10508 cmd->enable = params->dhcp_offload_enabled; 10509 cmd->num_client = params->dhcp_client_num; 10510 cmd->srv_ipv4 = params->dhcp_srv_addr; 10511 cmd->start_lsb = 0; 10512 status = wmi_unified_cmd_send(wmi_handle, buf, 10513 sizeof(*cmd), 10514 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 10515 if (QDF_IS_STATUS_ERROR(status)) { 10516 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 10517 wmi_buf_free(buf); 10518 return QDF_STATUS_E_FAILURE; 10519 } 10520 WMI_LOGD("Set dhcp server offload to vdevId %d", 10521 params->vdev_id); 10522 10523 return status; 10524 } 10525 10526 /** 10527 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 10528 * @wmi_handle: wmi handle 10529 * @flashing: flashing request 10530 * 10531 * Return: CDF status 10532 */ 10533 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 10534 struct flashing_req_params *flashing) 10535 { 10536 wmi_set_led_flashing_cmd_fixed_param *cmd; 10537 QDF_STATUS status; 10538 wmi_buf_t buf; 10539 uint8_t *buf_ptr; 10540 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 10541 10542 buf = wmi_buf_alloc(wmi_handle, len); 10543 if (!buf) { 10544 WMI_LOGP(FL("wmi_buf_alloc failed")); 10545 return QDF_STATUS_E_NOMEM; 10546 } 10547 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10548 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 10549 WMITLV_SET_HDR(&cmd->tlv_header, 10550 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 10551 WMITLV_GET_STRUCT_TLVLEN 10552 (wmi_set_led_flashing_cmd_fixed_param)); 10553 cmd->pattern_id = flashing->pattern_id; 10554 cmd->led_x0 = flashing->led_x0; 10555 cmd->led_x1 = flashing->led_x1; 10556 10557 status = wmi_unified_cmd_send(wmi_handle, buf, len, 10558 WMI_PDEV_SET_LED_FLASHING_CMDID); 10559 if (QDF_IS_STATUS_ERROR(status)) { 10560 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 10561 " returned Error %d", __func__, status); 10562 wmi_buf_free(buf); 10563 } 10564 10565 return status; 10566 } 10567 10568 /** 10569 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 10570 * @wmi_handle: wmi handle 10571 * @ch_avoid_update_req: channel avoid update params 10572 * 10573 * Return: CDF status 10574 */ 10575 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 10576 { 10577 QDF_STATUS status; 10578 wmi_buf_t buf = NULL; 10579 uint8_t *buf_ptr; 10580 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 10581 int len = sizeof(wmi_chan_avoid_update_cmd_param); 10582 10583 10584 buf = wmi_buf_alloc(wmi_handle, len); 10585 if (!buf) { 10586 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10587 return QDF_STATUS_E_NOMEM; 10588 } 10589 10590 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10591 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 10592 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 10593 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 10594 WMITLV_GET_STRUCT_TLVLEN 10595 (wmi_chan_avoid_update_cmd_param)); 10596 10597 status = wmi_unified_cmd_send(wmi_handle, buf, 10598 len, WMI_CHAN_AVOID_UPDATE_CMDID); 10599 if (QDF_IS_STATUS_ERROR(status)) { 10600 WMI_LOGE("wmi_unified_cmd_send" 10601 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 10602 " returned Error %d", status); 10603 wmi_buf_free(buf); 10604 } 10605 10606 return status; 10607 } 10608 10609 /** 10610 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 10611 * @wmi_handle: wmi handle 10612 * @param: pointer to pdev regdomain params 10613 * 10614 * Return: 0 for success or error code 10615 */ 10616 static QDF_STATUS 10617 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 10618 struct pdev_set_regdomain_params *param) 10619 { 10620 wmi_buf_t buf; 10621 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10622 int32_t len = sizeof(*cmd); 10623 10624 10625 buf = wmi_buf_alloc(wmi_handle, len); 10626 if (!buf) { 10627 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10628 return QDF_STATUS_E_NOMEM; 10629 } 10630 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10631 WMITLV_SET_HDR(&cmd->tlv_header, 10632 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10633 WMITLV_GET_STRUCT_TLVLEN 10634 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10635 10636 cmd->reg_domain = param->currentRDinuse; 10637 cmd->reg_domain_2G = param->currentRD2G; 10638 cmd->reg_domain_5G = param->currentRD5G; 10639 cmd->conformance_test_limit_2G = param->ctl_2G; 10640 cmd->conformance_test_limit_5G = param->ctl_5G; 10641 cmd->dfs_domain = param->dfsDomain; 10642 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10643 param->pdev_id); 10644 10645 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10646 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10647 WMI_LOGE("%s: Failed to send pdev set regdomain command", 10648 __func__); 10649 wmi_buf_free(buf); 10650 return QDF_STATUS_E_FAILURE; 10651 } 10652 10653 return QDF_STATUS_SUCCESS; 10654 } 10655 10656 /** 10657 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 10658 * @wmi_handle: wmi handle 10659 * @reg_dmn: reg domain 10660 * @regdmn2G: 2G reg domain 10661 * @regdmn5G: 5G reg domain 10662 * @ctl2G: 2G test limit 10663 * @ctl5G: 5G test limit 10664 * 10665 * Return: none 10666 */ 10667 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 10668 uint32_t reg_dmn, uint16_t regdmn2G, 10669 uint16_t regdmn5G, uint8_t ctl2G, 10670 uint8_t ctl5G) 10671 { 10672 wmi_buf_t buf; 10673 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10674 int32_t len = sizeof(*cmd); 10675 10676 10677 buf = wmi_buf_alloc(wmi_handle, len); 10678 if (!buf) { 10679 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10680 return QDF_STATUS_E_NOMEM; 10681 } 10682 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10683 WMITLV_SET_HDR(&cmd->tlv_header, 10684 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10685 WMITLV_GET_STRUCT_TLVLEN 10686 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10687 cmd->reg_domain = reg_dmn; 10688 cmd->reg_domain_2G = regdmn2G; 10689 cmd->reg_domain_5G = regdmn5G; 10690 cmd->conformance_test_limit_2G = ctl2G; 10691 cmd->conformance_test_limit_5G = ctl5G; 10692 10693 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10694 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10695 WMI_LOGP("%s: Failed to send pdev set regdomain command", 10696 __func__); 10697 wmi_buf_free(buf); 10698 return QDF_STATUS_E_FAILURE; 10699 } 10700 10701 return QDF_STATUS_SUCCESS; 10702 } 10703 10704 10705 /** 10706 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 10707 * @wmi_handle: wmi handle 10708 * @chan_switch_params: Pointer to tdls channel switch parameter structure 10709 * 10710 * This function sets tdls off channel mode 10711 * 10712 * Return: 0 on success; Negative errno otherwise 10713 */ 10714 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 10715 struct tdls_channel_switch_params *chan_switch_params) 10716 { 10717 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 10718 wmi_buf_t wmi_buf; 10719 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10720 10721 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10722 if (!wmi_buf) { 10723 WMI_LOGE(FL("wmi_buf_alloc failed")); 10724 return QDF_STATUS_E_FAILURE; 10725 } 10726 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10727 wmi_buf_data(wmi_buf); 10728 WMITLV_SET_HDR(&cmd->tlv_header, 10729 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10730 WMITLV_GET_STRUCT_TLVLEN( 10731 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10732 10733 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10734 &cmd->peer_macaddr); 10735 cmd->vdev_id = chan_switch_params->vdev_id; 10736 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 10737 cmd->is_peer_responder = chan_switch_params->is_responder; 10738 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10739 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10740 cmd->offchan_oper_class = chan_switch_params->oper_class; 10741 10742 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10743 cmd->peer_macaddr.mac_addr31to0, 10744 cmd->peer_macaddr.mac_addr47to32); 10745 10746 WMI_LOGD(FL( 10747 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10748 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10749 ), 10750 cmd->vdev_id, 10751 cmd->offchan_mode, 10752 cmd->offchan_num, 10753 cmd->offchan_bw_bitmap, 10754 cmd->is_peer_responder, 10755 cmd->offchan_oper_class); 10756 10757 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10758 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10759 WMI_LOGP(FL("failed to send tdls off chan command")); 10760 wmi_buf_free(wmi_buf); 10761 return QDF_STATUS_E_FAILURE; 10762 } 10763 10764 10765 return QDF_STATUS_SUCCESS; 10766 } 10767 10768 /** 10769 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10770 * @wmi_handle: wmi handle 10771 * @pwmaTdlsparams: TDLS params 10772 * 10773 * Return: 0 for sucess or error code 10774 */ 10775 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10776 void *tdls_param, uint8_t tdls_state) 10777 { 10778 wmi_tdls_set_state_cmd_fixed_param *cmd; 10779 wmi_buf_t wmi_buf; 10780 10781 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10782 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10783 10784 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10785 if (!wmi_buf) { 10786 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10787 return QDF_STATUS_E_FAILURE; 10788 } 10789 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10790 WMITLV_SET_HDR(&cmd->tlv_header, 10791 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10792 WMITLV_GET_STRUCT_TLVLEN 10793 (wmi_tdls_set_state_cmd_fixed_param)); 10794 cmd->vdev_id = wmi_tdls->vdev_id; 10795 cmd->state = tdls_state; 10796 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10797 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10798 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10799 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10800 cmd->rssi_delta = wmi_tdls->rssi_delta; 10801 cmd->tdls_options = wmi_tdls->tdls_options; 10802 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10803 cmd->tdls_peer_traffic_response_timeout_ms = 10804 wmi_tdls->peer_traffic_response_timeout; 10805 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10806 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10807 cmd->tdls_puapsd_rx_frame_threshold = 10808 wmi_tdls->puapsd_rx_frame_threshold; 10809 cmd->teardown_notification_ms = 10810 wmi_tdls->teardown_notification_ms; 10811 cmd->tdls_peer_kickout_threshold = 10812 wmi_tdls->tdls_peer_kickout_threshold; 10813 10814 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10815 "notification_interval_ms: %d, " 10816 "tx_discovery_threshold: %d, " 10817 "tx_teardown_threshold: %d, " 10818 "rssi_teardown_threshold: %d, " 10819 "rssi_delta: %d, " 10820 "tdls_options: 0x%x, " 10821 "tdls_peer_traffic_ind_window: %d, " 10822 "tdls_peer_traffic_response_timeout: %d, " 10823 "tdls_puapsd_mask: 0x%x, " 10824 "tdls_puapsd_inactivity_time: %d, " 10825 "tdls_puapsd_rx_frame_threshold: %d, " 10826 "teardown_notification_ms: %d, " 10827 "tdls_peer_kickout_threshold: %d", 10828 __func__, tdls_state, cmd->state, 10829 cmd->notification_interval_ms, 10830 cmd->tx_discovery_threshold, 10831 cmd->tx_teardown_threshold, 10832 cmd->rssi_teardown_threshold, 10833 cmd->rssi_delta, 10834 cmd->tdls_options, 10835 cmd->tdls_peer_traffic_ind_window, 10836 cmd->tdls_peer_traffic_response_timeout_ms, 10837 cmd->tdls_puapsd_mask, 10838 cmd->tdls_puapsd_inactivity_time_ms, 10839 cmd->tdls_puapsd_rx_frame_threshold, 10840 cmd->teardown_notification_ms, 10841 cmd->tdls_peer_kickout_threshold); 10842 10843 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10844 WMI_TDLS_SET_STATE_CMDID)) { 10845 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10846 wmi_buf_free(wmi_buf); 10847 return QDF_STATUS_E_FAILURE; 10848 } 10849 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10850 10851 return QDF_STATUS_SUCCESS; 10852 } 10853 10854 /** 10855 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10856 * @wmi_handle: wmi handle 10857 * @peerStateParams: TDLS peer state params 10858 * 10859 * Return: QDF_STATUS_SUCCESS for success or error code 10860 */ 10861 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10862 struct tdls_peer_state_params *peerStateParams, 10863 uint32_t *ch_mhz) 10864 { 10865 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10866 wmi_tdls_peer_capabilities *peer_cap; 10867 wmi_channel *chan_info; 10868 wmi_buf_t wmi_buf; 10869 uint8_t *buf_ptr; 10870 uint32_t i; 10871 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10872 sizeof(wmi_tdls_peer_capabilities); 10873 10874 10875 len += WMI_TLV_HDR_SIZE + 10876 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10877 10878 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10879 if (!wmi_buf) { 10880 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10881 return QDF_STATUS_E_FAILURE; 10882 } 10883 10884 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10885 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10886 WMITLV_SET_HDR(&cmd->tlv_header, 10887 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10888 WMITLV_GET_STRUCT_TLVLEN 10889 (wmi_tdls_peer_update_cmd_fixed_param)); 10890 10891 cmd->vdev_id = peerStateParams->vdevId; 10892 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10893 &cmd->peer_macaddr); 10894 10895 10896 cmd->peer_state = peerStateParams->peerState; 10897 10898 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10899 "peer_macaddr.mac_addr31to0: 0x%x, " 10900 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10901 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10902 cmd->peer_macaddr.mac_addr31to0, 10903 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10904 10905 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10906 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10907 WMITLV_SET_HDR(&peer_cap->tlv_header, 10908 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10909 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10910 10911 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10912 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10913 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10914 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10915 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10916 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10917 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10918 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10919 10920 /* Ack and More Data Ack are sent as 0, so no need to set 10921 * but fill SP 10922 */ 10923 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10924 peerStateParams->peerCap.peerMaxSp); 10925 10926 peer_cap->buff_sta_support = 10927 peerStateParams->peerCap.peerBuffStaSupport; 10928 peer_cap->off_chan_support = 10929 peerStateParams->peerCap.peerOffChanSupport; 10930 peer_cap->peer_curr_operclass = 10931 peerStateParams->peerCap.peerCurrOperClass; 10932 /* self curr operclass is not being used and so pass op class for 10933 * preferred off chan in it. 10934 */ 10935 peer_cap->self_curr_operclass = 10936 peerStateParams->peerCap.opClassForPrefOffChan; 10937 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10938 peer_cap->peer_operclass_len = 10939 peerStateParams->peerCap.peerOperClassLen; 10940 10941 WMI_LOGD("%s: peer_operclass_len: %d", 10942 __func__, peer_cap->peer_operclass_len); 10943 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10944 peer_cap->peer_operclass[i] = 10945 peerStateParams->peerCap.peerOperClass[i]; 10946 WMI_LOGD("%s: peer_operclass[%d]: %d", 10947 __func__, i, peer_cap->peer_operclass[i]); 10948 } 10949 10950 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10951 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10952 peer_cap->pref_offchan_bw = 10953 peerStateParams->peerCap.prefOffChanBandwidth; 10954 10955 WMI_LOGD 10956 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10957 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10958 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10959 " %d, pref_offchan_bw: %d", 10960 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10961 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10962 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10963 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10964 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10965 10966 /* next fill variable size array of peer chan info */ 10967 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10968 WMITLV_SET_HDR(buf_ptr, 10969 WMITLV_TAG_ARRAY_STRUC, 10970 sizeof(wmi_channel) * 10971 peerStateParams->peerCap.peerChanLen); 10972 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10973 10974 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10975 WMITLV_SET_HDR(&chan_info->tlv_header, 10976 WMITLV_TAG_STRUC_wmi_channel, 10977 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10978 chan_info->mhz = ch_mhz[i]; 10979 chan_info->band_center_freq1 = chan_info->mhz; 10980 chan_info->band_center_freq2 = 0; 10981 10982 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10983 10984 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10985 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10986 WMI_LOGI("chan[%d] DFS[%d]\n", 10987 peerStateParams->peerCap.peerChan[i].chanId, 10988 peerStateParams->peerCap.peerChan[i].dfsSet); 10989 } 10990 10991 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10992 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10993 else 10994 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10995 10996 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10997 peerStateParams->peerCap. 10998 peerChan[i].pwr); 10999 11000 WMI_SET_CHANNEL_REG_POWER(chan_info, 11001 peerStateParams->peerCap.peerChan[i]. 11002 pwr); 11003 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 11004 peerStateParams->peerCap.peerChan[i].pwr); 11005 11006 chan_info++; 11007 } 11008 11009 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11010 WMI_TDLS_PEER_UPDATE_CMDID)) { 11011 WMI_LOGE("%s: failed to send tdls peer update state command", 11012 __func__); 11013 wmi_buf_free(wmi_buf); 11014 return QDF_STATUS_E_FAILURE; 11015 } 11016 11017 11018 return QDF_STATUS_SUCCESS; 11019 } 11020 11021 /* 11022 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 11023 * @wmi_handle: Pointer to WMi handle 11024 * @ie_data: Pointer for ie data 11025 * 11026 * This function sends IE information to firmware 11027 * 11028 * Return: QDF_STATUS_SUCCESS for success otherwise failure 11029 * 11030 */ 11031 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 11032 struct vdev_ie_info_param *ie_info) 11033 { 11034 wmi_vdev_set_ie_cmd_fixed_param *cmd; 11035 wmi_buf_t buf; 11036 uint8_t *buf_ptr; 11037 uint32_t len, ie_len_aligned; 11038 QDF_STATUS ret; 11039 11040 11041 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 11042 /* Allocate memory for the WMI command */ 11043 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 11044 11045 buf = wmi_buf_alloc(wmi_handle, len); 11046 if (!buf) { 11047 WMI_LOGE(FL("wmi_buf_alloc failed")); 11048 return QDF_STATUS_E_NOMEM; 11049 } 11050 11051 buf_ptr = wmi_buf_data(buf); 11052 qdf_mem_zero(buf_ptr, len); 11053 11054 /* Populate the WMI command */ 11055 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 11056 11057 WMITLV_SET_HDR(&cmd->tlv_header, 11058 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 11059 WMITLV_GET_STRUCT_TLVLEN( 11060 wmi_vdev_set_ie_cmd_fixed_param)); 11061 cmd->vdev_id = ie_info->vdev_id; 11062 cmd->ie_id = ie_info->ie_id; 11063 cmd->ie_len = ie_info->length; 11064 cmd->band = ie_info->band; 11065 11066 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 11067 ie_info->length, ie_info->vdev_id); 11068 11069 buf_ptr += sizeof(*cmd); 11070 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 11071 buf_ptr += WMI_TLV_HDR_SIZE; 11072 11073 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 11074 11075 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11076 WMI_VDEV_SET_IE_CMDID); 11077 if (QDF_IS_STATUS_ERROR(ret)) { 11078 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 11079 wmi_buf_free(buf); 11080 } 11081 11082 return ret; 11083 } 11084 11085 /** 11086 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 11087 * 11088 * @param wmi_handle : handle to WMI. 11089 * @param param : pointer to antenna param 11090 * 11091 * This function sends smart antenna enable command to FW 11092 * 11093 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11094 */ 11095 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 11096 struct smart_ant_enable_params *param) 11097 { 11098 /* Send WMI COMMAND to Enable */ 11099 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 11100 wmi_pdev_smart_ant_gpio_handle *gpio_param; 11101 wmi_buf_t buf; 11102 uint8_t *buf_ptr; 11103 int len = 0; 11104 QDF_STATUS ret; 11105 int loop = 0; 11106 11107 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11108 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 11109 buf = wmi_buf_alloc(wmi_handle, len); 11110 11111 if (!buf) { 11112 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11113 return QDF_STATUS_E_NOMEM; 11114 } 11115 11116 buf_ptr = wmi_buf_data(buf); 11117 qdf_mem_zero(buf_ptr, len); 11118 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 11119 11120 WMITLV_SET_HDR(&cmd->tlv_header, 11121 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 11122 WMITLV_GET_STRUCT_TLVLEN( 11123 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 11124 11125 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11126 param->pdev_id); 11127 cmd->enable = param->enable; 11128 cmd->mode = param->mode; 11129 cmd->rx_antenna = param->rx_antenna; 11130 cmd->tx_default_antenna = param->rx_antenna; 11131 11132 /* TLV indicating array of structures to follow */ 11133 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 11134 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11135 WMI_HAL_MAX_SANTENNA * 11136 sizeof(wmi_pdev_smart_ant_gpio_handle)); 11137 11138 buf_ptr += WMI_TLV_HDR_SIZE; 11139 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 11140 11141 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 11142 WMITLV_SET_HDR(&gpio_param->tlv_header, 11143 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 11144 WMITLV_GET_STRUCT_TLVLEN( 11145 wmi_pdev_smart_ant_gpio_handle)); 11146 if (param->mode == SMART_ANT_MODE_SERIAL) { 11147 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 11148 gpio_param->gpio_pin = param->gpio_pin[loop]; 11149 gpio_param->gpio_func = param->gpio_func[loop]; 11150 } else { 11151 gpio_param->gpio_pin = 0; 11152 gpio_param->gpio_func = 0; 11153 } 11154 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 11155 gpio_param->gpio_pin = param->gpio_pin[loop]; 11156 gpio_param->gpio_func = param->gpio_func[loop]; 11157 } 11158 /* Setting it to 0 for now */ 11159 gpio_param->pdev_id = 11160 wmi_handle->ops->convert_pdev_id_host_to_target( 11161 param->pdev_id); 11162 gpio_param++; 11163 } 11164 11165 ret = wmi_unified_cmd_send(wmi_handle, 11166 buf, 11167 len, 11168 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 11169 11170 if (ret != 0) { 11171 WMI_LOGE(" %s :WMI Failed\n", __func__); 11172 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 11173 cmd->enable, 11174 cmd->mode, 11175 cmd->rx_antenna, 11176 param->gpio_pin[0], param->gpio_pin[1], 11177 param->gpio_pin[2], param->gpio_pin[3], 11178 param->gpio_func[0], param->gpio_func[1], 11179 param->gpio_func[2], param->gpio_func[3], 11180 ret); 11181 wmi_buf_free(buf); 11182 } 11183 11184 return ret; 11185 } 11186 11187 /** 11188 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 11189 * 11190 * @param wmi_handle : handle to WMI. 11191 * @param param : pointer to rx antenna param 11192 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11193 */ 11194 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11195 struct smart_ant_rx_ant_params *param) 11196 { 11197 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 11198 wmi_buf_t buf; 11199 uint8_t *buf_ptr; 11200 uint32_t len; 11201 QDF_STATUS ret; 11202 11203 len = sizeof(*cmd); 11204 buf = wmi_buf_alloc(wmi_handle, len); 11205 WMI_LOGD("%s:\n", __func__); 11206 if (!buf) { 11207 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11208 return QDF_STATUS_E_NOMEM; 11209 } 11210 11211 buf_ptr = wmi_buf_data(buf); 11212 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 11213 WMITLV_SET_HDR(&cmd->tlv_header, 11214 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 11215 WMITLV_GET_STRUCT_TLVLEN( 11216 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 11217 cmd->rx_antenna = param->antenna; 11218 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11219 param->pdev_id); 11220 11221 ret = wmi_unified_cmd_send(wmi_handle, 11222 buf, 11223 len, 11224 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 11225 11226 if (ret != 0) { 11227 WMI_LOGE(" %s :WMI Failed\n", __func__); 11228 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 11229 __func__, 11230 cmd->rx_antenna, 11231 ret); 11232 wmi_buf_free(buf); 11233 } 11234 11235 return ret; 11236 } 11237 11238 /** 11239 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 11240 * @wmi_handle: wmi handle 11241 * @param: pointer to hold ctl table param 11242 * 11243 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11244 */ 11245 static QDF_STATUS 11246 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 11247 struct ctl_table_params *param) 11248 { 11249 uint16_t len, ctl_tlv_len; 11250 uint8_t *buf_ptr; 11251 wmi_buf_t buf; 11252 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 11253 uint32_t *ctl_array; 11254 11255 if (!param->ctl_array) 11256 return QDF_STATUS_E_FAILURE; 11257 11258 ctl_tlv_len = WMI_TLV_HDR_SIZE + 11259 roundup(param->ctl_cmd_len, sizeof(A_UINT32)); 11260 len = sizeof(*cmd) + ctl_tlv_len; 11261 11262 buf = wmi_buf_alloc(wmi_handle, len); 11263 if (!buf) { 11264 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11265 return QDF_STATUS_E_FAILURE; 11266 } 11267 11268 buf_ptr = wmi_buf_data(buf); 11269 qdf_mem_zero(buf_ptr, len); 11270 11271 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 11272 11273 WMITLV_SET_HDR(&cmd->tlv_header, 11274 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 11275 WMITLV_GET_STRUCT_TLVLEN( 11276 wmi_pdev_set_ctl_table_cmd_fixed_param)); 11277 cmd->ctl_len = param->ctl_cmd_len; 11278 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11279 param->pdev_id); 11280 11281 buf_ptr += sizeof(*cmd); 11282 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11283 (cmd->ctl_len)); 11284 buf_ptr += WMI_TLV_HDR_SIZE; 11285 ctl_array = (uint32_t *)buf_ptr; 11286 11287 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 11288 sizeof(param->ctl_band)); 11289 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 11290 param->ctl_cmd_len - 11291 sizeof(param->ctl_band)); 11292 11293 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11294 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 11295 WMI_LOGE("%s:Failed to send command\n", __func__); 11296 wmi_buf_free(buf); 11297 return QDF_STATUS_E_FAILURE; 11298 } 11299 11300 return QDF_STATUS_SUCCESS; 11301 } 11302 11303 /** 11304 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 11305 * @wmi_handle: wmi handle 11306 * @param: pointer to hold mimogain table param 11307 * 11308 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11309 */ 11310 static QDF_STATUS 11311 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 11312 struct mimogain_table_params *param) 11313 { 11314 uint16_t len, table_tlv_len; 11315 wmi_buf_t buf; 11316 uint8_t *buf_ptr; 11317 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 11318 uint32_t *gain_table; 11319 11320 if (!param->array_gain) 11321 return QDF_STATUS_E_FAILURE; 11322 11323 /* len must be multiple of a single array gain table */ 11324 if (param->tbl_len % 11325 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 11326 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 11327 WMI_LOGE("Array gain table len not correct\n"); 11328 return QDF_STATUS_E_FAILURE; 11329 } 11330 11331 table_tlv_len = WMI_TLV_HDR_SIZE + 11332 roundup(param->tbl_len, sizeof(uint32_t)); 11333 len = sizeof(*cmd) + table_tlv_len; 11334 11335 buf = wmi_buf_alloc(wmi_handle, len); 11336 if (!buf) { 11337 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11338 return QDF_STATUS_E_FAILURE; 11339 } 11340 11341 buf_ptr = wmi_buf_data(buf); 11342 qdf_mem_zero(buf_ptr, len); 11343 11344 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 11345 11346 WMITLV_SET_HDR(&cmd->tlv_header, 11347 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 11348 WMITLV_GET_STRUCT_TLVLEN( 11349 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 11350 11351 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11352 param->pdev_id); 11353 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 11354 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 11355 param->multichain_gain_bypass); 11356 11357 buf_ptr += sizeof(*cmd); 11358 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11359 (param->tbl_len)); 11360 buf_ptr += WMI_TLV_HDR_SIZE; 11361 gain_table = (uint32_t *)buf_ptr; 11362 11363 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 11364 param->array_gain, 11365 param->tbl_len); 11366 11367 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11368 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 11369 return QDF_STATUS_E_FAILURE; 11370 } 11371 11372 return QDF_STATUS_SUCCESS; 11373 } 11374 11375 /** 11376 * enum packet_power_tlv_flags: target defined 11377 * packet power rate flags for TLV 11378 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 11379 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 11380 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 11381 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 11382 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 11383 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 11384 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 11385 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 11386 * @WMI_TLV_FLAG_STBC: STBC is set 11387 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 11388 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 11389 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 11390 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 11391 * @WMI_TLV_FLAG_RTSENA: RTS enabled 11392 * @WMI_TLV_FLAG_CTSENA: CTS enabled 11393 * @WMI_TLV_FLAG_LDPC: LDPC is set 11394 * @WMI_TLV_FLAG_SGI: Short gaurd interval 11395 * @WMI_TLV_FLAG_SU: SU Data 11396 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 11397 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 11398 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 11399 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 11400 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 11401 * 11402 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 11403 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 11404 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 11405 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 11406 */ 11407 enum packet_power_tlv_flags { 11408 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 11409 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 11410 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 11411 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 11412 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 11413 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 11414 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 11415 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 11416 WMI_TLV_FLAG_STBC = 0x00000100, 11417 WMI_TLV_FLAG_40MHZ = 0x00000200, 11418 WMI_TLV_FLAG_80MHZ = 0x00000300, 11419 WMI_TLV_FLAG_160MHZ = 0x00000400, 11420 WMI_TLV_FLAG_TXBF = 0x00000800, 11421 WMI_TLV_FLAG_RTSENA = 0x00001000, 11422 WMI_TLV_FLAG_CTSENA = 0x00002000, 11423 WMI_TLV_FLAG_LDPC = 0x00004000, 11424 WMI_TLV_FLAG_SGI = 0x00008000, 11425 WMI_TLV_FLAG_SU = 0x00100000, 11426 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 11427 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 11428 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 11429 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 11430 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 11431 11432 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 11433 WMI_TLV_FLAG_BW_MASK = 0x3, 11434 WMI_TLV_FLAG_BW_SHIFT = 9, 11435 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 11436 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 11437 }; 11438 11439 /** 11440 * convert_to_power_info_rate_flags() - convert packet_power_info_params 11441 * to FW understandable format 11442 * @param: pointer to hold packet power info param 11443 * 11444 * @return FW understandable 32 bit rate flags 11445 */ 11446 static uint32_t 11447 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 11448 { 11449 uint32_t rateflags = 0; 11450 11451 if (param->chainmask) 11452 rateflags |= 11453 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 11454 if (param->chan_width) 11455 rateflags |= 11456 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 11457 << WMI_TLV_FLAG_BW_SHIFT); 11458 if (param->su_mu_ofdma) 11459 rateflags |= 11460 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 11461 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 11462 if (param->rate_flags & WMI_HOST_FLAG_STBC) 11463 rateflags |= WMI_TLV_FLAG_STBC; 11464 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 11465 rateflags |= WMI_TLV_FLAG_LDPC; 11466 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 11467 rateflags |= WMI_TLV_FLAG_TXBF; 11468 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 11469 rateflags |= WMI_TLV_FLAG_RTSENA; 11470 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 11471 rateflags |= WMI_TLV_FLAG_CTSENA; 11472 if (param->rate_flags & WMI_HOST_FLAG_SGI) 11473 rateflags |= WMI_TLV_FLAG_SGI; 11474 11475 return rateflags; 11476 } 11477 11478 /** 11479 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 11480 * info to fw 11481 * @wmi_handle: wmi handle 11482 * @param: pointer to hold packet power info param 11483 * 11484 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11485 */ 11486 static QDF_STATUS 11487 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 11488 struct packet_power_info_params *param) 11489 { 11490 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 11491 wmi_buf_t wmibuf; 11492 uint8_t *buf_ptr; 11493 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 11494 11495 wmibuf = wmi_buf_alloc(wmi_handle, len); 11496 if (wmibuf == NULL) 11497 return QDF_STATUS_E_NOMEM; 11498 11499 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 11500 11501 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 11502 WMITLV_SET_HDR(&cmd->tlv_header, 11503 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 11504 WMITLV_GET_STRUCT_TLVLEN( 11505 wmi_pdev_get_tpc_cmd_fixed_param)); 11506 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11507 param->pdev_id); 11508 cmd->rate_flags = convert_to_power_info_rate_flags(param); 11509 cmd->nss = param->nss; 11510 cmd->preamble = param->preamble; 11511 cmd->hw_rate = param->hw_rate; 11512 11513 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 11514 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 11515 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 11516 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 11517 11518 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 11519 WMI_PDEV_GET_TPC_CMDID)) { 11520 WMI_LOGE(FL("Failed to get tpc command\n")); 11521 wmi_buf_free(wmibuf); 11522 return QDF_STATUS_E_FAILURE; 11523 } 11524 11525 return QDF_STATUS_SUCCESS; 11526 } 11527 11528 /** 11529 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 11530 * @wmi_handle: wmi handle 11531 * @param: pointer to hold config ratemask params 11532 * 11533 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11534 */ 11535 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 11536 struct config_ratemask_params *param) 11537 { 11538 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 11539 wmi_buf_t buf; 11540 int32_t len = sizeof(*cmd); 11541 11542 buf = wmi_buf_alloc(wmi_handle, len); 11543 if (!buf) { 11544 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11545 return QDF_STATUS_E_FAILURE; 11546 } 11547 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 11548 WMITLV_SET_HDR(&cmd->tlv_header, 11549 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 11550 WMITLV_GET_STRUCT_TLVLEN( 11551 wmi_vdev_config_ratemask_cmd_fixed_param)); 11552 cmd->vdev_id = param->vdev_id; 11553 cmd->type = param->type; 11554 cmd->mask_lower32 = param->lower32; 11555 cmd->mask_higher32 = param->higher32; 11556 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n", 11557 param->vdev_id, param->type, param->lower32, param->higher32); 11558 11559 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11560 WMI_VDEV_RATEMASK_CMDID)) { 11561 WMI_LOGE("Seting vdev ratemask failed\n"); 11562 wmi_buf_free(buf); 11563 return QDF_STATUS_E_FAILURE; 11564 } 11565 11566 return QDF_STATUS_SUCCESS; 11567 } 11568 11569 /** 11570 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 11571 * @param: param sent from the host side 11572 * @cmd: param to be sent to the fw side 11573 */ 11574 static inline void copy_custom_aggr_bitmap( 11575 struct set_custom_aggr_size_params *param, 11576 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 11577 { 11578 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 11579 param->ac); 11580 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 11581 param->aggr_type); 11582 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11583 param->tx_aggr_size_disable); 11584 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11585 param->rx_aggr_size_disable); 11586 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 11587 param->tx_ac_enable); 11588 } 11589 11590 /** 11591 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 11592 * @wmi_handle: wmi handle 11593 * @param: pointer to hold custom aggr size params 11594 * 11595 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11596 */ 11597 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 11598 wmi_unified_t wmi_handle, 11599 struct set_custom_aggr_size_params *param) 11600 { 11601 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 11602 wmi_buf_t buf; 11603 int32_t len = sizeof(*cmd); 11604 11605 buf = wmi_buf_alloc(wmi_handle, len); 11606 if (!buf) { 11607 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11608 return QDF_STATUS_E_FAILURE; 11609 } 11610 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 11611 wmi_buf_data(buf); 11612 WMITLV_SET_HDR(&cmd->tlv_header, 11613 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 11614 WMITLV_GET_STRUCT_TLVLEN( 11615 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 11616 cmd->vdev_id = param->vdev_id; 11617 cmd->tx_aggr_size = param->tx_aggr_size; 11618 cmd->rx_aggr_size = param->rx_aggr_size; 11619 copy_custom_aggr_bitmap(param, cmd); 11620 11621 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 11622 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 11623 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 11624 "tx_ac_enable=0x%X\n", 11625 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 11626 param->ac, param->aggr_type, param->tx_aggr_size_disable, 11627 param->rx_aggr_size_disable, param->tx_ac_enable); 11628 11629 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11630 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 11631 WMI_LOGE("Seting custom aggregation size failed\n"); 11632 wmi_buf_free(buf); 11633 return QDF_STATUS_E_FAILURE; 11634 } 11635 11636 return QDF_STATUS_SUCCESS; 11637 } 11638 11639 /** 11640 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 11641 * @param wmi_handle : handle to WMI. 11642 * @param param : pointer to tx antenna param 11643 * 11644 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11645 */ 11646 11647 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 11648 struct set_qdepth_thresh_params *param) 11649 { 11650 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 11651 wmi_msduq_qdepth_thresh_update *cmd_update; 11652 wmi_buf_t buf; 11653 int32_t len = 0; 11654 int i; 11655 uint8_t *buf_ptr; 11656 QDF_STATUS ret; 11657 11658 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 11659 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 11660 return QDF_STATUS_E_INVAL; 11661 } 11662 11663 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11664 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 11665 param->num_of_msduq_updates); 11666 buf = wmi_buf_alloc(wmi_handle, len); 11667 11668 if (!buf) { 11669 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11670 return QDF_STATUS_E_NOMEM; 11671 } 11672 11673 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11674 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 11675 buf_ptr; 11676 11677 WMITLV_SET_HDR(&cmd->tlv_header, 11678 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 11679 , WMITLV_GET_STRUCT_TLVLEN( 11680 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 11681 11682 cmd->pdev_id = 11683 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11684 cmd->vdev_id = param->vdev_id; 11685 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 11686 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 11687 11688 buf_ptr += sizeof( 11689 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 11690 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11691 param->num_of_msduq_updates * 11692 sizeof(wmi_msduq_qdepth_thresh_update)); 11693 buf_ptr += WMI_TLV_HDR_SIZE; 11694 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 11695 11696 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 11697 WMITLV_SET_HDR(&cmd_update->tlv_header, 11698 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 11699 WMITLV_GET_STRUCT_TLVLEN( 11700 wmi_msduq_qdepth_thresh_update)); 11701 cmd_update->tid_num = param->update_params[i].tid_num; 11702 cmd_update->msduq_update_mask = 11703 param->update_params[i].msduq_update_mask; 11704 cmd_update->qdepth_thresh_value = 11705 param->update_params[i].qdepth_thresh_value; 11706 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 11707 "mac_addr_upper4=%X, mac_addr_lower2:%X," 11708 " update mask=0x%X thresh val=0x%X\n", 11709 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 11710 cmd->peer_mac_address.mac_addr31to0, 11711 cmd->peer_mac_address.mac_addr47to32, 11712 cmd_update->msduq_update_mask, 11713 cmd_update->qdepth_thresh_value); 11714 cmd_update++; 11715 } 11716 11717 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11718 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 11719 11720 if (ret != 0) { 11721 WMI_LOGE(" %s :WMI Failed\n", __func__); 11722 wmi_buf_free(buf); 11723 } 11724 11725 return ret; 11726 } 11727 11728 /** 11729 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11730 * @wmi_handle: wmi handle 11731 * @param: pointer to hold vap dscp tid map param 11732 * 11733 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11734 */ 11735 static QDF_STATUS 11736 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11737 struct vap_dscp_tid_map_params *param) 11738 { 11739 wmi_buf_t buf; 11740 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11741 int32_t len = sizeof(*cmd); 11742 11743 buf = wmi_buf_alloc(wmi_handle, len); 11744 if (!buf) { 11745 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11746 return QDF_STATUS_E_FAILURE; 11747 } 11748 11749 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11750 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11751 sizeof(A_UINT32) * WMI_DSCP_MAP_MAX); 11752 11753 cmd->vdev_id = param->vdev_id; 11754 cmd->enable_override = 0; 11755 11756 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11757 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11758 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11759 WMI_LOGE("Failed to set dscp cmd\n"); 11760 wmi_buf_free(buf); 11761 return QDF_STATUS_E_FAILURE; 11762 } 11763 11764 return QDF_STATUS_SUCCESS; 11765 } 11766 11767 /** 11768 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11769 * @wmi_handle: wmi handle 11770 * @macaddr: vdev mac address 11771 * @param: pointer to hold neigbour rx param 11772 * 11773 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11774 */ 11775 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11776 uint8_t macaddr[IEEE80211_ADDR_LEN], 11777 struct set_neighbour_rx_params *param) 11778 { 11779 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11780 wmi_buf_t buf; 11781 int32_t len = sizeof(*cmd); 11782 11783 buf = wmi_buf_alloc(wmi_handle, len); 11784 if (!buf) { 11785 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11786 return QDF_STATUS_E_FAILURE; 11787 } 11788 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11789 WMITLV_SET_HDR(&cmd->tlv_header, 11790 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11791 WMITLV_GET_STRUCT_TLVLEN( 11792 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11793 cmd->vdev_id = param->vdev_id; 11794 cmd->bssid_idx = param->idx; 11795 cmd->action = param->action; 11796 cmd->type = param->type; 11797 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11798 cmd->flag = 0; 11799 11800 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11801 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11802 WMI_LOGE("Failed to set neighbour rx param\n"); 11803 wmi_buf_free(buf); 11804 return QDF_STATUS_E_FAILURE; 11805 } 11806 11807 return QDF_STATUS_SUCCESS; 11808 } 11809 11810 /** 11811 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11812 * @param wmi_handle : handle to WMI. 11813 * @param macaddr : vdev mac address 11814 * @param param : pointer to tx antenna param 11815 * 11816 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11817 */ 11818 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11819 uint8_t macaddr[IEEE80211_ADDR_LEN], 11820 struct smart_ant_tx_ant_params *param) 11821 { 11822 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11823 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11824 wmi_buf_t buf; 11825 int32_t len = 0; 11826 int i; 11827 uint8_t *buf_ptr; 11828 QDF_STATUS ret; 11829 11830 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11831 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11832 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11833 buf = wmi_buf_alloc(wmi_handle, len); 11834 11835 if (!buf) { 11836 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11837 return QDF_STATUS_E_NOMEM; 11838 } 11839 11840 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11841 qdf_mem_zero(buf_ptr, len); 11842 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11843 11844 WMITLV_SET_HDR(&cmd->tlv_header, 11845 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11846 WMITLV_GET_STRUCT_TLVLEN( 11847 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11848 11849 cmd->vdev_id = param->vdev_id; 11850 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11851 11852 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11853 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11854 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11855 buf_ptr += WMI_TLV_HDR_SIZE; 11856 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11857 11858 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11859 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11860 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11861 WMITLV_GET_STRUCT_TLVLEN( 11862 wmi_peer_smart_ant_set_tx_antenna_series)); 11863 ant_tx_series->antenna_series = param->antenna_array[i]; 11864 ant_tx_series++; 11865 } 11866 11867 ret = wmi_unified_cmd_send(wmi_handle, 11868 buf, 11869 len, 11870 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11871 11872 if (ret != 0) { 11873 WMI_LOGE(" %s :WMI Failed\n", __func__); 11874 wmi_buf_free(buf); 11875 } 11876 11877 return ret; 11878 } 11879 11880 /** 11881 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11882 * @wmi_handle: wmi handle 11883 * @param: pointer to hold ant switch tbl param 11884 * 11885 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11886 */ 11887 static QDF_STATUS 11888 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11889 struct ant_switch_tbl_params *param) 11890 { 11891 uint8_t len; 11892 wmi_buf_t buf; 11893 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11894 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11895 uint8_t *buf_ptr; 11896 11897 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11898 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11899 buf = wmi_buf_alloc(wmi_handle, len); 11900 11901 if (!buf) { 11902 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11903 return QDF_STATUS_E_NOMEM; 11904 } 11905 11906 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11907 qdf_mem_zero(buf_ptr, len); 11908 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11909 11910 WMITLV_SET_HDR(&cmd->tlv_header, 11911 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11912 WMITLV_GET_STRUCT_TLVLEN( 11913 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11914 11915 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11916 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11917 cmd->mac_id = 11918 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11919 11920 /* TLV indicating array of structures to follow */ 11921 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11922 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11923 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11924 buf_ptr += WMI_TLV_HDR_SIZE; 11925 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11926 11927 ctrl_chain->pdev_id = 11928 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11929 ctrl_chain->antCtrlChain = param->antCtrlChain; 11930 11931 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11932 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11933 wmi_buf_free(buf); 11934 return QDF_STATUS_E_FAILURE; 11935 } 11936 11937 return QDF_STATUS_SUCCESS; 11938 } 11939 11940 /** 11941 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11942 * training information function 11943 * @param wmi_handle : handle to WMI. 11944 * @macaddr : vdev mac address 11945 * @param param : pointer to tx antenna param 11946 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11947 */ 11948 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11949 wmi_unified_t wmi_handle, 11950 uint8_t macaddr[IEEE80211_ADDR_LEN], 11951 struct smart_ant_training_info_params *param) 11952 { 11953 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11954 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11955 wmi_buf_t buf; 11956 uint8_t *buf_ptr; 11957 int32_t len = 0; 11958 QDF_STATUS ret; 11959 int loop; 11960 11961 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11962 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11963 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11964 buf = wmi_buf_alloc(wmi_handle, len); 11965 11966 if (!buf) { 11967 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11968 return QDF_STATUS_E_NOMEM; 11969 } 11970 11971 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11972 qdf_mem_zero(buf_ptr, len); 11973 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11974 11975 WMITLV_SET_HDR(&cmd->tlv_header, 11976 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11977 WMITLV_GET_STRUCT_TLVLEN( 11978 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11979 11980 cmd->vdev_id = param->vdev_id; 11981 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11982 cmd->num_pkts = param->numpkts; 11983 11984 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11985 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11986 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11987 WMI_SMART_ANT_MAX_RATE_SERIES); 11988 11989 buf_ptr += WMI_TLV_HDR_SIZE; 11990 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11991 11992 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11993 WMITLV_SET_HDR(&train_param->tlv_header, 11994 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11995 WMITLV_GET_STRUCT_TLVLEN( 11996 wmi_peer_smart_ant_set_train_antenna_param)); 11997 train_param->train_rate_series = param->rate_array[loop]; 11998 train_param->train_antenna_series = param->antenna_array[loop]; 11999 train_param->rc_flags = 0; 12000 WMI_LOGI(FL("Series number:%d\n"), loop); 12001 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 12002 train_param->train_rate_series, 12003 train_param->train_antenna_series); 12004 train_param++; 12005 } 12006 12007 ret = wmi_unified_cmd_send(wmi_handle, 12008 buf, 12009 len, 12010 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 12011 12012 if (ret != 0) { 12013 WMI_LOGE(" %s :WMI Failed\n", __func__); 12014 wmi_buf_free(buf); 12015 return QDF_STATUS_E_FAILURE; 12016 } 12017 12018 return ret; 12019 } 12020 12021 /** 12022 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 12023 * configuration function 12024 * @param wmi_handle : handle to WMI. 12025 * @macaddr : vdev mad address 12026 * @param param : pointer to tx antenna param 12027 * 12028 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12029 */ 12030 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 12031 wmi_unified_t wmi_handle, 12032 uint8_t macaddr[IEEE80211_ADDR_LEN], 12033 struct smart_ant_node_config_params *param) 12034 { 12035 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 12036 wmi_buf_t buf; 12037 uint8_t *buf_ptr; 12038 int32_t len = 0, args_tlv_len; 12039 int ret; 12040 int i = 0; 12041 A_UINT32 *node_config_args; 12042 12043 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(A_UINT32); 12044 len = sizeof(*cmd) + args_tlv_len; 12045 12046 if ((param->args_count == 0)) { 12047 WMI_LOGE("%s: Can't send a command with %d arguments\n", 12048 __func__, param->args_count); 12049 return QDF_STATUS_E_FAILURE; 12050 } 12051 12052 buf = wmi_buf_alloc(wmi_handle, len); 12053 if (!buf) { 12054 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12055 return QDF_STATUS_E_NOMEM; 12056 } 12057 12058 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 12059 wmi_buf_data(buf); 12060 buf_ptr = (uint8_t *)cmd; 12061 WMITLV_SET_HDR(&cmd->tlv_header, 12062 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 12063 WMITLV_GET_STRUCT_TLVLEN( 12064 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 12065 cmd->vdev_id = param->vdev_id; 12066 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12067 cmd->cmd_id = param->cmd_id; 12068 cmd->args_count = param->args_count; 12069 buf_ptr += sizeof( 12070 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 12071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12072 (cmd->args_count * sizeof(A_UINT32))); 12073 buf_ptr += WMI_TLV_HDR_SIZE; 12074 node_config_args = (A_UINT32 *)buf_ptr; 12075 12076 for (i = 0; i < param->args_count; i++) { 12077 node_config_args[i] = param->args_arr[i]; 12078 WMI_LOGI("%d", param->args_arr[i]); 12079 } 12080 12081 ret = wmi_unified_cmd_send(wmi_handle, 12082 buf, 12083 len, 12084 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 12085 12086 if (ret != 0) { 12087 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 12088 __func__, param->cmd_id, macaddr[0], 12089 macaddr[1], macaddr[2], macaddr[3], 12090 macaddr[4], macaddr[5], ret); 12091 wmi_buf_free(buf); 12092 } 12093 12094 return ret; 12095 } 12096 12097 /** 12098 * send_set_atf_cmd_tlv() - send set atf command to fw 12099 * @wmi_handle: wmi handle 12100 * @param: pointer to set atf param 12101 * 12102 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12103 */ 12104 static QDF_STATUS 12105 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 12106 struct set_atf_params *param) 12107 { 12108 wmi_atf_peer_info *peer_info; 12109 wmi_peer_atf_request_fixed_param *cmd; 12110 wmi_buf_t buf; 12111 uint8_t *buf_ptr; 12112 int i; 12113 int32_t len = 0; 12114 QDF_STATUS retval; 12115 12116 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12117 len += param->num_peers * sizeof(wmi_atf_peer_info); 12118 buf = wmi_buf_alloc(wmi_handle, len); 12119 if (!buf) { 12120 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12121 return QDF_STATUS_E_FAILURE; 12122 } 12123 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12124 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 12125 WMITLV_SET_HDR(&cmd->tlv_header, 12126 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 12127 WMITLV_GET_STRUCT_TLVLEN( 12128 wmi_peer_atf_request_fixed_param)); 12129 cmd->num_peers = param->num_peers; 12130 12131 buf_ptr += sizeof(*cmd); 12132 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12133 sizeof(wmi_atf_peer_info) * 12134 cmd->num_peers); 12135 buf_ptr += WMI_TLV_HDR_SIZE; 12136 peer_info = (wmi_atf_peer_info *)buf_ptr; 12137 12138 for (i = 0; i < cmd->num_peers; i++) { 12139 WMITLV_SET_HDR(&peer_info->tlv_header, 12140 WMITLV_TAG_STRUC_wmi_atf_peer_info, 12141 WMITLV_GET_STRUCT_TLVLEN( 12142 wmi_atf_peer_info)); 12143 qdf_mem_copy(&(peer_info->peer_macaddr), 12144 &(param->peer_info[i].peer_macaddr), 12145 sizeof(wmi_mac_addr)); 12146 peer_info->atf_units = param->peer_info[i].percentage_peer; 12147 peer_info->vdev_id = param->peer_info[i].vdev_id; 12148 peer_info->pdev_id = 12149 wmi_handle->ops->convert_pdev_id_host_to_target( 12150 param->peer_info[i].pdev_id); 12151 /* 12152 * TLV definition for peer atf request fixed param combines 12153 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 12154 * stats and atf extension stats as two different 12155 * implementations. 12156 * Need to discuss with FW on this. 12157 * 12158 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 12159 * peer_info->atf_units_reserved = 12160 * param->peer_ext_info[i].atf_index_reserved; 12161 */ 12162 peer_info++; 12163 } 12164 12165 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12166 WMI_PEER_ATF_REQUEST_CMDID); 12167 12168 if (retval != QDF_STATUS_SUCCESS) { 12169 WMI_LOGE("%s : WMI Failed\n", __func__); 12170 wmi_buf_free(buf); 12171 } 12172 12173 return retval; 12174 } 12175 12176 /** 12177 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 12178 * @wmi_handle: wmi handle 12179 * @param: pointer to hold fwtest param 12180 * 12181 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12182 */ 12183 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 12184 struct set_fwtest_params *param) 12185 { 12186 wmi_fwtest_set_param_cmd_fixed_param *cmd; 12187 wmi_buf_t buf; 12188 int32_t len = sizeof(*cmd); 12189 12190 buf = wmi_buf_alloc(wmi_handle, len); 12191 12192 if (!buf) { 12193 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12194 return QDF_STATUS_E_FAILURE; 12195 } 12196 12197 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 12198 WMITLV_SET_HDR(&cmd->tlv_header, 12199 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 12200 WMITLV_GET_STRUCT_TLVLEN( 12201 wmi_fwtest_set_param_cmd_fixed_param)); 12202 cmd->param_id = param->arg; 12203 cmd->param_value = param->value; 12204 12205 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 12206 WMI_LOGE("Setting FW test param failed\n"); 12207 wmi_buf_free(buf); 12208 return QDF_STATUS_E_FAILURE; 12209 } 12210 12211 return QDF_STATUS_SUCCESS; 12212 } 12213 12214 /** 12215 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 12216 * @wmi_handle: wmi handle 12217 * @param: pointer to qboost params 12218 * @macaddr: vdev mac address 12219 * 12220 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12221 */ 12222 static QDF_STATUS 12223 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 12224 uint8_t macaddr[IEEE80211_ADDR_LEN], 12225 struct set_qboost_params *param) 12226 { 12227 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 12228 wmi_buf_t buf; 12229 int32_t len; 12230 QDF_STATUS ret; 12231 12232 len = sizeof(*cmd); 12233 12234 buf = wmi_buf_alloc(wmi_handle, len); 12235 if (!buf) { 12236 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12237 return QDF_STATUS_E_FAILURE; 12238 } 12239 12240 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 12241 WMITLV_SET_HDR(&cmd->tlv_header, 12242 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 12243 WMITLV_GET_STRUCT_TLVLEN( 12244 WMI_QBOOST_CFG_CMD_fixed_param)); 12245 cmd->vdev_id = param->vdev_id; 12246 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12247 cmd->qb_enable = param->value; 12248 12249 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12250 WMI_QBOOST_CFG_CMDID); 12251 12252 if (ret != 0) { 12253 WMI_LOGE("Setting qboost cmd failed\n"); 12254 wmi_buf_free(buf); 12255 } 12256 12257 return ret; 12258 } 12259 12260 /** 12261 * send_gpio_config_cmd_tlv() - send gpio config to fw 12262 * @wmi_handle: wmi handle 12263 * @param: pointer to hold gpio config param 12264 * 12265 * Return: 0 for success or error code 12266 */ 12267 static QDF_STATUS 12268 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 12269 struct gpio_config_params *param) 12270 { 12271 wmi_gpio_config_cmd_fixed_param *cmd; 12272 wmi_buf_t buf; 12273 int32_t len; 12274 QDF_STATUS ret; 12275 12276 len = sizeof(*cmd); 12277 12278 /* Sanity Checks */ 12279 if (param->pull_type > WMI_GPIO_PULL_DOWN || 12280 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 12281 return QDF_STATUS_E_FAILURE; 12282 } 12283 12284 buf = wmi_buf_alloc(wmi_handle, len); 12285 if (!buf) { 12286 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12287 return QDF_STATUS_E_FAILURE; 12288 } 12289 12290 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 12291 WMITLV_SET_HDR(&cmd->tlv_header, 12292 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 12293 WMITLV_GET_STRUCT_TLVLEN( 12294 wmi_gpio_config_cmd_fixed_param)); 12295 cmd->gpio_num = param->gpio_num; 12296 cmd->input = param->input; 12297 cmd->pull_type = param->pull_type; 12298 cmd->intr_mode = param->intr_mode; 12299 12300 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12301 WMI_GPIO_CONFIG_CMDID); 12302 12303 if (ret != 0) { 12304 WMI_LOGE("Sending GPIO config cmd failed\n"); 12305 wmi_buf_free(buf); 12306 } 12307 12308 return ret; 12309 } 12310 12311 /** 12312 * send_gpio_output_cmd_tlv() - send gpio output to fw 12313 * @wmi_handle: wmi handle 12314 * @param: pointer to hold gpio output param 12315 * 12316 * Return: 0 for success or error code 12317 */ 12318 static QDF_STATUS 12319 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 12320 struct gpio_output_params *param) 12321 { 12322 wmi_gpio_output_cmd_fixed_param *cmd; 12323 wmi_buf_t buf; 12324 int32_t len; 12325 QDF_STATUS ret; 12326 12327 len = sizeof(*cmd); 12328 12329 buf = wmi_buf_alloc(wmi_handle, len); 12330 if (!buf) { 12331 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12332 return QDF_STATUS_E_FAILURE; 12333 } 12334 12335 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 12336 WMITLV_SET_HDR(&cmd->tlv_header, 12337 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 12338 WMITLV_GET_STRUCT_TLVLEN( 12339 wmi_gpio_output_cmd_fixed_param)); 12340 cmd->gpio_num = param->gpio_num; 12341 cmd->set = param->set; 12342 12343 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12344 WMI_GPIO_OUTPUT_CMDID); 12345 12346 if (ret != 0) { 12347 WMI_LOGE("Sending GPIO output cmd failed\n"); 12348 wmi_buf_free(buf); 12349 } 12350 12351 return ret; 12352 12353 } 12354 12355 /** 12356 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 12357 * 12358 * @param wmi_handle : handle to WMI. 12359 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12360 */ 12361 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 12362 { 12363 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 12364 wmi_buf_t buf; 12365 QDF_STATUS ret; 12366 int32_t len; 12367 12368 len = sizeof(*cmd); 12369 12370 buf = wmi_buf_alloc(wmi_handle, len); 12371 if (!buf) { 12372 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12373 return QDF_STATUS_E_FAILURE; 12374 } 12375 12376 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 12377 WMITLV_SET_HDR(&cmd->tlv_header, 12378 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 12379 WMITLV_GET_STRUCT_TLVLEN( 12380 wmi_pdev_dfs_disable_cmd_fixed_param)); 12381 /* Filling it with WMI_PDEV_ID_SOC for now */ 12382 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12383 WMI_HOST_PDEV_ID_SOC); 12384 12385 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12386 WMI_PDEV_DFS_DISABLE_CMDID); 12387 12388 if (ret != 0) { 12389 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 12390 wmi_buf_free(buf); 12391 } 12392 12393 return ret; 12394 } 12395 12396 /** 12397 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 12398 * 12399 * @param wmi_handle : handle to WMI. 12400 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12401 */ 12402 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 12403 { 12404 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 12405 wmi_buf_t buf; 12406 QDF_STATUS ret; 12407 int32_t len; 12408 12409 len = sizeof(*cmd); 12410 12411 buf = wmi_buf_alloc(wmi_handle, len); 12412 if (!buf) { 12413 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12414 return QDF_STATUS_E_FAILURE; 12415 } 12416 12417 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 12418 WMITLV_SET_HDR(&cmd->tlv_header, 12419 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 12420 WMITLV_GET_STRUCT_TLVLEN( 12421 wmi_pdev_dfs_enable_cmd_fixed_param)); 12422 /* Reserved for future use */ 12423 cmd->reserved0 = 0; 12424 12425 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12426 WMI_PDEV_DFS_ENABLE_CMDID); 12427 12428 if (ret != 0) { 12429 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 12430 wmi_buf_free(buf); 12431 } 12432 12433 return ret; 12434 } 12435 12436 /** 12437 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 12438 * to fw 12439 * @wmi_handle: wmi handle 12440 * @param: pointer to hold periodic chan stats param 12441 * 12442 * Return: 0 for success or error code 12443 */ 12444 static QDF_STATUS 12445 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 12446 struct periodic_chan_stats_params *param) 12447 { 12448 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 12449 wmi_buf_t buf; 12450 QDF_STATUS ret; 12451 int32_t len; 12452 12453 len = sizeof(*cmd); 12454 12455 buf = wmi_buf_alloc(wmi_handle, len); 12456 if (!buf) { 12457 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12458 return QDF_STATUS_E_FAILURE; 12459 } 12460 12461 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 12462 wmi_buf_data(buf); 12463 WMITLV_SET_HDR(&cmd->tlv_header, 12464 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 12465 WMITLV_GET_STRUCT_TLVLEN( 12466 wmi_set_periodic_channel_stats_config_fixed_param)); 12467 cmd->enable = param->enable; 12468 cmd->stats_period = param->stats_period; 12469 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12470 param->pdev_id); 12471 12472 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12473 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 12474 12475 if (ret != 0) { 12476 WMI_LOGE("Sending periodic chan stats config failed"); 12477 wmi_buf_free(buf); 12478 } 12479 12480 return ret; 12481 } 12482 12483 /** 12484 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 12485 * @wmi_handle: wmi handle 12486 * @mac_id: radio context 12487 * 12488 * Return: 0 for success or error code 12489 */ 12490 static QDF_STATUS 12491 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 12492 { 12493 wmi_buf_t buf; 12494 QDF_STATUS ret; 12495 wmi_pdev_get_nfcal_power_fixed_param *cmd; 12496 int32_t len = sizeof(*cmd); 12497 12498 buf = wmi_buf_alloc(wmi_handle, len); 12499 if (buf == NULL) 12500 return QDF_STATUS_E_NOMEM; 12501 12502 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 12503 WMITLV_SET_HDR(&cmd->tlv_header, 12504 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 12505 WMITLV_GET_STRUCT_TLVLEN 12506 (wmi_pdev_get_nfcal_power_fixed_param)); 12507 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 12508 12509 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12510 WMI_PDEV_GET_NFCAL_POWER_CMDID); 12511 if (ret != 0) { 12512 WMI_LOGE("Sending get nfcal power cmd failed\n"); 12513 wmi_buf_free(buf); 12514 } 12515 12516 return ret; 12517 } 12518 12519 /** 12520 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 12521 * @wmi_handle: wmi handle 12522 * @param: pointer to ht ie param 12523 * 12524 * Return: 0 for success or error code 12525 */ 12526 static QDF_STATUS 12527 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12528 struct ht_ie_params *param) 12529 { 12530 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 12531 wmi_buf_t buf; 12532 QDF_STATUS ret; 12533 int32_t len; 12534 uint8_t *buf_ptr; 12535 12536 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12537 roundup(param->ie_len, sizeof(uint32_t)); 12538 12539 buf = wmi_buf_alloc(wmi_handle, len); 12540 if (!buf) { 12541 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12542 return QDF_STATUS_E_FAILURE; 12543 } 12544 12545 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12546 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 12547 WMITLV_SET_HDR(&cmd->tlv_header, 12548 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 12549 WMITLV_GET_STRUCT_TLVLEN( 12550 wmi_pdev_set_ht_ie_cmd_fixed_param)); 12551 cmd->reserved0 = 0; 12552 cmd->ie_len = param->ie_len; 12553 cmd->tx_streams = param->tx_streams; 12554 cmd->rx_streams = param->rx_streams; 12555 12556 buf_ptr += sizeof(*cmd); 12557 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12558 buf_ptr += WMI_TLV_HDR_SIZE; 12559 if (param->ie_len) 12560 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12561 cmd->ie_len); 12562 12563 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12564 WMI_PDEV_SET_HT_CAP_IE_CMDID); 12565 12566 if (ret != 0) { 12567 WMI_LOGE("Sending set ht ie cmd failed\n"); 12568 wmi_buf_free(buf); 12569 } 12570 12571 return ret; 12572 } 12573 12574 /** 12575 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 12576 * @wmi_handle: wmi handle 12577 * @param: pointer to vht ie param 12578 * 12579 * Return: 0 for success or error code 12580 */ 12581 static QDF_STATUS 12582 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12583 struct vht_ie_params *param) 12584 { 12585 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 12586 wmi_buf_t buf; 12587 QDF_STATUS ret; 12588 int32_t len; 12589 uint8_t *buf_ptr; 12590 12591 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12592 roundup(param->ie_len, sizeof(uint32_t)); 12593 12594 buf = wmi_buf_alloc(wmi_handle, len); 12595 if (!buf) { 12596 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12597 return QDF_STATUS_E_FAILURE; 12598 } 12599 12600 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12601 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 12602 WMITLV_SET_HDR(&cmd->tlv_header, 12603 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 12604 WMITLV_GET_STRUCT_TLVLEN( 12605 wmi_pdev_set_vht_ie_cmd_fixed_param)); 12606 cmd->reserved0 = 0; 12607 cmd->ie_len = param->ie_len; 12608 cmd->tx_streams = param->tx_streams; 12609 cmd->rx_streams = param->rx_streams; 12610 12611 buf_ptr += sizeof(*cmd); 12612 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12613 buf_ptr += WMI_TLV_HDR_SIZE; 12614 if (param->ie_len) 12615 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12616 cmd->ie_len); 12617 12618 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12619 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 12620 12621 if (ret != 0) { 12622 WMI_LOGE("Sending set vht ie cmd failed\n"); 12623 wmi_buf_free(buf); 12624 } 12625 12626 return ret; 12627 } 12628 12629 /** 12630 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 12631 * @wmi_handle: wmi handle 12632 * @param: pointer to quiet mode params 12633 * 12634 * Return: 0 for success or error code 12635 */ 12636 static QDF_STATUS 12637 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 12638 struct set_quiet_mode_params *param) 12639 { 12640 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 12641 wmi_buf_t buf; 12642 QDF_STATUS ret; 12643 int32_t len; 12644 12645 len = sizeof(*quiet_cmd); 12646 buf = wmi_buf_alloc(wmi_handle, len); 12647 if (!buf) { 12648 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12649 return QDF_STATUS_E_FAILURE; 12650 } 12651 12652 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12653 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 12654 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 12655 WMITLV_GET_STRUCT_TLVLEN( 12656 wmi_pdev_set_quiet_cmd_fixed_param)); 12657 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12658 quiet_cmd->enabled = param->enabled; 12659 quiet_cmd->period = (param->period)*(param->intval); 12660 quiet_cmd->duration = param->duration; 12661 quiet_cmd->next_start = param->offset; 12662 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12663 WMI_HOST_PDEV_ID_SOC); 12664 12665 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12666 WMI_PDEV_SET_QUIET_MODE_CMDID); 12667 12668 if (ret != 0) { 12669 WMI_LOGE("Sending set quiet cmd failed\n"); 12670 wmi_buf_free(buf); 12671 } 12672 12673 return ret; 12674 } 12675 12676 /** 12677 * send_set_bwf_cmd_tlv() - send set bwf command to fw 12678 * @wmi_handle: wmi handle 12679 * @param: pointer to set bwf param 12680 * 12681 * Return: 0 for success or error code 12682 */ 12683 static QDF_STATUS 12684 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12685 struct set_bwf_params *param) 12686 { 12687 wmi_bwf_peer_info *peer_info; 12688 wmi_peer_bwf_request_fixed_param *cmd; 12689 wmi_buf_t buf; 12690 QDF_STATUS retval; 12691 int32_t len; 12692 uint8_t *buf_ptr; 12693 int i; 12694 12695 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12696 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12697 buf = wmi_buf_alloc(wmi_handle, len); 12698 if (!buf) { 12699 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12700 return QDF_STATUS_E_FAILURE; 12701 } 12702 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12703 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12704 WMITLV_SET_HDR(&cmd->tlv_header, 12705 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12706 WMITLV_GET_STRUCT_TLVLEN( 12707 wmi_peer_bwf_request_fixed_param)); 12708 cmd->num_peers = param->num_peers; 12709 12710 buf_ptr += sizeof(*cmd); 12711 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12712 sizeof(wmi_bwf_peer_info) * 12713 cmd->num_peers); 12714 buf_ptr += WMI_TLV_HDR_SIZE; 12715 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12716 12717 for (i = 0; i < cmd->num_peers; i++) { 12718 WMITLV_SET_HDR(&peer_info->tlv_header, 12719 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12720 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12721 peer_info->bwf_guaranteed_bandwidth = 12722 param->peer_info[i].throughput; 12723 peer_info->bwf_max_airtime = 12724 param->peer_info[i].max_airtime; 12725 peer_info->bwf_peer_priority = 12726 param->peer_info[i].priority; 12727 qdf_mem_copy(&peer_info->peer_macaddr, 12728 ¶m->peer_info[i].peer_macaddr, 12729 sizeof(param->peer_info[i].peer_macaddr)); 12730 peer_info->vdev_id = 12731 param->peer_info[i].vdev_id; 12732 peer_info->pdev_id = 12733 wmi_handle->ops->convert_pdev_id_host_to_target( 12734 param->peer_info[i].pdev_id); 12735 peer_info++; 12736 } 12737 12738 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12739 WMI_PEER_BWF_REQUEST_CMDID); 12740 12741 if (retval != QDF_STATUS_SUCCESS) { 12742 WMI_LOGE("%s : WMI Failed\n", __func__); 12743 wmi_buf_free(buf); 12744 } 12745 12746 return retval; 12747 } 12748 12749 /** 12750 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12751 * @wmi_handle: wmi handle 12752 * @param: pointer to hold mcast update param 12753 * 12754 * Return: 0 for success or error code 12755 */ 12756 static QDF_STATUS 12757 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12758 struct mcast_group_update_params *param) 12759 { 12760 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12761 wmi_buf_t buf; 12762 QDF_STATUS ret; 12763 int32_t len; 12764 int offset = 0; 12765 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12766 12767 len = sizeof(*cmd); 12768 buf = wmi_buf_alloc(wmi_handle, len); 12769 if (!buf) { 12770 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12771 return QDF_STATUS_E_FAILURE; 12772 } 12773 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12774 WMITLV_SET_HDR(&cmd->tlv_header, 12775 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12776 WMITLV_GET_STRUCT_TLVLEN( 12777 wmi_peer_mcast_group_cmd_fixed_param)); 12778 /* confirm the buffer is 4-byte aligned */ 12779 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12780 qdf_mem_zero(cmd, sizeof(*cmd)); 12781 12782 cmd->vdev_id = param->vap_id; 12783 /* construct the message assuming our endianness matches the target */ 12784 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12785 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12786 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12787 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12788 if (param->is_action_delete) 12789 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12790 12791 if (param->is_mcast_addr_len) 12792 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12793 12794 if (param->is_filter_mode_snoop) 12795 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12796 12797 /* unicast address spec only applies for non-wildcard cases */ 12798 if (!param->wildcard && param->ucast_mac_addr) { 12799 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12800 &cmd->ucast_mac_addr); 12801 } 12802 12803 if (param->mcast_ip_addr) { 12804 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12805 sizeof(cmd->mcast_ip_addr)); 12806 offset = sizeof(cmd->mcast_ip_addr) - 12807 param->mcast_ip_addr_bytes; 12808 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12809 param->mcast_ip_addr, 12810 param->mcast_ip_addr_bytes); 12811 } 12812 if (!param->mask) 12813 param->mask = &dummymask[0]; 12814 12815 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12816 param->mask, 12817 param->mcast_ip_addr_bytes); 12818 12819 if (param->srcs && param->nsrcs) { 12820 cmd->num_filter_addr = param->nsrcs; 12821 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12822 sizeof(cmd->filter_addr)); 12823 12824 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12825 param->nsrcs * param->mcast_ip_addr_bytes); 12826 } 12827 12828 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12829 WMI_PEER_MCAST_GROUP_CMDID); 12830 12831 if (ret != QDF_STATUS_SUCCESS) { 12832 WMI_LOGE("%s : WMI Failed\n", __func__); 12833 wmi_buf_free(buf); 12834 } 12835 12836 return ret; 12837 } 12838 12839 /** 12840 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12841 * command to fw 12842 * @wmi_handle: wmi handle 12843 * @param: pointer to hold spectral config parameter 12844 * 12845 * Return: 0 for success or error code 12846 */ 12847 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12848 struct vdev_spectral_configure_params *param) 12849 { 12850 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12851 wmi_buf_t buf; 12852 QDF_STATUS ret; 12853 int32_t len; 12854 12855 len = sizeof(*cmd); 12856 buf = wmi_buf_alloc(wmi_handle, len); 12857 if (!buf) { 12858 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12859 return QDF_STATUS_E_FAILURE; 12860 } 12861 12862 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12863 WMITLV_SET_HDR(&cmd->tlv_header, 12864 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12865 WMITLV_GET_STRUCT_TLVLEN( 12866 wmi_vdev_spectral_configure_cmd_fixed_param)); 12867 12868 cmd->vdev_id = param->vdev_id; 12869 cmd->spectral_scan_count = param->count; 12870 cmd->spectral_scan_period = param->period; 12871 cmd->spectral_scan_priority = param->spectral_pri; 12872 cmd->spectral_scan_fft_size = param->fft_size; 12873 cmd->spectral_scan_gc_ena = param->gc_enable; 12874 cmd->spectral_scan_restart_ena = param->restart_enable; 12875 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12876 cmd->spectral_scan_init_delay = param->init_delay; 12877 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12878 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12879 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12880 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12881 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12882 cmd->spectral_scan_pwr_format = param->pwr_format; 12883 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12884 cmd->spectral_scan_bin_scale = param->bin_scale; 12885 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12886 cmd->spectral_scan_chn_mask = param->chn_mask; 12887 12888 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12889 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12890 12891 if (ret != 0) { 12892 WMI_LOGE("Sending set quiet cmd failed\n"); 12893 wmi_buf_free(buf); 12894 } 12895 12896 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12897 __func__); 12898 12899 WMI_LOGI("vdev_id = %u\n" 12900 "spectral_scan_count = %u\n" 12901 "spectral_scan_period = %u\n" 12902 "spectral_scan_priority = %u\n" 12903 "spectral_scan_fft_size = %u\n" 12904 "spectral_scan_gc_ena = %u\n" 12905 "spectral_scan_restart_ena = %u\n" 12906 "spectral_scan_noise_floor_ref = %u\n" 12907 "spectral_scan_init_delay = %u\n" 12908 "spectral_scan_nb_tone_thr = %u\n" 12909 "spectral_scan_str_bin_thr = %u\n" 12910 "spectral_scan_wb_rpt_mode = %u\n" 12911 "spectral_scan_rssi_rpt_mode = %u\n" 12912 "spectral_scan_rssi_thr = %u\n" 12913 "spectral_scan_pwr_format = %u\n" 12914 "spectral_scan_rpt_mode = %u\n" 12915 "spectral_scan_bin_scale = %u\n" 12916 "spectral_scan_dBm_adj = %u\n" 12917 "spectral_scan_chn_mask = %u\n", 12918 param->vdev_id, 12919 param->count, 12920 param->period, 12921 param->spectral_pri, 12922 param->fft_size, 12923 param->gc_enable, 12924 param->restart_enable, 12925 param->noise_floor_ref, 12926 param->init_delay, 12927 param->nb_tone_thr, 12928 param->str_bin_thr, 12929 param->wb_rpt_mode, 12930 param->rssi_rpt_mode, 12931 param->rssi_thr, 12932 param->pwr_format, 12933 param->rpt_mode, 12934 param->bin_scale, 12935 param->dbm_adj, 12936 param->chn_mask); 12937 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12938 12939 return ret; 12940 } 12941 12942 /** 12943 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12944 * command to fw 12945 * @wmi_handle: wmi handle 12946 * @param: pointer to hold spectral enable parameter 12947 * 12948 * Return: 0 for success or error code 12949 */ 12950 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12951 struct vdev_spectral_enable_params *param) 12952 { 12953 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12954 wmi_buf_t buf; 12955 QDF_STATUS ret; 12956 int32_t len; 12957 12958 len = sizeof(*cmd); 12959 buf = wmi_buf_alloc(wmi_handle, len); 12960 if (!buf) { 12961 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12962 return QDF_STATUS_E_FAILURE; 12963 } 12964 12965 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12966 WMITLV_SET_HDR(&cmd->tlv_header, 12967 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12968 WMITLV_GET_STRUCT_TLVLEN( 12969 wmi_vdev_spectral_enable_cmd_fixed_param)); 12970 12971 cmd->vdev_id = param->vdev_id; 12972 12973 if (param->active_valid) { 12974 cmd->trigger_cmd = param->active ? 1 : 2; 12975 /* 1: Trigger, 2: Clear Trigger */ 12976 } else { 12977 cmd->trigger_cmd = 0; /* 0: Ignore */ 12978 } 12979 12980 if (param->enabled_valid) { 12981 cmd->enable_cmd = param->enabled ? 1 : 2; 12982 /* 1: Enable 2: Disable */ 12983 } else { 12984 cmd->enable_cmd = 0; /* 0: Ignore */ 12985 } 12986 12987 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12988 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12989 12990 if (ret != 0) { 12991 WMI_LOGE("Sending scan enable CMD failed\n"); 12992 wmi_buf_free(buf); 12993 } 12994 12995 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12996 12997 WMI_LOGI("vdev_id = %u\n" 12998 "trigger_cmd = %u\n" 12999 "enable_cmd = %u\n", 13000 cmd->vdev_id, 13001 cmd->trigger_cmd, 13002 cmd->enable_cmd); 13003 13004 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 13005 13006 return ret; 13007 } 13008 13009 /** 13010 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 13011 * @param wmi_handle : handle to WMI. 13012 * @param param : pointer to hold thermal mitigation param 13013 * 13014 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 13015 */ 13016 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 13017 wmi_unified_t wmi_handle, 13018 struct thermal_mitigation_params *param) 13019 { 13020 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 13021 wmi_therm_throt_level_config_info *lvl_conf = NULL; 13022 wmi_buf_t buf = NULL; 13023 uint8_t *buf_ptr = NULL; 13024 int error; 13025 int32_t len; 13026 int i; 13027 13028 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 13029 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 13030 13031 buf = wmi_buf_alloc(wmi_handle, len); 13032 if (!buf) { 13033 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13034 return QDF_STATUS_E_NOMEM; 13035 } 13036 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 13037 13038 /* init fixed params */ 13039 WMITLV_SET_HDR(tt_conf, 13040 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 13041 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 13042 13043 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13044 param->pdev_id); 13045 tt_conf->enable = param->enable; 13046 tt_conf->dc = param->dc; 13047 tt_conf->dc_per_event = param->dc_per_event; 13048 tt_conf->therm_throt_levels = THERMAL_LEVELS; 13049 13050 buf_ptr = (uint8_t *) ++tt_conf; 13051 /* init TLV params */ 13052 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13053 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 13054 13055 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 13056 for (i = 0; i < THERMAL_LEVELS; i++) { 13057 WMITLV_SET_HDR(&lvl_conf->tlv_header, 13058 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 13059 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 13060 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 13061 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 13062 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 13063 lvl_conf->prio = param->levelconf[i].priority; 13064 lvl_conf++; 13065 } 13066 13067 error = wmi_unified_cmd_send(wmi_handle, buf, len, 13068 WMI_THERM_THROT_SET_CONF_CMDID); 13069 if (QDF_IS_STATUS_ERROR(error)) { 13070 wmi_buf_free(buf); 13071 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 13072 } 13073 13074 return error; 13075 } 13076 13077 /** 13078 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 13079 * @wmi_handle: wmi handle 13080 * @param: pointer to pdev_qvit_params 13081 * 13082 * Return: 0 for success or error code 13083 */ 13084 static QDF_STATUS 13085 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 13086 struct pdev_qvit_params *param) 13087 { 13088 wmi_buf_t buf; 13089 QDF_STATUS ret = QDF_STATUS_E_INVAL; 13090 uint8_t *cmd; 13091 static uint8_t msgref = 1; 13092 uint8_t segnumber = 0, seginfo, numsegments; 13093 uint16_t chunk_len, total_bytes; 13094 uint8_t *bufpos; 13095 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 13096 13097 bufpos = param->utf_payload; 13098 total_bytes = param->len; 13099 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 13100 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 13101 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 13102 13103 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 13104 numsegments++; 13105 13106 while (param->len) { 13107 if (param->len > MAX_WMI_QVIT_LEN) 13108 chunk_len = MAX_WMI_QVIT_LEN; /* MAX messsage */ 13109 else 13110 chunk_len = param->len; 13111 13112 buf = wmi_buf_alloc(wmi_handle, 13113 (chunk_len + sizeof(seghdrinfo) + 13114 WMI_TLV_HDR_SIZE)); 13115 if (!buf) { 13116 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13117 return QDF_STATUS_E_NOMEM; 13118 } 13119 13120 cmd = (uint8_t *) wmi_buf_data(buf); 13121 13122 seghdrinfo.len = total_bytes; 13123 seghdrinfo.msgref = msgref; 13124 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 13125 seghdrinfo.segmentInfo = seginfo; 13126 13127 segnumber++; 13128 13129 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 13130 (chunk_len + sizeof(seghdrinfo))); 13131 cmd += WMI_TLV_HDR_SIZE; 13132 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 13133 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 13134 13135 ret = wmi_unified_cmd_send(wmi_handle, buf, 13136 (chunk_len + sizeof(seghdrinfo) + 13137 WMI_TLV_HDR_SIZE), 13138 WMI_PDEV_QVIT_CMDID); 13139 13140 if (ret != 0) { 13141 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 13142 wmi_buf_free(buf); 13143 break; 13144 } 13145 13146 param->len -= chunk_len; 13147 bufpos += chunk_len; 13148 } 13149 msgref++; 13150 13151 return ret; 13152 } 13153 13154 /** 13155 * send_wmm_update_cmd_tlv() - send wmm update command to fw 13156 * @wmi_handle: wmi handle 13157 * @param: pointer to wmm update param 13158 * 13159 * Return: 0 for success or error code 13160 */ 13161 static QDF_STATUS 13162 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 13163 struct wmm_update_params *param) 13164 { 13165 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 13166 wmi_wmm_params *wmm_param; 13167 wmi_buf_t buf; 13168 QDF_STATUS ret; 13169 int32_t len; 13170 int ac = 0; 13171 struct wmi_host_wmeParams *wmep; 13172 uint8_t *buf_ptr; 13173 13174 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 13175 buf = wmi_buf_alloc(wmi_handle, len); 13176 if (!buf) { 13177 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13178 return QDF_STATUS_E_FAILURE; 13179 } 13180 13181 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13182 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 13183 WMITLV_SET_HDR(&cmd->tlv_header, 13184 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 13185 WMITLV_GET_STRUCT_TLVLEN 13186 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 13187 13188 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 13189 13190 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 13191 13192 for (ac = 0; ac < WME_NUM_AC; ac++) { 13193 wmep = ¶m->wmep_array[ac]; 13194 wmm_param = (wmi_wmm_params *)buf_ptr; 13195 WMITLV_SET_HDR(&wmm_param->tlv_header, 13196 WMITLV_TAG_STRUC_wmi_wmm_params, 13197 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 13198 wmm_param->aifs = wmep->wmep_aifsn; 13199 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 13200 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 13201 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 13202 wmm_param->acm = wmep->wmep_acm; 13203 wmm_param->no_ack = wmep->wmep_noackPolicy; 13204 buf_ptr += sizeof(wmi_wmm_params); 13205 } 13206 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13207 WMI_PDEV_SET_WMM_PARAMS_CMDID); 13208 13209 if (ret != 0) { 13210 WMI_LOGE("Sending WMM update CMD failed\n"); 13211 wmi_buf_free(buf); 13212 } 13213 13214 return ret; 13215 } 13216 13217 /** 13218 * send_coex_config_cmd_tlv() - send coex config command to fw 13219 * @wmi_handle: wmi handle 13220 * @param: pointer to coex config param 13221 * 13222 * Return: 0 for success or error code 13223 */ 13224 static QDF_STATUS 13225 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 13226 struct coex_config_params *param) 13227 { 13228 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 13229 wmi_buf_t buf; 13230 QDF_STATUS ret; 13231 int32_t len; 13232 13233 len = sizeof(*cmd); 13234 buf = wmi_buf_alloc(wmi_handle, len); 13235 if (!buf) { 13236 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13237 return QDF_STATUS_E_FAILURE; 13238 } 13239 13240 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 13241 WMITLV_SET_HDR(&cmd->tlv_header, 13242 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 13243 WMITLV_GET_STRUCT_TLVLEN( 13244 WMI_COEX_CONFIG_CMD_fixed_param)); 13245 13246 cmd->vdev_id = param->vdev_id; 13247 cmd->config_type = param->config_type; 13248 cmd->config_arg1 = param->config_arg1; 13249 cmd->config_arg2 = param->config_arg2; 13250 cmd->config_arg3 = param->config_arg3; 13251 cmd->config_arg4 = param->config_arg4; 13252 cmd->config_arg5 = param->config_arg5; 13253 cmd->config_arg6 = param->config_arg6; 13254 13255 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13256 WMI_COEX_CONFIG_CMDID); 13257 13258 if (ret != 0) { 13259 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 13260 wmi_buf_free(buf); 13261 } 13262 13263 return ret; 13264 } 13265 13266 static 13267 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 13268 target_resource_config *tgt_res_cfg) 13269 { 13270 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 13271 resource_cfg->num_peers = tgt_res_cfg->num_peers; 13272 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 13273 resource_cfg->num_offload_reorder_buffs = 13274 tgt_res_cfg->num_offload_reorder_buffs; 13275 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 13276 resource_cfg->num_tids = tgt_res_cfg->num_tids; 13277 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 13278 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 13279 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 13280 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 13281 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 13282 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 13283 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 13284 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 13285 resource_cfg->scan_max_pending_req = 13286 tgt_res_cfg->scan_max_pending_req; 13287 resource_cfg->bmiss_offload_max_vdev = 13288 tgt_res_cfg->bmiss_offload_max_vdev; 13289 resource_cfg->roam_offload_max_vdev = 13290 tgt_res_cfg->roam_offload_max_vdev; 13291 resource_cfg->roam_offload_max_ap_profiles = 13292 tgt_res_cfg->roam_offload_max_ap_profiles; 13293 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 13294 resource_cfg->num_mcast_table_elems = 13295 tgt_res_cfg->num_mcast_table_elems; 13296 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 13297 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 13298 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 13299 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 13300 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 13301 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 13302 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 13303 resource_cfg->vow_config = tgt_res_cfg->vow_config; 13304 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 13305 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 13306 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 13307 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 13308 resource_cfg->num_tdls_conn_table_entries = 13309 tgt_res_cfg->num_tdls_conn_table_entries; 13310 resource_cfg->beacon_tx_offload_max_vdev = 13311 tgt_res_cfg->beacon_tx_offload_max_vdev; 13312 resource_cfg->num_multicast_filter_entries = 13313 tgt_res_cfg->num_multicast_filter_entries; 13314 resource_cfg->num_wow_filters = 13315 tgt_res_cfg->num_wow_filters; 13316 resource_cfg->num_keep_alive_pattern = 13317 tgt_res_cfg->num_keep_alive_pattern; 13318 resource_cfg->keep_alive_pattern_size = 13319 tgt_res_cfg->keep_alive_pattern_size; 13320 resource_cfg->max_tdls_concurrent_sleep_sta = 13321 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 13322 resource_cfg->max_tdls_concurrent_buffer_sta = 13323 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 13324 resource_cfg->wmi_send_separate = 13325 tgt_res_cfg->wmi_send_separate; 13326 resource_cfg->num_ocb_vdevs = 13327 tgt_res_cfg->num_ocb_vdevs; 13328 resource_cfg->num_ocb_channels = 13329 tgt_res_cfg->num_ocb_channels; 13330 resource_cfg->num_ocb_schedules = 13331 tgt_res_cfg->num_ocb_schedules; 13332 resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size; 13333 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 13334 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 13335 resource_cfg->max_num_dbs_scan_duty_cycle = 13336 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 13337 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 13338 13339 if (tgt_res_cfg->atf_config) 13340 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 13341 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 13342 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 13343 resource_cfg->flag1, 1); 13344 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 13345 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 13346 resource_cfg->flag1, 1); 13347 if (tgt_res_cfg->cce_disable) 13348 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 13349 } 13350 13351 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 13352 * @wmi_handle: pointer to wmi handle 13353 * @buf_ptr: pointer to current position in init command buffer 13354 * @len: pointer to length. This will be updated with current lenght of cmd 13355 * @param: point host parameters for init command 13356 * 13357 * Return: Updated pointer of buf_ptr. 13358 */ 13359 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 13360 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 13361 { 13362 uint16_t idx; 13363 13364 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 13365 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 13366 wmi_pdev_band_to_mac *band_to_mac; 13367 13368 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 13369 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 13370 sizeof(wmi_resource_config) + 13371 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 13372 sizeof(wlan_host_memory_chunk))); 13373 13374 WMITLV_SET_HDR(&hw_mode->tlv_header, 13375 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13376 (WMITLV_GET_STRUCT_TLVLEN 13377 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 13378 13379 hw_mode->hw_mode_index = param->hw_mode_id; 13380 hw_mode->num_band_to_mac = param->num_band_to_mac; 13381 13382 buf_ptr = (uint8_t *) (hw_mode + 1); 13383 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 13384 WMI_TLV_HDR_SIZE); 13385 for (idx = 0; idx < param->num_band_to_mac; idx++) { 13386 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 13387 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 13388 WMITLV_GET_STRUCT_TLVLEN 13389 (wmi_pdev_band_to_mac)); 13390 band_to_mac[idx].pdev_id = 13391 wmi_handle->ops->convert_pdev_id_host_to_target( 13392 param->band_to_mac[idx].pdev_id); 13393 band_to_mac[idx].start_freq = 13394 param->band_to_mac[idx].start_freq; 13395 band_to_mac[idx].end_freq = 13396 param->band_to_mac[idx].end_freq; 13397 } 13398 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 13399 (param->num_band_to_mac * 13400 sizeof(wmi_pdev_band_to_mac)) + 13401 WMI_TLV_HDR_SIZE; 13402 13403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13404 (param->num_band_to_mac * 13405 sizeof(wmi_pdev_band_to_mac))); 13406 } 13407 13408 return buf_ptr; 13409 } 13410 13411 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 13412 wmi_init_cmd_fixed_param *cmd) 13413 { 13414 int num_whitelist; 13415 wmi_abi_version my_vers; 13416 13417 num_whitelist = sizeof(version_whitelist) / 13418 sizeof(wmi_whitelist_version_info); 13419 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 13420 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 13421 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 13422 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 13423 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 13424 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 13425 13426 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 13427 &my_vers, 13428 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 13429 &cmd->host_abi_vers); 13430 13431 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 13432 __func__, 13433 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 13434 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 13435 cmd->host_abi_vers.abi_version_ns_0, 13436 cmd->host_abi_vers.abi_version_ns_1, 13437 cmd->host_abi_vers.abi_version_ns_2, 13438 cmd->host_abi_vers.abi_version_ns_3); 13439 13440 /* Save version sent from host - 13441 * Will be used to check ready event 13442 */ 13443 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 13444 sizeof(wmi_abi_version)); 13445 } 13446 13447 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13448 { 13449 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13450 wmi_service_ready_event_fixed_param *ev; 13451 13452 13453 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13454 13455 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13456 if (!ev) 13457 return QDF_STATUS_E_FAILURE; 13458 13459 /*Save fw version from service ready message */ 13460 /*This will be used while sending INIT message */ 13461 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13462 sizeof(wmi_handle->fw_abi_version)); 13463 13464 return QDF_STATUS_SUCCESS; 13465 } 13466 13467 /** 13468 * wmi_unified_save_fw_version_cmd() - save fw version 13469 * @wmi_handle: pointer to wmi handle 13470 * @res_cfg: resource config 13471 * @num_mem_chunks: no of mem chunck 13472 * @mem_chunk: pointer to mem chunck structure 13473 * 13474 * This function sends IE information to firmware 13475 * 13476 * Return: QDF_STATUS_SUCCESS for success otherwise failure 13477 * 13478 */ 13479 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 13480 void *evt_buf) 13481 { 13482 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13483 wmi_ready_event_fixed_param *ev = NULL; 13484 13485 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13486 ev = param_buf->fixed_param; 13487 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 13488 &wmi_handle->final_abi_vers, 13489 &ev->fw_abi_vers)) { 13490 /* 13491 * Error: Our host version and the given firmware version 13492 * are incompatible. 13493 **/ 13494 WMI_LOGD("%s: Error: Incompatible WMI version." 13495 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 13496 __func__, 13497 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 13498 abi_version_0), 13499 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 13500 abi_version_0), 13501 wmi_handle->final_abi_vers.abi_version_ns_0, 13502 wmi_handle->final_abi_vers.abi_version_ns_1, 13503 wmi_handle->final_abi_vers.abi_version_ns_2, 13504 wmi_handle->final_abi_vers.abi_version_ns_3, 13505 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 13506 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 13507 ev->fw_abi_vers.abi_version_ns_0, 13508 ev->fw_abi_vers.abi_version_ns_1, 13509 ev->fw_abi_vers.abi_version_ns_2, 13510 ev->fw_abi_vers.abi_version_ns_3); 13511 13512 return QDF_STATUS_E_FAILURE; 13513 } 13514 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 13515 sizeof(wmi_abi_version)); 13516 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13517 sizeof(wmi_abi_version)); 13518 13519 return QDF_STATUS_SUCCESS; 13520 } 13521 13522 /** 13523 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 13524 * @wmi_handle: wmi handle 13525 * @custom_addr: base mac address 13526 * 13527 * Return: QDF_STATUS_SUCCESS for success or error code 13528 */ 13529 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 13530 uint8_t *custom_addr) 13531 { 13532 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 13533 wmi_buf_t buf; 13534 int err; 13535 13536 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13537 if (!buf) { 13538 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 13539 return QDF_STATUS_E_NOMEM; 13540 } 13541 13542 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 13543 qdf_mem_zero(cmd, sizeof(*cmd)); 13544 13545 WMITLV_SET_HDR(&cmd->tlv_header, 13546 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 13547 WMITLV_GET_STRUCT_TLVLEN 13548 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 13549 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 13550 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13551 WMI_HOST_PDEV_ID_SOC); 13552 err = wmi_unified_cmd_send(wmi_handle, buf, 13553 sizeof(*cmd), 13554 WMI_PDEV_SET_BASE_MACADDR_CMDID); 13555 if (err) { 13556 WMI_LOGE("Failed to send set_base_macaddr cmd"); 13557 wmi_buf_free(buf); 13558 return QDF_STATUS_E_FAILURE; 13559 } 13560 13561 return 0; 13562 } 13563 13564 /** 13565 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 13566 * @handle: wmi handle 13567 * @event: Event received from FW 13568 * @len: Length of the event 13569 * 13570 * Enables the low frequency events and disables the high frequency 13571 * events. Bit 17 indicates if the event if low/high frequency. 13572 * 1 - high frequency, 0 - low frequency 13573 * 13574 * Return: 0 on successfully enabling/disabling the events 13575 */ 13576 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 13577 uint8_t *event, 13578 uint32_t len) 13579 { 13580 uint32_t num_of_diag_events_logs; 13581 wmi_diag_event_log_config_fixed_param *cmd; 13582 wmi_buf_t buf; 13583 uint8_t *buf_ptr; 13584 uint32_t *cmd_args, *evt_args; 13585 uint32_t buf_len, i; 13586 13587 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 13588 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 13589 13590 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 13591 13592 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 13593 if (!param_buf) { 13594 WMI_LOGE("Invalid log supported event buffer"); 13595 return QDF_STATUS_E_INVAL; 13596 } 13597 wmi_event = param_buf->fixed_param; 13598 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 13599 13600 if (num_of_diag_events_logs > 13601 param_buf->num_diag_events_logs_list) { 13602 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 13603 num_of_diag_events_logs, 13604 param_buf->num_diag_events_logs_list); 13605 return QDF_STATUS_E_INVAL; 13606 } 13607 13608 evt_args = param_buf->diag_events_logs_list; 13609 if (!evt_args) { 13610 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 13611 __func__, num_of_diag_events_logs); 13612 return QDF_STATUS_E_INVAL; 13613 } 13614 13615 WMI_LOGD("%s: num_of_diag_events_logs=%d", 13616 __func__, num_of_diag_events_logs); 13617 13618 /* Free any previous allocation */ 13619 if (wmi_handle->events_logs_list) 13620 qdf_mem_free(wmi_handle->events_logs_list); 13621 13622 if (num_of_diag_events_logs > 13623 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 13624 WMI_LOGE("%s: excess num of logs:%d", __func__, 13625 num_of_diag_events_logs); 13626 QDF_ASSERT(0); 13627 return QDF_STATUS_E_INVAL; 13628 } 13629 /* Store the event list for run time enable/disable */ 13630 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 13631 sizeof(uint32_t)); 13632 if (!wmi_handle->events_logs_list) { 13633 WMI_LOGE("%s: event log list memory allocation failed", 13634 __func__); 13635 return QDF_STATUS_E_NOMEM; 13636 } 13637 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 13638 13639 /* Prepare the send buffer */ 13640 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13641 (num_of_diag_events_logs * sizeof(uint32_t)); 13642 13643 buf = wmi_buf_alloc(wmi_handle, buf_len); 13644 if (!buf) { 13645 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13646 qdf_mem_free(wmi_handle->events_logs_list); 13647 wmi_handle->events_logs_list = NULL; 13648 return QDF_STATUS_E_NOMEM; 13649 } 13650 13651 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13652 buf_ptr = (uint8_t *) cmd; 13653 13654 WMITLV_SET_HDR(&cmd->tlv_header, 13655 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13656 WMITLV_GET_STRUCT_TLVLEN( 13657 wmi_diag_event_log_config_fixed_param)); 13658 13659 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13660 13661 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13662 13663 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13664 (num_of_diag_events_logs * sizeof(uint32_t))); 13665 13666 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13667 13668 /* Populate the events */ 13669 for (i = 0; i < num_of_diag_events_logs; i++) { 13670 /* Low freq (0) - Enable (1) the event 13671 * High freq (1) - Disable (0) the event 13672 */ 13673 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13674 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13675 /* Set the event ID */ 13676 WMI_DIAG_ID_SET(cmd_args[i], 13677 WMI_DIAG_ID_GET(evt_args[i])); 13678 /* Set the type */ 13679 WMI_DIAG_TYPE_SET(cmd_args[i], 13680 WMI_DIAG_TYPE_GET(evt_args[i])); 13681 /* Storing the event/log list in WMI */ 13682 wmi_handle->events_logs_list[i] = evt_args[i]; 13683 } 13684 13685 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13686 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13687 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13688 __func__); 13689 wmi_buf_free(buf); 13690 /* Not clearing events_logs_list, though wmi cmd failed. 13691 * Host can still have this list 13692 */ 13693 return QDF_STATUS_E_INVAL; 13694 } 13695 13696 return 0; 13697 } 13698 13699 /** 13700 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13701 * @wmi_handle: wmi handle 13702 * @start_log: Start logging related parameters 13703 * 13704 * Send the command to the FW based on which specific logging of diag 13705 * event/log id can be started/stopped 13706 * 13707 * Return: None 13708 */ 13709 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13710 struct wmi_wifi_start_log *start_log) 13711 { 13712 wmi_diag_event_log_config_fixed_param *cmd; 13713 wmi_buf_t buf; 13714 uint8_t *buf_ptr; 13715 uint32_t len, count, log_level, i; 13716 uint32_t *cmd_args; 13717 uint32_t total_len; 13718 count = 0; 13719 13720 if (!wmi_handle->events_logs_list) { 13721 WMI_LOGE("%s: Not received event/log list from FW, yet", 13722 __func__); 13723 return QDF_STATUS_E_NOMEM; 13724 } 13725 /* total_len stores the number of events where BITS 17 and 18 are set. 13726 * i.e., events of high frequency (17) and for extended debugging (18) 13727 */ 13728 total_len = 0; 13729 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13730 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13731 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13732 total_len++; 13733 } 13734 13735 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13736 (total_len * sizeof(uint32_t)); 13737 13738 buf = wmi_buf_alloc(wmi_handle, len); 13739 if (!buf) { 13740 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13741 return QDF_STATUS_E_NOMEM; 13742 } 13743 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13744 buf_ptr = (uint8_t *) cmd; 13745 13746 WMITLV_SET_HDR(&cmd->tlv_header, 13747 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13748 WMITLV_GET_STRUCT_TLVLEN( 13749 wmi_diag_event_log_config_fixed_param)); 13750 13751 cmd->num_of_diag_events_logs = total_len; 13752 13753 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13754 13755 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13756 (total_len * sizeof(uint32_t))); 13757 13758 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13759 13760 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13761 log_level = 1; 13762 else 13763 log_level = 0; 13764 13765 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13766 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13767 uint32_t val = wmi_handle->events_logs_list[i]; 13768 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13769 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13770 13771 WMI_DIAG_ID_SET(cmd_args[count], 13772 WMI_DIAG_ID_GET(val)); 13773 WMI_DIAG_TYPE_SET(cmd_args[count], 13774 WMI_DIAG_TYPE_GET(val)); 13775 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13776 log_level); 13777 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13778 count++; 13779 } 13780 } 13781 13782 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13783 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13784 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13785 __func__); 13786 wmi_buf_free(buf); 13787 return QDF_STATUS_E_INVAL; 13788 } 13789 13790 return QDF_STATUS_SUCCESS; 13791 } 13792 13793 /** 13794 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13795 * @wmi_handle: WMI handle 13796 * 13797 * This function is used to send the flush command to the FW, 13798 * that will flush the fw logs that are residue in the FW 13799 * 13800 * Return: None 13801 */ 13802 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13803 { 13804 wmi_debug_mesg_flush_fixed_param *cmd; 13805 wmi_buf_t buf; 13806 int len = sizeof(*cmd); 13807 QDF_STATUS ret; 13808 13809 buf = wmi_buf_alloc(wmi_handle, len); 13810 if (!buf) { 13811 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13812 return QDF_STATUS_E_NOMEM; 13813 } 13814 13815 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13816 WMITLV_SET_HDR(&cmd->tlv_header, 13817 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13818 WMITLV_GET_STRUCT_TLVLEN( 13819 wmi_debug_mesg_flush_fixed_param)); 13820 cmd->reserved0 = 0; 13821 13822 ret = wmi_unified_cmd_send(wmi_handle, 13823 buf, 13824 len, 13825 WMI_DEBUG_MESG_FLUSH_CMDID); 13826 if (QDF_IS_STATUS_ERROR(ret)) { 13827 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13828 wmi_buf_free(buf); 13829 return QDF_STATUS_E_INVAL; 13830 } 13831 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13832 13833 return ret; 13834 } 13835 13836 /** 13837 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13838 * @wmi_handle: wmi handle 13839 * @msg: PCL structure containing the PCL and the number of channels 13840 * 13841 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13842 * firmware. The DBS Manager is the consumer of this information in the WLAN 13843 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13844 * to migrate to a new channel without host driver involvement. An example of 13845 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13846 * manage the channel selection without firmware involvement. 13847 * 13848 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13849 * channel list. The weights corresponds to the channels sent in 13850 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13851 * weightage compared to the non PCL channels. 13852 * 13853 * Return: Success if the cmd is sent successfully to the firmware 13854 */ 13855 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13856 struct wmi_pcl_chan_weights *msg) 13857 { 13858 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13859 wmi_buf_t buf; 13860 uint8_t *buf_ptr; 13861 uint32_t *cmd_args, i, len; 13862 uint32_t chan_len; 13863 13864 chan_len = msg->saved_num_chan; 13865 13866 len = sizeof(*cmd) + 13867 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13868 13869 buf = wmi_buf_alloc(wmi_handle, len); 13870 if (!buf) { 13871 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13872 return QDF_STATUS_E_NOMEM; 13873 } 13874 13875 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13876 buf_ptr = (uint8_t *) cmd; 13877 WMITLV_SET_HDR(&cmd->tlv_header, 13878 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13879 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13880 13881 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13882 WMI_HOST_PDEV_ID_SOC); 13883 cmd->num_chan = chan_len; 13884 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13885 13886 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13887 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13888 (chan_len * sizeof(uint32_t))); 13889 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13890 for (i = 0; i < chan_len ; i++) { 13891 cmd_args[i] = msg->weighed_valid_list[i]; 13892 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13893 msg->saved_chan_list[i], cmd_args[i]); 13894 } 13895 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13896 WMI_PDEV_SET_PCL_CMDID)) { 13897 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13898 wmi_buf_free(buf); 13899 return QDF_STATUS_E_FAILURE; 13900 } 13901 return QDF_STATUS_SUCCESS; 13902 } 13903 13904 /** 13905 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13906 * @wmi_handle: wmi handle 13907 * @msg: Structure containing the following parameters 13908 * 13909 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13910 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13911 * 13912 * Provides notification to the WLAN firmware that host driver is requesting a 13913 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13914 * configurations that include the Dual Band Simultaneous (DBS) feature. 13915 * 13916 * Return: Success if the cmd is sent successfully to the firmware 13917 */ 13918 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13919 uint32_t hw_mode_index) 13920 { 13921 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13922 wmi_buf_t buf; 13923 uint32_t len; 13924 13925 len = sizeof(*cmd); 13926 13927 buf = wmi_buf_alloc(wmi_handle, len); 13928 if (!buf) { 13929 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13930 return QDF_STATUS_E_NOMEM; 13931 } 13932 13933 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13934 WMITLV_SET_HDR(&cmd->tlv_header, 13935 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13936 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13937 13938 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13939 WMI_HOST_PDEV_ID_SOC); 13940 cmd->hw_mode_index = hw_mode_index; 13941 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13942 13943 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13944 WMI_PDEV_SET_HW_MODE_CMDID)) { 13945 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13946 __func__); 13947 wmi_buf_free(buf); 13948 return QDF_STATUS_E_FAILURE; 13949 } 13950 13951 return QDF_STATUS_SUCCESS; 13952 } 13953 13954 /** 13955 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13956 * @wmi_handle: wmi handle 13957 * @msg: Dual MAC config parameters 13958 * 13959 * Configures WLAN firmware with the dual MAC features 13960 * 13961 * Return: QDF_STATUS. 0 on success. 13962 */ 13963 static 13964 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13965 struct wmi_dual_mac_config *msg) 13966 { 13967 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13968 wmi_buf_t buf; 13969 uint32_t len; 13970 13971 len = sizeof(*cmd); 13972 13973 buf = wmi_buf_alloc(wmi_handle, len); 13974 if (!buf) { 13975 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13976 return QDF_STATUS_E_FAILURE; 13977 } 13978 13979 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13980 WMITLV_SET_HDR(&cmd->tlv_header, 13981 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13982 WMITLV_GET_STRUCT_TLVLEN( 13983 wmi_pdev_set_mac_config_cmd_fixed_param)); 13984 13985 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13986 WMI_HOST_PDEV_ID_SOC); 13987 cmd->concurrent_scan_config_bits = msg->scan_config; 13988 cmd->fw_mode_config_bits = msg->fw_mode_config; 13989 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 13990 __func__, msg->scan_config, msg->fw_mode_config); 13991 13992 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13993 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13994 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13995 __func__); 13996 wmi_buf_free(buf); 13997 } 13998 return QDF_STATUS_SUCCESS; 13999 } 14000 14001 #ifdef BIG_ENDIAN_HOST 14002 /** 14003 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14004 * @param data_len - data length 14005 * @param data - pointer to data 14006 * 14007 * Return: QDF_STATUS - success or error status 14008 */ 14009 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14010 struct fips_params *param) 14011 { 14012 unsigned char *key_unaligned, *data_unaligned; 14013 int c; 14014 u_int8_t *key_aligned = NULL; 14015 u_int8_t *data_aligned = NULL; 14016 14017 /* Assigning unaligned space to copy the key */ 14018 key_unaligned = qdf_mem_malloc( 14019 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 14020 data_unaligned = qdf_mem_malloc( 14021 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 14022 14023 /* Checking if kmalloc is succesful to allocate space */ 14024 if (key_unaligned == NULL) 14025 return QDF_STATUS_SUCCESS; 14026 /* Checking if space is aligned */ 14027 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 14028 /* align to 4 */ 14029 key_aligned = 14030 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 14031 FIPS_ALIGN); 14032 } else { 14033 key_aligned = (u_int8_t *)key_unaligned; 14034 } 14035 14036 /* memset and copy content from key to key aligned */ 14037 OS_MEMSET(key_aligned, 0, param->key_len); 14038 OS_MEMCPY(key_aligned, param->key, param->key_len); 14039 14040 /* print a hexdump for host debug */ 14041 print_hex_dump(KERN_DEBUG, 14042 "\t Aligned and Copied Key:@@@@ ", 14043 DUMP_PREFIX_NONE, 14044 16, 1, key_aligned, param->key_len, true); 14045 14046 /* Checking if kmalloc is succesful to allocate space */ 14047 if (data_unaligned == NULL) 14048 return QDF_STATUS_SUCCESS; 14049 /* Checking of space is aligned */ 14050 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14051 /* align to 4 */ 14052 data_aligned = 14053 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 14054 FIPS_ALIGN); 14055 } else { 14056 data_aligned = (u_int8_t *)data_unaligned; 14057 } 14058 14059 /* memset and copy content from data to data aligned */ 14060 OS_MEMSET(data_aligned, 0, param->data_len); 14061 OS_MEMCPY(data_aligned, param->data, param->data_len); 14062 14063 /* print a hexdump for host debug */ 14064 print_hex_dump(KERN_DEBUG, 14065 "\t Properly Aligned and Copied Data:@@@@ ", 14066 DUMP_PREFIX_NONE, 14067 16, 1, data_aligned, param->data_len, true); 14068 14069 /* converting to little Endian both key_aligned and 14070 * data_aligned*/ 14071 for (c = 0; c < param->key_len/4; c++) { 14072 *((u_int32_t *)key_aligned+c) = 14073 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 14074 } 14075 for (c = 0; c < param->data_len/4; c++) { 14076 *((u_int32_t *)data_aligned+c) = 14077 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 14078 } 14079 14080 /* update endian data to key and data vectors */ 14081 OS_MEMCPY(param->key, key_aligned, param->key_len); 14082 OS_MEMCPY(param->data, data_aligned, param->data_len); 14083 14084 /* clean up allocated spaces */ 14085 qdf_mem_free(key_unaligned); 14086 key_unaligned = NULL; 14087 key_aligned = NULL; 14088 14089 qdf_mem_free(data_unaligned); 14090 data_unaligned = NULL; 14091 data_aligned = NULL; 14092 14093 return QDF_STATUS_SUCCESS; 14094 } 14095 #else 14096 /** 14097 * fips_align_data_be() - DUMMY for LE platform 14098 * 14099 * Return: QDF_STATUS - success 14100 */ 14101 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14102 struct fips_params *param) 14103 { 14104 return QDF_STATUS_SUCCESS; 14105 } 14106 #endif 14107 14108 14109 /** 14110 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 14111 * @wmi_handle: wmi handle 14112 * @param: pointer to hold pdev fips param 14113 * 14114 * Return: 0 for success or error code 14115 */ 14116 static QDF_STATUS 14117 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 14118 struct fips_params *param) 14119 { 14120 wmi_pdev_fips_cmd_fixed_param *cmd; 14121 wmi_buf_t buf; 14122 uint8_t *buf_ptr; 14123 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 14124 QDF_STATUS retval = QDF_STATUS_SUCCESS; 14125 14126 /* Length TLV placeholder for array of bytes */ 14127 len += WMI_TLV_HDR_SIZE; 14128 if (param->data_len) 14129 len += (param->data_len*sizeof(uint8_t)); 14130 14131 /* 14132 * Data length must be multiples of 16 bytes - checked against 0xF - 14133 * and must be less than WMI_SVC_MSG_SIZE - static size of 14134 * wmi_pdev_fips_cmd structure 14135 */ 14136 14137 /* do sanity on the input */ 14138 if (!(((param->data_len & 0xF) == 0) && 14139 ((param->data_len > 0) && 14140 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 14141 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 14142 return QDF_STATUS_E_INVAL; 14143 } 14144 14145 buf = wmi_buf_alloc(wmi_handle, len); 14146 if (!buf) { 14147 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 14148 return QDF_STATUS_E_FAILURE; 14149 } 14150 14151 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14152 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 14153 WMITLV_SET_HDR(&cmd->tlv_header, 14154 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 14155 WMITLV_GET_STRUCT_TLVLEN 14156 (wmi_pdev_fips_cmd_fixed_param)); 14157 14158 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 14159 param->pdev_id); 14160 if (param->key != NULL && param->data != NULL) { 14161 cmd->key_len = param->key_len; 14162 cmd->data_len = param->data_len; 14163 cmd->fips_cmd = !!(param->op); 14164 14165 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 14166 return QDF_STATUS_E_FAILURE; 14167 14168 qdf_mem_copy(cmd->key, param->key, param->key_len); 14169 14170 if (param->mode == FIPS_ENGINE_AES_CTR || 14171 param->mode == FIPS_ENGINE_AES_MIC) { 14172 cmd->mode = param->mode; 14173 } else { 14174 cmd->mode = FIPS_ENGINE_AES_CTR; 14175 } 14176 qdf_print(KERN_ERR "Key len = %d, Data len = %d\n", 14177 cmd->key_len, cmd->data_len); 14178 14179 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 14180 cmd->key, cmd->key_len, true); 14181 buf_ptr += sizeof(*cmd); 14182 14183 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 14184 14185 buf_ptr += WMI_TLV_HDR_SIZE; 14186 if (param->data_len) 14187 qdf_mem_copy(buf_ptr, 14188 (uint8_t *) param->data, param->data_len); 14189 14190 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 14191 16, 1, buf_ptr, cmd->data_len, true); 14192 14193 buf_ptr += param->data_len; 14194 14195 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 14196 WMI_PDEV_FIPS_CMDID); 14197 qdf_print("%s return value %d\n", __func__, retval); 14198 } else { 14199 qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__); 14200 wmi_buf_free(buf); 14201 retval = -QDF_STATUS_E_BADMSG; 14202 } 14203 14204 return retval; 14205 } 14206 14207 #ifdef WLAN_PMO_ENABLE 14208 /** 14209 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 14210 * @wmi_handle: wmi handle 14211 * @vdev_id: vdev id 14212 * @bitmap: Event bitmap 14213 * @enable: enable/disable 14214 * 14215 * Return: CDF status 14216 */ 14217 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 14218 uint32_t vdev_id, 14219 uint32_t *bitmap, 14220 bool enable) 14221 { 14222 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 14223 uint16_t len; 14224 wmi_buf_t buf; 14225 int ret; 14226 14227 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 14228 buf = wmi_buf_alloc(wmi_handle, len); 14229 if (!buf) { 14230 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14231 return QDF_STATUS_E_NOMEM; 14232 } 14233 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 14234 WMITLV_SET_HDR(&cmd->tlv_header, 14235 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 14236 WMITLV_GET_STRUCT_TLVLEN 14237 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 14238 cmd->vdev_id = vdev_id; 14239 cmd->is_add = enable; 14240 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 14241 WMI_WOW_MAX_EVENT_BM_LEN); 14242 14243 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 14244 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 14245 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 14246 14247 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14248 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 14249 if (ret) { 14250 WMI_LOGE("Failed to config wow wakeup event"); 14251 wmi_buf_free(buf); 14252 return QDF_STATUS_E_FAILURE; 14253 } 14254 14255 return QDF_STATUS_SUCCESS; 14256 } 14257 14258 /** 14259 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 14260 * @wmi_handle: wmi handle 14261 * @vdev_id: vdev id 14262 * @ptrn_id: pattern id 14263 * @ptrn: pattern 14264 * @ptrn_len: pattern length 14265 * @ptrn_offset: pattern offset 14266 * @mask: mask 14267 * @mask_len: mask length 14268 * @user: true for user configured pattern and false for default pattern 14269 * @default_patterns: default patterns 14270 * 14271 * Return: CDF status 14272 */ 14273 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 14274 uint8_t vdev_id, uint8_t ptrn_id, 14275 const uint8_t *ptrn, uint8_t ptrn_len, 14276 uint8_t ptrn_offset, const uint8_t *mask, 14277 uint8_t mask_len, bool user, 14278 uint8_t default_patterns) 14279 { 14280 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14281 WOW_BITMAP_PATTERN_T *bitmap_pattern; 14282 wmi_buf_t buf; 14283 uint8_t *buf_ptr; 14284 int32_t len; 14285 int ret; 14286 14287 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14288 WMI_TLV_HDR_SIZE + 14289 1 * sizeof(WOW_BITMAP_PATTERN_T) + 14290 WMI_TLV_HDR_SIZE + 14291 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14292 WMI_TLV_HDR_SIZE + 14293 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14294 WMI_TLV_HDR_SIZE + 14295 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14296 WMI_TLV_HDR_SIZE + 14297 0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32); 14298 14299 buf = wmi_buf_alloc(wmi_handle, len); 14300 if (!buf) { 14301 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14302 return QDF_STATUS_E_NOMEM; 14303 } 14304 14305 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14306 buf_ptr = (uint8_t *) cmd; 14307 14308 WMITLV_SET_HDR(&cmd->tlv_header, 14309 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14310 WMITLV_GET_STRUCT_TLVLEN 14311 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14312 cmd->vdev_id = vdev_id; 14313 cmd->pattern_id = ptrn_id; 14314 14315 cmd->pattern_type = WOW_BITMAP_PATTERN; 14316 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14317 14318 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14319 sizeof(WOW_BITMAP_PATTERN_T)); 14320 buf_ptr += WMI_TLV_HDR_SIZE; 14321 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 14322 14323 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 14324 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 14325 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 14326 14327 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 14328 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 14329 14330 bitmap_pattern->pattern_offset = ptrn_offset; 14331 bitmap_pattern->pattern_len = ptrn_len; 14332 14333 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 14334 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 14335 14336 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 14337 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 14338 14339 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 14340 bitmap_pattern->pattern_id = ptrn_id; 14341 14342 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 14343 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 14344 bitmap_pattern->pattern_offset, user); 14345 WMI_LOGI("Pattern : "); 14346 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14347 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 14348 14349 WMI_LOGI("Mask : "); 14350 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14351 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 14352 14353 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 14354 14355 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14356 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14357 buf_ptr += WMI_TLV_HDR_SIZE; 14358 14359 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14360 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14361 buf_ptr += WMI_TLV_HDR_SIZE; 14362 14363 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14364 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14365 buf_ptr += WMI_TLV_HDR_SIZE; 14366 14367 /* Fill TLV for pattern_info_timeout but no data. */ 14368 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14369 buf_ptr += WMI_TLV_HDR_SIZE; 14370 14371 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 14372 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(A_UINT32)); 14373 buf_ptr += WMI_TLV_HDR_SIZE; 14374 *(A_UINT32 *) buf_ptr = 0; 14375 14376 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14377 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14378 if (ret) { 14379 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 14380 wmi_buf_free(buf); 14381 return QDF_STATUS_E_FAILURE; 14382 } 14383 14384 return QDF_STATUS_SUCCESS; 14385 } 14386 14387 /** 14388 * fill_arp_offload_params_tlv() - Fill ARP offload data 14389 * @wmi_handle: wmi handle 14390 * @offload_req: offload request 14391 * @buf_ptr: buffer pointer 14392 * 14393 * To fill ARP offload data to firmware 14394 * when target goes to wow mode. 14395 * 14396 * Return: None 14397 */ 14398 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 14399 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 14400 { 14401 14402 int i; 14403 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 14404 bool enable_or_disable = offload_req->enable; 14405 14406 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14407 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 14408 *buf_ptr += WMI_TLV_HDR_SIZE; 14409 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 14410 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 14411 WMITLV_SET_HDR(&arp_tuple->tlv_header, 14412 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 14413 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 14414 14415 /* Fill data for ARP and NS in the first tupple for LA */ 14416 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 14417 /* Copy the target ip addr and flags */ 14418 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 14419 qdf_mem_copy(&arp_tuple->target_ipaddr, 14420 offload_req->host_ipv4_addr, 14421 WMI_IPV4_ADDR_LEN); 14422 WMI_LOGD("ARPOffload IP4 address: %pI4", 14423 offload_req->host_ipv4_addr); 14424 } 14425 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 14426 } 14427 } 14428 14429 #ifdef WLAN_NS_OFFLOAD 14430 /** 14431 * fill_ns_offload_params_tlv() - Fill NS offload data 14432 * @wmi|_handle: wmi handle 14433 * @offload_req: offload request 14434 * @buf_ptr: buffer pointer 14435 * 14436 * To fill NS offload data to firmware 14437 * when target goes to wow mode. 14438 * 14439 * Return: None 14440 */ 14441 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14442 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14443 { 14444 14445 int i; 14446 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14447 14448 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14449 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14450 *buf_ptr += WMI_TLV_HDR_SIZE; 14451 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 14452 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14453 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14454 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14455 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 14456 14457 /* 14458 * Fill data only for NS offload in the first ARP tuple for LA 14459 */ 14460 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14461 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14462 /* Copy the target/solicitation/remote ip addr */ 14463 if (ns_req->target_ipv6_addr_valid[i]) 14464 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14465 &ns_req->target_ipv6_addr[i], 14466 sizeof(WMI_IPV6_ADDR)); 14467 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14468 &ns_req->self_ipv6_addr[i], 14469 sizeof(WMI_IPV6_ADDR)); 14470 if (ns_req->target_ipv6_addr_ac_type[i]) { 14471 ns_tuple->flags |= 14472 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14473 } 14474 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14475 i, &ns_req->self_ipv6_addr[i], 14476 &ns_req->target_ipv6_addr[i]); 14477 14478 /* target MAC is optional, check if it is valid, 14479 * if this is not valid, the target will use the known 14480 * local MAC address rather than the tuple 14481 */ 14482 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14483 ns_req->self_macaddr.bytes, 14484 &ns_tuple->target_mac); 14485 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14486 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14487 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14488 } 14489 } 14490 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14491 } 14492 } 14493 14494 14495 /** 14496 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 14497 * @wmi: wmi handle 14498 * @offload_req: offload request 14499 * @buf_ptr: buffer pointer 14500 * 14501 * To fill extended NS offload extended data to firmware 14502 * when target goes to wow mode. 14503 * 14504 * Return: None 14505 */ 14506 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14507 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14508 { 14509 int i; 14510 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14511 uint32_t count, num_ns_ext_tuples; 14512 14513 count = ns_req->num_ns_offload_count; 14514 num_ns_ext_tuples = ns_req->num_ns_offload_count - 14515 WMI_MAX_NS_OFFLOADS; 14516 14517 /* Populate extended NS offload tuples */ 14518 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14519 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14520 *buf_ptr += WMI_TLV_HDR_SIZE; 14521 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 14522 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14523 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14524 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14525 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 14526 14527 /* 14528 * Fill data only for NS offload in the first ARP tuple for LA 14529 */ 14530 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14531 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14532 /* Copy the target/solicitation/remote ip addr */ 14533 if (ns_req->target_ipv6_addr_valid[i]) 14534 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14535 &ns_req->target_ipv6_addr[i], 14536 sizeof(WMI_IPV6_ADDR)); 14537 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14538 &ns_req->self_ipv6_addr[i], 14539 sizeof(WMI_IPV6_ADDR)); 14540 if (ns_req->target_ipv6_addr_ac_type[i]) { 14541 ns_tuple->flags |= 14542 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14543 } 14544 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14545 i, &ns_req->self_ipv6_addr[i], 14546 &ns_req->target_ipv6_addr[i]); 14547 14548 /* target MAC is optional, check if it is valid, 14549 * if this is not valid, the target will use the 14550 * known local MAC address rather than the tuple 14551 */ 14552 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14553 ns_req->self_macaddr.bytes, 14554 &ns_tuple->target_mac); 14555 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14556 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14557 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14558 } 14559 } 14560 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14561 } 14562 } 14563 #else 14564 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14565 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14566 { 14567 } 14568 14569 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14570 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14571 { 14572 } 14573 #endif 14574 14575 /** 14576 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 14577 * @wma: wmi handle 14578 * @arp_offload_req: arp offload request 14579 * @ns_offload_req: ns offload request 14580 * @arp_only: flag 14581 * 14582 * To configure ARP NS off load data to firmware 14583 * when target goes to wow mode. 14584 * 14585 * Return: QDF Status 14586 */ 14587 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 14588 struct pmo_arp_offload_params *arp_offload_req, 14589 struct pmo_ns_offload_params *ns_offload_req, 14590 uint8_t vdev_id) 14591 { 14592 int32_t res; 14593 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 14594 A_UINT8 *buf_ptr; 14595 wmi_buf_t buf; 14596 int32_t len; 14597 uint32_t count = 0, num_ns_ext_tuples = 0; 14598 14599 count = ns_offload_req->num_ns_offload_count; 14600 14601 /* 14602 * TLV place holder size for array of NS tuples 14603 * TLV place holder size for array of ARP tuples 14604 */ 14605 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 14606 WMI_TLV_HDR_SIZE + 14607 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 14608 WMI_TLV_HDR_SIZE + 14609 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 14610 14611 /* 14612 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 14613 * extra length for extended NS offload tuples which follows ARP offload 14614 * tuples. Host needs to fill this structure in following format: 14615 * 2 NS ofload tuples 14616 * 2 ARP offload tuples 14617 * N numbers of extended NS offload tuples if HDD has given more than 14618 * 2 NS offload addresses 14619 */ 14620 if (count > WMI_MAX_NS_OFFLOADS) { 14621 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 14622 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 14623 * sizeof(WMI_NS_OFFLOAD_TUPLE); 14624 } 14625 14626 buf = wmi_buf_alloc(wmi_handle, len); 14627 if (!buf) { 14628 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14629 return QDF_STATUS_E_NOMEM; 14630 } 14631 14632 buf_ptr = (A_UINT8 *) wmi_buf_data(buf); 14633 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 14634 WMITLV_SET_HDR(&cmd->tlv_header, 14635 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 14636 WMITLV_GET_STRUCT_TLVLEN 14637 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 14638 cmd->flags = 0; 14639 cmd->vdev_id = vdev_id; 14640 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 14641 14642 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 14643 14644 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 14645 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14646 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 14647 if (num_ns_ext_tuples) 14648 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14649 14650 res = wmi_unified_cmd_send(wmi_handle, buf, len, 14651 WMI_SET_ARP_NS_OFFLOAD_CMDID); 14652 if (res) { 14653 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 14654 wmi_buf_free(buf); 14655 return QDF_STATUS_E_FAILURE; 14656 } 14657 14658 return QDF_STATUS_SUCCESS; 14659 } 14660 14661 /** 14662 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14663 * @wmi_handle: wmi handle 14664 * @vdev_id: vdev id 14665 * @action: true for enable else false 14666 * 14667 * To enable enhance multicast offload to firmware 14668 * when target goes to wow mode. 14669 * 14670 * Return: QDF Status 14671 */ 14672 14673 static 14674 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14675 wmi_unified_t wmi_handle, 14676 uint8_t vdev_id, bool action) 14677 { 14678 QDF_STATUS status; 14679 wmi_buf_t buf; 14680 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14681 14682 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14683 if (!buf) { 14684 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14685 return QDF_STATUS_E_NOMEM; 14686 } 14687 14688 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14689 wmi_buf_data(buf); 14690 14691 WMITLV_SET_HDR(&cmd->tlv_header, 14692 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14693 WMITLV_GET_STRUCT_TLVLEN( 14694 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14695 14696 cmd->vdev_id = vdev_id; 14697 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14698 ENHANCED_MCAST_FILTER_ENABLED); 14699 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14700 __func__, action, vdev_id); 14701 status = wmi_unified_cmd_send(wmi_handle, buf, 14702 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14703 if (status != QDF_STATUS_SUCCESS) { 14704 qdf_nbuf_free(buf); 14705 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14706 __func__); 14707 } 14708 14709 return status; 14710 } 14711 14712 /** 14713 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14714 * @wmi_handle: wmi handle 14715 * @param evt_buf: pointer to event buffer 14716 * @param hdr: Pointer to hold header 14717 * @param bufp: Pointer to hold pointer to rx param buffer 14718 * 14719 * Return: QDF_STATUS_SUCCESS for success or error code 14720 */ 14721 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14722 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14723 { 14724 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14725 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14726 14727 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14728 if (!param_buf) { 14729 WMI_LOGE("gtk param_buf is NULL"); 14730 return QDF_STATUS_E_INVAL; 14731 } 14732 14733 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14734 WMI_LOGE("Invalid length for GTK status"); 14735 return QDF_STATUS_E_INVAL; 14736 } 14737 14738 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14739 param_buf->fixed_param; 14740 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14741 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14742 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14743 qdf_mem_copy(>k_rsp_param->replay_counter, 14744 &fixed_param->replay_counter, 14745 GTK_REPLAY_COUNTER_BYTES); 14746 14747 return QDF_STATUS_SUCCESS; 14748 14749 } 14750 14751 #ifdef FEATURE_WLAN_RA_FILTERING 14752 /** 14753 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14754 * @wmi_handle: wmi handle 14755 * @vdev_id: vdev id 14756 * 14757 * Return: CDF status 14758 */ 14759 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14760 uint8_t vdev_id, uint8_t default_pattern, 14761 uint16_t rate_limit_interval) 14762 { 14763 14764 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14765 wmi_buf_t buf; 14766 uint8_t *buf_ptr; 14767 int32_t len; 14768 int ret; 14769 14770 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14771 WMI_TLV_HDR_SIZE + 14772 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14773 WMI_TLV_HDR_SIZE + 14774 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14775 WMI_TLV_HDR_SIZE + 14776 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14777 WMI_TLV_HDR_SIZE + 14778 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14779 WMI_TLV_HDR_SIZE + 14780 0 * sizeof(A_UINT32) + WMI_TLV_HDR_SIZE + 1 * sizeof(A_UINT32); 14781 14782 buf = wmi_buf_alloc(wmi_handle, len); 14783 if (!buf) { 14784 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14785 return QDF_STATUS_E_NOMEM; 14786 } 14787 14788 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14789 buf_ptr = (uint8_t *) cmd; 14790 14791 WMITLV_SET_HDR(&cmd->tlv_header, 14792 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14793 WMITLV_GET_STRUCT_TLVLEN 14794 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14795 cmd->vdev_id = vdev_id; 14796 cmd->pattern_id = default_pattern, 14797 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14798 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14799 14800 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14801 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14802 buf_ptr += WMI_TLV_HDR_SIZE; 14803 14804 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14805 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14806 buf_ptr += WMI_TLV_HDR_SIZE; 14807 14808 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14809 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14810 buf_ptr += WMI_TLV_HDR_SIZE; 14811 14812 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14813 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14814 buf_ptr += WMI_TLV_HDR_SIZE; 14815 14816 /* Fill TLV for pattern_info_timeout but no data. */ 14817 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14818 buf_ptr += WMI_TLV_HDR_SIZE; 14819 14820 /* Fill TLV for ra_ratelimit_interval. */ 14821 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32)); 14822 buf_ptr += WMI_TLV_HDR_SIZE; 14823 14824 *((A_UINT32 *) buf_ptr) = rate_limit_interval; 14825 14826 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14827 rate_limit_interval, vdev_id); 14828 14829 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14830 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14831 if (ret) { 14832 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14833 wmi_buf_free(buf); 14834 return QDF_STATUS_E_FAILURE; 14835 } 14836 14837 return QDF_STATUS_SUCCESS; 14838 14839 } 14840 #endif /* FEATURE_WLAN_RA_FILTERING */ 14841 14842 /** 14843 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14844 * @wmi_handle: wmi handle 14845 * @vdev_id: vdev id 14846 * @multicastAddr: mcast address 14847 * @clearList: clear list flag 14848 * 14849 * Return: QDF_STATUS_SUCCESS for success or error code 14850 */ 14851 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14852 uint8_t vdev_id, 14853 struct qdf_mac_addr multicast_addr, 14854 bool clearList) 14855 { 14856 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14857 wmi_buf_t buf; 14858 int err; 14859 14860 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14861 if (!buf) { 14862 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14863 return QDF_STATUS_E_NOMEM; 14864 } 14865 14866 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14867 qdf_mem_zero(cmd, sizeof(*cmd)); 14868 14869 WMITLV_SET_HDR(&cmd->tlv_header, 14870 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14871 WMITLV_GET_STRUCT_TLVLEN 14872 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14873 cmd->action = 14874 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14875 cmd->vdev_id = vdev_id; 14876 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14877 14878 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14879 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14880 14881 err = wmi_unified_cmd_send(wmi_handle, buf, 14882 sizeof(*cmd), 14883 WMI_SET_MCASTBCAST_FILTER_CMDID); 14884 if (err) { 14885 WMI_LOGE("Failed to send set_param cmd"); 14886 wmi_buf_free(buf); 14887 return QDF_STATUS_E_FAILURE; 14888 } 14889 14890 return QDF_STATUS_SUCCESS; 14891 } 14892 14893 /** 14894 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14895 * command to fw 14896 * @wmi_handle: wmi handle 14897 * @vdev_id: vdev id 14898 * @mcast_filter_params: mcast filter params 14899 * 14900 * Return: QDF_STATUS_SUCCESS for success or error code 14901 */ 14902 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14903 wmi_unified_t wmi_handle, 14904 uint8_t vdev_id, 14905 struct pmo_mcast_filter_params *filter_param) 14906 14907 { 14908 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14909 uint8_t *buf_ptr; 14910 wmi_buf_t buf; 14911 int err; 14912 int i; 14913 uint8_t *mac_addr_src_ptr = NULL; 14914 wmi_mac_addr *mac_addr_dst_ptr; 14915 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14916 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14917 14918 buf = wmi_buf_alloc(wmi_handle, len); 14919 if (!buf) { 14920 WMI_LOGE("Failed to allocate memory"); 14921 return QDF_STATUS_E_NOMEM; 14922 } 14923 14924 buf_ptr = (A_UINT8 *) wmi_buf_data(buf); 14925 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14926 wmi_buf_data(buf); 14927 qdf_mem_zero(cmd, sizeof(*cmd)); 14928 14929 WMITLV_SET_HDR(&cmd->tlv_header, 14930 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14931 WMITLV_GET_STRUCT_TLVLEN 14932 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14933 cmd->operation = 14934 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14935 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14936 cmd->vdev_id = vdev_id; 14937 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14938 14939 buf_ptr += sizeof(*cmd); 14940 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14941 sizeof(wmi_mac_addr) * 14942 filter_param->multicast_addr_cnt); 14943 14944 if (filter_param->multicast_addr_cnt == 0) 14945 goto send_cmd; 14946 14947 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14948 mac_addr_dst_ptr = (wmi_mac_addr *) 14949 (buf_ptr + WMI_TLV_HDR_SIZE); 14950 14951 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14952 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14953 mac_addr_src_ptr += ATH_MAC_LEN; 14954 mac_addr_dst_ptr++; 14955 } 14956 14957 send_cmd: 14958 err = wmi_unified_cmd_send(wmi_handle, buf, 14959 len, 14960 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14961 if (err) { 14962 WMI_LOGE("Failed to send set_param cmd"); 14963 wmi_buf_free(buf); 14964 return QDF_STATUS_E_FAILURE; 14965 } 14966 14967 return QDF_STATUS_SUCCESS; 14968 } 14969 14970 14971 /** 14972 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14973 * @wmi_handle: wmi handle 14974 * @vdev_id: vdev id 14975 * @params: GTK offload parameters 14976 * 14977 * Return: CDF status 14978 */ 14979 static 14980 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14981 struct pmo_gtk_req *params, 14982 bool enable_offload, 14983 uint32_t gtk_offload_opcode) 14984 { 14985 int len; 14986 wmi_buf_t buf; 14987 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14988 wmi_gtk_offload_fils_tlv_param *ext_param; 14989 QDF_STATUS status = QDF_STATUS_SUCCESS; 14990 uint8_t *buf_ptr; 14991 14992 WMI_LOGD("%s Enter", __func__); 14993 14994 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param); 14995 14996 /* alloc wmi buffer */ 14997 buf = wmi_buf_alloc(wmi_handle, len); 14998 if (!buf) { 14999 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15000 status = QDF_STATUS_E_NOMEM; 15001 goto out; 15002 } 15003 15004 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15005 buf_ptr = (uint8_t *)cmd; 15006 WMITLV_SET_HDR(&cmd->tlv_header, 15007 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15008 WMITLV_GET_STRUCT_TLVLEN 15009 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15010 15011 cmd->vdev_id = vdev_id; 15012 15013 /* Request target to enable GTK offload */ 15014 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 15015 cmd->flags = gtk_offload_opcode; 15016 15017 /* Copy the keys and replay counter */ 15018 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 15019 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 15020 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 15021 GTK_REPLAY_COUNTER_BYTES); 15022 } else { 15023 cmd->flags = gtk_offload_opcode; 15024 } 15025 15026 buf_ptr += sizeof(*cmd); 15027 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param)); 15028 buf_ptr += WMI_TLV_HDR_SIZE; 15029 15030 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 15031 WMITLV_SET_HDR(&ext_param->tlv_header, 15032 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 15033 WMITLV_GET_STRUCT_TLVLEN( 15034 wmi_gtk_offload_fils_tlv_param)); 15035 ext_param->vdev_id = vdev_id; 15036 ext_param->flags = cmd->flags; 15037 ext_param->kek_len = params->kek_len; 15038 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 15039 qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES); 15040 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 15041 GTK_REPLAY_COUNTER_BYTES); 15042 15043 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 15044 /* send the wmi command */ 15045 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15046 WMI_GTK_OFFLOAD_CMDID)) { 15047 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 15048 wmi_buf_free(buf); 15049 status = QDF_STATUS_E_FAILURE; 15050 } 15051 15052 out: 15053 WMI_LOGD("%s Exit", __func__); 15054 return status; 15055 } 15056 15057 /** 15058 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 15059 * @wmi_handle: wmi handle 15060 * @params: GTK offload params 15061 * 15062 * Return: CDF status 15063 */ 15064 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 15065 wmi_unified_t wmi_handle, 15066 uint8_t vdev_id, 15067 uint64_t offload_req_opcode) 15068 { 15069 int len; 15070 wmi_buf_t buf; 15071 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 15072 QDF_STATUS status = QDF_STATUS_SUCCESS; 15073 15074 len = sizeof(*cmd); 15075 15076 /* alloc wmi buffer */ 15077 buf = wmi_buf_alloc(wmi_handle, len); 15078 if (!buf) { 15079 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15080 status = QDF_STATUS_E_NOMEM; 15081 goto out; 15082 } 15083 15084 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15085 WMITLV_SET_HDR(&cmd->tlv_header, 15086 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15087 WMITLV_GET_STRUCT_TLVLEN 15088 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15089 15090 /* Request for GTK offload status */ 15091 cmd->flags = offload_req_opcode; 15092 cmd->vdev_id = vdev_id; 15093 15094 /* send the wmi command */ 15095 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15096 WMI_GTK_OFFLOAD_CMDID)) { 15097 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 15098 wmi_buf_free(buf); 15099 status = QDF_STATUS_E_FAILURE; 15100 } 15101 15102 out: 15103 return status; 15104 } 15105 15106 /** 15107 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 15108 * @wmi_handle: wmi handler 15109 * @action_params: pointer to action_params 15110 * 15111 * Return: 0 for success, otherwise appropriate error code 15112 */ 15113 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 15114 struct pmo_action_wakeup_set_params *action_params) 15115 { 15116 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 15117 wmi_buf_t buf; 15118 int i; 15119 int32_t err; 15120 uint32_t len = 0, *cmd_args; 15121 uint8_t *buf_ptr; 15122 15123 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(A_UINT32)) 15124 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 15125 buf = wmi_buf_alloc(wmi_handle, len); 15126 if (!buf) { 15127 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 15128 return QDF_STATUS_E_NOMEM; 15129 } 15130 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 15131 buf_ptr = (uint8_t *)cmd; 15132 WMITLV_SET_HDR(&cmd->tlv_header, 15133 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 15134 WMITLV_GET_STRUCT_TLVLEN( 15135 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 15136 15137 cmd->vdev_id = action_params->vdev_id; 15138 cmd->operation = action_params->operation; 15139 15140 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 15141 cmd->action_category_map[i] = 15142 action_params->action_category_map[i]; 15143 15144 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 15145 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15146 (PMO_SUPPORTED_ACTION_CATE * sizeof(A_UINT32))); 15147 buf_ptr += WMI_TLV_HDR_SIZE; 15148 cmd_args = (uint32_t *) buf_ptr; 15149 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 15150 cmd_args[i] = action_params->action_per_category[i]; 15151 15152 err = wmi_unified_cmd_send(wmi_handle, buf, 15153 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 15154 if (err) { 15155 WMI_LOGE("Failed to send ap_ps_egap cmd"); 15156 wmi_buf_free(buf); 15157 return QDF_STATUS_E_FAILURE; 15158 } 15159 15160 return QDF_STATUS_SUCCESS; 15161 } 15162 15163 #ifdef FEATURE_WLAN_LPHB 15164 15165 /** 15166 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 15167 * @wmi_handle: wmi handle 15168 * @lphb_conf_req: configuration info 15169 * 15170 * Return: CDF status 15171 */ 15172 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 15173 wmi_hb_set_enable_cmd_fixed_param *params) 15174 { 15175 QDF_STATUS status; 15176 wmi_buf_t buf = NULL; 15177 uint8_t *buf_ptr; 15178 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 15179 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 15180 15181 15182 buf = wmi_buf_alloc(wmi_handle, len); 15183 if (!buf) { 15184 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15185 return QDF_STATUS_E_NOMEM; 15186 } 15187 15188 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15189 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 15190 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 15191 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 15192 WMITLV_GET_STRUCT_TLVLEN 15193 (wmi_hb_set_enable_cmd_fixed_param)); 15194 15195 /* fill in values */ 15196 hb_enable_fp->vdev_id = params->session; 15197 hb_enable_fp->enable = params->enable; 15198 hb_enable_fp->item = params->item; 15199 hb_enable_fp->session = params->session; 15200 15201 status = wmi_unified_cmd_send(wmi_handle, buf, 15202 len, WMI_HB_SET_ENABLE_CMDID); 15203 if (QDF_IS_STATUS_ERROR(status)) { 15204 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 15205 status); 15206 wmi_buf_free(buf); 15207 } 15208 15209 return status; 15210 } 15211 15212 /** 15213 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 15214 * @wmi_handle: wmi handle 15215 * @lphb_conf_req: lphb config request 15216 * 15217 * Return: CDF status 15218 */ 15219 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 15220 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 15221 { 15222 QDF_STATUS status; 15223 wmi_buf_t buf = NULL; 15224 uint8_t *buf_ptr; 15225 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 15226 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 15227 15228 buf = wmi_buf_alloc(wmi_handle, len); 15229 if (!buf) { 15230 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15231 return QDF_STATUS_E_NOMEM; 15232 } 15233 15234 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15235 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 15236 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 15237 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 15238 WMITLV_GET_STRUCT_TLVLEN 15239 (wmi_hb_set_tcp_params_cmd_fixed_param)); 15240 15241 /* fill in values */ 15242 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15243 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15244 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15245 hb_tcp_params_fp->seq = lphb_conf_req->seq; 15246 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 15247 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 15248 hb_tcp_params_fp->interval = lphb_conf_req->interval; 15249 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 15250 hb_tcp_params_fp->session = lphb_conf_req->session; 15251 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 15252 &lphb_conf_req->gateway_mac, 15253 sizeof(hb_tcp_params_fp->gateway_mac)); 15254 15255 status = wmi_unified_cmd_send(wmi_handle, buf, 15256 len, WMI_HB_SET_TCP_PARAMS_CMDID); 15257 if (QDF_IS_STATUS_ERROR(status)) { 15258 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 15259 status); 15260 wmi_buf_free(buf); 15261 } 15262 15263 return status; 15264 } 15265 15266 /** 15267 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 15268 * @wmi_handle: wmi handle 15269 * @lphb_conf_req: lphb config request 15270 * 15271 * Return: CDF status 15272 */ 15273 static 15274 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15275 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 15276 { 15277 QDF_STATUS status; 15278 wmi_buf_t buf = NULL; 15279 uint8_t *buf_ptr; 15280 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 15281 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 15282 15283 buf = wmi_buf_alloc(wmi_handle, len); 15284 if (!buf) { 15285 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15286 return QDF_STATUS_E_NOMEM; 15287 } 15288 15289 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15290 hb_tcp_filter_fp = 15291 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 15292 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 15293 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 15294 WMITLV_GET_STRUCT_TLVLEN 15295 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 15296 15297 /* fill in values */ 15298 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 15299 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 15300 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 15301 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 15302 memcpy((void *)&hb_tcp_filter_fp->filter, 15303 (void *)&g_hb_tcp_filter_fp->filter, 15304 WMI_WLAN_HB_MAX_FILTER_SIZE); 15305 15306 status = wmi_unified_cmd_send(wmi_handle, buf, 15307 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 15308 if (QDF_IS_STATUS_ERROR(status)) { 15309 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 15310 status); 15311 wmi_buf_free(buf); 15312 } 15313 15314 return status; 15315 } 15316 15317 /** 15318 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 15319 * @wmi_handle: wmi handle 15320 * @lphb_conf_req: lphb config request 15321 * 15322 * Return: CDF status 15323 */ 15324 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 15325 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 15326 { 15327 QDF_STATUS status; 15328 wmi_buf_t buf = NULL; 15329 uint8_t *buf_ptr; 15330 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 15331 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 15332 15333 buf = wmi_buf_alloc(wmi_handle, len); 15334 if (!buf) { 15335 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15336 return QDF_STATUS_E_NOMEM; 15337 } 15338 15339 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15340 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 15341 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 15342 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 15343 WMITLV_GET_STRUCT_TLVLEN 15344 (wmi_hb_set_udp_params_cmd_fixed_param)); 15345 15346 /* fill in values */ 15347 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15348 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15349 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15350 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 15351 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 15352 hb_udp_params_fp->interval = lphb_conf_req->interval; 15353 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 15354 hb_udp_params_fp->session = lphb_conf_req->session; 15355 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 15356 &lphb_conf_req->gateway_mac, 15357 sizeof(lphb_conf_req->gateway_mac)); 15358 15359 status = wmi_unified_cmd_send(wmi_handle, buf, 15360 len, WMI_HB_SET_UDP_PARAMS_CMDID); 15361 if (QDF_IS_STATUS_ERROR(status)) { 15362 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 15363 status); 15364 wmi_buf_free(buf); 15365 } 15366 15367 return status; 15368 } 15369 15370 /** 15371 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 15372 * @wmi_handle: wmi handle 15373 * @lphb_conf_req: lphb config request 15374 * 15375 * Return: CDF status 15376 */ 15377 static 15378 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15379 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 15380 { 15381 QDF_STATUS status; 15382 wmi_buf_t buf = NULL; 15383 uint8_t *buf_ptr; 15384 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 15385 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 15386 15387 buf = wmi_buf_alloc(wmi_handle, len); 15388 if (!buf) { 15389 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15390 return QDF_STATUS_E_NOMEM; 15391 } 15392 15393 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15394 hb_udp_filter_fp = 15395 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 15396 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 15397 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 15398 WMITLV_GET_STRUCT_TLVLEN 15399 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 15400 15401 /* fill in values */ 15402 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 15403 hb_udp_filter_fp->length = lphb_conf_req->length; 15404 hb_udp_filter_fp->offset = lphb_conf_req->offset; 15405 hb_udp_filter_fp->session = lphb_conf_req->session; 15406 memcpy((void *)&hb_udp_filter_fp->filter, 15407 (void *)&lphb_conf_req->filter, 15408 WMI_WLAN_HB_MAX_FILTER_SIZE); 15409 15410 status = wmi_unified_cmd_send(wmi_handle, buf, 15411 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 15412 if (QDF_IS_STATUS_ERROR(status)) { 15413 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 15414 status); 15415 wmi_buf_free(buf); 15416 } 15417 15418 return status; 15419 } 15420 #endif /* FEATURE_WLAN_LPHB */ 15421 15422 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 15423 struct pmo_hw_filter_params *req) 15424 { 15425 QDF_STATUS status; 15426 wmi_hw_data_filter_cmd_fixed_param *cmd; 15427 wmi_buf_t wmi_buf; 15428 15429 if (!req) { 15430 WMI_LOGE("req is null"); 15431 return QDF_STATUS_E_INVAL; 15432 } 15433 15434 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 15435 if (!wmi_buf) { 15436 WMI_LOGE(FL("Out of memory")); 15437 return QDF_STATUS_E_NOMEM; 15438 } 15439 15440 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15441 WMITLV_SET_HDR(&cmd->tlv_header, 15442 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 15443 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 15444 cmd->vdev_id = req->vdev_id; 15445 cmd->enable = req->mode != PMO_HW_FILTER_DISABLED; 15446 cmd->hw_filter_bitmap = req->mode; 15447 15448 WMI_LOGD("configure hw filter (vdev_id: %d, mode: %d)", 15449 req->vdev_id, req->mode); 15450 15451 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 15452 WMI_HW_DATA_FILTER_CMDID); 15453 if (QDF_IS_STATUS_ERROR(status)) { 15454 WMI_LOGE("Failed to configure hw filter"); 15455 wmi_buf_free(wmi_buf); 15456 } 15457 15458 return status; 15459 } 15460 15461 /** 15462 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 15463 * @wmi_handle: wmi handle 15464 * @vdev_id: vdev id 15465 * @enable: Flag to enable/disable packet filter 15466 * 15467 * Return: QDF_STATUS_SUCCESS for success or error code 15468 */ 15469 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 15470 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 15471 { 15472 int32_t len; 15473 int ret = 0; 15474 wmi_buf_t buf; 15475 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 15476 15477 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 15478 15479 buf = wmi_buf_alloc(wmi_handle, len); 15480 if (!buf) { 15481 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 15482 return QDF_STATUS_E_NOMEM; 15483 } 15484 15485 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 15486 WMITLV_SET_HDR(&cmd->tlv_header, 15487 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 15488 WMITLV_GET_STRUCT_TLVLEN( 15489 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 15490 15491 cmd->vdev_id = vdev_id; 15492 if (enable) 15493 cmd->enable = PACKET_FILTER_SET_ENABLE; 15494 else 15495 cmd->enable = PACKET_FILTER_SET_DISABLE; 15496 15497 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 15498 __func__, cmd->enable, vdev_id); 15499 15500 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15501 WMI_PACKET_FILTER_ENABLE_CMDID); 15502 if (ret) { 15503 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 15504 wmi_buf_free(buf); 15505 } 15506 15507 return ret; 15508 } 15509 15510 /** 15511 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 15512 * @wmi_handle: wmi handle 15513 * @vdev_id: vdev id 15514 * @rcv_filter_param: Packet filter parameters 15515 * @filter_id: Filter id 15516 * @enable: Flag to add/delete packet filter configuration 15517 * 15518 * Return: QDF_STATUS_SUCCESS for success or error code 15519 */ 15520 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 15521 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 15522 uint8_t filter_id, bool enable) 15523 { 15524 int len, i; 15525 int err = 0; 15526 wmi_buf_t buf; 15527 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 15528 15529 15530 /* allocate the memory */ 15531 len = sizeof(*cmd); 15532 buf = wmi_buf_alloc(wmi_handle, len); 15533 if (!buf) { 15534 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 15535 return QDF_STATUS_E_NOMEM; 15536 } 15537 15538 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 15539 WMITLV_SET_HDR(&cmd->tlv_header, 15540 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 15541 WMITLV_GET_STRUCT_TLVLEN 15542 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 15543 15544 cmd->vdev_id = vdev_id; 15545 cmd->filter_id = filter_id; 15546 if (enable) 15547 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 15548 else 15549 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 15550 15551 if (enable) { 15552 cmd->num_params = QDF_MIN( 15553 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 15554 rcv_filter_param->num_params); 15555 cmd->filter_type = rcv_filter_param->filter_type; 15556 cmd->coalesce_time = rcv_filter_param->coalesce_time; 15557 15558 for (i = 0; i < cmd->num_params; i++) { 15559 cmd->paramsData[i].proto_type = 15560 rcv_filter_param->params_data[i].protocol_layer; 15561 cmd->paramsData[i].cmp_type = 15562 rcv_filter_param->params_data[i].compare_flag; 15563 cmd->paramsData[i].data_length = 15564 rcv_filter_param->params_data[i].data_length; 15565 cmd->paramsData[i].data_offset = 15566 rcv_filter_param->params_data[i].data_offset; 15567 memcpy(&cmd->paramsData[i].compareData, 15568 rcv_filter_param->params_data[i].compare_data, 15569 sizeof(cmd->paramsData[i].compareData)); 15570 memcpy(&cmd->paramsData[i].dataMask, 15571 rcv_filter_param->params_data[i].data_mask, 15572 sizeof(cmd->paramsData[i].dataMask)); 15573 } 15574 } 15575 15576 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 15577 cmd->filter_action, cmd->filter_id, cmd->num_params); 15578 /* send the command along with data */ 15579 err = wmi_unified_cmd_send(wmi_handle, buf, len, 15580 WMI_PACKET_FILTER_CONFIG_CMDID); 15581 if (err) { 15582 WMI_LOGE("Failed to send pkt_filter cmd"); 15583 wmi_buf_free(buf); 15584 return QDF_STATUS_E_FAILURE; 15585 } 15586 15587 return QDF_STATUS_SUCCESS; 15588 } 15589 #endif /* End of WLAN_PMO_ENABLE */ 15590 15591 /** 15592 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 15593 * @wmi_handle: wmi handle 15594 * @request: SSID hotlist set request 15595 * 15596 * Return: QDF_STATUS enumeration 15597 */ 15598 static QDF_STATUS 15599 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 15600 struct ssid_hotlist_request_params *request) 15601 { 15602 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 15603 wmi_buf_t wmi_buf; 15604 uint32_t len; 15605 uint32_t array_size; 15606 uint8_t *buf_ptr; 15607 15608 /* length of fixed portion */ 15609 len = sizeof(*cmd); 15610 15611 /* length of variable portion */ 15612 array_size = 15613 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 15614 len += WMI_TLV_HDR_SIZE + array_size; 15615 15616 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15617 if (!wmi_buf) { 15618 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15619 return QDF_STATUS_E_NOMEM; 15620 } 15621 15622 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 15623 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 15624 buf_ptr; 15625 WMITLV_SET_HDR 15626 (&cmd->tlv_header, 15627 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 15628 WMITLV_GET_STRUCT_TLVLEN 15629 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 15630 15631 cmd->request_id = request->request_id; 15632 cmd->requestor_id = 0; 15633 cmd->vdev_id = request->session_id; 15634 cmd->table_id = 0; 15635 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 15636 cmd->total_entries = request->ssid_count; 15637 cmd->num_entries_in_page = request->ssid_count; 15638 cmd->first_entry_index = 0; 15639 15640 buf_ptr += sizeof(*cmd); 15641 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15642 15643 if (request->ssid_count) { 15644 wmi_extscan_hotlist_ssid_entry *entry; 15645 int i; 15646 15647 buf_ptr += WMI_TLV_HDR_SIZE; 15648 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15649 for (i = 0; i < request->ssid_count; i++) { 15650 WMITLV_SET_HDR 15651 (entry, 15652 WMITLV_TAG_ARRAY_STRUC, 15653 WMITLV_GET_STRUCT_TLVLEN 15654 (wmi_extscan_hotlist_ssid_entry)); 15655 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15656 qdf_mem_copy(entry->ssid.ssid, 15657 request->ssids[i].ssid.mac_ssid, 15658 request->ssids[i].ssid.length); 15659 entry->band = request->ssids[i].band; 15660 entry->min_rssi = request->ssids[i].rssi_low; 15661 entry->max_rssi = request->ssids[i].rssi_high; 15662 entry++; 15663 } 15664 cmd->mode = WMI_EXTSCAN_MODE_START; 15665 } else { 15666 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15667 } 15668 15669 if (wmi_unified_cmd_send 15670 (wmi_handle, wmi_buf, len, 15671 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15672 WMI_LOGE("%s: failed to send command", __func__); 15673 wmi_buf_free(wmi_buf); 15674 return QDF_STATUS_E_FAILURE; 15675 } 15676 15677 return QDF_STATUS_SUCCESS; 15678 } 15679 15680 /** 15681 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 15682 * @wmi_handle: wmi handle 15683 * @vdev_id: vdev id 15684 * 15685 * This function sends roam synch complete event to fw. 15686 * 15687 * Return: CDF STATUS 15688 */ 15689 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 15690 uint8_t vdev_id) 15691 { 15692 wmi_roam_synch_complete_fixed_param *cmd; 15693 wmi_buf_t wmi_buf; 15694 uint8_t *buf_ptr; 15695 uint16_t len; 15696 len = sizeof(wmi_roam_synch_complete_fixed_param); 15697 15698 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15699 if (!wmi_buf) { 15700 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15701 return QDF_STATUS_E_NOMEM; 15702 } 15703 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15704 buf_ptr = (uint8_t *) cmd; 15705 WMITLV_SET_HDR(&cmd->tlv_header, 15706 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15707 WMITLV_GET_STRUCT_TLVLEN 15708 (wmi_roam_synch_complete_fixed_param)); 15709 cmd->vdev_id = vdev_id; 15710 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15711 WMI_ROAM_SYNCH_COMPLETE)) { 15712 WMI_LOGP("%s: failed to send roam synch confirmation", 15713 __func__); 15714 wmi_buf_free(wmi_buf); 15715 return QDF_STATUS_E_FAILURE; 15716 } 15717 15718 return QDF_STATUS_SUCCESS; 15719 } 15720 15721 /** 15722 * send_fw_test_cmd_tlv() - send fw test command to fw. 15723 * @wmi_handle: wmi handle 15724 * @wmi_fwtest: fw test command 15725 * 15726 * This function sends fw test command to fw. 15727 * 15728 * Return: CDF STATUS 15729 */ 15730 static 15731 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15732 struct set_fwtest_params *wmi_fwtest) 15733 { 15734 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15735 wmi_buf_t wmi_buf; 15736 uint16_t len; 15737 15738 len = sizeof(*cmd); 15739 15740 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15741 if (!wmi_buf) { 15742 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15743 return QDF_STATUS_E_NOMEM; 15744 } 15745 15746 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15747 WMITLV_SET_HDR(&cmd->tlv_header, 15748 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15749 WMITLV_GET_STRUCT_TLVLEN( 15750 wmi_fwtest_set_param_cmd_fixed_param)); 15751 cmd->param_id = wmi_fwtest->arg; 15752 cmd->param_value = wmi_fwtest->value; 15753 15754 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15755 WMI_FWTEST_CMDID)) { 15756 WMI_LOGP("%s: failed to send fw test command", __func__); 15757 qdf_nbuf_free(wmi_buf); 15758 return QDF_STATUS_E_FAILURE; 15759 } 15760 15761 return QDF_STATUS_SUCCESS; 15762 } 15763 15764 /** 15765 * send_unit_test_cmd_tlv() - send unit test command to fw. 15766 * @wmi_handle: wmi handle 15767 * @wmi_utest: unit test command 15768 * 15769 * This function send unit test command to fw. 15770 * 15771 * Return: CDF STATUS 15772 */ 15773 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15774 struct wmi_unit_test_cmd *wmi_utest) 15775 { 15776 wmi_unit_test_cmd_fixed_param *cmd; 15777 wmi_buf_t wmi_buf; 15778 uint8_t *buf_ptr; 15779 int i; 15780 uint16_t len, args_tlv_len; 15781 A_UINT32 *unit_test_cmd_args; 15782 15783 args_tlv_len = 15784 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(A_UINT32); 15785 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15786 15787 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15788 if (!wmi_buf) { 15789 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15790 return QDF_STATUS_E_NOMEM; 15791 } 15792 15793 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15794 buf_ptr = (uint8_t *) cmd; 15795 WMITLV_SET_HDR(&cmd->tlv_header, 15796 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15797 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15798 cmd->vdev_id = wmi_utest->vdev_id; 15799 cmd->module_id = wmi_utest->module_id; 15800 cmd->num_args = wmi_utest->num_args; 15801 cmd->diag_token = wmi_utest->diag_token; 15802 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15803 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15804 (wmi_utest->num_args * sizeof(uint32_t))); 15805 unit_test_cmd_args = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE); 15806 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15807 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15808 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15809 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15810 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15811 unit_test_cmd_args[i] = wmi_utest->args[i]; 15812 WMI_LOGI("%d,", wmi_utest->args[i]); 15813 } 15814 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15815 WMI_UNIT_TEST_CMDID)) { 15816 WMI_LOGP("%s: failed to send unit test command", __func__); 15817 wmi_buf_free(wmi_buf); 15818 return QDF_STATUS_E_FAILURE; 15819 } 15820 15821 return QDF_STATUS_SUCCESS; 15822 } 15823 15824 /** 15825 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15826 * @wmi_handle: wma handle 15827 * @roaminvoke: roam invoke command 15828 * 15829 * Send roam invoke command to fw for fastreassoc. 15830 * 15831 * Return: CDF STATUS 15832 */ 15833 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15834 struct wmi_roam_invoke_cmd *roaminvoke, 15835 uint32_t ch_hz) 15836 { 15837 wmi_roam_invoke_cmd_fixed_param *cmd; 15838 wmi_buf_t wmi_buf; 15839 u_int8_t *buf_ptr; 15840 u_int16_t len, args_tlv_len; 15841 A_UINT32 *channel_list; 15842 wmi_mac_addr *bssid_list; 15843 wmi_tlv_buf_len_param *buf_len_tlv; 15844 15845 /* Host sends only one channel and one bssid */ 15846 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(A_UINT32) + 15847 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15848 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15849 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15850 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15851 if (!wmi_buf) { 15852 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15853 return QDF_STATUS_E_NOMEM; 15854 } 15855 15856 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15857 buf_ptr = (u_int8_t *) cmd; 15858 WMITLV_SET_HDR(&cmd->tlv_header, 15859 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15860 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15861 cmd->vdev_id = roaminvoke->vdev_id; 15862 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15863 if (roaminvoke->is_same_bssid) 15864 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15865 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15866 15867 if (roaminvoke->frame_len) { 15868 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15869 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15870 cmd->num_buf = 1; 15871 } else { 15872 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15873 cmd->num_buf = 0; 15874 } 15875 15876 cmd->roam_ap_sel_mode = 0; 15877 cmd->roam_delay = 0; 15878 cmd->num_chan = 1; 15879 cmd->num_bssid = 1; 15880 15881 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15882 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15883 (sizeof(u_int32_t))); 15884 channel_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 15885 *channel_list = ch_hz; 15886 buf_ptr += sizeof(A_UINT32) + WMI_TLV_HDR_SIZE; 15887 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15888 (sizeof(wmi_mac_addr))); 15889 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15890 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15891 15892 /* move to next tlv i.e. bcn_prb_buf_list */ 15893 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15894 15895 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15896 sizeof(wmi_tlv_buf_len_param)); 15897 15898 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15899 buf_len_tlv->buf_len = roaminvoke->frame_len; 15900 15901 /* move to next tlv i.e. bcn_prb_frm */ 15902 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15903 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15904 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15905 15906 /* copy frame after the header */ 15907 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15908 roaminvoke->frame_buf, 15909 roaminvoke->frame_len); 15910 15911 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15912 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 15913 buf_ptr + WMI_TLV_HDR_SIZE, 15914 roaminvoke->frame_len); 15915 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15916 cmd->flags, cmd->roam_scan_mode, 15917 cmd->roam_ap_sel_mode, cmd->roam_delay, 15918 cmd->num_chan, cmd->num_bssid); 15919 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15920 15921 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15922 WMI_ROAM_INVOKE_CMDID)) { 15923 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15924 wmi_buf_free(wmi_buf); 15925 return QDF_STATUS_E_FAILURE; 15926 } 15927 15928 return QDF_STATUS_SUCCESS; 15929 } 15930 15931 /** 15932 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15933 * @wmi_handle: wmi handle 15934 * @command: command 15935 * @vdev_id: vdev id 15936 * 15937 * This function set roam offload command to fw. 15938 * 15939 * Return: CDF status 15940 */ 15941 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15942 uint32_t command, uint32_t vdev_id) 15943 { 15944 QDF_STATUS status; 15945 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15946 wmi_buf_t buf = NULL; 15947 int len; 15948 uint8_t *buf_ptr; 15949 15950 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15951 buf = wmi_buf_alloc(wmi_handle, len); 15952 if (!buf) { 15953 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15954 return QDF_STATUS_E_NOMEM; 15955 } 15956 15957 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15958 15959 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15960 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15961 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15962 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15963 cmd_fp->vdev_id = vdev_id; 15964 cmd_fp->command_arg = command; 15965 15966 status = wmi_unified_cmd_send(wmi_handle, buf, 15967 len, WMI_ROAM_SCAN_CMD); 15968 if (QDF_IS_STATUS_ERROR(status)) { 15969 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15970 status); 15971 goto error; 15972 } 15973 15974 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15975 return QDF_STATUS_SUCCESS; 15976 15977 error: 15978 wmi_buf_free(buf); 15979 15980 return status; 15981 } 15982 15983 /** 15984 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15985 * @wmi_handle: wmi handle 15986 * @ap_profile_p: ap profile 15987 * @vdev_id: vdev id 15988 * 15989 * Send WMI_ROAM_AP_PROFILE to firmware 15990 * 15991 * Return: CDF status 15992 */ 15993 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15994 struct ap_profile_params *ap_profile) 15995 { 15996 wmi_buf_t buf = NULL; 15997 QDF_STATUS status; 15998 int len; 15999 uint8_t *buf_ptr; 16000 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 16001 wmi_roam_cnd_scoring_param *score_param; 16002 wmi_ap_profile *profile; 16003 16004 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 16005 len += sizeof(*score_param); 16006 buf = wmi_buf_alloc(wmi_handle, len); 16007 if (!buf) { 16008 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16009 return QDF_STATUS_E_NOMEM; 16010 } 16011 16012 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16013 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 16014 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 16015 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 16016 WMITLV_GET_STRUCT_TLVLEN 16017 (wmi_roam_ap_profile_fixed_param)); 16018 /* fill in threshold values */ 16019 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 16020 roam_ap_profile_fp->id = 0; 16021 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 16022 16023 profile = (wmi_ap_profile *)buf_ptr; 16024 WMITLV_SET_HDR(&profile->tlv_header, 16025 WMITLV_TAG_STRUC_wmi_ap_profile, 16026 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 16027 profile->flags = ap_profile->profile.flags; 16028 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 16029 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 16030 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 16031 profile->ssid.ssid_len); 16032 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 16033 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 16034 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 16035 profile->rsn_mcastmgmtcipherset = 16036 ap_profile->profile.rsn_mcastmgmtcipherset; 16037 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 16038 16039 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", 16040 profile->flags, profile->rssi_threshold, 16041 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 16042 profile->rsn_authmode, profile->rsn_ucastcipherset, 16043 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 16044 profile->rssi_abs_thresh); 16045 16046 buf_ptr += sizeof(wmi_ap_profile); 16047 16048 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 16049 WMITLV_SET_HDR(&score_param->tlv_header, 16050 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 16051 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 16052 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 16053 score_param->rssi_weightage_pcnt = 16054 ap_profile->param.rssi_weightage; 16055 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 16056 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 16057 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 16058 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 16059 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 16060 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 16061 score_param->esp_qbss_weightage_pcnt = 16062 ap_profile->param.esp_qbss_weightage; 16063 score_param->beamforming_weightage_pcnt = 16064 ap_profile->param.beamforming_weightage; 16065 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 16066 score_param->oce_wan_weightage_pcnt = 16067 ap_profile->param.oce_wan_weightage; 16068 16069 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", 16070 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 16071 score_param->ht_weightage_pcnt, 16072 score_param->vht_weightage_pcnt, 16073 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 16074 score_param->band_weightage_pcnt, 16075 score_param->nss_weightage_pcnt, 16076 score_param->esp_qbss_weightage_pcnt, 16077 score_param->beamforming_weightage_pcnt, 16078 score_param->pcl_weightage_pcnt, 16079 score_param->oce_wan_weightage_pcnt); 16080 16081 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 16082 score_param->band_scoring.score_pcnt = 16083 ap_profile->param.band_index_score; 16084 score_param->nss_scoring.score_pcnt = 16085 ap_profile->param.nss_index_score; 16086 16087 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 16088 score_param->bw_scoring.score_pcnt, 16089 score_param->band_scoring.score_pcnt, 16090 score_param->nss_scoring.score_pcnt); 16091 16092 score_param->rssi_scoring.best_rssi_threshold = 16093 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 16094 score_param->rssi_scoring.good_rssi_threshold = 16095 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 16096 score_param->rssi_scoring.bad_rssi_threshold = 16097 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 16098 score_param->rssi_scoring.good_rssi_pcnt = 16099 ap_profile->param.rssi_scoring.good_rssi_pcnt; 16100 score_param->rssi_scoring.bad_rssi_pcnt = 16101 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 16102 score_param->rssi_scoring.good_bucket_size = 16103 ap_profile->param.rssi_scoring.good_bucket_size; 16104 score_param->rssi_scoring.bad_bucket_size = 16105 ap_profile->param.rssi_scoring.bad_bucket_size; 16106 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 16107 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 16108 16109 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 16110 score_param->rssi_scoring.best_rssi_threshold, 16111 score_param->rssi_scoring.good_rssi_threshold, 16112 score_param->rssi_scoring.bad_rssi_threshold, 16113 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 16114 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 16115 score_param->rssi_scoring.good_rssi_pcnt, 16116 score_param->rssi_scoring.bad_rssi_pcnt, 16117 score_param->rssi_scoring.good_bucket_size, 16118 score_param->rssi_scoring.bad_bucket_size); 16119 16120 score_param->esp_qbss_scoring.num_slot = 16121 ap_profile->param.esp_qbss_scoring.num_slot; 16122 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 16123 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 16124 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 16125 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 16126 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 16127 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 16128 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 16129 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 16130 16131 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16132 score_param->esp_qbss_scoring.num_slot, 16133 score_param->esp_qbss_scoring.score_pcnt3_to_0, 16134 score_param->esp_qbss_scoring.score_pcnt7_to_4, 16135 score_param->esp_qbss_scoring.score_pcnt11_to_8, 16136 score_param->esp_qbss_scoring.score_pcnt15_to_12); 16137 16138 score_param->oce_wan_scoring.num_slot = 16139 ap_profile->param.oce_wan_scoring.num_slot; 16140 score_param->oce_wan_scoring.score_pcnt3_to_0 = 16141 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 16142 score_param->oce_wan_scoring.score_pcnt7_to_4 = 16143 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 16144 score_param->oce_wan_scoring.score_pcnt11_to_8 = 16145 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 16146 score_param->oce_wan_scoring.score_pcnt15_to_12 = 16147 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 16148 16149 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16150 score_param->oce_wan_scoring.num_slot, 16151 score_param->oce_wan_scoring.score_pcnt3_to_0, 16152 score_param->oce_wan_scoring.score_pcnt7_to_4, 16153 score_param->oce_wan_scoring.score_pcnt11_to_8, 16154 score_param->oce_wan_scoring.score_pcnt15_to_12); 16155 16156 status = wmi_unified_cmd_send(wmi_handle, buf, 16157 len, WMI_ROAM_AP_PROFILE); 16158 if (QDF_IS_STATUS_ERROR(status)) { 16159 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 16160 status); 16161 wmi_buf_free(buf); 16162 } 16163 16164 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 16165 16166 return status; 16167 } 16168 16169 /** 16170 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 16171 * @wmi_handle: wmi handle 16172 * @scan_period: scan period 16173 * @scan_age: scan age 16174 * @vdev_id: vdev id 16175 * 16176 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 16177 * 16178 * Return: CDF status 16179 */ 16180 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 16181 uint32_t scan_period, 16182 uint32_t scan_age, 16183 uint32_t vdev_id) 16184 { 16185 QDF_STATUS status; 16186 wmi_buf_t buf = NULL; 16187 int len; 16188 uint8_t *buf_ptr; 16189 wmi_roam_scan_period_fixed_param *scan_period_fp; 16190 16191 /* Send scan period values */ 16192 len = sizeof(wmi_roam_scan_period_fixed_param); 16193 buf = wmi_buf_alloc(wmi_handle, len); 16194 if (!buf) { 16195 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16196 return QDF_STATUS_E_NOMEM; 16197 } 16198 16199 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16200 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 16201 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 16202 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 16203 WMITLV_GET_STRUCT_TLVLEN 16204 (wmi_roam_scan_period_fixed_param)); 16205 /* fill in scan period values */ 16206 scan_period_fp->vdev_id = vdev_id; 16207 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 16208 scan_period_fp->roam_scan_age = scan_age; 16209 16210 status = wmi_unified_cmd_send(wmi_handle, buf, 16211 len, WMI_ROAM_SCAN_PERIOD); 16212 if (QDF_IS_STATUS_ERROR(status)) { 16213 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 16214 status); 16215 goto error; 16216 } 16217 16218 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 16219 __func__, scan_period, scan_age); 16220 return QDF_STATUS_SUCCESS; 16221 error: 16222 wmi_buf_free(buf); 16223 16224 return status; 16225 } 16226 16227 /** 16228 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 16229 * @wmi_handle: wmi handle 16230 * @chan_count: channel count 16231 * @chan_list: channel list 16232 * @list_type: list type 16233 * @vdev_id: vdev id 16234 * 16235 * Set roam offload channel list. 16236 * 16237 * Return: CDF status 16238 */ 16239 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 16240 uint8_t chan_count, 16241 uint32_t *chan_list, 16242 uint8_t list_type, uint32_t vdev_id) 16243 { 16244 wmi_buf_t buf = NULL; 16245 QDF_STATUS status; 16246 int len, list_tlv_len; 16247 int i; 16248 uint8_t *buf_ptr; 16249 wmi_roam_chan_list_fixed_param *chan_list_fp; 16250 A_UINT32 *roam_chan_list_array; 16251 16252 if (chan_count == 0) { 16253 WMI_LOGD("%s : invalid number of channels %d", __func__, 16254 chan_count); 16255 return QDF_STATUS_E_EMPTY; 16256 } 16257 /* Channel list is a table of 2 TLV's */ 16258 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(A_UINT32); 16259 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 16260 buf = wmi_buf_alloc(wmi_handle, len); 16261 if (!buf) { 16262 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16263 return QDF_STATUS_E_NOMEM; 16264 } 16265 16266 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16267 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 16268 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 16269 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 16270 WMITLV_GET_STRUCT_TLVLEN 16271 (wmi_roam_chan_list_fixed_param)); 16272 chan_list_fp->vdev_id = vdev_id; 16273 chan_list_fp->num_chan = chan_count; 16274 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 16275 /* external app is controlling channel list */ 16276 chan_list_fp->chan_list_type = 16277 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 16278 } else { 16279 /* umac supplied occupied channel list in LFR */ 16280 chan_list_fp->chan_list_type = 16281 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 16282 } 16283 16284 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 16285 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16286 (chan_list_fp->num_chan * sizeof(uint32_t))); 16287 roam_chan_list_array = (A_UINT32 *) (buf_ptr + WMI_TLV_HDR_SIZE); 16288 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 16289 for (i = 0; ((i < chan_list_fp->num_chan) && 16290 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 16291 roam_chan_list_array[i] = chan_list[i]; 16292 WMI_LOGI("%d,", roam_chan_list_array[i]); 16293 } 16294 16295 status = wmi_unified_cmd_send(wmi_handle, buf, 16296 len, WMI_ROAM_CHAN_LIST); 16297 if (QDF_IS_STATUS_ERROR(status)) { 16298 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 16299 status); 16300 goto error; 16301 } 16302 16303 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 16304 return QDF_STATUS_SUCCESS; 16305 error: 16306 wmi_buf_free(buf); 16307 16308 return status; 16309 } 16310 16311 /** 16312 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 16313 * @wmi_handle: wmi handle 16314 * @req_buf: per roam config buffer 16315 * 16316 * Return: QDF status 16317 */ 16318 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 16319 struct wmi_per_roam_config_req *req_buf) 16320 { 16321 wmi_buf_t buf = NULL; 16322 QDF_STATUS status; 16323 int len; 16324 uint8_t *buf_ptr; 16325 wmi_roam_per_config_fixed_param *wmi_per_config; 16326 16327 len = sizeof(wmi_roam_per_config_fixed_param); 16328 buf = wmi_buf_alloc(wmi_handle, len); 16329 if (!buf) { 16330 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16331 return QDF_STATUS_E_NOMEM; 16332 } 16333 16334 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16335 wmi_per_config = 16336 (wmi_roam_per_config_fixed_param *) buf_ptr; 16337 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 16338 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 16339 WMITLV_GET_STRUCT_TLVLEN 16340 (wmi_roam_per_config_fixed_param)); 16341 16342 /* fill in per roam config values */ 16343 wmi_per_config->vdev_id = req_buf->vdev_id; 16344 16345 wmi_per_config->enable = req_buf->per_config.enable; 16346 wmi_per_config->high_rate_thresh = 16347 (req_buf->per_config.tx_high_rate_thresh << 16) | 16348 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 16349 wmi_per_config->low_rate_thresh = 16350 (req_buf->per_config.tx_low_rate_thresh << 16) | 16351 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 16352 wmi_per_config->pkt_err_rate_thresh_pct = 16353 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 16354 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 16355 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 16356 wmi_per_config->pkt_err_rate_mon_time = 16357 (req_buf->per_config.tx_per_mon_time << 16) | 16358 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 16359 wmi_per_config->min_candidate_rssi = 16360 req_buf->per_config.min_candidate_rssi; 16361 16362 /* Send per roam config parameters */ 16363 status = wmi_unified_cmd_send(wmi_handle, buf, 16364 len, WMI_ROAM_PER_CONFIG_CMDID); 16365 if (QDF_IS_STATUS_ERROR(status)) { 16366 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 16367 status); 16368 wmi_buf_free(buf); 16369 return status; 16370 } 16371 16372 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 16373 req_buf->per_config.enable, req_buf->vdev_id); 16374 return QDF_STATUS_SUCCESS; 16375 } 16376 16377 /** 16378 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 16379 * @wmi_handle: wmi handle 16380 * @rssi_change_thresh: RSSI Change threshold 16381 * @bcn_rssi_weight: beacon RSSI weight 16382 * @vdev_id: vdev id 16383 * 16384 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 16385 * 16386 * Return: CDF status 16387 */ 16388 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 16389 uint32_t vdev_id, 16390 int32_t rssi_change_thresh, 16391 uint32_t bcn_rssi_weight, 16392 uint32_t hirssi_delay_btw_scans) 16393 { 16394 wmi_buf_t buf = NULL; 16395 QDF_STATUS status; 16396 int len; 16397 uint8_t *buf_ptr; 16398 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 16399 16400 /* Send rssi change parameters */ 16401 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 16402 buf = wmi_buf_alloc(wmi_handle, len); 16403 if (!buf) { 16404 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16405 return QDF_STATUS_E_NOMEM; 16406 } 16407 16408 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16409 rssi_change_fp = 16410 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 16411 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 16412 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 16413 WMITLV_GET_STRUCT_TLVLEN 16414 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 16415 /* fill in rssi change threshold (hysteresis) values */ 16416 rssi_change_fp->vdev_id = vdev_id; 16417 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 16418 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 16419 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 16420 16421 status = wmi_unified_cmd_send(wmi_handle, buf, 16422 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 16423 if (QDF_IS_STATUS_ERROR(status)) { 16424 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 16425 status); 16426 goto error; 16427 } 16428 16429 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 16430 rssi_change_thresh, bcn_rssi_weight); 16431 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 16432 return QDF_STATUS_SUCCESS; 16433 error: 16434 wmi_buf_free(buf); 16435 16436 return status; 16437 } 16438 16439 /** wmi_get_hotlist_entries_per_page() - hotlist entries per page 16440 * @wmi_handle: wmi handle. 16441 * @cmd: size of command structure. 16442 * @per_entry_size: per entry size. 16443 * 16444 * This utility function calculates how many hotlist entries can 16445 * fit in one page. 16446 * 16447 * Return: number of entries 16448 */ 16449 static inline int wmi_get_hotlist_entries_per_page(wmi_unified_t wmi_handle, 16450 size_t cmd_size, 16451 size_t per_entry_size) 16452 { 16453 uint32_t avail_space = 0; 16454 int num_entries = 0; 16455 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle); 16456 16457 /* Calculate number of hotlist entries that can 16458 * be passed in wma message request. 16459 */ 16460 avail_space = max_msg_len - cmd_size; 16461 num_entries = avail_space / per_entry_size; 16462 return num_entries; 16463 } 16464 16465 /** 16466 * send_get_buf_extscan_hotlist_cmd_tlv() - prepare hotlist command 16467 * @wmi_handle: wmi handle 16468 * @photlist: hotlist command params 16469 * @buf_len: buffer length 16470 * 16471 * This function fills individual elements for hotlist request and 16472 * TLV for bssid entries 16473 * 16474 * Return: CDF Status. 16475 */ 16476 static QDF_STATUS send_get_buf_extscan_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 16477 struct ext_scan_setbssi_hotlist_params * 16478 photlist, int *buf_len) 16479 { 16480 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL; 16481 wmi_extscan_hotlist_entry *dest_hotlist; 16482 struct ap_threshold_params *src_ap = photlist->ap; 16483 wmi_buf_t buf; 16484 uint8_t *buf_ptr; 16485 16486 int j, index = 0; 16487 int cmd_len = 0; 16488 int num_entries; 16489 int min_entries = 0; 16490 uint32_t numap = photlist->numAp; 16491 int len = sizeof(*cmd); 16492 16493 len += WMI_TLV_HDR_SIZE; 16494 cmd_len = len; 16495 16496 num_entries = wmi_get_hotlist_entries_per_page(wmi_handle, 16497 cmd_len, 16498 sizeof(*dest_hotlist)); 16499 /* setbssid hotlist expects the bssid list 16500 * to be non zero value 16501 */ 16502 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS)) { 16503 WMI_LOGE("Invalid number of APs: %d", numap); 16504 return QDF_STATUS_E_INVAL; 16505 } 16506 16507 /* Split the hot list entry pages and send multiple command 16508 * requests if the buffer reaches the maximum request size 16509 */ 16510 while (index < numap) { 16511 min_entries = QDF_MIN(num_entries, numap); 16512 len += min_entries * sizeof(wmi_extscan_hotlist_entry); 16513 buf = wmi_buf_alloc(wmi_handle, len); 16514 if (!buf) { 16515 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 16516 return QDF_STATUS_E_FAILURE; 16517 } 16518 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16519 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 16520 buf_ptr; 16521 WMITLV_SET_HDR(&cmd->tlv_header, 16522 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 16523 WMITLV_GET_STRUCT_TLVLEN 16524 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 16525 16526 /* Multiple requests are sent until the num_entries_in_page 16527 * matches the total_entries 16528 */ 16529 cmd->request_id = photlist->requestId; 16530 cmd->vdev_id = photlist->sessionId; 16531 cmd->total_entries = numap; 16532 cmd->mode = 1; 16533 cmd->num_entries_in_page = min_entries; 16534 cmd->lost_ap_scan_count = photlist->lost_ap_sample_size; 16535 cmd->first_entry_index = index; 16536 16537 WMI_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d", 16538 __func__, cmd->vdev_id, cmd->total_entries, 16539 cmd->num_entries_in_page, 16540 cmd->lost_ap_scan_count); 16541 16542 buf_ptr += sizeof(*cmd); 16543 WMITLV_SET_HDR(buf_ptr, 16544 WMITLV_TAG_ARRAY_STRUC, 16545 min_entries * sizeof(wmi_extscan_hotlist_entry)); 16546 dest_hotlist = (wmi_extscan_hotlist_entry *) 16547 (buf_ptr + WMI_TLV_HDR_SIZE); 16548 16549 /* Populate bssid, channel info and rssi 16550 * for the bssid's that are sent as hotlists. 16551 */ 16552 for (j = 0; j < min_entries; j++) { 16553 WMITLV_SET_HDR(dest_hotlist, 16554 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 16555 WMITLV_GET_STRUCT_TLVLEN 16556 (wmi_extscan_hotlist_entry)); 16557 16558 dest_hotlist->min_rssi = src_ap->low; 16559 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 16560 &dest_hotlist->bssid); 16561 16562 WMI_LOGD("%s:channel:%d min_rssi %d", 16563 __func__, dest_hotlist->channel, 16564 dest_hotlist->min_rssi); 16565 WMI_LOGD 16566 ("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16567 __func__, dest_hotlist->bssid.mac_addr31to0, 16568 dest_hotlist->bssid.mac_addr47to32); 16569 dest_hotlist++; 16570 src_ap++; 16571 } 16572 buf_ptr += WMI_TLV_HDR_SIZE + 16573 (min_entries * sizeof(wmi_extscan_hotlist_entry)); 16574 16575 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16576 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 16577 WMI_LOGE("%s: failed to send command", __func__); 16578 wmi_buf_free(buf); 16579 return QDF_STATUS_E_FAILURE; 16580 } 16581 index = index + min_entries; 16582 num_entries = numap - min_entries; 16583 len = cmd_len; 16584 } 16585 return QDF_STATUS_SUCCESS; 16586 } 16587 16588 /** 16589 * send_set_active_bpf_mode_cmd_tlv() - configure active BPF mode in FW 16590 * @wmi_handle: the WMI handle 16591 * @vdev_id: the Id of the vdev to apply the configuration to 16592 * @ucast_mode: the active BPF mode to configure for unicast packets 16593 * @mcast_bcast_mode: the active BPF mode to configure for multicast/broadcast 16594 * packets 16595 * 16596 * Return: QDF status 16597 */ 16598 static QDF_STATUS send_set_active_bpf_mode_cmd_tlv(wmi_unified_t wmi_handle, 16599 uint8_t vdev_id, 16600 enum wmi_host_active_bpf_mode ucast_mode, 16601 enum wmi_host_active_bpf_mode mcast_bcast_mode) 16602 { 16603 const WMITLV_TAG_ID tag_id = 16604 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param; 16605 const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN( 16606 wmi_bpf_set_vdev_active_mode_cmd_fixed_param); 16607 QDF_STATUS status; 16608 wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd; 16609 wmi_buf_t buf; 16610 16611 WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)", 16612 vdev_id, ucast_mode, mcast_bcast_mode); 16613 16614 /* allocate command buffer */ 16615 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 16616 if (!buf) { 16617 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 16618 return QDF_STATUS_E_NOMEM; 16619 } 16620 16621 /* set TLV header */ 16622 cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf); 16623 WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len); 16624 16625 /* populate data */ 16626 cmd->vdev_id = vdev_id; 16627 cmd->uc_mode = ucast_mode; 16628 cmd->mcbc_mode = mcast_bcast_mode; 16629 16630 /* send to FW */ 16631 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 16632 WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID); 16633 if (QDF_IS_STATUS_ERROR(status)) { 16634 WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d", 16635 status); 16636 wmi_buf_free(buf); 16637 return status; 16638 } 16639 16640 WMI_LOGD("Sent WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID successfully"); 16641 16642 return QDF_STATUS_SUCCESS; 16643 } 16644 16645 /** 16646 * send_power_dbg_cmd_tlv() - send power debug commands 16647 * @wmi_handle: wmi handle 16648 * @param: wmi power debug parameter 16649 * 16650 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 16651 * 16652 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16653 */ 16654 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 16655 struct wmi_power_dbg_params *param) 16656 { 16657 wmi_buf_t buf = NULL; 16658 QDF_STATUS status; 16659 int len, args_tlv_len; 16660 uint8_t *buf_ptr; 16661 uint8_t i; 16662 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 16663 uint32_t *cmd_args; 16664 16665 /* Prepare and send power debug cmd parameters */ 16666 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 16667 len = sizeof(*cmd) + args_tlv_len; 16668 buf = wmi_buf_alloc(wmi_handle, len); 16669 if (!buf) { 16670 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16671 return QDF_STATUS_E_NOMEM; 16672 } 16673 16674 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16675 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 16676 WMITLV_SET_HDR(&cmd->tlv_header, 16677 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 16678 WMITLV_GET_STRUCT_TLVLEN 16679 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 16680 16681 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16682 param->pdev_id); 16683 cmd->module_id = param->module_id; 16684 cmd->num_args = param->num_args; 16685 buf_ptr += sizeof(*cmd); 16686 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16687 (param->num_args * sizeof(uint32_t))); 16688 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16689 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 16690 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 16691 cmd_args[i] = param->args[i]; 16692 WMI_LOGI("%d,", param->args[i]); 16693 } 16694 16695 status = wmi_unified_cmd_send(wmi_handle, buf, 16696 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 16697 if (QDF_IS_STATUS_ERROR(status)) { 16698 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 16699 status); 16700 goto error; 16701 } 16702 16703 return QDF_STATUS_SUCCESS; 16704 error: 16705 wmi_buf_free(buf); 16706 16707 return status; 16708 } 16709 16710 /** 16711 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 16712 * @wmi_handle: wmi handle 16713 * @param: wmi multiple vdev restart req param 16714 * 16715 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 16716 * 16717 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16718 */ 16719 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 16720 wmi_unified_t wmi_handle, 16721 struct multiple_vdev_restart_params *param) 16722 { 16723 wmi_buf_t buf; 16724 QDF_STATUS qdf_status; 16725 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 16726 int i; 16727 uint8_t *buf_ptr; 16728 uint32_t *vdev_ids; 16729 wmi_channel *chan_info; 16730 struct channel_param *tchan_info; 16731 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 16732 16733 len += sizeof(wmi_channel); 16734 if (param->num_vdevs) 16735 len += sizeof(uint32_t) * param->num_vdevs; 16736 16737 buf = wmi_buf_alloc(wmi_handle, len); 16738 if (!buf) { 16739 WMI_LOGE("Failed to allocate memory\n"); 16740 qdf_status = QDF_STATUS_E_NOMEM; 16741 goto end; 16742 } 16743 16744 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16745 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 16746 buf_ptr; 16747 16748 WMITLV_SET_HDR(&cmd->tlv_header, 16749 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 16750 WMITLV_GET_STRUCT_TLVLEN 16751 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 16752 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16753 param->pdev_id); 16754 cmd->requestor_id = param->requestor_id; 16755 cmd->disable_hw_ack = param->disable_hw_ack; 16756 cmd->cac_duration_ms = param->cac_duration_ms; 16757 cmd->num_vdevs = param->num_vdevs; 16758 16759 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 16760 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 16761 " cmd->num_vdevs: %d ", 16762 __func__, cmd->pdev_id, cmd->requestor_id, 16763 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 16764 buf_ptr += sizeof(*cmd); 16765 16766 WMITLV_SET_HDR(buf_ptr, 16767 WMITLV_TAG_ARRAY_UINT32, 16768 sizeof(A_UINT32) * param->num_vdevs); 16769 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 16770 for (i = 0; i < param->num_vdevs; i++) { 16771 vdev_ids[i] = param->vdev_ids[i]; 16772 } 16773 16774 buf_ptr += (sizeof(A_UINT32) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 16775 16776 WMITLV_SET_HDR(buf_ptr, 16777 WMITLV_TAG_STRUC_wmi_channel, 16778 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16779 chan_info = (wmi_channel *)buf_ptr; 16780 tchan_info = &(param->ch_param); 16781 chan_info->mhz = tchan_info->mhz; 16782 chan_info->band_center_freq1 = tchan_info->cfreq1; 16783 chan_info->band_center_freq2 = tchan_info->cfreq2; 16784 if (tchan_info->is_chan_passive) 16785 WMI_SET_CHANNEL_FLAG(chan_info, 16786 WMI_CHAN_FLAG_PASSIVE); 16787 if (tchan_info->dfs_set) 16788 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 16789 16790 if (tchan_info->allow_vht) 16791 WMI_SET_CHANNEL_FLAG(chan_info, 16792 WMI_CHAN_FLAG_ALLOW_VHT); 16793 else if (tchan_info->allow_ht) 16794 WMI_SET_CHANNEL_FLAG(chan_info, 16795 WMI_CHAN_FLAG_ALLOW_HT); 16796 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 16797 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 16798 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 16799 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 16800 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 16801 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 16802 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 16803 16804 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 16805 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 16806 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 16807 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 16808 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 16809 "tchan_info->reg_class_id: %d ," 16810 "tchan_info->maxregpower : %d ", __func__, 16811 tchan_info->is_chan_passive, tchan_info->dfs_set, 16812 tchan_info->allow_vht, tchan_info->allow_ht, 16813 tchan_info->antennamax, tchan_info->phy_mode, 16814 tchan_info->minpower, tchan_info->maxpower, 16815 tchan_info->maxregpower, tchan_info->reg_class_id, 16816 tchan_info->maxregpower); 16817 16818 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 16819 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 16820 16821 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16822 WMI_LOGE("%s: Failed to send\n", __func__); 16823 wmi_buf_free(buf); 16824 } 16825 16826 end: 16827 return qdf_status; 16828 } 16829 16830 /** 16831 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 16832 * @wmi_handle: wmi handle 16833 * @pdev_id: pdev id 16834 * 16835 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 16836 * 16837 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16838 */ 16839 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 16840 uint32_t pdev_id) 16841 { 16842 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 16843 wmi_buf_t buf; 16844 uint16_t len; 16845 QDF_STATUS ret; 16846 16847 len = sizeof(*cmd); 16848 buf = wmi_buf_alloc(wmi_handle, len); 16849 16850 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16851 16852 if (!buf) { 16853 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16854 return QDF_STATUS_E_NOMEM; 16855 } 16856 16857 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16858 wmi_buf_data(buf); 16859 16860 WMITLV_SET_HDR(&cmd->tlv_header, 16861 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16862 WMITLV_GET_STRUCT_TLVLEN( 16863 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16864 16865 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16866 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16867 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16868 if (QDF_IS_STATUS_ERROR(ret)) { 16869 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16870 __func__, ret, pdev_id); 16871 wmi_buf_free(buf); 16872 return QDF_STATUS_E_FAILURE; 16873 } 16874 16875 return QDF_STATUS_SUCCESS; 16876 } 16877 16878 /** 16879 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16880 * @wmi_handle: wmi handle 16881 * @pdev_id: pdev id 16882 * 16883 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16884 * 16885 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16886 */ 16887 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16888 uint32_t pdev_id) 16889 { 16890 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16891 wmi_buf_t buf; 16892 uint16_t len; 16893 QDF_STATUS ret; 16894 16895 len = sizeof(*cmd); 16896 buf = wmi_buf_alloc(wmi_handle, len); 16897 16898 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16899 16900 if (!buf) { 16901 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16902 return QDF_STATUS_E_NOMEM; 16903 } 16904 16905 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16906 wmi_buf_data(buf); 16907 16908 WMITLV_SET_HDR(&cmd->tlv_header, 16909 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16910 WMITLV_GET_STRUCT_TLVLEN( 16911 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16912 16913 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16914 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16915 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16916 if (QDF_IS_STATUS_ERROR(ret)) { 16917 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16918 __func__, ret, pdev_id); 16919 wmi_buf_free(buf); 16920 return QDF_STATUS_E_FAILURE; 16921 } 16922 16923 return QDF_STATUS_SUCCESS; 16924 } 16925 16926 /** 16927 * init_cmd_send_tlv() - send initialization cmd to fw 16928 * @wmi_handle: wmi handle 16929 * @param param: pointer to wmi init param 16930 * 16931 * Return: QDF_STATUS_SUCCESS for success or error code 16932 */ 16933 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16934 struct wmi_init_cmd_param *param) 16935 { 16936 wmi_buf_t buf; 16937 wmi_init_cmd_fixed_param *cmd; 16938 uint8_t *buf_ptr; 16939 wmi_resource_config *resource_cfg; 16940 wlan_host_memory_chunk *host_mem_chunks; 16941 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16942 uint16_t idx; 16943 int len; 16944 QDF_STATUS ret; 16945 16946 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16947 WMI_TLV_HDR_SIZE; 16948 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16949 16950 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16951 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16952 WMI_TLV_HDR_SIZE + 16953 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16954 16955 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16956 if (!buf) { 16957 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16958 return QDF_STATUS_E_FAILURE; 16959 } 16960 16961 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16962 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16963 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16964 16965 host_mem_chunks = (wlan_host_memory_chunk *) 16966 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16967 + WMI_TLV_HDR_SIZE); 16968 16969 WMITLV_SET_HDR(&cmd->tlv_header, 16970 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16971 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16972 16973 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16974 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16975 WMITLV_TAG_STRUC_wmi_resource_config, 16976 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16977 16978 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16979 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16980 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16981 WMITLV_GET_STRUCT_TLVLEN 16982 (wlan_host_memory_chunk)); 16983 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16984 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16985 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16986 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16987 "chunk %d len %d requested ,ptr 0x%x ", 16988 idx, host_mem_chunks[idx].size, 16989 host_mem_chunks[idx].ptr); 16990 } 16991 cmd->num_host_mem_chunks = param->num_mem_chunks; 16992 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16993 16994 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 16995 WMITLV_TAG_ARRAY_STRUC, 16996 (sizeof(wlan_host_memory_chunk) * 16997 param->num_mem_chunks)); 16998 16999 /* Fill hw mode id config */ 17000 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 17001 17002 /* Fill fw_abi_vers */ 17003 copy_fw_abi_version_tlv(wmi_handle, cmd); 17004 17005 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 17006 if (QDF_IS_STATUS_ERROR(ret)) { 17007 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 17008 ret); 17009 wmi_buf_free(buf); 17010 } 17011 17012 return ret; 17013 17014 } 17015 17016 /** 17017 * send_addba_send_cmd_tlv() - send addba send command to fw 17018 * @wmi_handle: wmi handle 17019 * @param: pointer to delba send params 17020 * @macaddr: peer mac address 17021 * 17022 * Send WMI_ADDBA_SEND_CMDID command to firmware 17023 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17024 */ 17025 static QDF_STATUS 17026 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 17027 uint8_t macaddr[IEEE80211_ADDR_LEN], 17028 struct addba_send_params *param) 17029 { 17030 wmi_addba_send_cmd_fixed_param *cmd; 17031 wmi_buf_t buf; 17032 uint16_t len; 17033 QDF_STATUS ret; 17034 17035 len = sizeof(*cmd); 17036 17037 buf = wmi_buf_alloc(wmi_handle, len); 17038 if (!buf) { 17039 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17040 return QDF_STATUS_E_NOMEM; 17041 } 17042 17043 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 17044 17045 WMITLV_SET_HDR(&cmd->tlv_header, 17046 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 17047 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 17048 17049 cmd->vdev_id = param->vdev_id; 17050 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17051 cmd->tid = param->tidno; 17052 cmd->buffersize = param->buffersize; 17053 17054 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 17055 if (QDF_IS_STATUS_ERROR(ret)) { 17056 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17057 wmi_buf_free(buf); 17058 return QDF_STATUS_E_FAILURE; 17059 } 17060 17061 return QDF_STATUS_SUCCESS; 17062 } 17063 17064 /** 17065 * send_delba_send_cmd_tlv() - send delba send command to fw 17066 * @wmi_handle: wmi handle 17067 * @param: pointer to delba send params 17068 * @macaddr: peer mac address 17069 * 17070 * Send WMI_DELBA_SEND_CMDID command to firmware 17071 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17072 */ 17073 static QDF_STATUS 17074 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 17075 uint8_t macaddr[IEEE80211_ADDR_LEN], 17076 struct delba_send_params *param) 17077 { 17078 wmi_delba_send_cmd_fixed_param *cmd; 17079 wmi_buf_t buf; 17080 uint16_t len; 17081 QDF_STATUS ret; 17082 17083 len = sizeof(*cmd); 17084 17085 buf = wmi_buf_alloc(wmi_handle, len); 17086 if (!buf) { 17087 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17088 return QDF_STATUS_E_NOMEM; 17089 } 17090 17091 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 17092 17093 WMITLV_SET_HDR(&cmd->tlv_header, 17094 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 17095 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 17096 17097 cmd->vdev_id = param->vdev_id; 17098 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17099 cmd->tid = param->tidno; 17100 cmd->initiator = param->initiator; 17101 cmd->reasoncode = param->reasoncode; 17102 17103 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 17104 if (QDF_IS_STATUS_ERROR(ret)) { 17105 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17106 wmi_buf_free(buf); 17107 return QDF_STATUS_E_FAILURE; 17108 } 17109 17110 return QDF_STATUS_SUCCESS; 17111 } 17112 17113 /** 17114 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 17115 * to fw 17116 * @wmi_handle: wmi handle 17117 * @param: pointer to addba clearresp params 17118 * @macaddr: peer mac address 17119 * Return: 0 for success or error code 17120 */ 17121 static QDF_STATUS 17122 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 17123 uint8_t macaddr[IEEE80211_ADDR_LEN], 17124 struct addba_clearresponse_params *param) 17125 { 17126 wmi_addba_clear_resp_cmd_fixed_param *cmd; 17127 wmi_buf_t buf; 17128 uint16_t len; 17129 QDF_STATUS ret; 17130 17131 len = sizeof(*cmd); 17132 17133 buf = wmi_buf_alloc(wmi_handle, len); 17134 if (!buf) { 17135 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 17136 return QDF_STATUS_E_FAILURE; 17137 } 17138 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 17139 17140 WMITLV_SET_HDR(&cmd->tlv_header, 17141 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 17142 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 17143 17144 cmd->vdev_id = param->vdev_id; 17145 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17146 17147 ret = wmi_unified_cmd_send(wmi_handle, 17148 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 17149 if (QDF_IS_STATUS_ERROR(ret)) { 17150 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17151 wmi_buf_free(buf); 17152 return QDF_STATUS_E_FAILURE; 17153 } 17154 17155 return QDF_STATUS_SUCCESS; 17156 } 17157 17158 /** 17159 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 17160 * @wmi_handle: wmi handle 17161 * @bcn_ctrl_param: pointer to bcn_offload_control param 17162 * 17163 * Return: QDF_STATUS_SUCCESS for success or error code 17164 */ 17165 static 17166 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 17167 struct bcn_offload_control *bcn_ctrl_param) 17168 { 17169 wmi_buf_t buf; 17170 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 17171 QDF_STATUS ret; 17172 uint32_t len; 17173 17174 len = sizeof(*cmd); 17175 17176 buf = wmi_buf_alloc(wmi_handle, len); 17177 if (!buf) { 17178 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17179 return QDF_STATUS_E_FAILURE; 17180 } 17181 17182 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 17183 WMITLV_SET_HDR(&cmd->tlv_header, 17184 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 17185 WMITLV_GET_STRUCT_TLVLEN 17186 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 17187 cmd->vdev_id = bcn_ctrl_param->vdev_id; 17188 if (bcn_ctrl_param->bcn_tx_enable) 17189 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 17190 else 17191 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 17192 17193 17194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17195 WMI_BCN_OFFLOAD_CTRL_CMDID); 17196 17197 if (QDF_IS_STATUS_ERROR(ret)) { 17198 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 17199 ret); 17200 wmi_buf_free(buf); 17201 } 17202 17203 return ret; 17204 } 17205 17206 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 17207 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 17208 struct nan_datapath_initiator_req *ndp_req) 17209 { 17210 uint16_t len; 17211 wmi_buf_t buf; 17212 uint8_t *tlv_ptr; 17213 QDF_STATUS status; 17214 wmi_channel *ch_tlv; 17215 wmi_ndp_initiator_req_fixed_param *cmd; 17216 uint32_t passphrase_len, service_name_len; 17217 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 17218 17219 /* 17220 * WMI command expects 4 byte alligned len: 17221 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17222 */ 17223 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 17224 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 17225 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 17226 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 17227 service_name_len = 17228 qdf_roundup(ndp_req->service_name.service_name_len, 4); 17229 /* allocated memory for fixed params as well as variable size data */ 17230 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 17231 + ndp_cfg_len + ndp_app_info_len + pmk_len 17232 + passphrase_len + service_name_len; 17233 17234 buf = wmi_buf_alloc(wmi_handle, len); 17235 if (!buf) { 17236 WMI_LOGE("wmi_buf_alloc failed"); 17237 return QDF_STATUS_E_NOMEM; 17238 } 17239 17240 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 17241 WMITLV_SET_HDR(&cmd->tlv_header, 17242 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 17243 WMITLV_GET_STRUCT_TLVLEN( 17244 wmi_ndp_initiator_req_fixed_param)); 17245 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 17246 cmd->transaction_id = ndp_req->transaction_id; 17247 cmd->service_instance_id = ndp_req->service_instance_id; 17248 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 17249 &cmd->peer_discovery_mac_addr); 17250 17251 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 17252 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 17253 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 17254 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 17255 cmd->nan_csid = ndp_req->ncs_sk_type; 17256 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 17257 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 17258 17259 ch_tlv = (wmi_channel *)&cmd[1]; 17260 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 17261 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 17262 ch_tlv->mhz = ndp_req->channel; 17263 tlv_ptr = (uint8_t *)&ch_tlv[1]; 17264 17265 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17266 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17267 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17268 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17269 17270 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17271 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17272 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 17273 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17274 17275 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17276 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 17277 cmd->nan_pmk_len); 17278 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17279 17280 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17281 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 17282 cmd->nan_passphrase_len); 17283 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17284 17285 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17286 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17287 ndp_req->service_name.service_name, 17288 cmd->nan_servicename_len); 17289 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17290 17291 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 17292 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 17293 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 17294 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 17295 cmd->peer_discovery_mac_addr.mac_addr31to0, 17296 cmd->peer_discovery_mac_addr.mac_addr47to32); 17297 17298 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 17299 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17300 ndp_req->ndp_config.ndp_cfg, 17301 ndp_req->ndp_config.ndp_cfg_len); 17302 17303 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 17304 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17305 ndp_req->ndp_info.ndp_app_info, 17306 ndp_req->ndp_info.ndp_app_info_len); 17307 17308 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17309 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17310 ndp_req->pmk.pmk, cmd->nan_pmk_len); 17311 17312 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17313 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17314 ndp_req->passphrase.passphrase, 17315 cmd->nan_passphrase_len); 17316 17317 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17318 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17319 ndp_req->service_name.service_name, 17320 cmd->nan_servicename_len); 17321 17322 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 17323 WMI_NDP_INITIATOR_REQ_CMDID); 17324 17325 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17326 WMI_NDP_INITIATOR_REQ_CMDID); 17327 if (QDF_IS_STATUS_ERROR(status)) { 17328 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 17329 wmi_buf_free(buf); 17330 } 17331 17332 return status; 17333 } 17334 17335 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 17336 struct nan_datapath_responder_req *req) 17337 { 17338 uint16_t len; 17339 wmi_buf_t buf; 17340 uint8_t *tlv_ptr; 17341 QDF_STATUS status; 17342 wmi_ndp_responder_req_fixed_param *cmd; 17343 uint32_t passphrase_len, service_name_len; 17344 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 17345 17346 vdev_id = wlan_vdev_get_id(req->vdev); 17347 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 17348 vdev_id, req->transaction_id, 17349 req->ndp_rsp, 17350 req->ndp_instance_id, 17351 req->ndp_info.ndp_app_info_len); 17352 17353 /* 17354 * WMI command expects 4 byte alligned len: 17355 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17356 */ 17357 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 17358 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 17359 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 17360 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 17361 service_name_len = 17362 qdf_roundup(req->service_name.service_name_len, 4); 17363 17364 /* allocated memory for fixed params as well as variable size data */ 17365 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 17366 + pmk_len + passphrase_len + service_name_len; 17367 17368 buf = wmi_buf_alloc(wmi_handle, len); 17369 if (!buf) { 17370 WMI_LOGE("wmi_buf_alloc failed"); 17371 return QDF_STATUS_E_NOMEM; 17372 } 17373 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 17374 WMITLV_SET_HDR(&cmd->tlv_header, 17375 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 17376 WMITLV_GET_STRUCT_TLVLEN( 17377 wmi_ndp_responder_req_fixed_param)); 17378 cmd->vdev_id = vdev_id; 17379 cmd->transaction_id = req->transaction_id; 17380 cmd->ndp_instance_id = req->ndp_instance_id; 17381 cmd->rsp_code = req->ndp_rsp; 17382 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 17383 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 17384 cmd->nan_pmk_len = req->pmk.pmk_len; 17385 cmd->nan_csid = req->ncs_sk_type; 17386 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 17387 cmd->nan_servicename_len = req->service_name.service_name_len; 17388 17389 tlv_ptr = (uint8_t *)&cmd[1]; 17390 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17391 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17392 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17393 17394 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17395 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17396 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17397 req->ndp_info.ndp_app_info, 17398 req->ndp_info.ndp_app_info_len); 17399 17400 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17401 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17402 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 17403 cmd->nan_pmk_len); 17404 17405 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17406 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17407 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17408 req->passphrase.passphrase, 17409 cmd->nan_passphrase_len); 17410 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17411 17412 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17413 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17414 req->service_name.service_name, 17415 cmd->nan_servicename_len); 17416 17417 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17418 17419 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 17420 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 17421 17422 WMI_LOGD("ndp_config len: %d", 17423 req->ndp_config.ndp_cfg_len); 17424 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17425 req->ndp_config.ndp_cfg, 17426 req->ndp_config.ndp_cfg_len); 17427 17428 WMI_LOGD("ndp_app_info len: %d", 17429 req->ndp_info.ndp_app_info_len); 17430 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17431 req->ndp_info.ndp_app_info, 17432 req->ndp_info.ndp_app_info_len); 17433 17434 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17435 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17436 req->pmk.pmk, cmd->nan_pmk_len); 17437 17438 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17439 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17440 req->passphrase.passphrase, 17441 cmd->nan_passphrase_len); 17442 17443 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17444 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17445 req->service_name.service_name, 17446 cmd->nan_servicename_len); 17447 17448 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 17449 WMI_NDP_RESPONDER_REQ_CMDID); 17450 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17451 WMI_NDP_RESPONDER_REQ_CMDID); 17452 if (QDF_IS_STATUS_ERROR(status)) { 17453 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 17454 wmi_buf_free(buf); 17455 } 17456 return status; 17457 } 17458 17459 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 17460 struct nan_datapath_end_req *req) 17461 { 17462 uint16_t len; 17463 wmi_buf_t buf; 17464 QDF_STATUS status; 17465 uint32_t ndp_end_req_len, i; 17466 wmi_ndp_end_req *ndp_end_req_lst; 17467 wmi_ndp_end_req_fixed_param *cmd; 17468 17469 /* len of tlv following fixed param */ 17470 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 17471 /* above comes out to 4 byte alligned already, no need of padding */ 17472 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 17473 buf = wmi_buf_alloc(wmi_handle, len); 17474 if (!buf) { 17475 WMI_LOGE("Malloc failed"); 17476 return QDF_STATUS_E_NOMEM; 17477 } 17478 17479 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 17480 WMITLV_SET_HDR(&cmd->tlv_header, 17481 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 17482 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 17483 17484 cmd->transaction_id = req->transaction_id; 17485 17486 /* set tlv pointer to end of fixed param */ 17487 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 17488 ndp_end_req_len); 17489 17490 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 17491 WMI_TLV_HDR_SIZE); 17492 for (i = 0; i < req->num_ndp_instances; i++) { 17493 WMITLV_SET_HDR(&ndp_end_req_lst[i], 17494 WMITLV_TAG_ARRAY_FIXED_STRUC, 17495 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 17496 17497 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 17498 } 17499 17500 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 17501 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17502 WMI_NDP_END_REQ_CMDID); 17503 if (QDF_IS_STATUS_ERROR(status)) { 17504 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 17505 wmi_buf_free(buf); 17506 } 17507 17508 return status; 17509 } 17510 17511 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 17512 uint8_t *data, struct nan_datapath_initiator_rsp **rsp) 17513 { 17514 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 17515 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 17516 17517 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 17518 fixed_params = event->fixed_param; 17519 17520 *rsp = qdf_mem_malloc(sizeof(**rsp)); 17521 if (!(*rsp)) { 17522 WMI_LOGE("malloc failed"); 17523 return QDF_STATUS_E_NOMEM; 17524 } 17525 17526 (*rsp)->vdev = 17527 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17528 fixed_params->vdev_id, 17529 WLAN_NAN_ID); 17530 if (!(*rsp)->vdev) { 17531 WMI_LOGE("vdev is null"); 17532 qdf_mem_free(*rsp); 17533 return QDF_STATUS_E_INVAL; 17534 } 17535 17536 (*rsp)->transaction_id = fixed_params->transaction_id; 17537 (*rsp)->ndp_instance_id = fixed_params->ndp_instance_id; 17538 (*rsp)->status = fixed_params->rsp_status; 17539 (*rsp)->reason = fixed_params->reason_code; 17540 17541 return QDF_STATUS_SUCCESS; 17542 } 17543 17544 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 17545 uint8_t *data, struct nan_datapath_indication_event **rsp) 17546 { 17547 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 17548 wmi_ndp_indication_event_fixed_param *fixed_params; 17549 17550 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 17551 fixed_params = 17552 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 17553 17554 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17555 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17556 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17557 return QDF_STATUS_E_INVAL; 17558 } 17559 17560 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17561 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17562 fixed_params->ndp_app_info_len, 17563 event->num_ndp_app_info); 17564 return QDF_STATUS_E_INVAL; 17565 } 17566 17567 *rsp = qdf_mem_malloc(sizeof(**rsp)); 17568 if (!(*rsp)) { 17569 WMI_LOGE("malloc failed"); 17570 return QDF_STATUS_E_NOMEM; 17571 } 17572 17573 (*rsp)->vdev = 17574 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17575 fixed_params->vdev_id, 17576 WLAN_NAN_ID); 17577 if (!(*rsp)->vdev) { 17578 WMI_LOGE("vdev is null"); 17579 qdf_mem_free(*rsp); 17580 return QDF_STATUS_E_INVAL; 17581 } 17582 (*rsp)->service_instance_id = fixed_params->service_instance_id; 17583 (*rsp)->ndp_instance_id = fixed_params->ndp_instance_id; 17584 (*rsp)->role = fixed_params->self_ndp_role; 17585 (*rsp)->policy = fixed_params->accept_policy; 17586 17587 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17588 (*rsp)->peer_mac_addr.bytes); 17589 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 17590 (*rsp)->peer_discovery_mac_addr.bytes); 17591 17592 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 17593 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 17594 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 17595 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 17596 fixed_params->service_instance_id, 17597 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 17598 fixed_params->accept_policy, 17599 fixed_params->nan_csid, fixed_params->nan_scid_len, 17600 (*rsp)->peer_mac_addr.bytes, 17601 (*rsp)->peer_discovery_mac_addr.bytes); 17602 17603 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17604 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17605 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17606 17607 WMI_LOGD("ndp_app_info - %d bytes", 17608 fixed_params->ndp_app_info_len); 17609 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17610 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17611 17612 (*rsp)->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 17613 (*rsp)->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17614 (*rsp)->ncs_sk_type = fixed_params->nan_csid; 17615 (*rsp)->scid.scid_len = fixed_params->nan_scid_len; 17616 qdf_mem_copy((*rsp)->ndp_config.ndp_cfg, event->ndp_cfg, 17617 (*rsp)->ndp_config.ndp_cfg_len); 17618 qdf_mem_copy((*rsp)->ndp_info.ndp_app_info, event->ndp_app_info, 17619 (*rsp)->ndp_info.ndp_app_info_len); 17620 qdf_mem_copy((*rsp)->scid.scid, event->ndp_scid, (*rsp)->scid.scid_len); 17621 WMI_LOGD("scid hex dump:"); 17622 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17623 (*rsp)->scid.scid, (*rsp)->scid.scid_len); 17624 17625 return QDF_STATUS_SUCCESS; 17626 } 17627 17628 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 17629 uint8_t *data, struct nan_datapath_confirm_event **rsp) 17630 { 17631 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 17632 wmi_ndp_confirm_event_fixed_param *fixed_params; 17633 17634 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 17635 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 17636 WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) recieved. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d", 17637 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 17638 fixed_params->ndp_instance_id, fixed_params->rsp_code, 17639 fixed_params->reason_code, 17640 fixed_params->num_active_ndps_on_peer); 17641 17642 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17643 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17644 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17645 return QDF_STATUS_E_INVAL; 17646 } 17647 17648 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17649 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17650 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17651 17652 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17653 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17654 fixed_params->ndp_app_info_len, 17655 event->num_ndp_app_info); 17656 return QDF_STATUS_E_INVAL; 17657 } 17658 17659 WMI_LOGD("ndp_app_info - %d bytes", 17660 fixed_params->ndp_app_info_len); 17661 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17662 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17663 17664 *rsp = qdf_mem_malloc(sizeof(**rsp)); 17665 if (!(*rsp)) { 17666 WMI_LOGE("malloc failed"); 17667 return QDF_STATUS_E_NOMEM; 17668 } 17669 17670 (*rsp)->vdev = 17671 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17672 fixed_params->vdev_id, 17673 WLAN_NAN_ID); 17674 if (!(*rsp)->vdev) { 17675 WMI_LOGE("vdev is null"); 17676 qdf_mem_free(*rsp); 17677 return QDF_STATUS_E_INVAL; 17678 } 17679 (*rsp)->ndp_instance_id = fixed_params->ndp_instance_id; 17680 (*rsp)->rsp_code = fixed_params->rsp_code; 17681 (*rsp)->reason_code = fixed_params->reason_code; 17682 (*rsp)->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 17683 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17684 (*rsp)->peer_ndi_mac_addr.bytes); 17685 (*rsp)->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17686 qdf_mem_copy((*rsp)->ndp_info.ndp_app_info, event->ndp_app_info, 17687 (*rsp)->ndp_info.ndp_app_info_len); 17688 17689 return QDF_STATUS_SUCCESS; 17690 } 17691 17692 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 17693 uint8_t *data, struct nan_datapath_responder_rsp **rsp) 17694 { 17695 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17696 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17697 17698 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17699 fixed_params = event->fixed_param; 17700 17701 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", 17702 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17703 (*rsp)->peer_mac_addr.bytes, (*rsp)->transaction_id, 17704 (*rsp)->status, (*rsp)->reason, (*rsp)->create_peer); 17705 17706 *rsp = qdf_mem_malloc(sizeof(**rsp)); 17707 if (!(*rsp)) { 17708 WMI_LOGE("malloc failed"); 17709 return QDF_STATUS_E_NOMEM; 17710 } 17711 17712 (*rsp)->vdev = 17713 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17714 fixed_params->vdev_id, 17715 WLAN_NAN_ID); 17716 if (!(*rsp)->vdev) { 17717 WMI_LOGE("vdev is null"); 17718 qdf_mem_free(*rsp); 17719 return QDF_STATUS_E_INVAL; 17720 } 17721 (*rsp)->transaction_id = fixed_params->transaction_id; 17722 (*rsp)->reason = fixed_params->reason_code; 17723 (*rsp)->status = fixed_params->rsp_status; 17724 (*rsp)->create_peer = fixed_params->create_peer; 17725 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17726 (*rsp)->peer_mac_addr.bytes); 17727 17728 return QDF_STATUS_SUCCESS; 17729 } 17730 17731 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17732 uint8_t *data, struct nan_datapath_end_rsp_event **rsp) 17733 { 17734 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17735 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17736 17737 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17738 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17739 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d", 17740 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17741 fixed_params->rsp_status, fixed_params->reason_code); 17742 17743 *rsp = qdf_mem_malloc(sizeof(**rsp)); 17744 if (!(*rsp)) { 17745 WMI_LOGE("malloc failed"); 17746 return QDF_STATUS_E_NOMEM; 17747 } 17748 17749 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17750 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17751 if (!(*rsp)->vdev) { 17752 WMI_LOGE("vdev is null"); 17753 qdf_mem_free(*rsp); 17754 return QDF_STATUS_E_INVAL; 17755 } 17756 (*rsp)->transaction_id = fixed_params->transaction_id; 17757 (*rsp)->reason = fixed_params->reason_code; 17758 (*rsp)->status = fixed_params->rsp_status; 17759 17760 return QDF_STATUS_SUCCESS; 17761 } 17762 17763 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17764 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17765 { 17766 uint32_t i, buf_size; 17767 wmi_ndp_end_indication *ind; 17768 struct qdf_mac_addr peer_addr; 17769 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17770 17771 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17772 ind = event->ndp_end_indication_list; 17773 17774 if (event->num_ndp_end_indication_list == 0) { 17775 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17776 return -EINVAL; 17777 } 17778 17779 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17780 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17781 if (!(*rsp)->vdev) { 17782 WMI_LOGE("vdev is null"); 17783 qdf_mem_free(*rsp); 17784 return QDF_STATUS_E_INVAL; 17785 } 17786 17787 WMI_LOGD("number of ndp instances = %d", 17788 event->num_ndp_end_indication_list); 17789 buf_size = sizeof(*rsp) + event->num_ndp_end_indication_list * 17790 sizeof((*rsp)->ndp_map[0]); 17791 *rsp = qdf_mem_malloc(buf_size); 17792 if (!(*rsp)) { 17793 WMI_LOGE("Failed to allocate memory"); 17794 return -ENOMEM; 17795 } 17796 17797 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17798 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17799 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17800 peer_addr.bytes); 17801 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17802 i, ind[i].type, ind[i].reason_code, 17803 ind[i].ndp_instance_id, 17804 ind[i].num_active_ndps_on_peer); 17805 /* Add each instance entry to the list */ 17806 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17807 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17808 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17809 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17810 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17811 ind[i].num_active_ndps_on_peer; 17812 (*rsp)->ndp_map[i].type = ind[i].type; 17813 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17814 } 17815 17816 return QDF_STATUS_SUCCESS; 17817 } 17818 #endif 17819 17820 /** 17821 * save_service_bitmap_tlv() - save service bitmap 17822 * @wmi_handle: wmi handle 17823 * @param evt_buf: pointer to event buffer 17824 * @param bitmap_buf: bitmap buffer, for converged legacy support 17825 * 17826 * Return: QDF_STATUS 17827 */ 17828 static 17829 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17830 void *bitmap_buf) 17831 { 17832 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17833 struct wmi_soc *soc = wmi_handle->soc; 17834 17835 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17836 17837 /* If it is already allocated, use that buffer. This can happen 17838 * during target stop/start scenarios where host allocation is skipped. 17839 */ 17840 if (!soc->wmi_service_bitmap) { 17841 soc->wmi_service_bitmap = 17842 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17843 if (!soc->wmi_service_bitmap) { 17844 WMI_LOGE("Failed memory allocation for service bitmap"); 17845 return QDF_STATUS_E_NOMEM; 17846 } 17847 } 17848 17849 qdf_mem_copy(soc->wmi_service_bitmap, 17850 param_buf->wmi_service_bitmap, 17851 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17852 17853 if (bitmap_buf) 17854 qdf_mem_copy(bitmap_buf, 17855 param_buf->wmi_service_bitmap, 17856 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17857 17858 return QDF_STATUS_SUCCESS; 17859 } 17860 17861 /** 17862 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17863 * @wmi_handle: wmi handle 17864 * @param evt_buf: pointer to event buffer 17865 * @param bitmap_buf: bitmap buffer, for converged legacy support 17866 * 17867 * Return: QDF_STATUS 17868 */ 17869 static 17870 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17871 void *bitmap_buf) 17872 { 17873 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17874 wmi_service_available_event_fixed_param *ev; 17875 struct wmi_soc *soc = wmi_handle->soc; 17876 17877 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17878 17879 ev = param_buf->fixed_param; 17880 17881 /* If it is already allocated, use that buffer. This can happen 17882 * during target stop/start scenarios where host allocation is skipped. 17883 */ 17884 if (!soc->wmi_ext_service_bitmap) { 17885 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17886 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17887 if (!soc->wmi_ext_service_bitmap) { 17888 WMI_LOGE("Failed memory allocation for service bitmap"); 17889 return QDF_STATUS_E_NOMEM; 17890 } 17891 } 17892 17893 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17894 ev->wmi_service_segment_bitmap, 17895 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17896 17897 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17898 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17899 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17900 17901 if (bitmap_buf) 17902 qdf_mem_copy(bitmap_buf, 17903 soc->wmi_ext_service_bitmap, 17904 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17905 17906 return QDF_STATUS_SUCCESS; 17907 } 17908 /** 17909 * is_service_enabled_tlv() - Check if service enabled 17910 * @param wmi_handle: wmi handle 17911 * @param service_id: service identifier 17912 * 17913 * Return: 1 enabled, 0 disabled 17914 */ 17915 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17916 uint32_t service_id) 17917 { 17918 struct wmi_soc *soc = wmi_handle->soc; 17919 17920 if (!soc->wmi_service_bitmap) { 17921 WMI_LOGE("WMI service bit map is not saved yet\n"); 17922 return false; 17923 } 17924 17925 /* if wmi_service_enabled was received with extended bitmap, 17926 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17927 */ 17928 if (soc->wmi_ext_service_bitmap) 17929 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17930 soc->wmi_ext_service_bitmap, 17931 service_id); 17932 17933 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17934 service_id); 17935 } 17936 17937 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17938 struct wlan_psoc_target_capability_info *cap) 17939 { 17940 /* except LDPC all flags are common betwen legacy and here 17941 * also IBFEER is not defined for TLV 17942 */ 17943 cap->ht_cap_info |= ev_target_cap & ( 17944 WMI_HT_CAP_ENABLED 17945 | WMI_HT_CAP_HT20_SGI 17946 | WMI_HT_CAP_DYNAMIC_SMPS 17947 | WMI_HT_CAP_TX_STBC 17948 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17949 | WMI_HT_CAP_RX_STBC 17950 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17951 | WMI_HT_CAP_LDPC 17952 | WMI_HT_CAP_L_SIG_TXOP_PROT 17953 | WMI_HT_CAP_MPDU_DENSITY 17954 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17955 | WMI_HT_CAP_HT40_SGI); 17956 if (ev_target_cap & WMI_HT_CAP_LDPC) 17957 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17958 WMI_HOST_HT_CAP_TX_LDPC; 17959 } 17960 /** 17961 * extract_service_ready_tlv() - extract service ready event 17962 * @wmi_handle: wmi handle 17963 * @param evt_buf: pointer to received event buffer 17964 * @param cap: pointer to hold target capability information extracted from even 17965 * 17966 * Return: QDF_STATUS_SUCCESS for success or error code 17967 */ 17968 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17969 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17970 { 17971 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17972 wmi_service_ready_event_fixed_param *ev; 17973 17974 17975 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17976 17977 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17978 if (!ev) { 17979 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17980 return QDF_STATUS_E_FAILURE; 17981 } 17982 17983 cap->phy_capability = ev->phy_capability; 17984 cap->max_frag_entry = ev->max_frag_entry; 17985 cap->num_rf_chains = ev->num_rf_chains; 17986 copy_ht_cap_info(ev->ht_cap_info, cap); 17987 cap->vht_cap_info = ev->vht_cap_info; 17988 cap->vht_supp_mcs = ev->vht_supp_mcs; 17989 cap->hw_min_tx_power = ev->hw_min_tx_power; 17990 cap->hw_max_tx_power = ev->hw_max_tx_power; 17991 cap->sys_cap_info = ev->sys_cap_info; 17992 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17993 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17994 cap->max_num_scan_channels = ev->max_num_scan_channels; 17995 cap->max_supported_macs = ev->max_supported_macs; 17996 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17997 cap->txrx_chainmask = ev->txrx_chainmask; 17998 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17999 cap->num_msdu_desc = ev->num_msdu_desc; 18000 cap->fw_version = ev->fw_build_vers; 18001 /* fw_version_1 is not available in TLV. */ 18002 cap->fw_version_1 = 0; 18003 18004 return QDF_STATUS_SUCCESS; 18005 } 18006 18007 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 18008 * to host internal WMI_HOST_REGDMN_MODE values. 18009 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 18010 * host currently. Add this in the future if required. 18011 * 11AX (Phase II) : 11ax related values are not currently 18012 * advertised separately by FW. As part of phase II regulatory bring-up, 18013 * finalize the advertisement mechanism. 18014 * @target_wireless_mode: target wireless mode received in message 18015 * 18016 * Return: returns the host internal wireless mode. 18017 */ 18018 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 18019 { 18020 18021 uint32_t wireless_modes = 0; 18022 18023 if (target_wireless_mode & REGDMN_MODE_11A) 18024 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 18025 18026 if (target_wireless_mode & REGDMN_MODE_TURBO) 18027 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 18028 18029 if (target_wireless_mode & REGDMN_MODE_11B) 18030 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 18031 18032 if (target_wireless_mode & REGDMN_MODE_PUREG) 18033 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 18034 18035 if (target_wireless_mode & REGDMN_MODE_11G) 18036 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 18037 18038 if (target_wireless_mode & REGDMN_MODE_108G) 18039 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 18040 18041 if (target_wireless_mode & REGDMN_MODE_108A) 18042 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 18043 18044 if (target_wireless_mode & REGDMN_MODE_XR) 18045 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 18046 18047 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 18048 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 18049 18050 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 18051 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 18052 18053 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 18054 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 18055 18056 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 18057 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 18058 18059 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 18060 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 18061 18062 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 18063 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 18064 18065 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 18066 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 18067 18068 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 18069 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 18070 18071 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 18072 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 18073 18074 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 18075 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 18076 18077 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 18078 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 18079 18080 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 18081 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 18082 18083 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 18084 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 18085 18086 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 18087 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 18088 18089 return wireless_modes; 18090 } 18091 18092 /** 18093 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 18094 * @wmi_handle: wmi handle 18095 * @param evt_buf: Pointer to event buffer 18096 * @param cap: pointer to hold HAL reg capabilities 18097 * 18098 * Return: QDF_STATUS_SUCCESS for success or error code 18099 */ 18100 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 18101 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 18102 { 18103 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18104 18105 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18106 18107 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 18108 sizeof(uint32_t)), 18109 sizeof(struct wlan_psoc_hal_reg_capability)); 18110 18111 cap->wireless_modes = convert_wireless_modes_tlv( 18112 param_buf->hal_reg_capabilities->wireless_modes); 18113 18114 return QDF_STATUS_SUCCESS; 18115 } 18116 18117 /** 18118 * extract_host_mem_req_tlv() - Extract host memory request event 18119 * @wmi_handle: wmi handle 18120 * @param evt_buf: pointer to event buffer 18121 * @param num_entries: pointer to hold number of entries requested 18122 * 18123 * Return: Number of entries requested 18124 */ 18125 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 18126 void *evt_buf, uint8_t *num_entries) 18127 { 18128 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18129 wmi_service_ready_event_fixed_param *ev; 18130 18131 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18132 18133 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18134 if (!ev) { 18135 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18136 return NULL; 18137 } 18138 18139 *num_entries = ev->num_mem_reqs; 18140 18141 return (host_mem_req *)param_buf->mem_reqs; 18142 } 18143 18144 /** 18145 * save_fw_version_in_service_ready_tlv() - Save fw version in service 18146 * ready function 18147 * @wmi_handle: wmi handle 18148 * @param evt_buf: pointer to event buffer 18149 * 18150 * Return: QDF_STATUS_SUCCESS for success or error code 18151 */ 18152 static QDF_STATUS 18153 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 18154 { 18155 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18156 wmi_service_ready_event_fixed_param *ev; 18157 18158 18159 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18160 18161 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18162 if (!ev) { 18163 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18164 return QDF_STATUS_E_FAILURE; 18165 } 18166 18167 /*Save fw version from service ready message */ 18168 /*This will be used while sending INIT message */ 18169 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 18170 sizeof(wmi_handle->fw_abi_version)); 18171 18172 return QDF_STATUS_SUCCESS; 18173 } 18174 18175 /** 18176 * ready_extract_init_status_tlv() - Extract init status from ready event 18177 * @wmi_handle: wmi handle 18178 * @param evt_buf: Pointer to event buffer 18179 * 18180 * Return: ready status 18181 */ 18182 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 18183 void *evt_buf) 18184 { 18185 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18186 wmi_ready_event_fixed_param *ev = NULL; 18187 18188 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18189 ev = param_buf->fixed_param; 18190 18191 qdf_print("%s:%d\n", __func__, ev->status); 18192 18193 return ev->status; 18194 } 18195 18196 /** 18197 * ready_extract_mac_addr_tlv() - extract mac address from ready event 18198 * @wmi_handle: wmi handle 18199 * @param evt_buf: pointer to event buffer 18200 * @param macaddr: Pointer to hold MAC address 18201 * 18202 * Return: QDF_STATUS_SUCCESS for success or error code 18203 */ 18204 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 18205 void *evt_buf, uint8_t *macaddr) 18206 { 18207 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18208 wmi_ready_event_fixed_param *ev = NULL; 18209 18210 18211 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18212 ev = param_buf->fixed_param; 18213 18214 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 18215 18216 return QDF_STATUS_SUCCESS; 18217 } 18218 18219 /** 18220 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 18221 * @wmi_handle: wmi handle 18222 * @param evt_buf: pointer to event buffer 18223 * @param macaddr: Pointer to hold number of MAC addresses 18224 * 18225 * Return: Pointer to addr list 18226 */ 18227 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 18228 void *evt_buf, uint8_t *num_mac) 18229 { 18230 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18231 wmi_ready_event_fixed_param *ev = NULL; 18232 18233 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18234 ev = param_buf->fixed_param; 18235 18236 *num_mac = ev->num_extra_mac_addr; 18237 18238 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 18239 } 18240 18241 /** 18242 * extract_ready_params_tlv() - Extract data from ready event apart from 18243 * status, macaddr and version. 18244 * @wmi_handle: Pointer to WMI handle. 18245 * @evt_buf: Pointer to Ready event buffer. 18246 * @ev_param: Pointer to host defined struct to copy the data from event. 18247 * 18248 * Return: QDF_STATUS_SUCCESS on success. 18249 */ 18250 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 18251 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 18252 { 18253 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18254 wmi_ready_event_fixed_param *ev = NULL; 18255 18256 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18257 ev = param_buf->fixed_param; 18258 18259 ev_param->status = ev->status; 18260 ev_param->num_dscp_table = ev->num_dscp_table; 18261 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 18262 ev_param->num_total_peer = ev->num_total_peers; 18263 ev_param->num_extra_peer = ev->num_extra_peers; 18264 /* Agile_cap in ready event is not supported in TLV target */ 18265 ev_param->agile_capability = false; 18266 18267 return QDF_STATUS_SUCCESS; 18268 } 18269 18270 /** 18271 * extract_dbglog_data_len_tlv() - extract debuglog data length 18272 * @wmi_handle: wmi handle 18273 * @param evt_buf: pointer to event buffer 18274 * 18275 * Return: length 18276 */ 18277 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 18278 void *evt_buf, uint32_t *len) 18279 { 18280 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 18281 18282 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 18283 18284 *len = param_buf->num_bufp; 18285 18286 return param_buf->bufp; 18287 } 18288 18289 /** 18290 * extract_vdev_start_resp_tlv() - extract vdev start response 18291 * @wmi_handle: wmi handle 18292 * @param evt_buf: pointer to event buffer 18293 * @param vdev_rsp: Pointer to hold vdev response 18294 * 18295 * Return: QDF_STATUS_SUCCESS for success or error code 18296 */ 18297 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 18298 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 18299 { 18300 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 18301 wmi_vdev_start_response_event_fixed_param *ev; 18302 18303 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 18304 if (!param_buf) { 18305 qdf_print("Invalid start response event buffer\n"); 18306 return QDF_STATUS_E_INVAL; 18307 } 18308 18309 ev = param_buf->fixed_param; 18310 if (!ev) { 18311 qdf_print("Invalid start response event buffer\n"); 18312 return QDF_STATUS_E_INVAL; 18313 } 18314 18315 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 18316 18317 vdev_rsp->vdev_id = ev->vdev_id; 18318 vdev_rsp->requestor_id = ev->requestor_id; 18319 switch (ev->resp_type) { 18320 case WMI_VDEV_START_RESP_EVENT: 18321 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 18322 break; 18323 case WMI_VDEV_RESTART_RESP_EVENT: 18324 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 18325 break; 18326 default: 18327 qdf_print("Invalid start response event buffer\n"); 18328 break; 18329 }; 18330 vdev_rsp->status = ev->status; 18331 vdev_rsp->chain_mask = ev->chain_mask; 18332 vdev_rsp->smps_mode = ev->smps_mode; 18333 vdev_rsp->mac_id = ev->mac_id; 18334 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 18335 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 18336 18337 return QDF_STATUS_SUCCESS; 18338 } 18339 18340 /** 18341 * extract_vdev_delete_resp_tlv() - extract vdev delete response 18342 * @wmi_handle: wmi handle 18343 * @param evt_buf: pointer to event buffer 18344 * @param delete_rsp: Pointer to hold vdev delete response 18345 * 18346 * Return: QDF_STATUS_SUCCESS for success or error code 18347 */ 18348 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 18349 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 18350 { 18351 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 18352 wmi_vdev_delete_resp_event_fixed_param *ev; 18353 18354 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 18355 if (!param_buf) { 18356 WMI_LOGE("Invalid vdev delete response event buffer\n"); 18357 return QDF_STATUS_E_INVAL; 18358 } 18359 18360 ev = param_buf->fixed_param; 18361 if (!ev) { 18362 WMI_LOGE("Invalid vdev delete response event\n"); 18363 return QDF_STATUS_E_INVAL; 18364 } 18365 18366 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 18367 delete_rsp->vdev_id = ev->vdev_id; 18368 18369 return QDF_STATUS_SUCCESS; 18370 } 18371 18372 18373 /** 18374 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 18375 * @wmi_handle: wmi handle 18376 * @param evt_buf: pointer to event buffer 18377 * @param num_vdevs: Pointer to hold num vdev 18378 * 18379 * Return: QDF_STATUS_SUCCESS for success or error code 18380 */ 18381 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18382 void *evt_buf, uint32_t *num_vdevs) 18383 { 18384 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18385 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18386 uint32_t vdev_map; 18387 18388 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 18389 if (!param_buf) { 18390 qdf_print("Invalid tbtt update ext event buffer\n"); 18391 return QDF_STATUS_E_INVAL; 18392 } 18393 tbtt_offset_event = param_buf->fixed_param; 18394 vdev_map = tbtt_offset_event->vdev_map; 18395 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18396 18397 return QDF_STATUS_SUCCESS; 18398 } 18399 18400 /** 18401 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 18402 * @wmi_handle: wmi handle 18403 * @param evt_buf: pointer to event buffer 18404 * @param num_vdevs: Pointer to hold num vdev 18405 * 18406 * Return: QDF_STATUS_SUCCESS for success or error code 18407 */ 18408 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18409 void *evt_buf, uint32_t *num_vdevs) 18410 { 18411 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18412 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 18413 18414 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18415 if (!param_buf) { 18416 qdf_print("Invalid tbtt update ext event buffer\n"); 18417 return QDF_STATUS_E_INVAL; 18418 } 18419 tbtt_offset_ext_event = param_buf->fixed_param; 18420 18421 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 18422 18423 return QDF_STATUS_SUCCESS; 18424 } 18425 18426 /** 18427 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 18428 * @wmi_handle: wmi handle 18429 * @param evt_buf: pointer to event buffer 18430 * @param idx: Index refering to a vdev 18431 * @param tbtt_param: Pointer to tbttoffset event param 18432 * 18433 * Return: QDF_STATUS_SUCCESS for success or error code 18434 */ 18435 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 18436 void *evt_buf, uint8_t idx, 18437 struct tbttoffset_params *tbtt_param) 18438 { 18439 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18440 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18441 uint32_t vdev_map; 18442 18443 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 18444 if (!param_buf) { 18445 qdf_print("Invalid tbtt update event buffer\n"); 18446 return QDF_STATUS_E_INVAL; 18447 } 18448 18449 tbtt_offset_event = param_buf->fixed_param; 18450 vdev_map = tbtt_offset_event->vdev_map; 18451 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 18452 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 18453 return QDF_STATUS_E_INVAL; 18454 tbtt_param->tbttoffset = 18455 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 18456 18457 return QDF_STATUS_SUCCESS; 18458 } 18459 18460 /** 18461 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 18462 * @wmi_handle: wmi handle 18463 * @param evt_buf: pointer to event buffer 18464 * @param idx: Index refering to a vdev 18465 * @param tbtt_param: Pointer to tbttoffset event param 18466 * 18467 * Return: QDF_STATUS_SUCCESS for success or error code 18468 */ 18469 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 18470 void *evt_buf, uint8_t idx, 18471 struct tbttoffset_params *tbtt_param) 18472 { 18473 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18474 wmi_tbtt_offset_info *tbtt_offset_info; 18475 18476 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18477 if (!param_buf) { 18478 qdf_print("Invalid tbtt update event buffer\n"); 18479 return QDF_STATUS_E_INVAL; 18480 } 18481 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 18482 18483 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 18484 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 18485 18486 return QDF_STATUS_SUCCESS; 18487 } 18488 18489 /** 18490 * extract_mgmt_rx_params_tlv() - extract management rx params from event 18491 * @wmi_handle: wmi handle 18492 * @param evt_buf: pointer to event buffer 18493 * @param hdr: Pointer to hold header 18494 * @param bufp: Pointer to hold pointer to rx param buffer 18495 * 18496 * Return: QDF_STATUS_SUCCESS for success or error code 18497 */ 18498 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 18499 void *evt_buf, struct mgmt_rx_event_params *hdr, 18500 uint8_t **bufp) 18501 { 18502 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 18503 wmi_mgmt_rx_hdr *ev_hdr = NULL; 18504 int i; 18505 18506 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 18507 if (!param_tlvs) { 18508 WMI_LOGE("Get NULL point message from FW"); 18509 return QDF_STATUS_E_INVAL; 18510 } 18511 18512 ev_hdr = param_tlvs->hdr; 18513 if (!hdr) { 18514 WMI_LOGE("Rx event is NULL"); 18515 return QDF_STATUS_E_INVAL; 18516 } 18517 18518 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18519 ev_hdr->pdev_id); 18520 18521 hdr->channel = ev_hdr->channel; 18522 hdr->snr = ev_hdr->snr; 18523 hdr->rate = ev_hdr->rate; 18524 hdr->phy_mode = ev_hdr->phy_mode; 18525 hdr->buf_len = ev_hdr->buf_len; 18526 hdr->status = ev_hdr->status; 18527 hdr->flags = ev_hdr->flags; 18528 hdr->rssi = ev_hdr->rssi; 18529 hdr->tsf_delta = ev_hdr->tsf_delta; 18530 for (i = 0; i < ATH_MAX_ANTENNA; i++) 18531 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 18532 18533 *bufp = param_tlvs->bufp; 18534 18535 return QDF_STATUS_SUCCESS; 18536 } 18537 18538 /** 18539 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 18540 * @wmi_handle: wmi handle 18541 * @param evt_buf: pointer to event buffer 18542 * @param vdev_id: Pointer to hold vdev identifier 18543 * 18544 * Return: QDF_STATUS_SUCCESS for success or error code 18545 */ 18546 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 18547 void *evt_buf, uint32_t *vdev_id) 18548 { 18549 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 18550 wmi_vdev_stopped_event_fixed_param *resp_event; 18551 18552 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 18553 if (!param_buf) { 18554 WMI_LOGE("Invalid event buffer"); 18555 return QDF_STATUS_E_INVAL; 18556 } 18557 resp_event = param_buf->fixed_param; 18558 *vdev_id = resp_event->vdev_id; 18559 18560 return QDF_STATUS_SUCCESS; 18561 } 18562 18563 /** 18564 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 18565 * @wmi_handle: wmi handle 18566 * @param evt_buf: pointer to event buffer 18567 * @param param: Pointer to hold roam param 18568 * 18569 * Return: QDF_STATUS_SUCCESS for success or error code 18570 */ 18571 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 18572 void *evt_buf, wmi_host_roam_event *param) 18573 { 18574 WMI_ROAM_EVENTID_param_tlvs *param_buf; 18575 wmi_roam_event_fixed_param *evt; 18576 18577 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 18578 if (!param_buf) { 18579 WMI_LOGE("Invalid roam event buffer"); 18580 return QDF_STATUS_E_INVAL; 18581 } 18582 18583 evt = param_buf->fixed_param; 18584 qdf_mem_zero(param, sizeof(*param)); 18585 18586 param->vdev_id = evt->vdev_id; 18587 param->reason = evt->reason; 18588 param->rssi = evt->rssi; 18589 18590 return QDF_STATUS_SUCCESS; 18591 } 18592 18593 /** 18594 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 18595 * @wmi_handle: wmi handle 18596 * @param evt_buf: pointer to event buffer 18597 * @param param: Pointer to hold vdev scan param 18598 * 18599 * Return: QDF_STATUS_SUCCESS for success or error code 18600 */ 18601 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18602 void *evt_buf, struct scan_event *param) 18603 { 18604 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18605 wmi_scan_event_fixed_param *evt = NULL; 18606 18607 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18608 evt = param_buf->fixed_param; 18609 18610 qdf_mem_zero(param, sizeof(*param)); 18611 18612 switch (evt->event) { 18613 case WMI_SCAN_EVENT_STARTED: 18614 param->type = SCAN_EVENT_TYPE_STARTED; 18615 break; 18616 case WMI_SCAN_EVENT_COMPLETED: 18617 param->type = SCAN_EVENT_TYPE_COMPLETED; 18618 break; 18619 case WMI_SCAN_EVENT_BSS_CHANNEL: 18620 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18621 break; 18622 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18623 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18624 break; 18625 case WMI_SCAN_EVENT_DEQUEUED: 18626 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18627 break; 18628 case WMI_SCAN_EVENT_PREEMPTED: 18629 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18630 break; 18631 case WMI_SCAN_EVENT_START_FAILED: 18632 param->type = SCAN_EVENT_TYPE_START_FAILED; 18633 break; 18634 case WMI_SCAN_EVENT_RESTARTED: 18635 param->type = SCAN_EVENT_TYPE_RESTARTED; 18636 break; 18637 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18638 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18639 break; 18640 case WMI_SCAN_EVENT_MAX: 18641 default: 18642 param->type = SCAN_EVENT_TYPE_MAX; 18643 break; 18644 }; 18645 18646 switch (evt->reason) { 18647 case WMI_SCAN_REASON_NONE: 18648 param->reason = SCAN_REASON_NONE; 18649 break; 18650 case WMI_SCAN_REASON_COMPLETED: 18651 param->reason = SCAN_REASON_COMPLETED; 18652 break; 18653 case WMI_SCAN_REASON_CANCELLED: 18654 param->reason = SCAN_REASON_CANCELLED; 18655 break; 18656 case WMI_SCAN_REASON_PREEMPTED: 18657 param->reason = SCAN_REASON_PREEMPTED; 18658 break; 18659 case WMI_SCAN_REASON_TIMEDOUT: 18660 param->reason = SCAN_REASON_TIMEDOUT; 18661 break; 18662 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18663 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18664 break; 18665 case WMI_SCAN_REASON_SUSPENDED: 18666 param->reason = SCAN_REASON_SUSPENDED; 18667 break; 18668 case WMI_SCAN_REASON_MAX: 18669 param->reason = SCAN_REASON_MAX; 18670 break; 18671 default: 18672 param->reason = SCAN_REASON_MAX; 18673 break; 18674 }; 18675 18676 param->chan_freq = evt->channel_freq; 18677 param->requester = evt->requestor; 18678 param->scan_id = evt->scan_id; 18679 param->vdev_id = evt->vdev_id; 18680 param->timestamp = evt->tsf_timestamp; 18681 18682 return QDF_STATUS_SUCCESS; 18683 } 18684 18685 #ifdef CONVERGED_TDLS_ENABLE 18686 /** 18687 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18688 * @wmi_handle: wmi handle 18689 * @param evt_buf: pointer to event buffer 18690 * @param param: Pointer to hold vdev tdls param 18691 * 18692 * Return: QDF_STATUS_SUCCESS for success or error code 18693 */ 18694 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18695 void *evt_buf, struct tdls_event_info *param) 18696 { 18697 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18698 wmi_tdls_peer_event_fixed_param *evt; 18699 18700 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18701 if (!param_buf) { 18702 WMI_LOGE("%s: NULL param_buf", __func__); 18703 return QDF_STATUS_E_NULL_VALUE; 18704 } 18705 18706 evt = param_buf->fixed_param; 18707 18708 qdf_mem_zero(param, sizeof(*param)); 18709 18710 param->vdev_id = evt->vdev_id; 18711 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18712 param->peermac.bytes); 18713 switch (evt->peer_status) { 18714 case WMI_TDLS_SHOULD_DISCOVER: 18715 param->message_type = TDLS_SHOULD_DISCOVER; 18716 break; 18717 case WMI_TDLS_SHOULD_TEARDOWN: 18718 param->message_type = TDLS_SHOULD_TEARDOWN; 18719 break; 18720 case WMI_TDLS_PEER_DISCONNECTED: 18721 param->message_type = TDLS_PEER_DISCONNECTED; 18722 break; 18723 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18724 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18725 break; 18726 default: 18727 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18728 __func__, evt->peer_status); 18729 return QDF_STATUS_E_INVAL; 18730 }; 18731 18732 switch (evt->peer_reason) { 18733 case WMI_TDLS_TEARDOWN_REASON_TX: 18734 param->peer_reason = TDLS_TEARDOWN_TX; 18735 break; 18736 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18737 param->peer_reason = TDLS_TEARDOWN_RSSI; 18738 break; 18739 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18740 param->peer_reason = TDLS_TEARDOWN_SCAN; 18741 break; 18742 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18743 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18744 break; 18745 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18746 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18747 break; 18748 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18749 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18750 break; 18751 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18752 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18753 break; 18754 case WMI_TDLS_ENTER_BUF_STA: 18755 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18756 break; 18757 case WMI_TDLS_EXIT_BUF_STA: 18758 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18759 break; 18760 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18761 param->peer_reason = TDLS_ENTER_BT_BUSY; 18762 break; 18763 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18764 param->peer_reason = TDLS_EXIT_BT_BUSY; 18765 break; 18766 case WMI_TDLS_SCAN_STARTED_EVENT: 18767 param->peer_reason = TDLS_SCAN_STARTED; 18768 break; 18769 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18770 param->peer_reason = TDLS_SCAN_COMPLETED; 18771 break; 18772 18773 default: 18774 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18775 __func__, evt->peer_reason, evt->peer_status); 18776 return QDF_STATUS_E_INVAL; 18777 }; 18778 18779 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18780 __func__, param->peermac.bytes, param->message_type, 18781 param->peer_reason, param->vdev_id); 18782 18783 return QDF_STATUS_SUCCESS; 18784 } 18785 #endif 18786 18787 /** 18788 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18789 * @wmi_handle: wmi handle 18790 * @param evt_buf: pointer to event buffer 18791 * @param param: Pointer to hold MGMT TX completion params 18792 * 18793 * Return: QDF_STATUS_SUCCESS for success or error code 18794 */ 18795 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18796 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18797 { 18798 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18799 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18800 18801 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18802 evt_buf; 18803 if (!param_buf) { 18804 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18805 return QDF_STATUS_E_INVAL; 18806 } 18807 cmpl_params = param_buf->fixed_param; 18808 18809 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18810 cmpl_params->pdev_id); 18811 param->desc_id = cmpl_params->desc_id; 18812 param->status = cmpl_params->status; 18813 18814 return QDF_STATUS_SUCCESS; 18815 } 18816 18817 /** 18818 * extract_offchan_data_tx_compl_param_tlv() - 18819 * extract Offchan data tx completion event params 18820 * @wmi_handle: wmi handle 18821 * @param evt_buf: pointer to event buffer 18822 * @param param: Pointer to hold offchan data TX completion params 18823 * 18824 * Return: QDF_STATUS_SUCCESS for success or error code 18825 */ 18826 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18827 wmi_unified_t wmi_handle, void *evt_buf, 18828 struct wmi_host_offchan_data_tx_compl_event *param) 18829 { 18830 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18831 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18832 18833 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18834 evt_buf; 18835 if (!param_buf) { 18836 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18837 return QDF_STATUS_E_INVAL; 18838 } 18839 cmpl_params = param_buf->fixed_param; 18840 18841 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18842 cmpl_params->pdev_id); 18843 param->desc_id = cmpl_params->desc_id; 18844 param->status = cmpl_params->status; 18845 18846 return QDF_STATUS_SUCCESS; 18847 } 18848 18849 /** 18850 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18851 * status tlv 18852 * @wmi_handle: wmi handle 18853 * @param evt_buf: pointer to event buffer 18854 * @param param: Pointer to hold csa switch count status event param 18855 * 18856 * Return: QDF_STATUS_SUCCESS for success or error code 18857 */ 18858 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18859 wmi_unified_t wmi_handle, 18860 void *evt_buf, 18861 struct pdev_csa_switch_count_status *param) 18862 { 18863 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18864 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18865 18866 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18867 evt_buf; 18868 if (!param_buf) { 18869 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18870 return QDF_STATUS_E_INVAL; 18871 } 18872 18873 csa_status = param_buf->fixed_param; 18874 18875 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18876 csa_status->pdev_id); 18877 param->current_switch_count = csa_status->current_switch_count; 18878 param->num_vdevs = csa_status->num_vdevs; 18879 param->vdev_ids = param_buf->vdev_ids; 18880 18881 return QDF_STATUS_SUCCESS; 18882 } 18883 18884 /** 18885 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18886 * param from event 18887 * @wmi_handle: wmi handle 18888 * @param evt_buf: pointer to event buffer 18889 * @param param: Pointer to hold tpc configuration 18890 * 18891 * Return: 0 for success or error code 18892 */ 18893 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18894 void *evt_buf, 18895 wmi_host_pdev_tpc_config_event *param) 18896 { 18897 wmi_pdev_tpc_config_event_fixed_param *event = 18898 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18899 18900 if (!event) { 18901 WMI_LOGE("Invalid event buffer"); 18902 return QDF_STATUS_E_INVAL; 18903 } 18904 18905 param->pdev_id = event->pdev_id; 18906 param->regDomain = event->regDomain; 18907 param->chanFreq = event->chanFreq; 18908 param->phyMode = event->phyMode; 18909 param->twiceAntennaReduction = event->twiceAntennaReduction; 18910 param->twiceMaxRDPower = event->twiceMaxRDPower; 18911 param->powerLimit = event->powerLimit; 18912 param->rateMax = event->rateMax; 18913 param->numTxChain = event->numTxChain; 18914 param->ctl = event->ctl; 18915 param->flags = event->flags; 18916 18917 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18918 sizeof(param->maxRegAllowedPower)); 18919 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18920 event->maxRegAllowedPowerAGCDD, 18921 sizeof(param->maxRegAllowedPowerAGCDD)); 18922 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18923 event->maxRegAllowedPowerAGSTBC, 18924 sizeof(param->maxRegAllowedPowerAGSTBC)); 18925 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18926 event->maxRegAllowedPowerAGTXBF, 18927 sizeof(param->maxRegAllowedPowerAGTXBF)); 18928 WMI_LOGD("%s:extract success", __func__); 18929 18930 return QDF_STATUS_SUCCESS; 18931 } 18932 18933 /** 18934 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18935 * @wmi_handle: wmi handle 18936 * @param evt_buf: pointer to event buffer 18937 * @param num_vdevs: Pointer to hold num vdevs 18938 * 18939 * Return: QDF_STATUS_SUCCESS for success or error code 18940 */ 18941 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18942 void *evt_buf, uint32_t *num_vdevs) 18943 { 18944 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18945 wmi_host_swba_event_fixed_param *swba_event; 18946 uint32_t vdev_map; 18947 18948 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18949 if (!param_buf) { 18950 WMI_LOGE("Invalid swba event buffer"); 18951 return QDF_STATUS_E_INVAL; 18952 } 18953 18954 swba_event = param_buf->fixed_param; 18955 *num_vdevs = swba_event->num_vdevs; 18956 if (!(*num_vdevs)) { 18957 vdev_map = swba_event->vdev_map; 18958 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18959 } 18960 18961 return QDF_STATUS_SUCCESS; 18962 } 18963 18964 /** 18965 * extract_swba_tim_info_tlv() - extract swba tim info from event 18966 * @wmi_handle: wmi handle 18967 * @param evt_buf: pointer to event buffer 18968 * @param idx: Index to bcn info 18969 * @param tim_info: Pointer to hold tim info 18970 * 18971 * Return: QDF_STATUS_SUCCESS for success or error code 18972 */ 18973 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18974 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18975 { 18976 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18977 wmi_tim_info *tim_info_ev; 18978 18979 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18980 if (!param_buf) { 18981 WMI_LOGE("Invalid swba event buffer"); 18982 return QDF_STATUS_E_INVAL; 18983 } 18984 18985 tim_info_ev = ¶m_buf->tim_info[idx]; 18986 18987 tim_info->tim_len = tim_info_ev->tim_len; 18988 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18989 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18990 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18991 tim_info->tim_changed = tim_info_ev->tim_changed; 18992 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18993 tim_info->vdev_id = tim_info_ev->vdev_id; 18994 18995 return QDF_STATUS_SUCCESS; 18996 } 18997 18998 /** 18999 * extract_swba_noa_info_tlv() - extract swba NoA information from event 19000 * @wmi_handle: wmi handle 19001 * @param evt_buf: pointer to event buffer 19002 * @param idx: Index to bcn info 19003 * @param p2p_desc: Pointer to hold p2p NoA info 19004 * 19005 * Return: QDF_STATUS_SUCCESS for success or error code 19006 */ 19007 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 19008 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 19009 { 19010 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 19011 wmi_p2p_noa_info *p2p_noa_info; 19012 uint8_t i = 0; 19013 19014 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 19015 if (!param_buf) { 19016 WMI_LOGE("Invalid swba event buffer"); 19017 return QDF_STATUS_E_INVAL; 19018 } 19019 19020 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 19021 19022 p2p_desc->modified = false; 19023 p2p_desc->num_descriptors = 0; 19024 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 19025 p2p_desc->modified = true; 19026 p2p_desc->index = 19027 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 19028 p2p_desc->oppPS = 19029 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 19030 p2p_desc->ctwindow = 19031 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 19032 p2p_desc->num_descriptors = 19033 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 19034 (p2p_noa_info); 19035 for (i = 0; i < p2p_desc->num_descriptors; i++) { 19036 p2p_desc->noa_descriptors[i].type_count = 19037 (uint8_t) p2p_noa_info->noa_descriptors[i]. 19038 type_count; 19039 p2p_desc->noa_descriptors[i].duration = 19040 p2p_noa_info->noa_descriptors[i].duration; 19041 p2p_desc->noa_descriptors[i].interval = 19042 p2p_noa_info->noa_descriptors[i].interval; 19043 p2p_desc->noa_descriptors[i].start_time = 19044 p2p_noa_info->noa_descriptors[i].start_time; 19045 } 19046 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 19047 } 19048 19049 return QDF_STATUS_SUCCESS; 19050 } 19051 19052 #ifdef CONVERGED_P2P_ENABLE 19053 /** 19054 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 19055 * @wmi_handle: wmi handle 19056 * @param evt_buf: pointer to event buffer 19057 * @param param: Pointer to hold p2p noa info 19058 * 19059 * Return: QDF_STATUS_SUCCESS for success or error code 19060 */ 19061 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 19062 wmi_unified_t wmi_handle, void *evt_buf, 19063 struct p2p_noa_info *param) 19064 { 19065 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 19066 wmi_p2p_noa_event_fixed_param *fixed_param; 19067 uint8_t i; 19068 wmi_p2p_noa_info *wmi_noa_info; 19069 uint8_t *buf_ptr; 19070 uint32_t descriptors; 19071 19072 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 19073 if (!param_tlvs) { 19074 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 19075 return QDF_STATUS_E_INVAL; 19076 } 19077 19078 if (!param) { 19079 WMI_LOGE("noa information param is null"); 19080 return QDF_STATUS_E_INVAL; 19081 } 19082 19083 fixed_param = param_tlvs->fixed_param; 19084 buf_ptr = (uint8_t *) fixed_param; 19085 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 19086 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 19087 19088 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 19089 WMI_LOGE("%s: noa attr is not modified", __func__); 19090 return QDF_STATUS_E_INVAL; 19091 } 19092 19093 param->vdev_id = fixed_param->vdev_id; 19094 param->index = 19095 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 19096 param->opps_ps = 19097 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 19098 param->ct_window = 19099 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 19100 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 19101 param->num_desc = (uint8_t) descriptors; 19102 19103 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 19104 param->index, param->opps_ps, param->ct_window, 19105 param->num_desc); 19106 for (i = 0; i < param->num_desc; i++) { 19107 param->noa_desc[i].type_count = 19108 (uint8_t) wmi_noa_info->noa_descriptors[i]. 19109 type_count; 19110 param->noa_desc[i].duration = 19111 wmi_noa_info->noa_descriptors[i].duration; 19112 param->noa_desc[i].interval = 19113 wmi_noa_info->noa_descriptors[i].interval; 19114 param->noa_desc[i].start_time = 19115 wmi_noa_info->noa_descriptors[i].start_time; 19116 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 19117 __func__, i, param->noa_desc[i].type_count, 19118 param->noa_desc[i].duration, 19119 param->noa_desc[i].interval, 19120 param->noa_desc[i].start_time); 19121 } 19122 19123 return QDF_STATUS_SUCCESS; 19124 } 19125 19126 /** 19127 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 19128 * information from event 19129 * @wmi_handle: wmi handle 19130 * @param evt_buf: pointer to event buffer 19131 * @param param: Pointer to hold p2p lo stop event information 19132 * 19133 * Return: QDF_STATUS_SUCCESS for success or error code 19134 */ 19135 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 19136 wmi_unified_t wmi_handle, void *evt_buf, 19137 struct p2p_lo_event *param) 19138 { 19139 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 19140 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 19141 19142 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 19143 evt_buf; 19144 if (!param_tlvs) { 19145 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 19146 return QDF_STATUS_E_INVAL; 19147 } 19148 19149 if (!param) { 19150 WMI_LOGE("lo stop event param is null"); 19151 return QDF_STATUS_E_INVAL; 19152 } 19153 19154 lo_param = param_tlvs->fixed_param; 19155 param->vdev_id = lo_param->vdev_id; 19156 param->reason_code = lo_param->reason; 19157 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 19158 param->vdev_id, param->reason_code); 19159 19160 return QDF_STATUS_SUCCESS; 19161 } 19162 #endif /* End of CONVERGED_P2P_ENABLE */ 19163 19164 /** 19165 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 19166 * @wmi_handle: wmi handle 19167 * @param evt_buf: pointer to event buffer 19168 * @param ev: Pointer to hold peer param 19169 * 19170 * Return: QDF_STATUS_SUCCESS for success or error code 19171 */ 19172 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 19173 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 19174 { 19175 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 19176 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 19177 19178 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 19179 kickout_event = param_buf->fixed_param; 19180 19181 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 19182 ev->peer_macaddr); 19183 19184 ev->reason = kickout_event->reason; 19185 ev->rssi = kickout_event->rssi; 19186 19187 return QDF_STATUS_SUCCESS; 19188 } 19189 19190 /** 19191 * extract_all_stats_counts_tlv() - extract all stats count from event 19192 * @wmi_handle: wmi handle 19193 * @param evt_buf: pointer to event buffer 19194 * @param stats_param: Pointer to hold stats count 19195 * 19196 * Return: QDF_STATUS_SUCCESS for success or error code 19197 */ 19198 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 19199 void *evt_buf, wmi_host_stats_event *stats_param) 19200 { 19201 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19202 wmi_stats_event_fixed_param *ev; 19203 19204 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19205 19206 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19207 if (!ev) { 19208 WMI_LOGE("%s: Failed to alloc memory\n", __func__); 19209 return QDF_STATUS_E_FAILURE; 19210 } 19211 19212 switch (ev->stats_id) { 19213 case WMI_REQUEST_PEER_STAT: 19214 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 19215 break; 19216 19217 case WMI_REQUEST_AP_STAT: 19218 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 19219 break; 19220 19221 case WMI_REQUEST_PDEV_STAT: 19222 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 19223 break; 19224 19225 case WMI_REQUEST_VDEV_STAT: 19226 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 19227 break; 19228 19229 case WMI_REQUEST_BCNFLT_STAT: 19230 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 19231 break; 19232 19233 case WMI_REQUEST_VDEV_RATE_STAT: 19234 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 19235 break; 19236 19237 case WMI_REQUEST_BCN_STAT: 19238 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 19239 break; 19240 19241 default: 19242 stats_param->stats_id = 0; 19243 break; 19244 19245 } 19246 19247 stats_param->num_pdev_stats = ev->num_pdev_stats; 19248 stats_param->num_pdev_ext_stats = 0; 19249 stats_param->num_vdev_stats = ev->num_vdev_stats; 19250 stats_param->num_peer_stats = ev->num_peer_stats; 19251 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 19252 stats_param->num_chan_stats = ev->num_chan_stats; 19253 stats_param->num_bcn_stats = ev->num_bcn_stats; 19254 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19255 ev->pdev_id); 19256 19257 return QDF_STATUS_SUCCESS; 19258 } 19259 19260 /** 19261 * extract_pdev_tx_stats() - extract pdev tx stats from event 19262 */ 19263 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 19264 { 19265 /* Tx Stats */ 19266 tx->comp_queued = tx_stats->comp_queued; 19267 tx->comp_delivered = tx_stats->comp_delivered; 19268 tx->msdu_enqued = tx_stats->msdu_enqued; 19269 tx->mpdu_enqued = tx_stats->mpdu_enqued; 19270 tx->wmm_drop = tx_stats->wmm_drop; 19271 tx->local_enqued = tx_stats->local_enqued; 19272 tx->local_freed = tx_stats->local_freed; 19273 tx->hw_queued = tx_stats->hw_queued; 19274 tx->hw_reaped = tx_stats->hw_reaped; 19275 tx->underrun = tx_stats->underrun; 19276 tx->tx_abort = tx_stats->tx_abort; 19277 tx->mpdus_requed = tx_stats->mpdus_requed; 19278 tx->data_rc = tx_stats->data_rc; 19279 tx->self_triggers = tx_stats->self_triggers; 19280 tx->sw_retry_failure = tx_stats->sw_retry_failure; 19281 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 19282 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 19283 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 19284 tx->pdev_resets = tx_stats->pdev_resets; 19285 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 19286 tx->phy_underrun = tx_stats->phy_underrun; 19287 tx->txop_ovf = tx_stats->txop_ovf; 19288 19289 return; 19290 } 19291 19292 19293 /** 19294 * extract_pdev_rx_stats() - extract pdev rx stats from event 19295 */ 19296 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 19297 { 19298 /* Rx Stats */ 19299 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 19300 rx->status_rcvd = rx_stats->status_rcvd; 19301 rx->r0_frags = rx_stats->r0_frags; 19302 rx->r1_frags = rx_stats->r1_frags; 19303 rx->r2_frags = rx_stats->r2_frags; 19304 /* Only TLV */ 19305 rx->r3_frags = 0; 19306 rx->htt_msdus = rx_stats->htt_msdus; 19307 rx->htt_mpdus = rx_stats->htt_mpdus; 19308 rx->loc_msdus = rx_stats->loc_msdus; 19309 rx->loc_mpdus = rx_stats->loc_mpdus; 19310 rx->oversize_amsdu = rx_stats->oversize_amsdu; 19311 rx->phy_errs = rx_stats->phy_errs; 19312 rx->phy_err_drop = rx_stats->phy_err_drop; 19313 rx->mpdu_errs = rx_stats->mpdu_errs; 19314 19315 return; 19316 } 19317 19318 /** 19319 * extract_pdev_stats_tlv() - extract pdev stats from event 19320 * @wmi_handle: wmi handle 19321 * @param evt_buf: pointer to event buffer 19322 * @param index: Index into pdev stats 19323 * @param pdev_stats: Pointer to hold pdev stats 19324 * 19325 * Return: QDF_STATUS_SUCCESS for success or error code 19326 */ 19327 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 19328 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 19329 { 19330 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19331 wmi_stats_event_fixed_param *ev_param; 19332 uint8_t *data; 19333 19334 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19335 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19336 19337 data = param_buf->data; 19338 19339 if (index < ev_param->num_pdev_stats) { 19340 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 19341 (index * sizeof(wmi_pdev_stats))); 19342 19343 pdev_stats->chan_nf = ev->chan_nf; 19344 pdev_stats->tx_frame_count = ev->tx_frame_count; 19345 pdev_stats->rx_frame_count = ev->rx_frame_count; 19346 pdev_stats->rx_clear_count = ev->rx_clear_count; 19347 pdev_stats->cycle_count = ev->cycle_count; 19348 pdev_stats->phy_err_count = ev->phy_err_count; 19349 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 19350 19351 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 19352 &(ev->pdev_stats.tx)); 19353 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 19354 &(ev->pdev_stats.rx)); 19355 } 19356 19357 return QDF_STATUS_SUCCESS; 19358 } 19359 19360 /** 19361 * extract_unit_test_tlv() - extract unit test data 19362 * @wmi_handle: wmi handle 19363 * @param evt_buf: pointer to event buffer 19364 * @param unit_test: pointer to hold unit test data 19365 * @param maxspace: Amount of space in evt_buf 19366 * 19367 * Return: QDF_STATUS_SUCCESS for success or error code 19368 */ 19369 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 19370 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 19371 { 19372 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 19373 wmi_unit_test_event_fixed_param *ev_param; 19374 uint32_t num_bufp; 19375 uint32_t copy_size; 19376 uint8_t *bufp; 19377 19378 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 19379 ev_param = param_buf->fixed_param; 19380 bufp = param_buf->bufp; 19381 num_bufp = param_buf->num_bufp; 19382 unit_test->vdev_id = ev_param->vdev_id; 19383 unit_test->module_id = ev_param->module_id; 19384 unit_test->diag_token = ev_param->diag_token; 19385 unit_test->flag = ev_param->flag; 19386 unit_test->payload_len = ev_param->payload_len; 19387 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 19388 ev_param->vdev_id, 19389 ev_param->module_id, 19390 ev_param->diag_token, 19391 ev_param->flag); 19392 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 19393 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 19394 bufp, num_bufp); 19395 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 19396 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 19397 unit_test->buffer_len = copy_size; 19398 19399 return QDF_STATUS_SUCCESS; 19400 } 19401 19402 /** 19403 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 19404 * @wmi_handle: wmi handle 19405 * @param evt_buf: pointer to event buffer 19406 * @param index: Index into extended pdev stats 19407 * @param pdev_ext_stats: Pointer to hold extended pdev stats 19408 * 19409 * Return: QDF_STATUS_SUCCESS for success or error code 19410 */ 19411 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 19412 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 19413 { 19414 return QDF_STATUS_SUCCESS; 19415 } 19416 19417 /** 19418 * extract_vdev_stats_tlv() - extract vdev stats from event 19419 * @wmi_handle: wmi handle 19420 * @param evt_buf: pointer to event buffer 19421 * @param index: Index into vdev stats 19422 * @param vdev_stats: Pointer to hold vdev stats 19423 * 19424 * Return: QDF_STATUS_SUCCESS for success or error code 19425 */ 19426 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 19427 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 19428 { 19429 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19430 wmi_stats_event_fixed_param *ev_param; 19431 uint8_t *data; 19432 19433 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19434 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19435 data = (uint8_t *) param_buf->data; 19436 19437 if (index < ev_param->num_vdev_stats) { 19438 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 19439 ((ev_param->num_pdev_stats) * 19440 sizeof(wmi_pdev_stats)) + 19441 (index * sizeof(wmi_vdev_stats))); 19442 19443 vdev_stats->vdev_id = ev->vdev_id; 19444 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 19445 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 19446 19447 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 19448 sizeof(ev->tx_frm_cnt)); 19449 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 19450 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 19451 ev->multiple_retry_cnt, 19452 sizeof(ev->multiple_retry_cnt)); 19453 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 19454 sizeof(ev->fail_cnt)); 19455 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 19456 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 19457 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 19458 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 19459 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 19460 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 19461 sizeof(ev->tx_rate_history)); 19462 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 19463 sizeof(ev->bcn_rssi_history)); 19464 19465 } 19466 19467 return QDF_STATUS_SUCCESS; 19468 } 19469 19470 /** 19471 * extract_bcn_stats_tlv() - extract bcn stats from event 19472 * @wmi_handle: wmi handle 19473 * @param evt_buf: pointer to event buffer 19474 * @param index: Index into vdev stats 19475 * @param bcn_stats: Pointer to hold bcn stats 19476 * 19477 * Return: QDF_STATUS_SUCCESS for success or error code 19478 */ 19479 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 19480 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 19481 { 19482 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19483 wmi_stats_event_fixed_param *ev_param; 19484 uint8_t *data; 19485 19486 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19487 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19488 data = (uint8_t *) param_buf->data; 19489 19490 if (index < ev_param->num_bcn_stats) { 19491 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 19492 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19493 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19494 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19495 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 19496 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 19497 (index * sizeof(wmi_bcn_stats))); 19498 19499 bcn_stats->vdev_id = ev->vdev_id; 19500 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 19501 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 19502 } 19503 19504 return QDF_STATUS_SUCCESS; 19505 } 19506 19507 /** 19508 * extract_peer_stats_tlv() - extract peer stats from event 19509 * @wmi_handle: wmi handle 19510 * @param evt_buf: pointer to event buffer 19511 * @param index: Index into peer stats 19512 * @param peer_stats: Pointer to hold peer stats 19513 * 19514 * Return: QDF_STATUS_SUCCESS for success or error code 19515 */ 19516 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 19517 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 19518 { 19519 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19520 wmi_stats_event_fixed_param *ev_param; 19521 uint8_t *data; 19522 19523 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19524 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19525 data = (uint8_t *) param_buf->data; 19526 19527 if (index < ev_param->num_peer_stats) { 19528 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 19529 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19530 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19531 (index * sizeof(wmi_peer_stats))); 19532 19533 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19534 19535 OS_MEMCPY(&(peer_stats->peer_macaddr), 19536 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19537 19538 peer_stats->peer_rssi = ev->peer_rssi; 19539 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19540 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19541 } 19542 19543 return QDF_STATUS_SUCCESS; 19544 } 19545 19546 /** 19547 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19548 * @wmi_handle: wmi handle 19549 * @param evt_buf: pointer to event buffer 19550 * @param index: Index into bcn fault stats 19551 * @param bcnflt_stats: Pointer to hold bcn fault stats 19552 * 19553 * Return: QDF_STATUS_SUCCESS for success or error code 19554 */ 19555 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19556 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19557 { 19558 return QDF_STATUS_SUCCESS; 19559 } 19560 19561 /** 19562 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19563 * @wmi_handle: wmi handle 19564 * @param evt_buf: pointer to event buffer 19565 * @param index: Index into extended peer stats 19566 * @param peer_extd_stats: Pointer to hold extended peer stats 19567 * 19568 * Return: QDF_STATUS_SUCCESS for success or error code 19569 */ 19570 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19571 void *evt_buf, uint32_t index, 19572 wmi_host_peer_extd_stats *peer_extd_stats) 19573 { 19574 return QDF_STATUS_SUCCESS; 19575 } 19576 19577 /** 19578 * extract_chan_stats_tlv() - extract chan stats from event 19579 * @wmi_handle: wmi handle 19580 * @param evt_buf: pointer to event buffer 19581 * @param index: Index into chan stats 19582 * @param vdev_extd_stats: Pointer to hold chan stats 19583 * 19584 * Return: QDF_STATUS_SUCCESS for success or error code 19585 */ 19586 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19587 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19588 { 19589 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19590 wmi_stats_event_fixed_param *ev_param; 19591 uint8_t *data; 19592 19593 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19594 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19595 data = (uint8_t *) param_buf->data; 19596 19597 if (index < ev_param->num_chan_stats) { 19598 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19599 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19600 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19601 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19602 (index * sizeof(wmi_chan_stats))); 19603 19604 19605 /* Non-TLV doesnt have num_chan_stats */ 19606 chan_stats->chan_mhz = ev->chan_mhz; 19607 chan_stats->sampling_period_us = ev->sampling_period_us; 19608 chan_stats->rx_clear_count = ev->rx_clear_count; 19609 chan_stats->tx_duration_us = ev->tx_duration_us; 19610 chan_stats->rx_duration_us = ev->rx_duration_us; 19611 } 19612 19613 return QDF_STATUS_SUCCESS; 19614 } 19615 19616 /** 19617 * extract_profile_ctx_tlv() - extract profile context from event 19618 * @wmi_handle: wmi handle 19619 * @param evt_buf: pointer to event buffer 19620 * @idx: profile stats index to extract 19621 * @param profile_ctx: Pointer to hold profile context 19622 * 19623 * Return: QDF_STATUS_SUCCESS for success or error code 19624 */ 19625 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19626 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19627 { 19628 return QDF_STATUS_SUCCESS; 19629 } 19630 19631 /** 19632 * extract_profile_data_tlv() - extract profile data from event 19633 * @wmi_handle: wmi handle 19634 * @param evt_buf: pointer to event buffer 19635 * @param profile_data: Pointer to hold profile data 19636 * 19637 * Return: QDF_STATUS_SUCCESS for success or error code 19638 */ 19639 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19640 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19641 { 19642 19643 return QDF_STATUS_SUCCESS; 19644 } 19645 19646 /** 19647 * extract_chan_info_event_tlv() - extract chan information from event 19648 * @wmi_handle: wmi handle 19649 * @param evt_buf: pointer to event buffer 19650 * @param chan_info: Pointer to hold chan information 19651 * 19652 * Return: QDF_STATUS_SUCCESS for success or error code 19653 */ 19654 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19655 void *evt_buf, wmi_host_chan_info_event *chan_info) 19656 { 19657 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19658 wmi_chan_info_event_fixed_param *ev; 19659 19660 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19661 19662 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19663 if (!ev) { 19664 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19665 return QDF_STATUS_E_FAILURE; 19666 } 19667 19668 chan_info->err_code = ev->err_code; 19669 chan_info->freq = ev->freq; 19670 chan_info->cmd_flags = ev->cmd_flags; 19671 chan_info->noise_floor = ev->noise_floor; 19672 chan_info->rx_clear_count = ev->rx_clear_count; 19673 chan_info->cycle_count = ev->cycle_count; 19674 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19675 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19676 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19677 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19678 ev->vdev_id, WLAN_SCAN_ID); 19679 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19680 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19681 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19682 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19683 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19684 chan_info->rx_frame_count = ev->rx_frame_count; 19685 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19686 chan_info->vdev_id = ev->vdev_id; 19687 19688 return QDF_STATUS_SUCCESS; 19689 } 19690 19691 /** 19692 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19693 * @wmi_handle: WMI handle 19694 * @param evt_buf: Pointer to event buffer 19695 * @param param: Pointer to hold data 19696 * 19697 * Return : QDF_STATUS_SUCCESS for success or error code 19698 */ 19699 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19700 uint8_t *evt_buf, 19701 struct wmi_host_pdev_utf_event *event) 19702 { 19703 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19704 struct wmi_host_utf_seg_header_info *seg_hdr; 19705 19706 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19707 event->data = param_buf->data; 19708 event->datalen = param_buf->num_data; 19709 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19710 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19711 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19712 seg_hdr->pdev_id); 19713 19714 return QDF_STATUS_SUCCESS; 19715 } 19716 19717 /** 19718 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19719 * @wmi_handle: wmi handle 19720 * @param evt_buf: pointer to event buffer 19721 * @param param: Pointer to hold evt buf 19722 * 19723 * Return: QDF_STATUS_SUCCESS for success or error code 19724 */ 19725 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19726 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19727 { 19728 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19729 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19730 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19731 uint8_t i = 0, j = 0; 19732 19733 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19734 if (!param_buf) 19735 return QDF_STATUS_E_INVAL; 19736 19737 hw_caps = param_buf->soc_hw_mode_caps; 19738 if (!hw_caps) 19739 return QDF_STATUS_E_INVAL; 19740 19741 if (!hw_caps->num_chainmask_tables) 19742 return QDF_STATUS_E_INVAL; 19743 19744 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19745 19746 if (chainmask_caps == NULL) 19747 return QDF_STATUS_E_INVAL; 19748 19749 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19750 19751 qdf_print("Dumping chain mask combo data for table : %d\n", i); 19752 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19753 19754 chainmask_table[i].cap_list[j].chainmask = 19755 chainmask_caps->chainmask; 19756 19757 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19758 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19759 19760 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19761 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19762 19763 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19764 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19765 19766 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19767 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19768 19769 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19770 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19771 19772 chainmask_table[i].cap_list[j].chain_mask_2G = 19773 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19774 19775 chainmask_table[i].cap_list[j].chain_mask_5G = 19776 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19777 19778 chainmask_table[i].cap_list[j].chain_mask_tx = 19779 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19780 19781 chainmask_table[i].cap_list[j].chain_mask_rx = 19782 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19783 19784 chainmask_table[i].cap_list[j].supports_aDFS = 19785 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19786 19787 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x\n", 19788 chainmask_caps->supported_flags, 19789 chainmask_caps->chainmask 19790 ); 19791 chainmask_caps++; 19792 } 19793 } 19794 19795 return QDF_STATUS_SUCCESS; 19796 } 19797 19798 /** 19799 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19800 * from event 19801 * @wmi_handle: wmi handle 19802 * @param evt_buf: pointer to event buffer 19803 * @param param: Pointer to hold evt buf 19804 * 19805 * Return: QDF_STATUS_SUCCESS for success or error code 19806 */ 19807 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19808 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19809 { 19810 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19811 wmi_service_ready_ext_event_fixed_param *ev; 19812 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19813 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19814 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19815 uint8_t i = 0; 19816 19817 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19818 if (!param_buf) 19819 return QDF_STATUS_E_INVAL; 19820 19821 ev = param_buf->fixed_param; 19822 if (!ev) 19823 return QDF_STATUS_E_INVAL; 19824 19825 /* Move this to host based bitmap */ 19826 param->default_conc_scan_config_bits = 19827 ev->default_conc_scan_config_bits; 19828 param->default_fw_config_bits = ev->default_fw_config_bits; 19829 param->he_cap_info = ev->he_cap_info; 19830 param->mpdu_density = ev->mpdu_density; 19831 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19832 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19833 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19834 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19835 19836 hw_caps = param_buf->soc_hw_mode_caps; 19837 if (hw_caps) 19838 param->num_hw_modes = hw_caps->num_hw_modes; 19839 else 19840 param->num_hw_modes = 0; 19841 19842 reg_caps = param_buf->soc_hal_reg_caps; 19843 if (reg_caps) 19844 param->num_phy = reg_caps->num_phy; 19845 else 19846 param->num_phy = 0; 19847 19848 if (hw_caps) { 19849 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19850 qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables); 19851 } else 19852 param->num_chainmask_tables = 0; 19853 19854 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19855 19856 if (chain_mask_combo == NULL) 19857 return QDF_STATUS_SUCCESS; 19858 19859 qdf_print("Dumping chain mask combo data\n"); 19860 19861 for (i = 0; i < param->num_chainmask_tables; i++) { 19862 19863 qdf_print("table_id : %d Num valid chainmasks: %d\n", 19864 chain_mask_combo->chainmask_table_id, 19865 chain_mask_combo->num_valid_chainmask 19866 ); 19867 19868 param->chainmask_table[i].table_id = 19869 chain_mask_combo->chainmask_table_id; 19870 param->chainmask_table[i].num_valid_chainmasks = 19871 chain_mask_combo->num_valid_chainmask; 19872 chain_mask_combo++; 19873 } 19874 qdf_print("chain mask combo end\n"); 19875 19876 return QDF_STATUS_SUCCESS; 19877 } 19878 19879 /** 19880 * extract_hw_mode_cap_service_ready_ext_tlv() - 19881 * extract HW mode cap from service ready event 19882 * @wmi_handle: wmi handle 19883 * @param evt_buf: pointer to event buffer 19884 * @param param: Pointer to hold evt buf 19885 * @param hw_mode_idx: hw mode idx should be less than num_mode 19886 * 19887 * Return: QDF_STATUS_SUCCESS for success or error code 19888 */ 19889 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19890 wmi_unified_t wmi_handle, 19891 uint8_t *event, uint8_t hw_mode_idx, 19892 struct wlan_psoc_host_hw_mode_caps *param) 19893 { 19894 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19895 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19896 19897 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19898 if (!param_buf) 19899 return QDF_STATUS_E_INVAL; 19900 19901 hw_caps = param_buf->soc_hw_mode_caps; 19902 if (!hw_caps) 19903 return QDF_STATUS_E_INVAL; 19904 19905 if (hw_mode_idx >= hw_caps->num_hw_modes) 19906 return QDF_STATUS_E_INVAL; 19907 19908 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19909 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19910 19911 param->hw_mode_config_type = 19912 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19913 19914 return QDF_STATUS_SUCCESS; 19915 } 19916 19917 /** 19918 * extract_mac_phy_cap_service_ready_ext_tlv() - 19919 * extract MAC phy cap from service ready event 19920 * @wmi_handle: wmi handle 19921 * @param evt_buf: pointer to event buffer 19922 * @param param: Pointer to hold evt buf 19923 * @param hw_mode_idx: hw mode idx should be less than num_mode 19924 * @param phy_id: phy id within hw_mode 19925 * 19926 * Return: QDF_STATUS_SUCCESS for success or error code 19927 */ 19928 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19929 wmi_unified_t wmi_handle, 19930 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19931 struct wlan_psoc_host_mac_phy_caps *param) 19932 { 19933 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19934 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19935 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19936 uint32_t phy_map; 19937 uint8_t hw_idx, phy_idx = 0; 19938 19939 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19940 if (!param_buf) 19941 return QDF_STATUS_E_INVAL; 19942 19943 hw_caps = param_buf->soc_hw_mode_caps; 19944 if (!hw_caps) 19945 return QDF_STATUS_E_INVAL; 19946 19947 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19948 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19949 break; 19950 19951 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19952 while (phy_map) { 19953 phy_map >>= 1; 19954 phy_idx++; 19955 } 19956 } 19957 19958 if (hw_idx == hw_caps->num_hw_modes) 19959 return QDF_STATUS_E_INVAL; 19960 19961 phy_idx += phy_id; 19962 if (phy_idx >= param_buf->num_mac_phy_caps) 19963 return QDF_STATUS_E_INVAL; 19964 19965 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19966 19967 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19968 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19969 mac_phy_caps->pdev_id); 19970 param->phy_id = mac_phy_caps->phy_id; 19971 param->supports_11b = 19972 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19973 param->supports_11g = 19974 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19975 param->supports_11a = 19976 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19977 param->supports_11n = 19978 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19979 param->supports_11ac = 19980 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19981 param->supports_11ax = 19982 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19983 19984 param->supported_bands = mac_phy_caps->supported_bands; 19985 param->ampdu_density = mac_phy_caps->ampdu_density; 19986 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19987 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19988 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19989 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19990 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 19991 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19992 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19993 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19994 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19995 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19996 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19997 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19998 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 19999 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 20000 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 20001 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 20002 qdf_mem_copy(¶m->he_cap_phy_info_2G, 20003 &mac_phy_caps->he_cap_phy_info_2G, 20004 sizeof(param->he_cap_phy_info_2G)); 20005 qdf_mem_copy(¶m->he_cap_phy_info_5G, 20006 &mac_phy_caps->he_cap_phy_info_5G, 20007 sizeof(param->he_cap_phy_info_5G)); 20008 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 20009 sizeof(param->he_ppet2G)); 20010 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 20011 sizeof(param->he_ppet5G)); 20012 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 20013 20014 return QDF_STATUS_SUCCESS; 20015 } 20016 20017 /** 20018 * extract_reg_cap_service_ready_ext_tlv() - 20019 * extract REG cap from service ready event 20020 * @wmi_handle: wmi handle 20021 * @param evt_buf: pointer to event buffer 20022 * @param param: Pointer to hold evt buf 20023 * @param phy_idx: phy idx should be less than num_mode 20024 * 20025 * Return: QDF_STATUS_SUCCESS for success or error code 20026 */ 20027 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 20028 wmi_unified_t wmi_handle, 20029 uint8_t *event, uint8_t phy_idx, 20030 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 20031 { 20032 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20033 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 20034 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 20035 20036 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 20037 if (!param_buf) 20038 return QDF_STATUS_E_INVAL; 20039 20040 reg_caps = param_buf->soc_hal_reg_caps; 20041 if (!reg_caps) 20042 return QDF_STATUS_E_INVAL; 20043 20044 if (phy_idx >= reg_caps->num_phy) 20045 return QDF_STATUS_E_INVAL; 20046 20047 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 20048 20049 param->phy_id = ext_reg_cap->phy_id; 20050 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 20051 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 20052 param->regcap1 = ext_reg_cap->regcap1; 20053 param->regcap2 = ext_reg_cap->regcap2; 20054 param->wireless_modes = convert_wireless_modes_tlv( 20055 ext_reg_cap->wireless_modes); 20056 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 20057 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 20058 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 20059 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 20060 20061 return QDF_STATUS_SUCCESS; 20062 } 20063 20064 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 20065 wmi_unified_t wmi_handle, 20066 uint8_t *event, uint8_t idx, 20067 struct wlan_psoc_host_dbr_ring_caps *param) 20068 { 20069 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20070 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 20071 20072 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 20073 if (!param_buf) 20074 return QDF_STATUS_E_INVAL; 20075 20076 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 20077 20078 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20079 dbr_ring_caps->pdev_id); 20080 param->mod_id = dbr_ring_caps->mod_id; 20081 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 20082 param->min_buf_size = dbr_ring_caps->min_buf_size; 20083 param->min_buf_align = dbr_ring_caps->min_buf_align; 20084 20085 return QDF_STATUS_SUCCESS; 20086 } 20087 20088 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 20089 uint8_t *event, struct direct_buf_rx_rsp *param) 20090 { 20091 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20092 wmi_dma_buf_release_fixed_param *ev; 20093 20094 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20095 if (!param_buf) 20096 return QDF_STATUS_E_INVAL; 20097 20098 ev = param_buf->fixed_param; 20099 if (!ev) 20100 return QDF_STATUS_E_INVAL; 20101 20102 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20103 ev->pdev_id); 20104 param->mod_id = ev->mod_id; 20105 param->num_buf_release_entry = ev->num_buf_release_entry; 20106 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 20107 param->pdev_id, param->mod_id, param->num_buf_release_entry); 20108 20109 return QDF_STATUS_SUCCESS; 20110 } 20111 20112 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 20113 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 20114 { 20115 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20116 wmi_dma_buf_release_entry *entry; 20117 20118 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20119 if (!param_buf) 20120 return QDF_STATUS_E_INVAL; 20121 20122 entry = ¶m_buf->entries[idx]; 20123 20124 if (!entry) { 20125 WMI_LOGE("%s: Entry is NULL\n", __func__); 20126 return QDF_STATUS_E_FAILURE; 20127 } 20128 20129 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 20130 20131 param->paddr_lo = entry->paddr_lo; 20132 param->paddr_hi = entry->paddr_hi; 20133 20134 return QDF_STATUS_SUCCESS; 20135 } 20136 20137 /** 20138 * extract_dcs_interference_type_tlv() - extract dcs interference type 20139 * from event 20140 * @wmi_handle: wmi handle 20141 * @param evt_buf: pointer to event buffer 20142 * @param param: Pointer to hold dcs interference param 20143 * 20144 * Return: 0 for success or error code 20145 */ 20146 static QDF_STATUS extract_dcs_interference_type_tlv( 20147 wmi_unified_t wmi_handle, 20148 void *evt_buf, struct wmi_host_dcs_interference_param *param) 20149 { 20150 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20151 20152 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20153 if (!param_buf) 20154 return QDF_STATUS_E_INVAL; 20155 20156 param->interference_type = param_buf->fixed_param->interference_type; 20157 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20158 param_buf->fixed_param->pdev_id); 20159 20160 return QDF_STATUS_SUCCESS; 20161 } 20162 20163 /* 20164 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 20165 * @wmi_handle: wmi handle 20166 * @param evt_buf: pointer to event buffer 20167 * @param cw_int: Pointer to hold cw interference 20168 * 20169 * Return: 0 for success or error code 20170 */ 20171 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 20172 void *evt_buf, 20173 wmi_host_ath_dcs_cw_int *cw_int) 20174 { 20175 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20176 wlan_dcs_cw_int *ev; 20177 20178 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20179 if (!param_buf) 20180 return QDF_STATUS_E_INVAL; 20181 20182 ev = param_buf->cw_int; 20183 20184 cw_int->channel = ev->channel; 20185 20186 return QDF_STATUS_SUCCESS; 20187 } 20188 20189 /** 20190 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 20191 * @wmi_handle: wmi handle 20192 * @param evt_buf: pointer to event buffer 20193 * @param wlan_stat: Pointer to hold wlan stats 20194 * 20195 * Return: 0 for success or error code 20196 */ 20197 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 20198 void *evt_buf, 20199 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 20200 { 20201 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20202 wlan_dcs_im_tgt_stats_t *ev; 20203 20204 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20205 if (!param_buf) 20206 return QDF_STATUS_E_INVAL; 20207 20208 ev = param_buf->wlan_stat; 20209 wlan_stat->reg_tsf32 = ev->reg_tsf32; 20210 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 20211 wlan_stat->tx_waste_time = ev->tx_waste_time; 20212 wlan_stat->rx_time = ev->rx_time; 20213 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 20214 wlan_stat->mib_stats.listen_time = ev->listen_time; 20215 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 20216 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 20217 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 20218 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 20219 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 20220 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 20221 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 20222 wlan_stat->chan_nf = ev->chan_nf; 20223 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 20224 20225 return QDF_STATUS_SUCCESS; 20226 } 20227 20228 /** 20229 * extract_thermal_stats_tlv() - extract thermal stats from event 20230 * @wmi_handle: wmi handle 20231 * @param evt_buf: Pointer to event buffer 20232 * @param temp: Pointer to hold extracted temperature 20233 * @param level: Pointer to hold extracted level 20234 * 20235 * Return: 0 for success or error code 20236 */ 20237 static QDF_STATUS 20238 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 20239 void *evt_buf, uint32_t *temp, 20240 uint32_t *level, uint32_t *pdev_id) 20241 { 20242 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20243 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 20244 20245 param_buf = 20246 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20247 if (!param_buf) 20248 return QDF_STATUS_E_INVAL; 20249 20250 tt_stats_event = param_buf->fixed_param; 20251 20252 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20253 tt_stats_event->pdev_id); 20254 *temp = tt_stats_event->temp; 20255 *level = tt_stats_event->level; 20256 20257 return QDF_STATUS_SUCCESS; 20258 } 20259 20260 /** 20261 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 20262 * @wmi_handle: wmi handle 20263 * @param evt_buf: pointer to event buffer 20264 * @param idx: Index to level stats 20265 * @param levelcount: Pointer to hold levelcount 20266 * @param dccount: Pointer to hold dccount 20267 * 20268 * Return: 0 for success or error code 20269 */ 20270 static QDF_STATUS 20271 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 20272 void *evt_buf, uint8_t idx, uint32_t *levelcount, 20273 uint32_t *dccount) 20274 { 20275 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20276 wmi_therm_throt_level_stats_info *tt_level_info; 20277 20278 param_buf = 20279 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20280 if (!param_buf) 20281 return QDF_STATUS_E_INVAL; 20282 20283 tt_level_info = param_buf->therm_throt_level_stats_info; 20284 20285 if (idx < THERMAL_LEVELS) { 20286 *levelcount = tt_level_info[idx].level_count; 20287 *dccount = tt_level_info[idx].dc_count; 20288 return QDF_STATUS_SUCCESS; 20289 } 20290 20291 return QDF_STATUS_E_FAILURE; 20292 } 20293 #ifdef BIG_ENDIAN_HOST 20294 /** 20295 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 20296 * @param data_len - data length 20297 * @param data - pointer to data 20298 * 20299 * Return: QDF_STATUS - success or error status 20300 */ 20301 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20302 { 20303 uint8_t *data_aligned = NULL; 20304 int c; 20305 unsigned char *data_unaligned; 20306 20307 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 20308 FIPS_ALIGN)); 20309 /* Assigning unaligned space to copy the data */ 20310 /* Checking if kmalloc does succesful allocation */ 20311 if (data_unaligned == NULL) 20312 return QDF_STATUS_E_FAILURE; 20313 20314 /* Checking if space is alligned */ 20315 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 20316 /* align the data space */ 20317 data_aligned = 20318 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 20319 } else { 20320 data_aligned = (u_int8_t *)data_unaligned; 20321 } 20322 20323 /* memset and copy content from data to data aligned */ 20324 OS_MEMSET(data_aligned, 0, data_len); 20325 OS_MEMCPY(data_aligned, data, data_len); 20326 /* Endianness to LE */ 20327 for (c = 0; c < data_len/4; c++) { 20328 *((u_int32_t *)data_aligned + c) = 20329 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 20330 } 20331 20332 /* Copy content to event->data */ 20333 OS_MEMCPY(data, data_aligned, data_len); 20334 20335 /* clean up allocated space */ 20336 qdf_mem_free(data_unaligned); 20337 data_aligned = NULL; 20338 data_unaligned = NULL; 20339 20340 /*************************************************************/ 20341 20342 return QDF_STATUS_SUCCESS; 20343 } 20344 #else 20345 /** 20346 * fips_conv_data_be() - DUMMY for LE platform 20347 * 20348 * Return: QDF_STATUS - success 20349 */ 20350 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20351 { 20352 return QDF_STATUS_SUCCESS; 20353 } 20354 #endif 20355 20356 /** 20357 * extract_fips_event_data_tlv() - extract fips event data 20358 * @wmi_handle: wmi handle 20359 * @param evt_buf: pointer to event buffer 20360 * @param param: pointer FIPS event params 20361 * 20362 * Return: 0 for success or error code 20363 */ 20364 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 20365 void *evt_buf, struct wmi_host_fips_event_param *param) 20366 { 20367 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 20368 wmi_pdev_fips_event_fixed_param *event; 20369 20370 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 20371 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 20372 20373 if (fips_conv_data_be(event->data_len, param_buf->data) != 20374 QDF_STATUS_SUCCESS) 20375 return QDF_STATUS_E_FAILURE; 20376 20377 param->data = (uint32_t *)param_buf->data; 20378 param->data_len = event->data_len; 20379 param->error_status = event->error_status; 20380 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20381 event->pdev_id); 20382 20383 return QDF_STATUS_SUCCESS; 20384 } 20385 20386 /* 20387 * extract_peer_delete_response_event_tlv() - extract peer delete response event 20388 * @wmi_handle: wmi handle 20389 * @param evt_buf: pointer to event buffer 20390 * @param vdev_id: Pointer to hold vdev_id 20391 * @param mac_addr: Pointer to hold peer mac address 20392 * 20393 * Return: QDF_STATUS_SUCCESS for success or error code 20394 */ 20395 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 20396 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 20397 { 20398 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 20399 wmi_peer_delete_resp_event_fixed_param *ev; 20400 20401 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 20402 20403 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 20404 if (!ev) { 20405 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 20406 return QDF_STATUS_E_FAILURE; 20407 } 20408 20409 param->vdev_id = ev->vdev_id; 20410 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 20411 ¶m->mac_address.bytes[0]); 20412 20413 return QDF_STATUS_SUCCESS; 20414 } 20415 20416 static bool is_management_record_tlv(uint32_t cmd_id) 20417 { 20418 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 20419 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 20420 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 20421 return true; 20422 } 20423 20424 return false; 20425 } 20426 20427 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20428 { 20429 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 20430 20431 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20432 20433 switch (set_cmd->param_id) { 20434 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 20435 case WMI_VDEV_PARAM_DTIM_POLICY: 20436 return HTC_TX_PACKET_TAG_AUTO_PM; 20437 default: 20438 break; 20439 } 20440 20441 return 0; 20442 } 20443 20444 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20445 { 20446 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 20447 20448 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 20449 20450 switch (ps_cmd->param) { 20451 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 20452 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 20453 case WMI_STA_PS_ENABLE_QPOWER: 20454 return HTC_TX_PACKET_TAG_AUTO_PM; 20455 default: 20456 break; 20457 } 20458 20459 return 0; 20460 } 20461 20462 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 20463 uint32_t cmd_id) 20464 { 20465 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 20466 return 0; 20467 20468 switch (cmd_id) { 20469 case WMI_VDEV_SET_PARAM_CMDID: 20470 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 20471 case WMI_STA_POWERSAVE_PARAM_CMDID: 20472 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 20473 default: 20474 break; 20475 } 20476 20477 return 0; 20478 } 20479 20480 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20481 { 20482 uint16_t tag = 0; 20483 20484 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20485 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20486 __func__); 20487 return tag; 20488 } 20489 20490 if (wmi_handle->tag_crash_inject) 20491 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20492 20493 wmi_handle->tag_crash_inject = false; 20494 return tag; 20495 } 20496 20497 /** 20498 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20499 * @wmi_handle: WMI handle 20500 * @buf: WMI buffer 20501 * @cmd_id: WMI command Id 20502 * 20503 * Return htc_tx_tag 20504 */ 20505 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20506 wmi_buf_t buf, 20507 uint32_t cmd_id) 20508 { 20509 uint16_t htc_tx_tag = 0; 20510 20511 switch (cmd_id) { 20512 case WMI_WOW_ENABLE_CMDID: 20513 case WMI_PDEV_SUSPEND_CMDID: 20514 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20515 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20516 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20517 case WMI_PDEV_RESUME_CMDID: 20518 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20519 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20520 #ifdef FEATURE_WLAN_D0WOW 20521 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20522 #endif 20523 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20524 break; 20525 case WMI_FORCE_FW_HANG_CMDID: 20526 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20527 break; 20528 case WMI_VDEV_SET_PARAM_CMDID: 20529 case WMI_STA_POWERSAVE_PARAM_CMDID: 20530 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20531 default: 20532 break; 20533 } 20534 20535 return htc_tx_tag; 20536 } 20537 20538 /** 20539 * extract_channel_hopping_event_tlv() - extract channel hopping param 20540 * from event 20541 * @wmi_handle: wmi handle 20542 * @param evt_buf: pointer to event buffer 20543 * @param ch_hopping: Pointer to hold channel hopping param 20544 * 20545 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20546 */ 20547 static QDF_STATUS extract_channel_hopping_event_tlv( 20548 wmi_unified_t wmi_handle, void *evt_buf, 20549 wmi_host_pdev_channel_hopping_event *ch_hopping) 20550 { 20551 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20552 wmi_pdev_channel_hopping_event_fixed_param *event; 20553 20554 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20555 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20556 param_buf->fixed_param; 20557 20558 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20559 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20560 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20561 event->pdev_id); 20562 20563 return QDF_STATUS_SUCCESS; 20564 } 20565 20566 /** 20567 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20568 * @wmi_handle: wmi handle 20569 * @param evt_buf: pointer to event buffer 20570 * @param param: Pointer to hold tpc param 20571 * 20572 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20573 */ 20574 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20575 void *evt_buf, 20576 wmi_host_pdev_tpc_event *param) 20577 { 20578 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20579 wmi_pdev_tpc_event_fixed_param *event; 20580 20581 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20582 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20583 20584 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20585 event->pdev_id); 20586 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20587 20588 return QDF_STATUS_SUCCESS; 20589 } 20590 20591 /** 20592 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20593 * power param from event 20594 * @wmi_handle: wmi handle 20595 * @param evt_buf: pointer to event buffer 20596 * @param param: Pointer to hold nf cal power param 20597 * 20598 * Return: 0 for success or error code 20599 */ 20600 static QDF_STATUS 20601 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20602 void *evt_buf, 20603 wmi_host_pdev_nfcal_power_all_channels_event *param) 20604 { 20605 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20606 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20607 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20608 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20609 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20610 uint32_t i; 20611 20612 param_buf = 20613 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20614 event = param_buf->fixed_param; 20615 ch_nfdbr = param_buf->nfdbr; 20616 ch_nfdbm = param_buf->nfdbm; 20617 ch_freqnum = param_buf->freqnum; 20618 20619 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20620 event->pdev_id, param_buf->num_nfdbr, 20621 param_buf->num_nfdbm, param_buf->num_freqnum); 20622 20623 if (param_buf->num_nfdbr > 20624 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20625 WMI_LOGE("invalid number of nfdBr"); 20626 return QDF_STATUS_E_FAILURE; 20627 } 20628 20629 if (param_buf->num_nfdbm > 20630 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20631 WMI_LOGE("invalid number of nfdBm"); 20632 return QDF_STATUS_E_FAILURE; 20633 } 20634 20635 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20636 WMI_LOGE("invalid number of freqNum"); 20637 return QDF_STATUS_E_FAILURE; 20638 } 20639 20640 for (i = 0; i < param_buf->num_nfdbr; i++) { 20641 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20642 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20643 ch_nfdbr++; 20644 ch_nfdbm++; 20645 } 20646 20647 for (i = 0; i < param_buf->num_freqnum; i++) { 20648 param->freqnum[i] = ch_freqnum->freqNum; 20649 ch_freqnum++; 20650 } 20651 20652 param->pdev_id = event->pdev_id; 20653 20654 return QDF_STATUS_SUCCESS; 20655 } 20656 20657 20658 #ifdef BIG_ENDIAN_HOST 20659 /** 20660 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20661 * @param data_len - data length 20662 * @param data - pointer to data 20663 * 20664 * Return: QDF_STATUS - success or error status 20665 */ 20666 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20667 { 20668 uint8_t *datap = (uint8_t *)ev; 20669 int i; 20670 /* Skip swapping the first word */ 20671 datap += sizeof(uint32_t); 20672 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20673 i++, datap += sizeof(uint32_t)) { 20674 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20675 } 20676 20677 return QDF_STATUS_SUCCESS; 20678 } 20679 #else 20680 /** 20681 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20682 * @param data_len - data length 20683 * @param data - pointer to data 20684 * 20685 * Return: QDF_STATUS - success or error status 20686 */ 20687 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20688 { 20689 return QDF_STATUS_SUCCESS; 20690 } 20691 #endif 20692 20693 /** 20694 * extract_wds_addr_event_tlv() - extract wds address from event 20695 * @wmi_handle: wmi handle 20696 * @param evt_buf: pointer to event buffer 20697 * @param wds_ev: Pointer to hold wds address 20698 * 20699 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20700 */ 20701 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20702 void *evt_buf, 20703 uint16_t len, wds_addr_event_t *wds_ev) 20704 { 20705 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20706 wmi_wds_addr_event_fixed_param *ev; 20707 int i; 20708 20709 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20710 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20711 20712 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20713 return QDF_STATUS_E_FAILURE; 20714 20715 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20716 sizeof(wds_ev->event_type)); 20717 for (i = 0; i < 4; i++) { 20718 wds_ev->peer_mac[i] = 20719 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20720 wds_ev->dest_mac[i] = 20721 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20722 } 20723 for (i = 0; i < 2; i++) { 20724 wds_ev->peer_mac[4+i] = 20725 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20726 wds_ev->dest_mac[4+i] = 20727 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20728 } 20729 return QDF_STATUS_SUCCESS; 20730 } 20731 20732 /** 20733 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20734 * from event 20735 * @wmi_handle: wmi handle 20736 * @param evt_buf: pointer to event buffer 20737 * @param ev: Pointer to hold peer param and ps state 20738 * 20739 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20740 */ 20741 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20742 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20743 { 20744 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20745 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20746 20747 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20748 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20749 param_buf->fixed_param; 20750 20751 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20752 ev->peer_ps_state = event->peer_ps_state; 20753 20754 return QDF_STATUS_SUCCESS; 20755 } 20756 20757 /** 20758 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20759 * @wmi_handle: wmi handle 20760 * @param evt_buf: pointer to event buffer 20761 * @param inst_rssi_resp: Pointer to hold inst rssi response 20762 * 20763 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20764 */ 20765 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20766 wmi_unified_t wmi_handle, void *evt_buf, 20767 wmi_host_inst_stats_resp *inst_rssi_resp) 20768 { 20769 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20770 wmi_inst_rssi_stats_resp_fixed_param *event; 20771 20772 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20773 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20774 20775 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20776 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20777 inst_rssi_resp->iRSSI = event->iRSSI; 20778 20779 return QDF_STATUS_SUCCESS; 20780 } 20781 20782 static struct cur_reg_rule 20783 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20784 wmi_regulatory_rule_struct *wmi_reg_rule) 20785 { 20786 struct cur_reg_rule *reg_rule_ptr; 20787 uint32_t count; 20788 20789 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20790 20791 if (NULL == reg_rule_ptr) { 20792 WMI_LOGE("memory allocation failure"); 20793 return NULL; 20794 } 20795 20796 for (count = 0; count < num_reg_rules; count++) { 20797 reg_rule_ptr[count].start_freq = 20798 WMI_REG_RULE_START_FREQ_GET( 20799 wmi_reg_rule[count].freq_info); 20800 reg_rule_ptr[count].end_freq = 20801 WMI_REG_RULE_END_FREQ_GET( 20802 wmi_reg_rule[count].freq_info); 20803 reg_rule_ptr[count].max_bw = 20804 WMI_REG_RULE_MAX_BW_GET( 20805 wmi_reg_rule[count].bw_pwr_info); 20806 reg_rule_ptr[count].reg_power = 20807 WMI_REG_RULE_REG_POWER_GET( 20808 wmi_reg_rule[count].bw_pwr_info); 20809 reg_rule_ptr[count].ant_gain = 20810 WMI_REG_RULE_ANTENNA_GAIN_GET( 20811 wmi_reg_rule[count].bw_pwr_info); 20812 reg_rule_ptr[count].flags = 20813 WMI_REG_RULE_FLAGS_GET( 20814 wmi_reg_rule[count].flag_info); 20815 } 20816 20817 return reg_rule_ptr; 20818 } 20819 20820 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20821 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20822 struct cur_regulatory_info *reg_info, uint32_t len) 20823 { 20824 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20825 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20826 wmi_regulatory_rule_struct *wmi_reg_rule; 20827 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20828 20829 WMI_LOGD("processing regulatory channel list"); 20830 20831 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20832 if (!param_buf) { 20833 WMI_LOGE("invalid channel list event buf"); 20834 return QDF_STATUS_E_FAILURE; 20835 } 20836 20837 chan_list_event_hdr = param_buf->fixed_param; 20838 20839 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20840 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20841 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20842 REG_ALPHA2_LEN); 20843 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20844 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20845 reg_info->offload_enabled = true; 20846 reg_info->num_phy = chan_list_event_hdr->num_phy; 20847 reg_info->phy_id = chan_list_event_hdr->phy_id; 20848 reg_info->ctry_code = chan_list_event_hdr->country_id; 20849 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20850 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20851 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20852 else if (chan_list_event_hdr->status_code == 20853 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20854 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20855 else if (chan_list_event_hdr->status_code == 20856 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20857 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20858 else if (chan_list_event_hdr->status_code == 20859 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20860 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20861 else if (chan_list_event_hdr->status_code == 20862 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20863 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20864 else if (chan_list_event_hdr->status_code == 20865 WMI_REG_SET_CC_STATUS_FAIL) 20866 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20867 20868 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20869 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20870 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20871 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20872 20873 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20874 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20875 20876 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20877 __func__, reg_info->alpha2, reg_info->dfs_region, 20878 reg_info->min_bw_2g, reg_info->max_bw_2g, 20879 reg_info->min_bw_5g, reg_info->max_bw_5g); 20880 20881 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20882 num_2g_reg_rules, num_5g_reg_rules); 20883 wmi_reg_rule = 20884 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20885 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20886 + WMI_TLV_HDR_SIZE); 20887 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20888 wmi_reg_rule); 20889 wmi_reg_rule += num_2g_reg_rules; 20890 20891 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20892 wmi_reg_rule); 20893 20894 WMI_LOGD("processed regulatory channel list"); 20895 20896 return QDF_STATUS_SUCCESS; 20897 } 20898 20899 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20900 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20901 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20902 { 20903 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20904 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20905 20906 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20907 if (!param_buf) { 20908 WMI_LOGE("invalid 11d country event buf"); 20909 return QDF_STATUS_E_FAILURE; 20910 } 20911 20912 reg_11d_country_event = param_buf->fixed_param; 20913 20914 qdf_mem_copy(reg_11d_country->alpha2, 20915 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20916 20917 WMI_LOGD("processed 11d country event, new cc %s", 20918 reg_11d_country->alpha2); 20919 20920 return QDF_STATUS_SUCCESS; 20921 } 20922 20923 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20924 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20925 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20926 { 20927 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20928 wmi_avoid_freq_range_desc *afr_desc; 20929 uint32_t num_freq_ranges, freq_range_idx; 20930 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20931 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20932 20933 if (!param_buf) { 20934 WMI_LOGE("Invalid channel avoid event buffer"); 20935 return QDF_STATUS_E_INVAL; 20936 } 20937 20938 afr_fixed_param = param_buf->fixed_param; 20939 if (!afr_fixed_param) { 20940 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20941 return QDF_STATUS_E_INVAL; 20942 } 20943 20944 if (!ch_avoid_ind) { 20945 WMI_LOGE("Invalid channel avoid indication buffer"); 20946 return QDF_STATUS_E_INVAL; 20947 } 20948 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20949 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20950 afr_fixed_param->num_freq_ranges; 20951 20952 WMI_LOGD("Channel avoid event received with %d ranges", 20953 num_freq_ranges); 20954 20955 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20956 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20957 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20958 freq_range_idx++) { 20959 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20960 afr_desc->start_freq; 20961 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20962 afr_desc->end_freq; 20963 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20964 freq_range_idx, afr_desc->tlv_header, 20965 afr_desc->start_freq, afr_desc->end_freq); 20966 afr_desc++; 20967 } 20968 20969 return QDF_STATUS_SUCCESS; 20970 } 20971 #ifdef DFS_COMPONENT_ENABLE 20972 /** 20973 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20974 * @wmi_handle: wma handle 20975 * @evt_buf: event buffer 20976 * @vdev_id: vdev id 20977 * @len: length of buffer 20978 * 20979 * Return: 0 for success or error code 20980 */ 20981 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20982 uint8_t *evt_buf, 20983 uint32_t *vdev_id, 20984 uint32_t len) 20985 { 20986 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20987 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20988 20989 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20990 if (!param_tlvs) { 20991 WMI_LOGE("invalid cac complete event buf"); 20992 return QDF_STATUS_E_FAILURE; 20993 } 20994 20995 cac_event = param_tlvs->fixed_param; 20996 *vdev_id = cac_event->vdev_id; 20997 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20998 20999 return QDF_STATUS_SUCCESS; 21000 } 21001 21002 /** 21003 * extract_dfs_radar_detection_event_tlv() - extract radar found event 21004 * @wmi_handle: wma handle 21005 * @evt_buf: event buffer 21006 * @radar_found: radar found event info 21007 * @len: length of buffer 21008 * 21009 * Return: 0 for success or error code 21010 */ 21011 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 21012 wmi_unified_t wmi_handle, 21013 uint8_t *evt_buf, 21014 struct radar_found_info *radar_found, 21015 uint32_t len) 21016 { 21017 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 21018 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 21019 21020 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 21021 if (!param_tlv) { 21022 WMI_LOGE("invalid radar detection event buf"); 21023 return QDF_STATUS_E_FAILURE; 21024 } 21025 21026 radar_event = param_tlv->fixed_param; 21027 radar_found->pdev_id = wmi_handle->ops-> 21028 convert_pdev_id_target_to_host(radar_event->pdev_id); 21029 radar_found->detection_mode = radar_event->detection_mode; 21030 radar_found->chan_freq = radar_event->chan_freq; 21031 radar_found->chan_width = radar_event->chan_width; 21032 radar_found->detector_id = radar_event->detector_id; 21033 radar_found->segment_id = radar_event->segment_id; 21034 radar_found->timestamp = radar_event->timestamp; 21035 radar_found->is_chirp = radar_event->is_chirp; 21036 radar_found->freq_offset = radar_event->freq_offset; 21037 radar_found->sidx = radar_event->sidx; 21038 21039 WMI_LOGI("processed radar found event pdev %d," 21040 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 21041 "chan_width (RSSI) %d,detector_id (false_radar) %d," 21042 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 21043 "is_chirp %d,detection mode %d\n", 21044 radar_event->pdev_id, radar_event->pdev_id, 21045 radar_event->timestamp, radar_event->chan_freq, 21046 radar_event->chan_width, radar_event->detector_id, 21047 radar_event->freq_offset, radar_event->segment_id, 21048 radar_event->sidx, radar_event->is_chirp, 21049 radar_event->detection_mode); 21050 21051 return QDF_STATUS_SUCCESS; 21052 } 21053 21054 #ifdef QCA_MCL_DFS_SUPPORT 21055 /** 21056 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 21057 * @wmi_handle: wma handle 21058 * @evt_buf: event buffer 21059 * @wlan_radar_event: Pointer to struct radar_event_info 21060 * @len: length of buffer 21061 * 21062 * Return: QDF_STATUS 21063 */ 21064 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21065 wmi_unified_t wmi_handle, 21066 uint8_t *evt_buf, 21067 struct radar_event_info *wlan_radar_event, 21068 uint32_t len) 21069 { 21070 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 21071 wmi_dfs_radar_event_fixed_param *radar_event; 21072 21073 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 21074 if (!param_tlv) { 21075 WMI_LOGE("invalid wlan radar event buf"); 21076 return QDF_STATUS_E_FAILURE; 21077 } 21078 21079 radar_event = param_tlv->fixed_param; 21080 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 21081 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 21082 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 21083 wlan_radar_event->rssi = radar_event->rssi; 21084 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 21085 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 21086 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 21087 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 21088 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 21089 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 21090 wlan_radar_event->pdev_id = radar_event->pdev_id; 21091 21092 return QDF_STATUS_SUCCESS; 21093 } 21094 #else 21095 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21096 wmi_unified_t wmi_handle, 21097 uint8_t *evt_buf, 21098 struct radar_event_info *wlan_radar_event, 21099 uint32_t len) 21100 { 21101 return QDF_STATUS_SUCCESS; 21102 } 21103 #endif 21104 #endif 21105 21106 /** 21107 * send_get_rcpi_cmd_tlv() - send request for rcpi value 21108 * @wmi_handle: wmi handle 21109 * @get_rcpi_param: rcpi params 21110 * 21111 * Return: QDF status 21112 */ 21113 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 21114 struct rcpi_req *get_rcpi_param) 21115 { 21116 wmi_buf_t buf; 21117 wmi_request_rcpi_cmd_fixed_param *cmd; 21118 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 21119 21120 buf = wmi_buf_alloc(wmi_handle, len); 21121 if (!buf) { 21122 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21123 return QDF_STATUS_E_NOMEM; 21124 } 21125 21126 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 21127 WMITLV_SET_HDR(&cmd->tlv_header, 21128 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 21129 WMITLV_GET_STRUCT_TLVLEN 21130 (wmi_request_rcpi_cmd_fixed_param)); 21131 21132 cmd->vdev_id = get_rcpi_param->vdev_id; 21133 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 21134 &cmd->peer_macaddr); 21135 cmd->measurement_type = get_rcpi_param->measurement_type; 21136 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 21137 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21138 WMI_REQUEST_RCPI_CMDID)) { 21139 21140 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 21141 __func__); 21142 wmi_buf_free(buf); 21143 return QDF_STATUS_E_FAILURE; 21144 } 21145 21146 return QDF_STATUS_SUCCESS; 21147 } 21148 21149 /** 21150 * extract_rcpi_response_event_tlv() - Extract RCPI event params 21151 * @wmi_handle: wmi handle 21152 * @evt_buf: pointer to event buffer 21153 * @res: pointer to hold rcpi response from firmware 21154 * 21155 * Return: QDF_STATUS_SUCCESS for successful event parse 21156 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 21157 */ 21158 static QDF_STATUS 21159 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 21160 void *evt_buf, struct rcpi_res *res) 21161 { 21162 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 21163 wmi_update_rcpi_event_fixed_param *event; 21164 21165 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 21166 if (!param_buf) { 21167 WMI_LOGE(FL("Invalid rcpi event")); 21168 return QDF_STATUS_E_INVAL; 21169 } 21170 21171 event = param_buf->fixed_param; 21172 res->vdev_id = event->vdev_id; 21173 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 21174 21175 switch (event->measurement_type) { 21176 21177 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21178 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21179 break; 21180 21181 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 21182 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 21183 break; 21184 21185 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21186 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21187 break; 21188 21189 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 21190 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 21191 break; 21192 21193 default: 21194 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 21195 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 21196 return QDF_STATUS_E_FAILURE; 21197 } 21198 21199 if (event->status) 21200 return QDF_STATUS_E_FAILURE; 21201 else 21202 return QDF_STATUS_SUCCESS; 21203 } 21204 21205 /** 21206 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 21207 * host to target defines. For legacy there is not conversion 21208 * required. Just return pdev_id as it is. 21209 * @param pdev_id: host pdev_id to be converted. 21210 * Return: target pdev_id after conversion. 21211 */ 21212 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 21213 uint32_t pdev_id) 21214 { 21215 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 21216 return WMI_PDEV_ID_SOC; 21217 21218 /*No conversion required*/ 21219 return pdev_id; 21220 } 21221 21222 /** 21223 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 21224 * target to host defines. For legacy there is not conversion 21225 * required. Just return pdev_id as it is. 21226 * @param pdev_id: target pdev_id to be converted. 21227 * Return: host pdev_id after conversion. 21228 */ 21229 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 21230 uint32_t pdev_id) 21231 { 21232 /*No conversion required*/ 21233 return pdev_id; 21234 } 21235 21236 /** 21237 * send_set_country_cmd_tlv() - WMI scan channel list function 21238 * @param wmi_handle : handle to WMI. 21239 * @param param : pointer to hold scan channel list parameter 21240 * 21241 * Return: 0 on success and -ve on failure. 21242 */ 21243 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 21244 struct set_country *params) 21245 { 21246 wmi_buf_t buf; 21247 QDF_STATUS qdf_status; 21248 wmi_set_current_country_cmd_fixed_param *cmd; 21249 uint16_t len = sizeof(*cmd); 21250 21251 buf = wmi_buf_alloc(wmi_handle, len); 21252 if (!buf) { 21253 WMI_LOGE("Failed to allocate memory"); 21254 qdf_status = QDF_STATUS_E_NOMEM; 21255 goto end; 21256 } 21257 21258 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 21259 WMITLV_SET_HDR(&cmd->tlv_header, 21260 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 21261 WMITLV_GET_STRUCT_TLVLEN 21262 (wmi_set_current_country_cmd_fixed_param)); 21263 21264 WMI_LOGD("setting cuurnet country to %s", params->country); 21265 21266 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 21267 21268 cmd->pdev_id = params->pdev_id; 21269 21270 qdf_status = wmi_unified_cmd_send(wmi_handle, 21271 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 21272 21273 if (QDF_IS_STATUS_ERROR(qdf_status)) { 21274 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 21275 wmi_buf_free(buf); 21276 } 21277 21278 end: 21279 return qdf_status; 21280 } 21281 21282 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 21283 WMI_SET_BITS(alpha, 0, 8, val0); \ 21284 WMI_SET_BITS(alpha, 8, 8, val1); \ 21285 WMI_SET_BITS(alpha, 16, 8, val2); \ 21286 } while (0) 21287 21288 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 21289 uint8_t pdev_id, struct cc_regdmn_s *rd) 21290 { 21291 wmi_set_init_country_cmd_fixed_param *cmd; 21292 uint16_t len; 21293 wmi_buf_t buf; 21294 int ret; 21295 21296 len = sizeof(wmi_set_init_country_cmd_fixed_param); 21297 buf = wmi_buf_alloc(wmi_handle, len); 21298 if (!buf) { 21299 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 21300 return QDF_STATUS_E_NOMEM; 21301 } 21302 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 21303 WMITLV_SET_HDR(&cmd->tlv_header, 21304 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 21305 WMITLV_GET_STRUCT_TLVLEN 21306 (wmi_set_init_country_cmd_fixed_param)); 21307 21308 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 21309 21310 if (rd->flags == CC_IS_SET) { 21311 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 21312 cmd->country_code.country_id = rd->cc.country_code; 21313 } else if (rd->flags == ALPHA_IS_SET) { 21314 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 21315 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 21316 rd->cc.alpha[0], 21317 rd->cc.alpha[1], 21318 rd->cc.alpha[2]); 21319 } else if (rd->flags == REGDMN_IS_SET) { 21320 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 21321 cmd->country_code.domain_code = rd->cc.regdmn_id; 21322 } 21323 21324 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21325 WMI_SET_INIT_COUNTRY_CMDID); 21326 if (ret) { 21327 WMI_LOGE("Failed to config wow wakeup event"); 21328 wmi_buf_free(buf); 21329 return QDF_STATUS_E_FAILURE; 21330 } 21331 21332 return QDF_STATUS_SUCCESS; 21333 } 21334 21335 /** 21336 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 21337 * configuration params 21338 * @wmi_handle: wmi handler 21339 * @limit_off_chan_param: pointer to wmi_off_chan_param 21340 * 21341 * Return: 0 for success and non zero for failure 21342 */ 21343 static 21344 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 21345 struct wmi_limit_off_chan_param *limit_off_chan_param) 21346 { 21347 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 21348 wmi_buf_t buf; 21349 uint32_t len = sizeof(*cmd); 21350 int err; 21351 21352 buf = wmi_buf_alloc(wmi_handle, len); 21353 if (!buf) { 21354 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 21355 __func__); 21356 return QDF_STATUS_E_NOMEM; 21357 } 21358 21359 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 21360 21361 WMITLV_SET_HDR(&cmd->tlv_header, 21362 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 21363 WMITLV_GET_STRUCT_TLVLEN( 21364 wmi_vdev_limit_offchan_cmd_fixed_param)); 21365 21366 cmd->vdev_id = limit_off_chan_param->vdev_id; 21367 21368 cmd->flags &= 0; 21369 if (limit_off_chan_param->status) 21370 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 21371 if (limit_off_chan_param->skip_dfs_chans) 21372 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 21373 21374 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 21375 cmd->rest_time = limit_off_chan_param->rest_time; 21376 21377 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 21378 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 21379 cmd->rest_time); 21380 21381 err = wmi_unified_cmd_send(wmi_handle, buf, 21382 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 21383 if (QDF_IS_STATUS_ERROR(err)) { 21384 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 21385 wmi_buf_free(buf); 21386 return QDF_STATUS_E_FAILURE; 21387 } 21388 21389 return QDF_STATUS_SUCCESS; 21390 } 21391 21392 /** 21393 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 21394 * @wmi_handle: wmi handler 21395 * @req_buf: set arp stats request buffer 21396 * 21397 * Return: 0 for success and non zero for failure 21398 */ 21399 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21400 struct set_arp_stats *req_buf) 21401 { 21402 wmi_buf_t buf = NULL; 21403 QDF_STATUS status; 21404 int len; 21405 uint8_t *buf_ptr; 21406 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 21407 21408 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21409 if (req_buf->pkt_type_bitmap) { 21410 len += WMI_TLV_HDR_SIZE; 21411 len += sizeof(wmi_vdev_set_connectivity_check_stats); 21412 } 21413 buf = wmi_buf_alloc(wmi_handle, len); 21414 if (!buf) { 21415 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21416 return QDF_STATUS_E_NOMEM; 21417 } 21418 21419 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21420 wmi_set_arp = 21421 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 21422 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 21423 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 21424 WMITLV_GET_STRUCT_TLVLEN 21425 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 21426 21427 /* fill in per roam config values */ 21428 wmi_set_arp->vdev_id = req_buf->vdev_id; 21429 21430 wmi_set_arp->set_clr = req_buf->flag; 21431 wmi_set_arp->pkt_type = req_buf->pkt_type; 21432 wmi_set_arp->ipv4 = req_buf->ip_addr; 21433 21434 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 21435 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 21436 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 21437 21438 /* 21439 * pkt_type_bitmap should be non-zero to ensure 21440 * presence of additional stats. 21441 */ 21442 if (req_buf->pkt_type_bitmap) { 21443 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21444 21445 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21446 WMITLV_SET_HDR(buf_ptr, 21447 WMITLV_TAG_ARRAY_STRUC, 21448 sizeof(wmi_vdev_set_connectivity_check_stats)); 21449 buf_ptr += WMI_TLV_HDR_SIZE; 21450 wmi_set_connect_stats = 21451 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21452 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21453 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21454 WMITLV_GET_STRUCT_TLVLEN( 21455 wmi_vdev_set_connectivity_check_stats)); 21456 wmi_set_connect_stats->pkt_type_bitmap = 21457 req_buf->pkt_type_bitmap; 21458 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21459 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21460 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21461 21462 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21463 wmi_set_connect_stats->pkt_type_bitmap, 21464 wmi_set_connect_stats->tcp_src_port, 21465 wmi_set_connect_stats->tcp_dst_port, 21466 wmi_set_connect_stats->icmp_ipv4); 21467 } 21468 21469 /* Send per roam config parameters */ 21470 status = wmi_unified_cmd_send(wmi_handle, buf, 21471 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21472 if (QDF_IS_STATUS_ERROR(status)) { 21473 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21474 status); 21475 goto error; 21476 } 21477 21478 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 21479 req_buf->flag, req_buf->vdev_id); 21480 return QDF_STATUS_SUCCESS; 21481 error: 21482 wmi_buf_free(buf); 21483 21484 return status; 21485 } 21486 21487 /** 21488 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21489 * @wmi_handle: wmi handler 21490 * @req_buf: get arp stats request buffer 21491 * 21492 * Return: 0 for success and non zero for failure 21493 */ 21494 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21495 struct get_arp_stats *req_buf) 21496 { 21497 wmi_buf_t buf = NULL; 21498 QDF_STATUS status; 21499 int len; 21500 uint8_t *buf_ptr; 21501 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21502 21503 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21504 buf = wmi_buf_alloc(wmi_handle, len); 21505 if (!buf) { 21506 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21507 return QDF_STATUS_E_NOMEM; 21508 } 21509 21510 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21511 get_arp_stats = 21512 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21513 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21514 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21515 WMITLV_GET_STRUCT_TLVLEN 21516 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21517 21518 /* fill in arp stats req cmd values */ 21519 get_arp_stats->vdev_id = req_buf->vdev_id; 21520 21521 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21522 /* Send per roam config parameters */ 21523 status = wmi_unified_cmd_send(wmi_handle, buf, 21524 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21525 if (QDF_IS_STATUS_ERROR(status)) { 21526 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21527 status); 21528 goto error; 21529 } 21530 21531 return QDF_STATUS_SUCCESS; 21532 error: 21533 wmi_buf_free(buf); 21534 21535 return status; 21536 } 21537 21538 /** 21539 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21540 * @wmi_handle: wmi handler 21541 * @pmk_info: pointer to PMK cache entry 21542 * @vdev_id: vdev id 21543 * 21544 * Return: 0 for success and non zero for failure 21545 */ 21546 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21547 struct wmi_unified_pmk_cache *pmk_info) 21548 { 21549 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21550 wmi_buf_t buf; 21551 QDF_STATUS status; 21552 uint8_t *buf_ptr; 21553 wmi_pmk_cache *pmksa; 21554 uint32_t len = sizeof(*cmd); 21555 21556 if (pmk_info->pmk_len) 21557 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21558 21559 buf = wmi_buf_alloc(wmi_handle, len); 21560 if (!buf) { 21561 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21562 __func__); 21563 return QDF_STATUS_E_NOMEM; 21564 } 21565 21566 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21567 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21568 21569 WMITLV_SET_HDR(&cmd->tlv_header, 21570 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21571 WMITLV_GET_STRUCT_TLVLEN( 21572 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21573 21574 cmd->vdev_id = pmk_info->session_id; 21575 21576 /* If pmk_info->pmk_len is 0, this is a flush request */ 21577 if (!pmk_info->pmk_len) { 21578 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21579 cmd->num_cache = 0; 21580 goto send_cmd; 21581 } 21582 21583 cmd->num_cache = 1; 21584 buf_ptr += sizeof(*cmd); 21585 21586 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21587 sizeof(*pmksa)); 21588 buf_ptr += WMI_TLV_HDR_SIZE; 21589 21590 pmksa = (wmi_pmk_cache *)buf_ptr; 21591 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21592 WMITLV_GET_STRUCT_TLVLEN 21593 (wmi_pmk_cache)); 21594 pmksa->pmk_len = pmk_info->pmk_len; 21595 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21596 pmksa->pmkid_len = pmk_info->pmkid_len; 21597 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21598 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21599 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21600 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21601 pmksa->ssid.ssid_len); 21602 pmksa->cache_id = pmk_info->cache_id; 21603 pmksa->cat_flag = pmk_info->cat_flag; 21604 pmksa->action_flag = pmk_info->action_flag; 21605 21606 send_cmd: 21607 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21608 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21609 if (status != QDF_STATUS_SUCCESS) { 21610 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21611 __func__, status); 21612 wmi_buf_free(buf); 21613 } 21614 21615 return status; 21616 } 21617 21618 /** 21619 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21620 * @wmi_handle: wmi handle 21621 * @param: reserved param 21622 * 21623 * Return: 0 for success or error code 21624 */ 21625 static QDF_STATUS 21626 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21627 uint32_t param) 21628 { 21629 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21630 wmi_buf_t buf; 21631 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21632 21633 buf = wmi_buf_alloc(wmi_handle, len); 21634 if (!buf) { 21635 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21636 return QDF_STATUS_E_FAILURE; 21637 } 21638 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21639 WMITLV_SET_HDR(&cmd->tlv_header, 21640 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21641 WMITLV_GET_STRUCT_TLVLEN 21642 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21643 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21644 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21645 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21646 wmi_buf_free(buf); 21647 return QDF_STATUS_E_FAILURE; 21648 } 21649 21650 return QDF_STATUS_SUCCESS; 21651 } 21652 21653 /** 21654 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 21655 * host to target defines. 21656 * @param pdev_id: host pdev_id to be converted. 21657 * Return: target pdev_id after conversion. 21658 */ 21659 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 21660 { 21661 switch (pdev_id) { 21662 case WMI_HOST_PDEV_ID_SOC: 21663 return WMI_PDEV_ID_SOC; 21664 case WMI_HOST_PDEV_ID_0: 21665 return WMI_PDEV_ID_1ST; 21666 case WMI_HOST_PDEV_ID_1: 21667 return WMI_PDEV_ID_2ND; 21668 case WMI_HOST_PDEV_ID_2: 21669 return WMI_PDEV_ID_3RD; 21670 } 21671 21672 QDF_ASSERT(0); 21673 21674 return WMI_PDEV_ID_SOC; 21675 } 21676 21677 /** 21678 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 21679 * target to host defines. 21680 * @param pdev_id: target pdev_id to be converted. 21681 * Return: host pdev_id after conversion. 21682 */ 21683 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 21684 { 21685 switch (pdev_id) { 21686 case WMI_PDEV_ID_SOC: 21687 return WMI_HOST_PDEV_ID_SOC; 21688 case WMI_PDEV_ID_1ST: 21689 return WMI_HOST_PDEV_ID_0; 21690 case WMI_PDEV_ID_2ND: 21691 return WMI_HOST_PDEV_ID_1; 21692 case WMI_PDEV_ID_3RD: 21693 return WMI_HOST_PDEV_ID_2; 21694 } 21695 21696 QDF_ASSERT(0); 21697 21698 return WMI_HOST_PDEV_ID_SOC; 21699 } 21700 21701 /** 21702 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 21703 * 21704 * Return None. 21705 */ 21706 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 21707 { 21708 wmi_handle->ops->convert_pdev_id_host_to_target = 21709 convert_host_pdev_id_to_target_pdev_id; 21710 wmi_handle->ops->convert_pdev_id_target_to_host = 21711 convert_target_pdev_id_to_host_pdev_id; 21712 } 21713 21714 /** 21715 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21716 * @wmi_handle: wmi handle 21717 * @param evt_buf: pointer to event buffer 21718 * @param param: Pointer to hold peer caldata version data 21719 * 21720 * Return: 0 for success or error code 21721 */ 21722 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21723 wmi_unified_t wmi_handle, 21724 void *evt_buf, 21725 wmi_host_pdev_check_cal_version_event *param) 21726 { 21727 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21728 wmi_pdev_check_cal_version_event_fixed_param *event; 21729 21730 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21731 if (!param_tlvs) { 21732 WMI_LOGE("invalid cal version event buf"); 21733 return QDF_STATUS_E_FAILURE; 21734 } 21735 event = param_tlvs->fixed_param; 21736 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21737 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21738 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21739 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21740 21741 param->software_cal_version = event->software_cal_version; 21742 param->board_cal_version = event->board_cal_version; 21743 param->cal_ok = event->cal_status; 21744 21745 return QDF_STATUS_SUCCESS; 21746 } 21747 21748 /* 21749 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21750 * @wmi_handle: wmi handle 21751 * @params: pointer to wmi_btm_config 21752 * 21753 * Return: QDF_STATUS 21754 */ 21755 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21756 struct wmi_btm_config *params) 21757 { 21758 21759 wmi_btm_config_fixed_param *cmd; 21760 wmi_buf_t buf; 21761 uint32_t len; 21762 21763 len = sizeof(*cmd); 21764 buf = wmi_buf_alloc(wmi_handle, len); 21765 if (!buf) { 21766 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21767 return QDF_STATUS_E_NOMEM; 21768 } 21769 21770 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21771 WMITLV_SET_HDR(&cmd->tlv_header, 21772 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21773 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21774 cmd->vdev_id = params->vdev_id; 21775 cmd->flags = params->btm_offload_config; 21776 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21777 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21778 cmd->stick_time_seconds = params->btm_sticky_time; 21779 21780 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21781 WMI_ROAM_BTM_CONFIG_CMDID)) { 21782 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21783 __func__); 21784 wmi_buf_free(buf); 21785 return QDF_STATUS_E_FAILURE; 21786 } 21787 21788 return QDF_STATUS_SUCCESS; 21789 } 21790 21791 /** 21792 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21793 * configurations to firmware. 21794 * @wmi_handle: wmi handle 21795 * @obss_cfg_param: obss detection configurations 21796 * 21797 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21798 * 21799 * Return: QDF_STATUS 21800 */ 21801 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21802 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21803 { 21804 wmi_buf_t buf; 21805 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21806 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21807 21808 buf = wmi_buf_alloc(wmi_handle, len); 21809 if (!buf) { 21810 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21811 return QDF_STATUS_E_NOMEM; 21812 } 21813 21814 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21815 WMITLV_SET_HDR(&cmd->tlv_header, 21816 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21817 WMITLV_GET_STRUCT_TLVLEN 21818 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21819 21820 cmd->vdev_id = obss_cfg_param->vdev_id; 21821 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21822 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21823 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21824 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21825 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21826 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21827 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21828 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21829 21830 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21831 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21832 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21833 wmi_buf_free(buf); 21834 return QDF_STATUS_E_FAILURE; 21835 } 21836 21837 return QDF_STATUS_SUCCESS; 21838 } 21839 21840 /** 21841 * extract_obss_detection_info_tlv() - Extract obss detection info 21842 * received from firmware. 21843 * @evt_buf: pointer to event buffer 21844 * @obss_detection: Pointer to hold obss detection info 21845 * 21846 * Return: QDF_STATUS 21847 */ 21848 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21849 struct wmi_obss_detect_info 21850 *obss_detection) 21851 { 21852 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21853 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21854 21855 if (!obss_detection) { 21856 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21857 return QDF_STATUS_E_INVAL; 21858 } 21859 21860 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21861 if (!param_buf) { 21862 WMI_LOGE("%s: Invalid evt_buf", __func__); 21863 return QDF_STATUS_E_INVAL; 21864 } 21865 21866 fix_param = param_buf->fixed_param; 21867 obss_detection->vdev_id = fix_param->vdev_id; 21868 obss_detection->matched_detection_masks = 21869 fix_param->matched_detection_masks; 21870 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21871 &obss_detection->matched_bssid_addr[0]); 21872 switch (fix_param->reason) { 21873 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21874 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21875 break; 21876 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21877 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21878 break; 21879 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21880 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21881 break; 21882 default: 21883 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21884 return QDF_STATUS_E_INVAL; 21885 } 21886 21887 return QDF_STATUS_SUCCESS; 21888 } 21889 21890 /** 21891 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 21892 * @wmi_handle: wmi handler 21893 * @params: pointer to 11k offload params 21894 * 21895 * Return: 0 for success and non zero for failure 21896 */ 21897 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 21898 struct wmi_11k_offload_params *params) 21899 { 21900 wmi_11k_offload_report_fixed_param *cmd; 21901 wmi_buf_t buf; 21902 QDF_STATUS status; 21903 uint8_t *buf_ptr; 21904 wmi_neighbor_report_11k_offload_tlv_param 21905 *neighbor_report_offload_params; 21906 wmi_neighbor_report_offload *neighbor_report_offload; 21907 21908 uint32_t len = sizeof(*cmd); 21909 21910 if (params->offload_11k_bitmask & 21911 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 21912 len += WMI_TLV_HDR_SIZE + 21913 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 21914 21915 buf = wmi_buf_alloc(wmi_handle, len); 21916 if (!buf) { 21917 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 21918 __func__); 21919 return QDF_STATUS_E_NOMEM; 21920 } 21921 21922 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21923 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 21924 21925 WMITLV_SET_HDR(&cmd->tlv_header, 21926 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 21927 WMITLV_GET_STRUCT_TLVLEN( 21928 wmi_11k_offload_report_fixed_param)); 21929 21930 cmd->vdev_id = params->vdev_id; 21931 cmd->offload_11k = params->offload_11k_bitmask; 21932 21933 if (params->offload_11k_bitmask & 21934 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 21935 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 21936 21937 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21938 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 21939 buf_ptr += WMI_TLV_HDR_SIZE; 21940 21941 neighbor_report_offload_params = 21942 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 21943 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 21944 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 21945 WMITLV_GET_STRUCT_TLVLEN( 21946 wmi_neighbor_report_11k_offload_tlv_param)); 21947 21948 neighbor_report_offload = &neighbor_report_offload_params-> 21949 neighbor_rep_ofld_params; 21950 21951 neighbor_report_offload->time_offset = 21952 params->neighbor_report_params.time_offset; 21953 neighbor_report_offload->low_rssi_offset = 21954 params->neighbor_report_params.low_rssi_offset; 21955 neighbor_report_offload->bmiss_count_trigger = 21956 params->neighbor_report_params.bmiss_count_trigger; 21957 neighbor_report_offload->per_threshold_offset = 21958 params->neighbor_report_params.per_threshold_offset; 21959 neighbor_report_offload->neighbor_report_cache_timeout = 21960 params->neighbor_report_params. 21961 neighbor_report_cache_timeout; 21962 neighbor_report_offload->max_neighbor_report_req_cap = 21963 params->neighbor_report_params. 21964 max_neighbor_report_req_cap; 21965 neighbor_report_offload->ssid.ssid_len = 21966 params->neighbor_report_params.ssid.length; 21967 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 21968 ¶ms->neighbor_report_params.ssid.mac_ssid, 21969 neighbor_report_offload->ssid.ssid_len); 21970 } 21971 21972 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21973 WMI_11K_OFFLOAD_REPORT_CMDID); 21974 if (status != QDF_STATUS_SUCCESS) { 21975 WMI_LOGE("%s: failed to send 11k offload command %d", 21976 __func__, status); 21977 wmi_buf_free(buf); 21978 } 21979 21980 return status; 21981 } 21982 21983 /** 21984 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 21985 * command 21986 * @wmi_handle: wmi handler 21987 * @params: pointer to neighbor report invoke params 21988 * 21989 * Return: 0 for success and non zero for failure 21990 */ 21991 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 21992 struct wmi_invoke_neighbor_report_params *params) 21993 { 21994 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 21995 wmi_buf_t buf; 21996 QDF_STATUS status; 21997 uint8_t *buf_ptr; 21998 uint32_t len = sizeof(*cmd); 21999 22000 buf = wmi_buf_alloc(wmi_handle, len); 22001 if (!buf) { 22002 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 22003 __func__); 22004 return QDF_STATUS_E_NOMEM; 22005 } 22006 22007 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22008 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 22009 22010 WMITLV_SET_HDR(&cmd->tlv_header, 22011 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 22012 WMITLV_GET_STRUCT_TLVLEN( 22013 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 22014 22015 cmd->vdev_id = params->vdev_id; 22016 cmd->flags = params->send_resp_to_host; 22017 22018 cmd->ssid.ssid_len = params->ssid.length; 22019 qdf_mem_copy(cmd->ssid.ssid, 22020 ¶ms->ssid.mac_ssid, 22021 cmd->ssid.ssid_len); 22022 22023 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22024 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 22025 if (status != QDF_STATUS_SUCCESS) { 22026 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 22027 __func__, status); 22028 wmi_buf_free(buf); 22029 } 22030 22031 return status; 22032 } 22033 22034 #ifdef WLAN_SUPPORT_GREEN_AP 22035 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 22036 uint8_t *evt_buf, 22037 struct wlan_green_ap_egap_status_info *egap_status_info_params) 22038 { 22039 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 22040 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 22041 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 22042 22043 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 22044 if (!param_buf) { 22045 WMI_LOGE("Invalid EGAP Info status event buffer"); 22046 return QDF_STATUS_E_INVAL; 22047 } 22048 22049 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 22050 param_buf->fixed_param; 22051 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 22052 param_buf->chainmask_list; 22053 22054 egap_status_info_params->status = egap_info_event->status; 22055 egap_status_info_params->mac_id = chainmask_event->mac_id; 22056 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 22057 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 22058 22059 return QDF_STATUS_SUCCESS; 22060 } 22061 #endif 22062 22063 /* 22064 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 22065 * updating bss color change within firmware when AP announces bss color change. 22066 * @wmi_handle: wmi handle 22067 * @vdev_id: vdev ID 22068 * @enable: enable bss color change within firmware 22069 * 22070 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 22071 * 22072 * Return: QDF_STATUS 22073 */ 22074 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 22075 uint32_t vdev_id, 22076 bool enable) 22077 { 22078 wmi_buf_t buf; 22079 wmi_bss_color_change_enable_fixed_param *cmd; 22080 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 22081 22082 buf = wmi_buf_alloc(wmi_handle, len); 22083 if (!buf) { 22084 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22085 return QDF_STATUS_E_NOMEM; 22086 } 22087 22088 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 22089 WMITLV_SET_HDR(&cmd->tlv_header, 22090 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 22091 WMITLV_GET_STRUCT_TLVLEN 22092 (wmi_bss_color_change_enable_fixed_param)); 22093 cmd->vdev_id = vdev_id; 22094 cmd->enable = enable; 22095 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22096 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 22097 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 22098 wmi_buf_free(buf); 22099 return QDF_STATUS_E_FAILURE; 22100 } 22101 22102 return QDF_STATUS_SUCCESS; 22103 } 22104 22105 /** 22106 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 22107 * configurations to firmware. 22108 * @wmi_handle: wmi handle 22109 * @cfg_param: obss detection configurations 22110 * 22111 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 22112 * 22113 * Return: QDF_STATUS 22114 */ 22115 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 22116 wmi_unified_t wmi_handle, 22117 struct wmi_obss_color_collision_cfg_param *cfg_param) 22118 { 22119 wmi_buf_t buf; 22120 wmi_obss_color_collision_det_config_fixed_param *cmd; 22121 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 22122 22123 buf = wmi_buf_alloc(wmi_handle, len); 22124 if (!buf) { 22125 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22126 return QDF_STATUS_E_NOMEM; 22127 } 22128 22129 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 22130 buf); 22131 WMITLV_SET_HDR(&cmd->tlv_header, 22132 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 22133 WMITLV_GET_STRUCT_TLVLEN 22134 (wmi_obss_color_collision_det_config_fixed_param)); 22135 cmd->vdev_id = cfg_param->vdev_id; 22136 cmd->flags = cfg_param->flags; 22137 cmd->current_bss_color = cfg_param->current_bss_color; 22138 cmd->detection_period_ms = cfg_param->detection_period_ms; 22139 cmd->scan_period_ms = cfg_param->scan_period_ms; 22140 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 22141 22142 switch (cfg_param->evt_type) { 22143 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 22144 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 22145 break; 22146 case OBSS_COLOR_COLLISION_DETECTION: 22147 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 22148 break; 22149 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22150 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22151 break; 22152 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 22153 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 22154 break; 22155 default: 22156 WMI_LOGE("%s: invalid event type: %d", 22157 __func__, cfg_param->evt_type); 22158 wmi_buf_free(buf); 22159 return QDF_STATUS_E_FAILURE; 22160 } 22161 22162 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22163 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 22164 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 22165 __func__, cfg_param->vdev_id); 22166 wmi_buf_free(buf); 22167 return QDF_STATUS_E_FAILURE; 22168 } 22169 22170 return QDF_STATUS_SUCCESS; 22171 } 22172 22173 /** 22174 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 22175 * received from firmware. 22176 * @evt_buf: pointer to event buffer 22177 * @info: Pointer to hold bss collision info 22178 * 22179 * Return: QDF_STATUS 22180 */ 22181 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 22182 struct wmi_obss_color_collision_info *info) 22183 { 22184 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 22185 wmi_obss_color_collision_evt_fixed_param *fix_param; 22186 22187 if (!info) { 22188 WMI_LOGE("%s: Invalid obss color buffer", __func__); 22189 return QDF_STATUS_E_INVAL; 22190 } 22191 22192 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 22193 evt_buf; 22194 if (!param_buf) { 22195 WMI_LOGE("%s: Invalid evt_buf", __func__); 22196 return QDF_STATUS_E_INVAL; 22197 } 22198 22199 fix_param = param_buf->fixed_param; 22200 info->vdev_id = fix_param->vdev_id; 22201 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 22202 info->obss_color_bitmap_bit32to63 = 22203 fix_param->bss_color_bitmap_bit32to63; 22204 22205 switch (fix_param->evt_type) { 22206 case WMI_BSS_COLOR_COLLISION_DISABLE: 22207 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 22208 break; 22209 case WMI_BSS_COLOR_COLLISION_DETECTION: 22210 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 22211 break; 22212 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22213 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22214 break; 22215 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 22216 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 22217 break; 22218 default: 22219 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 22220 __func__, fix_param->evt_type, fix_param->vdev_id); 22221 return QDF_STATUS_E_FAILURE; 22222 } 22223 22224 return QDF_STATUS_SUCCESS; 22225 } 22226 22227 /* 22228 * extract_comb_phyerr_tlv() - extract comb phy error from event 22229 * @wmi_handle: wmi handle 22230 * @evt_buf: pointer to event buffer 22231 * @datalen: data length of event buffer 22232 * @buf_offset: Pointer to hold value of current event buffer offset 22233 * post extraction 22234 * @phyerr: Pointer to hold phyerr 22235 * 22236 * Return: QDF_STATUS 22237 */ 22238 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 22239 void *evt_buf, 22240 uint16_t datalen, 22241 uint16_t *buf_offset, 22242 wmi_host_phyerr_t *phyerr) 22243 { 22244 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 22245 wmi_comb_phyerr_rx_hdr *pe_hdr; 22246 22247 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 22248 if (!param_tlvs) { 22249 WMI_LOGD("%s: Received null data from FW", __func__); 22250 return QDF_STATUS_E_FAILURE; 22251 } 22252 22253 pe_hdr = param_tlvs->hdr; 22254 if (!pe_hdr) { 22255 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 22256 return QDF_STATUS_E_FAILURE; 22257 } 22258 22259 /* Ensure it's at least the size of the header */ 22260 if (datalen < sizeof(*pe_hdr)) { 22261 WMI_LOGD("%s: Expected minimum size %zu, received %d", 22262 __func__, sizeof(*pe_hdr), datalen); 22263 return QDF_STATUS_E_FAILURE; 22264 } 22265 22266 phyerr->pdev_id = wmi_handle->ops-> 22267 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 22268 phyerr->tsf64 = pe_hdr->tsf_l32; 22269 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 22270 phyerr->bufp = param_tlvs->bufp; 22271 phyerr->buf_len = pe_hdr->buf_len; 22272 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 22273 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 22274 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 22275 22276 return QDF_STATUS_SUCCESS; 22277 } 22278 22279 /** 22280 * extract_single_phyerr_tlv() - extract single phy error from event 22281 * @wmi_handle: wmi handle 22282 * @evt_buf: pointer to event buffer 22283 * @datalen: data length of event buffer 22284 * @buf_offset: Pointer to hold value of current event buffer offset 22285 * post extraction 22286 * @phyerr: Pointer to hold phyerr 22287 * 22288 * Return: QDF_STATUS 22289 */ 22290 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 22291 void *evt_buf, 22292 uint16_t datalen, 22293 uint16_t *buf_offset, 22294 wmi_host_phyerr_t *phyerr) 22295 { 22296 wmi_single_phyerr_rx_event *ev; 22297 uint16_t n = *buf_offset; 22298 uint8_t *data = (uint8_t *)evt_buf; 22299 22300 if (n < datalen) { 22301 if ((datalen - n) < sizeof(ev->hdr)) { 22302 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 22303 __func__, datalen, n, sizeof(ev->hdr)); 22304 return QDF_STATUS_E_FAILURE; 22305 } 22306 22307 /* 22308 * Obtain a pointer to the beginning of the current event. 22309 * data[0] is the beginning of the WMI payload. 22310 */ 22311 ev = (wmi_single_phyerr_rx_event *)&data[n]; 22312 22313 /* 22314 * Sanity check the buffer length of the event against 22315 * what we currently have. 22316 * 22317 * Since buf_len is 32 bits, we check if it overflows 22318 * a large 32 bit value. It's not 0x7fffffff because 22319 * we increase n by (buf_len + sizeof(hdr)), which would 22320 * in itself cause n to overflow. 22321 * 22322 * If "int" is 64 bits then this becomes a moot point. 22323 */ 22324 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 22325 WMI_LOGD("%s: buf_len is garbage 0x%x", 22326 __func__, ev->hdr.buf_len); 22327 return QDF_STATUS_E_FAILURE; 22328 } 22329 22330 if ((n + ev->hdr.buf_len) > datalen) { 22331 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 22332 __func__, n, ev->hdr.buf_len, datalen); 22333 return QDF_STATUS_E_FAILURE; 22334 } 22335 22336 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 22337 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 22338 phyerr->bufp = &ev->bufp[0]; 22339 phyerr->buf_len = ev->hdr.buf_len; 22340 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 22341 22342 /* 22343 * Advance the buffer pointer to the next PHY error. 22344 * buflen is the length of this payload, so we need to 22345 * advance past the current header _AND_ the payload. 22346 */ 22347 n += sizeof(*ev) + ev->hdr.buf_len; 22348 } 22349 *buf_offset = n; 22350 22351 return QDF_STATUS_SUCCESS; 22352 } 22353 22354 struct wmi_ops tlv_ops = { 22355 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 22356 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 22357 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 22358 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 22359 .send_hidden_ssid_vdev_restart_cmd = 22360 send_hidden_ssid_vdev_restart_cmd_tlv, 22361 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 22362 .send_peer_param_cmd = send_peer_param_cmd_tlv, 22363 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 22364 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 22365 .send_peer_create_cmd = send_peer_create_cmd_tlv, 22366 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 22367 .send_peer_rx_reorder_queue_setup_cmd = 22368 send_peer_rx_reorder_queue_setup_cmd_tlv, 22369 .send_peer_rx_reorder_queue_remove_cmd = 22370 send_peer_rx_reorder_queue_remove_cmd_tlv, 22371 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 22372 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 22373 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 22374 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 22375 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 22376 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 22377 .send_suspend_cmd = send_suspend_cmd_tlv, 22378 .send_resume_cmd = send_resume_cmd_tlv, 22379 #ifdef FEATURE_WLAN_D0WOW 22380 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 22381 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 22382 #endif 22383 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 22384 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 22385 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 22386 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 22387 .send_dbglog_cmd = send_dbglog_cmd_tlv, 22388 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 22389 .send_stats_request_cmd = send_stats_request_cmd_tlv, 22390 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 22391 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 22392 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 22393 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 22394 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 22395 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 22396 .send_scan_start_cmd = send_scan_start_cmd_tlv, 22397 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 22398 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 22399 .send_mgmt_cmd = send_mgmt_cmd_tlv, 22400 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 22401 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 22402 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 22403 .send_set_sta_uapsd_auto_trig_cmd = 22404 send_set_sta_uapsd_auto_trig_cmd_tlv, 22405 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 22406 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 22407 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 22408 #ifdef CONVERGED_P2P_ENABLE 22409 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 22410 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 22411 #endif 22412 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 22413 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 22414 #ifdef WLAN_FEATURE_DSRC 22415 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 22416 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 22417 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 22418 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 22419 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 22420 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 22421 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 22422 .send_ocb_start_timing_advert_cmd = 22423 send_ocb_start_timing_advert_cmd_tlv, 22424 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 22425 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 22426 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 22427 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 22428 #endif 22429 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 22430 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 22431 .send_set_mcc_channel_time_latency_cmd = 22432 send_set_mcc_channel_time_latency_cmd_tlv, 22433 .send_set_mcc_channel_time_quota_cmd = 22434 send_set_mcc_channel_time_quota_cmd_tlv, 22435 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 22436 .send_lro_config_cmd = send_lro_config_cmd_tlv, 22437 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 22438 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 22439 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 22440 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 22441 .send_probe_rsp_tmpl_send_cmd = 22442 send_probe_rsp_tmpl_send_cmd_tlv, 22443 .send_p2p_go_set_beacon_ie_cmd = 22444 send_p2p_go_set_beacon_ie_cmd_tlv, 22445 .send_setup_install_key_cmd = 22446 send_setup_install_key_cmd_tlv, 22447 .send_set_gateway_params_cmd = 22448 send_set_gateway_params_cmd_tlv, 22449 .send_set_rssi_monitoring_cmd = 22450 send_set_rssi_monitoring_cmd_tlv, 22451 .send_scan_probe_setoui_cmd = 22452 send_scan_probe_setoui_cmd_tlv, 22453 .send_reset_passpoint_network_list_cmd = 22454 send_reset_passpoint_network_list_cmd_tlv, 22455 .send_set_passpoint_network_list_cmd = 22456 send_set_passpoint_network_list_cmd_tlv, 22457 .send_roam_scan_offload_rssi_thresh_cmd = 22458 send_roam_scan_offload_rssi_thresh_cmd_tlv, 22459 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 22460 .send_roam_scan_filter_cmd = 22461 send_roam_scan_filter_cmd_tlv, 22462 .send_set_epno_network_list_cmd = 22463 send_set_epno_network_list_cmd_tlv, 22464 .send_ipa_offload_control_cmd = 22465 send_ipa_offload_control_cmd_tlv, 22466 .send_extscan_get_capabilities_cmd = 22467 send_extscan_get_capabilities_cmd_tlv, 22468 .send_extscan_get_cached_results_cmd = 22469 send_extscan_get_cached_results_cmd_tlv, 22470 .send_extscan_stop_change_monitor_cmd = 22471 send_extscan_stop_change_monitor_cmd_tlv, 22472 .send_extscan_start_change_monitor_cmd = 22473 send_extscan_start_change_monitor_cmd_tlv, 22474 .send_extscan_stop_hotlist_monitor_cmd = 22475 send_extscan_stop_hotlist_monitor_cmd_tlv, 22476 .send_stop_extscan_cmd = send_stop_extscan_cmd_tlv, 22477 .send_start_extscan_cmd = send_start_extscan_cmd_tlv, 22478 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 22479 .send_plm_start_cmd = send_plm_start_cmd_tlv, 22480 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 22481 .send_pno_start_cmd = send_pno_start_cmd_tlv, 22482 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 22483 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 22484 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 22485 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 22486 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 22487 .send_congestion_cmd = send_congestion_cmd_tlv, 22488 .send_snr_request_cmd = send_snr_request_cmd_tlv, 22489 .send_snr_cmd = send_snr_cmd_tlv, 22490 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 22491 #ifdef WLAN_PMO_ENABLE 22492 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 22493 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 22494 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 22495 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 22496 .send_multiple_add_clear_mcbc_filter_cmd = 22497 send_multiple_add_clear_mcbc_filter_cmd_tlv, 22498 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 22499 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 22500 .send_process_gtk_offload_getinfo_cmd = 22501 send_process_gtk_offload_getinfo_cmd_tlv, 22502 .send_enable_enhance_multicast_offload_cmd = 22503 send_enable_enhance_multicast_offload_tlv, 22504 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 22505 #ifdef FEATURE_WLAN_RA_FILTERING 22506 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 22507 #endif 22508 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 22509 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 22510 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 22511 .send_lphb_config_tcp_pkt_filter_cmd = 22512 send_lphb_config_tcp_pkt_filter_cmd_tlv, 22513 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22514 .send_lphb_config_udp_pkt_filter_cmd = 22515 send_lphb_config_udp_pkt_filter_cmd_tlv, 22516 .send_enable_disable_packet_filter_cmd = 22517 send_enable_disable_packet_filter_cmd_tlv, 22518 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22519 #endif /* End of WLAN_PMO_ENABLE */ 22520 #ifdef CONFIG_MCL 22521 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22522 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22523 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22524 .send_roam_scan_offload_mode_cmd = 22525 send_roam_scan_offload_mode_cmd_tlv, 22526 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22527 .send_roam_scan_offload_ap_profile_cmd = 22528 send_roam_scan_offload_ap_profile_cmd_tlv, 22529 #endif 22530 #ifdef WLAN_SUPPORT_GREEN_AP 22531 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22532 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22533 .extract_green_ap_egap_status_info = 22534 extract_green_ap_egap_status_info_tlv, 22535 #endif 22536 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22537 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22538 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22539 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22540 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22541 #ifdef WLAN_FEATURE_CIF_CFR 22542 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22543 #endif 22544 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22545 .send_dfs_phyerr_filter_offload_en_cmd = 22546 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22547 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22548 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22549 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22550 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22551 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22552 .send_process_add_periodic_tx_ptrn_cmd = 22553 send_process_add_periodic_tx_ptrn_cmd_tlv, 22554 .send_process_del_periodic_tx_ptrn_cmd = 22555 send_process_del_periodic_tx_ptrn_cmd_tlv, 22556 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22557 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22558 .send_set_app_type2_params_in_fw_cmd = 22559 send_set_app_type2_params_in_fw_cmd_tlv, 22560 .send_set_auto_shutdown_timer_cmd = 22561 send_set_auto_shutdown_timer_cmd_tlv, 22562 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22563 .send_process_dhcpserver_offload_cmd = 22564 send_process_dhcpserver_offload_cmd_tlv, 22565 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22566 .send_process_ch_avoid_update_cmd = 22567 send_process_ch_avoid_update_cmd_tlv, 22568 .send_pdev_set_regdomain_cmd = 22569 send_pdev_set_regdomain_cmd_tlv, 22570 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22571 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22572 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22573 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22574 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22575 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22576 .check_and_update_fw_version = 22577 check_and_update_fw_version_cmd_tlv, 22578 .send_set_base_macaddr_indicate_cmd = 22579 send_set_base_macaddr_indicate_cmd_tlv, 22580 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22581 .send_enable_specific_fw_logs_cmd = 22582 send_enable_specific_fw_logs_cmd_tlv, 22583 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22584 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22585 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22586 .send_pdev_set_dual_mac_config_cmd = 22587 send_pdev_set_dual_mac_config_cmd_tlv, 22588 .send_app_type1_params_in_fw_cmd = 22589 send_app_type1_params_in_fw_cmd_tlv, 22590 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22591 .send_process_roam_synch_complete_cmd = 22592 send_process_roam_synch_complete_cmd_tlv, 22593 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22594 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22595 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22596 .send_roam_scan_offload_scan_period_cmd = 22597 send_roam_scan_offload_scan_period_cmd_tlv, 22598 .send_roam_scan_offload_chan_list_cmd = 22599 send_roam_scan_offload_chan_list_cmd_tlv, 22600 .send_roam_scan_offload_rssi_change_cmd = 22601 send_roam_scan_offload_rssi_change_cmd_tlv, 22602 .send_get_buf_extscan_hotlist_cmd = 22603 send_get_buf_extscan_hotlist_cmd_tlv, 22604 .send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv, 22605 .send_adapt_dwelltime_params_cmd = 22606 send_adapt_dwelltime_params_cmd_tlv, 22607 .send_dbs_scan_sel_params_cmd = 22608 send_dbs_scan_sel_params_cmd_tlv, 22609 .init_cmd_send = init_cmd_send_tlv, 22610 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22611 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22612 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22613 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22614 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22615 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22616 .send_vdev_set_custom_aggr_size_cmd = 22617 send_vdev_set_custom_aggr_size_cmd_tlv, 22618 .send_vdev_set_qdepth_thresh_cmd = 22619 send_vdev_set_qdepth_thresh_cmd_tlv, 22620 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22621 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22622 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22623 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22624 .send_smart_ant_set_training_info_cmd = 22625 send_smart_ant_set_training_info_cmd_tlv, 22626 .send_smart_ant_set_node_config_cmd = 22627 send_smart_ant_set_node_config_cmd_tlv, 22628 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22629 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22630 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22631 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22632 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22633 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22634 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22635 .send_periodic_chan_stats_config_cmd = 22636 send_periodic_chan_stats_config_cmd_tlv, 22637 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22638 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22639 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22640 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22641 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22642 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22643 .send_vdev_spectral_configure_cmd = 22644 send_vdev_spectral_configure_cmd_tlv, 22645 .send_vdev_spectral_enable_cmd = 22646 send_vdev_spectral_enable_cmd_tlv, 22647 .send_thermal_mitigation_param_cmd = 22648 send_thermal_mitigation_param_cmd_tlv, 22649 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22650 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22651 .send_process_update_edca_param_cmd = 22652 send_process_update_edca_param_cmd_tlv, 22653 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22654 .send_set_country_cmd = send_set_country_cmd_tlv, 22655 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22656 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22657 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22658 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22659 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22660 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22661 .extract_host_mem_req = extract_host_mem_req_tlv, 22662 .save_service_bitmap = save_service_bitmap_tlv, 22663 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22664 .is_service_enabled = is_service_enabled_tlv, 22665 .save_fw_version = save_fw_version_in_service_ready_tlv, 22666 .ready_extract_init_status = ready_extract_init_status_tlv, 22667 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22668 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22669 .extract_ready_event_params = extract_ready_event_params_tlv, 22670 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22671 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22672 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22673 .extract_tbttoffset_update_params = 22674 extract_tbttoffset_update_params_tlv, 22675 .extract_ext_tbttoffset_update_params = 22676 extract_ext_tbttoffset_update_params_tlv, 22677 .extract_tbttoffset_num_vdevs = 22678 extract_tbttoffset_num_vdevs_tlv, 22679 .extract_ext_tbttoffset_num_vdevs = 22680 extract_ext_tbttoffset_num_vdevs_tlv, 22681 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22682 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22683 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22684 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22685 #ifdef CONVERGED_TDLS_ENABLE 22686 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22687 #endif 22688 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22689 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22690 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22691 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22692 #ifdef CONVERGED_P2P_ENABLE 22693 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22694 .extract_p2p_lo_stop_ev_param = 22695 extract_p2p_lo_stop_ev_param_tlv, 22696 #endif 22697 .extract_offchan_data_tx_compl_param = 22698 extract_offchan_data_tx_compl_param_tlv, 22699 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22700 .extract_all_stats_count = extract_all_stats_counts_tlv, 22701 .extract_pdev_stats = extract_pdev_stats_tlv, 22702 .extract_unit_test = extract_unit_test_tlv, 22703 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22704 .extract_vdev_stats = extract_vdev_stats_tlv, 22705 .extract_peer_stats = extract_peer_stats_tlv, 22706 .extract_bcn_stats = extract_bcn_stats_tlv, 22707 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22708 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22709 .extract_chan_stats = extract_chan_stats_tlv, 22710 .extract_profile_ctx = extract_profile_ctx_tlv, 22711 .extract_profile_data = extract_profile_data_tlv, 22712 .extract_chan_info_event = extract_chan_info_event_tlv, 22713 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22714 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22715 #ifdef WLAN_FEATURE_DISA 22716 .send_encrypt_decrypt_send_cmd = 22717 send_encrypt_decrypt_send_cmd_tlv, 22718 .extract_encrypt_decrypt_resp_event = 22719 extract_encrypt_decrypt_resp_event_tlv, 22720 #endif 22721 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22722 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22723 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22724 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22725 .send_multiple_vdev_restart_req_cmd = 22726 send_multiple_vdev_restart_req_cmd_tlv, 22727 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22728 .extract_hw_mode_cap_service_ready_ext = 22729 extract_hw_mode_cap_service_ready_ext_tlv, 22730 .extract_mac_phy_cap_service_ready_ext = 22731 extract_mac_phy_cap_service_ready_ext_tlv, 22732 .extract_reg_cap_service_ready_ext = 22733 extract_reg_cap_service_ready_ext_tlv, 22734 .extract_dbr_ring_cap_service_ready_ext = 22735 extract_dbr_ring_cap_service_ready_ext_tlv, 22736 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22737 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22738 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22739 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22740 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22741 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22742 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22743 .extract_fips_event_data = extract_fips_event_data_tlv, 22744 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22745 .extract_peer_delete_response_event = 22746 extract_peer_delete_response_event_tlv, 22747 .is_management_record = is_management_record_tlv, 22748 .extract_pdev_csa_switch_count_status = 22749 extract_pdev_csa_switch_count_status_tlv, 22750 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22751 .extract_pdev_tpc_config_ev_param = 22752 extract_pdev_tpc_config_ev_param_tlv, 22753 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22754 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22755 .extract_peer_sta_ps_statechange_ev = 22756 extract_peer_sta_ps_statechange_ev_tlv, 22757 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22758 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22759 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22760 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22761 .extract_reg_chan_list_update_event = 22762 extract_reg_chan_list_update_event_tlv, 22763 .extract_chainmask_tables = 22764 extract_chainmask_tables_tlv, 22765 .extract_thermal_stats = extract_thermal_stats_tlv, 22766 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22767 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22768 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22769 #ifdef DFS_COMPONENT_ENABLE 22770 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22771 .extract_dfs_radar_detection_event = 22772 extract_dfs_radar_detection_event_tlv, 22773 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22774 #endif 22775 .convert_pdev_id_host_to_target = 22776 convert_host_pdev_id_to_target_pdev_id_legacy, 22777 .convert_pdev_id_target_to_host = 22778 convert_target_pdev_id_to_host_pdev_id_legacy, 22779 22780 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22781 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22782 .extract_reg_11d_new_country_event = 22783 extract_reg_11d_new_country_event_tlv, 22784 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22785 .send_limit_off_chan_cmd = 22786 send_limit_off_chan_cmd_tlv, 22787 .extract_reg_ch_avoid_event = 22788 extract_reg_ch_avoid_event_tlv, 22789 .send_pdev_caldata_version_check_cmd = 22790 send_pdev_caldata_version_check_cmd_tlv, 22791 .extract_pdev_caldata_version_check_ev_param = 22792 extract_pdev_caldata_version_check_ev_param_tlv, 22793 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22794 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22795 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22796 #if defined(WLAN_FEATURE_FILS_SK) 22797 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22798 #endif 22799 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22800 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22801 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22802 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22803 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22804 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22805 .extract_ndp_ind = extract_ndp_ind_tlv, 22806 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22807 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22808 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22809 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22810 #endif 22811 .send_btm_config = send_btm_config_cmd_tlv, 22812 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22813 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22814 #ifdef WLAN_SUPPORT_FILS 22815 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22816 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22817 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22818 #endif /* WLAN_SUPPORT_FILS */ 22819 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22820 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22821 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22822 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22823 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22824 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22825 .send_bss_color_change_enable_cmd = 22826 send_bss_color_change_enable_cmd_tlv, 22827 .send_obss_color_collision_cfg_cmd = 22828 send_obss_color_collision_cfg_cmd_tlv, 22829 .extract_obss_color_collision_info = 22830 extract_obss_color_collision_info_tlv, 22831 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22832 .extract_single_phyerr = extract_single_phyerr_tlv, 22833 }; 22834 22835 /** 22836 * populate_tlv_event_id() - populates wmi event ids 22837 * 22838 * @param event_ids: Pointer to hold event ids 22839 * Return: None 22840 */ 22841 static void populate_tlv_events_id(uint32_t *event_ids) 22842 { 22843 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22844 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22845 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22846 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22847 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22848 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22849 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22850 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22851 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22852 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22853 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22854 event_ids[wmi_service_ready_ext_event_id] = 22855 WMI_SERVICE_READY_EXT_EVENTID; 22856 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22857 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22858 event_ids[wmi_vdev_install_key_complete_event_id] = 22859 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22860 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22861 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22862 22863 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22864 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22865 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22866 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22867 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22868 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22869 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22870 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22871 event_ids[wmi_peer_delete_response_event_id] = 22872 WMI_PEER_DELETE_RESP_EVENTID; 22873 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22874 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22875 event_ids[wmi_tbttoffset_update_event_id] = 22876 WMI_TBTTOFFSET_UPDATE_EVENTID; 22877 event_ids[wmi_ext_tbttoffset_update_event_id] = 22878 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22879 event_ids[wmi_offload_bcn_tx_status_event_id] = 22880 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22881 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22882 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22883 event_ids[wmi_mgmt_tx_completion_event_id] = 22884 WMI_MGMT_TX_COMPLETION_EVENTID; 22885 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22886 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22887 event_ids[wmi_tx_delba_complete_event_id] = 22888 WMI_TX_DELBA_COMPLETE_EVENTID; 22889 event_ids[wmi_tx_addba_complete_event_id] = 22890 WMI_TX_ADDBA_COMPLETE_EVENTID; 22891 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22892 22893 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22894 22895 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22896 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22897 22898 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22899 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22900 22901 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22902 22903 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22904 event_ids[wmi_p2p_lo_stop_event_id] = 22905 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22906 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22907 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22908 event_ids[wmi_d0_wow_disable_ack_event_id] = 22909 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22910 event_ids[wmi_wow_initial_wakeup_event_id] = 22911 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22912 22913 event_ids[wmi_rtt_meas_report_event_id] = 22914 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22915 event_ids[wmi_tsf_meas_report_event_id] = 22916 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22917 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22918 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22919 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22920 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22921 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22922 event_ids[wmi_diag_event_id_log_supported_event_id] = 22923 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22924 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22925 event_ids[wmi_nlo_scan_complete_event_id] = 22926 WMI_NLO_SCAN_COMPLETE_EVENTID; 22927 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22928 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22929 22930 event_ids[wmi_gtk_offload_status_event_id] = 22931 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22932 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22933 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22934 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22935 22936 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22937 22938 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22939 22940 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22941 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22942 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22943 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22944 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22945 event_ids[wmi_wlan_profile_data_event_id] = 22946 WMI_WLAN_PROFILE_DATA_EVENTID; 22947 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22948 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22949 event_ids[wmi_vdev_get_keepalive_event_id] = 22950 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22951 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22952 22953 event_ids[wmi_diag_container_event_id] = 22954 WMI_DIAG_DATA_CONTAINER_EVENTID; 22955 22956 event_ids[wmi_host_auto_shutdown_event_id] = 22957 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22958 22959 event_ids[wmi_update_whal_mib_stats_event_id] = 22960 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22961 22962 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22963 event_ids[wmi_update_vdev_rate_stats_event_id] = 22964 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22965 22966 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22967 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22968 22969 /** Set OCB Sched Response, deprecated */ 22970 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22971 22972 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22973 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22974 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22975 22976 /* GPIO Event */ 22977 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22978 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22979 22980 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22981 event_ids[wmi_rfkill_state_change_event_id] = 22982 WMI_RFKILL_STATE_CHANGE_EVENTID; 22983 22984 /* TDLS Event */ 22985 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22986 22987 event_ids[wmi_batch_scan_enabled_event_id] = 22988 WMI_BATCH_SCAN_ENABLED_EVENTID; 22989 event_ids[wmi_batch_scan_result_event_id] = 22990 WMI_BATCH_SCAN_RESULT_EVENTID; 22991 /* OEM Event */ 22992 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22993 event_ids[wmi_oem_meas_report_event_id] = 22994 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22995 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22996 22997 /* NAN Event */ 22998 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22999 23000 /* LPI Event */ 23001 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 23002 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 23003 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 23004 23005 /* ExtScan events */ 23006 event_ids[wmi_extscan_start_stop_event_id] = 23007 WMI_EXTSCAN_START_STOP_EVENTID; 23008 event_ids[wmi_extscan_operation_event_id] = 23009 WMI_EXTSCAN_OPERATION_EVENTID; 23010 event_ids[wmi_extscan_table_usage_event_id] = 23011 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 23012 event_ids[wmi_extscan_cached_results_event_id] = 23013 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 23014 event_ids[wmi_extscan_wlan_change_results_event_id] = 23015 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 23016 event_ids[wmi_extscan_hotlist_match_event_id] = 23017 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 23018 event_ids[wmi_extscan_capabilities_event_id] = 23019 WMI_EXTSCAN_CAPABILITIES_EVENTID; 23020 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 23021 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 23022 23023 /* mDNS offload events */ 23024 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 23025 23026 /* SAP Authentication offload events */ 23027 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 23028 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 23029 23030 /** Out-of-context-of-bss (OCB) events */ 23031 event_ids[wmi_ocb_set_config_resp_event_id] = 23032 WMI_OCB_SET_CONFIG_RESP_EVENTID; 23033 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 23034 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 23035 event_ids[wmi_dcc_get_stats_resp_event_id] = 23036 WMI_DCC_GET_STATS_RESP_EVENTID; 23037 event_ids[wmi_dcc_update_ndl_resp_event_id] = 23038 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 23039 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 23040 /* System-On-Chip events */ 23041 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 23042 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 23043 event_ids[wmi_soc_hw_mode_transition_event_id] = 23044 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 23045 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 23046 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 23047 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 23048 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 23049 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 23050 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 23051 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 23052 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23053 event_ids[wmi_peer_sta_ps_statechg_event_id] = 23054 WMI_PEER_STA_PS_STATECHG_EVENTID; 23055 event_ids[wmi_pdev_channel_hopping_event_id] = 23056 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 23057 event_ids[wmi_offchan_data_tx_completion_event] = 23058 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 23059 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 23060 event_ids[wmi_dfs_radar_detection_event_id] = 23061 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 23062 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 23063 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 23064 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 23065 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 23066 event_ids[wmi_service_available_event_id] = 23067 WMI_SERVICE_AVAILABLE_EVENTID; 23068 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 23069 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 23070 /* NDP events */ 23071 event_ids[wmi_ndp_initiator_rsp_event_id] = 23072 WMI_NDP_INITIATOR_RSP_EVENTID; 23073 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 23074 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 23075 event_ids[wmi_ndp_responder_rsp_event_id] = 23076 WMI_NDP_RESPONDER_RSP_EVENTID; 23077 event_ids[wmi_ndp_end_indication_event_id] = 23078 WMI_NDP_END_INDICATION_EVENTID; 23079 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 23080 23081 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 23082 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 23083 event_ids[wmi_pdev_chip_power_stats_event_id] = 23084 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 23085 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 23086 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 23087 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 23088 event_ids[wmi_bpf_capability_info_event_id] = 23089 WMI_BPF_CAPABILIY_INFO_EVENTID; 23090 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 23091 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 23092 event_ids[wmi_report_rx_aggr_failure_event_id] = 23093 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 23094 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 23095 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 23096 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 23097 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 23098 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 23099 event_ids[wmi_pdev_hw_mode_transition_event_id] = 23100 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 23101 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 23102 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 23103 event_ids[wmi_coex_bt_activity_event_id] = 23104 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 23105 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 23106 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 23107 event_ids[wmi_radio_tx_power_level_stats_event_id] = 23108 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 23109 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 23110 event_ids[wmi_dma_buf_release_event_id] = 23111 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 23112 event_ids[wmi_sap_obss_detection_report_event_id] = 23113 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 23114 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 23115 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 23116 event_ids[wmi_obss_color_collision_report_event_id] = 23117 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 23118 } 23119 23120 /** 23121 * populate_tlv_service() - populates wmi services 23122 * 23123 * @param wmi_service: Pointer to hold wmi_service 23124 * Return: None 23125 */ 23126 static void populate_tlv_service(uint32_t *wmi_service) 23127 { 23128 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 23129 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 23130 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 23131 wmi_service[wmi_service_roam_scan_offload] = 23132 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 23133 wmi_service[wmi_service_bcn_miss_offload] = 23134 WMI_SERVICE_BCN_MISS_OFFLOAD; 23135 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 23136 wmi_service[wmi_service_sta_advanced_pwrsave] = 23137 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 23138 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 23139 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 23140 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 23141 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 23142 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 23143 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 23144 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 23145 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 23146 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 23147 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 23148 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 23149 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 23150 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 23151 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 23152 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 23153 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 23154 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 23155 wmi_service[wmi_service_packet_power_save] = 23156 WMI_SERVICE_PACKET_POWER_SAVE; 23157 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 23158 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 23159 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 23160 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 23161 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 23162 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 23163 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 23164 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 23165 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 23166 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 23167 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 23168 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 23169 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 23170 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 23171 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 23172 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 23173 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 23174 wmi_service[wmi_service_mcc_bcn_interval_change] = 23175 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 23176 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 23177 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 23178 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 23179 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 23180 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 23181 wmi_service[wmi_service_lte_ant_share_support] = 23182 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 23183 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 23184 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 23185 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 23186 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 23187 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 23188 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 23189 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 23190 wmi_service[wmi_service_bcn_txrate_override] = 23191 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 23192 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 23193 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 23194 wmi_service[wmi_service_estimate_linkspeed] = 23195 WMI_SERVICE_ESTIMATE_LINKSPEED; 23196 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 23197 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 23198 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 23199 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 23200 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 23201 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 23202 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 23203 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 23204 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 23205 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 23206 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 23207 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 23208 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 23209 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 23210 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 23211 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 23212 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 23213 wmi_service[wmi_service_sap_auth_offload] = 23214 WMI_SERVICE_SAP_AUTH_OFFLOAD; 23215 wmi_service[wmi_service_dual_band_simultaneous_support] = 23216 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 23217 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 23218 wmi_service[wmi_service_ap_arpns_offload] = 23219 WMI_SERVICE_AP_ARPNS_OFFLOAD; 23220 wmi_service[wmi_service_per_band_chainmask_support] = 23221 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 23222 wmi_service[wmi_service_packet_filter_offload] = 23223 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 23224 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 23225 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 23226 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 23227 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 23228 wmi_service[wmi_service_multiple_vdev_restart] = 23229 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 23230 23231 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 23232 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 23233 wmi_service[wmi_service_smart_antenna_sw_support] = 23234 WMI_SERVICE_UNAVAILABLE; 23235 wmi_service[wmi_service_smart_antenna_hw_support] = 23236 WMI_SERVICE_UNAVAILABLE; 23237 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 23238 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 23239 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 23240 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 23241 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 23242 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 23243 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 23244 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 23245 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 23246 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 23247 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 23248 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 23249 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 23250 wmi_service[wmi_service_periodic_chan_stat_support] = 23251 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 23252 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 23253 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 23254 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 23255 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 23256 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 23257 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23258 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 23259 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 23260 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 23261 wmi_service[wmi_service_unified_wow_capability] = 23262 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 23263 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23264 wmi_service[wmi_service_bpf_offload] = WMI_SERVICE_BPF_OFFLOAD; 23265 wmi_service[wmi_service_sync_delete_cmds] = 23266 WMI_SERVICE_SYNC_DELETE_CMDS; 23267 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 23268 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 23269 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 23270 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 23271 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 23272 wmi_service[wmi_service_deprecated_replace] = 23273 WMI_SERVICE_DEPRECATED_REPLACE; 23274 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 23275 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 23276 wmi_service[wmi_service_enhanced_mcast_filter] = 23277 WMI_SERVICE_ENHANCED_MCAST_FILTER; 23278 wmi_service[wmi_service_half_rate_quarter_rate_support] = 23279 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 23280 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 23281 wmi_service[wmi_service_p2p_listen_offload_support] = 23282 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 23283 wmi_service[wmi_service_mark_first_wakeup_packet] = 23284 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 23285 wmi_service[wmi_service_multiple_mcast_filter_set] = 23286 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 23287 wmi_service[wmi_service_host_managed_rx_reorder] = 23288 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 23289 wmi_service[wmi_service_flash_rdwr_support] = 23290 WMI_SERVICE_FLASH_RDWR_SUPPORT; 23291 wmi_service[wmi_service_wlan_stats_report] = 23292 WMI_SERVICE_WLAN_STATS_REPORT; 23293 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 23294 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 23295 wmi_service[wmi_service_dfs_phyerr_offload] = 23296 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 23297 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 23298 wmi_service[wmi_service_fw_mem_dump_support] = 23299 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 23300 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 23301 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 23302 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 23303 wmi_service[wmi_service_hw_data_filtering] = 23304 WMI_SERVICE_HW_DATA_FILTERING; 23305 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 23306 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 23307 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 23308 wmi_service[wmi_service_extended_nss_support] = 23309 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 23310 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 23311 wmi_service[wmi_service_bcn_offload_start_stop_support] = 23312 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 23313 wmi_service[wmi_service_offchan_data_tid_support] = 23314 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 23315 wmi_service[wmi_service_support_dma] = 23316 WMI_SERVICE_SUPPORT_DIRECT_DMA; 23317 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 23318 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 23319 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 23320 wmi_service[wmi_service_11k_neighbour_report_support] = 23321 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 23322 wmi_service[wmi_service_ap_obss_detection_offload] = 23323 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 23324 wmi_service[wmi_service_bss_color_offload] = 23325 WMI_SERVICE_BSS_COLOR_OFFLOAD; 23326 wmi_service[wmi_service_gmac_offload_support] = 23327 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 23328 23329 } 23330 23331 #ifndef CONFIG_MCL 23332 23333 /** 23334 * populate_pdev_param_tlv() - populates pdev params 23335 * 23336 * @param pdev_param: Pointer to hold pdev params 23337 * Return: None 23338 */ 23339 static void populate_pdev_param_tlv(uint32_t *pdev_param) 23340 { 23341 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 23342 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 23343 pdev_param[wmi_pdev_param_txpower_limit2g] = 23344 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 23345 pdev_param[wmi_pdev_param_txpower_limit5g] = 23346 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 23347 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 23348 pdev_param[wmi_pdev_param_beacon_gen_mode] = 23349 WMI_PDEV_PARAM_BEACON_GEN_MODE; 23350 pdev_param[wmi_pdev_param_beacon_tx_mode] = 23351 WMI_PDEV_PARAM_BEACON_TX_MODE; 23352 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 23353 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 23354 pdev_param[wmi_pdev_param_protection_mode] = 23355 WMI_PDEV_PARAM_PROTECTION_MODE; 23356 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 23357 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 23358 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 23359 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 23360 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 23361 pdev_param[wmi_pdev_param_sta_kickout_th] = 23362 WMI_PDEV_PARAM_STA_KICKOUT_TH; 23363 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 23364 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 23365 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 23366 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 23367 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 23368 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 23369 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 23370 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 23371 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 23372 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 23373 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 23374 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 23375 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 23376 pdev_param[wmi_pdev_param_ltr_sleep_override] = 23377 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 23378 pdev_param[wmi_pdev_param_ltr_rx_override] = 23379 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 23380 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 23381 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 23382 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 23383 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 23384 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 23385 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 23386 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 23387 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 23388 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 23389 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 23390 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 23391 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 23392 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 23393 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 23394 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 23395 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 23396 pdev_param[wmi_pdev_param_peer_stats_update_period] = 23397 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 23398 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 23399 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 23400 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 23401 pdev_param[wmi_pdev_param_arp_ac_override] = 23402 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 23403 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 23404 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 23405 pdev_param[wmi_pdev_param_ani_poll_period] = 23406 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 23407 pdev_param[wmi_pdev_param_ani_listen_period] = 23408 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 23409 pdev_param[wmi_pdev_param_ani_ofdm_level] = 23410 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 23411 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 23412 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 23413 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 23414 pdev_param[wmi_pdev_param_idle_ps_config] = 23415 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 23416 pdev_param[wmi_pdev_param_power_gating_sleep] = 23417 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 23418 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 23419 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 23420 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 23421 pdev_param[wmi_pdev_param_hw_rfkill_config] = 23422 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 23423 pdev_param[wmi_pdev_param_low_power_rf_enable] = 23424 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 23425 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 23426 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 23427 pdev_param[wmi_pdev_param_power_collapse_enable] = 23428 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 23429 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 23430 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 23431 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 23432 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 23433 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 23434 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 23435 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 23436 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 23437 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 23438 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 23439 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 23440 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 23441 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 23442 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 23443 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 23444 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 23445 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 23446 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 23447 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 23448 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 23449 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 23450 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 23451 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 23452 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 23453 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 23454 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 23455 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 23456 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 23457 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 23458 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 23459 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 23460 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 23461 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 23462 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 23463 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 23464 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 23465 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 23466 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 23467 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 23468 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 23469 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 23470 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 23471 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23472 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23473 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23474 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23475 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23476 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23477 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23478 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23479 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23480 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23481 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23482 WMI_PDEV_PARAM_PROXY_STA_MODE; 23483 pdev_param[wmi_pdev_param_mu_group_policy] = 23484 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23485 pdev_param[wmi_pdev_param_noise_detection] = 23486 WMI_PDEV_PARAM_NOISE_DETECTION; 23487 pdev_param[wmi_pdev_param_noise_threshold] = 23488 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23489 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23490 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23491 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23492 pdev_param[wmi_pdev_param_atf_strict_sch] = 23493 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23494 pdev_param[wmi_pdev_param_atf_sched_duration] = 23495 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23496 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23497 pdev_param[wmi_pdev_param_sensitivity_level] = 23498 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23499 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23500 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23501 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23502 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23503 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23504 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23505 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23506 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23507 pdev_param[wmi_pdev_param_cca_threshold] = 23508 WMI_PDEV_PARAM_CCA_THRESHOLD; 23509 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23510 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23511 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23512 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23513 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23514 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23515 pdev_param[wmi_pdev_param_arp_srcaddr] = 23516 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23517 pdev_param[wmi_pdev_param_arp_dstaddr] = 23518 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23519 pdev_param[wmi_pdev_param_txpower_decr_db] = 23520 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23521 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23522 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23523 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23524 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23525 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23526 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23527 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23528 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23529 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23530 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23531 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23532 WMI_UNAVAILABLE_PARAM; 23533 pdev_param[wmi_pdev_param_igmpmld_override] = WMI_UNAVAILABLE_PARAM; 23534 pdev_param[wmi_pdev_param_igmpmld_tid] = WMI_UNAVAILABLE_PARAM; 23535 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23536 pdev_param[wmi_pdev_param_block_interbss] = 23537 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23538 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23539 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23540 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23541 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23542 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23543 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23544 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23545 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23546 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23547 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23548 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23549 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23550 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23551 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23552 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23553 pdev_param[wmi_pdev_param_igmpmld_ac_override] = 23554 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23555 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23556 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23557 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23558 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23559 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23560 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23561 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23562 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23563 pdev_param[wmi_pdev_param_fast_channel_reset] = 23564 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23565 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23566 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23567 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23568 } 23569 23570 /** 23571 * populate_vdev_param_tlv() - populates vdev params 23572 * 23573 * @param vdev_param: Pointer to hold vdev params 23574 * Return: None 23575 */ 23576 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23577 { 23578 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23579 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23580 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23581 vdev_param[wmi_vdev_param_beacon_interval] = 23582 WMI_VDEV_PARAM_BEACON_INTERVAL; 23583 vdev_param[wmi_vdev_param_listen_interval] = 23584 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23585 vdev_param[wmi_vdev_param_multicast_rate] = 23586 WMI_VDEV_PARAM_MULTICAST_RATE; 23587 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23588 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23589 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23590 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23591 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23592 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23593 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23594 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23595 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23596 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23597 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23598 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23599 vdev_param[wmi_vdev_param_bmiss_count_max] = 23600 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23601 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23602 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23603 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23604 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23605 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23606 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23607 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23608 vdev_param[wmi_vdev_param_disable_htprotection] = 23609 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23610 vdev_param[wmi_vdev_param_sta_quickkickout] = 23611 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23612 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23613 vdev_param[wmi_vdev_param_protection_mode] = 23614 WMI_VDEV_PARAM_PROTECTION_MODE; 23615 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23616 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23617 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23618 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23619 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23620 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23621 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23622 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23623 vdev_param[wmi_vdev_param_bcast_data_rate] = 23624 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23625 vdev_param[wmi_vdev_param_mcast_data_rate] = 23626 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23627 vdev_param[wmi_vdev_param_mcast_indicate] = 23628 WMI_VDEV_PARAM_MCAST_INDICATE; 23629 vdev_param[wmi_vdev_param_dhcp_indicate] = 23630 WMI_VDEV_PARAM_DHCP_INDICATE; 23631 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23632 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23633 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23634 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23635 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23636 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23637 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23638 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23639 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23640 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23641 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23642 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23643 vdev_param[wmi_vdev_param_packet_powersave] = 23644 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23645 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23646 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23647 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23648 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23649 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23650 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23651 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23652 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23653 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23654 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23655 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23656 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23657 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23658 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23659 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23660 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23661 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23662 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23663 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23664 vdev_param[wmi_vdev_param_roam_fw_offload] = 23665 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23666 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23667 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23668 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23669 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23670 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23671 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23672 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23673 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23674 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23675 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23676 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23677 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23678 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23679 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23680 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23681 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23682 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23683 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23684 vdev_param[wmi_vdev_param_inactivity_cnt] = 23685 WMI_VDEV_PARAM_INACTIVITY_CNT; 23686 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23687 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23688 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23689 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23690 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23691 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23692 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23693 vdev_param[wmi_vdev_param_rx_leak_window] = 23694 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23695 vdev_param[wmi_vdev_param_stats_avg_factor] = 23696 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23697 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23698 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23699 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23700 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23701 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23702 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23703 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23704 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23705 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23706 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23707 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23708 WMI_VDEV_PARAM_HE_RANGE_EXT; 23709 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23710 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23711 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23712 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23713 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23714 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23715 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23716 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23717 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23718 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23719 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23720 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23721 vdev_param[wmi_vdev_param_rc_num_retries] = 23722 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23723 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23724 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23725 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23726 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23727 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23728 vdev_param[wmi_vdev_param_vht80_ratemask] = 23729 WMI_VDEV_PARAM_VHT80_RATEMASK; 23730 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23731 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23732 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23733 vdev_param[wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF; 23734 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23735 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23736 vdev_param[wmi_vdev_param_set_ba_mode] = 23737 WMI_VDEV_PARAM_BA_MODE; 23738 } 23739 #endif 23740 23741 /** 23742 * populate_target_defines_tlv() - Populate target defines and params 23743 * @wmi_handle: pointer to wmi handle 23744 * 23745 * Return: None 23746 */ 23747 #ifndef CONFIG_MCL 23748 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23749 { 23750 populate_pdev_param_tlv(wmi_handle->pdev_param); 23751 populate_vdev_param_tlv(wmi_handle->vdev_param); 23752 } 23753 #else 23754 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23755 { } 23756 #endif 23757 23758 /** 23759 * wmi_ocb_ut_attach() - Attach OCB test framework 23760 * @wmi_handle: wmi handle 23761 * 23762 * Return: None 23763 */ 23764 #ifdef WLAN_OCB_UT 23765 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23766 #else 23767 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23768 { 23769 return; 23770 } 23771 #endif 23772 23773 /** 23774 * wmi_tlv_attach() - Attach TLV APIs 23775 * 23776 * Return: None 23777 */ 23778 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23779 { 23780 wmi_handle->ops = &tlv_ops; 23781 wmi_ocb_ut_attach(wmi_handle); 23782 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23783 #ifdef WMI_INTERFACE_EVENT_LOGGING 23784 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23785 wmi_handle->log_info.buf_offset_command = 8; 23786 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23787 wmi_handle->log_info.buf_offset_event = 4; 23788 #endif 23789 populate_tlv_events_id(wmi_handle->wmi_events); 23790 populate_tlv_service(wmi_handle->services); 23791 populate_target_defines_tlv(wmi_handle); 23792 } 23793 EXPORT_SYMBOL(wmi_tlv_attach); 23794 23795 /** 23796 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23797 * 23798 * Return: None 23799 */ 23800 void wmi_tlv_init(void) 23801 { 23802 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23803 } 23804