1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "wmi_unified_api.h" 20 #include "wmi.h" 21 #include "wmi_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_version_whitelist.h" 24 #include <qdf_module.h> 25 #include <wlan_defs.h> 26 #include <htc_services.h> 27 28 #ifdef CONVERGED_P2P_ENABLE 29 #include "wlan_p2p_public_struct.h" 30 #endif 31 #ifdef WLAN_PMO_ENABLE 32 #include "wlan_pmo_hw_filter_public_struct.h" 33 #endif 34 #include <wlan_utility.h> 35 #ifdef WLAN_SUPPORT_GREEN_AP 36 #include "wlan_green_ap_api.h" 37 #endif 38 39 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 40 #include "nan_public_structs.h" 41 #endif 42 43 #ifdef WLAN_POLICY_MGR_ENABLE 44 #include "wlan_policy_mgr_public_struct.h" 45 #endif 46 47 /* HTC service ids for WMI for multi-radio */ 48 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 49 WMI_CONTROL_SVC_WMAC1, 50 WMI_CONTROL_SVC_WMAC2}; 51 52 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 53 * buffer. 54 * @wmi_handle: pointer to wmi_handle 55 * @cmd: pointer target vdev create command buffer 56 * @param: pointer host params for vdev create 57 * 58 * Return: None 59 */ 60 #ifdef CONFIG_MCL 61 static inline void copy_vdev_create_pdev_id( 62 struct wmi_unified *wmi_handle, 63 wmi_vdev_create_cmd_fixed_param * cmd, 64 struct vdev_create_params *param) 65 { 66 cmd->pdev_id = WMI_PDEV_ID_SOC; 67 } 68 #else 69 static inline void copy_vdev_create_pdev_id( 70 struct wmi_unified *wmi_handle, 71 wmi_vdev_create_cmd_fixed_param * cmd, 72 struct vdev_create_params *param) 73 { 74 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 75 param->pdev_id); 76 } 77 #endif 78 79 /** 80 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 81 * @wmi_handle: wmi handle 82 * @param: pointer to hold vdev create parameter 83 * @macaddr: vdev mac address 84 * 85 * Return: QDF_STATUS_SUCCESS for success or error code 86 */ 87 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 88 uint8_t macaddr[IEEE80211_ADDR_LEN], 89 struct vdev_create_params *param) 90 { 91 wmi_vdev_create_cmd_fixed_param *cmd; 92 wmi_buf_t buf; 93 int32_t len = sizeof(*cmd); 94 QDF_STATUS ret; 95 int num_bands = 2; 96 uint8_t *buf_ptr; 97 wmi_vdev_txrx_streams *txrx_streams; 98 99 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 100 buf = wmi_buf_alloc(wmi_handle, len); 101 if (!buf) { 102 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 103 return QDF_STATUS_E_NOMEM; 104 } 105 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 106 WMITLV_SET_HDR(&cmd->tlv_header, 107 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 108 WMITLV_GET_STRUCT_TLVLEN 109 (wmi_vdev_create_cmd_fixed_param)); 110 cmd->vdev_id = param->if_id; 111 cmd->vdev_type = param->type; 112 cmd->vdev_subtype = param->subtype; 113 cmd->num_cfg_txrx_streams = num_bands; 114 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 115 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 116 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 117 __func__, param->if_id, cmd->pdev_id, 118 macaddr[0], macaddr[1], macaddr[2], 119 macaddr[3], macaddr[4], macaddr[5]); 120 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 121 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 122 (num_bands * sizeof(wmi_vdev_txrx_streams))); 123 buf_ptr += WMI_TLV_HDR_SIZE; 124 125 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 126 param->type, param->subtype, 127 param->nss_2g, param->nss_5g); 128 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 129 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 130 txrx_streams->supported_tx_streams = param->nss_2g; 131 txrx_streams->supported_rx_streams = param->nss_2g; 132 WMITLV_SET_HDR(&txrx_streams->tlv_header, 133 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 134 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 135 136 txrx_streams++; 137 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 138 txrx_streams->supported_tx_streams = param->nss_5g; 139 txrx_streams->supported_rx_streams = param->nss_5g; 140 WMITLV_SET_HDR(&txrx_streams->tlv_header, 141 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 142 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 143 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 144 if (QDF_IS_STATUS_ERROR(ret)) { 145 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 146 wmi_buf_free(buf); 147 } 148 149 return ret; 150 } 151 152 /** 153 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 154 * @wmi_handle: wmi handle 155 * @if_id: vdev id 156 * 157 * Return: QDF_STATUS_SUCCESS for success or error code 158 */ 159 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 160 uint8_t if_id) 161 { 162 wmi_vdev_delete_cmd_fixed_param *cmd; 163 wmi_buf_t buf; 164 QDF_STATUS ret; 165 166 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 167 if (!buf) { 168 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 169 return QDF_STATUS_E_NOMEM; 170 } 171 172 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 173 WMITLV_SET_HDR(&cmd->tlv_header, 174 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 175 WMITLV_GET_STRUCT_TLVLEN 176 (wmi_vdev_delete_cmd_fixed_param)); 177 cmd->vdev_id = if_id; 178 ret = wmi_unified_cmd_send(wmi_handle, buf, 179 sizeof(wmi_vdev_delete_cmd_fixed_param), 180 WMI_VDEV_DELETE_CMDID); 181 if (QDF_IS_STATUS_ERROR(ret)) { 182 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 183 wmi_buf_free(buf); 184 } 185 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 186 187 return ret; 188 } 189 190 /** 191 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 192 * @wmi: wmi handle 193 * @vdev_id: vdev id 194 * 195 * Return: QDF_STATUS_SUCCESS for success or erro code 196 */ 197 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 198 uint8_t vdev_id) 199 { 200 wmi_vdev_stop_cmd_fixed_param *cmd; 201 wmi_buf_t buf; 202 int32_t len = sizeof(*cmd); 203 204 buf = wmi_buf_alloc(wmi, len); 205 if (!buf) { 206 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 207 return QDF_STATUS_E_NOMEM; 208 } 209 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 210 WMITLV_SET_HDR(&cmd->tlv_header, 211 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 212 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 213 cmd->vdev_id = vdev_id; 214 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 215 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 216 wmi_buf_free(buf); 217 return QDF_STATUS_E_FAILURE; 218 } 219 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 220 221 return 0; 222 } 223 224 /** 225 * send_vdev_down_cmd_tlv() - send vdev down command to fw 226 * @wmi: wmi handle 227 * @vdev_id: vdev id 228 * 229 * Return: QDF_STATUS_SUCCESS for success or error code 230 */ 231 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 232 { 233 wmi_vdev_down_cmd_fixed_param *cmd; 234 wmi_buf_t buf; 235 int32_t len = sizeof(*cmd); 236 237 buf = wmi_buf_alloc(wmi, len); 238 if (!buf) { 239 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 240 return QDF_STATUS_E_NOMEM; 241 } 242 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 243 WMITLV_SET_HDR(&cmd->tlv_header, 244 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 245 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 246 cmd->vdev_id = vdev_id; 247 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 248 WMI_LOGP("%s: Failed to send vdev down", __func__); 249 wmi_buf_free(buf); 250 return QDF_STATUS_E_FAILURE; 251 } 252 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 253 254 return 0; 255 } 256 257 #ifdef CONFIG_MCL 258 static inline void copy_channel_info( 259 wmi_vdev_start_request_cmd_fixed_param * cmd, 260 wmi_channel *chan, 261 struct vdev_start_params *req) 262 { 263 chan->mhz = req->chan_freq; 264 265 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 266 267 chan->band_center_freq1 = req->band_center_freq1; 268 chan->band_center_freq2 = req->band_center_freq2; 269 270 if (req->is_half_rate) 271 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 272 else if (req->is_quarter_rate) 273 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 274 275 if (req->is_dfs && req->flag_dfs) { 276 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 277 cmd->disable_hw_ack = req->dis_hw_ack; 278 } 279 280 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 281 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 282 283 } 284 #else 285 static inline void copy_channel_info( 286 wmi_vdev_start_request_cmd_fixed_param * cmd, 287 wmi_channel *chan, 288 struct vdev_start_params *req) 289 { 290 chan->mhz = req->channel.mhz; 291 292 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 293 294 chan->band_center_freq1 = req->channel.cfreq1; 295 chan->band_center_freq2 = req->channel.cfreq2; 296 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 297 298 if (req->channel.half_rate) 299 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 300 else if (req->channel.quarter_rate) 301 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 302 303 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 304 305 if (req->channel.dfs_set) { 306 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 307 cmd->disable_hw_ack = req->disable_hw_ack; 308 } 309 310 if (req->channel.dfs_set_cfreq2) 311 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 312 313 /* According to firmware both reg power and max tx power 314 * on set channel power is used and set it to max reg 315 * power from regulatory. 316 */ 317 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 318 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 319 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 320 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 321 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 322 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 323 324 } 325 #endif 326 /** 327 * send_vdev_start_cmd_tlv() - send vdev start request to fw 328 * @wmi_handle: wmi handle 329 * @req: vdev start params 330 * 331 * Return: QDF status 332 */ 333 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 334 struct vdev_start_params *req) 335 { 336 wmi_vdev_start_request_cmd_fixed_param *cmd; 337 wmi_buf_t buf; 338 wmi_channel *chan; 339 int32_t len, ret; 340 uint8_t *buf_ptr; 341 342 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 343 buf = wmi_buf_alloc(wmi_handle, len); 344 if (!buf) { 345 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 346 return QDF_STATUS_E_NOMEM; 347 } 348 buf_ptr = (uint8_t *) wmi_buf_data(buf); 349 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 350 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 351 WMITLV_SET_HDR(&cmd->tlv_header, 352 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 353 WMITLV_GET_STRUCT_TLVLEN 354 (wmi_vdev_start_request_cmd_fixed_param)); 355 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 356 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 357 cmd->vdev_id = req->vdev_id; 358 359 /* Fill channel info */ 360 copy_channel_info(cmd, chan, req); 361 362 cmd->beacon_interval = req->beacon_intval; 363 cmd->dtim_period = req->dtim_period; 364 365 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 366 if (req->bcn_tx_rate_code) 367 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 368 369 if (!req->is_restart) { 370 cmd->beacon_interval = req->beacon_intval; 371 cmd->dtim_period = req->dtim_period; 372 373 /* Copy the SSID */ 374 if (req->ssid.length) { 375 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 376 cmd->ssid.ssid_len = req->ssid.length; 377 else 378 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 379 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 380 cmd->ssid.ssid_len); 381 } 382 383 if (req->hidden_ssid) 384 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 385 386 if (req->pmf_enabled) 387 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 388 } 389 390 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 391 cmd->num_noa_descriptors = req->num_noa_descriptors; 392 cmd->preferred_rx_streams = req->preferred_rx_streams; 393 cmd->preferred_tx_streams = req->preferred_tx_streams; 394 cmd->cac_duration_ms = req->cac_duration_ms; 395 cmd->regdomain = req->regdomain; 396 cmd->he_ops = req->he_ops; 397 398 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 399 sizeof(wmi_channel)); 400 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 401 cmd->num_noa_descriptors * 402 sizeof(wmi_p2p_noa_descriptor)); 403 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 404 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 405 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 406 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 407 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 408 chan->mhz, req->chan_mode, chan->info, 409 req->is_dfs, req->beacon_intval, cmd->dtim_period, 410 chan->band_center_freq1, chan->band_center_freq2, 411 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 412 req->preferred_tx_streams, req->preferred_rx_streams, 413 req->ldpc_rx_enabled, req->cac_duration_ms, 414 req->regdomain, req->he_ops, 415 req->dis_hw_ack); 416 417 if (req->is_restart) 418 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 419 WMI_VDEV_RESTART_REQUEST_CMDID); 420 else 421 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 422 WMI_VDEV_START_REQUEST_CMDID); 423 if (ret) { 424 WMI_LOGP("%s: Failed to send vdev start command", __func__); 425 wmi_buf_free(buf); 426 return QDF_STATUS_E_FAILURE; 427 } 428 429 return QDF_STATUS_SUCCESS; 430 } 431 432 /** 433 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 434 * @wmi_handle: wmi handle 435 * @restart_params: vdev restart params 436 * 437 * Return: QDF_STATUS_SUCCESS for success or error code 438 */ 439 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 440 struct hidden_ssid_vdev_restart_params *restart_params) 441 { 442 wmi_vdev_start_request_cmd_fixed_param *cmd; 443 wmi_buf_t buf; 444 wmi_channel *chan; 445 int32_t len; 446 uint8_t *buf_ptr; 447 QDF_STATUS ret = 0; 448 449 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 450 buf = wmi_buf_alloc(wmi_handle, len); 451 if (!buf) { 452 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 453 return QDF_STATUS_E_NOMEM; 454 } 455 buf_ptr = (uint8_t *) wmi_buf_data(buf); 456 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 457 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 458 459 WMITLV_SET_HDR(&cmd->tlv_header, 460 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 461 WMITLV_GET_STRUCT_TLVLEN 462 (wmi_vdev_start_request_cmd_fixed_param)); 463 464 WMITLV_SET_HDR(&chan->tlv_header, 465 WMITLV_TAG_STRUC_wmi_channel, 466 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 467 468 cmd->vdev_id = restart_params->session_id; 469 cmd->ssid.ssid_len = restart_params->ssid_len; 470 qdf_mem_copy(cmd->ssid.ssid, 471 restart_params->ssid, 472 cmd->ssid.ssid_len); 473 cmd->flags = restart_params->flags; 474 cmd->requestor_id = restart_params->requestor_id; 475 cmd->disable_hw_ack = restart_params->disable_hw_ack; 476 477 chan->mhz = restart_params->mhz; 478 chan->band_center_freq1 = 479 restart_params->band_center_freq1; 480 chan->band_center_freq2 = 481 restart_params->band_center_freq2; 482 chan->info = restart_params->info; 483 chan->reg_info_1 = restart_params->reg_info_1; 484 chan->reg_info_2 = restart_params->reg_info_2; 485 486 cmd->num_noa_descriptors = 0; 487 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 488 sizeof(wmi_channel)); 489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 490 cmd->num_noa_descriptors * 491 sizeof(wmi_p2p_noa_descriptor)); 492 493 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 494 WMI_VDEV_RESTART_REQUEST_CMDID); 495 if (QDF_IS_STATUS_ERROR(ret)) { 496 wmi_buf_free(buf); 497 return QDF_STATUS_E_FAILURE; 498 } 499 return QDF_STATUS_SUCCESS; 500 } 501 502 503 /** 504 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 505 * @wmi: wmi handle 506 * @peer_addr: peer mac address 507 * @param: pointer to hold peer flush tid parameter 508 * 509 * Return: 0 for success or error code 510 */ 511 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 512 uint8_t peer_addr[IEEE80211_ADDR_LEN], 513 struct peer_flush_params *param) 514 { 515 wmi_peer_flush_tids_cmd_fixed_param *cmd; 516 wmi_buf_t buf; 517 int32_t len = sizeof(*cmd); 518 519 buf = wmi_buf_alloc(wmi, len); 520 if (!buf) { 521 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 522 return QDF_STATUS_E_NOMEM; 523 } 524 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 525 WMITLV_SET_HDR(&cmd->tlv_header, 526 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 527 WMITLV_GET_STRUCT_TLVLEN 528 (wmi_peer_flush_tids_cmd_fixed_param)); 529 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 530 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 531 cmd->vdev_id = param->vdev_id; 532 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 533 peer_addr, param->vdev_id, 534 param->peer_tid_bitmap); 535 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 536 WMI_LOGP("%s: Failed to send flush tid command", __func__); 537 wmi_buf_free(buf); 538 return QDF_STATUS_E_FAILURE; 539 } 540 541 return 0; 542 } 543 544 /** 545 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 546 * @wmi: wmi handle 547 * @peer_addr: peer mac addr 548 * @vdev_id: vdev id 549 * 550 * Return: QDF_STATUS_SUCCESS for success or error code 551 */ 552 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 553 uint8_t peer_addr[IEEE80211_ADDR_LEN], 554 uint8_t vdev_id) 555 { 556 wmi_peer_delete_cmd_fixed_param *cmd; 557 wmi_buf_t buf; 558 int32_t len = sizeof(*cmd); 559 buf = wmi_buf_alloc(wmi, len); 560 if (!buf) { 561 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 562 return QDF_STATUS_E_NOMEM; 563 } 564 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 565 WMITLV_SET_HDR(&cmd->tlv_header, 566 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 567 WMITLV_GET_STRUCT_TLVLEN 568 (wmi_peer_delete_cmd_fixed_param)); 569 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 570 cmd->vdev_id = vdev_id; 571 572 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 573 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 574 WMI_LOGP("%s: Failed to send peer delete command", __func__); 575 wmi_buf_free(buf); 576 return QDF_STATUS_E_FAILURE; 577 } 578 579 return 0; 580 } 581 582 /** 583 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 584 * to target id. 585 * @targ_paramid: Target parameter id to hold the result. 586 * @peer_param_id: host param id. 587 * 588 * Return: QDF_STATUS_SUCCESS for success 589 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 590 */ 591 #ifdef CONFIG_MCL 592 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 593 uint32_t *targ_paramid, 594 uint32_t peer_param_id) 595 { 596 *targ_paramid = peer_param_id; 597 return QDF_STATUS_SUCCESS; 598 } 599 #else 600 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 601 uint32_t *targ_paramid, 602 uint32_t peer_param_id) 603 { 604 switch (peer_param_id) { 605 case WMI_HOST_PEER_MIMO_PS_STATE: 606 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 607 break; 608 case WMI_HOST_PEER_AMPDU: 609 *targ_paramid = WMI_PEER_AMPDU; 610 break; 611 case WMI_HOST_PEER_AUTHORIZE: 612 *targ_paramid = WMI_PEER_AUTHORIZE; 613 break; 614 case WMI_HOST_PEER_CHWIDTH: 615 *targ_paramid = WMI_PEER_CHWIDTH; 616 break; 617 case WMI_HOST_PEER_NSS: 618 *targ_paramid = WMI_PEER_NSS; 619 break; 620 case WMI_HOST_PEER_USE_4ADDR: 621 *targ_paramid = WMI_PEER_USE_4ADDR; 622 break; 623 case WMI_HOST_PEER_MEMBERSHIP: 624 *targ_paramid = WMI_PEER_MEMBERSHIP; 625 break; 626 case WMI_HOST_PEER_USERPOS: 627 *targ_paramid = WMI_PEER_USERPOS; 628 break; 629 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 630 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 631 break; 632 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 633 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 634 break; 635 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 636 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 637 break; 638 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 639 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 640 break; 641 case WMI_HOST_PEER_PHYMODE: 642 *targ_paramid = WMI_PEER_PHYMODE; 643 break; 644 case WMI_HOST_PEER_USE_FIXED_PWR: 645 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 646 break; 647 case WMI_HOST_PEER_PARAM_FIXED_RATE: 648 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 649 break; 650 case WMI_HOST_PEER_SET_MU_WHITELIST: 651 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 652 break; 653 case WMI_HOST_PEER_SET_MAC_TX_RATE: 654 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 655 break; 656 case WMI_HOST_PEER_SET_MIN_TX_RATE: 657 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 658 break; 659 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 660 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 661 break; 662 case WMI_HOST_PEER_NSS_VHT160: 663 *targ_paramid = WMI_PEER_NSS_VHT160; 664 break; 665 case WMI_HOST_PEER_NSS_VHT80_80: 666 *targ_paramid = WMI_PEER_NSS_VHT80_80; 667 break; 668 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 669 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 670 break; 671 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 672 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 673 break; 674 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 675 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 676 break; 677 case WMI_HOST_PEER_PARAM_MU_ENABLE: 678 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 679 break; 680 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 681 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 682 break; 683 default: 684 return QDF_STATUS_E_NOSUPPORT; 685 } 686 687 return QDF_STATUS_SUCCESS; 688 } 689 #endif 690 /** 691 * send_peer_param_cmd_tlv() - set peer parameter in fw 692 * @wmi: wmi handle 693 * @peer_addr: peer mac address 694 * @param : pointer to hold peer set parameter 695 * 696 * Return: QDF_STATUS_SUCCESS for success or error code 697 */ 698 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 699 uint8_t peer_addr[IEEE80211_ADDR_LEN], 700 struct peer_set_params *param) 701 { 702 wmi_peer_set_param_cmd_fixed_param *cmd; 703 wmi_buf_t buf; 704 int32_t err; 705 uint32_t param_id; 706 707 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 708 param->param_id) != QDF_STATUS_SUCCESS) 709 return QDF_STATUS_E_NOSUPPORT; 710 711 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 712 if (!buf) { 713 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 714 return QDF_STATUS_E_NOMEM; 715 } 716 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 717 WMITLV_SET_HDR(&cmd->tlv_header, 718 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 719 WMITLV_GET_STRUCT_TLVLEN 720 (wmi_peer_set_param_cmd_fixed_param)); 721 cmd->vdev_id = param->vdev_id; 722 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 723 cmd->param_id = param_id; 724 cmd->param_value = param->param_value; 725 err = wmi_unified_cmd_send(wmi, buf, 726 sizeof(wmi_peer_set_param_cmd_fixed_param), 727 WMI_PEER_SET_PARAM_CMDID); 728 if (err) { 729 WMI_LOGE("Failed to send set_param cmd"); 730 wmi_buf_free(buf); 731 return QDF_STATUS_E_FAILURE; 732 } 733 734 return 0; 735 } 736 737 /** 738 * send_vdev_up_cmd_tlv() - send vdev up command in fw 739 * @wmi: wmi handle 740 * @bssid: bssid 741 * @vdev_up_params: pointer to hold vdev up parameter 742 * 743 * Return: QDF_STATUS_SUCCESS for success or error code 744 */ 745 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 746 uint8_t bssid[IEEE80211_ADDR_LEN], 747 struct vdev_up_params *params) 748 { 749 wmi_vdev_up_cmd_fixed_param *cmd; 750 wmi_buf_t buf; 751 int32_t len = sizeof(*cmd); 752 753 WMI_LOGD("%s: VDEV_UP", __func__); 754 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 755 params->vdev_id, params->assoc_id, bssid); 756 buf = wmi_buf_alloc(wmi, len); 757 if (!buf) { 758 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 759 return QDF_STATUS_E_NOMEM; 760 } 761 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 762 WMITLV_SET_HDR(&cmd->tlv_header, 763 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 764 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 765 cmd->vdev_id = params->vdev_id; 766 cmd->vdev_assoc_id = params->assoc_id; 767 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 768 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 769 WMI_LOGP("%s: Failed to send vdev up command", __func__); 770 wmi_buf_free(buf); 771 return QDF_STATUS_E_FAILURE; 772 } 773 774 return 0; 775 } 776 777 /** 778 * send_peer_create_cmd_tlv() - send peer create command to fw 779 * @wmi: wmi handle 780 * @peer_addr: peer mac address 781 * @peer_type: peer type 782 * @vdev_id: vdev id 783 * 784 * Return: QDF_STATUS_SUCCESS for success or error code 785 */ 786 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 787 struct peer_create_params *param) 788 { 789 wmi_peer_create_cmd_fixed_param *cmd; 790 wmi_buf_t buf; 791 int32_t len = sizeof(*cmd); 792 793 buf = wmi_buf_alloc(wmi, len); 794 if (!buf) { 795 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 796 return QDF_STATUS_E_NOMEM; 797 } 798 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 799 WMITLV_SET_HDR(&cmd->tlv_header, 800 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 801 WMITLV_GET_STRUCT_TLVLEN 802 (wmi_peer_create_cmd_fixed_param)); 803 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 804 cmd->peer_type = param->peer_type; 805 cmd->vdev_id = param->vdev_id; 806 807 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 808 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 809 wmi_buf_free(buf); 810 return QDF_STATUS_E_FAILURE; 811 } 812 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 813 param->vdev_id); 814 815 return 0; 816 } 817 818 /** 819 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 820 * command to fw 821 * @wmi: wmi handle 822 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 823 * 824 * Return: 0 for success or error code 825 */ 826 static 827 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 828 struct rx_reorder_queue_setup_params *param) 829 { 830 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 831 wmi_buf_t buf; 832 int32_t len = sizeof(*cmd); 833 834 buf = wmi_buf_alloc(wmi, len); 835 if (!buf) { 836 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 837 return QDF_STATUS_E_NOMEM; 838 } 839 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 840 WMITLV_SET_HDR(&cmd->tlv_header, 841 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 842 WMITLV_GET_STRUCT_TLVLEN 843 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 844 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 845 cmd->vdev_id = param->vdev_id; 846 cmd->tid = param->tid; 847 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 848 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 849 cmd->queue_no = param->queue_no; 850 851 if (wmi_unified_cmd_send(wmi, buf, len, 852 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 853 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 854 __func__); 855 qdf_nbuf_free(buf); 856 return QDF_STATUS_E_FAILURE; 857 } 858 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 859 param->peer_macaddr, param->vdev_id, param->tid); 860 861 return QDF_STATUS_SUCCESS; 862 } 863 864 /** 865 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 866 * command to fw 867 * @wmi: wmi handle 868 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 869 * 870 * Return: 0 for success or error code 871 */ 872 static 873 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 874 struct rx_reorder_queue_remove_params *param) 875 { 876 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 877 wmi_buf_t buf; 878 int32_t len = sizeof(*cmd); 879 880 buf = wmi_buf_alloc(wmi, len); 881 if (!buf) { 882 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 883 return QDF_STATUS_E_NOMEM; 884 } 885 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 886 wmi_buf_data(buf); 887 WMITLV_SET_HDR(&cmd->tlv_header, 888 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 889 WMITLV_GET_STRUCT_TLVLEN 890 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 891 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 892 cmd->vdev_id = param->vdev_id; 893 cmd->tid_mask = param->peer_tid_bitmap; 894 895 if (wmi_unified_cmd_send(wmi, buf, len, 896 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 897 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 898 __func__); 899 qdf_nbuf_free(buf); 900 return QDF_STATUS_E_FAILURE; 901 } 902 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 903 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 904 905 return QDF_STATUS_SUCCESS; 906 } 907 908 /** 909 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 910 * @wmi_handle: wmi handle 911 * @param: pointer holding peer details 912 * 913 * Return: 0 for success or error code 914 */ 915 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 916 struct peer_add_wds_entry_params *param) 917 { 918 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 919 wmi_buf_t buf; 920 int len = sizeof(*cmd); 921 922 buf = wmi_buf_alloc(wmi_handle, len); 923 if (!buf) { 924 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 925 return QDF_STATUS_E_FAILURE; 926 } 927 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 928 WMITLV_SET_HDR(&cmd->tlv_header, 929 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 930 WMITLV_GET_STRUCT_TLVLEN 931 (wmi_peer_add_wds_entry_cmd_fixed_param)); 932 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 933 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 934 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 935 cmd->vdev_id = param->vdev_id; 936 937 return wmi_unified_cmd_send(wmi_handle, buf, len, 938 WMI_PEER_ADD_WDS_ENTRY_CMDID); 939 } 940 941 /** 942 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 943 * @wmi_handle: wmi handle 944 * @param: pointer holding peer details 945 * 946 * Return: 0 for success or error code 947 */ 948 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 949 struct peer_del_wds_entry_params *param) 950 { 951 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 952 wmi_buf_t buf; 953 int len = sizeof(*cmd); 954 955 buf = wmi_buf_alloc(wmi_handle, len); 956 if (!buf) { 957 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 958 return QDF_STATUS_E_NOMEM; 959 } 960 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 961 WMITLV_SET_HDR(&cmd->tlv_header, 962 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 963 WMITLV_GET_STRUCT_TLVLEN 964 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 965 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 966 cmd->vdev_id = param->vdev_id; 967 return wmi_unified_cmd_send(wmi_handle, buf, len, 968 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 969 } 970 971 /** 972 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 973 * @wmi_handle: wmi handle 974 * @param: pointer holding peer details 975 * 976 * Return: 0 for success or error code 977 */ 978 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 979 struct peer_update_wds_entry_params *param) 980 { 981 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 982 wmi_buf_t buf; 983 int len = sizeof(*cmd); 984 985 buf = wmi_buf_alloc(wmi_handle, len); 986 if (!buf) { 987 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 988 return QDF_STATUS_E_NOMEM; 989 } 990 991 /* wmi_buf_alloc returns zeroed command buffer */ 992 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 993 WMITLV_SET_HDR(&cmd->tlv_header, 994 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 995 WMITLV_GET_STRUCT_TLVLEN 996 (wmi_peer_update_wds_entry_cmd_fixed_param)); 997 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 998 cmd->vdev_id = param->vdev_id; 999 if (param->wds_macaddr) 1000 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1001 &cmd->wds_macaddr); 1002 if (param->peer_macaddr) 1003 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1004 &cmd->peer_macaddr); 1005 return wmi_unified_cmd_send(wmi_handle, buf, len, 1006 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1007 } 1008 1009 /** 1010 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1011 * @wmi_handle: wmi handle 1012 * @param: pointer to get tpc config params 1013 * 1014 * Return: 0 for success or error code 1015 */ 1016 static QDF_STATUS 1017 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1018 uint32_t param) 1019 { 1020 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1021 wmi_buf_t buf; 1022 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1023 1024 buf = wmi_buf_alloc(wmi_handle, len); 1025 if (!buf) { 1026 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1027 return QDF_STATUS_E_NOMEM; 1028 } 1029 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1030 WMITLV_SET_HDR(&cmd->tlv_header, 1031 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1032 WMITLV_GET_STRUCT_TLVLEN 1033 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1034 1035 cmd->param = param; 1036 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1037 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1038 WMI_LOGE("Send pdev get tpc config cmd failed"); 1039 wmi_buf_free(buf); 1040 return QDF_STATUS_E_FAILURE; 1041 1042 } 1043 WMI_LOGD("%s:send success", __func__); 1044 1045 return QDF_STATUS_SUCCESS; 1046 } 1047 1048 #ifdef WLAN_SUPPORT_GREEN_AP 1049 /** 1050 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1051 * @wmi_handle: wmi handle 1052 * @value: value 1053 * @pdev_id: pdev id to have radio context 1054 * 1055 * Return: QDF_STATUS_SUCCESS for success or error code 1056 */ 1057 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1058 uint32_t value, uint8_t pdev_id) 1059 { 1060 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1061 wmi_buf_t buf; 1062 int32_t len = sizeof(*cmd); 1063 1064 WMI_LOGD("Set Green AP PS val %d", value); 1065 1066 buf = wmi_buf_alloc(wmi_handle, len); 1067 if (!buf) { 1068 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1069 return QDF_STATUS_E_NOMEM; 1070 } 1071 1072 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1073 WMITLV_SET_HDR(&cmd->tlv_header, 1074 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1075 WMITLV_GET_STRUCT_TLVLEN 1076 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1077 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1078 cmd->enable = value; 1079 1080 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1081 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1082 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1083 wmi_buf_free(buf); 1084 return QDF_STATUS_E_FAILURE; 1085 } 1086 1087 return 0; 1088 } 1089 #endif 1090 1091 /** 1092 * send_pdev_utf_cmd_tlv() - send utf command to fw 1093 * @wmi_handle: wmi handle 1094 * @param: pointer to pdev_utf_params 1095 * @mac_id: mac id to have radio context 1096 * 1097 * Return: QDF_STATUS_SUCCESS for success or error code 1098 */ 1099 static QDF_STATUS 1100 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1101 struct pdev_utf_params *param, 1102 uint8_t mac_id) 1103 { 1104 wmi_buf_t buf; 1105 uint8_t *cmd; 1106 /* if param->len is 0 no data is sent, return error */ 1107 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1108 static uint8_t msgref = 1; 1109 uint8_t segNumber = 0, segInfo, numSegments; 1110 uint16_t chunk_len, total_bytes; 1111 uint8_t *bufpos; 1112 struct seg_hdr_info segHdrInfo; 1113 1114 bufpos = param->utf_payload; 1115 total_bytes = param->len; 1116 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1117 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1118 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1119 1120 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1121 numSegments++; 1122 1123 while (param->len) { 1124 if (param->len > MAX_WMI_UTF_LEN) 1125 chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */ 1126 else 1127 chunk_len = param->len; 1128 1129 buf = wmi_buf_alloc(wmi_handle, 1130 (chunk_len + sizeof(segHdrInfo) + 1131 WMI_TLV_HDR_SIZE)); 1132 if (!buf) { 1133 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1134 return QDF_STATUS_E_NOMEM; 1135 } 1136 1137 cmd = (uint8_t *) wmi_buf_data(buf); 1138 1139 segHdrInfo.len = total_bytes; 1140 segHdrInfo.msgref = msgref; 1141 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1142 segHdrInfo.segmentInfo = segInfo; 1143 segHdrInfo.pad = 0; 1144 1145 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1146 " segHdrInfo.segmentInfo = %d", 1147 __func__, segHdrInfo.len, segHdrInfo.msgref, 1148 segHdrInfo.segmentInfo); 1149 1150 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1151 "chunk len %d", __func__, total_bytes, segNumber, 1152 numSegments, chunk_len); 1153 1154 segNumber++; 1155 1156 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1157 (chunk_len + sizeof(segHdrInfo))); 1158 cmd += WMI_TLV_HDR_SIZE; 1159 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1160 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1161 1162 ret = wmi_unified_cmd_send(wmi_handle, buf, 1163 (chunk_len + sizeof(segHdrInfo) + 1164 WMI_TLV_HDR_SIZE), 1165 WMI_PDEV_UTF_CMDID); 1166 1167 if (QDF_IS_STATUS_ERROR(ret)) { 1168 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1169 wmi_buf_free(buf); 1170 break; 1171 } 1172 1173 param->len -= chunk_len; 1174 bufpos += chunk_len; 1175 } 1176 1177 msgref++; 1178 1179 return ret; 1180 } 1181 #ifdef CONFIG_MCL 1182 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1183 uint32_t host_param) 1184 { 1185 return host_param; 1186 } 1187 #else 1188 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1189 uint32_t host_param) 1190 { 1191 if (host_param < wmi_pdev_param_max) 1192 return wmi_handle->pdev_param[host_param]; 1193 1194 return WMI_UNAVAILABLE_PARAM; 1195 } 1196 #endif 1197 /** 1198 * send_pdev_param_cmd_tlv() - set pdev parameters 1199 * @wmi_handle: wmi handle 1200 * @param: pointer to pdev parameter 1201 * @mac_id: radio context 1202 * 1203 * Return: 0 on success, errno on failure 1204 */ 1205 static QDF_STATUS 1206 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1207 struct pdev_params *param, 1208 uint8_t mac_id) 1209 { 1210 QDF_STATUS ret; 1211 wmi_pdev_set_param_cmd_fixed_param *cmd; 1212 wmi_buf_t buf; 1213 uint16_t len = sizeof(*cmd); 1214 uint32_t pdev_param; 1215 1216 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1217 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1218 WMI_LOGW("%s: Unavailable param %d\n", 1219 __func__, param->param_id); 1220 return QDF_STATUS_E_INVAL; 1221 } 1222 1223 buf = wmi_buf_alloc(wmi_handle, len); 1224 if (!buf) { 1225 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1226 return QDF_STATUS_E_NOMEM; 1227 } 1228 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1229 WMITLV_SET_HDR(&cmd->tlv_header, 1230 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1231 WMITLV_GET_STRUCT_TLVLEN 1232 (wmi_pdev_set_param_cmd_fixed_param)); 1233 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1234 cmd->param_id = pdev_param; 1235 cmd->param_value = param->param_value; 1236 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1237 param->param_value); 1238 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1239 WMI_PDEV_SET_PARAM_CMDID); 1240 if (QDF_IS_STATUS_ERROR(ret)) { 1241 WMI_LOGE("Failed to send set param command ret = %d", ret); 1242 wmi_buf_free(buf); 1243 } 1244 return ret; 1245 } 1246 1247 /** 1248 * send_suspend_cmd_tlv() - WMI suspend function 1249 * @param wmi_handle : handle to WMI. 1250 * @param param : pointer to hold suspend parameter 1251 * @mac_id: radio context 1252 * 1253 * Return 0 on success and -ve on failure. 1254 */ 1255 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1256 struct suspend_params *param, 1257 uint8_t mac_id) 1258 { 1259 wmi_pdev_suspend_cmd_fixed_param *cmd; 1260 wmi_buf_t wmibuf; 1261 uint32_t len = sizeof(*cmd); 1262 int32_t ret; 1263 1264 /* 1265 * send the command to Target to ignore the 1266 * PCIE reset so as to ensure that Host and target 1267 * states are in sync 1268 */ 1269 wmibuf = wmi_buf_alloc(wmi_handle, len); 1270 if (wmibuf == NULL) 1271 return QDF_STATUS_E_NOMEM; 1272 1273 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1274 WMITLV_SET_HDR(&cmd->tlv_header, 1275 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1276 WMITLV_GET_STRUCT_TLVLEN 1277 (wmi_pdev_suspend_cmd_fixed_param)); 1278 if (param->disable_target_intr) 1279 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1280 else 1281 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1282 1283 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1284 1285 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1286 WMI_PDEV_SUSPEND_CMDID); 1287 if (ret) { 1288 wmi_buf_free(wmibuf); 1289 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1290 } 1291 1292 return ret; 1293 } 1294 1295 /** 1296 * send_resume_cmd_tlv() - WMI resume function 1297 * @param wmi_handle : handle to WMI. 1298 * @mac_id: radio context 1299 * 1300 * Return: 0 on success and -ve on failure. 1301 */ 1302 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1303 uint8_t mac_id) 1304 { 1305 wmi_buf_t wmibuf; 1306 wmi_pdev_resume_cmd_fixed_param *cmd; 1307 QDF_STATUS ret; 1308 1309 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1310 if (wmibuf == NULL) 1311 return QDF_STATUS_E_NOMEM; 1312 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1313 WMITLV_SET_HDR(&cmd->tlv_header, 1314 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1315 WMITLV_GET_STRUCT_TLVLEN 1316 (wmi_pdev_resume_cmd_fixed_param)); 1317 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1318 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1319 WMI_PDEV_RESUME_CMDID); 1320 if (QDF_IS_STATUS_ERROR(ret)) { 1321 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1322 wmi_buf_free(wmibuf); 1323 } 1324 1325 return ret; 1326 } 1327 1328 #ifdef FEATURE_WLAN_D0WOW 1329 /** 1330 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1331 * @param wmi_handle: handle to WMI. 1332 * @mac_id: radio context 1333 * 1334 * Return: 0 on success and error code on failure. 1335 */ 1336 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1337 uint8_t mac_id) 1338 { 1339 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1340 wmi_buf_t buf; 1341 int32_t len; 1342 QDF_STATUS status; 1343 1344 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1345 1346 buf = wmi_buf_alloc(wmi_handle, len); 1347 if (!buf) { 1348 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1349 return QDF_STATUS_E_NOMEM; 1350 } 1351 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1352 WMITLV_SET_HDR(&cmd->tlv_header, 1353 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1354 WMITLV_GET_STRUCT_TLVLEN 1355 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1356 1357 cmd->enable = true; 1358 1359 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1360 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1361 if (QDF_IS_STATUS_ERROR(status)) 1362 wmi_buf_free(buf); 1363 1364 return status; 1365 } 1366 1367 /** 1368 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1369 * @param wmi_handle: handle to WMI. 1370 * @mac_id: radio context 1371 * 1372 * Return: 0 on success and error code on failure. 1373 */ 1374 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1375 uint8_t mac_id) 1376 { 1377 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1378 wmi_buf_t buf; 1379 int32_t len; 1380 QDF_STATUS status; 1381 1382 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1383 1384 buf = wmi_buf_alloc(wmi_handle, len); 1385 if (!buf) { 1386 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1387 return QDF_STATUS_E_NOMEM; 1388 } 1389 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1390 WMITLV_SET_HDR(&cmd->tlv_header, 1391 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1392 WMITLV_GET_STRUCT_TLVLEN 1393 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1394 1395 cmd->enable = false; 1396 1397 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1398 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1399 if (QDF_IS_STATUS_ERROR(status)) 1400 wmi_buf_free(buf); 1401 1402 return status; 1403 } 1404 #endif 1405 1406 /** 1407 * send_wow_enable_cmd_tlv() - WMI wow enable function 1408 * @param wmi_handle : handle to WMI. 1409 * @param param : pointer to hold wow enable parameter 1410 * @mac_id: radio context 1411 * 1412 * Return: 0 on success and -ve on failure. 1413 */ 1414 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1415 struct wow_cmd_params *param, 1416 uint8_t mac_id) 1417 { 1418 wmi_wow_enable_cmd_fixed_param *cmd; 1419 wmi_buf_t buf; 1420 int32_t len; 1421 int32_t ret; 1422 1423 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1424 1425 buf = wmi_buf_alloc(wmi_handle, len); 1426 if (!buf) { 1427 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1428 return QDF_STATUS_E_NOMEM; 1429 } 1430 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1431 WMITLV_SET_HDR(&cmd->tlv_header, 1432 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1433 WMITLV_GET_STRUCT_TLVLEN 1434 (wmi_wow_enable_cmd_fixed_param)); 1435 cmd->enable = param->enable; 1436 if (param->can_suspend_link) 1437 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1438 else 1439 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1440 cmd->flags = param->flags; 1441 1442 WMI_LOGI("suspend type: %s", 1443 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1444 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1445 1446 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1447 WMI_WOW_ENABLE_CMDID); 1448 if (ret) 1449 wmi_buf_free(buf); 1450 1451 return ret; 1452 } 1453 1454 /** 1455 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1456 * @wmi_handle: wmi handle 1457 * @peer_addr: peer mac address 1458 * @param: pointer to ap_ps parameter structure 1459 * 1460 * Return: QDF_STATUS_SUCCESS for success or error code 1461 */ 1462 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1463 uint8_t *peer_addr, 1464 struct ap_ps_params *param) 1465 { 1466 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1467 wmi_buf_t buf; 1468 int32_t err; 1469 1470 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1471 if (!buf) { 1472 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1473 return QDF_STATUS_E_NOMEM; 1474 } 1475 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1476 WMITLV_SET_HDR(&cmd->tlv_header, 1477 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1478 WMITLV_GET_STRUCT_TLVLEN 1479 (wmi_ap_ps_peer_cmd_fixed_param)); 1480 cmd->vdev_id = param->vdev_id; 1481 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1482 cmd->param = param->param; 1483 cmd->value = param->value; 1484 err = wmi_unified_cmd_send(wmi_handle, buf, 1485 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1486 if (err) { 1487 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1488 wmi_buf_free(buf); 1489 return QDF_STATUS_E_FAILURE; 1490 } 1491 1492 return 0; 1493 } 1494 1495 /** 1496 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1497 * @wmi_handle: wmi handle 1498 * @peer_addr: peer mac address 1499 * @param: pointer to sta_ps parameter structure 1500 * 1501 * Return: QDF_STATUS_SUCCESS for success or error code 1502 */ 1503 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1504 struct sta_ps_params *param) 1505 { 1506 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1507 wmi_buf_t buf; 1508 int32_t len = sizeof(*cmd); 1509 1510 buf = wmi_buf_alloc(wmi_handle, len); 1511 if (!buf) { 1512 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1513 return QDF_STATUS_E_NOMEM; 1514 } 1515 1516 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1517 WMITLV_SET_HDR(&cmd->tlv_header, 1518 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1519 WMITLV_GET_STRUCT_TLVLEN 1520 (wmi_sta_powersave_param_cmd_fixed_param)); 1521 cmd->vdev_id = param->vdev_id; 1522 cmd->param = param->param; 1523 cmd->value = param->value; 1524 1525 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1526 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1527 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1528 param->vdev_id, param->param, param->value); 1529 wmi_buf_free(buf); 1530 return QDF_STATUS_E_FAILURE; 1531 } 1532 1533 return 0; 1534 } 1535 1536 /** 1537 * send_crash_inject_cmd_tlv() - inject fw crash 1538 * @wmi_handle: wmi handle 1539 * @param: ponirt to crash inject parameter structure 1540 * 1541 * Return: QDF_STATUS_SUCCESS for success or return error 1542 */ 1543 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1544 struct crash_inject *param) 1545 { 1546 int32_t ret = 0; 1547 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1548 uint16_t len = sizeof(*cmd); 1549 wmi_buf_t buf; 1550 1551 buf = wmi_buf_alloc(wmi_handle, len); 1552 if (!buf) { 1553 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1554 return QDF_STATUS_E_NOMEM; 1555 } 1556 1557 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1558 WMITLV_SET_HDR(&cmd->tlv_header, 1559 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1560 WMITLV_GET_STRUCT_TLVLEN 1561 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1562 cmd->type = param->type; 1563 cmd->delay_time_ms = param->delay_time_ms; 1564 1565 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1566 WMI_FORCE_FW_HANG_CMDID); 1567 if (ret) { 1568 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1569 __func__, ret); 1570 wmi_buf_free(buf); 1571 } 1572 1573 return ret; 1574 } 1575 1576 /** 1577 * send_dbglog_cmd_tlv() - set debug log level 1578 * @param wmi_handle : handle to WMI. 1579 * @param param : pointer to hold dbglog level parameter 1580 * 1581 * Return: 0 on success and -ve on failure. 1582 */ 1583 static QDF_STATUS 1584 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1585 struct dbglog_params *dbglog_param) 1586 { 1587 wmi_buf_t buf; 1588 wmi_debug_log_config_cmd_fixed_param *configmsg; 1589 QDF_STATUS status; 1590 int32_t i; 1591 int32_t len; 1592 int8_t *buf_ptr; 1593 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1594 1595 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1596 1597 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1598 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1599 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1600 buf = wmi_buf_alloc(wmi_handle, len); 1601 if (buf == NULL) 1602 return QDF_STATUS_E_NOMEM; 1603 1604 configmsg = 1605 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1606 buf_ptr = (int8_t *) configmsg; 1607 WMITLV_SET_HDR(&configmsg->tlv_header, 1608 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1609 WMITLV_GET_STRUCT_TLVLEN 1610 (wmi_debug_log_config_cmd_fixed_param)); 1611 configmsg->dbg_log_param = dbglog_param->param; 1612 configmsg->value = dbglog_param->val; 1613 /* Filling in the data part of second tlv -- should 1614 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1615 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1616 sizeof 1617 (wmi_debug_log_config_cmd_fixed_param) 1618 + WMI_TLV_HDR_SIZE); 1619 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1620 WMITLV_TAG_ARRAY_UINT32, 1621 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1622 if (dbglog_param->module_id_bitmap) { 1623 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1624 module_id_bitmap_array[i] = 1625 dbglog_param->module_id_bitmap[i]; 1626 } 1627 } 1628 1629 status = wmi_unified_cmd_send(wmi_handle, buf, 1630 len, WMI_DBGLOG_CFG_CMDID); 1631 1632 if (status != QDF_STATUS_SUCCESS) 1633 wmi_buf_free(buf); 1634 1635 return status; 1636 } 1637 1638 #ifdef CONFIG_MCL 1639 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1640 uint32_t host_param) 1641 { 1642 return host_param; 1643 } 1644 #else 1645 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1646 uint32_t host_param) 1647 { 1648 if (host_param < wmi_vdev_param_max) 1649 return wmi_handle->vdev_param[host_param]; 1650 1651 return WMI_UNAVAILABLE_PARAM; 1652 } 1653 #endif 1654 /** 1655 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1656 * @param wmi_handle : handle to WMI. 1657 * @param macaddr : MAC address 1658 * @param param : pointer to hold vdev set parameter 1659 * 1660 * Return: 0 on success and -ve on failure. 1661 */ 1662 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1663 struct vdev_set_params *param) 1664 { 1665 QDF_STATUS ret; 1666 wmi_vdev_set_param_cmd_fixed_param *cmd; 1667 wmi_buf_t buf; 1668 uint16_t len = sizeof(*cmd); 1669 uint32_t vdev_param; 1670 1671 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1672 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1673 WMI_LOGW("%s:Vdev param %d not available", __func__, 1674 param->param_id); 1675 return QDF_STATUS_E_INVAL; 1676 1677 } 1678 1679 buf = wmi_buf_alloc(wmi_handle, len); 1680 if (!buf) { 1681 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1682 return QDF_STATUS_E_NOMEM; 1683 } 1684 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1685 WMITLV_SET_HDR(&cmd->tlv_header, 1686 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1687 WMITLV_GET_STRUCT_TLVLEN 1688 (wmi_vdev_set_param_cmd_fixed_param)); 1689 cmd->vdev_id = param->if_id; 1690 cmd->param_id = vdev_param; 1691 cmd->param_value = param->param_value; 1692 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1693 cmd->vdev_id, cmd->param_id, cmd->param_value); 1694 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1695 WMI_VDEV_SET_PARAM_CMDID); 1696 if (QDF_IS_STATUS_ERROR(ret)) { 1697 WMI_LOGE("Failed to send set param command ret = %d", ret); 1698 wmi_buf_free(buf); 1699 } 1700 1701 return ret; 1702 } 1703 1704 /** 1705 * send_stats_request_cmd_tlv() - WMI request stats function 1706 * @param wmi_handle : handle to WMI. 1707 * @param macaddr : MAC address 1708 * @param param : pointer to hold stats request parameter 1709 * 1710 * Return: 0 on success and -ve on failure. 1711 */ 1712 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1713 uint8_t macaddr[IEEE80211_ADDR_LEN], 1714 struct stats_request_params *param) 1715 { 1716 int32_t ret; 1717 wmi_request_stats_cmd_fixed_param *cmd; 1718 wmi_buf_t buf; 1719 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1720 1721 buf = wmi_buf_alloc(wmi_handle, len); 1722 if (!buf) { 1723 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1724 return -QDF_STATUS_E_NOMEM; 1725 } 1726 1727 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1728 WMITLV_SET_HDR(&cmd->tlv_header, 1729 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1730 WMITLV_GET_STRUCT_TLVLEN 1731 (wmi_request_stats_cmd_fixed_param)); 1732 cmd->stats_id = param->stats_id; 1733 cmd->vdev_id = param->vdev_id; 1734 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1735 param->pdev_id); 1736 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1737 1738 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1739 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1740 1741 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1742 WMI_REQUEST_STATS_CMDID); 1743 1744 if (ret) { 1745 WMI_LOGE("Failed to send status request to fw =%d", ret); 1746 wmi_buf_free(buf); 1747 } 1748 1749 return ret; 1750 } 1751 1752 #ifdef CONFIG_WIN 1753 /** 1754 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1755 * @param wmi_handle : handle to WMI. 1756 * @param PKTLOG_EVENT : packet log event 1757 * @mac_id: mac id to have radio context 1758 * 1759 * Return: 0 on success and -ve on failure. 1760 */ 1761 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1762 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1763 { 1764 int32_t ret; 1765 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1766 wmi_buf_t buf; 1767 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1768 1769 buf = wmi_buf_alloc(wmi_handle, len); 1770 if (!buf) { 1771 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1772 return -QDF_STATUS_E_NOMEM; 1773 } 1774 1775 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1776 WMITLV_SET_HDR(&cmd->tlv_header, 1777 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1778 WMITLV_GET_STRUCT_TLVLEN 1779 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1780 cmd->evlist = PKTLOG_EVENT; 1781 cmd->pdev_id = mac_id; 1782 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1783 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1784 if (ret) { 1785 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1786 wmi_buf_free(buf); 1787 } 1788 1789 return ret; 1790 } 1791 1792 /** 1793 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1794 * @param wmi_handle : handle to WMI. 1795 * @mac_id: mac id to have radio context 1796 * 1797 * Return: 0 on success and -ve on failure. 1798 */ 1799 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1800 uint8_t mac_id) 1801 { 1802 int32_t ret; 1803 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1804 wmi_buf_t buf; 1805 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1806 1807 buf = wmi_buf_alloc(wmi_handle, len); 1808 if (!buf) { 1809 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1810 return -QDF_STATUS_E_NOMEM; 1811 } 1812 1813 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1814 WMITLV_SET_HDR(&cmd->tlv_header, 1815 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1816 WMITLV_GET_STRUCT_TLVLEN 1817 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1818 cmd->pdev_id = mac_id; 1819 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1820 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1821 if (ret) { 1822 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1823 wmi_buf_free(buf); 1824 } 1825 1826 return ret; 1827 } 1828 #else 1829 /** 1830 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1831 * packet-log 1832 * @param wmi_handle : handle to WMI. 1833 * @param macaddr : MAC address 1834 * @param param : pointer to hold stats request parameter 1835 * 1836 * Return: 0 on success and -ve on failure. 1837 */ 1838 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1839 uint8_t macaddr[IEEE80211_ADDR_LEN], 1840 struct packet_enable_params *param) 1841 { 1842 return 0; 1843 } 1844 /** 1845 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1846 * packet-log 1847 * @param wmi_handle : handle to WMI. 1848 * @mac_id: mac id to have radio context 1849 * 1850 * Return: 0 on success and -ve on failure. 1851 */ 1852 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1853 uint8_t mac_id) 1854 { 1855 return 0; 1856 } 1857 #endif 1858 1859 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1860 /** 1861 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1862 * sync time between bwtween host and firmware 1863 * @param wmi_handle : handle to WMI. 1864 * 1865 * Return: None 1866 */ 1867 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1868 { 1869 wmi_buf_t buf; 1870 QDF_STATUS status = QDF_STATUS_SUCCESS; 1871 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1872 int32_t len; 1873 qdf_time_t time_ms; 1874 1875 len = sizeof(*time_stamp); 1876 buf = wmi_buf_alloc(wmi_handle, len); 1877 1878 if (!buf) { 1879 WMI_LOGP(FL("wmi_buf_alloc failed")); 1880 return; 1881 } 1882 time_stamp = 1883 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1884 (wmi_buf_data(buf)); 1885 WMITLV_SET_HDR(&time_stamp->tlv_header, 1886 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1887 WMITLV_GET_STRUCT_TLVLEN( 1888 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1889 1890 time_ms = qdf_get_time_of_the_day_ms(); 1891 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1892 time_stamp->time_stamp_low = time_ms & 1893 WMI_FW_TIME_STAMP_LOW_MASK; 1894 /* 1895 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1896 * wont exceed 27 bit 1897 */ 1898 time_stamp->time_stamp_high = 0; 1899 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1900 time_stamp->mode, time_stamp->time_stamp_low, 1901 time_stamp->time_stamp_high); 1902 1903 status = wmi_unified_cmd_send(wmi_handle, buf, 1904 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1905 if (status) { 1906 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1907 wmi_buf_free(buf); 1908 } 1909 1910 } 1911 1912 #ifdef WLAN_SUPPORT_FILS 1913 /** 1914 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 1915 * @wmi_handle: wmi handle 1916 * @evt_buf: pointer to event buffer 1917 * @vdev_id: pointer to hold vdev id 1918 * 1919 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 1920 */ 1921 static QDF_STATUS 1922 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 1923 void *evt_buf, uint32_t *vdev_id) 1924 { 1925 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 1926 wmi_host_swfda_event_fixed_param *swfda_event; 1927 1928 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 1929 if (!param_buf) { 1930 WMI_LOGE("Invalid swfda event buffer"); 1931 return QDF_STATUS_E_INVAL; 1932 } 1933 swfda_event = param_buf->fixed_param; 1934 *vdev_id = swfda_event->vdev_id; 1935 1936 return QDF_STATUS_SUCCESS; 1937 } 1938 1939 /** 1940 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 1941 * @wmi_handle: wmi handle 1942 * @param: pointer to hold FILS discovery enable param 1943 * 1944 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 1945 */ 1946 static QDF_STATUS 1947 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 1948 struct config_fils_params *param) 1949 { 1950 wmi_enable_fils_cmd_fixed_param *cmd; 1951 wmi_buf_t buf; 1952 QDF_STATUS status; 1953 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 1954 1955 buf = wmi_buf_alloc(wmi_handle, len); 1956 if (!buf) { 1957 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 1958 return QDF_STATUS_E_NOMEM; 1959 } 1960 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 1961 WMITLV_SET_HDR(&cmd->tlv_header, 1962 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 1963 WMITLV_GET_STRUCT_TLVLEN( 1964 wmi_enable_fils_cmd_fixed_param)); 1965 cmd->vdev_id = param->vdev_id; 1966 cmd->fd_period = param->fd_period; 1967 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 1968 param->fd_period, param->vdev_id); 1969 1970 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1971 WMI_ENABLE_FILS_CMDID); 1972 if (status != QDF_STATUS_SUCCESS) { 1973 wmi_buf_free(buf); 1974 return QDF_STATUS_E_FAILURE; 1975 } 1976 1977 return QDF_STATUS_SUCCESS; 1978 } 1979 1980 /** 1981 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 1982 * @wmi_handle: wmi handle 1983 * @param: pointer to hold FD send cmd parameter 1984 * 1985 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 1986 */ 1987 static QDF_STATUS 1988 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 1989 struct fd_params *param) 1990 { 1991 QDF_STATUS ret; 1992 wmi_fd_send_from_host_cmd_fixed_param *cmd; 1993 wmi_buf_t wmi_buf; 1994 qdf_dma_addr_t dma_addr; 1995 1996 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1997 if (!wmi_buf) { 1998 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 1999 return QDF_STATUS_E_NOMEM; 2000 } 2001 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2002 WMITLV_SET_HDR(&cmd->tlv_header, 2003 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2004 WMITLV_GET_STRUCT_TLVLEN( 2005 wmi_fd_send_from_host_cmd_fixed_param)); 2006 cmd->vdev_id = param->vdev_id; 2007 cmd->data_len = qdf_nbuf_len(param->wbuf); 2008 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2009 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2010 cmd->frame_ctrl = param->frame_ctrl; 2011 2012 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2013 WMI_PDEV_SEND_FD_CMDID); 2014 if (ret != QDF_STATUS_SUCCESS) { 2015 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2016 __func__, ret); 2017 wmi_buf_free(wmi_buf); 2018 } 2019 2020 return ret; 2021 } 2022 #endif /* WLAN_SUPPORT_FILS */ 2023 2024 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2025 struct beacon_params *param) 2026 { 2027 QDF_STATUS ret; 2028 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2029 wmi_buf_t wmi_buf; 2030 qdf_dma_addr_t dma_addr; 2031 uint32_t dtim_flag = 0; 2032 2033 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2034 if (!wmi_buf) { 2035 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2036 return QDF_STATUS_E_NOMEM; 2037 } 2038 if (param->is_dtim_count_zero) { 2039 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2040 if (param->is_bitctl_reqd) { 2041 /* deliver CAB traffic in next DTIM beacon */ 2042 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2043 } 2044 } 2045 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2046 WMITLV_SET_HDR(&cmd->tlv_header, 2047 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2048 WMITLV_GET_STRUCT_TLVLEN 2049 (wmi_bcn_send_from_host_cmd_fixed_param)); 2050 cmd->vdev_id = param->vdev_id; 2051 cmd->data_len = qdf_nbuf_len(param->wbuf); 2052 cmd->frame_ctrl = param->frame_ctrl; 2053 cmd->dtim_flag = dtim_flag; 2054 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2055 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2056 #if defined(HTT_PADDR64) 2057 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2058 #endif 2059 cmd->bcn_antenna = param->bcn_txant; 2060 2061 ret = wmi_unified_cmd_send(wmi_handle, 2062 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2063 if (ret != QDF_STATUS_SUCCESS) { 2064 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2065 wmi_buf_free(wmi_buf); 2066 } 2067 2068 return ret; 2069 } 2070 2071 /** 2072 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2073 * @param wmi_handle : handle to WMI. 2074 * @param param : pointer to hold beacon send cmd parameter 2075 * 2076 * Return: 0 on success and -ve on failure. 2077 */ 2078 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2079 struct beacon_tmpl_params *param) 2080 { 2081 int32_t ret; 2082 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2083 wmi_bcn_prb_info *bcn_prb_info; 2084 wmi_buf_t wmi_buf; 2085 uint8_t *buf_ptr; 2086 uint32_t wmi_buf_len; 2087 2088 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2089 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2090 param->tmpl_len_aligned; 2091 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2092 if (!wmi_buf) { 2093 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2094 return QDF_STATUS_E_NOMEM; 2095 } 2096 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2097 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2098 WMITLV_SET_HDR(&cmd->tlv_header, 2099 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2100 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2101 cmd->vdev_id = param->vdev_id; 2102 cmd->tim_ie_offset = param->tim_ie_offset; 2103 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2104 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2105 cmd->buf_len = param->tmpl_len; 2106 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2107 2108 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2109 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2110 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2111 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2112 bcn_prb_info->caps = 0; 2113 bcn_prb_info->erp = 0; 2114 buf_ptr += sizeof(wmi_bcn_prb_info); 2115 2116 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2117 buf_ptr += WMI_TLV_HDR_SIZE; 2118 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2119 2120 ret = wmi_unified_cmd_send(wmi_handle, 2121 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2122 if (ret) { 2123 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2124 wmi_buf_free(wmi_buf); 2125 } 2126 2127 return 0; 2128 } 2129 2130 #ifdef CONFIG_MCL 2131 static inline void copy_peer_flags_tlv( 2132 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2133 struct peer_assoc_params *param) 2134 { 2135 cmd->peer_flags = param->peer_flags; 2136 } 2137 #else 2138 static inline void copy_peer_flags_tlv( 2139 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2140 struct peer_assoc_params *param) 2141 { 2142 /* 2143 * The target only needs a subset of the flags maintained in the host. 2144 * Just populate those flags and send it down 2145 */ 2146 cmd->peer_flags = 0; 2147 2148 /* 2149 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2150 */ 2151 if (param->is_wme_set) { 2152 2153 if (param->qos_flag) 2154 cmd->peer_flags |= WMI_PEER_QOS; 2155 if (param->apsd_flag) 2156 cmd->peer_flags |= WMI_PEER_APSD; 2157 if (param->ht_flag) 2158 cmd->peer_flags |= WMI_PEER_HT; 2159 if (param->bw_40) 2160 cmd->peer_flags |= WMI_PEER_40MHZ; 2161 if (param->bw_80) 2162 cmd->peer_flags |= WMI_PEER_80MHZ; 2163 if (param->bw_160) 2164 cmd->peer_flags |= WMI_PEER_160MHZ; 2165 2166 /* Typically if STBC is enabled for VHT it should be enabled 2167 * for HT as well 2168 **/ 2169 if (param->stbc_flag) 2170 cmd->peer_flags |= WMI_PEER_STBC; 2171 2172 /* Typically if LDPC is enabled for VHT it should be enabled 2173 * for HT as well 2174 **/ 2175 if (param->ldpc_flag) 2176 cmd->peer_flags |= WMI_PEER_LDPC; 2177 2178 if (param->static_mimops_flag) 2179 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2180 if (param->dynamic_mimops_flag) 2181 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2182 if (param->spatial_mux_flag) 2183 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2184 if (param->vht_flag) 2185 cmd->peer_flags |= WMI_PEER_VHT; 2186 if (param->he_flag) 2187 cmd->peer_flags |= WMI_PEER_HE; 2188 } 2189 2190 if (param->is_pmf_enabled) 2191 cmd->peer_flags |= WMI_PEER_PMF; 2192 /* 2193 * Suppress authorization for all AUTH modes that need 4-way handshake 2194 * (during re-association). 2195 * Authorization will be done for these modes on key installation. 2196 */ 2197 if (param->auth_flag) 2198 cmd->peer_flags |= WMI_PEER_AUTH; 2199 if (param->need_ptk_4_way) 2200 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2201 else 2202 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2203 if (param->need_gtk_2_way) 2204 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2205 /* safe mode bypass the 4-way handshake */ 2206 if (param->safe_mode_enabled) 2207 cmd->peer_flags &= 2208 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2209 /* Disable AMSDU for station transmit, if user configures it */ 2210 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2211 * it 2212 * if (param->amsdu_disable) Add after FW support 2213 **/ 2214 2215 /* Target asserts if node is marked HT and all MCS is set to 0. 2216 * Mark the node as non-HT if all the mcs rates are disabled through 2217 * iwpriv 2218 **/ 2219 if (param->peer_ht_rates.num_rates == 0) 2220 cmd->peer_flags &= ~WMI_PEER_HT; 2221 } 2222 #endif 2223 2224 #ifdef CONFIG_MCL 2225 static inline void copy_peer_mac_addr_tlv( 2226 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2227 struct peer_assoc_params *param) 2228 { 2229 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2230 sizeof(param->peer_macaddr)); 2231 } 2232 #else 2233 static inline void copy_peer_mac_addr_tlv( 2234 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2235 struct peer_assoc_params *param) 2236 { 2237 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2238 } 2239 #endif 2240 2241 /** 2242 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2243 * @param wmi_handle : handle to WMI. 2244 * @param param : pointer to peer assoc parameter 2245 * 2246 * Return: 0 on success and -ve on failure. 2247 */ 2248 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2249 struct peer_assoc_params *param) 2250 { 2251 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2252 wmi_vht_rate_set *mcs; 2253 wmi_he_rate_set *he_mcs; 2254 wmi_buf_t buf; 2255 int32_t len; 2256 uint8_t *buf_ptr; 2257 QDF_STATUS ret; 2258 uint32_t peer_legacy_rates_align; 2259 uint32_t peer_ht_rates_align; 2260 int32_t i; 2261 2262 2263 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2264 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2265 2266 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2267 (peer_legacy_rates_align * sizeof(uint8_t)) + 2268 WMI_TLV_HDR_SIZE + 2269 (peer_ht_rates_align * sizeof(uint8_t)) + 2270 sizeof(wmi_vht_rate_set) + 2271 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2272 + WMI_TLV_HDR_SIZE); 2273 2274 buf = wmi_buf_alloc(wmi_handle, len); 2275 if (!buf) { 2276 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2277 return QDF_STATUS_E_NOMEM; 2278 } 2279 2280 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2281 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2282 WMITLV_SET_HDR(&cmd->tlv_header, 2283 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2284 WMITLV_GET_STRUCT_TLVLEN 2285 (wmi_peer_assoc_complete_cmd_fixed_param)); 2286 2287 cmd->vdev_id = param->vdev_id; 2288 2289 cmd->peer_new_assoc = param->peer_new_assoc; 2290 cmd->peer_associd = param->peer_associd; 2291 2292 copy_peer_flags_tlv(cmd, param); 2293 copy_peer_mac_addr_tlv(cmd, param); 2294 2295 cmd->peer_rate_caps = param->peer_rate_caps; 2296 cmd->peer_caps = param->peer_caps; 2297 cmd->peer_listen_intval = param->peer_listen_intval; 2298 cmd->peer_ht_caps = param->peer_ht_caps; 2299 cmd->peer_max_mpdu = param->peer_max_mpdu; 2300 cmd->peer_mpdu_density = param->peer_mpdu_density; 2301 cmd->peer_vht_caps = param->peer_vht_caps; 2302 cmd->peer_phymode = param->peer_phymode; 2303 2304 /* Update 11ax capabilities */ 2305 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2306 cmd->peer_he_ops = param->peer_he_ops; 2307 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2308 sizeof(param->peer_he_cap_phyinfo)); 2309 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2310 sizeof(param->peer_ppet)); 2311 2312 /* Update peer legacy rate information */ 2313 buf_ptr += sizeof(*cmd); 2314 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2315 peer_legacy_rates_align); 2316 buf_ptr += WMI_TLV_HDR_SIZE; 2317 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2318 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2319 param->peer_legacy_rates.num_rates); 2320 2321 /* Update peer HT rate information */ 2322 buf_ptr += peer_legacy_rates_align; 2323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2324 peer_ht_rates_align); 2325 buf_ptr += WMI_TLV_HDR_SIZE; 2326 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2327 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2328 param->peer_ht_rates.num_rates); 2329 2330 /* VHT Rates */ 2331 buf_ptr += peer_ht_rates_align; 2332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2333 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2334 2335 cmd->peer_nss = param->peer_nss; 2336 2337 /* Update bandwidth-NSS mapping */ 2338 cmd->peer_bw_rxnss_override = 0; 2339 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2340 2341 mcs = (wmi_vht_rate_set *) buf_ptr; 2342 if (param->vht_capable) { 2343 mcs->rx_max_rate = param->rx_max_rate; 2344 mcs->rx_mcs_set = param->rx_mcs_set; 2345 mcs->tx_max_rate = param->tx_max_rate; 2346 mcs->tx_mcs_set = param->tx_mcs_set; 2347 } 2348 2349 /* HE Rates */ 2350 cmd->peer_he_mcs = param->peer_he_mcs_count; 2351 buf_ptr += sizeof(wmi_vht_rate_set); 2352 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2353 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2354 buf_ptr += WMI_TLV_HDR_SIZE; 2355 2356 /* Loop through the HE rate set */ 2357 for (i = 0; i < param->peer_he_mcs_count; i++) { 2358 he_mcs = (wmi_he_rate_set *) buf_ptr; 2359 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2360 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2361 2362 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2363 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2364 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2365 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2366 buf_ptr += sizeof(wmi_he_rate_set); 2367 } 2368 2369 2370 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2371 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2372 "nss %d phymode %d peer_mpdu_density %d " 2373 "cmd->peer_vht_caps %x " 2374 "HE cap_info %x ops %x " 2375 "HE phy %x %x %x " 2376 "peer_bw_rxnss_override %x", __func__, 2377 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2378 cmd->peer_rate_caps, cmd->peer_caps, 2379 cmd->peer_listen_intval, cmd->peer_ht_caps, 2380 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2381 cmd->peer_mpdu_density, 2382 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2383 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2384 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2385 cmd->peer_bw_rxnss_override); 2386 2387 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2388 WMI_PEER_ASSOC_CMDID); 2389 if (QDF_IS_STATUS_ERROR(ret)) { 2390 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2391 __func__, ret); 2392 wmi_buf_free(buf); 2393 } 2394 2395 return ret; 2396 } 2397 2398 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2399 */ 2400 static inline void copy_scan_event_cntrl_flags( 2401 wmi_start_scan_cmd_fixed_param * cmd, 2402 struct scan_req_params *param) 2403 { 2404 2405 /* Scan events subscription */ 2406 if (param->scan_ev_started) 2407 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2408 if (param->scan_ev_completed) 2409 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2410 if (param->scan_ev_bss_chan) 2411 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2412 if (param->scan_ev_foreign_chan) 2413 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2414 if (param->scan_ev_dequeued) 2415 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2416 if (param->scan_ev_preempted) 2417 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2418 if (param->scan_ev_start_failed) 2419 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2420 if (param->scan_ev_restarted) 2421 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2422 if (param->scan_ev_foreign_chn_exit) 2423 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2424 if (param->scan_ev_suspended) 2425 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2426 if (param->scan_ev_resumed) 2427 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2428 2429 /** Set scan control flags */ 2430 cmd->scan_ctrl_flags = 0; 2431 if (param->scan_f_passive) 2432 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2433 if (param->scan_f_strict_passive_pch) 2434 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2435 if (param->scan_f_promisc_mode) 2436 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2437 if (param->scan_f_capture_phy_err) 2438 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2439 if (param->scan_f_half_rate) 2440 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2441 if (param->scan_f_quarter_rate) 2442 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2443 if (param->scan_f_cck_rates) 2444 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2445 if (param->scan_f_ofdm_rates) 2446 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2447 if (param->scan_f_chan_stat_evnt) 2448 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2449 if (param->scan_f_filter_prb_req) 2450 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2451 if (param->scan_f_bcast_probe) 2452 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2453 if (param->scan_f_offchan_mgmt_tx) 2454 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2455 if (param->scan_f_offchan_data_tx) 2456 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2457 if (param->scan_f_force_active_dfs_chn) 2458 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2459 if (param->scan_f_add_tpc_ie_in_probe) 2460 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2461 if (param->scan_f_add_ds_ie_in_probe) 2462 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2463 if (param->scan_f_add_spoofed_mac_in_probe) 2464 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2465 if (param->scan_f_add_rand_seq_in_probe) 2466 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2467 if (param->scan_f_en_ie_whitelist_in_probe) 2468 cmd->scan_ctrl_flags |= 2469 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2470 2471 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2472 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2473 param->adaptive_dwell_time_mode); 2474 } 2475 2476 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2477 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2478 struct scan_req_params *params) 2479 { 2480 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2481 } 2482 2483 /** 2484 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2485 * @mac: random mac addr 2486 * @mask: random mac mask 2487 * @mac_addr: wmi random mac 2488 * @mac_mask: wmi random mac mask 2489 * 2490 * Return None. 2491 */ 2492 static inline 2493 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2494 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2495 { 2496 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2497 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2498 } 2499 2500 /* 2501 * wmi_fill_vendor_oui() - fill vendor OUIs 2502 * @buf_ptr: pointer to wmi tlv buffer 2503 * @num_vendor_oui: number of vendor OUIs to be filled 2504 * @param_voui: pointer to OUI buffer 2505 * 2506 * This function populates the wmi tlv buffer when vendor specific OUIs are 2507 * present. 2508 * 2509 * Return: None 2510 */ 2511 static inline 2512 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2513 uint32_t *pvoui) 2514 { 2515 wmi_vendor_oui *voui = NULL; 2516 uint32_t i; 2517 2518 voui = (wmi_vendor_oui *)buf_ptr; 2519 2520 for (i = 0; i < num_vendor_oui; i++) { 2521 WMITLV_SET_HDR(&voui[i].tlv_header, 2522 WMITLV_TAG_STRUC_wmi_vendor_oui, 2523 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2524 voui[i].oui_type_subtype = pvoui[i]; 2525 } 2526 } 2527 2528 /* 2529 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2530 * @ie_bitmap: output pointer to ie bit map in cmd 2531 * @num_vendor_oui: output pointer to num vendor OUIs 2532 * @ie_whitelist: input parameter 2533 * 2534 * This function populates the IE whitelist attrs of scan, pno and 2535 * scan oui commands for ie_whitelist parameter. 2536 * 2537 * Return: None 2538 */ 2539 static inline 2540 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2541 uint32_t *num_vendor_oui, 2542 struct probe_req_whitelist_attr *ie_whitelist) 2543 { 2544 uint32_t i = 0; 2545 2546 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2547 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2548 2549 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2550 } 2551 2552 /** 2553 * send_scan_start_cmd_tlv() - WMI scan start function 2554 * @param wmi_handle : handle to WMI. 2555 * @param param : pointer to hold scan start cmd parameter 2556 * 2557 * Return: 0 on success and -ve on failure. 2558 */ 2559 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2560 struct scan_req_params *params) 2561 { 2562 int32_t ret = 0; 2563 int32_t i; 2564 wmi_buf_t wmi_buf; 2565 wmi_start_scan_cmd_fixed_param *cmd; 2566 uint8_t *buf_ptr; 2567 uint32_t *tmp_ptr; 2568 wmi_ssid *ssid = NULL; 2569 wmi_mac_addr *bssid; 2570 int len = sizeof(*cmd); 2571 uint8_t extraie_len_with_pad = 0; 2572 uint8_t phymode_roundup = 0; 2573 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2574 2575 /* Length TLV placeholder for array of uint32_t */ 2576 len += WMI_TLV_HDR_SIZE; 2577 /* calculate the length of buffer required */ 2578 if (params->chan_list.num_chan) 2579 len += params->chan_list.num_chan * sizeof(uint32_t); 2580 2581 /* Length TLV placeholder for array of wmi_ssid structures */ 2582 len += WMI_TLV_HDR_SIZE; 2583 if (params->num_ssids) 2584 len += params->num_ssids * sizeof(wmi_ssid); 2585 2586 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2587 len += WMI_TLV_HDR_SIZE; 2588 if (params->num_bssid) 2589 len += sizeof(wmi_mac_addr) * params->num_bssid; 2590 2591 /* Length TLV placeholder for array of bytes */ 2592 len += WMI_TLV_HDR_SIZE; 2593 if (params->extraie.len) 2594 extraie_len_with_pad = 2595 roundup(params->extraie.len, sizeof(uint32_t)); 2596 len += extraie_len_with_pad; 2597 2598 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2599 if (ie_whitelist->num_vendor_oui) 2600 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2601 2602 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2603 if (params->scan_f_wide_band) 2604 phymode_roundup = 2605 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2606 sizeof(uint32_t)); 2607 len += phymode_roundup; 2608 2609 /* Allocate the memory */ 2610 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2611 if (!wmi_buf) { 2612 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2613 __func__); 2614 return QDF_STATUS_E_FAILURE; 2615 } 2616 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2617 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2618 WMITLV_SET_HDR(&cmd->tlv_header, 2619 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2620 WMITLV_GET_STRUCT_TLVLEN 2621 (wmi_start_scan_cmd_fixed_param)); 2622 2623 cmd->scan_id = params->scan_id; 2624 cmd->scan_req_id = params->scan_req_id; 2625 cmd->vdev_id = params->vdev_id; 2626 cmd->scan_priority = params->scan_priority; 2627 2628 copy_scan_event_cntrl_flags(cmd, params); 2629 2630 cmd->dwell_time_active = params->dwell_time_active; 2631 cmd->dwell_time_passive = params->dwell_time_passive; 2632 cmd->min_rest_time = params->min_rest_time; 2633 cmd->max_rest_time = params->max_rest_time; 2634 cmd->repeat_probe_time = params->repeat_probe_time; 2635 cmd->probe_spacing_time = params->probe_spacing_time; 2636 cmd->idle_time = params->idle_time; 2637 cmd->max_scan_time = params->max_scan_time; 2638 cmd->probe_delay = params->probe_delay; 2639 cmd->burst_duration = params->burst_duration; 2640 cmd->num_chan = params->chan_list.num_chan; 2641 cmd->num_bssid = params->num_bssid; 2642 cmd->num_ssids = params->num_ssids; 2643 cmd->ie_len = params->extraie.len; 2644 cmd->n_probes = params->n_probes; 2645 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2646 2647 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2648 2649 if (params->scan_random.randomize) 2650 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2651 params->scan_random.mac_mask, 2652 &cmd->mac_addr, 2653 &cmd->mac_mask); 2654 2655 if (ie_whitelist->white_list) 2656 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2657 &cmd->num_vendor_oui, 2658 ie_whitelist); 2659 2660 buf_ptr += sizeof(*cmd); 2661 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2662 for (i = 0; i < params->chan_list.num_chan; ++i) 2663 tmp_ptr[i] = params->chan_list.chan[i].freq; 2664 2665 WMITLV_SET_HDR(buf_ptr, 2666 WMITLV_TAG_ARRAY_UINT32, 2667 (params->chan_list.num_chan * sizeof(uint32_t))); 2668 buf_ptr += WMI_TLV_HDR_SIZE + 2669 (params->chan_list.num_chan * sizeof(uint32_t)); 2670 2671 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2672 WMI_LOGE("Invalid value for numSsid"); 2673 goto error; 2674 } 2675 2676 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2677 (params->num_ssids * sizeof(wmi_ssid))); 2678 2679 if (params->num_ssids) { 2680 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2681 for (i = 0; i < params->num_ssids; ++i) { 2682 ssid->ssid_len = params->ssid[i].length; 2683 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2684 params->ssid[i].length); 2685 ssid++; 2686 } 2687 } 2688 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2689 2690 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2691 (params->num_bssid * sizeof(wmi_mac_addr))); 2692 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2693 2694 if (params->num_bssid) { 2695 for (i = 0; i < params->num_bssid; ++i) { 2696 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2697 ¶ms->bssid_list[i].bytes[0], bssid); 2698 bssid++; 2699 } 2700 } 2701 2702 buf_ptr += WMI_TLV_HDR_SIZE + 2703 (params->num_bssid * sizeof(wmi_mac_addr)); 2704 2705 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2706 if (params->extraie.len) 2707 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2708 params); 2709 2710 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2711 2712 /* probe req ie whitelisting */ 2713 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2714 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2715 2716 buf_ptr += WMI_TLV_HDR_SIZE; 2717 2718 if (cmd->num_vendor_oui) { 2719 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2720 ie_whitelist->voui); 2721 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2722 } 2723 2724 /* Add phy mode TLV if it's a wide band scan */ 2725 if (params->scan_f_wide_band) { 2726 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2727 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2728 for (i = 0; i < params->chan_list.num_chan; ++i) 2729 buf_ptr[i] = 2730 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2731 buf_ptr += phymode_roundup; 2732 } else { 2733 /* Add ZERO legth phy mode TLV */ 2734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2735 } 2736 2737 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2738 len, WMI_START_SCAN_CMDID); 2739 if (ret) { 2740 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2741 wmi_buf_free(wmi_buf); 2742 } 2743 return ret; 2744 error: 2745 wmi_buf_free(wmi_buf); 2746 return QDF_STATUS_E_FAILURE; 2747 } 2748 2749 /** 2750 * send_scan_stop_cmd_tlv() - WMI scan start function 2751 * @param wmi_handle : handle to WMI. 2752 * @param param : pointer to hold scan cancel cmd parameter 2753 * 2754 * Return: 0 on success and -ve on failure. 2755 */ 2756 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2757 struct scan_cancel_param *param) 2758 { 2759 wmi_stop_scan_cmd_fixed_param *cmd; 2760 int ret; 2761 int len = sizeof(*cmd); 2762 wmi_buf_t wmi_buf; 2763 2764 /* Allocate the memory */ 2765 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2766 if (!wmi_buf) { 2767 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2768 __func__); 2769 ret = QDF_STATUS_E_NOMEM; 2770 goto error; 2771 } 2772 2773 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2774 WMITLV_SET_HDR(&cmd->tlv_header, 2775 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2776 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2777 cmd->vdev_id = param->vdev_id; 2778 cmd->requestor = param->requester; 2779 cmd->scan_id = param->scan_id; 2780 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2781 param->pdev_id); 2782 /* stop the scan with the corresponding scan_id */ 2783 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2784 /* Cancelling all scans */ 2785 cmd->req_type = WMI_SCAN_STOP_ALL; 2786 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2787 /* Cancelling VAP scans */ 2788 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2789 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2790 /* Cancelling specific scan */ 2791 cmd->req_type = WMI_SCAN_STOP_ONE; 2792 } else { 2793 WMI_LOGE("%s: Invalid Command : ", __func__); 2794 wmi_buf_free(wmi_buf); 2795 return QDF_STATUS_E_INVAL; 2796 } 2797 2798 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2799 len, WMI_STOP_SCAN_CMDID); 2800 if (ret) { 2801 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2802 wmi_buf_free(wmi_buf); 2803 } 2804 2805 error: 2806 return ret; 2807 } 2808 2809 #ifdef CONFIG_MCL 2810 /** 2811 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2812 * @param wmi_handle : handle to WMI. 2813 * @param param : pointer to hold scan channel list parameter 2814 * 2815 * Return: 0 on success and -ve on failure. 2816 */ 2817 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2818 struct scan_chan_list_params *chan_list) 2819 { 2820 wmi_buf_t buf; 2821 QDF_STATUS qdf_status; 2822 wmi_scan_chan_list_cmd_fixed_param *cmd; 2823 int i; 2824 uint8_t *buf_ptr; 2825 wmi_channel_param *chan_info, *tchan_info; 2826 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2827 2828 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2829 buf = wmi_buf_alloc(wmi_handle, len); 2830 if (!buf) { 2831 WMI_LOGE("Failed to allocate memory"); 2832 qdf_status = QDF_STATUS_E_NOMEM; 2833 goto end; 2834 } 2835 2836 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2837 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2838 WMITLV_SET_HDR(&cmd->tlv_header, 2839 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2840 WMITLV_GET_STRUCT_TLVLEN 2841 (wmi_scan_chan_list_cmd_fixed_param)); 2842 2843 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2844 2845 cmd->num_scan_chans = chan_list->num_scan_chans; 2846 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2847 WMITLV_TAG_ARRAY_STRUC, 2848 sizeof(wmi_channel) * chan_list->num_scan_chans); 2849 chan_info = (wmi_channel_param *) 2850 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2851 tchan_info = chan_list->chan_info; 2852 2853 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2854 WMITLV_SET_HDR(&chan_info->tlv_header, 2855 WMITLV_TAG_STRUC_wmi_channel, 2856 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2857 chan_info->mhz = tchan_info->mhz; 2858 chan_info->band_center_freq1 = 2859 tchan_info->band_center_freq1; 2860 chan_info->band_center_freq2 = 2861 tchan_info->band_center_freq2; 2862 chan_info->info = tchan_info->info; 2863 chan_info->reg_info_1 = tchan_info->reg_info_1; 2864 chan_info->reg_info_2 = tchan_info->reg_info_2; 2865 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2866 2867 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2868 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2869 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2870 tchan_info++; 2871 chan_info++; 2872 } 2873 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2874 chan_list->pdev_id); 2875 2876 qdf_status = wmi_unified_cmd_send(wmi_handle, 2877 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2878 2879 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2880 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2881 wmi_buf_free(buf); 2882 } 2883 2884 end: 2885 return qdf_status; 2886 } 2887 #else 2888 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2889 struct scan_chan_list_params *chan_list) 2890 { 2891 wmi_buf_t buf; 2892 QDF_STATUS qdf_status; 2893 wmi_scan_chan_list_cmd_fixed_param *cmd; 2894 int i; 2895 uint8_t *buf_ptr; 2896 wmi_channel *chan_info; 2897 struct channel_param *tchan_info; 2898 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2899 2900 len += sizeof(wmi_channel) * chan_list->nallchans; 2901 buf = wmi_buf_alloc(wmi_handle, len); 2902 if (!buf) { 2903 WMI_LOGE("Failed to allocate memory"); 2904 qdf_status = QDF_STATUS_E_NOMEM; 2905 goto end; 2906 } 2907 2908 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2909 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2910 WMITLV_SET_HDR(&cmd->tlv_header, 2911 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2912 WMITLV_GET_STRUCT_TLVLEN 2913 (wmi_scan_chan_list_cmd_fixed_param)); 2914 2915 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2916 2917 if (chan_list->append) 2918 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2919 2920 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2921 chan_list->pdev_id); 2922 cmd->num_scan_chans = chan_list->nallchans; 2923 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2924 WMITLV_TAG_ARRAY_STRUC, 2925 sizeof(wmi_channel) * chan_list->nallchans); 2926 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2927 tchan_info = &(chan_list->ch_param[0]); 2928 2929 for (i = 0; i < chan_list->nallchans; ++i) { 2930 WMITLV_SET_HDR(&chan_info->tlv_header, 2931 WMITLV_TAG_STRUC_wmi_channel, 2932 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2933 chan_info->mhz = tchan_info->mhz; 2934 chan_info->band_center_freq1 = 2935 tchan_info->cfreq1; 2936 chan_info->band_center_freq2 = 2937 tchan_info->cfreq2; 2938 2939 if (tchan_info->is_chan_passive) 2940 WMI_SET_CHANNEL_FLAG(chan_info, 2941 WMI_CHAN_FLAG_PASSIVE); 2942 2943 if (tchan_info->allow_vht) 2944 WMI_SET_CHANNEL_FLAG(chan_info, 2945 WMI_CHAN_FLAG_ALLOW_VHT); 2946 else if (tchan_info->allow_ht) 2947 WMI_SET_CHANNEL_FLAG(chan_info, 2948 WMI_CHAN_FLAG_ALLOW_HT); 2949 WMI_SET_CHANNEL_MODE(chan_info, 2950 tchan_info->phy_mode); 2951 2952 if (tchan_info->half_rate) 2953 WMI_SET_CHANNEL_FLAG(chan_info, 2954 WMI_CHAN_FLAG_HALF_RATE); 2955 2956 if (tchan_info->quarter_rate) 2957 WMI_SET_CHANNEL_FLAG(chan_info, 2958 WMI_CHAN_FLAG_QUARTER_RATE); 2959 2960 /* also fill in power information */ 2961 WMI_SET_CHANNEL_MIN_POWER(chan_info, 2962 tchan_info->minpower); 2963 WMI_SET_CHANNEL_MAX_POWER(chan_info, 2964 tchan_info->maxpower); 2965 WMI_SET_CHANNEL_REG_POWER(chan_info, 2966 tchan_info->maxregpower); 2967 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 2968 tchan_info->antennamax); 2969 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 2970 tchan_info->reg_class_id); 2971 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 2972 tchan_info->maxregpower); 2973 2974 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2975 2976 tchan_info++; 2977 chan_info++; 2978 } 2979 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2980 chan_list->pdev_id); 2981 2982 qdf_status = wmi_unified_cmd_send( 2983 wmi_handle, 2984 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2985 2986 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2987 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2988 wmi_buf_free(buf); 2989 } 2990 2991 end: 2992 return qdf_status; 2993 } 2994 #endif 2995 2996 /** 2997 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 2998 * 2999 * @bufp: Pointer to buffer 3000 * @param: Pointer to tx param 3001 * 3002 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3003 */ 3004 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3005 struct tx_send_params param) 3006 { 3007 wmi_tx_send_params *tx_param; 3008 QDF_STATUS status = QDF_STATUS_SUCCESS; 3009 3010 if (!bufp) { 3011 status = QDF_STATUS_E_FAILURE; 3012 return status; 3013 } 3014 tx_param = (wmi_tx_send_params *)bufp; 3015 WMITLV_SET_HDR(&tx_param->tlv_header, 3016 WMITLV_TAG_STRUC_wmi_tx_send_params, 3017 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3018 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3019 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3020 param.mcs_mask); 3021 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3022 param.nss_mask); 3023 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3024 param.retry_limit); 3025 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3026 param.chain_mask); 3027 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3028 param.bw_mask); 3029 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3030 param.preamble_type); 3031 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3032 param.frame_type); 3033 3034 return status; 3035 } 3036 3037 /** 3038 * send_mgmt_cmd_tlv() - WMI scan start function 3039 * @wmi_handle : handle to WMI. 3040 * @param : pointer to hold mgmt cmd parameter 3041 * 3042 * Return: 0 on success and -ve on failure. 3043 */ 3044 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3045 struct wmi_mgmt_params *param) 3046 { 3047 wmi_buf_t buf; 3048 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3049 int32_t cmd_len; 3050 uint64_t dma_addr; 3051 void *qdf_ctx = param->qdf_ctx; 3052 uint8_t *bufp; 3053 QDF_STATUS status = QDF_STATUS_SUCCESS; 3054 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3055 mgmt_tx_dl_frm_len; 3056 3057 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3058 WMI_TLV_HDR_SIZE + 3059 roundup(bufp_len, sizeof(uint32_t)); 3060 3061 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3062 if (!buf) { 3063 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3064 return QDF_STATUS_E_NOMEM; 3065 } 3066 3067 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3068 bufp = (uint8_t *) cmd; 3069 WMITLV_SET_HDR(&cmd->tlv_header, 3070 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3071 WMITLV_GET_STRUCT_TLVLEN 3072 (wmi_mgmt_tx_send_cmd_fixed_param)); 3073 3074 cmd->vdev_id = param->vdev_id; 3075 3076 cmd->desc_id = param->desc_id; 3077 cmd->chanfreq = param->chanfreq; 3078 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3079 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3080 sizeof(uint32_t))); 3081 bufp += WMI_TLV_HDR_SIZE; 3082 qdf_mem_copy(bufp, param->pdata, bufp_len); 3083 3084 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3085 QDF_DMA_TO_DEVICE); 3086 if (status != QDF_STATUS_SUCCESS) { 3087 WMI_LOGE("%s: wmi buf map failed", __func__); 3088 goto free_buf; 3089 } 3090 3091 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3092 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3093 #if defined(HTT_PADDR64) 3094 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3095 #endif 3096 cmd->frame_len = param->frm_len; 3097 cmd->buf_len = bufp_len; 3098 cmd->tx_params_valid = param->tx_params_valid; 3099 3100 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3101 bufp, cmd->vdev_id, cmd->chanfreq); 3102 3103 bufp += roundup(bufp_len, sizeof(uint32_t)); 3104 if (param->tx_params_valid) { 3105 status = populate_tx_send_params(bufp, param->tx_param); 3106 if (status != QDF_STATUS_SUCCESS) { 3107 WMI_LOGE("%s: Populate TX send params failed", 3108 __func__); 3109 goto unmap_tx_frame; 3110 } 3111 cmd_len += sizeof(wmi_tx_send_params); 3112 } 3113 3114 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3115 WMI_MGMT_TX_SEND_CMDID)) { 3116 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3117 goto unmap_tx_frame; 3118 } 3119 return QDF_STATUS_SUCCESS; 3120 3121 unmap_tx_frame: 3122 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3123 QDF_DMA_TO_DEVICE); 3124 free_buf: 3125 wmi_buf_free(buf); 3126 return QDF_STATUS_E_FAILURE; 3127 } 3128 3129 /** 3130 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3131 * @wmi_handle : handle to WMI. 3132 * @param : pointer to offchan data tx cmd parameter 3133 * 3134 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3135 */ 3136 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3137 struct wmi_offchan_data_tx_params *param) 3138 { 3139 wmi_buf_t buf; 3140 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3141 int32_t cmd_len; 3142 uint64_t dma_addr; 3143 void *qdf_ctx = param->qdf_ctx; 3144 uint8_t *bufp; 3145 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3146 param->frm_len : mgmt_tx_dl_frm_len; 3147 QDF_STATUS status = QDF_STATUS_SUCCESS; 3148 3149 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3150 WMI_TLV_HDR_SIZE + 3151 roundup(bufp_len, sizeof(uint32_t)); 3152 3153 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3154 if (!buf) { 3155 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3156 return QDF_STATUS_E_NOMEM; 3157 } 3158 3159 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3160 bufp = (uint8_t *) cmd; 3161 WMITLV_SET_HDR(&cmd->tlv_header, 3162 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3163 WMITLV_GET_STRUCT_TLVLEN 3164 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3165 3166 cmd->vdev_id = param->vdev_id; 3167 3168 cmd->desc_id = param->desc_id; 3169 cmd->chanfreq = param->chanfreq; 3170 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3171 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3172 sizeof(uint32_t))); 3173 bufp += WMI_TLV_HDR_SIZE; 3174 qdf_mem_copy(bufp, param->pdata, bufp_len); 3175 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3176 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3177 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3178 #if defined(HTT_PADDR64) 3179 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3180 #endif 3181 cmd->frame_len = param->frm_len; 3182 cmd->buf_len = bufp_len; 3183 cmd->tx_params_valid = param->tx_params_valid; 3184 3185 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3186 bufp, cmd->vdev_id, cmd->chanfreq); 3187 3188 bufp += roundup(bufp_len, sizeof(uint32_t)); 3189 if (param->tx_params_valid) { 3190 status = populate_tx_send_params(bufp, param->tx_param); 3191 if (status != QDF_STATUS_SUCCESS) { 3192 WMI_LOGE("%s: Populate TX send params failed", 3193 __func__); 3194 goto err1; 3195 } 3196 cmd_len += sizeof(wmi_tx_send_params); 3197 } 3198 3199 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3200 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3201 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3202 goto err1; 3203 } 3204 3205 return QDF_STATUS_SUCCESS; 3206 3207 err1: 3208 wmi_buf_free(buf); 3209 return QDF_STATUS_E_FAILURE; 3210 } 3211 3212 /** 3213 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3214 * @wmi_handle: wmi handle 3215 * @param_value: parameter value 3216 * 3217 * Return: QDF_STATUS_SUCCESS for success or error code 3218 */ 3219 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3220 uint32_t param_value) 3221 { 3222 QDF_STATUS ret; 3223 wmi_modem_power_state_cmd_param *cmd; 3224 wmi_buf_t buf; 3225 uint16_t len = sizeof(*cmd); 3226 3227 buf = wmi_buf_alloc(wmi_handle, len); 3228 if (!buf) { 3229 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3230 return QDF_STATUS_E_NOMEM; 3231 } 3232 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3233 WMITLV_SET_HDR(&cmd->tlv_header, 3234 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3235 WMITLV_GET_STRUCT_TLVLEN 3236 (wmi_modem_power_state_cmd_param)); 3237 cmd->modem_power_state = param_value; 3238 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3239 param_value); 3240 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3241 WMI_MODEM_POWER_STATE_CMDID); 3242 if (QDF_IS_STATUS_ERROR(ret)) { 3243 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3244 wmi_buf_free(buf); 3245 } 3246 3247 return ret; 3248 } 3249 3250 /** 3251 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3252 * @wmi_handle: wmi handle 3253 * @vdev_id: vdev id 3254 * @val: value 3255 * 3256 * Return: QDF_STATUS_SUCCESS for success or error code. 3257 */ 3258 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3259 uint32_t vdev_id, uint8_t val) 3260 { 3261 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3262 wmi_buf_t buf; 3263 int32_t len = sizeof(*cmd); 3264 3265 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3266 3267 buf = wmi_buf_alloc(wmi_handle, len); 3268 if (!buf) { 3269 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3270 return QDF_STATUS_E_NOMEM; 3271 } 3272 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3273 WMITLV_SET_HDR(&cmd->tlv_header, 3274 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3275 WMITLV_GET_STRUCT_TLVLEN 3276 (wmi_sta_powersave_mode_cmd_fixed_param)); 3277 cmd->vdev_id = vdev_id; 3278 if (val) 3279 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3280 else 3281 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3282 3283 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3284 WMI_STA_POWERSAVE_MODE_CMDID)) { 3285 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3286 vdev_id, val); 3287 wmi_buf_free(buf); 3288 return QDF_STATUS_E_FAILURE; 3289 } 3290 return 0; 3291 } 3292 3293 /** 3294 * send_set_mimops_cmd_tlv() - set MIMO powersave 3295 * @wmi_handle: wmi handle 3296 * @vdev_id: vdev id 3297 * @value: value 3298 * 3299 * Return: QDF_STATUS_SUCCESS for success or error code. 3300 */ 3301 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3302 uint8_t vdev_id, int value) 3303 { 3304 QDF_STATUS ret; 3305 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3306 wmi_buf_t buf; 3307 uint16_t len = sizeof(*cmd); 3308 3309 buf = wmi_buf_alloc(wmi_handle, len); 3310 if (!buf) { 3311 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3312 return QDF_STATUS_E_NOMEM; 3313 } 3314 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3315 WMITLV_SET_HDR(&cmd->tlv_header, 3316 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3317 WMITLV_GET_STRUCT_TLVLEN 3318 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3319 3320 cmd->vdev_id = vdev_id; 3321 3322 /* WMI_SMPS_FORCED_MODE values do not directly map 3323 * to SM power save values defined in the specification. 3324 * Make sure to send the right mapping. 3325 */ 3326 switch (value) { 3327 case 0: 3328 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3329 break; 3330 case 1: 3331 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3332 break; 3333 case 2: 3334 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3335 break; 3336 case 3: 3337 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3338 break; 3339 default: 3340 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3341 wmi_buf_free(buf); 3342 return QDF_STATUS_E_FAILURE; 3343 } 3344 3345 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3346 3347 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3348 WMI_STA_SMPS_FORCE_MODE_CMDID); 3349 if (QDF_IS_STATUS_ERROR(ret)) { 3350 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3351 wmi_buf_free(buf); 3352 } 3353 3354 return ret; 3355 } 3356 3357 /** 3358 * send_set_smps_params_cmd_tlv() - set smps params 3359 * @wmi_handle: wmi handle 3360 * @vdev_id: vdev id 3361 * @value: value 3362 * 3363 * Return: QDF_STATUS_SUCCESS for success or error code. 3364 */ 3365 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3366 int value) 3367 { 3368 QDF_STATUS ret; 3369 wmi_sta_smps_param_cmd_fixed_param *cmd; 3370 wmi_buf_t buf; 3371 uint16_t len = sizeof(*cmd); 3372 3373 buf = wmi_buf_alloc(wmi_handle, len); 3374 if (!buf) { 3375 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3376 return QDF_STATUS_E_NOMEM; 3377 } 3378 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3379 WMITLV_SET_HDR(&cmd->tlv_header, 3380 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3381 WMITLV_GET_STRUCT_TLVLEN 3382 (wmi_sta_smps_param_cmd_fixed_param)); 3383 3384 cmd->vdev_id = vdev_id; 3385 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3386 cmd->param = 3387 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3388 3389 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3390 cmd->param); 3391 3392 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3393 WMI_STA_SMPS_PARAM_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_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3404 * @wmi_handle: wmi handle 3405 * @noa: p2p power save parameters 3406 * 3407 * Return: CDF status 3408 */ 3409 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3410 struct p2p_ps_params *noa) 3411 { 3412 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3413 wmi_p2p_noa_descriptor *noa_discriptor; 3414 wmi_buf_t buf; 3415 uint8_t *buf_ptr; 3416 uint16_t len; 3417 QDF_STATUS status; 3418 uint32_t duration; 3419 3420 WMI_LOGD("%s: Enter", __func__); 3421 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3422 buf = wmi_buf_alloc(wmi_handle, len); 3423 if (!buf) { 3424 WMI_LOGE("Failed to allocate memory"); 3425 status = QDF_STATUS_E_FAILURE; 3426 goto end; 3427 } 3428 3429 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3430 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3431 WMITLV_SET_HDR(&cmd->tlv_header, 3432 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3433 WMITLV_GET_STRUCT_TLVLEN 3434 (wmi_p2p_set_noa_cmd_fixed_param)); 3435 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3436 cmd->vdev_id = noa->session_id; 3437 cmd->enable = (duration) ? true : false; 3438 cmd->num_noa = 1; 3439 3440 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3441 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3442 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3443 sizeof 3444 (wmi_p2p_set_noa_cmd_fixed_param) 3445 + WMI_TLV_HDR_SIZE); 3446 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3447 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3448 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3449 noa_discriptor->type_count = noa->count; 3450 noa_discriptor->duration = duration; 3451 noa_discriptor->interval = noa->interval; 3452 noa_discriptor->start_time = 0; 3453 3454 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3455 cmd->vdev_id, noa->count, noa_discriptor->duration, 3456 noa->interval); 3457 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3458 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3459 if (QDF_IS_STATUS_ERROR(status)) { 3460 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3461 wmi_buf_free(buf); 3462 } 3463 3464 end: 3465 WMI_LOGD("%s: Exit", __func__); 3466 return status; 3467 } 3468 3469 3470 /** 3471 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3472 * @wmi_handle: wmi handle 3473 * @noa: p2p opp power save parameters 3474 * 3475 * Return: CDF status 3476 */ 3477 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3478 struct p2p_ps_params *oppps) 3479 { 3480 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3481 wmi_buf_t buf; 3482 QDF_STATUS status; 3483 3484 WMI_LOGD("%s: Enter", __func__); 3485 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3486 if (!buf) { 3487 WMI_LOGE("Failed to allocate memory"); 3488 status = QDF_STATUS_E_FAILURE; 3489 goto end; 3490 } 3491 3492 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3493 WMITLV_SET_HDR(&cmd->tlv_header, 3494 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3495 WMITLV_GET_STRUCT_TLVLEN 3496 (wmi_p2p_set_oppps_cmd_fixed_param)); 3497 cmd->vdev_id = oppps->session_id; 3498 if (oppps->ctwindow) 3499 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3500 3501 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3502 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3503 cmd->vdev_id, oppps->ctwindow); 3504 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3505 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3506 if (QDF_IS_STATUS_ERROR(status)) { 3507 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3508 wmi_buf_free(buf); 3509 } 3510 3511 end: 3512 WMI_LOGD("%s: Exit", __func__); 3513 return status; 3514 } 3515 3516 #ifdef CONVERGED_P2P_ENABLE 3517 /** 3518 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3519 * @wmi_handle: wmi handle 3520 * @param: p2p listen offload start parameters 3521 * 3522 * Return: QDF status 3523 */ 3524 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3525 struct p2p_lo_start *param) 3526 { 3527 wmi_buf_t buf; 3528 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3529 int32_t len = sizeof(*cmd); 3530 uint8_t *buf_ptr; 3531 QDF_STATUS status; 3532 int device_types_len_aligned; 3533 int probe_resp_len_aligned; 3534 3535 if (!param) { 3536 WMI_LOGE("lo start param is null"); 3537 return QDF_STATUS_E_INVAL; 3538 } 3539 3540 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3541 3542 device_types_len_aligned = 3543 qdf_roundup(param->dev_types_len, 3544 sizeof(uint32_t)); 3545 probe_resp_len_aligned = 3546 qdf_roundup(param->probe_resp_len, 3547 sizeof(uint32_t)); 3548 3549 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3550 probe_resp_len_aligned; 3551 3552 buf = wmi_buf_alloc(wmi_handle, len); 3553 if (!buf) { 3554 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3555 __func__); 3556 return QDF_STATUS_E_NOMEM; 3557 } 3558 3559 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3560 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3561 3562 WMITLV_SET_HDR(&cmd->tlv_header, 3563 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3564 WMITLV_GET_STRUCT_TLVLEN( 3565 wmi_p2p_lo_start_cmd_fixed_param)); 3566 3567 cmd->vdev_id = param->vdev_id; 3568 cmd->ctl_flags = param->ctl_flags; 3569 cmd->channel = param->freq; 3570 cmd->period = param->period; 3571 cmd->interval = param->interval; 3572 cmd->count = param->count; 3573 cmd->device_types_len = param->dev_types_len; 3574 cmd->prob_resp_len = param->probe_resp_len; 3575 3576 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3577 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3578 device_types_len_aligned); 3579 buf_ptr += WMI_TLV_HDR_SIZE; 3580 qdf_mem_copy(buf_ptr, param->device_types, 3581 param->dev_types_len); 3582 3583 buf_ptr += device_types_len_aligned; 3584 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3585 probe_resp_len_aligned); 3586 buf_ptr += WMI_TLV_HDR_SIZE; 3587 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3588 param->probe_resp_len); 3589 3590 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3591 cmd->channel, cmd->period, cmd->interval, cmd->count); 3592 3593 status = wmi_unified_cmd_send(wmi_handle, 3594 buf, len, 3595 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3596 if (status != QDF_STATUS_SUCCESS) { 3597 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3598 __func__, status); 3599 wmi_buf_free(buf); 3600 return status; 3601 } 3602 3603 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3604 3605 return QDF_STATUS_SUCCESS; 3606 } 3607 3608 /** 3609 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3610 * @wmi_handle: wmi handle 3611 * @param: p2p listen offload stop parameters 3612 * 3613 * Return: QDF status 3614 */ 3615 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3616 uint8_t vdev_id) 3617 { 3618 wmi_buf_t buf; 3619 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3620 int32_t len; 3621 QDF_STATUS status; 3622 3623 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3624 3625 len = sizeof(*cmd); 3626 buf = wmi_buf_alloc(wmi_handle, len); 3627 if (!buf) { 3628 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3629 __func__); 3630 return QDF_STATUS_E_NOMEM; 3631 } 3632 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3633 3634 WMITLV_SET_HDR(&cmd->tlv_header, 3635 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3636 WMITLV_GET_STRUCT_TLVLEN( 3637 wmi_p2p_lo_stop_cmd_fixed_param)); 3638 3639 cmd->vdev_id = vdev_id; 3640 3641 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3642 3643 status = wmi_unified_cmd_send(wmi_handle, 3644 buf, len, 3645 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3646 if (status != QDF_STATUS_SUCCESS) { 3647 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3648 __func__, status); 3649 wmi_buf_free(buf); 3650 return status; 3651 } 3652 3653 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3654 3655 return QDF_STATUS_SUCCESS; 3656 } 3657 #endif /* End of CONVERGED_P2P_ENABLE */ 3658 3659 /** 3660 * send_get_temperature_cmd_tlv() - get pdev temperature req 3661 * @wmi_handle: wmi handle 3662 * 3663 * Return: QDF_STATUS_SUCCESS for success or error code. 3664 */ 3665 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3666 { 3667 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3668 wmi_buf_t wmi_buf; 3669 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3670 uint8_t *buf_ptr; 3671 3672 if (!wmi_handle) { 3673 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3674 return QDF_STATUS_E_INVAL; 3675 } 3676 3677 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3678 if (!wmi_buf) { 3679 WMI_LOGE(FL("wmi_buf_alloc failed")); 3680 return QDF_STATUS_E_NOMEM; 3681 } 3682 3683 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3684 3685 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3686 WMITLV_SET_HDR(&cmd->tlv_header, 3687 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3688 WMITLV_GET_STRUCT_TLVLEN 3689 (wmi_pdev_get_temperature_cmd_fixed_param)); 3690 3691 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3692 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3693 WMI_LOGE(FL("failed to send get temperature command")); 3694 wmi_buf_free(wmi_buf); 3695 return QDF_STATUS_E_FAILURE; 3696 } 3697 3698 return QDF_STATUS_SUCCESS; 3699 } 3700 3701 /** 3702 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3703 * @wmi_handle: wmi handle 3704 * @vdevid: vdev id 3705 * @peer_addr: peer mac address 3706 * @auto_triggerparam: auto trigger parameters 3707 * @num_ac: number of access category 3708 * 3709 * This function sets the trigger 3710 * uapsd params such as service interval, delay interval 3711 * and suspend interval which will be used by the firmware 3712 * to send trigger frames periodically when there is no 3713 * traffic on the transmit side. 3714 * 3715 * Return: QDF_STATUS_SUCCESS for success or error code. 3716 */ 3717 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3718 struct sta_uapsd_trig_params *param) 3719 { 3720 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3721 QDF_STATUS ret; 3722 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3723 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3724 uint32_t i; 3725 wmi_buf_t buf; 3726 uint8_t *buf_ptr; 3727 struct sta_uapsd_params *uapsd_param; 3728 wmi_sta_uapsd_auto_trig_param *trig_param; 3729 3730 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3731 if (!buf) { 3732 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3733 return QDF_STATUS_E_NOMEM; 3734 } 3735 3736 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3737 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3738 WMITLV_SET_HDR(&cmd->tlv_header, 3739 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3740 WMITLV_GET_STRUCT_TLVLEN 3741 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3742 cmd->vdev_id = param->vdevid; 3743 cmd->num_ac = param->num_ac; 3744 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3745 3746 /* TLV indicating array of structures to follow */ 3747 buf_ptr += sizeof(*cmd); 3748 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3749 3750 buf_ptr += WMI_TLV_HDR_SIZE; 3751 3752 /* 3753 * Update tag and length for uapsd auto trigger params (this will take 3754 * care of updating tag and length if it is not pre-filled by caller). 3755 */ 3756 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3757 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3758 for (i = 0; i < param->num_ac; i++) { 3759 WMITLV_SET_HDR((buf_ptr + 3760 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3761 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3762 WMITLV_GET_STRUCT_TLVLEN 3763 (wmi_sta_uapsd_auto_trig_param)); 3764 trig_param->wmm_ac = uapsd_param->wmm_ac; 3765 trig_param->user_priority = uapsd_param->user_priority; 3766 trig_param->service_interval = uapsd_param->service_interval; 3767 trig_param->suspend_interval = uapsd_param->suspend_interval; 3768 trig_param->delay_interval = uapsd_param->delay_interval; 3769 trig_param++; 3770 uapsd_param++; 3771 } 3772 3773 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3774 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3775 if (QDF_IS_STATUS_ERROR(ret)) { 3776 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3777 wmi_buf_free(buf); 3778 } 3779 3780 return ret; 3781 } 3782 3783 #ifdef WLAN_FEATURE_DSRC 3784 /** 3785 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3786 * @wmi_handle: pointer to the wmi handle 3787 * @utc: pointer to the UTC time struct 3788 * 3789 * Return: 0 on succes 3790 */ 3791 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3792 struct ocb_utc_param *utc) 3793 { 3794 QDF_STATUS ret; 3795 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3796 uint8_t *buf_ptr; 3797 uint32_t len, i; 3798 wmi_buf_t buf; 3799 3800 len = sizeof(*cmd); 3801 buf = wmi_buf_alloc(wmi_handle, len); 3802 if (!buf) { 3803 WMI_LOGE(FL("wmi_buf_alloc failed")); 3804 return QDF_STATUS_E_NOMEM; 3805 } 3806 3807 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3808 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3809 WMITLV_SET_HDR(&cmd->tlv_header, 3810 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3811 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3812 cmd->vdev_id = utc->vdev_id; 3813 3814 for (i = 0; i < SIZE_UTC_TIME; i++) 3815 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 3816 3817 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 3818 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 3819 3820 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3821 WMI_OCB_SET_UTC_TIME_CMDID); 3822 if (QDF_IS_STATUS_ERROR(ret)) { 3823 WMI_LOGE(FL("Failed to set OCB UTC time")); 3824 wmi_buf_free(buf); 3825 } 3826 3827 return ret; 3828 } 3829 3830 /** 3831 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 3832 * frames on a channel 3833 * @wmi_handle: pointer to the wmi handle 3834 * @timing_advert: pointer to the timing advertisement struct 3835 * 3836 * Return: 0 on succes 3837 */ 3838 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3839 struct ocb_timing_advert_param *timing_advert) 3840 { 3841 QDF_STATUS ret; 3842 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 3843 uint8_t *buf_ptr; 3844 uint32_t len, len_template; 3845 wmi_buf_t buf; 3846 3847 len = sizeof(*cmd) + 3848 WMI_TLV_HDR_SIZE; 3849 3850 len_template = timing_advert->template_length; 3851 /* Add padding to the template if needed */ 3852 if (len_template % 4 != 0) 3853 len_template += 4 - (len_template % 4); 3854 len += len_template; 3855 3856 buf = wmi_buf_alloc(wmi_handle, len); 3857 if (!buf) { 3858 WMI_LOGE(FL("wmi_buf_alloc failed")); 3859 return QDF_STATUS_E_NOMEM; 3860 } 3861 3862 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3863 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 3864 WMITLV_SET_HDR(&cmd->tlv_header, 3865 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 3866 WMITLV_GET_STRUCT_TLVLEN( 3867 wmi_ocb_start_timing_advert_cmd_fixed_param)); 3868 cmd->vdev_id = timing_advert->vdev_id; 3869 cmd->repeat_rate = timing_advert->repeat_rate; 3870 cmd->channel_freq = timing_advert->chan_freq; 3871 cmd->timestamp_offset = timing_advert->timestamp_offset; 3872 cmd->time_value_offset = timing_advert->time_value_offset; 3873 cmd->timing_advert_template_length = timing_advert->template_length; 3874 buf_ptr += sizeof(*cmd); 3875 3876 /* Add the timing advert template */ 3877 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3878 len_template); 3879 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 3880 (uint8_t *)timing_advert->template_value, 3881 timing_advert->template_length); 3882 3883 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3884 WMI_OCB_START_TIMING_ADVERT_CMDID); 3885 if (QDF_IS_STATUS_ERROR(ret)) { 3886 WMI_LOGE(FL("Failed to start OCB timing advert")); 3887 wmi_buf_free(buf); 3888 } 3889 3890 return ret; 3891 } 3892 3893 /** 3894 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 3895 * on a channel 3896 * @wmi_handle: pointer to the wmi handle 3897 * @timing_advert: pointer to the timing advertisement struct 3898 * 3899 * Return: 0 on succes 3900 */ 3901 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3902 struct ocb_timing_advert_param *timing_advert) 3903 { 3904 QDF_STATUS ret; 3905 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 3906 uint8_t *buf_ptr; 3907 uint32_t len; 3908 wmi_buf_t buf; 3909 3910 len = sizeof(*cmd); 3911 buf = wmi_buf_alloc(wmi_handle, len); 3912 if (!buf) { 3913 WMI_LOGE(FL("wmi_buf_alloc failed")); 3914 return QDF_STATUS_E_NOMEM; 3915 } 3916 3917 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3918 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 3919 WMITLV_SET_HDR(&cmd->tlv_header, 3920 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 3921 WMITLV_GET_STRUCT_TLVLEN( 3922 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 3923 cmd->vdev_id = timing_advert->vdev_id; 3924 cmd->channel_freq = timing_advert->chan_freq; 3925 3926 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3927 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 3928 if (QDF_IS_STATUS_ERROR(ret)) { 3929 WMI_LOGE(FL("Failed to stop OCB timing advert")); 3930 wmi_buf_free(buf); 3931 } 3932 3933 return ret; 3934 } 3935 3936 /** 3937 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 3938 * @wmi_handle: pointer to the wmi handle 3939 * @request: pointer to the request 3940 * 3941 * Return: 0 on succes 3942 */ 3943 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 3944 uint8_t vdev_id) 3945 { 3946 QDF_STATUS ret; 3947 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 3948 uint8_t *buf_ptr; 3949 wmi_buf_t buf; 3950 int32_t len; 3951 3952 len = sizeof(*cmd); 3953 buf = wmi_buf_alloc(wmi_handle, len); 3954 if (!buf) { 3955 WMI_LOGE(FL("wmi_buf_alloc failed")); 3956 return QDF_STATUS_E_NOMEM; 3957 } 3958 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3959 3960 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 3961 qdf_mem_zero(cmd, len); 3962 WMITLV_SET_HDR(&cmd->tlv_header, 3963 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 3964 WMITLV_GET_STRUCT_TLVLEN( 3965 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 3966 cmd->vdev_id = vdev_id; 3967 3968 /* Send the WMI command */ 3969 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3970 WMI_OCB_GET_TSF_TIMER_CMDID); 3971 /* If there is an error, set the completion event */ 3972 if (QDF_IS_STATUS_ERROR(ret)) { 3973 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 3974 wmi_buf_free(buf); 3975 } 3976 3977 return ret; 3978 } 3979 3980 /** 3981 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 3982 * @wmi_handle: pointer to the wmi handle 3983 * @get_stats_param: pointer to the dcc stats 3984 * 3985 * Return: 0 on succes 3986 */ 3987 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 3988 struct ocb_dcc_get_stats_param *get_stats_param) 3989 { 3990 QDF_STATUS ret; 3991 wmi_dcc_get_stats_cmd_fixed_param *cmd; 3992 wmi_dcc_channel_stats_request *channel_stats_array; 3993 wmi_buf_t buf; 3994 uint8_t *buf_ptr; 3995 uint32_t len; 3996 uint32_t i; 3997 3998 /* Validate the input */ 3999 if (get_stats_param->request_array_len != 4000 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4001 WMI_LOGE(FL("Invalid parameter")); 4002 return QDF_STATUS_E_INVAL; 4003 } 4004 4005 /* Allocate memory for the WMI command */ 4006 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4007 get_stats_param->request_array_len; 4008 4009 buf = wmi_buf_alloc(wmi_handle, len); 4010 if (!buf) { 4011 WMI_LOGE(FL("wmi_buf_alloc failed")); 4012 return QDF_STATUS_E_NOMEM; 4013 } 4014 4015 buf_ptr = wmi_buf_data(buf); 4016 qdf_mem_zero(buf_ptr, len); 4017 4018 /* Populate the WMI command */ 4019 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4020 buf_ptr += sizeof(*cmd); 4021 4022 WMITLV_SET_HDR(&cmd->tlv_header, 4023 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4024 WMITLV_GET_STRUCT_TLVLEN( 4025 wmi_dcc_get_stats_cmd_fixed_param)); 4026 cmd->vdev_id = get_stats_param->vdev_id; 4027 cmd->num_channels = get_stats_param->channel_count; 4028 4029 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4030 get_stats_param->request_array_len); 4031 buf_ptr += WMI_TLV_HDR_SIZE; 4032 4033 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4034 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4035 get_stats_param->request_array_len); 4036 for (i = 0; i < cmd->num_channels; i++) 4037 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4038 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4039 WMITLV_GET_STRUCT_TLVLEN( 4040 wmi_dcc_channel_stats_request)); 4041 4042 /* Send the WMI command */ 4043 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4044 WMI_DCC_GET_STATS_CMDID); 4045 4046 if (QDF_IS_STATUS_ERROR(ret)) { 4047 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4048 wmi_buf_free(buf); 4049 } 4050 4051 return ret; 4052 } 4053 4054 /** 4055 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4056 * @wmi_handle: pointer to the wmi handle 4057 * @vdev_id: vdev id 4058 * @dcc_stats_bitmap: dcc status bitmap 4059 * 4060 * Return: 0 on succes 4061 */ 4062 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4063 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4064 { 4065 QDF_STATUS ret; 4066 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4067 wmi_buf_t buf; 4068 uint8_t *buf_ptr; 4069 uint32_t len; 4070 4071 /* Allocate memory for the WMI command */ 4072 len = sizeof(*cmd); 4073 4074 buf = wmi_buf_alloc(wmi_handle, len); 4075 if (!buf) { 4076 WMI_LOGE(FL("wmi_buf_alloc failed")); 4077 return QDF_STATUS_E_NOMEM; 4078 } 4079 4080 buf_ptr = wmi_buf_data(buf); 4081 qdf_mem_zero(buf_ptr, len); 4082 4083 /* Populate the WMI command */ 4084 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4085 4086 WMITLV_SET_HDR(&cmd->tlv_header, 4087 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4088 WMITLV_GET_STRUCT_TLVLEN( 4089 wmi_dcc_clear_stats_cmd_fixed_param)); 4090 cmd->vdev_id = vdev_id; 4091 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4092 4093 /* Send the WMI command */ 4094 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4095 WMI_DCC_CLEAR_STATS_CMDID); 4096 if (QDF_IS_STATUS_ERROR(ret)) { 4097 WMI_LOGE(FL("Failed to send the WMI command")); 4098 wmi_buf_free(buf); 4099 } 4100 4101 return ret; 4102 } 4103 4104 /** 4105 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4106 * @wmi_handle: pointer to the wmi handle 4107 * @update_ndl_param: pointer to the request parameters 4108 * 4109 * Return: 0 on success 4110 */ 4111 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4112 struct ocb_dcc_update_ndl_param *update_ndl_param) 4113 { 4114 QDF_STATUS qdf_status; 4115 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4116 wmi_dcc_ndl_chan *ndl_chan_array; 4117 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4118 uint32_t active_state_count; 4119 wmi_buf_t buf; 4120 uint8_t *buf_ptr; 4121 uint32_t len; 4122 uint32_t i; 4123 4124 /* validate the input */ 4125 if (update_ndl_param->dcc_ndl_chan_list_len != 4126 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4127 WMI_LOGE(FL("Invalid parameter")); 4128 return QDF_STATUS_E_INVAL; 4129 } 4130 active_state_count = 0; 4131 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4132 for (i = 0; i < update_ndl_param->channel_count; i++) 4133 active_state_count += 4134 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4135 if (update_ndl_param->dcc_ndl_active_state_list_len != 4136 active_state_count * sizeof(*ndl_active_state_array)) { 4137 WMI_LOGE(FL("Invalid parameter")); 4138 return QDF_STATUS_E_INVAL; 4139 } 4140 4141 /* Allocate memory for the WMI command */ 4142 len = sizeof(*cmd) + 4143 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4144 WMI_TLV_HDR_SIZE + 4145 update_ndl_param->dcc_ndl_active_state_list_len; 4146 4147 buf = wmi_buf_alloc(wmi_handle, len); 4148 if (!buf) { 4149 WMI_LOGE(FL("wmi_buf_alloc failed")); 4150 return QDF_STATUS_E_NOMEM; 4151 } 4152 4153 buf_ptr = wmi_buf_data(buf); 4154 qdf_mem_zero(buf_ptr, len); 4155 4156 /* Populate the WMI command */ 4157 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4158 buf_ptr += sizeof(*cmd); 4159 4160 WMITLV_SET_HDR(&cmd->tlv_header, 4161 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4162 WMITLV_GET_STRUCT_TLVLEN( 4163 wmi_dcc_update_ndl_cmd_fixed_param)); 4164 cmd->vdev_id = update_ndl_param->vdev_id; 4165 cmd->num_channel = update_ndl_param->channel_count; 4166 4167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4168 update_ndl_param->dcc_ndl_chan_list_len); 4169 buf_ptr += WMI_TLV_HDR_SIZE; 4170 4171 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4172 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4173 update_ndl_param->dcc_ndl_chan_list_len); 4174 for (i = 0; i < cmd->num_channel; i++) 4175 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4176 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4177 WMITLV_GET_STRUCT_TLVLEN( 4178 wmi_dcc_ndl_chan)); 4179 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4180 4181 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4182 update_ndl_param->dcc_ndl_active_state_list_len); 4183 buf_ptr += WMI_TLV_HDR_SIZE; 4184 4185 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4186 qdf_mem_copy(ndl_active_state_array, 4187 update_ndl_param->dcc_ndl_active_state_list, 4188 update_ndl_param->dcc_ndl_active_state_list_len); 4189 for (i = 0; i < active_state_count; i++) { 4190 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4191 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4192 WMITLV_GET_STRUCT_TLVLEN( 4193 wmi_dcc_ndl_active_state_config)); 4194 } 4195 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4196 4197 /* Send the WMI command */ 4198 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4199 WMI_DCC_UPDATE_NDL_CMDID); 4200 /* If there is an error, set the completion event */ 4201 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4202 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4203 wmi_buf_free(buf); 4204 } 4205 4206 return qdf_status; 4207 } 4208 4209 /** 4210 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4211 * @wmi_handle: pointer to the wmi handle 4212 * @config: the OCB configuration 4213 * 4214 * Return: 0 on success 4215 */ 4216 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4217 struct ocb_config *config) 4218 { 4219 QDF_STATUS ret; 4220 wmi_ocb_set_config_cmd_fixed_param *cmd; 4221 wmi_channel *chan; 4222 wmi_ocb_channel *ocb_chan; 4223 wmi_qos_parameter *qos_param; 4224 wmi_dcc_ndl_chan *ndl_chan; 4225 wmi_dcc_ndl_active_state_config *ndl_active_config; 4226 wmi_ocb_schedule_element *sched_elem; 4227 uint8_t *buf_ptr; 4228 wmi_buf_t buf; 4229 int32_t len; 4230 int32_t i, j, active_state_count; 4231 4232 /* 4233 * Validate the dcc_ndl_chan_list_len and count the number of active 4234 * states. Validate dcc_ndl_active_state_list_len. 4235 */ 4236 active_state_count = 0; 4237 if (config->dcc_ndl_chan_list_len) { 4238 if (!config->dcc_ndl_chan_list || 4239 config->dcc_ndl_chan_list_len != 4240 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4241 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4242 config->dcc_ndl_chan_list_len); 4243 return QDF_STATUS_E_INVAL; 4244 } 4245 4246 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4247 i < config->channel_count; ++i, ++ndl_chan) 4248 active_state_count += 4249 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4250 4251 if (active_state_count) { 4252 if (!config->dcc_ndl_active_state_list || 4253 config->dcc_ndl_active_state_list_len != 4254 active_state_count * 4255 sizeof(wmi_dcc_ndl_active_state_config)) { 4256 WMI_LOGE(FL("NDL active state is invalid.")); 4257 return QDF_STATUS_E_INVAL; 4258 } 4259 } 4260 } 4261 4262 len = sizeof(*cmd) + 4263 WMI_TLV_HDR_SIZE + config->channel_count * 4264 sizeof(wmi_channel) + 4265 WMI_TLV_HDR_SIZE + config->channel_count * 4266 sizeof(wmi_ocb_channel) + 4267 WMI_TLV_HDR_SIZE + config->channel_count * 4268 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4269 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4270 WMI_TLV_HDR_SIZE + active_state_count * 4271 sizeof(wmi_dcc_ndl_active_state_config) + 4272 WMI_TLV_HDR_SIZE + config->schedule_size * 4273 sizeof(wmi_ocb_schedule_element); 4274 buf = wmi_buf_alloc(wmi_handle, len); 4275 if (!buf) { 4276 WMI_LOGE(FL("wmi_buf_alloc failed")); 4277 return QDF_STATUS_E_NOMEM; 4278 } 4279 4280 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4281 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4282 WMITLV_SET_HDR(&cmd->tlv_header, 4283 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4284 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4285 cmd->vdev_id = config->vdev_id; 4286 cmd->channel_count = config->channel_count; 4287 cmd->schedule_size = config->schedule_size; 4288 cmd->flags = config->flags; 4289 buf_ptr += sizeof(*cmd); 4290 4291 /* Add the wmi_channel info */ 4292 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4293 config->channel_count*sizeof(wmi_channel)); 4294 buf_ptr += WMI_TLV_HDR_SIZE; 4295 for (i = 0; i < config->channel_count; i++) { 4296 chan = (wmi_channel *)buf_ptr; 4297 WMITLV_SET_HDR(&chan->tlv_header, 4298 WMITLV_TAG_STRUC_wmi_channel, 4299 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4300 chan->mhz = config->channels[i].chan_freq; 4301 chan->band_center_freq1 = config->channels[i].chan_freq; 4302 chan->band_center_freq2 = 0; 4303 chan->info = 0; 4304 4305 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4306 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4307 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4308 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4309 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4310 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4311 config->channels[i].antenna_max); 4312 4313 if (config->channels[i].bandwidth < 10) 4314 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4315 else if (config->channels[i].bandwidth < 20) 4316 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4317 buf_ptr += sizeof(*chan); 4318 } 4319 4320 /* Add the wmi_ocb_channel info */ 4321 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4322 config->channel_count*sizeof(wmi_ocb_channel)); 4323 buf_ptr += WMI_TLV_HDR_SIZE; 4324 for (i = 0; i < config->channel_count; i++) { 4325 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4326 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4327 WMITLV_TAG_STRUC_wmi_ocb_channel, 4328 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4329 ocb_chan->bandwidth = config->channels[i].bandwidth; 4330 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4331 config->channels[i].mac_address.bytes, 4332 &ocb_chan->mac_address); 4333 buf_ptr += sizeof(*ocb_chan); 4334 } 4335 4336 /* Add the wmi_qos_parameter info */ 4337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4338 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4339 buf_ptr += WMI_TLV_HDR_SIZE; 4340 /* WMI_MAX_NUM_AC parameters for each channel */ 4341 for (i = 0; i < config->channel_count; i++) { 4342 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4343 qos_param = (wmi_qos_parameter *)buf_ptr; 4344 WMITLV_SET_HDR(&qos_param->tlv_header, 4345 WMITLV_TAG_STRUC_wmi_qos_parameter, 4346 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4347 qos_param->aifsn = 4348 config->channels[i].qos_params[j].aifsn; 4349 qos_param->cwmin = 4350 config->channels[i].qos_params[j].cwmin; 4351 qos_param->cwmax = 4352 config->channels[i].qos_params[j].cwmax; 4353 buf_ptr += sizeof(*qos_param); 4354 } 4355 } 4356 4357 /* Add the wmi_dcc_ndl_chan (per channel) */ 4358 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4359 config->dcc_ndl_chan_list_len); 4360 buf_ptr += WMI_TLV_HDR_SIZE; 4361 if (config->dcc_ndl_chan_list_len) { 4362 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4363 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4364 config->dcc_ndl_chan_list_len); 4365 for (i = 0; i < config->channel_count; i++) 4366 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4367 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4368 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4369 buf_ptr += config->dcc_ndl_chan_list_len; 4370 } 4371 4372 /* Add the wmi_dcc_ndl_active_state_config */ 4373 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4374 sizeof(wmi_dcc_ndl_active_state_config)); 4375 buf_ptr += WMI_TLV_HDR_SIZE; 4376 if (active_state_count) { 4377 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4378 qdf_mem_copy(ndl_active_config, 4379 config->dcc_ndl_active_state_list, 4380 active_state_count * sizeof(*ndl_active_config)); 4381 for (i = 0; i < active_state_count; ++i) 4382 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4383 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4384 WMITLV_GET_STRUCT_TLVLEN( 4385 wmi_dcc_ndl_active_state_config)); 4386 buf_ptr += active_state_count * 4387 sizeof(*ndl_active_config); 4388 } 4389 4390 /* Add the wmi_ocb_schedule_element info */ 4391 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4392 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4393 buf_ptr += WMI_TLV_HDR_SIZE; 4394 for (i = 0; i < config->schedule_size; i++) { 4395 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4396 WMITLV_SET_HDR(&sched_elem->tlv_header, 4397 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4398 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4399 sched_elem->channel_freq = config->schedule[i].chan_freq; 4400 sched_elem->total_duration = config->schedule[i].total_duration; 4401 sched_elem->guard_interval = config->schedule[i].guard_interval; 4402 buf_ptr += sizeof(*sched_elem); 4403 } 4404 4405 4406 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4407 WMI_OCB_SET_CONFIG_CMDID); 4408 if (QDF_IS_STATUS_ERROR(ret)) { 4409 WMI_LOGE("Failed to set OCB config"); 4410 wmi_buf_free(buf); 4411 } 4412 4413 return ret; 4414 } 4415 4416 /** 4417 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4418 * @wmi_handle: wmi handle 4419 * @evt_buf: wmi event buffer 4420 * @status: status buffer 4421 * 4422 * Return: QDF_STATUS_SUCCESS on success 4423 */ 4424 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4425 void *evt_buf, 4426 uint32_t *status) 4427 { 4428 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4429 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4430 4431 param_tlvs = evt_buf; 4432 fix_param = param_tlvs->fixed_param; 4433 4434 *status = fix_param->status; 4435 return QDF_STATUS_SUCCESS; 4436 } 4437 4438 /** 4439 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4440 * @wmi_handle: wmi handle 4441 * @evt_buf: wmi event buffer 4442 * @resp: response buffer 4443 * 4444 * Return: QDF_STATUS_SUCCESS on success 4445 */ 4446 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4447 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4448 { 4449 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4450 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4451 4452 param_tlvs = evt_buf; 4453 fix_param = param_tlvs->fixed_param; 4454 resp->vdev_id = fix_param->vdev_id; 4455 resp->timer_high = fix_param->tsf_timer_high; 4456 resp->timer_low = fix_param->tsf_timer_low; 4457 4458 return QDF_STATUS_SUCCESS; 4459 } 4460 4461 /** 4462 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4463 * @wmi_handle: wmi handle 4464 * @evt_buf: wmi event buffer 4465 * @resp: response buffer 4466 * 4467 * Return: QDF_STATUS_SUCCESS on success 4468 */ 4469 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4470 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4471 { 4472 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4473 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4474 4475 param_tlvs = evt_buf; 4476 fix_param = param_tlvs->fixed_param; 4477 resp->vdev_id = fix_param->vdev_id; 4478 resp->status = fix_param->status; 4479 return QDF_STATUS_SUCCESS; 4480 } 4481 4482 /** 4483 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4484 * @wmi_handle: wmi handle 4485 * @evt_buf: wmi event buffer 4486 * @resp: response buffer 4487 * 4488 * Since length of stats is variable, buffer for DCC stats will be allocated 4489 * in this function. The caller must free the buffer. 4490 * 4491 * Return: QDF_STATUS_SUCCESS on success 4492 */ 4493 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4494 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4495 { 4496 struct ocb_dcc_get_stats_response *response; 4497 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4498 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4499 4500 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4501 fix_param = param_tlvs->fixed_param; 4502 4503 /* Allocate and populate the response */ 4504 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4505 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4506 WMI_LOGE("%s: too many channels:%d", __func__, 4507 fix_param->num_channels); 4508 QDF_ASSERT(0); 4509 *resp = NULL; 4510 return QDF_STATUS_E_INVAL; 4511 } 4512 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4513 sizeof(wmi_dcc_ndl_stats_per_channel)); 4514 *resp = response; 4515 if (!response) 4516 return QDF_STATUS_E_NOMEM; 4517 4518 response->vdev_id = fix_param->vdev_id; 4519 response->num_channels = fix_param->num_channels; 4520 response->channel_stats_array_len = 4521 fix_param->num_channels * 4522 sizeof(wmi_dcc_ndl_stats_per_channel); 4523 response->channel_stats_array = ((uint8_t *)response) + 4524 sizeof(*response); 4525 qdf_mem_copy(response->channel_stats_array, 4526 param_tlvs->stats_per_channel_list, 4527 response->channel_stats_array_len); 4528 4529 return QDF_STATUS_SUCCESS; 4530 } 4531 #endif 4532 4533 /** 4534 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4535 * @wmi_handle: wmi handle 4536 * @mcc_adaptive_scheduler: enable/disable 4537 * 4538 * This function enable/disable mcc adaptive scheduler in fw. 4539 * 4540 * Return: QDF_STATUS_SUCCESS for success or error code 4541 */ 4542 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4543 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4544 uint32_t pdev_id) 4545 { 4546 QDF_STATUS ret; 4547 wmi_buf_t buf = 0; 4548 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4549 uint16_t len = 4550 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4551 4552 buf = wmi_buf_alloc(wmi_handle, len); 4553 if (!buf) { 4554 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4555 return QDF_STATUS_E_NOMEM; 4556 } 4557 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4558 wmi_buf_data(buf); 4559 4560 WMITLV_SET_HDR(&cmd->tlv_header, 4561 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4562 WMITLV_GET_STRUCT_TLVLEN 4563 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4564 cmd->enable = mcc_adaptive_scheduler; 4565 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4566 4567 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4568 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4569 if (QDF_IS_STATUS_ERROR(ret)) { 4570 WMI_LOGP("%s: Failed to send enable/disable MCC" 4571 " adaptive scheduler command", __func__); 4572 wmi_buf_free(buf); 4573 } 4574 4575 return ret; 4576 } 4577 4578 /** 4579 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4580 * @wmi: wmi handle 4581 * @mcc_channel: mcc channel 4582 * @mcc_channel_time_latency: MCC channel time latency. 4583 * 4584 * Currently used to set time latency for an MCC vdev/adapter using operating 4585 * channel of it and channel number. The info is provided run time using 4586 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4587 * 4588 * Return: CDF status 4589 */ 4590 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4591 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4592 { 4593 QDF_STATUS ret; 4594 wmi_buf_t buf = 0; 4595 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4596 uint16_t len = 0; 4597 uint8_t *buf_ptr = NULL; 4598 wmi_resmgr_chan_latency chan_latency; 4599 /* Note: we only support MCC time latency for a single channel */ 4600 uint32_t num_channels = 1; 4601 uint32_t chan1_freq = mcc_channel_freq; 4602 uint32_t latency_chan1 = mcc_channel_time_latency; 4603 4604 4605 /* If 0ms latency is provided, then FW will set to a default. 4606 * Otherwise, latency must be at least 30ms. 4607 */ 4608 if ((latency_chan1 > 0) && 4609 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4610 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4611 "Minimum is 30ms (or 0 to use default value by " 4612 "firmware)", __func__, latency_chan1); 4613 return QDF_STATUS_E_INVAL; 4614 } 4615 4616 /* Set WMI CMD for channel time latency here */ 4617 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4618 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4619 num_channels * sizeof(wmi_resmgr_chan_latency); 4620 buf = wmi_buf_alloc(wmi_handle, len); 4621 if (!buf) { 4622 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4623 return QDF_STATUS_E_NOMEM; 4624 } 4625 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4626 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4627 wmi_buf_data(buf); 4628 WMITLV_SET_HDR(&cmdTL->tlv_header, 4629 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4630 WMITLV_GET_STRUCT_TLVLEN 4631 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4632 cmdTL->num_chans = num_channels; 4633 /* Update channel time latency information for home channel(s) */ 4634 buf_ptr += sizeof(*cmdTL); 4635 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4636 num_channels * sizeof(wmi_resmgr_chan_latency)); 4637 buf_ptr += WMI_TLV_HDR_SIZE; 4638 chan_latency.chan_mhz = chan1_freq; 4639 chan_latency.latency = latency_chan1; 4640 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4641 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4642 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4643 if (QDF_IS_STATUS_ERROR(ret)) { 4644 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4645 __func__); 4646 wmi_buf_free(buf); 4647 QDF_ASSERT(0); 4648 } 4649 4650 return ret; 4651 } 4652 4653 /** 4654 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4655 * @wmi: wmi handle 4656 * @adapter_1_chan_number: adapter 1 channel number 4657 * @adapter_1_quota: adapter 1 quota 4658 * @adapter_2_chan_number: adapter 2 channel number 4659 * 4660 * Return: CDF status 4661 */ 4662 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4663 uint32_t adapter_1_chan_freq, 4664 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4665 { 4666 QDF_STATUS ret; 4667 wmi_buf_t buf = 0; 4668 uint16_t len = 0; 4669 uint8_t *buf_ptr = NULL; 4670 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4671 wmi_resmgr_chan_time_quota chan_quota; 4672 uint32_t quota_chan1 = adapter_1_quota; 4673 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4674 uint32_t quota_chan2 = 100 - quota_chan1; 4675 /* Note: setting time quota for MCC requires info for 2 channels */ 4676 uint32_t num_channels = 2; 4677 uint32_t chan1_freq = adapter_1_chan_freq; 4678 uint32_t chan2_freq = adapter_2_chan_freq; 4679 4680 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4681 "freq2:%dMHz, Quota2:%dms", __func__, 4682 chan1_freq, quota_chan1, chan2_freq, 4683 quota_chan2); 4684 4685 /* 4686 * Perform sanity check on time quota values provided. 4687 */ 4688 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4689 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4690 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4691 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4692 return QDF_STATUS_E_INVAL; 4693 } 4694 /* Set WMI CMD for channel time quota here */ 4695 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4696 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4697 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4698 buf = wmi_buf_alloc(wmi_handle, len); 4699 if (!buf) { 4700 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4701 QDF_ASSERT(0); 4702 return QDF_STATUS_E_NOMEM; 4703 } 4704 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4705 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4706 wmi_buf_data(buf); 4707 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4708 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4709 WMITLV_GET_STRUCT_TLVLEN 4710 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4711 cmdTQ->num_chans = num_channels; 4712 4713 /* Update channel time quota information for home channel(s) */ 4714 buf_ptr += sizeof(*cmdTQ); 4715 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4716 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4717 buf_ptr += WMI_TLV_HDR_SIZE; 4718 chan_quota.chan_mhz = chan1_freq; 4719 chan_quota.channel_time_quota = quota_chan1; 4720 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4721 /* Construct channel and quota record for the 2nd MCC mode. */ 4722 buf_ptr += sizeof(chan_quota); 4723 chan_quota.chan_mhz = chan2_freq; 4724 chan_quota.channel_time_quota = quota_chan2; 4725 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4726 4727 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4728 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4729 if (QDF_IS_STATUS_ERROR(ret)) { 4730 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4731 wmi_buf_free(buf); 4732 QDF_ASSERT(0); 4733 } 4734 4735 return ret; 4736 } 4737 4738 /** 4739 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4740 * @wmi_handle: Pointer to wmi handle 4741 * @thermal_info: Thermal command information 4742 * 4743 * This function sends the thermal management command 4744 * to the firmware 4745 * 4746 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4747 */ 4748 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4749 struct thermal_cmd_params *thermal_info) 4750 { 4751 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4752 wmi_buf_t buf = NULL; 4753 QDF_STATUS status; 4754 uint32_t len = 0; 4755 4756 len = sizeof(*cmd); 4757 4758 buf = wmi_buf_alloc(wmi_handle, len); 4759 if (!buf) { 4760 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4761 return QDF_STATUS_E_FAILURE; 4762 } 4763 4764 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4765 4766 WMITLV_SET_HDR(&cmd->tlv_header, 4767 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4768 WMITLV_GET_STRUCT_TLVLEN 4769 (wmi_thermal_mgmt_cmd_fixed_param)); 4770 4771 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4772 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4773 cmd->enable = thermal_info->thermal_enable; 4774 4775 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4776 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4777 4778 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4779 WMI_THERMAL_MGMT_CMDID); 4780 if (QDF_IS_STATUS_ERROR(status)) { 4781 wmi_buf_free(buf); 4782 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4783 } 4784 4785 return status; 4786 } 4787 4788 4789 /** 4790 * send_lro_config_cmd_tlv() - process the LRO config command 4791 * @wmi_handle: Pointer to WMI handle 4792 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4793 * 4794 * This function sends down the LRO configuration parameters to 4795 * the firmware to enable LRO, sets the TCP flags and sets the 4796 * seed values for the toeplitz hash generation 4797 * 4798 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4799 */ 4800 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4801 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4802 { 4803 wmi_lro_info_cmd_fixed_param *cmd; 4804 wmi_buf_t buf; 4805 QDF_STATUS status; 4806 4807 4808 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4809 if (!buf) { 4810 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 4814 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4815 4816 WMITLV_SET_HDR(&cmd->tlv_header, 4817 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4818 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4819 4820 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4821 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4822 wmi_lro_cmd->tcp_flag); 4823 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4824 wmi_lro_cmd->tcp_flag_mask); 4825 cmd->toeplitz_hash_ipv4_0_3 = 4826 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4827 cmd->toeplitz_hash_ipv4_4_7 = 4828 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4829 cmd->toeplitz_hash_ipv4_8_11 = 4830 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4831 cmd->toeplitz_hash_ipv4_12_15 = 4832 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4833 cmd->toeplitz_hash_ipv4_16 = 4834 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4835 4836 cmd->toeplitz_hash_ipv6_0_3 = 4837 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4838 cmd->toeplitz_hash_ipv6_4_7 = 4839 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4840 cmd->toeplitz_hash_ipv6_8_11 = 4841 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4842 cmd->toeplitz_hash_ipv6_12_15 = 4843 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4844 cmd->toeplitz_hash_ipv6_16_19 = 4845 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4846 cmd->toeplitz_hash_ipv6_20_23 = 4847 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4848 cmd->toeplitz_hash_ipv6_24_27 = 4849 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4850 cmd->toeplitz_hash_ipv6_28_31 = 4851 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4852 cmd->toeplitz_hash_ipv6_32_35 = 4853 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4854 cmd->toeplitz_hash_ipv6_36_39 = 4855 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4856 cmd->toeplitz_hash_ipv6_40 = 4857 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4858 4859 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 4860 cmd->lro_enable, cmd->tcp_flag_u32); 4861 4862 status = wmi_unified_cmd_send(wmi_handle, buf, 4863 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4864 if (QDF_IS_STATUS_ERROR(status)) { 4865 wmi_buf_free(buf); 4866 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4867 } 4868 4869 return status; 4870 } 4871 4872 /** 4873 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4874 * @wmi_handle: Pointer to wmi handle 4875 * @rate_report_params: Pointer to peer rate report parameters 4876 * 4877 * 4878 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4879 */ 4880 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4881 struct wmi_peer_rate_report_params *rate_report_params) 4882 { 4883 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4884 wmi_buf_t buf = NULL; 4885 QDF_STATUS status = 0; 4886 uint32_t len = 0; 4887 uint32_t i, j; 4888 4889 len = sizeof(*cmd); 4890 4891 buf = wmi_buf_alloc(wmi_handle, len); 4892 if (!buf) { 4893 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 4894 return QDF_STATUS_E_FAILURE; 4895 } 4896 4897 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4898 wmi_buf_data(buf); 4899 4900 WMITLV_SET_HDR( 4901 &cmd->tlv_header, 4902 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4903 WMITLV_GET_STRUCT_TLVLEN( 4904 wmi_peer_set_rate_report_condition_fixed_param)); 4905 4906 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4907 cmd->report_backoff_time = rate_report_params->backoff_time; 4908 cmd->report_timer_period = rate_report_params->timer_period; 4909 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4910 cmd->cond_per_phy[i].val_cond_flags = 4911 rate_report_params->report_per_phy[i].cond_flags; 4912 cmd->cond_per_phy[i].rate_delta.min_delta = 4913 rate_report_params->report_per_phy[i].delta.delta_min; 4914 cmd->cond_per_phy[i].rate_delta.percentage = 4915 rate_report_params->report_per_phy[i].delta.percent; 4916 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4917 cmd->cond_per_phy[i].rate_threshold[j] = 4918 rate_report_params->report_per_phy[i]. 4919 report_rate_threshold[j]; 4920 } 4921 } 4922 4923 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 4924 cmd->enable_rate_report, 4925 cmd->report_backoff_time, cmd->report_timer_period); 4926 4927 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4928 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4929 if (QDF_IS_STATUS_ERROR(status)) { 4930 wmi_buf_free(buf); 4931 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4932 __func__); 4933 } 4934 return status; 4935 } 4936 4937 /** 4938 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 4939 * @wmi_handle: wmi handle 4940 * @param: bcn ll cmd parameter 4941 * 4942 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4943 */ 4944 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 4945 wmi_bcn_send_from_host_cmd_fixed_param *param) 4946 { 4947 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 4948 wmi_buf_t wmi_buf; 4949 QDF_STATUS ret; 4950 4951 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4952 if (!wmi_buf) { 4953 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 4954 return QDF_STATUS_E_FAILURE; 4955 } 4956 4957 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4958 WMITLV_SET_HDR(&cmd->tlv_header, 4959 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 4960 WMITLV_GET_STRUCT_TLVLEN 4961 (wmi_bcn_send_from_host_cmd_fixed_param)); 4962 cmd->vdev_id = param->vdev_id; 4963 cmd->data_len = param->data_len; 4964 cmd->frame_ctrl = param->frame_ctrl; 4965 cmd->frag_ptr = param->frag_ptr; 4966 cmd->dtim_flag = param->dtim_flag; 4967 4968 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 4969 WMI_PDEV_SEND_BCN_CMDID); 4970 4971 if (QDF_IS_STATUS_ERROR(ret)) { 4972 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 4973 wmi_buf_free(wmi_buf); 4974 } 4975 4976 return ret; 4977 } 4978 4979 /** 4980 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 4981 * @wmi_handle: wmi handle 4982 * @vdev_id: vdev id 4983 * @max_retries: max retries 4984 * @retry_interval: retry interval 4985 * This function sets sta query related parameters in fw. 4986 * 4987 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4988 */ 4989 4990 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 4991 uint8_t vdev_id, uint32_t max_retries, 4992 uint32_t retry_interval) 4993 { 4994 wmi_buf_t buf; 4995 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 4996 int len; 4997 4998 len = sizeof(*cmd); 4999 buf = wmi_buf_alloc(wmi_handle, len); 5000 if (!buf) { 5001 WMI_LOGE(FL("wmi_buf_alloc failed")); 5002 return QDF_STATUS_E_FAILURE; 5003 } 5004 5005 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5006 WMITLV_SET_HDR(&cmd->tlv_header, 5007 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5008 WMITLV_GET_STRUCT_TLVLEN 5009 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5010 5011 5012 cmd->vdev_id = vdev_id; 5013 cmd->sa_query_max_retry_count = max_retries; 5014 cmd->sa_query_retry_interval = retry_interval; 5015 5016 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5017 vdev_id, retry_interval, max_retries); 5018 5019 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5020 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5021 WMI_LOGE(FL("Failed to offload STA SA Query")); 5022 wmi_buf_free(buf); 5023 return QDF_STATUS_E_FAILURE; 5024 } 5025 5026 WMI_LOGD(FL("Exit :")); 5027 return 0; 5028 } 5029 5030 /** 5031 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5032 * @wmi_handle: wmi handle 5033 * @params: sta keep alive parameter 5034 * 5035 * This function sets keep alive related parameters in fw. 5036 * 5037 * Return: CDF status 5038 */ 5039 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5040 struct sta_params *params) 5041 { 5042 wmi_buf_t buf; 5043 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5044 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5045 uint8_t *buf_ptr; 5046 int len; 5047 QDF_STATUS ret; 5048 5049 WMI_LOGD("%s: Enter", __func__); 5050 5051 len = sizeof(*cmd) + sizeof(*arp_rsp); 5052 buf = wmi_buf_alloc(wmi_handle, len); 5053 if (!buf) { 5054 WMI_LOGE("wmi_buf_alloc failed"); 5055 return QDF_STATUS_E_FAILURE; 5056 } 5057 5058 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5059 buf_ptr = (uint8_t *) cmd; 5060 WMITLV_SET_HDR(&cmd->tlv_header, 5061 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5062 WMITLV_GET_STRUCT_TLVLEN 5063 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5064 cmd->interval = params->timeperiod; 5065 cmd->enable = (params->timeperiod) ? 1 : 0; 5066 cmd->vdev_id = params->vdev_id; 5067 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5068 params->timeperiod, params->method); 5069 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5070 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5071 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5072 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5073 5074 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5075 (params->method == 5076 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5077 if ((NULL == params->hostv4addr) || 5078 (NULL == params->destv4addr) || 5079 (NULL == params->destmac)) { 5080 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5081 "destv4addr:%pK destmac:%pK ", __func__, 5082 params->hostv4addr, params->destv4addr, params->destmac); 5083 wmi_buf_free(buf); 5084 return QDF_STATUS_E_FAILURE; 5085 } 5086 cmd->method = params->method; 5087 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5088 WMI_IPV4_ADDR_LEN); 5089 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5090 WMI_IPV4_ADDR_LEN); 5091 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5092 } else { 5093 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5094 } 5095 5096 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5097 WMI_STA_KEEPALIVE_CMDID); 5098 if (QDF_IS_STATUS_ERROR(ret)) { 5099 WMI_LOGE("Failed to set KeepAlive"); 5100 wmi_buf_free(buf); 5101 } 5102 5103 WMI_LOGD("%s: Exit", __func__); 5104 return ret; 5105 } 5106 5107 /** 5108 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5109 * @wmi_handle: wmi handle 5110 * @if_id: vdev id 5111 * @gtx_info: GTX config params 5112 * 5113 * This function set GTX related params in firmware. 5114 * 5115 * Return: QDF_STATUS_SUCCESS for success or error code 5116 */ 5117 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5118 struct wmi_gtx_config *gtx_info) 5119 { 5120 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5121 wmi_buf_t buf; 5122 QDF_STATUS ret; 5123 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5124 5125 buf = wmi_buf_alloc(wmi_handle, len); 5126 if (!buf) { 5127 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5128 return QDF_STATUS_E_NOMEM; 5129 } 5130 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5131 WMITLV_SET_HDR(&cmd->tlv_header, 5132 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5133 WMITLV_GET_STRUCT_TLVLEN 5134 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5135 cmd->vdev_id = if_id; 5136 5137 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5138 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5139 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5140 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5141 cmd->gtxPERMargin = gtx_info->gtx_margin; 5142 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5143 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5144 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5145 5146 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5147 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5148 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5149 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5150 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5151 5152 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5153 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5154 if (QDF_IS_STATUS_ERROR(ret)) { 5155 WMI_LOGE("Failed to set GTX PARAMS"); 5156 wmi_buf_free(buf); 5157 } 5158 return ret; 5159 } 5160 5161 /** 5162 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5163 * @wmi_handle: wmi handle 5164 * @vdev_id: vdev id. 5165 * @wmm_vparams: edca parameters 5166 * 5167 * This function updates EDCA parameters to the target 5168 * 5169 * Return: CDF Status 5170 */ 5171 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5172 uint8_t vdev_id, bool mu_edca_param, 5173 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5174 { 5175 uint8_t *buf_ptr; 5176 wmi_buf_t buf; 5177 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5178 wmi_wmm_vparams *wmm_param; 5179 struct wmi_host_wme_vparams *twmm_param; 5180 int len = sizeof(*cmd); 5181 int ac; 5182 5183 buf = wmi_buf_alloc(wmi_handle, len); 5184 5185 if (!buf) { 5186 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5187 return QDF_STATUS_E_NOMEM; 5188 } 5189 5190 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5191 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5192 WMITLV_SET_HDR(&cmd->tlv_header, 5193 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5194 WMITLV_GET_STRUCT_TLVLEN 5195 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5196 cmd->vdev_id = vdev_id; 5197 cmd->wmm_param_type = mu_edca_param; 5198 5199 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5200 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5201 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5202 WMITLV_SET_HDR(&wmm_param->tlv_header, 5203 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5204 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5205 wmm_param->cwmin = twmm_param->cwmin; 5206 wmm_param->cwmax = twmm_param->cwmax; 5207 wmm_param->aifs = twmm_param->aifs; 5208 if (mu_edca_param) 5209 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5210 else 5211 wmm_param->txoplimit = twmm_param->txoplimit; 5212 wmm_param->acm = twmm_param->acm; 5213 wmm_param->no_ack = twmm_param->noackpolicy; 5214 } 5215 5216 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5217 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5218 goto fail; 5219 5220 return QDF_STATUS_SUCCESS; 5221 5222 fail: 5223 wmi_buf_free(buf); 5224 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5225 return QDF_STATUS_E_FAILURE; 5226 } 5227 5228 /** 5229 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5230 * @wmi_handle: wmi handle 5231 * @vdev_id: vdev id 5232 * @probe_rsp_info: probe response info 5233 * 5234 * Return: QDF_STATUS_SUCCESS for success or error code 5235 */ 5236 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5237 uint8_t vdev_id, 5238 struct wmi_probe_resp_params *probe_rsp_info) 5239 { 5240 wmi_prb_tmpl_cmd_fixed_param *cmd; 5241 wmi_bcn_prb_info *bcn_prb_info; 5242 wmi_buf_t wmi_buf; 5243 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5244 uint8_t *buf_ptr; 5245 QDF_STATUS ret; 5246 5247 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5248 5249 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5250 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5251 5252 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5253 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5254 tmpl_len_aligned; 5255 5256 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5257 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5258 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5259 return QDF_STATUS_E_INVAL; 5260 } 5261 5262 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5263 if (!wmi_buf) { 5264 WMI_LOGE(FL("wmi_buf_alloc failed")); 5265 return QDF_STATUS_E_NOMEM; 5266 } 5267 5268 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5269 5270 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5271 WMITLV_SET_HDR(&cmd->tlv_header, 5272 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5273 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5274 cmd->vdev_id = vdev_id; 5275 cmd->buf_len = tmpl_len; 5276 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5277 5278 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5279 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5280 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5281 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5282 bcn_prb_info->caps = 0; 5283 bcn_prb_info->erp = 0; 5284 buf_ptr += sizeof(wmi_bcn_prb_info); 5285 5286 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5287 buf_ptr += WMI_TLV_HDR_SIZE; 5288 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5289 5290 ret = wmi_unified_cmd_send(wmi_handle, 5291 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5292 if (QDF_IS_STATUS_ERROR(ret)) { 5293 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5294 wmi_buf_free(wmi_buf); 5295 } 5296 5297 return ret; 5298 } 5299 5300 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5301 #define WPI_IV_LEN 16 5302 5303 /** 5304 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5305 * 5306 * @dest_tx: destination address of tsc key counter 5307 * @src_tx: source address of tsc key counter 5308 * @dest_rx: destination address of rsc key counter 5309 * @src_rx: source address of rsc key counter 5310 * 5311 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5312 * 5313 * Return: None 5314 * 5315 */ 5316 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5317 uint8_t *dest_rx, uint8_t *src_rx) 5318 { 5319 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5320 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5321 } 5322 #else 5323 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5324 uint8_t *dest_rx, uint8_t *src_rx) 5325 { 5326 return; 5327 } 5328 #endif 5329 5330 /** 5331 * send_setup_install_key_cmd_tlv() - set key parameters 5332 * @wmi_handle: wmi handle 5333 * @key_params: key parameters 5334 * 5335 * This function fills structure from information 5336 * passed in key_params. 5337 * 5338 * Return: QDF_STATUS_SUCCESS - success 5339 * QDF_STATUS_E_FAILURE - failure 5340 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5341 */ 5342 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5343 struct set_key_params *key_params) 5344 { 5345 wmi_vdev_install_key_cmd_fixed_param *cmd; 5346 wmi_buf_t buf; 5347 uint8_t *buf_ptr; 5348 uint32_t len; 5349 uint8_t *key_data; 5350 QDF_STATUS status; 5351 5352 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5353 WMI_TLV_HDR_SIZE; 5354 5355 buf = wmi_buf_alloc(wmi_handle, len); 5356 if (!buf) { 5357 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5358 return QDF_STATUS_E_NOMEM; 5359 } 5360 5361 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5362 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5363 WMITLV_SET_HDR(&cmd->tlv_header, 5364 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5365 WMITLV_GET_STRUCT_TLVLEN 5366 (wmi_vdev_install_key_cmd_fixed_param)); 5367 cmd->vdev_id = key_params->vdev_id; 5368 cmd->key_ix = key_params->key_idx; 5369 5370 5371 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5372 cmd->key_flags |= key_params->key_flags; 5373 cmd->key_cipher = key_params->key_cipher; 5374 if ((key_params->key_txmic_len) && 5375 (key_params->key_rxmic_len)) { 5376 cmd->key_txmic_len = key_params->key_txmic_len; 5377 cmd->key_rxmic_len = key_params->key_rxmic_len; 5378 } 5379 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5380 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5381 key_params->tx_iv, 5382 cmd->wpi_key_rsc_counter, 5383 key_params->rx_iv); 5384 #endif 5385 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5386 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5387 roundup(key_params->key_len, sizeof(uint32_t))); 5388 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5389 qdf_mem_copy((void *)key_data, 5390 (const void *)key_params->key_data, key_params->key_len); 5391 if (key_params->key_rsc_counter) 5392 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5393 sizeof(wmi_key_seq_counter)); 5394 cmd->key_len = key_params->key_len; 5395 5396 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5397 WMI_VDEV_INSTALL_KEY_CMDID); 5398 if (QDF_IS_STATUS_ERROR(status)) 5399 wmi_buf_free(buf); 5400 5401 return status; 5402 } 5403 5404 /** 5405 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5406 * @wmi_handle: wmi handle 5407 * @params: sar limit params 5408 * 5409 * Return: QDF_STATUS_SUCCESS for success or error code 5410 */ 5411 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5412 struct sar_limit_cmd_params *sar_limit_params) 5413 { 5414 wmi_buf_t buf; 5415 QDF_STATUS qdf_status; 5416 wmi_sar_limits_cmd_fixed_param *cmd; 5417 int i; 5418 uint8_t *buf_ptr; 5419 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5420 struct sar_limit_cmd_row *sar_rows_list; 5421 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5422 5423 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5424 buf = wmi_buf_alloc(wmi_handle, len); 5425 if (!buf) { 5426 WMI_LOGE("Failed to allocate memory"); 5427 qdf_status = QDF_STATUS_E_NOMEM; 5428 goto end; 5429 } 5430 5431 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5432 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5433 WMITLV_SET_HDR(&cmd->tlv_header, 5434 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5435 WMITLV_GET_STRUCT_TLVLEN 5436 (wmi_sar_limits_cmd_fixed_param)); 5437 cmd->sar_enable = sar_limit_params->sar_enable; 5438 cmd->commit_limits = sar_limit_params->commit_limits; 5439 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5440 5441 WMI_LOGD("no of sar rows = %d, len = %d", 5442 sar_limit_params->num_limit_rows, len); 5443 buf_ptr += sizeof(*cmd); 5444 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5445 sizeof(wmi_sar_limit_cmd_row) * 5446 sar_limit_params->num_limit_rows); 5447 if (cmd->num_limit_rows == 0) 5448 goto send_sar_limits; 5449 5450 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5451 (buf_ptr + WMI_TLV_HDR_SIZE); 5452 sar_rows_list = sar_limit_params->sar_limit_row_list; 5453 5454 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5455 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5456 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5457 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5458 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5459 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5460 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5461 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5462 wmi_sar_rows_list->validity_bitmap = 5463 sar_rows_list->validity_bitmap; 5464 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5465 i, wmi_sar_rows_list->band_id, 5466 wmi_sar_rows_list->chain_id, 5467 wmi_sar_rows_list->mod_id, 5468 wmi_sar_rows_list->limit_value, 5469 wmi_sar_rows_list->validity_bitmap); 5470 sar_rows_list++; 5471 wmi_sar_rows_list++; 5472 } 5473 send_sar_limits: 5474 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5475 WMI_SAR_LIMITS_CMDID); 5476 5477 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5478 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5479 wmi_buf_free(buf); 5480 } 5481 5482 end: 5483 return qdf_status; 5484 } 5485 5486 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5487 { 5488 wmi_sar_get_limits_cmd_fixed_param *cmd; 5489 wmi_buf_t wmi_buf; 5490 uint32_t len; 5491 QDF_STATUS status; 5492 5493 WMI_LOGD(FL("Enter")); 5494 5495 len = sizeof(*cmd); 5496 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5497 if (!wmi_buf) { 5498 WMI_LOGP(FL("failed to allocate memory for msg")); 5499 return QDF_STATUS_E_NOMEM; 5500 } 5501 5502 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5503 5504 WMITLV_SET_HDR(&cmd->tlv_header, 5505 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5506 WMITLV_GET_STRUCT_TLVLEN 5507 (wmi_sar_get_limits_cmd_fixed_param)); 5508 5509 cmd->reserved = 0; 5510 5511 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5512 WMI_SAR_GET_LIMITS_CMDID); 5513 if (QDF_IS_STATUS_ERROR(status)) { 5514 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5515 wmi_buf_free(wmi_buf); 5516 } 5517 5518 WMI_LOGD(FL("Exit")); 5519 5520 return status; 5521 } 5522 5523 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5524 uint8_t *evt_buf, 5525 struct sar_limit_event *event) 5526 { 5527 wmi_sar_get_limits_event_fixed_param *fixed_param; 5528 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5529 wmi_sar_get_limit_event_row *row_in; 5530 struct sar_limit_event_row *row_out; 5531 uint32_t row; 5532 5533 if (!evt_buf) { 5534 WMI_LOGE(FL("input event is NULL")); 5535 return QDF_STATUS_E_INVAL; 5536 } 5537 if (!event) { 5538 WMI_LOGE(FL("output event is NULL")); 5539 return QDF_STATUS_E_INVAL; 5540 } 5541 5542 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5543 5544 fixed_param = param_buf->fixed_param; 5545 if (!fixed_param) { 5546 WMI_LOGE(FL("Invalid fixed param")); 5547 return QDF_STATUS_E_INVAL; 5548 } 5549 5550 event->sar_enable = fixed_param->sar_enable; 5551 event->num_limit_rows = fixed_param->num_limit_rows; 5552 5553 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5554 QDF_ASSERT(0); 5555 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5556 event->num_limit_rows, 5557 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5558 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5559 } 5560 5561 row_in = param_buf->sar_get_limits; 5562 row_out = &event->sar_limit_row[0]; 5563 for (row = 0; row < event->num_limit_rows; row++) { 5564 row_out->band_id = row_in->band_id; 5565 row_out->chain_id = row_in->chain_id; 5566 row_out->mod_id = row_in->mod_id; 5567 row_out->limit_value = row_in->limit_value; 5568 row_out++; 5569 row_in++; 5570 } 5571 5572 return QDF_STATUS_SUCCESS; 5573 } 5574 5575 #ifdef WLAN_FEATURE_DISA 5576 /** 5577 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5578 * @wmi_handle: wmi handle 5579 * @params: encrypt/decrypt params 5580 * 5581 * Return: QDF_STATUS_SUCCESS for success or error code 5582 */ 5583 static 5584 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5585 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5586 { 5587 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5588 wmi_buf_t wmi_buf; 5589 uint8_t *buf_ptr; 5590 QDF_STATUS ret; 5591 uint32_t len; 5592 5593 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5594 5595 len = sizeof(*cmd) + 5596 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5597 WMI_TLV_HDR_SIZE; 5598 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5599 if (!wmi_buf) { 5600 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5601 __func__); 5602 return QDF_STATUS_E_NOMEM; 5603 } 5604 5605 buf_ptr = wmi_buf_data(wmi_buf); 5606 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5607 5608 WMITLV_SET_HDR(&cmd->tlv_header, 5609 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5610 WMITLV_GET_STRUCT_TLVLEN( 5611 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5612 5613 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5614 cmd->key_flag = encrypt_decrypt_params->key_flag; 5615 cmd->key_idx = encrypt_decrypt_params->key_idx; 5616 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5617 cmd->key_len = encrypt_decrypt_params->key_len; 5618 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5619 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5620 5621 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5622 encrypt_decrypt_params->key_len); 5623 5624 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5625 MAX_MAC_HEADER_LEN); 5626 5627 cmd->data_len = encrypt_decrypt_params->data_len; 5628 5629 if (cmd->data_len) { 5630 buf_ptr += sizeof(*cmd); 5631 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5632 roundup(encrypt_decrypt_params->data_len, 5633 sizeof(uint32_t))); 5634 buf_ptr += WMI_TLV_HDR_SIZE; 5635 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5636 encrypt_decrypt_params->data_len); 5637 } 5638 5639 /* This conversion is to facilitate data to FW in little endian */ 5640 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5641 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5642 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5643 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5644 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5645 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5646 5647 ret = wmi_unified_cmd_send(wmi_handle, 5648 wmi_buf, len, 5649 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5650 if (QDF_IS_STATUS_ERROR(ret)) { 5651 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5652 wmi_buf_free(wmi_buf); 5653 } 5654 5655 return ret; 5656 } 5657 5658 /** 5659 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5660 * params from event 5661 * @wmi_handle: wmi handle 5662 * @evt_buf: pointer to event buffer 5663 * @resp: Pointer to hold resp parameters 5664 * 5665 * Return: QDF_STATUS_SUCCESS for success or error code 5666 */ 5667 static 5668 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5669 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5670 { 5671 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5672 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5673 5674 param_buf = evt_buf; 5675 if (!param_buf) { 5676 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5677 return QDF_STATUS_E_INVAL; 5678 } 5679 5680 data_event = param_buf->fixed_param; 5681 5682 resp->vdev_id = data_event->vdev_id; 5683 resp->status = data_event->status; 5684 5685 if (data_event->data_length > param_buf->num_enc80211_frame) { 5686 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5687 data_event->data_length, 5688 param_buf->num_enc80211_frame); 5689 return QDF_STATUS_E_INVAL; 5690 } 5691 5692 resp->data_len = data_event->data_length; 5693 5694 if (resp->data_len) 5695 resp->data = (uint8_t *)param_buf->enc80211_frame; 5696 5697 return QDF_STATUS_SUCCESS; 5698 } 5699 #endif 5700 5701 /** 5702 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5703 * @wmi_handle: wmi handle 5704 * @vdev_id: vdev id 5705 * @p2p_ie: p2p IE 5706 * 5707 * Return: QDF_STATUS_SUCCESS for success or error code 5708 */ 5709 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5710 uint32_t vdev_id, uint8_t *p2p_ie) 5711 { 5712 QDF_STATUS ret; 5713 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5714 wmi_buf_t wmi_buf; 5715 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5716 uint8_t *buf_ptr; 5717 5718 ie_len = (uint32_t) (p2p_ie[1] + 2); 5719 5720 /* More than one P2P IE may be included in a single frame. 5721 If multiple P2P IEs are present, the complete P2P attribute 5722 data consists of the concatenation of the P2P Attribute 5723 fields of the P2P IEs. The P2P Attributes field of each 5724 P2P IE may be any length up to the maximum (251 octets). 5725 In this case host sends one P2P IE to firmware so the length 5726 should not exceed more than 251 bytes 5727 */ 5728 if (ie_len > 251) { 5729 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5730 return QDF_STATUS_E_INVAL; 5731 } 5732 5733 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5734 5735 wmi_buf_len = 5736 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5737 WMI_TLV_HDR_SIZE; 5738 5739 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5740 if (!wmi_buf) { 5741 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5742 return QDF_STATUS_E_NOMEM; 5743 } 5744 5745 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5746 5747 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5748 WMITLV_SET_HDR(&cmd->tlv_header, 5749 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5750 WMITLV_GET_STRUCT_TLVLEN 5751 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5752 cmd->vdev_id = vdev_id; 5753 cmd->ie_buf_len = ie_len; 5754 5755 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5757 buf_ptr += WMI_TLV_HDR_SIZE; 5758 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5759 5760 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 5761 5762 ret = wmi_unified_cmd_send(wmi_handle, 5763 wmi_buf, wmi_buf_len, 5764 WMI_P2P_GO_SET_BEACON_IE); 5765 if (QDF_IS_STATUS_ERROR(ret)) { 5766 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 5767 wmi_buf_free(wmi_buf); 5768 } 5769 5770 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 5771 return ret; 5772 } 5773 5774 /** 5775 * send_set_gateway_params_cmd_tlv() - set gateway parameters 5776 * @wmi_handle: wmi handle 5777 * @req: gateway parameter update request structure 5778 * 5779 * This function reads the incoming @req and fill in the destination 5780 * WMI structure and sends down the gateway configs down to the firmware 5781 * 5782 * Return: QDF_STATUS 5783 */ 5784 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 5785 struct gateway_update_req_param *req) 5786 { 5787 wmi_roam_subnet_change_config_fixed_param *cmd; 5788 wmi_buf_t buf; 5789 QDF_STATUS ret; 5790 int len = sizeof(*cmd); 5791 5792 buf = wmi_buf_alloc(wmi_handle, len); 5793 if (!buf) { 5794 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5795 return QDF_STATUS_E_NOMEM; 5796 } 5797 5798 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 5799 WMITLV_SET_HDR(&cmd->tlv_header, 5800 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 5801 WMITLV_GET_STRUCT_TLVLEN( 5802 wmi_roam_subnet_change_config_fixed_param)); 5803 5804 cmd->vdev_id = req->session_id; 5805 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 5806 QDF_IPV4_ADDR_SIZE); 5807 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 5808 QDF_IPV6_ADDR_SIZE); 5809 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 5810 &cmd->inet_gw_mac_addr); 5811 cmd->max_retries = req->max_retries; 5812 cmd->timeout = req->timeout; 5813 cmd->num_skip_subnet_change_detection_bssid_list = 0; 5814 cmd->flag = 0; 5815 if (req->ipv4_addr_type) 5816 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 5817 5818 if (req->ipv6_addr_type) 5819 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 5820 5821 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5822 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 5823 if (QDF_IS_STATUS_ERROR(ret)) { 5824 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 5825 ret); 5826 wmi_buf_free(buf); 5827 } 5828 5829 return ret; 5830 } 5831 5832 /** 5833 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 5834 * @wmi_handle: wmi handle 5835 * @req: rssi monitoring request structure 5836 * 5837 * This function reads the incoming @req and fill in the destination 5838 * WMI structure and send down the rssi monitoring configs down to the firmware 5839 * 5840 * Return: 0 on success; error number otherwise 5841 */ 5842 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 5843 struct rssi_monitor_param *req) 5844 { 5845 wmi_rssi_breach_monitor_config_fixed_param *cmd; 5846 wmi_buf_t buf; 5847 QDF_STATUS ret; 5848 uint32_t len = sizeof(*cmd); 5849 5850 buf = wmi_buf_alloc(wmi_handle, len); 5851 if (!buf) { 5852 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 5853 return QDF_STATUS_E_NOMEM; 5854 } 5855 5856 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 5857 WMITLV_SET_HDR(&cmd->tlv_header, 5858 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 5859 WMITLV_GET_STRUCT_TLVLEN( 5860 wmi_rssi_breach_monitor_config_fixed_param)); 5861 5862 cmd->vdev_id = req->session_id; 5863 cmd->request_id = req->request_id; 5864 cmd->lo_rssi_reenable_hysteresis = 0; 5865 cmd->hi_rssi_reenable_histeresis = 0; 5866 cmd->min_report_interval = 0; 5867 cmd->max_num_report = 1; 5868 if (req->control) { 5869 /* enable one threshold for each min/max */ 5870 cmd->enabled_bitmap = 0x09; 5871 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 5872 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 5873 } else { 5874 cmd->enabled_bitmap = 0; 5875 cmd->low_rssi_breach_threshold[0] = 0; 5876 cmd->hi_rssi_breach_threshold[0] = 0; 5877 } 5878 5879 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5880 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 5881 if (QDF_IS_STATUS_ERROR(ret)) { 5882 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 5883 wmi_buf_free(buf); 5884 } 5885 5886 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 5887 5888 return ret; 5889 } 5890 5891 /** 5892 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5893 * @wmi_handle: wmi handle 5894 * @psetoui: OUI parameters 5895 * 5896 * set scan probe OUI parameters in firmware 5897 * 5898 * Return: CDF status 5899 */ 5900 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5901 struct scan_mac_oui *psetoui) 5902 { 5903 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5904 wmi_buf_t wmi_buf; 5905 uint32_t len; 5906 uint8_t *buf_ptr; 5907 uint32_t *oui_buf; 5908 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 5909 5910 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5911 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 5912 5913 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5914 if (!wmi_buf) { 5915 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5916 return QDF_STATUS_E_NOMEM; 5917 } 5918 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5919 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5920 WMITLV_SET_HDR(&cmd->tlv_header, 5921 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5922 WMITLV_GET_STRUCT_TLVLEN 5923 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5924 5925 oui_buf = &cmd->prob_req_oui; 5926 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5927 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5928 | psetoui->oui[2]; 5929 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 5930 cmd->prob_req_oui); 5931 5932 cmd->vdev_id = psetoui->vdev_id; 5933 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5934 if (psetoui->enb_probe_req_sno_randomization) 5935 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5936 5937 if (ie_whitelist->white_list) { 5938 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5939 &cmd->num_vendor_oui, 5940 ie_whitelist); 5941 cmd->flags |= 5942 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5943 } 5944 5945 buf_ptr += sizeof(*cmd); 5946 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5947 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5948 buf_ptr += WMI_TLV_HDR_SIZE; 5949 5950 if (cmd->num_vendor_oui != 0) { 5951 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5952 ie_whitelist->voui); 5953 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5954 } 5955 5956 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5957 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5958 WMI_LOGE("%s: failed to send command", __func__); 5959 wmi_buf_free(wmi_buf); 5960 return QDF_STATUS_E_FAILURE; 5961 } 5962 return QDF_STATUS_SUCCESS; 5963 } 5964 5965 /** 5966 * send_reset_passpoint_network_list_cmd_tlv() - reset passpoint network list 5967 * @wmi_handle: wmi handle 5968 * @req: passpoint network request structure 5969 * 5970 * This function sends down WMI command with network id set to wildcard id. 5971 * firmware shall clear all the config entries 5972 * 5973 * Return: QDF_STATUS enumeration 5974 */ 5975 static QDF_STATUS send_reset_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 5976 struct wifi_passpoint_req_param *req) 5977 { 5978 wmi_passpoint_config_cmd_fixed_param *cmd; 5979 wmi_buf_t buf; 5980 uint32_t len; 5981 int ret; 5982 5983 len = sizeof(*cmd); 5984 buf = wmi_buf_alloc(wmi_handle, len); 5985 if (!buf) { 5986 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 5987 return QDF_STATUS_E_NOMEM; 5988 } 5989 5990 cmd = (wmi_passpoint_config_cmd_fixed_param *) wmi_buf_data(buf); 5991 5992 WMITLV_SET_HDR(&cmd->tlv_header, 5993 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 5994 WMITLV_GET_STRUCT_TLVLEN( 5995 wmi_passpoint_config_cmd_fixed_param)); 5996 cmd->id = WMI_PASSPOINT_NETWORK_ID_WILDCARD; 5997 5998 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5999 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6000 if (ret) { 6001 WMI_LOGE("%s: Failed to send reset passpoint network list wmi cmd", 6002 __func__); 6003 wmi_buf_free(buf); 6004 return QDF_STATUS_E_FAILURE; 6005 } 6006 6007 return QDF_STATUS_SUCCESS; 6008 } 6009 6010 /** 6011 * send_set_passpoint_network_list_cmd_tlv() - set passpoint network list 6012 * @wmi_handle: wmi handle 6013 * @req: passpoint network request structure 6014 * 6015 * This function reads the incoming @req and fill in the destination 6016 * WMI structure and send down the passpoint configs down to the firmware 6017 * 6018 * Return: QDF_STATUS enumeration 6019 */ 6020 static QDF_STATUS send_set_passpoint_network_list_cmd_tlv(wmi_unified_t wmi_handle, 6021 struct wifi_passpoint_req_param *req) 6022 { 6023 wmi_passpoint_config_cmd_fixed_param *cmd; 6024 u_int8_t i, j, *bytes; 6025 wmi_buf_t buf; 6026 uint32_t len; 6027 int ret; 6028 6029 len = sizeof(*cmd); 6030 for (i = 0; i < req->num_networks; i++) { 6031 buf = wmi_buf_alloc(wmi_handle, len); 6032 if (!buf) { 6033 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 6034 return QDF_STATUS_E_NOMEM; 6035 } 6036 6037 cmd = (wmi_passpoint_config_cmd_fixed_param *) 6038 wmi_buf_data(buf); 6039 6040 WMITLV_SET_HDR(&cmd->tlv_header, 6041 WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, 6042 WMITLV_GET_STRUCT_TLVLEN( 6043 wmi_passpoint_config_cmd_fixed_param)); 6044 cmd->id = req->networks[i].id; 6045 WMI_LOGD("%s: network id: %u", __func__, cmd->id); 6046 qdf_mem_copy(cmd->realm, req->networks[i].realm, 6047 strlen(req->networks[i].realm) + 1); 6048 WMI_LOGD("%s: realm: %s", __func__, cmd->realm); 6049 for (j = 0; j < PASSPOINT_ROAMING_CONSORTIUM_ID_NUM; j++) { 6050 bytes = (uint8_t *) &req->networks[i].roaming_consortium_ids[j]; 6051 WMI_LOGD("index: %d rcids: %02x %02x %02x %02x %02x %02x %02x %02x", 6052 j, bytes[0], bytes[1], bytes[2], bytes[3], 6053 bytes[4], bytes[5], bytes[6], bytes[7]); 6054 6055 qdf_mem_copy(&cmd->roaming_consortium_ids[j], 6056 &req->networks[i].roaming_consortium_ids[j], 6057 PASSPOINT_ROAMING_CONSORTIUM_ID_LEN); 6058 } 6059 qdf_mem_copy(cmd->plmn, req->networks[i].plmn, 6060 PASSPOINT_PLMN_ID_LEN); 6061 WMI_LOGD("%s: plmn: %02x:%02x:%02x", __func__, 6062 cmd->plmn[0], cmd->plmn[1], cmd->plmn[2]); 6063 6064 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6065 WMI_PASSPOINT_LIST_CONFIG_CMDID); 6066 if (ret) { 6067 WMI_LOGE("%s: Failed to send set passpoint network list wmi cmd", 6068 __func__); 6069 wmi_buf_free(buf); 6070 return QDF_STATUS_E_FAILURE; 6071 } 6072 } 6073 6074 return QDF_STATUS_SUCCESS; 6075 } 6076 6077 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6078 /** 6079 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6080 * @wmi_handle: wmi handle 6081 * @roam_req: Roam scan offload params 6082 * @buf_ptr: command buffer to send 6083 * @fils_tlv_len: fils tlv length 6084 * 6085 * Return: Updated buffer pointer 6086 */ 6087 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6088 struct roam_offload_scan_params *roam_req, 6089 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6090 { 6091 wmi_roam_fils_offload_tlv_param *fils_tlv; 6092 wmi_erp_info *erp_info; 6093 struct roam_fils_params *roam_fils_params; 6094 6095 if (!roam_req->add_fils_tlv) 6096 return buf_ptr; 6097 6098 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6099 sizeof(*fils_tlv)); 6100 buf_ptr += WMI_TLV_HDR_SIZE; 6101 6102 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6103 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6104 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6105 WMITLV_GET_STRUCT_TLVLEN 6106 (wmi_roam_fils_offload_tlv_param)); 6107 6108 roam_fils_params = &roam_req->roam_fils_params; 6109 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6110 6111 erp_info->username_length = roam_fils_params->username_length; 6112 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6113 erp_info->username_length); 6114 6115 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6116 6117 erp_info->rRk_length = roam_fils_params->rrk_length; 6118 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6119 erp_info->rRk_length); 6120 6121 erp_info->rIk_length = roam_fils_params->rik_length; 6122 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6123 erp_info->rIk_length); 6124 6125 erp_info->realm_len = roam_fils_params->realm_len; 6126 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6127 erp_info->realm_len); 6128 6129 buf_ptr += sizeof(*fils_tlv); 6130 return buf_ptr; 6131 } 6132 #else 6133 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6134 struct roam_offload_scan_params *roam_req, 6135 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6136 { 6137 return buf_ptr; 6138 } 6139 #endif 6140 /** 6141 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6142 * @wmi_handle: wmi handle 6143 * @scan_cmd_fp: start scan command ptr 6144 * @roam_req: roam request param 6145 * 6146 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6147 * of WMI_ROAM_SCAN_MODE. 6148 * 6149 * Return: QDF status 6150 */ 6151 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6152 wmi_start_scan_cmd_fixed_param * 6153 scan_cmd_fp, 6154 struct roam_offload_scan_params *roam_req) 6155 { 6156 wmi_buf_t buf = NULL; 6157 QDF_STATUS status; 6158 int len; 6159 uint8_t *buf_ptr; 6160 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6161 6162 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6163 int auth_mode = roam_req->auth_mode; 6164 wmi_roam_offload_tlv_param *roam_offload_params; 6165 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6166 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6167 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6168 wmi_tlv_buf_len_param *assoc_ies; 6169 uint32_t fils_tlv_len = 0; 6170 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6171 /* Need to create a buf with roam_scan command at 6172 * front and piggyback with scan command */ 6173 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6174 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6175 (2 * WMI_TLV_HDR_SIZE) + 6176 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6177 sizeof(wmi_start_scan_cmd_fixed_param); 6178 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6179 WMI_LOGD("auth_mode = %d", auth_mode); 6180 if (roam_req->is_roam_req_valid && 6181 roam_req->roam_offload_enabled) { 6182 len += sizeof(wmi_roam_offload_tlv_param); 6183 len += WMI_TLV_HDR_SIZE; 6184 if ((auth_mode != WMI_AUTH_NONE) && 6185 ((auth_mode != WMI_AUTH_OPEN) || 6186 (auth_mode == WMI_AUTH_OPEN && 6187 roam_req->mdid.mdie_present && 6188 roam_req->is_11r_assoc) || 6189 roam_req->is_ese_assoc)) { 6190 len += WMI_TLV_HDR_SIZE; 6191 if (roam_req->is_ese_assoc) 6192 len += 6193 sizeof(wmi_roam_ese_offload_tlv_param); 6194 else if (auth_mode == WMI_AUTH_FT_RSNA || 6195 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6196 (auth_mode == WMI_AUTH_OPEN && 6197 roam_req->mdid.mdie_present && 6198 roam_req->is_11r_assoc)) 6199 len += 6200 sizeof(wmi_roam_11r_offload_tlv_param); 6201 else 6202 len += 6203 sizeof(wmi_roam_11i_offload_tlv_param); 6204 } else { 6205 len += WMI_TLV_HDR_SIZE; 6206 } 6207 6208 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6209 + roundup(roam_req->assoc_ie_length, 6210 sizeof(uint32_t))); 6211 6212 if (roam_req->add_fils_tlv) { 6213 fils_tlv_len = sizeof( 6214 wmi_roam_fils_offload_tlv_param); 6215 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6216 } 6217 } else { 6218 if (roam_req->is_roam_req_valid) 6219 WMI_LOGD("%s : roam offload = %d", 6220 __func__, roam_req->roam_offload_enabled); 6221 else 6222 WMI_LOGD("%s : roam_req is NULL", __func__); 6223 len += (4 * WMI_TLV_HDR_SIZE); 6224 } 6225 if (roam_req->is_roam_req_valid && 6226 roam_req->roam_offload_enabled) { 6227 roam_req->mode = roam_req->mode | 6228 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6229 } 6230 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6231 6232 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6233 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6234 len = sizeof(wmi_roam_scan_mode_fixed_param); 6235 6236 buf = wmi_buf_alloc(wmi_handle, len); 6237 if (!buf) { 6238 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6239 return QDF_STATUS_E_NOMEM; 6240 } 6241 6242 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6243 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6244 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6245 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6246 WMITLV_GET_STRUCT_TLVLEN 6247 (wmi_roam_scan_mode_fixed_param)); 6248 6249 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6250 roam_req->roam_trigger_reason_bitmask; 6251 roam_scan_mode_fp->min_delay_btw_scans = 6252 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6253 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6254 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6255 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6256 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6257 roam_scan_mode_fp->flags |= 6258 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6259 goto send_roam_scan_mode_cmd; 6260 } 6261 6262 /* Fill in scan parameters suitable for roaming scan */ 6263 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6264 6265 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6266 sizeof(wmi_start_scan_cmd_fixed_param)); 6267 /* Ensure there is no additional IEs */ 6268 scan_cmd_fp->ie_len = 0; 6269 WMITLV_SET_HDR(buf_ptr, 6270 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6271 WMITLV_GET_STRUCT_TLVLEN 6272 (wmi_start_scan_cmd_fixed_param)); 6273 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6274 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6275 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6276 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6277 sizeof(wmi_roam_offload_tlv_param)); 6278 buf_ptr += WMI_TLV_HDR_SIZE; 6279 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6280 WMITLV_SET_HDR(buf_ptr, 6281 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6282 WMITLV_GET_STRUCT_TLVLEN 6283 (wmi_roam_offload_tlv_param)); 6284 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6285 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6286 roam_offload_params->select_5g_margin = 6287 roam_req->select_5ghz_margin; 6288 roam_offload_params->handoff_delay_for_rx = 6289 roam_req->roam_offload_params.ho_delay_for_rx; 6290 roam_offload_params->reassoc_failure_timeout = 6291 roam_req->reassoc_failure_timeout; 6292 6293 /* Fill the capabilities */ 6294 roam_offload_params->capability = 6295 roam_req->roam_offload_params.capability; 6296 roam_offload_params->ht_caps_info = 6297 roam_req->roam_offload_params.ht_caps_info; 6298 roam_offload_params->ampdu_param = 6299 roam_req->roam_offload_params.ampdu_param; 6300 roam_offload_params->ht_ext_cap = 6301 roam_req->roam_offload_params.ht_ext_cap; 6302 roam_offload_params->ht_txbf = 6303 roam_req->roam_offload_params.ht_txbf; 6304 roam_offload_params->asel_cap = 6305 roam_req->roam_offload_params.asel_cap; 6306 roam_offload_params->qos_caps = 6307 roam_req->roam_offload_params.qos_caps; 6308 roam_offload_params->qos_enabled = 6309 roam_req->roam_offload_params.qos_enabled; 6310 roam_offload_params->wmm_caps = 6311 roam_req->roam_offload_params.wmm_caps; 6312 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6313 (uint8_t *)roam_req->roam_offload_params.mcsset, 6314 ROAM_OFFLOAD_NUM_MCS_SET); 6315 6316 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6317 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6318 * they are filled in the same order.Depending on the 6319 * authentication type, the other mode TLV's are nullified 6320 * and only headers are filled.*/ 6321 if ((auth_mode != WMI_AUTH_NONE) && 6322 ((auth_mode != WMI_AUTH_OPEN) || 6323 (auth_mode == WMI_AUTH_OPEN 6324 && roam_req->mdid.mdie_present && 6325 roam_req->is_11r_assoc) || 6326 roam_req->is_ese_assoc)) { 6327 if (roam_req->is_ese_assoc) { 6328 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6329 WMITLV_GET_STRUCT_TLVLEN(0)); 6330 buf_ptr += WMI_TLV_HDR_SIZE; 6331 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6332 WMITLV_GET_STRUCT_TLVLEN(0)); 6333 buf_ptr += WMI_TLV_HDR_SIZE; 6334 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6335 sizeof(wmi_roam_ese_offload_tlv_param)); 6336 buf_ptr += WMI_TLV_HDR_SIZE; 6337 roam_offload_ese = 6338 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6339 qdf_mem_copy(roam_offload_ese->krk, 6340 roam_req->krk, 6341 sizeof(roam_req->krk)); 6342 qdf_mem_copy(roam_offload_ese->btk, 6343 roam_req->btk, 6344 sizeof(roam_req->btk)); 6345 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6346 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6347 WMITLV_GET_STRUCT_TLVLEN 6348 (wmi_roam_ese_offload_tlv_param)); 6349 buf_ptr += 6350 sizeof(wmi_roam_ese_offload_tlv_param); 6351 } else if (auth_mode == WMI_AUTH_FT_RSNA 6352 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6353 || (auth_mode == WMI_AUTH_OPEN 6354 && roam_req->mdid.mdie_present && 6355 roam_req->is_11r_assoc)) { 6356 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6357 0); 6358 buf_ptr += WMI_TLV_HDR_SIZE; 6359 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6360 sizeof(wmi_roam_11r_offload_tlv_param)); 6361 buf_ptr += WMI_TLV_HDR_SIZE; 6362 roam_offload_11r = 6363 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6364 roam_offload_11r->r0kh_id_len = 6365 roam_req->rokh_id_length; 6366 qdf_mem_copy(roam_offload_11r->r0kh_id, 6367 roam_req->rokh_id, 6368 roam_offload_11r->r0kh_id_len); 6369 qdf_mem_copy(roam_offload_11r->psk_msk, 6370 roam_req->psk_pmk, 6371 sizeof(roam_req->psk_pmk)); 6372 roam_offload_11r->psk_msk_len = 6373 roam_req->pmk_len; 6374 roam_offload_11r->mdie_present = 6375 roam_req->mdid.mdie_present; 6376 roam_offload_11r->mdid = 6377 roam_req->mdid.mobility_domain; 6378 if (auth_mode == WMI_AUTH_OPEN) { 6379 /* If FT-Open ensure pmk length 6380 and r0khid len are zero */ 6381 roam_offload_11r->r0kh_id_len = 0; 6382 roam_offload_11r->psk_msk_len = 0; 6383 } 6384 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6385 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6386 WMITLV_GET_STRUCT_TLVLEN 6387 (wmi_roam_11r_offload_tlv_param)); 6388 buf_ptr += 6389 sizeof(wmi_roam_11r_offload_tlv_param); 6390 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6391 WMITLV_GET_STRUCT_TLVLEN(0)); 6392 buf_ptr += WMI_TLV_HDR_SIZE; 6393 WMI_LOGD("psk_msk_len = %d", 6394 roam_offload_11r->psk_msk_len); 6395 if (roam_offload_11r->psk_msk_len) 6396 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6397 QDF_TRACE_LEVEL_DEBUG, 6398 roam_offload_11r->psk_msk, 6399 roam_offload_11r->psk_msk_len); 6400 } else { 6401 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6402 sizeof(wmi_roam_11i_offload_tlv_param)); 6403 buf_ptr += WMI_TLV_HDR_SIZE; 6404 roam_offload_11i = 6405 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6406 6407 if (roam_req->roam_key_mgmt_offload_enabled && 6408 roam_req->fw_okc) { 6409 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6410 (roam_offload_11i->flags); 6411 WMI_LOGI("LFR3:OKC enabled"); 6412 } else { 6413 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6414 (roam_offload_11i->flags); 6415 WMI_LOGI("LFR3:OKC disabled"); 6416 } 6417 if (roam_req->roam_key_mgmt_offload_enabled && 6418 roam_req->fw_pmksa_cache) { 6419 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6420 (roam_offload_11i->flags); 6421 WMI_LOGI("LFR3:PMKSA caching enabled"); 6422 } else { 6423 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6424 (roam_offload_11i->flags); 6425 WMI_LOGI("LFR3:PMKSA caching disabled"); 6426 } 6427 6428 qdf_mem_copy(roam_offload_11i->pmk, 6429 roam_req->psk_pmk, 6430 sizeof(roam_req->psk_pmk)); 6431 roam_offload_11i->pmk_len = roam_req->pmk_len; 6432 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6433 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6434 WMITLV_GET_STRUCT_TLVLEN 6435 (wmi_roam_11i_offload_tlv_param)); 6436 buf_ptr += 6437 sizeof(wmi_roam_11i_offload_tlv_param); 6438 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6439 0); 6440 buf_ptr += WMI_TLV_HDR_SIZE; 6441 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6442 0); 6443 buf_ptr += WMI_TLV_HDR_SIZE; 6444 WMI_LOGD("pmk_len = %d", 6445 roam_offload_11i->pmk_len); 6446 if (roam_offload_11i->pmk_len) 6447 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6448 QDF_TRACE_LEVEL_DEBUG, 6449 roam_offload_11i->pmk, 6450 roam_offload_11i->pmk_len); 6451 } 6452 } else { 6453 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6454 WMITLV_GET_STRUCT_TLVLEN(0)); 6455 buf_ptr += WMI_TLV_HDR_SIZE; 6456 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6457 WMITLV_GET_STRUCT_TLVLEN(0)); 6458 buf_ptr += WMI_TLV_HDR_SIZE; 6459 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6460 WMITLV_GET_STRUCT_TLVLEN(0)); 6461 buf_ptr += WMI_TLV_HDR_SIZE; 6462 } 6463 6464 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6465 sizeof(*assoc_ies)); 6466 buf_ptr += WMI_TLV_HDR_SIZE; 6467 6468 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6469 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6470 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6471 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6472 assoc_ies->buf_len = roam_req->assoc_ie_length; 6473 6474 buf_ptr += sizeof(*assoc_ies); 6475 6476 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6477 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6478 buf_ptr += WMI_TLV_HDR_SIZE; 6479 6480 if (assoc_ies->buf_len != 0) { 6481 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6482 assoc_ies->buf_len); 6483 } 6484 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6485 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6486 buf_ptr, fils_tlv_len); 6487 } else { 6488 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6489 WMITLV_GET_STRUCT_TLVLEN(0)); 6490 buf_ptr += WMI_TLV_HDR_SIZE; 6491 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6492 WMITLV_GET_STRUCT_TLVLEN(0)); 6493 buf_ptr += WMI_TLV_HDR_SIZE; 6494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6495 WMITLV_GET_STRUCT_TLVLEN(0)); 6496 buf_ptr += WMI_TLV_HDR_SIZE; 6497 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6498 WMITLV_GET_STRUCT_TLVLEN(0)); 6499 buf_ptr += WMI_TLV_HDR_SIZE; 6500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6501 WMITLV_GET_STRUCT_TLVLEN(0)); 6502 buf_ptr += WMI_TLV_HDR_SIZE; 6503 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6504 WMITLV_GET_STRUCT_TLVLEN(0)); 6505 } 6506 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6507 6508 send_roam_scan_mode_cmd: 6509 status = wmi_unified_cmd_send(wmi_handle, buf, 6510 len, WMI_ROAM_SCAN_MODE); 6511 if (QDF_IS_STATUS_ERROR(status)) { 6512 WMI_LOGE( 6513 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6514 status); 6515 wmi_buf_free(buf); 6516 } 6517 6518 return status; 6519 } 6520 6521 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6522 struct wmi_mawc_roam_params *params) 6523 { 6524 wmi_buf_t buf = NULL; 6525 QDF_STATUS status; 6526 int len; 6527 uint8_t *buf_ptr; 6528 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6529 6530 len = sizeof(*wmi_roam_mawc_params); 6531 buf = wmi_buf_alloc(wmi_handle, len); 6532 if (!buf) { 6533 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6534 return QDF_STATUS_E_NOMEM; 6535 } 6536 6537 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6538 wmi_roam_mawc_params = 6539 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6540 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6541 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6542 WMITLV_GET_STRUCT_TLVLEN 6543 (wmi_roam_configure_mawc_cmd_fixed_param)); 6544 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6545 if (params->enable) 6546 wmi_roam_mawc_params->enable = 1; 6547 else 6548 wmi_roam_mawc_params->enable = 0; 6549 wmi_roam_mawc_params->traffic_load_threshold = 6550 params->traffic_load_threshold; 6551 wmi_roam_mawc_params->best_ap_rssi_threshold = 6552 params->best_ap_rssi_threshold; 6553 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6554 params->rssi_stationary_high_adjust; 6555 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6556 params->rssi_stationary_low_adjust; 6557 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6558 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6559 wmi_roam_mawc_params->traffic_load_threshold, 6560 wmi_roam_mawc_params->best_ap_rssi_threshold, 6561 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6562 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6563 6564 status = wmi_unified_cmd_send(wmi_handle, buf, 6565 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6566 if (QDF_IS_STATUS_ERROR(status)) { 6567 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6568 status); 6569 wmi_buf_free(buf); 6570 return status; 6571 } 6572 6573 return QDF_STATUS_SUCCESS; 6574 } 6575 6576 /** 6577 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6578 * rssi threashold 6579 * @wmi_handle: wmi handle 6580 * @roam_req: Roaming request buffer 6581 * 6582 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6583 * 6584 * Return: QDF status 6585 */ 6586 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6587 struct roam_offload_scan_rssi_params *roam_req) 6588 { 6589 wmi_buf_t buf = NULL; 6590 QDF_STATUS status; 6591 int len; 6592 uint8_t *buf_ptr; 6593 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6594 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6595 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6596 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6597 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6598 6599 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6600 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6601 len += sizeof(wmi_roam_scan_extended_threshold_param); 6602 len += WMI_TLV_HDR_SIZE; 6603 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6604 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6605 len += sizeof(wmi_roam_dense_thres_param); 6606 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6607 len += sizeof(wmi_roam_bg_scan_roaming_param); 6608 buf = wmi_buf_alloc(wmi_handle, len); 6609 if (!buf) { 6610 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6611 return QDF_STATUS_E_NOMEM; 6612 } 6613 6614 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6615 rssi_threshold_fp = 6616 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6617 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6618 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6619 WMITLV_GET_STRUCT_TLVLEN 6620 (wmi_roam_scan_rssi_threshold_fixed_param)); 6621 /* fill in threshold values */ 6622 rssi_threshold_fp->vdev_id = roam_req->session_id; 6623 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6624 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6625 rssi_threshold_fp->hirssi_scan_max_count = 6626 roam_req->hi_rssi_scan_max_count; 6627 rssi_threshold_fp->hirssi_scan_delta = 6628 roam_req->hi_rssi_scan_rssi_delta; 6629 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6630 rssi_threshold_fp->rssi_thresh_offset_5g = 6631 roam_req->rssi_thresh_offset_5g; 6632 6633 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6634 WMITLV_SET_HDR(buf_ptr, 6635 WMITLV_TAG_ARRAY_STRUC, 6636 sizeof(wmi_roam_scan_extended_threshold_param)); 6637 buf_ptr += WMI_TLV_HDR_SIZE; 6638 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6639 6640 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6641 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6642 ext_thresholds->boost_threshold_5g = 6643 roam_req->boost_threshold_5g; 6644 6645 ext_thresholds->boost_algorithm_5g = 6646 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6647 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6648 ext_thresholds->penalty_algorithm_5g = 6649 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6650 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6651 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6652 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6653 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6654 6655 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6656 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6657 WMITLV_GET_STRUCT_TLVLEN 6658 (wmi_roam_scan_extended_threshold_param)); 6659 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6660 WMITLV_SET_HDR(buf_ptr, 6661 WMITLV_TAG_ARRAY_STRUC, 6662 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6663 buf_ptr += WMI_TLV_HDR_SIZE; 6664 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6665 early_stop_thresholds->roam_earlystop_thres_min = 6666 roam_req->roam_earlystop_thres_min; 6667 early_stop_thresholds->roam_earlystop_thres_max = 6668 roam_req->roam_earlystop_thres_max; 6669 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6670 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6671 WMITLV_GET_STRUCT_TLVLEN 6672 (wmi_roam_earlystop_rssi_thres_param)); 6673 6674 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6675 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6676 sizeof(wmi_roam_dense_thres_param)); 6677 buf_ptr += WMI_TLV_HDR_SIZE; 6678 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6679 dense_thresholds->roam_dense_rssi_thres_offset = 6680 roam_req->dense_rssi_thresh_offset; 6681 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6682 dense_thresholds->roam_dense_traffic_thres = 6683 roam_req->traffic_threshold; 6684 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6685 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6686 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6687 WMITLV_GET_STRUCT_TLVLEN 6688 (wmi_roam_dense_thres_param)); 6689 6690 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6692 sizeof(wmi_roam_bg_scan_roaming_param)); 6693 buf_ptr += WMI_TLV_HDR_SIZE; 6694 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6695 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6696 roam_req->bg_scan_bad_rssi_thresh; 6697 bg_scan_params->roam_bg_scan_client_bitmap = 6698 roam_req->bg_scan_client_bitmap; 6699 bg_scan_params->bad_rssi_thresh_offset_2g = 6700 roam_req->roam_bad_rssi_thresh_offset_2g; 6701 bg_scan_params->flags = roam_req->flags; 6702 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6703 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6704 WMITLV_GET_STRUCT_TLVLEN 6705 (wmi_roam_bg_scan_roaming_param)); 6706 6707 status = wmi_unified_cmd_send(wmi_handle, buf, 6708 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6709 if (QDF_IS_STATUS_ERROR(status)) { 6710 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6711 status); 6712 wmi_buf_free(buf); 6713 } 6714 6715 return status; 6716 } 6717 6718 /** 6719 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6720 * configuration params 6721 * @wma_handle: wma handler 6722 * @dwelltime_params: pointer to dwelltime_params 6723 * 6724 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6725 */ 6726 static 6727 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6728 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6729 { 6730 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6731 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6732 wmi_buf_t buf; 6733 uint8_t *buf_ptr; 6734 int32_t err; 6735 int len; 6736 6737 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6738 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6739 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6740 buf = wmi_buf_alloc(wmi_handle, len); 6741 if (!buf) { 6742 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6743 __func__); 6744 return QDF_STATUS_E_NOMEM; 6745 } 6746 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6747 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6748 WMITLV_SET_HDR(&dwell_param->tlv_header, 6749 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6750 WMITLV_GET_STRUCT_TLVLEN 6751 (wmi_scan_adaptive_dwell_config_fixed_param)); 6752 6753 dwell_param->enable = dwelltime_params->is_enabled; 6754 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6755 WMITLV_SET_HDR(buf_ptr, 6756 WMITLV_TAG_ARRAY_STRUC, 6757 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6758 buf_ptr += WMI_TLV_HDR_SIZE; 6759 6760 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6761 WMITLV_SET_HDR(&cmd->tlv_header, 6762 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6763 WMITLV_GET_STRUCT_TLVLEN( 6764 wmi_scan_adaptive_dwell_parameters_tlv)); 6765 6766 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6767 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6768 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6769 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6770 err = wmi_unified_cmd_send(wmi_handle, buf, 6771 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6772 if (err) { 6773 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6774 wmi_buf_free(buf); 6775 return QDF_STATUS_E_FAILURE; 6776 } 6777 6778 return QDF_STATUS_SUCCESS; 6779 } 6780 6781 /** 6782 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6783 * configuration params 6784 * @wmi_handle: wmi handler 6785 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6786 * 6787 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6788 */ 6789 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6790 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6791 { 6792 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6793 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6794 wmi_buf_t buf; 6795 uint8_t *buf_ptr; 6796 QDF_STATUS err; 6797 uint32_t i; 6798 int len; 6799 6800 len = sizeof(*dbs_scan_param); 6801 len += WMI_TLV_HDR_SIZE; 6802 len += dbs_scan_params->num_clients * sizeof(*cmd); 6803 6804 buf = wmi_buf_alloc(wmi_handle, len); 6805 if (!buf) { 6806 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6807 return QDF_STATUS_E_NOMEM; 6808 } 6809 6810 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6811 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6812 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6813 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6814 WMITLV_GET_STRUCT_TLVLEN 6815 (wmi_scan_dbs_duty_cycle_fixed_param)); 6816 6817 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6818 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6819 buf_ptr += sizeof(*dbs_scan_param); 6820 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6821 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6822 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6823 6824 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6825 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6826 WMITLV_SET_HDR(&cmd->tlv_header, 6827 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6828 WMITLV_GET_STRUCT_TLVLEN( 6829 wmi_scan_dbs_duty_cycle_tlv_param)); 6830 cmd->module_id = dbs_scan_params->module_id[i]; 6831 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6832 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6833 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6834 } 6835 6836 err = wmi_unified_cmd_send(wmi_handle, buf, 6837 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6838 if (QDF_IS_STATUS_ERROR(err)) { 6839 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6840 wmi_buf_free(buf); 6841 return QDF_STATUS_E_FAILURE; 6842 } 6843 6844 return QDF_STATUS_SUCCESS; 6845 } 6846 6847 /** 6848 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6849 * @wmi_handle: wmi handle 6850 * @roam_req: Request which contains the filters 6851 * 6852 * There are filters such as whitelist, blacklist and preferred 6853 * list that need to be applied to the scan results to form the 6854 * probable candidates for roaming. 6855 * 6856 * Return: Return success upon succesfully passing the 6857 * parameters to the firmware, otherwise failure. 6858 */ 6859 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6860 struct roam_scan_filter_params *roam_req) 6861 { 6862 wmi_buf_t buf = NULL; 6863 QDF_STATUS status; 6864 uint32_t i; 6865 uint32_t len, blist_len = 0; 6866 uint8_t *buf_ptr; 6867 wmi_roam_filter_fixed_param *roam_filter; 6868 uint8_t *bssid_src_ptr = NULL; 6869 wmi_mac_addr *bssid_dst_ptr = NULL; 6870 wmi_ssid *ssid_ptr = NULL; 6871 uint32_t *bssid_preferred_factor_ptr = NULL; 6872 wmi_roam_lca_disallow_config_tlv_param *blist_param; 6873 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 6874 6875 len = sizeof(wmi_roam_filter_fixed_param); 6876 6877 len += WMI_TLV_HDR_SIZE; 6878 if (roam_req->num_bssid_black_list) 6879 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 6880 len += WMI_TLV_HDR_SIZE; 6881 if (roam_req->num_ssid_white_list) 6882 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 6883 len += 2 * WMI_TLV_HDR_SIZE; 6884 if (roam_req->num_bssid_preferred_list) { 6885 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 6886 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 6887 } 6888 len += WMI_TLV_HDR_SIZE; 6889 if (roam_req->lca_disallow_config_present) { 6890 len += sizeof(*blist_param); 6891 blist_len = sizeof(*blist_param); 6892 } 6893 6894 len += WMI_TLV_HDR_SIZE; 6895 if (roam_req->num_rssi_rejection_ap) 6896 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 6897 6898 buf = wmi_buf_alloc(wmi_handle, len); 6899 if (!buf) { 6900 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6901 return QDF_STATUS_E_NOMEM; 6902 } 6903 6904 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 6905 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 6906 WMITLV_SET_HDR(&roam_filter->tlv_header, 6907 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 6908 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 6909 /* fill in fixed values */ 6910 roam_filter->vdev_id = roam_req->session_id; 6911 roam_filter->flags = 0; 6912 roam_filter->op_bitmap = roam_req->op_bitmap; 6913 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 6914 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 6915 roam_filter->num_bssid_preferred_list = 6916 roam_req->num_bssid_preferred_list; 6917 roam_filter->num_rssi_rejection_ap = 6918 roam_req->num_rssi_rejection_ap; 6919 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 6920 6921 WMITLV_SET_HDR((buf_ptr), 6922 WMITLV_TAG_ARRAY_FIXED_STRUC, 6923 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 6924 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 6925 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6926 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 6927 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 6928 bssid_src_ptr += ATH_MAC_LEN; 6929 bssid_dst_ptr++; 6930 } 6931 buf_ptr += WMI_TLV_HDR_SIZE + 6932 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 6933 WMITLV_SET_HDR((buf_ptr), 6934 WMITLV_TAG_ARRAY_FIXED_STRUC, 6935 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 6936 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 6937 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 6938 qdf_mem_copy(&ssid_ptr->ssid, 6939 &roam_req->ssid_allowed_list[i].mac_ssid, 6940 roam_req->ssid_allowed_list[i].length); 6941 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 6942 ssid_ptr++; 6943 } 6944 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 6945 sizeof(wmi_ssid)); 6946 WMITLV_SET_HDR((buf_ptr), 6947 WMITLV_TAG_ARRAY_FIXED_STRUC, 6948 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 6949 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 6950 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 6951 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6952 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 6953 (wmi_mac_addr *)bssid_dst_ptr); 6954 bssid_src_ptr += ATH_MAC_LEN; 6955 bssid_dst_ptr++; 6956 } 6957 buf_ptr += WMI_TLV_HDR_SIZE + 6958 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 6959 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6960 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 6961 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 6962 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 6963 *bssid_preferred_factor_ptr = 6964 roam_req->bssid_favored_factor[i]; 6965 bssid_preferred_factor_ptr++; 6966 } 6967 buf_ptr += WMI_TLV_HDR_SIZE + 6968 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 6969 6970 WMITLV_SET_HDR(buf_ptr, 6971 WMITLV_TAG_ARRAY_STRUC, blist_len); 6972 buf_ptr += WMI_TLV_HDR_SIZE; 6973 if (roam_req->lca_disallow_config_present) { 6974 blist_param = 6975 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 6976 WMITLV_SET_HDR(&blist_param->tlv_header, 6977 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 6978 WMITLV_GET_STRUCT_TLVLEN( 6979 wmi_roam_lca_disallow_config_tlv_param)); 6980 6981 blist_param->disallow_duration = roam_req->disallow_duration; 6982 blist_param->rssi_channel_penalization = 6983 roam_req->rssi_channel_penalization; 6984 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 6985 blist_param->disallow_lca_enable_source_bitmap = 6986 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 6987 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 6988 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 6989 } 6990 6991 WMITLV_SET_HDR(buf_ptr, 6992 WMITLV_TAG_ARRAY_STRUC, 6993 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 6994 buf_ptr += WMI_TLV_HDR_SIZE; 6995 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 6996 rssi_rej = 6997 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 6998 WMITLV_SET_HDR(&rssi_rej->tlv_header, 6999 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7000 WMITLV_GET_STRUCT_TLVLEN( 7001 wmi_roam_rssi_rejection_oce_config_param)); 7002 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7003 roam_req->rssi_rejection_ap[i].bssid.bytes, 7004 &rssi_rej->bssid); 7005 rssi_rej->remaining_disallow_duration = 7006 roam_req->rssi_rejection_ap[i].remaining_duration; 7007 rssi_rej->requested_rssi = 7008 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 7009 buf_ptr += 7010 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7011 } 7012 7013 status = wmi_unified_cmd_send(wmi_handle, buf, 7014 len, WMI_ROAM_FILTER_CMDID); 7015 if (QDF_IS_STATUS_ERROR(status)) { 7016 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7017 status); 7018 wmi_buf_free(buf); 7019 } 7020 7021 return status; 7022 } 7023 7024 #if defined(WLAN_FEATURE_FILS_SK) 7025 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7026 struct hlp_params *params) 7027 { 7028 uint32_t len; 7029 uint8_t *buf_ptr; 7030 wmi_buf_t buf = NULL; 7031 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7032 7033 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7034 len += WMI_TLV_HDR_SIZE; 7035 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7036 7037 buf = wmi_buf_alloc(wmi_handle, len); 7038 if (!buf) { 7039 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7040 return QDF_STATUS_E_NOMEM; 7041 } 7042 7043 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7044 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7045 WMITLV_SET_HDR(&hlp_params->tlv_header, 7046 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7047 WMITLV_GET_STRUCT_TLVLEN( 7048 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7049 7050 hlp_params->vdev_id = params->vdev_id; 7051 hlp_params->size = params->hlp_ie_len; 7052 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7053 7054 buf_ptr += sizeof(*hlp_params); 7055 7056 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7057 round_up(params->hlp_ie_len, 7058 sizeof(uint32_t))); 7059 buf_ptr += WMI_TLV_HDR_SIZE; 7060 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7061 7062 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7063 hlp_params->vdev_id, hlp_params->size); 7064 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7065 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7066 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7067 wmi_buf_free(buf); 7068 return QDF_STATUS_E_FAILURE; 7069 } 7070 7071 return QDF_STATUS_SUCCESS; 7072 } 7073 #endif 7074 7075 /** send_set_epno_network_list_cmd_tlv() - set epno network list 7076 * @wmi_handle: wmi handle 7077 * @req: epno config params request structure 7078 * 7079 * This function reads the incoming epno config request structure 7080 * and constructs the WMI message to the firmware. 7081 * 7082 * Returns: 0 on success, error number otherwise 7083 */ 7084 static QDF_STATUS send_set_epno_network_list_cmd_tlv(wmi_unified_t wmi_handle, 7085 struct wifi_enhanched_pno_params *req) 7086 { 7087 wmi_nlo_config_cmd_fixed_param *cmd; 7088 nlo_configured_parameters *nlo_list; 7089 enlo_candidate_score_params *cand_score_params; 7090 u_int8_t i, *buf_ptr; 7091 wmi_buf_t buf; 7092 uint32_t len; 7093 QDF_STATUS ret; 7094 7095 /* Fixed Params */ 7096 len = sizeof(*cmd); 7097 if (req->num_networks) { 7098 /* TLV place holder for array of structures 7099 * then each nlo_configured_parameters(nlo_list) TLV. 7100 */ 7101 len += WMI_TLV_HDR_SIZE; 7102 len += (sizeof(nlo_configured_parameters) 7103 * QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS)); 7104 /* TLV for array of uint32 channel_list */ 7105 len += WMI_TLV_HDR_SIZE; 7106 /* TLV for nlo_channel_prediction_cfg */ 7107 len += WMI_TLV_HDR_SIZE; 7108 /* TLV for candidate score params */ 7109 len += sizeof(enlo_candidate_score_params); 7110 } 7111 7112 buf = wmi_buf_alloc(wmi_handle, len); 7113 if (!buf) { 7114 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7115 return QDF_STATUS_E_NOMEM; 7116 } 7117 7118 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7119 7120 buf_ptr = (u_int8_t *) cmd; 7121 WMITLV_SET_HDR(&cmd->tlv_header, 7122 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7123 WMITLV_GET_STRUCT_TLVLEN( 7124 wmi_nlo_config_cmd_fixed_param)); 7125 cmd->vdev_id = req->session_id; 7126 7127 /* set flag to reset if num of networks are 0 */ 7128 cmd->flags = (req->num_networks == 0 ? 7129 WMI_NLO_CONFIG_ENLO_RESET : WMI_NLO_CONFIG_ENLO); 7130 7131 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7132 7133 cmd->no_of_ssids = QDF_MIN(req->num_networks, WMI_NLO_MAX_SSIDS); 7134 WMI_LOGD("SSID count: %d flags: %d", 7135 cmd->no_of_ssids, cmd->flags); 7136 7137 /* Fill nlo_config only when num_networks are non zero */ 7138 if (cmd->no_of_ssids) { 7139 /* Fill networks */ 7140 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7141 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7142 buf_ptr += WMI_TLV_HDR_SIZE; 7143 7144 nlo_list = (nlo_configured_parameters *) buf_ptr; 7145 for (i = 0; i < cmd->no_of_ssids; i++) { 7146 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7147 WMITLV_TAG_ARRAY_BYTE, 7148 WMITLV_GET_STRUCT_TLVLEN( 7149 nlo_configured_parameters)); 7150 /* Copy ssid and it's length */ 7151 nlo_list[i].ssid.valid = true; 7152 nlo_list[i].ssid.ssid.ssid_len = 7153 req->networks[i].ssid.length; 7154 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7155 req->networks[i].ssid.mac_ssid, 7156 nlo_list[i].ssid.ssid.ssid_len); 7157 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7158 nlo_list[i].ssid.ssid.ssid_len, 7159 (char *) nlo_list[i].ssid.ssid.ssid, 7160 nlo_list[i].ssid.ssid.ssid_len); 7161 7162 /* Copy pno flags */ 7163 nlo_list[i].bcast_nw_type.valid = true; 7164 nlo_list[i].bcast_nw_type.bcast_nw_type = 7165 req->networks[i].flags; 7166 WMI_LOGD("PNO flags (%u)", 7167 nlo_list[i].bcast_nw_type.bcast_nw_type); 7168 7169 /* Copy auth bit field */ 7170 nlo_list[i].auth_type.valid = true; 7171 nlo_list[i].auth_type.auth_type = 7172 req->networks[i].auth_bit_field; 7173 WMI_LOGD("Auth bit field (%u)", 7174 nlo_list[i].auth_type.auth_type); 7175 } 7176 7177 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7178 /* Fill the channel list */ 7179 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7180 buf_ptr += WMI_TLV_HDR_SIZE; 7181 7182 /* Fill prediction_param */ 7183 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7184 buf_ptr += WMI_TLV_HDR_SIZE; 7185 7186 /* Fill epno candidate score params */ 7187 cand_score_params = (enlo_candidate_score_params *) buf_ptr; 7188 WMITLV_SET_HDR(buf_ptr, 7189 WMITLV_TAG_STRUC_enlo_candidate_score_param, 7190 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7191 cand_score_params->min5GHz_rssi = 7192 req->min_5ghz_rssi; 7193 cand_score_params->min24GHz_rssi = 7194 req->min_24ghz_rssi; 7195 cand_score_params->initial_score_max = 7196 req->initial_score_max; 7197 cand_score_params->current_connection_bonus = 7198 req->current_connection_bonus; 7199 cand_score_params->same_network_bonus = 7200 req->same_network_bonus; 7201 cand_score_params->secure_bonus = 7202 req->secure_bonus; 7203 cand_score_params->band5GHz_bonus = 7204 req->band_5ghz_bonus; 7205 buf_ptr += sizeof(enlo_candidate_score_params); 7206 } 7207 7208 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7209 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7210 if (QDF_IS_STATUS_ERROR(ret)) { 7211 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7212 wmi_buf_free(buf); 7213 return QDF_STATUS_E_INVAL; 7214 } 7215 7216 WMI_LOGD("set ePNO list request sent successfully for vdev %d", 7217 req->session_id); 7218 7219 return ret; 7220 } 7221 7222 #ifdef IPA_OFFLOAD 7223 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7224 * @wmi_handle: wmi handle 7225 * @ipa_offload: ipa offload control parameter 7226 * 7227 * Returns: 0 on success, error number otherwise 7228 */ 7229 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7230 struct ipa_uc_offload_control_params *ipa_offload) 7231 { 7232 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7233 wmi_buf_t wmi_buf; 7234 uint32_t len; 7235 u_int8_t *buf_ptr; 7236 7237 len = sizeof(*cmd); 7238 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7239 if (!wmi_buf) { 7240 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7241 return QDF_STATUS_E_NOMEM; 7242 } 7243 7244 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7245 ipa_offload->offload_type, ipa_offload->enable); 7246 7247 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7248 7249 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7250 WMITLV_SET_HDR(&cmd->tlv_header, 7251 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7252 WMITLV_GET_STRUCT_TLVLEN( 7253 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7254 7255 cmd->offload_type = ipa_offload->offload_type; 7256 cmd->vdev_id = ipa_offload->vdev_id; 7257 cmd->enable = ipa_offload->enable; 7258 7259 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7260 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7261 WMI_LOGE("%s: failed to command", __func__); 7262 wmi_buf_free(wmi_buf); 7263 return QDF_STATUS_E_FAILURE; 7264 } 7265 7266 return QDF_STATUS_SUCCESS; 7267 } 7268 #endif 7269 7270 /** 7271 * send_extscan_get_capabilities_cmd_tlv() - extscan get capabilities 7272 * @wmi_handle: wmi handle 7273 * @pgetcapab: get capabilities params 7274 * 7275 * This function send request to fw to get extscan capabilities. 7276 * 7277 * Return: CDF status 7278 */ 7279 static QDF_STATUS send_extscan_get_capabilities_cmd_tlv(wmi_unified_t wmi_handle, 7280 struct extscan_capabilities_params *pgetcapab) 7281 { 7282 wmi_extscan_get_capabilities_cmd_fixed_param *cmd; 7283 wmi_buf_t wmi_buf; 7284 uint32_t len; 7285 uint8_t *buf_ptr; 7286 7287 len = sizeof(*cmd); 7288 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7289 if (!wmi_buf) { 7290 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7291 return QDF_STATUS_E_NOMEM; 7292 } 7293 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7294 7295 cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *) buf_ptr; 7296 WMITLV_SET_HDR(&cmd->tlv_header, 7297 WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, 7298 WMITLV_GET_STRUCT_TLVLEN 7299 (wmi_extscan_get_capabilities_cmd_fixed_param)); 7300 7301 cmd->request_id = pgetcapab->request_id; 7302 7303 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7304 WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) { 7305 WMI_LOGE("%s: failed to command", __func__); 7306 wmi_buf_free(wmi_buf); 7307 return QDF_STATUS_E_FAILURE; 7308 } 7309 return QDF_STATUS_SUCCESS; 7310 } 7311 7312 /** 7313 * send_extscan_get_cached_results_cmd_tlv() - extscan get cached results 7314 * @wmi_handle: wmi handle 7315 * @pcached_results: cached results parameters 7316 * 7317 * This function send request to fw to get cached results. 7318 * 7319 * Return: CDF status 7320 */ 7321 static QDF_STATUS send_extscan_get_cached_results_cmd_tlv(wmi_unified_t wmi_handle, 7322 struct extscan_cached_result_params *pcached_results) 7323 { 7324 wmi_extscan_get_cached_results_cmd_fixed_param *cmd; 7325 wmi_buf_t wmi_buf; 7326 uint32_t len; 7327 uint8_t *buf_ptr; 7328 7329 len = sizeof(*cmd); 7330 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7331 if (!wmi_buf) { 7332 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7333 return QDF_STATUS_E_NOMEM; 7334 } 7335 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7336 7337 cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *) buf_ptr; 7338 WMITLV_SET_HDR(&cmd->tlv_header, 7339 WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, 7340 WMITLV_GET_STRUCT_TLVLEN 7341 (wmi_extscan_get_cached_results_cmd_fixed_param)); 7342 7343 cmd->request_id = pcached_results->request_id; 7344 cmd->vdev_id = pcached_results->session_id; 7345 cmd->control_flags = pcached_results->flush; 7346 7347 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7348 WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) { 7349 WMI_LOGE("%s: failed to command", __func__); 7350 wmi_buf_free(wmi_buf); 7351 return QDF_STATUS_E_FAILURE; 7352 } 7353 return QDF_STATUS_SUCCESS; 7354 } 7355 7356 /** 7357 * send_extscan_stop_change_monitor_cmd_tlv() - send stop change monitor cmd 7358 * @wmi_handle: wmi handle 7359 * @reset_req: Reset change request params 7360 * 7361 * This function sends stop change monitor request to fw. 7362 * 7363 * Return: CDF status 7364 */ 7365 static QDF_STATUS send_extscan_stop_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7366 struct extscan_capabilities_reset_params *reset_req) 7367 { 7368 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7369 wmi_buf_t wmi_buf; 7370 uint32_t len; 7371 uint8_t *buf_ptr; 7372 int change_list = 0; 7373 7374 len = sizeof(*cmd); 7375 7376 /* reset significant change tlv is set to 0 */ 7377 len += WMI_TLV_HDR_SIZE; 7378 len += change_list * sizeof(wmi_extscan_wlan_change_bssid_param); 7379 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7380 if (!wmi_buf) { 7381 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7382 return QDF_STATUS_E_NOMEM; 7383 } 7384 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7385 7386 cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7387 buf_ptr; 7388 WMITLV_SET_HDR(&cmd->tlv_header, 7389 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7390 WMITLV_GET_STRUCT_TLVLEN 7391 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7392 7393 cmd->request_id = reset_req->request_id; 7394 cmd->vdev_id = reset_req->session_id; 7395 cmd->mode = 0; 7396 7397 buf_ptr += sizeof(*cmd); 7398 WMITLV_SET_HDR(buf_ptr, 7399 WMITLV_TAG_ARRAY_STRUC, 7400 change_list * 7401 sizeof(wmi_extscan_wlan_change_bssid_param)); 7402 buf_ptr += WMI_TLV_HDR_SIZE + (change_list * 7403 sizeof 7404 (wmi_extscan_wlan_change_bssid_param)); 7405 7406 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7407 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7408 WMI_LOGE("%s: failed to command", __func__); 7409 wmi_buf_free(wmi_buf); 7410 return QDF_STATUS_E_FAILURE; 7411 } 7412 return QDF_STATUS_SUCCESS; 7413 } 7414 7415 /** 7416 * wmi_get_buf_extscan_change_monitor_cmd() - fill change monitor request 7417 * @wmi_handle: wmi handle 7418 * @psigchange: change monitor request params 7419 * @buf: wmi buffer 7420 * @buf_len: buffer length 7421 * 7422 * This function fills elements of change monitor request buffer. 7423 * 7424 * Return: CDF status 7425 */ 7426 static QDF_STATUS wmi_get_buf_extscan_change_monitor_cmd(wmi_unified_t wmi_handle, 7427 struct extscan_set_sig_changereq_params 7428 *psigchange, wmi_buf_t *buf, int *buf_len) 7429 { 7430 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; 7431 wmi_extscan_wlan_change_bssid_param *dest_chglist; 7432 uint8_t *buf_ptr; 7433 int j; 7434 int len = sizeof(*cmd); 7435 uint32_t numap = psigchange->num_ap; 7436 struct ap_threshold_params *src_ap = psigchange->ap; 7437 7438 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) { 7439 WMI_LOGE("%s: Invalid number of bssid's", __func__); 7440 return QDF_STATUS_E_INVAL; 7441 } 7442 len += WMI_TLV_HDR_SIZE; 7443 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param); 7444 7445 *buf = wmi_buf_alloc(wmi_handle, len); 7446 if (!*buf) { 7447 WMI_LOGP("%s: failed to allocate memory for change monitor cmd", 7448 __func__); 7449 return QDF_STATUS_E_FAILURE; 7450 } 7451 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7452 cmd = 7453 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *) 7454 buf_ptr; 7455 WMITLV_SET_HDR(&cmd->tlv_header, 7456 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, 7457 WMITLV_GET_STRUCT_TLVLEN 7458 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); 7459 7460 cmd->request_id = psigchange->request_id; 7461 cmd->vdev_id = psigchange->session_id; 7462 cmd->total_entries = numap; 7463 cmd->mode = 1; 7464 cmd->num_entries_in_page = numap; 7465 cmd->lost_ap_scan_count = psigchange->lostap_sample_size; 7466 cmd->max_rssi_samples = psigchange->rssi_sample_size; 7467 cmd->rssi_averaging_samples = psigchange->rssi_sample_size; 7468 cmd->max_out_of_range_count = psigchange->min_breaching; 7469 7470 buf_ptr += sizeof(*cmd); 7471 WMITLV_SET_HDR(buf_ptr, 7472 WMITLV_TAG_ARRAY_STRUC, 7473 numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7474 dest_chglist = (wmi_extscan_wlan_change_bssid_param *) 7475 (buf_ptr + WMI_TLV_HDR_SIZE); 7476 7477 for (j = 0; j < numap; j++) { 7478 WMITLV_SET_HDR(dest_chglist, 7479 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7480 WMITLV_GET_STRUCT_TLVLEN 7481 (wmi_extscan_wlan_change_bssid_param)); 7482 7483 dest_chglist->lower_rssi_limit = src_ap->low; 7484 dest_chglist->upper_rssi_limit = src_ap->high; 7485 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 7486 &dest_chglist->bssid); 7487 7488 WMI_LOGD("%s: min_rssi %d", __func__, 7489 dest_chglist->lower_rssi_limit); 7490 dest_chglist++; 7491 src_ap++; 7492 } 7493 buf_ptr += WMI_TLV_HDR_SIZE + 7494 (numap * sizeof(wmi_extscan_wlan_change_bssid_param)); 7495 *buf_len = len; 7496 return QDF_STATUS_SUCCESS; 7497 } 7498 7499 /** 7500 * send_extscan_start_change_monitor_cmd_tlv() - send start change monitor cmd 7501 * @wmi_handle: wmi handle 7502 * @psigchange: change monitor request params 7503 * 7504 * This function sends start change monitor request to fw. 7505 * 7506 * Return: CDF status 7507 */ 7508 static QDF_STATUS send_extscan_start_change_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7509 struct extscan_set_sig_changereq_params * 7510 psigchange) 7511 { 7512 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7513 wmi_buf_t buf; 7514 int len; 7515 7516 7517 qdf_status = wmi_get_buf_extscan_change_monitor_cmd(wmi_handle, 7518 psigchange, &buf, 7519 &len); 7520 if (qdf_status != QDF_STATUS_SUCCESS) { 7521 WMI_LOGE("%s: Failed to get buffer for change monitor cmd", 7522 __func__); 7523 return QDF_STATUS_E_FAILURE; 7524 } 7525 if (!buf) { 7526 WMI_LOGE("%s: Failed to get buffer", __func__); 7527 return QDF_STATUS_E_FAILURE; 7528 } 7529 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7530 WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { 7531 WMI_LOGE("%s: failed to send command", __func__); 7532 wmi_buf_free(buf); 7533 return QDF_STATUS_E_FAILURE; 7534 } 7535 return QDF_STATUS_SUCCESS; 7536 } 7537 7538 /** 7539 * send_extscan_stop_hotlist_monitor_cmd_tlv() - stop hotlist monitor 7540 * @wmi_handle: wmi handle 7541 * @photlist_reset: hotlist reset params 7542 * 7543 * This function configures hotlist monitor to stop in fw. 7544 * 7545 * Return: CDF status 7546 */ 7547 static QDF_STATUS send_extscan_stop_hotlist_monitor_cmd_tlv(wmi_unified_t wmi_handle, 7548 struct extscan_bssid_hotlist_reset_params *photlist_reset) 7549 { 7550 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; 7551 wmi_buf_t wmi_buf; 7552 uint32_t len; 7553 uint8_t *buf_ptr; 7554 int hotlist_entries = 0; 7555 7556 len = sizeof(*cmd); 7557 7558 /* reset bssid hotlist with tlv set to 0 */ 7559 len += WMI_TLV_HDR_SIZE; 7560 len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry); 7561 7562 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7563 if (!wmi_buf) { 7564 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7565 return QDF_STATUS_E_NOMEM; 7566 } 7567 7568 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7569 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 7570 buf_ptr; 7571 WMITLV_SET_HDR(&cmd->tlv_header, 7572 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 7573 WMITLV_GET_STRUCT_TLVLEN 7574 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 7575 7576 cmd->request_id = photlist_reset->request_id; 7577 cmd->vdev_id = photlist_reset->session_id; 7578 cmd->mode = 0; 7579 7580 buf_ptr += sizeof(*cmd); 7581 WMITLV_SET_HDR(buf_ptr, 7582 WMITLV_TAG_ARRAY_STRUC, 7583 hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7584 buf_ptr += WMI_TLV_HDR_SIZE + 7585 (hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); 7586 7587 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7588 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 7589 WMI_LOGE("%s: failed to command", __func__); 7590 wmi_buf_free(wmi_buf); 7591 return QDF_STATUS_E_FAILURE; 7592 } 7593 return QDF_STATUS_SUCCESS; 7594 } 7595 7596 /** 7597 * send_stop_extscan_cmd_tlv() - stop extscan command to fw. 7598 * @wmi_handle: wmi handle 7599 * @pstopcmd: stop scan command request params 7600 * 7601 * This function sends stop extscan request to fw. 7602 * 7603 * Return: CDF Status. 7604 */ 7605 static QDF_STATUS send_stop_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7606 struct extscan_stop_req_params *pstopcmd) 7607 { 7608 wmi_extscan_stop_cmd_fixed_param *cmd; 7609 wmi_buf_t wmi_buf; 7610 uint32_t len; 7611 uint8_t *buf_ptr; 7612 7613 len = sizeof(*cmd); 7614 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7615 if (!wmi_buf) { 7616 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 7617 return QDF_STATUS_E_NOMEM; 7618 } 7619 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 7620 cmd = (wmi_extscan_stop_cmd_fixed_param *) buf_ptr; 7621 WMITLV_SET_HDR(&cmd->tlv_header, 7622 WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, 7623 WMITLV_GET_STRUCT_TLVLEN 7624 (wmi_extscan_stop_cmd_fixed_param)); 7625 7626 cmd->request_id = pstopcmd->request_id; 7627 cmd->vdev_id = pstopcmd->session_id; 7628 7629 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7630 WMI_EXTSCAN_STOP_CMDID)) { 7631 WMI_LOGE("%s: failed to command", __func__); 7632 wmi_buf_free(wmi_buf); 7633 return QDF_STATUS_E_FAILURE; 7634 } 7635 7636 return QDF_STATUS_SUCCESS; 7637 } 7638 7639 /** 7640 * wmi_get_buf_extscan_start_cmd() - Fill extscan start request 7641 * @wmi_handle: wmi handle 7642 * @pstart: scan command request params 7643 * @buf: event buffer 7644 * @buf_len: length of buffer 7645 * 7646 * This function fills individual elements of extscan request and 7647 * TLV for buckets, channel list. 7648 * 7649 * Return: CDF Status. 7650 */ 7651 static 7652 QDF_STATUS wmi_get_buf_extscan_start_cmd(wmi_unified_t wmi_handle, 7653 struct wifi_scan_cmd_req_params *pstart, 7654 wmi_buf_t *buf, int *buf_len) 7655 { 7656 wmi_extscan_start_cmd_fixed_param *cmd; 7657 wmi_extscan_bucket *dest_blist; 7658 wmi_extscan_bucket_channel *dest_clist; 7659 struct wifi_scan_bucket_params *src_bucket = pstart->buckets; 7660 struct wifi_scan_channelspec_params *src_channel = src_bucket->channels; 7661 struct wifi_scan_channelspec_params save_channel[WMI_WLAN_EXTSCAN_MAX_CHANNELS]; 7662 7663 uint8_t *buf_ptr; 7664 int i, k, count = 0; 7665 int len = sizeof(*cmd); 7666 int nbuckets = pstart->numBuckets; 7667 int nchannels = 0; 7668 7669 /* These TLV's are are NULL by default */ 7670 uint32_t ie_len_with_pad = 0; 7671 int num_ssid = 0; 7672 int num_bssid = 0; 7673 int ie_len = 0; 7674 7675 uint32_t base_period = pstart->basePeriod; 7676 7677 /* TLV placeholder for ssid_list (NULL) */ 7678 len += WMI_TLV_HDR_SIZE; 7679 len += num_ssid * sizeof(wmi_ssid); 7680 7681 /* TLV placeholder for bssid_list (NULL) */ 7682 len += WMI_TLV_HDR_SIZE; 7683 len += num_bssid * sizeof(wmi_mac_addr); 7684 7685 /* TLV placeholder for ie_data (NULL) */ 7686 len += WMI_TLV_HDR_SIZE; 7687 len += ie_len * sizeof(uint32_t); 7688 7689 /* TLV placeholder for bucket */ 7690 len += WMI_TLV_HDR_SIZE; 7691 len += nbuckets * sizeof(wmi_extscan_bucket); 7692 7693 /* TLV channel placeholder */ 7694 len += WMI_TLV_HDR_SIZE; 7695 for (i = 0; i < nbuckets; i++) { 7696 nchannels += src_bucket->numChannels; 7697 src_bucket++; 7698 } 7699 7700 WMI_LOGD("%s: Total buckets: %d total #of channels is %d", 7701 __func__, nbuckets, nchannels); 7702 len += nchannels * sizeof(wmi_extscan_bucket_channel); 7703 /* Allocate the memory */ 7704 *buf = wmi_buf_alloc(wmi_handle, len); 7705 if (!*buf) { 7706 WMI_LOGP("%s: failed to allocate memory" 7707 " for start extscan cmd", __func__); 7708 return QDF_STATUS_E_NOMEM; 7709 } 7710 buf_ptr = (uint8_t *) wmi_buf_data(*buf); 7711 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr; 7712 WMITLV_SET_HDR(&cmd->tlv_header, 7713 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, 7714 WMITLV_GET_STRUCT_TLVLEN 7715 (wmi_extscan_start_cmd_fixed_param)); 7716 7717 cmd->request_id = pstart->requestId; 7718 cmd->vdev_id = pstart->sessionId; 7719 cmd->base_period = pstart->basePeriod; 7720 cmd->num_buckets = nbuckets; 7721 cmd->configuration_flags = 0; 7722 if (pstart->configuration_flags & WMI_EXTSCAN_LP_EXTENDED_BATCHING) 7723 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN; 7724 WMI_LOGI("%s: configuration_flags: 0x%x", __func__, 7725 cmd->configuration_flags); 7726 #ifdef FEATURE_WLAN_EXTSCAN 7727 cmd->min_rest_time = WMI_EXTSCAN_REST_TIME; 7728 cmd->max_rest_time = WMI_EXTSCAN_REST_TIME; 7729 cmd->max_scan_time = WMI_EXTSCAN_MAX_SCAN_TIME; 7730 cmd->burst_duration = WMI_EXTSCAN_BURST_DURATION; 7731 #endif 7732 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7733 7734 /* The max dwell time is retrieved from the first channel 7735 * of the first bucket and kept common for all channels. 7736 */ 7737 cmd->min_dwell_time_active = pstart->min_dwell_time_active; 7738 cmd->max_dwell_time_active = pstart->max_dwell_time_active; 7739 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive; 7740 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive; 7741 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; 7742 cmd->max_table_usage = pstart->report_threshold_percent; 7743 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans; 7744 7745 cmd->repeat_probe_time = cmd->max_dwell_time_active / 7746 WMI_SCAN_NPROBES_DEFAULT; 7747 cmd->probe_delay = 0; 7748 cmd->probe_spacing_time = 0; 7749 cmd->idle_time = 0; 7750 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ | 7751 WMI_SCAN_ADD_CCK_RATES | 7752 WMI_SCAN_ADD_OFDM_RATES | 7753 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ | 7754 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 7755 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 7756 pstart->extscan_adaptive_dwell_mode); 7757 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_LOW; 7758 cmd->num_ssids = 0; 7759 cmd->num_bssid = 0; 7760 cmd->ie_len = 0; 7761 cmd->n_probes = (cmd->repeat_probe_time > 0) ? 7762 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0; 7763 7764 buf_ptr += sizeof(*cmd); 7765 WMITLV_SET_HDR(buf_ptr, 7766 WMITLV_TAG_ARRAY_FIXED_STRUC, 7767 num_ssid * sizeof(wmi_ssid)); 7768 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid)); 7769 7770 WMITLV_SET_HDR(buf_ptr, 7771 WMITLV_TAG_ARRAY_FIXED_STRUC, 7772 num_bssid * sizeof(wmi_mac_addr)); 7773 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr)); 7774 7775 ie_len_with_pad = 0; 7776 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7777 ie_len_with_pad); 7778 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; 7779 7780 WMITLV_SET_HDR(buf_ptr, 7781 WMITLV_TAG_ARRAY_STRUC, 7782 nbuckets * sizeof(wmi_extscan_bucket)); 7783 dest_blist = (wmi_extscan_bucket *) 7784 (buf_ptr + WMI_TLV_HDR_SIZE); 7785 src_bucket = pstart->buckets; 7786 7787 /* Retrieve scanning information from each bucket and 7788 * channels and send it to the target 7789 */ 7790 for (i = 0; i < nbuckets; i++) { 7791 WMITLV_SET_HDR(dest_blist, 7792 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 7793 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket)); 7794 7795 dest_blist->bucket_id = src_bucket->bucket; 7796 dest_blist->base_period_multiplier = 7797 src_bucket->period / base_period; 7798 dest_blist->min_period = src_bucket->period; 7799 dest_blist->max_period = src_bucket->max_period; 7800 dest_blist->exp_backoff = src_bucket->exponent; 7801 dest_blist->exp_max_step_count = src_bucket->step_count; 7802 dest_blist->channel_band = src_bucket->band; 7803 dest_blist->num_channels = src_bucket->numChannels; 7804 dest_blist->notify_extscan_events = 0; 7805 7806 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_EACH_SCAN) 7807 dest_blist->notify_extscan_events = 7808 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | 7809 WMI_EXTSCAN_CYCLE_STARTED_EVENT; 7810 7811 if (src_bucket->reportEvents & 7812 WMI_EXTSCAN_REPORT_EVENTS_FULL_RESULTS) { 7813 dest_blist->forwarding_flags = 7814 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; 7815 dest_blist->notify_extscan_events |= 7816 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT | 7817 WMI_EXTSCAN_CYCLE_STARTED_EVENT | 7818 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT; 7819 } else { 7820 dest_blist->forwarding_flags = 7821 WMI_EXTSCAN_NO_FORWARDING; 7822 } 7823 7824 if (src_bucket->reportEvents & WMI_EXTSCAN_REPORT_EVENTS_NO_BATCH) 7825 dest_blist->configuration_flags = 0; 7826 else 7827 dest_blist->configuration_flags = 7828 WMI_EXTSCAN_BUCKET_CACHE_RESULTS; 7829 7830 WMI_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u", 7831 __func__, dest_blist->notify_extscan_events, 7832 dest_blist->configuration_flags, 7833 dest_blist->forwarding_flags); 7834 7835 dest_blist->min_dwell_time_active = 7836 src_bucket->min_dwell_time_active; 7837 dest_blist->max_dwell_time_active = 7838 src_bucket->max_dwell_time_active; 7839 dest_blist->min_dwell_time_passive = 7840 src_bucket->min_dwell_time_passive; 7841 dest_blist->max_dwell_time_passive = 7842 src_bucket->max_dwell_time_passive; 7843 src_channel = src_bucket->channels; 7844 7845 /* save the channel info to later populate 7846 * the channel TLV 7847 */ 7848 for (k = 0; k < src_bucket->numChannels; k++) { 7849 save_channel[count++].channel = src_channel->channel; 7850 src_channel++; 7851 } 7852 dest_blist++; 7853 src_bucket++; 7854 } 7855 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket)); 7856 WMITLV_SET_HDR(buf_ptr, 7857 WMITLV_TAG_ARRAY_STRUC, 7858 nchannels * sizeof(wmi_extscan_bucket_channel)); 7859 dest_clist = (wmi_extscan_bucket_channel *) 7860 (buf_ptr + WMI_TLV_HDR_SIZE); 7861 7862 /* Active or passive scan is based on the bucket dwell time 7863 * and channel specific active,passive scans are not 7864 * supported yet 7865 */ 7866 for (i = 0; i < nchannels; i++) { 7867 WMITLV_SET_HDR(dest_clist, 7868 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, 7869 WMITLV_GET_STRUCT_TLVLEN 7870 (wmi_extscan_bucket_channel)); 7871 dest_clist->channel = save_channel[i].channel; 7872 dest_clist++; 7873 } 7874 buf_ptr += WMI_TLV_HDR_SIZE + 7875 (nchannels * sizeof(wmi_extscan_bucket_channel)); 7876 *buf_len = len; 7877 return QDF_STATUS_SUCCESS; 7878 } 7879 7880 /** 7881 * send_start_extscan_cmd_tlv() - start extscan command to fw. 7882 * @wmi_handle: wmi handle 7883 * @pstart: scan command request params 7884 * 7885 * This function sends start extscan request to fw. 7886 * 7887 * Return: CDF Status. 7888 */ 7889 static QDF_STATUS send_start_extscan_cmd_tlv(wmi_unified_t wmi_handle, 7890 struct wifi_scan_cmd_req_params *pstart) 7891 { 7892 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 7893 wmi_buf_t buf; 7894 int len; 7895 7896 /* Fill individual elements of extscan request and 7897 * TLV for buckets, channel list. 7898 */ 7899 qdf_status = wmi_get_buf_extscan_start_cmd(wmi_handle, 7900 pstart, &buf, &len); 7901 if (qdf_status != QDF_STATUS_SUCCESS) { 7902 WMI_LOGE("%s: Failed to get buffer for ext scan cmd", __func__); 7903 return QDF_STATUS_E_FAILURE; 7904 } 7905 if (!buf) { 7906 WMI_LOGE("%s:Failed to get buffer" 7907 "for current extscan info", __func__); 7908 return QDF_STATUS_E_FAILURE; 7909 } 7910 if (wmi_unified_cmd_send(wmi_handle, buf, 7911 len, WMI_EXTSCAN_START_CMDID)) { 7912 WMI_LOGE("%s: failed to send command", __func__); 7913 wmi_buf_free(buf); 7914 return QDF_STATUS_E_FAILURE; 7915 } 7916 7917 return QDF_STATUS_SUCCESS; 7918 } 7919 7920 /** 7921 * send_plm_stop_cmd_tlv() - plm stop request 7922 * @wmi_handle: wmi handle 7923 * @plm: plm request parameters 7924 * 7925 * This function request FW to stop PLM. 7926 * 7927 * Return: CDF status 7928 */ 7929 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7930 const struct plm_req_params *plm) 7931 { 7932 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7933 int32_t len; 7934 wmi_buf_t buf; 7935 uint8_t *buf_ptr; 7936 int ret; 7937 7938 len = sizeof(*cmd); 7939 buf = wmi_buf_alloc(wmi_handle, len); 7940 if (!buf) { 7941 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7942 return QDF_STATUS_E_NOMEM; 7943 } 7944 7945 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7946 7947 buf_ptr = (uint8_t *) cmd; 7948 7949 WMITLV_SET_HDR(&cmd->tlv_header, 7950 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7951 WMITLV_GET_STRUCT_TLVLEN 7952 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7953 7954 cmd->vdev_id = plm->session_id; 7955 7956 cmd->meas_token = plm->meas_token; 7957 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7958 7959 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7960 WMI_VDEV_PLMREQ_STOP_CMDID); 7961 if (ret) { 7962 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7963 wmi_buf_free(buf); 7964 return QDF_STATUS_E_FAILURE; 7965 } 7966 7967 return QDF_STATUS_SUCCESS; 7968 } 7969 7970 /** 7971 * send_plm_start_cmd_tlv() - plm start request 7972 * @wmi_handle: wmi handle 7973 * @plm: plm request parameters 7974 * 7975 * This function request FW to start PLM. 7976 * 7977 * Return: CDF status 7978 */ 7979 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7980 const struct plm_req_params *plm, 7981 uint32_t *gchannel_list) 7982 { 7983 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7984 uint32_t *channel_list; 7985 int32_t len; 7986 wmi_buf_t buf; 7987 uint8_t *buf_ptr; 7988 uint8_t count; 7989 int ret; 7990 7991 /* TLV place holder for channel_list */ 7992 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7993 len += sizeof(uint32_t) * plm->plm_num_ch; 7994 7995 buf = wmi_buf_alloc(wmi_handle, len); 7996 if (!buf) { 7997 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7998 return QDF_STATUS_E_NOMEM; 7999 } 8000 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 8001 8002 buf_ptr = (uint8_t *) cmd; 8003 8004 WMITLV_SET_HDR(&cmd->tlv_header, 8005 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 8006 WMITLV_GET_STRUCT_TLVLEN 8007 (wmi_vdev_plmreq_start_cmd_fixed_param)); 8008 8009 cmd->vdev_id = plm->session_id; 8010 8011 cmd->meas_token = plm->meas_token; 8012 cmd->dialog_token = plm->diag_token; 8013 cmd->number_bursts = plm->num_bursts; 8014 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 8015 cmd->off_duration = plm->meas_duration; 8016 cmd->burst_cycle = plm->burst_len; 8017 cmd->tx_power = plm->desired_tx_pwr; 8018 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 8019 cmd->num_chans = plm->plm_num_ch; 8020 8021 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 8022 8023 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 8024 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 8025 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 8026 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 8027 WMI_LOGD("off_duration: %d", cmd->off_duration); 8028 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 8029 WMI_LOGD("tx_power: %d", cmd->tx_power); 8030 WMI_LOGD("Number of channels : %d", cmd->num_chans); 8031 8032 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8033 (cmd->num_chans * sizeof(uint32_t))); 8034 8035 buf_ptr += WMI_TLV_HDR_SIZE; 8036 if (cmd->num_chans) { 8037 channel_list = (uint32_t *) buf_ptr; 8038 for (count = 0; count < cmd->num_chans; count++) { 8039 channel_list[count] = plm->plm_ch_list[count]; 8040 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 8041 channel_list[count] = 8042 gchannel_list[count]; 8043 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 8044 } 8045 buf_ptr += cmd->num_chans * sizeof(uint32_t); 8046 } 8047 8048 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8049 WMI_VDEV_PLMREQ_START_CMDID); 8050 if (ret) { 8051 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 8052 wmi_buf_free(buf); 8053 return QDF_STATUS_E_FAILURE; 8054 } 8055 8056 return QDF_STATUS_SUCCESS; 8057 } 8058 8059 /** 8060 * send_pno_stop_cmd_tlv() - PNO stop request 8061 * @wmi_handle: wmi handle 8062 * @vdev_id: vdev id 8063 * 8064 * This function request FW to stop ongoing PNO operation. 8065 * 8066 * Return: CDF status 8067 */ 8068 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8069 { 8070 wmi_nlo_config_cmd_fixed_param *cmd; 8071 int32_t len = sizeof(*cmd); 8072 wmi_buf_t buf; 8073 uint8_t *buf_ptr; 8074 int ret; 8075 8076 /* 8077 * TLV place holder for array of structures nlo_configured_parameters 8078 * TLV place holder for array of uint32_t channel_list 8079 * TLV place holder for chnl prediction cfg 8080 */ 8081 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8082 buf = wmi_buf_alloc(wmi_handle, len); 8083 if (!buf) { 8084 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8085 return QDF_STATUS_E_NOMEM; 8086 } 8087 8088 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8089 buf_ptr = (uint8_t *) cmd; 8090 8091 WMITLV_SET_HDR(&cmd->tlv_header, 8092 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8093 WMITLV_GET_STRUCT_TLVLEN 8094 (wmi_nlo_config_cmd_fixed_param)); 8095 8096 cmd->vdev_id = vdev_id; 8097 cmd->flags = WMI_NLO_CONFIG_STOP; 8098 buf_ptr += sizeof(*cmd); 8099 8100 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8101 buf_ptr += WMI_TLV_HDR_SIZE; 8102 8103 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 8104 buf_ptr += WMI_TLV_HDR_SIZE; 8105 8106 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8107 buf_ptr += WMI_TLV_HDR_SIZE; 8108 8109 8110 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8111 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8112 if (ret) { 8113 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8114 wmi_buf_free(buf); 8115 return QDF_STATUS_E_FAILURE; 8116 } 8117 8118 return QDF_STATUS_SUCCESS; 8119 } 8120 8121 /** 8122 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 8123 * @buf_ptr: Buffer passed by upper layers 8124 * @pno: Buffer to be sent to the firmware 8125 * 8126 * Copy the PNO Channel prediction configuration parameters 8127 * passed by the upper layers to a WMI format TLV and send it 8128 * down to the firmware. 8129 * 8130 * Return: None 8131 */ 8132 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 8133 struct pno_scan_req_params *pno) 8134 { 8135 nlo_channel_prediction_cfg *channel_prediction_cfg = 8136 (nlo_channel_prediction_cfg *) buf_ptr; 8137 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 8138 WMITLV_TAG_ARRAY_BYTE, 8139 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 8140 #ifdef FEATURE_WLAN_SCAN_PNO 8141 channel_prediction_cfg->enable = pno->pno_channel_prediction; 8142 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 8143 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 8144 channel_prediction_cfg->full_scan_period_ms = 8145 pno->channel_prediction_full_scan; 8146 #endif 8147 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8148 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 8149 channel_prediction_cfg->enable, 8150 channel_prediction_cfg->top_k_num, 8151 channel_prediction_cfg->stationary_threshold, 8152 channel_prediction_cfg->full_scan_period_ms); 8153 } 8154 8155 /** 8156 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 8157 * @wmi_handle: wmi handle 8158 * @params: configuration parameters 8159 * 8160 * Return: QDF_STATUS 8161 */ 8162 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 8163 struct nlo_mawc_params *params) 8164 { 8165 wmi_buf_t buf = NULL; 8166 QDF_STATUS status; 8167 int len; 8168 uint8_t *buf_ptr; 8169 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 8170 8171 len = sizeof(*wmi_nlo_mawc_params); 8172 buf = wmi_buf_alloc(wmi_handle, len); 8173 if (!buf) { 8174 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8175 return QDF_STATUS_E_NOMEM; 8176 } 8177 8178 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8179 wmi_nlo_mawc_params = 8180 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 8181 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 8182 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 8183 WMITLV_GET_STRUCT_TLVLEN 8184 (wmi_nlo_configure_mawc_cmd_fixed_param)); 8185 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 8186 if (params->enable) 8187 wmi_nlo_mawc_params->enable = 1; 8188 else 8189 wmi_nlo_mawc_params->enable = 0; 8190 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 8191 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 8192 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 8193 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 8194 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 8195 wmi_nlo_mawc_params->exp_backoff_ratio, 8196 wmi_nlo_mawc_params->init_scan_interval, 8197 wmi_nlo_mawc_params->max_scan_interval); 8198 8199 status = wmi_unified_cmd_send(wmi_handle, buf, 8200 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 8201 if (QDF_IS_STATUS_ERROR(status)) { 8202 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 8203 status); 8204 wmi_buf_free(buf); 8205 return QDF_STATUS_E_FAILURE; 8206 } 8207 8208 return QDF_STATUS_SUCCESS; 8209 } 8210 8211 /** 8212 * send_pno_start_cmd_tlv() - PNO start request 8213 * @wmi_handle: wmi handle 8214 * @pno: PNO request 8215 * 8216 * This function request FW to start PNO request. 8217 * Request: CDF status 8218 */ 8219 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 8220 struct pno_scan_req_params *pno) 8221 { 8222 wmi_nlo_config_cmd_fixed_param *cmd; 8223 nlo_configured_parameters *nlo_list; 8224 uint32_t *channel_list; 8225 int32_t len; 8226 wmi_buf_t buf; 8227 uint8_t *buf_ptr; 8228 uint8_t i; 8229 int ret; 8230 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 8231 connected_nlo_rssi_params *nlo_relative_rssi; 8232 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 8233 8234 /* 8235 * TLV place holder for array nlo_configured_parameters(nlo_list) 8236 * TLV place holder for array of uint32_t channel_list 8237 * TLV place holder for chnnl prediction cfg 8238 * TLV place holder for array of wmi_vendor_oui 8239 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 8240 */ 8241 len = sizeof(*cmd) + 8242 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 8243 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 8244 8245 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 8246 WMI_NLO_MAX_CHAN); 8247 len += sizeof(nlo_configured_parameters) * 8248 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8249 len += sizeof(nlo_channel_prediction_cfg); 8250 len += sizeof(enlo_candidate_score_params); 8251 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 8252 len += sizeof(connected_nlo_rssi_params); 8253 len += sizeof(connected_nlo_bss_band_rssi_pref); 8254 8255 buf = wmi_buf_alloc(wmi_handle, len); 8256 if (!buf) { 8257 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8258 return QDF_STATUS_E_NOMEM; 8259 } 8260 8261 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 8262 8263 buf_ptr = (uint8_t *) cmd; 8264 WMITLV_SET_HDR(&cmd->tlv_header, 8265 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 8266 WMITLV_GET_STRUCT_TLVLEN 8267 (wmi_nlo_config_cmd_fixed_param)); 8268 cmd->vdev_id = pno->vdev_id; 8269 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 8270 8271 #ifdef FEATURE_WLAN_SCAN_PNO 8272 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 8273 pno->adaptive_dwell_mode); 8274 #endif 8275 /* Current FW does not support min-max range for dwell time */ 8276 cmd->active_dwell_time = pno->active_dwell_time; 8277 cmd->passive_dwell_time = pno->passive_dwell_time; 8278 8279 if (pno->do_passive_scan) 8280 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 8281 /* Copy scan interval */ 8282 cmd->fast_scan_period = pno->fast_scan_period; 8283 cmd->slow_scan_period = pno->slow_scan_period; 8284 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 8285 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 8286 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 8287 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 8288 cmd->fast_scan_period, cmd->slow_scan_period); 8289 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 8290 8291 /* mac randomization attributes */ 8292 if (pno->scan_random.randomize) { 8293 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 8294 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 8295 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 8296 pno->scan_random.mac_mask, 8297 &cmd->mac_addr, 8298 &cmd->mac_mask); 8299 } 8300 8301 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 8302 8303 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 8304 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 8305 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8306 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 8307 buf_ptr += WMI_TLV_HDR_SIZE; 8308 8309 nlo_list = (nlo_configured_parameters *) buf_ptr; 8310 for (i = 0; i < cmd->no_of_ssids; i++) { 8311 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 8312 WMITLV_TAG_ARRAY_BYTE, 8313 WMITLV_GET_STRUCT_TLVLEN 8314 (nlo_configured_parameters)); 8315 /* Copy ssid and it's length */ 8316 nlo_list[i].ssid.valid = true; 8317 nlo_list[i].ssid.ssid.ssid_len = 8318 pno->networks_list[i].ssid.length; 8319 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 8320 pno->networks_list[i].ssid.ssid, 8321 nlo_list[i].ssid.ssid.ssid_len); 8322 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 8323 nlo_list[i].ssid.ssid.ssid_len, 8324 (char *)nlo_list[i].ssid.ssid.ssid, 8325 nlo_list[i].ssid.ssid.ssid_len); 8326 8327 /* Copy rssi threshold */ 8328 if (pno->networks_list[i].rssi_thresh && 8329 pno->networks_list[i].rssi_thresh > 8330 WMI_RSSI_THOLD_DEFAULT) { 8331 nlo_list[i].rssi_cond.valid = true; 8332 nlo_list[i].rssi_cond.rssi = 8333 pno->networks_list[i].rssi_thresh; 8334 WMI_LOGD("RSSI threshold : %d dBm", 8335 nlo_list[i].rssi_cond.rssi); 8336 } 8337 nlo_list[i].bcast_nw_type.valid = true; 8338 nlo_list[i].bcast_nw_type.bcast_nw_type = 8339 pno->networks_list[i].bc_new_type; 8340 WMI_LOGD("Broadcast NW type (%u)", 8341 nlo_list[i].bcast_nw_type.bcast_nw_type); 8342 } 8343 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 8344 8345 /* Copy channel info */ 8346 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 8347 WMI_NLO_MAX_CHAN); 8348 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 8349 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8350 (cmd->num_of_channels * sizeof(uint32_t))); 8351 buf_ptr += WMI_TLV_HDR_SIZE; 8352 8353 channel_list = (uint32_t *) buf_ptr; 8354 for (i = 0; i < cmd->num_of_channels; i++) { 8355 channel_list[i] = pno->networks_list[0].channels[i]; 8356 8357 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 8358 channel_list[i] = 8359 wlan_chan_to_freq(pno-> 8360 networks_list[0].channels[i]); 8361 8362 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 8363 } 8364 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 8365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8366 sizeof(nlo_channel_prediction_cfg)); 8367 buf_ptr += WMI_TLV_HDR_SIZE; 8368 wmi_set_pno_channel_prediction(buf_ptr, pno); 8369 buf_ptr += sizeof(nlo_channel_prediction_cfg); 8370 /** TODO: Discrete firmware doesn't have command/option to configure 8371 * App IE which comes from wpa_supplicant as of part PNO start request. 8372 */ 8373 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 8374 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 8375 buf_ptr += sizeof(enlo_candidate_score_params); 8376 8377 if (ie_whitelist->white_list) { 8378 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 8379 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 8380 &cmd->num_vendor_oui, 8381 ie_whitelist); 8382 } 8383 8384 /* ie white list */ 8385 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8386 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 8387 buf_ptr += WMI_TLV_HDR_SIZE; 8388 if (cmd->num_vendor_oui != 0) { 8389 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 8390 ie_whitelist->voui); 8391 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 8392 } 8393 8394 if (pno->relative_rssi_set) 8395 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 8396 8397 /* 8398 * Firmware calculation using connected PNO params: 8399 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 8400 * deduction of rssi_pref for chosen band_pref and 8401 * addition of rssi_pref for remaining bands (other than chosen band). 8402 */ 8403 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 8404 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 8405 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 8406 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 8407 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 8408 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 8409 buf_ptr += sizeof(*nlo_relative_rssi); 8410 8411 /* 8412 * As of now Kernel and Host supports one band and rssi preference. 8413 * Firmware supports array of band and rssi preferences 8414 */ 8415 cmd->num_cnlo_band_pref = 1; 8416 WMITLV_SET_HDR(buf_ptr, 8417 WMITLV_TAG_ARRAY_STRUC, 8418 cmd->num_cnlo_band_pref * 8419 sizeof(connected_nlo_bss_band_rssi_pref)); 8420 buf_ptr += WMI_TLV_HDR_SIZE; 8421 8422 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 8423 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 8424 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 8425 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 8426 WMITLV_GET_STRUCT_TLVLEN( 8427 connected_nlo_bss_band_rssi_pref)); 8428 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 8429 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 8430 WMI_LOGI("band_pref %d, rssi_pref %d", 8431 nlo_band_rssi[i].band, 8432 nlo_band_rssi[i].rssi_pref); 8433 } 8434 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 8435 8436 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8437 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 8438 if (ret) { 8439 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 8440 wmi_buf_free(buf); 8441 return QDF_STATUS_E_FAILURE; 8442 } 8443 8444 return QDF_STATUS_SUCCESS; 8445 } 8446 8447 /* send_set_ric_req_cmd_tlv() - set ric request element 8448 * @wmi_handle: wmi handle 8449 * @msg: message 8450 * @is_add_ts: is addts required 8451 * 8452 * This function sets ric request element for 11r roaming. 8453 * 8454 * Return: CDF status 8455 */ 8456 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 8457 void *msg, uint8_t is_add_ts) 8458 { 8459 wmi_ric_request_fixed_param *cmd; 8460 wmi_ric_tspec *tspec_param; 8461 wmi_buf_t buf; 8462 uint8_t *buf_ptr; 8463 struct mac_tspec_ie *ptspecIE = NULL; 8464 int32_t len = sizeof(wmi_ric_request_fixed_param) + 8465 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 8466 8467 buf = wmi_buf_alloc(wmi_handle, len); 8468 if (!buf) { 8469 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8470 return QDF_STATUS_E_NOMEM; 8471 } 8472 8473 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8474 8475 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 8476 WMITLV_SET_HDR(&cmd->tlv_header, 8477 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 8478 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 8479 if (is_add_ts) 8480 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 8481 else 8482 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 8483 cmd->num_ric_request = 1; 8484 cmd->is_add_ric = is_add_ts; 8485 8486 buf_ptr += sizeof(wmi_ric_request_fixed_param); 8487 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 8488 8489 buf_ptr += WMI_TLV_HDR_SIZE; 8490 tspec_param = (wmi_ric_tspec *) buf_ptr; 8491 WMITLV_SET_HDR(&tspec_param->tlv_header, 8492 WMITLV_TAG_STRUC_wmi_ric_tspec, 8493 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 8494 8495 if (is_add_ts) 8496 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 8497 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 8498 else 8499 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 8500 #endif 8501 if (ptspecIE) { 8502 /* Fill the tsinfo in the format expected by firmware */ 8503 #ifndef ANI_LITTLE_BIT_ENDIAN 8504 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 8505 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8506 #else 8507 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 8508 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 8509 #endif /* ANI_LITTLE_BIT_ENDIAN */ 8510 8511 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 8512 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 8513 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 8514 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 8515 tspec_param->inactivity_interval = ptspecIE->inactInterval; 8516 tspec_param->suspension_interval = ptspecIE->suspendInterval; 8517 tspec_param->svc_start_time = ptspecIE->svcStartTime; 8518 tspec_param->min_data_rate = ptspecIE->minDataRate; 8519 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 8520 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 8521 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 8522 tspec_param->delay_bound = ptspecIE->delayBound; 8523 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 8524 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 8525 tspec_param->medium_time = 0; 8526 } 8527 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 8528 8529 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8530 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 8531 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 8532 __func__); 8533 if (is_add_ts) 8534 ((struct add_ts_param *) msg)->status = 8535 QDF_STATUS_E_FAILURE; 8536 wmi_buf_free(buf); 8537 return QDF_STATUS_E_FAILURE; 8538 } 8539 8540 return QDF_STATUS_SUCCESS; 8541 } 8542 8543 /** 8544 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 8545 * @wmi_handle: wmi handle 8546 * @clear_req: ll stats clear request command params 8547 * 8548 * Return: QDF_STATUS_SUCCESS for success or error code 8549 */ 8550 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 8551 const struct ll_stats_clear_params *clear_req, 8552 uint8_t addr[IEEE80211_ADDR_LEN]) 8553 { 8554 wmi_clear_link_stats_cmd_fixed_param *cmd; 8555 int32_t len; 8556 wmi_buf_t buf; 8557 uint8_t *buf_ptr; 8558 int ret; 8559 8560 len = sizeof(*cmd); 8561 buf = wmi_buf_alloc(wmi_handle, len); 8562 8563 if (!buf) { 8564 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8565 return QDF_STATUS_E_NOMEM; 8566 } 8567 8568 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8569 qdf_mem_zero(buf_ptr, len); 8570 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 8571 8572 WMITLV_SET_HDR(&cmd->tlv_header, 8573 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 8574 WMITLV_GET_STRUCT_TLVLEN 8575 (wmi_clear_link_stats_cmd_fixed_param)); 8576 8577 cmd->stop_stats_collection_req = clear_req->stop_req; 8578 cmd->vdev_id = clear_req->sta_id; 8579 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 8580 8581 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8582 &cmd->peer_macaddr); 8583 8584 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 8585 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 8586 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 8587 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 8588 /* WMI_LOGD("Peer MAC Addr : %pM", 8589 cmd->peer_macaddr); */ 8590 8591 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8592 WMI_CLEAR_LINK_STATS_CMDID); 8593 if (ret) { 8594 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 8595 wmi_buf_free(buf); 8596 return QDF_STATUS_E_FAILURE; 8597 } 8598 8599 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 8600 return QDF_STATUS_SUCCESS; 8601 } 8602 8603 /** 8604 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 8605 * @wmi_handle: wmi handle 8606 * @setReq: ll stats set request command params 8607 * 8608 * Return: QDF_STATUS_SUCCESS for success or error code 8609 */ 8610 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 8611 const struct ll_stats_set_params *set_req) 8612 { 8613 wmi_start_link_stats_cmd_fixed_param *cmd; 8614 int32_t len; 8615 wmi_buf_t buf; 8616 uint8_t *buf_ptr; 8617 int ret; 8618 8619 len = sizeof(*cmd); 8620 buf = wmi_buf_alloc(wmi_handle, len); 8621 8622 if (!buf) { 8623 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8624 return QDF_STATUS_E_NOMEM; 8625 } 8626 8627 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8628 qdf_mem_zero(buf_ptr, len); 8629 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 8630 8631 WMITLV_SET_HDR(&cmd->tlv_header, 8632 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 8633 WMITLV_GET_STRUCT_TLVLEN 8634 (wmi_start_link_stats_cmd_fixed_param)); 8635 8636 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 8637 cmd->aggressive_statistics_gathering = 8638 set_req->aggressive_statistics_gathering; 8639 8640 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 8641 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 8642 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 8643 8644 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8645 WMI_START_LINK_STATS_CMDID); 8646 if (ret) { 8647 WMI_LOGE("%s: Failed to send set link stats request", __func__); 8648 wmi_buf_free(buf); 8649 return QDF_STATUS_E_FAILURE; 8650 } 8651 8652 return QDF_STATUS_SUCCESS; 8653 } 8654 8655 /** 8656 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 8657 * @wmi_handle:wmi handle 8658 * @get_req:ll stats get request command params 8659 * @addr: mac address 8660 * 8661 * Return: QDF_STATUS_SUCCESS for success or error code 8662 */ 8663 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 8664 const struct ll_stats_get_params *get_req, 8665 uint8_t addr[IEEE80211_ADDR_LEN]) 8666 { 8667 wmi_request_link_stats_cmd_fixed_param *cmd; 8668 int32_t len; 8669 wmi_buf_t buf; 8670 uint8_t *buf_ptr; 8671 int ret; 8672 8673 len = sizeof(*cmd); 8674 buf = wmi_buf_alloc(wmi_handle, len); 8675 8676 if (!buf) { 8677 WMI_LOGE("%s: buf allocation failed", __func__); 8678 return QDF_STATUS_E_NOMEM; 8679 } 8680 8681 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8682 qdf_mem_zero(buf_ptr, len); 8683 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 8684 8685 WMITLV_SET_HDR(&cmd->tlv_header, 8686 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 8687 WMITLV_GET_STRUCT_TLVLEN 8688 (wmi_request_link_stats_cmd_fixed_param)); 8689 8690 cmd->request_id = get_req->req_id; 8691 cmd->stats_type = get_req->param_id_mask; 8692 cmd->vdev_id = get_req->sta_id; 8693 8694 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8695 &cmd->peer_macaddr); 8696 8697 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 8698 WMI_LOGD("Request ID : %u", cmd->request_id); 8699 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 8700 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 8701 WMI_LOGD("Peer MAC Addr : %pM", addr); 8702 8703 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8704 WMI_REQUEST_LINK_STATS_CMDID); 8705 if (ret) { 8706 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8707 wmi_buf_free(buf); 8708 return QDF_STATUS_E_FAILURE; 8709 } 8710 8711 return QDF_STATUS_SUCCESS; 8712 } 8713 8714 8715 /** 8716 * send_congestion_cmd_tlv() - send request to fw to get CCA 8717 * @wmi_handle: wmi handle 8718 * @vdev_id: vdev id 8719 * 8720 * Return: CDF status 8721 */ 8722 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8723 uint8_t vdev_id) 8724 { 8725 wmi_buf_t buf; 8726 wmi_request_stats_cmd_fixed_param *cmd; 8727 uint8_t len; 8728 uint8_t *buf_ptr; 8729 8730 len = sizeof(*cmd); 8731 buf = wmi_buf_alloc(wmi_handle, len); 8732 if (!buf) { 8733 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8734 return QDF_STATUS_E_FAILURE; 8735 } 8736 8737 buf_ptr = wmi_buf_data(buf); 8738 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8739 WMITLV_SET_HDR(&cmd->tlv_header, 8740 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8741 WMITLV_GET_STRUCT_TLVLEN 8742 (wmi_request_stats_cmd_fixed_param)); 8743 8744 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8745 cmd->vdev_id = vdev_id; 8746 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8747 cmd->vdev_id, cmd->stats_id); 8748 8749 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8750 WMI_REQUEST_STATS_CMDID)) { 8751 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8752 __func__); 8753 wmi_buf_free(buf); 8754 return QDF_STATUS_E_FAILURE; 8755 } 8756 8757 return QDF_STATUS_SUCCESS; 8758 } 8759 8760 /** 8761 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8762 * @wmi_handle: wmi handle 8763 * @rssi_req: get RSSI request 8764 * 8765 * Return: CDF status 8766 */ 8767 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8768 { 8769 wmi_buf_t buf; 8770 wmi_request_stats_cmd_fixed_param *cmd; 8771 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8772 8773 buf = wmi_buf_alloc(wmi_handle, len); 8774 if (!buf) { 8775 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8776 return QDF_STATUS_E_FAILURE; 8777 } 8778 8779 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8780 WMITLV_SET_HDR(&cmd->tlv_header, 8781 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8782 WMITLV_GET_STRUCT_TLVLEN 8783 (wmi_request_stats_cmd_fixed_param)); 8784 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8785 if (wmi_unified_cmd_send 8786 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8787 WMI_LOGE("Failed to send host stats request to fw"); 8788 wmi_buf_free(buf); 8789 return QDF_STATUS_E_FAILURE; 8790 } 8791 8792 return QDF_STATUS_SUCCESS; 8793 } 8794 8795 /** 8796 * send_snr_cmd_tlv() - get RSSI from fw 8797 * @wmi_handle: wmi handle 8798 * @vdev_id: vdev id 8799 * 8800 * Return: CDF status 8801 */ 8802 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8803 { 8804 wmi_buf_t buf; 8805 wmi_request_stats_cmd_fixed_param *cmd; 8806 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8807 8808 buf = wmi_buf_alloc(wmi_handle, len); 8809 if (!buf) { 8810 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8811 return QDF_STATUS_E_FAILURE; 8812 } 8813 8814 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8815 cmd->vdev_id = vdev_id; 8816 8817 WMITLV_SET_HDR(&cmd->tlv_header, 8818 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8819 WMITLV_GET_STRUCT_TLVLEN 8820 (wmi_request_stats_cmd_fixed_param)); 8821 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8822 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8823 WMI_REQUEST_STATS_CMDID)) { 8824 WMI_LOGE("Failed to send host stats request to fw"); 8825 wmi_buf_free(buf); 8826 return QDF_STATUS_E_FAILURE; 8827 } 8828 8829 return QDF_STATUS_SUCCESS; 8830 } 8831 8832 /** 8833 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8834 * @wmi_handle: wmi handle 8835 * @link_status: get link params 8836 * 8837 * Return: CDF status 8838 */ 8839 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8840 struct link_status_params *link_status) 8841 { 8842 wmi_buf_t buf; 8843 wmi_request_stats_cmd_fixed_param *cmd; 8844 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8845 8846 buf = wmi_buf_alloc(wmi_handle, len); 8847 if (!buf) { 8848 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8849 return QDF_STATUS_E_FAILURE; 8850 } 8851 8852 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8853 WMITLV_SET_HDR(&cmd->tlv_header, 8854 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8855 WMITLV_GET_STRUCT_TLVLEN 8856 (wmi_request_stats_cmd_fixed_param)); 8857 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8858 cmd->vdev_id = link_status->session_id; 8859 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8860 WMI_REQUEST_STATS_CMDID)) { 8861 WMI_LOGE("Failed to send WMI link status request to fw"); 8862 wmi_buf_free(buf); 8863 return QDF_STATUS_E_FAILURE; 8864 } 8865 8866 return QDF_STATUS_SUCCESS; 8867 } 8868 8869 /** 8870 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8871 * @wmi_handle: wmi handle 8872 * @ta_dhcp_ind: DHCP indication parameter 8873 * 8874 * Return: CDF Status 8875 */ 8876 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8877 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8878 { 8879 QDF_STATUS status; 8880 wmi_buf_t buf = NULL; 8881 uint8_t *buf_ptr; 8882 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8883 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8884 8885 8886 buf = wmi_buf_alloc(wmi_handle, len); 8887 if (!buf) { 8888 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8889 return QDF_STATUS_E_NOMEM; 8890 } 8891 8892 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8893 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8894 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8895 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8896 WMITLV_GET_STRUCT_TLVLEN 8897 (wmi_peer_set_param_cmd_fixed_param)); 8898 8899 /* fill in values */ 8900 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8901 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8902 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8903 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8904 &ta_dhcp_ind->peer_macaddr, 8905 sizeof(ta_dhcp_ind->peer_macaddr)); 8906 8907 status = wmi_unified_cmd_send(wmi_handle, buf, 8908 len, WMI_PEER_SET_PARAM_CMDID); 8909 if (QDF_IS_STATUS_ERROR(status)) { 8910 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8911 " returned Error %d", __func__, status); 8912 wmi_buf_free(buf); 8913 } 8914 8915 return status; 8916 } 8917 8918 /** 8919 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8920 * @wmi_handle: wmi handle 8921 * @pLinkSpeed: link speed info 8922 * 8923 * Return: CDF status 8924 */ 8925 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8926 wmi_mac_addr peer_macaddr) 8927 { 8928 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8929 wmi_buf_t wmi_buf; 8930 uint32_t len; 8931 uint8_t *buf_ptr; 8932 8933 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8934 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8935 if (!wmi_buf) { 8936 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8937 return QDF_STATUS_E_NOMEM; 8938 } 8939 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8940 8941 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8942 WMITLV_SET_HDR(&cmd->tlv_header, 8943 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8944 WMITLV_GET_STRUCT_TLVLEN 8945 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8946 8947 /* Copy the peer macaddress to the wma buffer */ 8948 qdf_mem_copy(&cmd->peer_macaddr, 8949 &peer_macaddr, 8950 sizeof(peer_macaddr)); 8951 8952 8953 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8954 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8955 WMI_LOGE("%s: failed to send link speed command", __func__); 8956 wmi_buf_free(wmi_buf); 8957 return QDF_STATUS_E_FAILURE; 8958 } 8959 return QDF_STATUS_SUCCESS; 8960 } 8961 8962 #ifdef WLAN_SUPPORT_GREEN_AP 8963 /** 8964 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8965 * @wmi_handle: wmi handler 8966 * @egap_params: pointer to egap_params 8967 * 8968 * Return: 0 for success, otherwise appropriate error code 8969 */ 8970 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8971 struct wlan_green_ap_egap_params *egap_params) 8972 { 8973 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8974 wmi_buf_t buf; 8975 int32_t err; 8976 8977 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8978 if (!buf) { 8979 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8980 return QDF_STATUS_E_NOMEM; 8981 } 8982 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8983 WMITLV_SET_HDR(&cmd->tlv_header, 8984 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8985 WMITLV_GET_STRUCT_TLVLEN( 8986 wmi_ap_ps_egap_param_cmd_fixed_param)); 8987 8988 cmd->enable = egap_params->host_enable_egap; 8989 cmd->inactivity_time = egap_params->egap_inactivity_time; 8990 cmd->wait_time = egap_params->egap_wait_time; 8991 cmd->flags = egap_params->egap_feature_flags; 8992 err = wmi_unified_cmd_send(wmi_handle, buf, 8993 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 8994 if (err) { 8995 WMI_LOGE("Failed to send ap_ps_egap cmd"); 8996 wmi_buf_free(buf); 8997 return QDF_STATUS_E_FAILURE; 8998 } 8999 9000 return QDF_STATUS_SUCCESS; 9001 } 9002 #endif 9003 9004 /** 9005 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 9006 * @wmi_handl: wmi handle 9007 * @cmd: Profiling command index 9008 * @value1: parameter1 value 9009 * @value2: parameter2 value 9010 * 9011 * Return: QDF_STATUS_SUCCESS for success else error code 9012 */ 9013 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 9014 uint32_t cmd, uint32_t value1, uint32_t value2) 9015 { 9016 wmi_buf_t buf; 9017 int32_t len = 0; 9018 int ret; 9019 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 9020 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9021 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 9022 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 9023 9024 switch (cmd) { 9025 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 9026 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 9027 buf = wmi_buf_alloc(wmi_handle, len); 9028 if (!buf) { 9029 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9030 return QDF_STATUS_E_NOMEM; 9031 } 9032 prof_trig_cmd = 9033 (wmi_wlan_profile_trigger_cmd_fixed_param *) 9034 wmi_buf_data(buf); 9035 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 9036 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 9037 WMITLV_GET_STRUCT_TLVLEN 9038 (wmi_wlan_profile_trigger_cmd_fixed_param)); 9039 prof_trig_cmd->enable = value1; 9040 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9041 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9042 if (ret) { 9043 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 9044 value1); 9045 wmi_buf_free(buf); 9046 return ret; 9047 } 9048 break; 9049 9050 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 9051 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 9052 buf = wmi_buf_alloc(wmi_handle, len); 9053 if (!buf) { 9054 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9055 return QDF_STATUS_E_NOMEM; 9056 } 9057 profile_getdata_cmd = 9058 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 9059 wmi_buf_data(buf); 9060 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 9061 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 9062 WMITLV_GET_STRUCT_TLVLEN 9063 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 9064 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9065 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 9066 if (ret) { 9067 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 9068 value1, value2); 9069 wmi_buf_free(buf); 9070 return ret; 9071 } 9072 break; 9073 9074 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 9075 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9076 buf = wmi_buf_alloc(wmi_handle, len); 9077 if (!buf) { 9078 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9079 return QDF_STATUS_E_NOMEM; 9080 } 9081 hist_intvl_cmd = 9082 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9083 wmi_buf_data(buf); 9084 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9085 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9086 WMITLV_GET_STRUCT_TLVLEN 9087 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9088 hist_intvl_cmd->profile_id = value1; 9089 hist_intvl_cmd->value = value2; 9090 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9091 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9092 if (ret) { 9093 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 9094 value1, value2); 9095 wmi_buf_free(buf); 9096 return ret; 9097 } 9098 break; 9099 9100 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 9101 len = 9102 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 9103 buf = wmi_buf_alloc(wmi_handle, len); 9104 if (!buf) { 9105 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 9106 return QDF_STATUS_E_NOMEM; 9107 } 9108 profile_enable_cmd = 9109 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 9110 wmi_buf_data(buf); 9111 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 9112 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 9113 WMITLV_GET_STRUCT_TLVLEN 9114 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 9115 profile_enable_cmd->profile_id = value1; 9116 profile_enable_cmd->enable = value2; 9117 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9118 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 9119 if (ret) { 9120 WMI_LOGE("enable cmd Failed for id %d value %d", 9121 value1, value2); 9122 wmi_buf_free(buf); 9123 return ret; 9124 } 9125 break; 9126 9127 default: 9128 WMI_LOGD("%s: invalid profiling command", __func__); 9129 break; 9130 } 9131 9132 return 0; 9133 } 9134 9135 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 9136 struct wlm_latency_level_param *params) 9137 { 9138 wmi_wlm_config_cmd_fixed_param *cmd; 9139 wmi_buf_t buf; 9140 uint32_t len = sizeof(*cmd); 9141 static uint32_t ll[4] = {100, 60, 40, 20}; 9142 9143 buf = wmi_buf_alloc(wmi_handle, len); 9144 if (!buf) { 9145 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9146 return QDF_STATUS_E_NOMEM; 9147 } 9148 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 9149 WMITLV_SET_HDR(&cmd->tlv_header, 9150 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 9151 WMITLV_GET_STRUCT_TLVLEN 9152 (wmi_wlm_config_cmd_fixed_param)); 9153 cmd->vdev_id = params->vdev_id; 9154 cmd->latency_level = params->wlm_latency_level; 9155 cmd->ul_latency = ll[params->wlm_latency_level]; 9156 cmd->dl_latency = ll[params->wlm_latency_level]; 9157 cmd->flags = params->wlm_latency_flags; 9158 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9159 WMI_WLM_CONFIG_CMDID)) { 9160 WMI_LOGE("%s: Failed to send setting latency config command", 9161 __func__); 9162 wmi_buf_free(buf); 9163 return QDF_STATUS_E_FAILURE; 9164 } 9165 9166 return 0; 9167 } 9168 /** 9169 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 9170 * @wmi_handle: wmi handle 9171 * @vdev_id: vdev id 9172 * 9173 * Return: QDF_STATUS_SUCCESS for success or error code 9174 */ 9175 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 9176 { 9177 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 9178 wmi_buf_t buf; 9179 int32_t len = sizeof(*cmd); 9180 9181 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9182 buf = wmi_buf_alloc(wmi_handle, len); 9183 if (!buf) { 9184 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9185 return QDF_STATUS_E_NOMEM; 9186 } 9187 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 9188 wmi_buf_data(buf); 9189 WMITLV_SET_HDR(&cmd->tlv_header, 9190 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 9191 WMITLV_GET_STRUCT_TLVLEN 9192 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 9193 cmd->vdev_id = vdev_id; 9194 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 9195 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9196 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 9197 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 9198 __func__); 9199 wmi_buf_free(buf); 9200 return QDF_STATUS_E_FAILURE; 9201 } 9202 9203 return 0; 9204 } 9205 9206 /** 9207 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 9208 * @wmi_handle: wmi handle 9209 * @vdev_id: vdev id 9210 * 9211 * Return: QDF_STATUS_SUCCESS for success or error code 9212 */ 9213 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 9214 uint8_t vdev_id) 9215 { 9216 wmi_csa_offload_enable_cmd_fixed_param *cmd; 9217 wmi_buf_t buf; 9218 int32_t len = sizeof(*cmd); 9219 9220 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 9221 buf = wmi_buf_alloc(wmi_handle, len); 9222 if (!buf) { 9223 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9224 return QDF_STATUS_E_NOMEM; 9225 } 9226 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 9227 WMITLV_SET_HDR(&cmd->tlv_header, 9228 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 9229 WMITLV_GET_STRUCT_TLVLEN 9230 (wmi_csa_offload_enable_cmd_fixed_param)); 9231 cmd->vdev_id = vdev_id; 9232 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 9233 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9234 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 9235 WMI_LOGP("%s: Failed to send CSA offload enable command", 9236 __func__); 9237 wmi_buf_free(buf); 9238 return QDF_STATUS_E_FAILURE; 9239 } 9240 9241 return 0; 9242 } 9243 9244 #ifdef WLAN_FEATURE_CIF_CFR 9245 /** 9246 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 9247 * @wmi_handle: wmi handle 9248 * @data_len: len of dma cfg req 9249 * @data: dma cfg req 9250 * 9251 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9252 */ 9253 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9254 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 9255 { 9256 wmi_buf_t buf; 9257 uint8_t *cmd; 9258 QDF_STATUS ret; 9259 9260 WMITLV_SET_HDR(cfg, 9261 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 9262 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 9263 9264 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 9265 if (!buf) { 9266 WMI_LOGE(FL("wmi_buf_alloc failed")); 9267 return QDF_STATUS_E_FAILURE; 9268 } 9269 9270 cmd = (uint8_t *) wmi_buf_data(buf); 9271 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 9272 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 9273 sizeof(*cfg)); 9274 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 9275 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 9276 if (QDF_IS_STATUS_ERROR(ret)) { 9277 WMI_LOGE(FL(":wmi cmd send failed")); 9278 wmi_buf_free(buf); 9279 } 9280 9281 return ret; 9282 } 9283 #endif 9284 9285 /** 9286 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 9287 * @wmi_handle: wmi handle 9288 * @data_len: len of dma cfg req 9289 * @data: dma cfg req 9290 * 9291 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9292 */ 9293 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9294 struct direct_buf_rx_cfg_req *cfg) 9295 { 9296 wmi_buf_t buf; 9297 wmi_dma_ring_cfg_req_fixed_param *cmd; 9298 QDF_STATUS ret; 9299 int32_t len = sizeof(*cmd); 9300 9301 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9302 if (!buf) { 9303 WMI_LOGE(FL("wmi_buf_alloc failed")); 9304 return QDF_STATUS_E_FAILURE; 9305 } 9306 9307 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 9308 9309 WMITLV_SET_HDR(&cmd->tlv_header, 9310 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 9311 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 9312 9313 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9314 cfg->pdev_id); 9315 cmd->mod_id = cfg->mod_id; 9316 cmd->base_paddr_lo = cfg->base_paddr_lo; 9317 cmd->base_paddr_hi = cfg->base_paddr_hi; 9318 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 9319 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 9320 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 9321 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 9322 cmd->num_elems = cfg->num_elems; 9323 cmd->buf_size = cfg->buf_size; 9324 cmd->num_resp_per_event = cfg->num_resp_per_event; 9325 cmd->event_timeout_ms = cfg->event_timeout_ms; 9326 9327 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 9328 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 9329 "head idx paddr hi %x tail idx paddr lo %x" 9330 "tail idx addr hi %x num elems %d buf size %d num resp %d" 9331 "event timeout %d\n", __func__, cmd->pdev_id, 9332 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 9333 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 9334 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 9335 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 9336 cmd->event_timeout_ms); 9337 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9338 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 9339 if (QDF_IS_STATUS_ERROR(ret)) { 9340 WMI_LOGE(FL(":wmi cmd send failed")); 9341 wmi_buf_free(buf); 9342 } 9343 9344 return ret; 9345 } 9346 9347 /** 9348 * send_start_11d_scan_cmd_tlv() - start 11d scan request 9349 * @wmi_handle: wmi handle 9350 * @start_11d_scan: 11d scan start request parameters 9351 * 9352 * This function request FW to start 11d scan. 9353 * 9354 * Return: QDF status 9355 */ 9356 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9357 struct reg_start_11d_scan_req *start_11d_scan) 9358 { 9359 wmi_11d_scan_start_cmd_fixed_param *cmd; 9360 int32_t len; 9361 wmi_buf_t buf; 9362 int ret; 9363 9364 len = sizeof(*cmd); 9365 buf = wmi_buf_alloc(wmi_handle, len); 9366 if (!buf) { 9367 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9368 return QDF_STATUS_E_NOMEM; 9369 } 9370 9371 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 9372 9373 WMITLV_SET_HDR(&cmd->tlv_header, 9374 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 9375 WMITLV_GET_STRUCT_TLVLEN 9376 (wmi_11d_scan_start_cmd_fixed_param)); 9377 9378 cmd->vdev_id = start_11d_scan->vdev_id; 9379 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 9380 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 9381 9382 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 9383 9384 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9385 WMI_11D_SCAN_START_CMDID); 9386 if (ret) { 9387 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 9388 wmi_buf_free(buf); 9389 return QDF_STATUS_E_FAILURE; 9390 } 9391 9392 return QDF_STATUS_SUCCESS; 9393 } 9394 9395 /** 9396 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 9397 * @wmi_handle: wmi handle 9398 * @start_11d_scan: 11d scan stop request parameters 9399 * 9400 * This function request FW to stop 11d scan. 9401 * 9402 * Return: QDF status 9403 */ 9404 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 9405 struct reg_stop_11d_scan_req *stop_11d_scan) 9406 { 9407 wmi_11d_scan_stop_cmd_fixed_param *cmd; 9408 int32_t len; 9409 wmi_buf_t buf; 9410 int ret; 9411 9412 len = sizeof(*cmd); 9413 buf = wmi_buf_alloc(wmi_handle, len); 9414 if (!buf) { 9415 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9416 return QDF_STATUS_E_NOMEM; 9417 } 9418 9419 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 9420 9421 WMITLV_SET_HDR(&cmd->tlv_header, 9422 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 9423 WMITLV_GET_STRUCT_TLVLEN 9424 (wmi_11d_scan_stop_cmd_fixed_param)); 9425 9426 cmd->vdev_id = stop_11d_scan->vdev_id; 9427 9428 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 9429 9430 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9431 WMI_11D_SCAN_STOP_CMDID); 9432 if (ret) { 9433 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 9434 wmi_buf_free(buf); 9435 return QDF_STATUS_E_FAILURE; 9436 } 9437 9438 return QDF_STATUS_SUCCESS; 9439 } 9440 9441 /** 9442 * send_start_oem_data_cmd_tlv() - start OEM data request to target 9443 * @wmi_handle: wmi handle 9444 * @startOemDataReq: start request params 9445 * 9446 * Return: CDF status 9447 */ 9448 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 9449 uint32_t data_len, 9450 uint8_t *data) 9451 { 9452 wmi_buf_t buf; 9453 uint8_t *cmd; 9454 QDF_STATUS ret; 9455 9456 buf = wmi_buf_alloc(wmi_handle, 9457 (data_len + WMI_TLV_HDR_SIZE)); 9458 if (!buf) { 9459 WMI_LOGE(FL("wmi_buf_alloc failed")); 9460 return QDF_STATUS_E_FAILURE; 9461 } 9462 9463 cmd = (uint8_t *) wmi_buf_data(buf); 9464 9465 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 9466 cmd += WMI_TLV_HDR_SIZE; 9467 qdf_mem_copy(cmd, data, 9468 data_len); 9469 9470 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 9471 data_len); 9472 9473 ret = wmi_unified_cmd_send(wmi_handle, buf, 9474 (data_len + 9475 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 9476 9477 if (QDF_IS_STATUS_ERROR(ret)) { 9478 WMI_LOGE(FL(":wmi cmd send failed")); 9479 wmi_buf_free(buf); 9480 } 9481 9482 return ret; 9483 } 9484 9485 /** 9486 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 9487 * @wmi_handle: wmi handle 9488 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 9489 * 9490 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 9491 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 9492 * to firmware based on phyerr filtering 9493 * offload status. 9494 * 9495 * Return: 1 success, 0 failure 9496 */ 9497 static QDF_STATUS 9498 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9499 bool dfs_phyerr_filter_offload) 9500 { 9501 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 9502 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 9503 wmi_buf_t buf; 9504 uint16_t len; 9505 QDF_STATUS ret; 9506 9507 9508 if (false == dfs_phyerr_filter_offload) { 9509 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 9510 __func__); 9511 len = sizeof(*disable_phyerr_offload_cmd); 9512 buf = wmi_buf_alloc(wmi_handle, len); 9513 if (!buf) { 9514 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9515 return 0; 9516 } 9517 disable_phyerr_offload_cmd = 9518 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 9519 wmi_buf_data(buf); 9520 9521 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 9522 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 9523 WMITLV_GET_STRUCT_TLVLEN 9524 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 9525 9526 /* 9527 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 9528 * to the firmware to disable the phyerror 9529 * filtering offload. 9530 */ 9531 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9532 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 9533 if (QDF_IS_STATUS_ERROR(ret)) { 9534 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 9535 __func__, ret); 9536 wmi_buf_free(buf); 9537 return QDF_STATUS_E_FAILURE; 9538 } 9539 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 9540 __func__); 9541 } else { 9542 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 9543 __func__); 9544 9545 len = sizeof(*enable_phyerr_offload_cmd); 9546 buf = wmi_buf_alloc(wmi_handle, len); 9547 if (!buf) { 9548 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9549 return QDF_STATUS_E_FAILURE; 9550 } 9551 9552 enable_phyerr_offload_cmd = 9553 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 9554 wmi_buf_data(buf); 9555 9556 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 9557 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 9558 WMITLV_GET_STRUCT_TLVLEN 9559 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 9560 9561 /* 9562 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 9563 * to the firmware to enable the phyerror 9564 * filtering offload. 9565 */ 9566 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9567 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 9568 9569 if (QDF_IS_STATUS_ERROR(ret)) { 9570 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 9571 __func__, ret); 9572 wmi_buf_free(buf); 9573 return QDF_STATUS_E_FAILURE; 9574 } 9575 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 9576 __func__); 9577 } 9578 9579 return QDF_STATUS_SUCCESS; 9580 } 9581 9582 /** 9583 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 9584 * will wake up host after specified time is elapsed 9585 * @wmi_handle: wmi handle 9586 * @vdev_id: vdev id 9587 * @cookie: value to identify reason why host set up wake call. 9588 * @time: time in ms 9589 * 9590 * Return: QDF status 9591 */ 9592 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9593 uint8_t vdev_id, uint32_t cookie, uint32_t time) 9594 { 9595 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 9596 wmi_buf_t buf; 9597 uint8_t *buf_ptr; 9598 int32_t len; 9599 int ret; 9600 9601 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 9602 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 9603 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 9604 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 9605 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 9606 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 9607 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 9608 9609 buf = wmi_buf_alloc(wmi_handle, len); 9610 if (!buf) { 9611 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9612 return QDF_STATUS_E_NOMEM; 9613 } 9614 9615 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9616 buf_ptr = (uint8_t *) cmd; 9617 9618 WMITLV_SET_HDR(&cmd->tlv_header, 9619 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 9620 WMITLV_GET_STRUCT_TLVLEN 9621 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 9622 cmd->vdev_id = vdev_id; 9623 cmd->pattern_id = cookie, 9624 cmd->pattern_type = WOW_TIMER_PATTERN; 9625 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 9626 9627 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 9628 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9629 buf_ptr += WMI_TLV_HDR_SIZE; 9630 9631 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 9632 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9633 buf_ptr += WMI_TLV_HDR_SIZE; 9634 9635 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 9636 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9637 buf_ptr += WMI_TLV_HDR_SIZE; 9638 9639 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 9640 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9641 buf_ptr += WMI_TLV_HDR_SIZE; 9642 9643 /* Fill TLV for pattern_info_timeout, and time value */ 9644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9645 buf_ptr += WMI_TLV_HDR_SIZE; 9646 *((uint32_t *) buf_ptr) = time; 9647 buf_ptr += sizeof(uint32_t); 9648 9649 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 9650 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9651 buf_ptr += WMI_TLV_HDR_SIZE; 9652 *((uint32_t *) buf_ptr) = 0; 9653 9654 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 9655 __func__, time, vdev_id); 9656 9657 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9658 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 9659 if (ret) { 9660 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 9661 __func__); 9662 wmi_buf_free(buf); 9663 return QDF_STATUS_E_FAILURE; 9664 } 9665 9666 return QDF_STATUS_SUCCESS; 9667 } 9668 9669 #if !defined(REMOVE_PKT_LOG) 9670 /** 9671 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 9672 * @wmi_handle: wmi handle 9673 * @pktlog_event: pktlog event 9674 * @cmd_id: pktlog cmd id 9675 * 9676 * Return: CDF status 9677 */ 9678 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 9679 WMI_PKTLOG_EVENT pktlog_event, 9680 WMI_CMD_ID cmd_id, uint8_t user_triggered) 9681 { 9682 WMI_PKTLOG_EVENT PKTLOG_EVENT; 9683 WMI_CMD_ID CMD_ID; 9684 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 9685 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 9686 int len = 0; 9687 wmi_buf_t buf; 9688 9689 PKTLOG_EVENT = pktlog_event; 9690 CMD_ID = cmd_id; 9691 9692 switch (CMD_ID) { 9693 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 9694 len = sizeof(*cmd); 9695 buf = wmi_buf_alloc(wmi_handle, len); 9696 if (!buf) { 9697 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9698 return QDF_STATUS_E_NOMEM; 9699 } 9700 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 9701 wmi_buf_data(buf); 9702 WMITLV_SET_HDR(&cmd->tlv_header, 9703 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9704 WMITLV_GET_STRUCT_TLVLEN 9705 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9706 cmd->evlist = PKTLOG_EVENT; 9707 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9708 : WMI_PKTLOG_ENABLE_AUTO; 9709 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9710 WMI_HOST_PDEV_ID_SOC); 9711 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9712 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9713 WMI_LOGE("failed to send pktlog enable cmdid"); 9714 goto wmi_send_failed; 9715 } 9716 break; 9717 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9718 len = sizeof(*disable_cmd); 9719 buf = wmi_buf_alloc(wmi_handle, len); 9720 if (!buf) { 9721 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9722 return QDF_STATUS_E_NOMEM; 9723 } 9724 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9725 wmi_buf_data(buf); 9726 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9727 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9728 WMITLV_GET_STRUCT_TLVLEN 9729 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9730 disable_cmd->pdev_id = 9731 wmi_handle->ops->convert_pdev_id_host_to_target( 9732 WMI_HOST_PDEV_ID_SOC); 9733 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9734 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9735 WMI_LOGE("failed to send pktlog disable cmdid"); 9736 goto wmi_send_failed; 9737 } 9738 break; 9739 default: 9740 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9741 break; 9742 } 9743 9744 return QDF_STATUS_SUCCESS; 9745 9746 wmi_send_failed: 9747 wmi_buf_free(buf); 9748 return QDF_STATUS_E_FAILURE; 9749 } 9750 #endif /* REMOVE_PKT_LOG */ 9751 9752 /** 9753 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9754 * @wmi_handle: wmi handle 9755 * @ptrn_id: pattern id 9756 * @vdev_id: vdev id 9757 * 9758 * Return: CDF status 9759 */ 9760 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9761 uint8_t ptrn_id, uint8_t vdev_id) 9762 { 9763 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9764 wmi_buf_t buf; 9765 int32_t len; 9766 int ret; 9767 9768 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9769 9770 9771 buf = wmi_buf_alloc(wmi_handle, len); 9772 if (!buf) { 9773 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9774 return QDF_STATUS_E_NOMEM; 9775 } 9776 9777 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9778 9779 WMITLV_SET_HDR(&cmd->tlv_header, 9780 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9781 WMITLV_GET_STRUCT_TLVLEN( 9782 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9783 cmd->vdev_id = vdev_id; 9784 cmd->pattern_id = ptrn_id; 9785 cmd->pattern_type = WOW_BITMAP_PATTERN; 9786 9787 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9788 cmd->pattern_id, vdev_id); 9789 9790 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9791 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9792 if (ret) { 9793 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9794 wmi_buf_free(buf); 9795 return QDF_STATUS_E_FAILURE; 9796 } 9797 9798 return QDF_STATUS_SUCCESS; 9799 } 9800 9801 /** 9802 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9803 * @wmi_handle: wmi handle 9804 * 9805 * Sends host wakeup indication to FW. On receiving this indication, 9806 * FW will come out of WOW. 9807 * 9808 * Return: CDF status 9809 */ 9810 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9811 { 9812 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9813 wmi_buf_t buf; 9814 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9815 int32_t len; 9816 int ret; 9817 9818 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9819 9820 buf = wmi_buf_alloc(wmi_handle, len); 9821 if (!buf) { 9822 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9823 return QDF_STATUS_E_NOMEM; 9824 } 9825 9826 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9827 wmi_buf_data(buf); 9828 WMITLV_SET_HDR(&cmd->tlv_header, 9829 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9830 WMITLV_GET_STRUCT_TLVLEN 9831 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9832 9833 9834 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9835 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9836 if (ret) { 9837 WMI_LOGE("Failed to send host wakeup indication to fw"); 9838 wmi_buf_free(buf); 9839 return QDF_STATUS_E_FAILURE; 9840 } 9841 9842 return qdf_status; 9843 } 9844 9845 /** 9846 * send_del_ts_cmd_tlv() - send DELTS request to fw 9847 * @wmi_handle: wmi handle 9848 * @msg: delts params 9849 * 9850 * Return: CDF status 9851 */ 9852 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9853 uint8_t ac) 9854 { 9855 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9856 wmi_buf_t buf; 9857 int32_t len = sizeof(*cmd); 9858 9859 buf = wmi_buf_alloc(wmi_handle, len); 9860 if (!buf) { 9861 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9862 return QDF_STATUS_E_NOMEM; 9863 } 9864 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9865 WMITLV_SET_HDR(&cmd->tlv_header, 9866 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9867 WMITLV_GET_STRUCT_TLVLEN 9868 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9869 cmd->vdev_id = vdev_id; 9870 cmd->ac = ac; 9871 9872 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9873 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9874 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9875 WMI_VDEV_WMM_DELTS_CMDID)) { 9876 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9877 wmi_buf_free(buf); 9878 return QDF_STATUS_E_FAILURE; 9879 } 9880 9881 return QDF_STATUS_SUCCESS; 9882 } 9883 9884 /** 9885 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9886 * @wmi_handle: handle to wmi 9887 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9888 * 9889 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9890 * ADD_TS requestes to firmware in loop for all the ACs with 9891 * active flow. 9892 * 9893 * Return: CDF status 9894 */ 9895 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9896 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9897 { 9898 int i = 0; 9899 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9900 wmi_buf_t buf; 9901 int32_t len = sizeof(*cmd); 9902 9903 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9904 /* if flow in this AC is active */ 9905 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9906 /* 9907 * as per implementation of wma_add_ts_req() we 9908 * are not waiting any response from firmware so 9909 * apart from sending ADDTS to firmware just send 9910 * success to upper layers 9911 */ 9912 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9913 9914 buf = wmi_buf_alloc(wmi_handle, len); 9915 if (!buf) { 9916 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9917 return QDF_STATUS_E_NOMEM; 9918 } 9919 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9920 wmi_buf_data(buf); 9921 WMITLV_SET_HDR(&cmd->tlv_header, 9922 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9923 WMITLV_GET_STRUCT_TLVLEN 9924 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9925 cmd->vdev_id = aggr_qos_rsp_msg->sessionId; 9926 cmd->ac = 9927 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9928 traffic.userPrio); 9929 cmd->medium_time_us = 9930 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9931 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9932 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9933 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9934 cmd->medium_time_us, cmd->downgrade_type); 9935 if (wmi_unified_cmd_send 9936 (wmi_handle, buf, len, 9937 WMI_VDEV_WMM_ADDTS_CMDID)) { 9938 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9939 __func__); 9940 aggr_qos_rsp_msg->status[i] = 9941 QDF_STATUS_E_FAILURE; 9942 wmi_buf_free(buf); 9943 return QDF_STATUS_E_FAILURE; 9944 } 9945 } 9946 } 9947 9948 return QDF_STATUS_SUCCESS; 9949 } 9950 9951 /** 9952 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9953 * @wmi_handle: wmi handle 9954 * @msg: ADDTS params 9955 * 9956 * Return: CDF status 9957 */ 9958 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9959 struct add_ts_param *msg) 9960 { 9961 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9962 wmi_buf_t buf; 9963 int32_t len = sizeof(*cmd); 9964 9965 msg->status = QDF_STATUS_SUCCESS; 9966 9967 buf = wmi_buf_alloc(wmi_handle, len); 9968 if (!buf) { 9969 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9970 return QDF_STATUS_E_NOMEM; 9971 } 9972 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9973 WMITLV_SET_HDR(&cmd->tlv_header, 9974 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9975 WMITLV_GET_STRUCT_TLVLEN 9976 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9977 cmd->vdev_id = msg->sme_session_id; 9978 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9979 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9980 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9981 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9982 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9983 cmd->downgrade_type, __func__, __LINE__); 9984 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9985 WMI_VDEV_WMM_ADDTS_CMDID)) { 9986 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9987 msg->status = QDF_STATUS_E_FAILURE; 9988 wmi_buf_free(buf); 9989 return QDF_STATUS_E_FAILURE; 9990 } 9991 9992 return QDF_STATUS_SUCCESS; 9993 } 9994 9995 /** 9996 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 9997 * @wmi_handle: wmi handle 9998 * @pAddPeriodicTxPtrnParams: tx ptrn params 9999 * 10000 * Retrun: CDF status 10001 */ 10002 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10003 struct periodic_tx_pattern * 10004 pAddPeriodicTxPtrnParams, 10005 uint8_t vdev_id) 10006 { 10007 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10008 wmi_buf_t wmi_buf; 10009 uint32_t len; 10010 uint8_t *buf_ptr; 10011 uint32_t ptrn_len, ptrn_len_aligned; 10012 int j; 10013 10014 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 10015 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 10016 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 10017 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 10018 10019 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10020 if (!wmi_buf) { 10021 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10022 return QDF_STATUS_E_NOMEM; 10023 } 10024 10025 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10026 10027 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 10028 WMITLV_SET_HDR(&cmd->tlv_header, 10029 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10030 WMITLV_GET_STRUCT_TLVLEN 10031 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10032 10033 /* Pass the pattern id to delete for the corresponding vdev id */ 10034 cmd->vdev_id = vdev_id; 10035 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 10036 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 10037 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 10038 10039 /* Pattern info */ 10040 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10041 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 10042 buf_ptr += WMI_TLV_HDR_SIZE; 10043 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 10044 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 10045 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 10046 10047 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 10048 __func__, cmd->pattern_id, cmd->vdev_id); 10049 10050 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10051 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10052 WMI_LOGE("%s: failed to add pattern set state command", 10053 __func__); 10054 wmi_buf_free(wmi_buf); 10055 return QDF_STATUS_E_FAILURE; 10056 } 10057 return QDF_STATUS_SUCCESS; 10058 } 10059 10060 /** 10061 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 10062 * @wmi_handle: wmi handle 10063 * @vdev_id: vdev id 10064 * @pattern_id: pattern id 10065 * 10066 * Retrun: CDF status 10067 */ 10068 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 10069 uint8_t vdev_id, 10070 uint8_t pattern_id) 10071 { 10072 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 10073 wmi_buf_t wmi_buf; 10074 uint32_t len = 10075 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 10076 10077 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10078 if (!wmi_buf) { 10079 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10080 return QDF_STATUS_E_NOMEM; 10081 } 10082 10083 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 10084 wmi_buf_data(wmi_buf); 10085 WMITLV_SET_HDR(&cmd->tlv_header, 10086 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 10087 WMITLV_GET_STRUCT_TLVLEN 10088 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 10089 10090 /* Pass the pattern id to delete for the corresponding vdev id */ 10091 cmd->vdev_id = vdev_id; 10092 cmd->pattern_id = pattern_id; 10093 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 10094 __func__, cmd->pattern_id, cmd->vdev_id); 10095 10096 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10097 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 10098 WMI_LOGE("%s: failed to send del pattern command", __func__); 10099 wmi_buf_free(wmi_buf); 10100 return QDF_STATUS_E_FAILURE; 10101 } 10102 return QDF_STATUS_SUCCESS; 10103 } 10104 10105 /** 10106 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 10107 * @wmi_handle: wmi handle 10108 * @preq: stats ext params 10109 * 10110 * Return: CDF status 10111 */ 10112 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 10113 struct stats_ext_params *preq) 10114 { 10115 QDF_STATUS ret; 10116 wmi_req_stats_ext_cmd_fixed_param *cmd; 10117 wmi_buf_t buf; 10118 uint16_t len; 10119 uint8_t *buf_ptr; 10120 10121 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 10122 10123 buf = wmi_buf_alloc(wmi_handle, len); 10124 if (!buf) { 10125 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10126 return QDF_STATUS_E_NOMEM; 10127 } 10128 10129 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10130 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 10131 10132 WMITLV_SET_HDR(&cmd->tlv_header, 10133 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 10134 WMITLV_GET_STRUCT_TLVLEN 10135 (wmi_req_stats_ext_cmd_fixed_param)); 10136 cmd->vdev_id = preq->vdev_id; 10137 cmd->data_len = preq->request_data_len; 10138 10139 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 10140 __func__, preq->request_data_len, preq->vdev_id); 10141 10142 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 10143 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 10144 10145 buf_ptr += WMI_TLV_HDR_SIZE; 10146 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 10147 10148 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10149 WMI_REQUEST_STATS_EXT_CMDID); 10150 if (QDF_IS_STATUS_ERROR(ret)) { 10151 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 10152 ret); 10153 wmi_buf_free(buf); 10154 } 10155 10156 return ret; 10157 } 10158 10159 /** 10160 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 10161 * @wmi_handle: wmi handle 10162 * @params: ext wow params 10163 * 10164 * Return:0 for success or error code 10165 */ 10166 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 10167 struct ext_wow_params *params) 10168 { 10169 wmi_extwow_enable_cmd_fixed_param *cmd; 10170 wmi_buf_t buf; 10171 int32_t len; 10172 int ret; 10173 10174 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 10175 buf = wmi_buf_alloc(wmi_handle, len); 10176 if (!buf) { 10177 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10178 return QDF_STATUS_E_NOMEM; 10179 } 10180 10181 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 10182 10183 WMITLV_SET_HDR(&cmd->tlv_header, 10184 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 10185 WMITLV_GET_STRUCT_TLVLEN 10186 (wmi_extwow_enable_cmd_fixed_param)); 10187 10188 cmd->vdev_id = params->vdev_id; 10189 cmd->type = params->type; 10190 cmd->wakeup_pin_num = params->wakeup_pin_num; 10191 10192 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 10193 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 10194 10195 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10196 WMI_EXTWOW_ENABLE_CMDID); 10197 if (ret) { 10198 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 10199 wmi_buf_free(buf); 10200 return QDF_STATUS_E_FAILURE; 10201 } 10202 10203 return QDF_STATUS_SUCCESS; 10204 10205 } 10206 10207 /** 10208 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 10209 * @wmi_handle: wmi handle 10210 * @app_type1_params: app type1 params 10211 * 10212 * Return: CDF status 10213 */ 10214 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10215 struct app_type1_params *app_type1_params) 10216 { 10217 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 10218 wmi_buf_t buf; 10219 int32_t len; 10220 int ret; 10221 10222 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 10223 buf = wmi_buf_alloc(wmi_handle, len); 10224 if (!buf) { 10225 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10226 return QDF_STATUS_E_NOMEM; 10227 } 10228 10229 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 10230 wmi_buf_data(buf); 10231 10232 WMITLV_SET_HDR(&cmd->tlv_header, 10233 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 10234 WMITLV_GET_STRUCT_TLVLEN 10235 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 10236 10237 cmd->vdev_id = app_type1_params->vdev_id; 10238 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 10239 &cmd->wakee_mac); 10240 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 10241 cmd->ident_len = app_type1_params->id_length; 10242 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 10243 cmd->passwd_len = app_type1_params->pass_length; 10244 10245 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 10246 "identification_id %.8s id_length %u " 10247 "password %.16s pass_length %u", 10248 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 10249 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 10250 10251 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10252 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 10253 if (ret) { 10254 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 10255 wmi_buf_free(buf); 10256 return QDF_STATUS_E_FAILURE; 10257 } 10258 10259 return QDF_STATUS_SUCCESS; 10260 } 10261 10262 /** 10263 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 10264 * @wmi_handle: wmi handle 10265 * @appType2Params: app type2 params 10266 * 10267 * Return: CDF status 10268 */ 10269 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 10270 struct app_type2_params *appType2Params) 10271 { 10272 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 10273 wmi_buf_t buf; 10274 int32_t len; 10275 int ret; 10276 10277 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 10278 buf = wmi_buf_alloc(wmi_handle, len); 10279 if (!buf) { 10280 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 10281 return QDF_STATUS_E_NOMEM; 10282 } 10283 10284 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 10285 wmi_buf_data(buf); 10286 10287 WMITLV_SET_HDR(&cmd->tlv_header, 10288 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 10289 WMITLV_GET_STRUCT_TLVLEN 10290 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 10291 10292 cmd->vdev_id = appType2Params->vdev_id; 10293 10294 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 10295 cmd->rc4_key_len = appType2Params->rc4_key_len; 10296 10297 cmd->ip_id = appType2Params->ip_id; 10298 cmd->ip_device_ip = appType2Params->ip_device_ip; 10299 cmd->ip_server_ip = appType2Params->ip_server_ip; 10300 10301 cmd->tcp_src_port = appType2Params->tcp_src_port; 10302 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 10303 cmd->tcp_seq = appType2Params->tcp_seq; 10304 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 10305 10306 cmd->keepalive_init = appType2Params->keepalive_init; 10307 cmd->keepalive_min = appType2Params->keepalive_min; 10308 cmd->keepalive_max = appType2Params->keepalive_max; 10309 cmd->keepalive_inc = appType2Params->keepalive_inc; 10310 10311 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 10312 &cmd->gateway_mac); 10313 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 10314 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 10315 10316 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 10317 "rc4_key %.16s rc4_key_len %u " 10318 "ip_id %x ip_device_ip %x ip_server_ip %x " 10319 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 10320 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 10321 "keepalive_max %u keepalive_inc %u " 10322 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 10323 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 10324 cmd->rc4_key, cmd->rc4_key_len, 10325 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 10326 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 10327 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 10328 cmd->keepalive_max, cmd->keepalive_inc, 10329 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 10330 10331 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10332 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 10333 if (ret) { 10334 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 10335 wmi_buf_free(buf); 10336 return QDF_STATUS_E_FAILURE; 10337 } 10338 10339 return QDF_STATUS_SUCCESS; 10340 10341 } 10342 10343 /** 10344 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 10345 * @wmi_handle: wmi handle 10346 * @timer_val: auto shutdown timer value 10347 * 10348 * Return: CDF status 10349 */ 10350 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 10351 uint32_t timer_val) 10352 { 10353 QDF_STATUS status; 10354 wmi_buf_t buf = NULL; 10355 uint8_t *buf_ptr; 10356 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 10357 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 10358 10359 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 10360 __func__, timer_val); 10361 10362 buf = wmi_buf_alloc(wmi_handle, len); 10363 if (!buf) { 10364 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10365 return QDF_STATUS_E_NOMEM; 10366 } 10367 10368 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10369 wmi_auto_sh_cmd = 10370 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 10371 wmi_auto_sh_cmd->timer_value = timer_val; 10372 10373 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 10374 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 10375 WMITLV_GET_STRUCT_TLVLEN 10376 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 10377 10378 status = wmi_unified_cmd_send(wmi_handle, buf, 10379 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 10380 if (QDF_IS_STATUS_ERROR(status)) { 10381 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 10382 __func__, status); 10383 wmi_buf_free(buf); 10384 } 10385 10386 return status; 10387 } 10388 10389 /** 10390 * send_nan_req_cmd_tlv() - to send nan request to target 10391 * @wmi_handle: wmi handle 10392 * @nan_req: request data which will be non-null 10393 * 10394 * Return: CDF status 10395 */ 10396 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 10397 struct nan_req_params *nan_req) 10398 { 10399 QDF_STATUS ret; 10400 wmi_nan_cmd_param *cmd; 10401 wmi_buf_t buf; 10402 uint16_t len = sizeof(*cmd); 10403 uint16_t nan_data_len, nan_data_len_aligned; 10404 uint8_t *buf_ptr; 10405 10406 /* 10407 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 10408 * +------------+----------+-----------------------+--------------+ 10409 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 10410 * +------------+----------+-----------------------+--------------+ 10411 */ 10412 if (!nan_req) { 10413 WMI_LOGE("%s:nan req is not valid", __func__); 10414 return QDF_STATUS_E_FAILURE; 10415 } 10416 nan_data_len = nan_req->request_data_len; 10417 nan_data_len_aligned = roundup(nan_req->request_data_len, 10418 sizeof(uint32_t)); 10419 if (nan_data_len_aligned < nan_req->request_data_len) { 10420 WMI_LOGE("%s: integer overflow while rounding up data_len", 10421 __func__); 10422 return QDF_STATUS_E_FAILURE; 10423 } 10424 10425 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 10426 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 10427 __func__); 10428 return QDF_STATUS_E_FAILURE; 10429 } 10430 10431 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 10432 buf = wmi_buf_alloc(wmi_handle, len); 10433 if (!buf) { 10434 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 10435 return QDF_STATUS_E_NOMEM; 10436 } 10437 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10438 cmd = (wmi_nan_cmd_param *) buf_ptr; 10439 WMITLV_SET_HDR(&cmd->tlv_header, 10440 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 10441 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 10442 cmd->data_len = nan_req->request_data_len; 10443 WMI_LOGD("%s: The data len value is %u", 10444 __func__, nan_req->request_data_len); 10445 buf_ptr += sizeof(wmi_nan_cmd_param); 10446 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 10447 buf_ptr += WMI_TLV_HDR_SIZE; 10448 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 10449 10450 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10451 WMI_NAN_CMDID); 10452 if (QDF_IS_STATUS_ERROR(ret)) { 10453 WMI_LOGE("%s Failed to send set param command ret = %d", 10454 __func__, ret); 10455 wmi_buf_free(buf); 10456 } 10457 10458 return ret; 10459 } 10460 10461 /** 10462 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 10463 * @wmi_handle: wmi handle 10464 * @params: DHCP server offload info 10465 * 10466 * Return: QDF_STATUS_SUCCESS for success or error code 10467 */ 10468 static QDF_STATUS 10469 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 10470 struct dhcp_offload_info_params *params) 10471 { 10472 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 10473 wmi_buf_t buf; 10474 QDF_STATUS status; 10475 10476 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 10477 if (!buf) { 10478 WMI_LOGE("Failed to allocate buffer to send " 10479 "set_dhcp_server_offload cmd"); 10480 return QDF_STATUS_E_NOMEM; 10481 } 10482 10483 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 10484 10485 WMITLV_SET_HDR(&cmd->tlv_header, 10486 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 10487 WMITLV_GET_STRUCT_TLVLEN 10488 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 10489 cmd->vdev_id = params->vdev_id; 10490 cmd->enable = params->dhcp_offload_enabled; 10491 cmd->num_client = params->dhcp_client_num; 10492 cmd->srv_ipv4 = params->dhcp_srv_addr; 10493 cmd->start_lsb = 0; 10494 status = wmi_unified_cmd_send(wmi_handle, buf, 10495 sizeof(*cmd), 10496 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 10497 if (QDF_IS_STATUS_ERROR(status)) { 10498 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 10499 wmi_buf_free(buf); 10500 return QDF_STATUS_E_FAILURE; 10501 } 10502 WMI_LOGD("Set dhcp server offload to vdevId %d", 10503 params->vdev_id); 10504 10505 return status; 10506 } 10507 10508 /** 10509 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 10510 * @wmi_handle: wmi handle 10511 * @flashing: flashing request 10512 * 10513 * Return: CDF status 10514 */ 10515 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 10516 struct flashing_req_params *flashing) 10517 { 10518 wmi_set_led_flashing_cmd_fixed_param *cmd; 10519 QDF_STATUS status; 10520 wmi_buf_t buf; 10521 uint8_t *buf_ptr; 10522 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 10523 10524 buf = wmi_buf_alloc(wmi_handle, len); 10525 if (!buf) { 10526 WMI_LOGP(FL("wmi_buf_alloc failed")); 10527 return QDF_STATUS_E_NOMEM; 10528 } 10529 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10530 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 10531 WMITLV_SET_HDR(&cmd->tlv_header, 10532 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 10533 WMITLV_GET_STRUCT_TLVLEN 10534 (wmi_set_led_flashing_cmd_fixed_param)); 10535 cmd->pattern_id = flashing->pattern_id; 10536 cmd->led_x0 = flashing->led_x0; 10537 cmd->led_x1 = flashing->led_x1; 10538 10539 status = wmi_unified_cmd_send(wmi_handle, buf, len, 10540 WMI_PDEV_SET_LED_FLASHING_CMDID); 10541 if (QDF_IS_STATUS_ERROR(status)) { 10542 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 10543 " returned Error %d", __func__, status); 10544 wmi_buf_free(buf); 10545 } 10546 10547 return status; 10548 } 10549 10550 /** 10551 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 10552 * @wmi_handle: wmi handle 10553 * @ch_avoid_update_req: channel avoid update params 10554 * 10555 * Return: CDF status 10556 */ 10557 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 10558 { 10559 QDF_STATUS status; 10560 wmi_buf_t buf = NULL; 10561 uint8_t *buf_ptr; 10562 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 10563 int len = sizeof(wmi_chan_avoid_update_cmd_param); 10564 10565 10566 buf = wmi_buf_alloc(wmi_handle, len); 10567 if (!buf) { 10568 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10569 return QDF_STATUS_E_NOMEM; 10570 } 10571 10572 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10573 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 10574 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 10575 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 10576 WMITLV_GET_STRUCT_TLVLEN 10577 (wmi_chan_avoid_update_cmd_param)); 10578 10579 status = wmi_unified_cmd_send(wmi_handle, buf, 10580 len, WMI_CHAN_AVOID_UPDATE_CMDID); 10581 if (QDF_IS_STATUS_ERROR(status)) { 10582 WMI_LOGE("wmi_unified_cmd_send" 10583 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 10584 " returned Error %d", status); 10585 wmi_buf_free(buf); 10586 } 10587 10588 return status; 10589 } 10590 10591 /** 10592 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 10593 * @wmi_handle: wmi handle 10594 * @param: pointer to pdev regdomain params 10595 * 10596 * Return: 0 for success or error code 10597 */ 10598 static QDF_STATUS 10599 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 10600 struct pdev_set_regdomain_params *param) 10601 { 10602 wmi_buf_t buf; 10603 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10604 int32_t len = sizeof(*cmd); 10605 10606 10607 buf = wmi_buf_alloc(wmi_handle, len); 10608 if (!buf) { 10609 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10610 return QDF_STATUS_E_NOMEM; 10611 } 10612 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10613 WMITLV_SET_HDR(&cmd->tlv_header, 10614 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10615 WMITLV_GET_STRUCT_TLVLEN 10616 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10617 10618 cmd->reg_domain = param->currentRDinuse; 10619 cmd->reg_domain_2G = param->currentRD2G; 10620 cmd->reg_domain_5G = param->currentRD5G; 10621 cmd->conformance_test_limit_2G = param->ctl_2G; 10622 cmd->conformance_test_limit_5G = param->ctl_5G; 10623 cmd->dfs_domain = param->dfsDomain; 10624 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10625 param->pdev_id); 10626 10627 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10628 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10629 WMI_LOGE("%s: Failed to send pdev set regdomain command", 10630 __func__); 10631 wmi_buf_free(buf); 10632 return QDF_STATUS_E_FAILURE; 10633 } 10634 10635 return QDF_STATUS_SUCCESS; 10636 } 10637 10638 /** 10639 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 10640 * @wmi_handle: wmi handle 10641 * @reg_dmn: reg domain 10642 * @regdmn2G: 2G reg domain 10643 * @regdmn5G: 5G reg domain 10644 * @ctl2G: 2G test limit 10645 * @ctl5G: 5G test limit 10646 * 10647 * Return: none 10648 */ 10649 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 10650 uint32_t reg_dmn, uint16_t regdmn2G, 10651 uint16_t regdmn5G, uint8_t ctl2G, 10652 uint8_t ctl5G) 10653 { 10654 wmi_buf_t buf; 10655 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10656 int32_t len = sizeof(*cmd); 10657 10658 10659 buf = wmi_buf_alloc(wmi_handle, len); 10660 if (!buf) { 10661 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10662 return QDF_STATUS_E_NOMEM; 10663 } 10664 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10665 WMITLV_SET_HDR(&cmd->tlv_header, 10666 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10667 WMITLV_GET_STRUCT_TLVLEN 10668 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10669 cmd->reg_domain = reg_dmn; 10670 cmd->reg_domain_2G = regdmn2G; 10671 cmd->reg_domain_5G = regdmn5G; 10672 cmd->conformance_test_limit_2G = ctl2G; 10673 cmd->conformance_test_limit_5G = ctl5G; 10674 10675 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10676 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10677 WMI_LOGP("%s: Failed to send pdev set regdomain command", 10678 __func__); 10679 wmi_buf_free(buf); 10680 return QDF_STATUS_E_FAILURE; 10681 } 10682 10683 return QDF_STATUS_SUCCESS; 10684 } 10685 10686 10687 /** 10688 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 10689 * @wmi_handle: wmi handle 10690 * @chan_switch_params: Pointer to tdls channel switch parameter structure 10691 * 10692 * This function sets tdls off channel mode 10693 * 10694 * Return: 0 on success; Negative errno otherwise 10695 */ 10696 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 10697 struct tdls_channel_switch_params *chan_switch_params) 10698 { 10699 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 10700 wmi_buf_t wmi_buf; 10701 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10702 10703 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10704 if (!wmi_buf) { 10705 WMI_LOGE(FL("wmi_buf_alloc failed")); 10706 return QDF_STATUS_E_FAILURE; 10707 } 10708 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10709 wmi_buf_data(wmi_buf); 10710 WMITLV_SET_HDR(&cmd->tlv_header, 10711 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10712 WMITLV_GET_STRUCT_TLVLEN( 10713 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10714 10715 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10716 &cmd->peer_macaddr); 10717 cmd->vdev_id = chan_switch_params->vdev_id; 10718 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 10719 cmd->is_peer_responder = chan_switch_params->is_responder; 10720 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10721 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10722 cmd->offchan_oper_class = chan_switch_params->oper_class; 10723 10724 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10725 cmd->peer_macaddr.mac_addr31to0, 10726 cmd->peer_macaddr.mac_addr47to32); 10727 10728 WMI_LOGD(FL( 10729 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10730 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10731 ), 10732 cmd->vdev_id, 10733 cmd->offchan_mode, 10734 cmd->offchan_num, 10735 cmd->offchan_bw_bitmap, 10736 cmd->is_peer_responder, 10737 cmd->offchan_oper_class); 10738 10739 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10740 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10741 WMI_LOGP(FL("failed to send tdls off chan command")); 10742 wmi_buf_free(wmi_buf); 10743 return QDF_STATUS_E_FAILURE; 10744 } 10745 10746 10747 return QDF_STATUS_SUCCESS; 10748 } 10749 10750 /** 10751 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10752 * @wmi_handle: wmi handle 10753 * @pwmaTdlsparams: TDLS params 10754 * 10755 * Return: 0 for success or error code 10756 */ 10757 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10758 void *tdls_param, uint8_t tdls_state) 10759 { 10760 wmi_tdls_set_state_cmd_fixed_param *cmd; 10761 wmi_buf_t wmi_buf; 10762 10763 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10764 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10765 10766 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10767 if (!wmi_buf) { 10768 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10769 return QDF_STATUS_E_FAILURE; 10770 } 10771 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10772 WMITLV_SET_HDR(&cmd->tlv_header, 10773 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10774 WMITLV_GET_STRUCT_TLVLEN 10775 (wmi_tdls_set_state_cmd_fixed_param)); 10776 cmd->vdev_id = wmi_tdls->vdev_id; 10777 cmd->state = tdls_state; 10778 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10779 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10780 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10781 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10782 cmd->rssi_delta = wmi_tdls->rssi_delta; 10783 cmd->tdls_options = wmi_tdls->tdls_options; 10784 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10785 cmd->tdls_peer_traffic_response_timeout_ms = 10786 wmi_tdls->peer_traffic_response_timeout; 10787 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10788 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10789 cmd->tdls_puapsd_rx_frame_threshold = 10790 wmi_tdls->puapsd_rx_frame_threshold; 10791 cmd->teardown_notification_ms = 10792 wmi_tdls->teardown_notification_ms; 10793 cmd->tdls_peer_kickout_threshold = 10794 wmi_tdls->tdls_peer_kickout_threshold; 10795 10796 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10797 "notification_interval_ms: %d, " 10798 "tx_discovery_threshold: %d, " 10799 "tx_teardown_threshold: %d, " 10800 "rssi_teardown_threshold: %d, " 10801 "rssi_delta: %d, " 10802 "tdls_options: 0x%x, " 10803 "tdls_peer_traffic_ind_window: %d, " 10804 "tdls_peer_traffic_response_timeout: %d, " 10805 "tdls_puapsd_mask: 0x%x, " 10806 "tdls_puapsd_inactivity_time: %d, " 10807 "tdls_puapsd_rx_frame_threshold: %d, " 10808 "teardown_notification_ms: %d, " 10809 "tdls_peer_kickout_threshold: %d", 10810 __func__, tdls_state, cmd->state, 10811 cmd->notification_interval_ms, 10812 cmd->tx_discovery_threshold, 10813 cmd->tx_teardown_threshold, 10814 cmd->rssi_teardown_threshold, 10815 cmd->rssi_delta, 10816 cmd->tdls_options, 10817 cmd->tdls_peer_traffic_ind_window, 10818 cmd->tdls_peer_traffic_response_timeout_ms, 10819 cmd->tdls_puapsd_mask, 10820 cmd->tdls_puapsd_inactivity_time_ms, 10821 cmd->tdls_puapsd_rx_frame_threshold, 10822 cmd->teardown_notification_ms, 10823 cmd->tdls_peer_kickout_threshold); 10824 10825 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10826 WMI_TDLS_SET_STATE_CMDID)) { 10827 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10828 wmi_buf_free(wmi_buf); 10829 return QDF_STATUS_E_FAILURE; 10830 } 10831 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10832 10833 return QDF_STATUS_SUCCESS; 10834 } 10835 10836 /** 10837 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10838 * @wmi_handle: wmi handle 10839 * @peerStateParams: TDLS peer state params 10840 * 10841 * Return: QDF_STATUS_SUCCESS for success or error code 10842 */ 10843 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10844 struct tdls_peer_state_params *peerStateParams, 10845 uint32_t *ch_mhz) 10846 { 10847 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10848 wmi_tdls_peer_capabilities *peer_cap; 10849 wmi_channel *chan_info; 10850 wmi_buf_t wmi_buf; 10851 uint8_t *buf_ptr; 10852 uint32_t i; 10853 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10854 sizeof(wmi_tdls_peer_capabilities); 10855 10856 10857 len += WMI_TLV_HDR_SIZE + 10858 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10859 10860 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10861 if (!wmi_buf) { 10862 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10863 return QDF_STATUS_E_FAILURE; 10864 } 10865 10866 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10867 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10868 WMITLV_SET_HDR(&cmd->tlv_header, 10869 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10870 WMITLV_GET_STRUCT_TLVLEN 10871 (wmi_tdls_peer_update_cmd_fixed_param)); 10872 10873 cmd->vdev_id = peerStateParams->vdevId; 10874 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10875 &cmd->peer_macaddr); 10876 10877 10878 cmd->peer_state = peerStateParams->peerState; 10879 10880 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10881 "peer_macaddr.mac_addr31to0: 0x%x, " 10882 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10883 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10884 cmd->peer_macaddr.mac_addr31to0, 10885 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10886 10887 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10888 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10889 WMITLV_SET_HDR(&peer_cap->tlv_header, 10890 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10891 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10892 10893 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10894 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10895 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10896 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10897 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10898 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10899 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10900 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10901 10902 /* Ack and More Data Ack are sent as 0, so no need to set 10903 * but fill SP 10904 */ 10905 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10906 peerStateParams->peerCap.peerMaxSp); 10907 10908 peer_cap->buff_sta_support = 10909 peerStateParams->peerCap.peerBuffStaSupport; 10910 peer_cap->off_chan_support = 10911 peerStateParams->peerCap.peerOffChanSupport; 10912 peer_cap->peer_curr_operclass = 10913 peerStateParams->peerCap.peerCurrOperClass; 10914 /* self curr operclass is not being used and so pass op class for 10915 * preferred off chan in it. 10916 */ 10917 peer_cap->self_curr_operclass = 10918 peerStateParams->peerCap.opClassForPrefOffChan; 10919 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10920 peer_cap->peer_operclass_len = 10921 peerStateParams->peerCap.peerOperClassLen; 10922 10923 WMI_LOGD("%s: peer_operclass_len: %d", 10924 __func__, peer_cap->peer_operclass_len); 10925 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10926 peer_cap->peer_operclass[i] = 10927 peerStateParams->peerCap.peerOperClass[i]; 10928 WMI_LOGD("%s: peer_operclass[%d]: %d", 10929 __func__, i, peer_cap->peer_operclass[i]); 10930 } 10931 10932 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10933 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10934 peer_cap->pref_offchan_bw = 10935 peerStateParams->peerCap.prefOffChanBandwidth; 10936 10937 WMI_LOGD 10938 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10939 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10940 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10941 " %d, pref_offchan_bw: %d", 10942 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10943 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10944 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10945 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10946 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10947 10948 /* next fill variable size array of peer chan info */ 10949 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10950 WMITLV_SET_HDR(buf_ptr, 10951 WMITLV_TAG_ARRAY_STRUC, 10952 sizeof(wmi_channel) * 10953 peerStateParams->peerCap.peerChanLen); 10954 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10955 10956 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10957 WMITLV_SET_HDR(&chan_info->tlv_header, 10958 WMITLV_TAG_STRUC_wmi_channel, 10959 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10960 chan_info->mhz = ch_mhz[i]; 10961 chan_info->band_center_freq1 = chan_info->mhz; 10962 chan_info->band_center_freq2 = 0; 10963 10964 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10965 10966 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10967 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10968 WMI_LOGI("chan[%d] DFS[%d]\n", 10969 peerStateParams->peerCap.peerChan[i].chanId, 10970 peerStateParams->peerCap.peerChan[i].dfsSet); 10971 } 10972 10973 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10974 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10975 else 10976 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10977 10978 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10979 peerStateParams->peerCap. 10980 peerChan[i].pwr); 10981 10982 WMI_SET_CHANNEL_REG_POWER(chan_info, 10983 peerStateParams->peerCap.peerChan[i]. 10984 pwr); 10985 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10986 peerStateParams->peerCap.peerChan[i].pwr); 10987 10988 chan_info++; 10989 } 10990 10991 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10992 WMI_TDLS_PEER_UPDATE_CMDID)) { 10993 WMI_LOGE("%s: failed to send tdls peer update state command", 10994 __func__); 10995 wmi_buf_free(wmi_buf); 10996 return QDF_STATUS_E_FAILURE; 10997 } 10998 10999 11000 return QDF_STATUS_SUCCESS; 11001 } 11002 11003 /* 11004 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 11005 * @wmi_handle: Pointer to WMi handle 11006 * @ie_data: Pointer for ie data 11007 * 11008 * This function sends IE information to firmware 11009 * 11010 * Return: QDF_STATUS_SUCCESS for success otherwise failure 11011 * 11012 */ 11013 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 11014 struct vdev_ie_info_param *ie_info) 11015 { 11016 wmi_vdev_set_ie_cmd_fixed_param *cmd; 11017 wmi_buf_t buf; 11018 uint8_t *buf_ptr; 11019 uint32_t len, ie_len_aligned; 11020 QDF_STATUS ret; 11021 11022 11023 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 11024 /* Allocate memory for the WMI command */ 11025 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 11026 11027 buf = wmi_buf_alloc(wmi_handle, len); 11028 if (!buf) { 11029 WMI_LOGE(FL("wmi_buf_alloc failed")); 11030 return QDF_STATUS_E_NOMEM; 11031 } 11032 11033 buf_ptr = wmi_buf_data(buf); 11034 qdf_mem_zero(buf_ptr, len); 11035 11036 /* Populate the WMI command */ 11037 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 11038 11039 WMITLV_SET_HDR(&cmd->tlv_header, 11040 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 11041 WMITLV_GET_STRUCT_TLVLEN( 11042 wmi_vdev_set_ie_cmd_fixed_param)); 11043 cmd->vdev_id = ie_info->vdev_id; 11044 cmd->ie_id = ie_info->ie_id; 11045 cmd->ie_len = ie_info->length; 11046 cmd->band = ie_info->band; 11047 11048 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 11049 ie_info->length, ie_info->vdev_id); 11050 11051 buf_ptr += sizeof(*cmd); 11052 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 11053 buf_ptr += WMI_TLV_HDR_SIZE; 11054 11055 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 11056 11057 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11058 WMI_VDEV_SET_IE_CMDID); 11059 if (QDF_IS_STATUS_ERROR(ret)) { 11060 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 11061 wmi_buf_free(buf); 11062 } 11063 11064 return ret; 11065 } 11066 11067 /** 11068 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 11069 * 11070 * @param wmi_handle : handle to WMI. 11071 * @param param : pointer to antenna param 11072 * 11073 * This function sends smart antenna enable command to FW 11074 * 11075 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11076 */ 11077 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 11078 struct smart_ant_enable_params *param) 11079 { 11080 /* Send WMI COMMAND to Enable */ 11081 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 11082 wmi_pdev_smart_ant_gpio_handle *gpio_param; 11083 wmi_buf_t buf; 11084 uint8_t *buf_ptr; 11085 int len = 0; 11086 QDF_STATUS ret; 11087 int loop = 0; 11088 11089 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11090 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 11091 buf = wmi_buf_alloc(wmi_handle, len); 11092 11093 if (!buf) { 11094 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11095 return QDF_STATUS_E_NOMEM; 11096 } 11097 11098 buf_ptr = wmi_buf_data(buf); 11099 qdf_mem_zero(buf_ptr, len); 11100 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 11101 11102 WMITLV_SET_HDR(&cmd->tlv_header, 11103 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 11104 WMITLV_GET_STRUCT_TLVLEN( 11105 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 11106 11107 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11108 param->pdev_id); 11109 cmd->enable = param->enable; 11110 cmd->mode = param->mode; 11111 cmd->rx_antenna = param->rx_antenna; 11112 cmd->tx_default_antenna = param->rx_antenna; 11113 11114 /* TLV indicating array of structures to follow */ 11115 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 11116 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11117 WMI_HAL_MAX_SANTENNA * 11118 sizeof(wmi_pdev_smart_ant_gpio_handle)); 11119 11120 buf_ptr += WMI_TLV_HDR_SIZE; 11121 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 11122 11123 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 11124 WMITLV_SET_HDR(&gpio_param->tlv_header, 11125 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 11126 WMITLV_GET_STRUCT_TLVLEN( 11127 wmi_pdev_smart_ant_gpio_handle)); 11128 if (param->mode == SMART_ANT_MODE_SERIAL) { 11129 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 11130 gpio_param->gpio_pin = param->gpio_pin[loop]; 11131 gpio_param->gpio_func = param->gpio_func[loop]; 11132 } else { 11133 gpio_param->gpio_pin = 0; 11134 gpio_param->gpio_func = 0; 11135 } 11136 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 11137 gpio_param->gpio_pin = param->gpio_pin[loop]; 11138 gpio_param->gpio_func = param->gpio_func[loop]; 11139 } 11140 /* Setting it to 0 for now */ 11141 gpio_param->pdev_id = 11142 wmi_handle->ops->convert_pdev_id_host_to_target( 11143 param->pdev_id); 11144 gpio_param++; 11145 } 11146 11147 ret = wmi_unified_cmd_send(wmi_handle, 11148 buf, 11149 len, 11150 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 11151 11152 if (ret != 0) { 11153 WMI_LOGE(" %s :WMI Failed\n", __func__); 11154 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 11155 cmd->enable, 11156 cmd->mode, 11157 cmd->rx_antenna, 11158 param->gpio_pin[0], param->gpio_pin[1], 11159 param->gpio_pin[2], param->gpio_pin[3], 11160 param->gpio_func[0], param->gpio_func[1], 11161 param->gpio_func[2], param->gpio_func[3], 11162 ret); 11163 wmi_buf_free(buf); 11164 } 11165 11166 return ret; 11167 } 11168 11169 /** 11170 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 11171 * 11172 * @param wmi_handle : handle to WMI. 11173 * @param param : pointer to rx antenna param 11174 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11175 */ 11176 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11177 struct smart_ant_rx_ant_params *param) 11178 { 11179 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 11180 wmi_buf_t buf; 11181 uint8_t *buf_ptr; 11182 uint32_t len; 11183 QDF_STATUS ret; 11184 11185 len = sizeof(*cmd); 11186 buf = wmi_buf_alloc(wmi_handle, len); 11187 WMI_LOGD("%s:\n", __func__); 11188 if (!buf) { 11189 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11190 return QDF_STATUS_E_NOMEM; 11191 } 11192 11193 buf_ptr = wmi_buf_data(buf); 11194 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 11195 WMITLV_SET_HDR(&cmd->tlv_header, 11196 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 11197 WMITLV_GET_STRUCT_TLVLEN( 11198 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 11199 cmd->rx_antenna = param->antenna; 11200 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11201 param->pdev_id); 11202 11203 ret = wmi_unified_cmd_send(wmi_handle, 11204 buf, 11205 len, 11206 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 11207 11208 if (ret != 0) { 11209 WMI_LOGE(" %s :WMI Failed\n", __func__); 11210 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 11211 __func__, 11212 cmd->rx_antenna, 11213 ret); 11214 wmi_buf_free(buf); 11215 } 11216 11217 return ret; 11218 } 11219 11220 /** 11221 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 11222 * @wmi_handle: wmi handle 11223 * @param: pointer to hold ctl table param 11224 * 11225 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11226 */ 11227 static QDF_STATUS 11228 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 11229 struct ctl_table_params *param) 11230 { 11231 uint16_t len, ctl_tlv_len; 11232 uint8_t *buf_ptr; 11233 wmi_buf_t buf; 11234 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 11235 uint32_t *ctl_array; 11236 11237 if (!param->ctl_array) 11238 return QDF_STATUS_E_FAILURE; 11239 11240 ctl_tlv_len = WMI_TLV_HDR_SIZE + 11241 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 11242 len = sizeof(*cmd) + ctl_tlv_len; 11243 11244 buf = wmi_buf_alloc(wmi_handle, len); 11245 if (!buf) { 11246 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11247 return QDF_STATUS_E_FAILURE; 11248 } 11249 11250 buf_ptr = wmi_buf_data(buf); 11251 qdf_mem_zero(buf_ptr, len); 11252 11253 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 11254 11255 WMITLV_SET_HDR(&cmd->tlv_header, 11256 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 11257 WMITLV_GET_STRUCT_TLVLEN( 11258 wmi_pdev_set_ctl_table_cmd_fixed_param)); 11259 cmd->ctl_len = param->ctl_cmd_len; 11260 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11261 param->pdev_id); 11262 11263 buf_ptr += sizeof(*cmd); 11264 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11265 (cmd->ctl_len)); 11266 buf_ptr += WMI_TLV_HDR_SIZE; 11267 ctl_array = (uint32_t *)buf_ptr; 11268 11269 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 11270 sizeof(param->ctl_band)); 11271 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 11272 param->ctl_cmd_len - 11273 sizeof(param->ctl_band)); 11274 11275 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11276 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 11277 WMI_LOGE("%s:Failed to send command\n", __func__); 11278 wmi_buf_free(buf); 11279 return QDF_STATUS_E_FAILURE; 11280 } 11281 11282 return QDF_STATUS_SUCCESS; 11283 } 11284 11285 /** 11286 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 11287 * @wmi_handle: wmi handle 11288 * @param: pointer to hold mimogain table param 11289 * 11290 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11291 */ 11292 static QDF_STATUS 11293 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 11294 struct mimogain_table_params *param) 11295 { 11296 uint16_t len, table_tlv_len; 11297 wmi_buf_t buf; 11298 uint8_t *buf_ptr; 11299 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 11300 uint32_t *gain_table; 11301 11302 if (!param->array_gain) 11303 return QDF_STATUS_E_FAILURE; 11304 11305 /* len must be multiple of a single array gain table */ 11306 if (param->tbl_len % 11307 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 11308 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 11309 WMI_LOGE("Array gain table len not correct\n"); 11310 return QDF_STATUS_E_FAILURE; 11311 } 11312 11313 table_tlv_len = WMI_TLV_HDR_SIZE + 11314 roundup(param->tbl_len, sizeof(uint32_t)); 11315 len = sizeof(*cmd) + table_tlv_len; 11316 11317 buf = wmi_buf_alloc(wmi_handle, len); 11318 if (!buf) { 11319 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11320 return QDF_STATUS_E_FAILURE; 11321 } 11322 11323 buf_ptr = wmi_buf_data(buf); 11324 qdf_mem_zero(buf_ptr, len); 11325 11326 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 11327 11328 WMITLV_SET_HDR(&cmd->tlv_header, 11329 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 11330 WMITLV_GET_STRUCT_TLVLEN( 11331 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 11332 11333 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11334 param->pdev_id); 11335 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 11336 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 11337 param->multichain_gain_bypass); 11338 11339 buf_ptr += sizeof(*cmd); 11340 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11341 (param->tbl_len)); 11342 buf_ptr += WMI_TLV_HDR_SIZE; 11343 gain_table = (uint32_t *)buf_ptr; 11344 11345 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 11346 param->array_gain, 11347 param->tbl_len); 11348 11349 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11350 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 11351 return QDF_STATUS_E_FAILURE; 11352 } 11353 11354 return QDF_STATUS_SUCCESS; 11355 } 11356 11357 /** 11358 * enum packet_power_tlv_flags: target defined 11359 * packet power rate flags for TLV 11360 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 11361 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 11362 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 11363 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 11364 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 11365 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 11366 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 11367 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 11368 * @WMI_TLV_FLAG_STBC: STBC is set 11369 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 11370 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 11371 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 11372 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 11373 * @WMI_TLV_FLAG_RTSENA: RTS enabled 11374 * @WMI_TLV_FLAG_CTSENA: CTS enabled 11375 * @WMI_TLV_FLAG_LDPC: LDPC is set 11376 * @WMI_TLV_FLAG_SGI: Short gaurd interval 11377 * @WMI_TLV_FLAG_SU: SU Data 11378 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 11379 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 11380 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 11381 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 11382 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 11383 * 11384 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 11385 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 11386 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 11387 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 11388 */ 11389 enum packet_power_tlv_flags { 11390 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 11391 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 11392 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 11393 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 11394 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 11395 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 11396 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 11397 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 11398 WMI_TLV_FLAG_STBC = 0x00000100, 11399 WMI_TLV_FLAG_40MHZ = 0x00000200, 11400 WMI_TLV_FLAG_80MHZ = 0x00000300, 11401 WMI_TLV_FLAG_160MHZ = 0x00000400, 11402 WMI_TLV_FLAG_TXBF = 0x00000800, 11403 WMI_TLV_FLAG_RTSENA = 0x00001000, 11404 WMI_TLV_FLAG_CTSENA = 0x00002000, 11405 WMI_TLV_FLAG_LDPC = 0x00004000, 11406 WMI_TLV_FLAG_SGI = 0x00008000, 11407 WMI_TLV_FLAG_SU = 0x00100000, 11408 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 11409 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 11410 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 11411 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 11412 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 11413 11414 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 11415 WMI_TLV_FLAG_BW_MASK = 0x3, 11416 WMI_TLV_FLAG_BW_SHIFT = 9, 11417 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 11418 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 11419 }; 11420 11421 /** 11422 * convert_to_power_info_rate_flags() - convert packet_power_info_params 11423 * to FW understandable format 11424 * @param: pointer to hold packet power info param 11425 * 11426 * @return FW understandable 32 bit rate flags 11427 */ 11428 static uint32_t 11429 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 11430 { 11431 uint32_t rateflags = 0; 11432 11433 if (param->chainmask) 11434 rateflags |= 11435 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 11436 if (param->chan_width) 11437 rateflags |= 11438 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 11439 << WMI_TLV_FLAG_BW_SHIFT); 11440 if (param->su_mu_ofdma) 11441 rateflags |= 11442 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 11443 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 11444 if (param->rate_flags & WMI_HOST_FLAG_STBC) 11445 rateflags |= WMI_TLV_FLAG_STBC; 11446 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 11447 rateflags |= WMI_TLV_FLAG_LDPC; 11448 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 11449 rateflags |= WMI_TLV_FLAG_TXBF; 11450 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 11451 rateflags |= WMI_TLV_FLAG_RTSENA; 11452 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 11453 rateflags |= WMI_TLV_FLAG_CTSENA; 11454 if (param->rate_flags & WMI_HOST_FLAG_SGI) 11455 rateflags |= WMI_TLV_FLAG_SGI; 11456 11457 return rateflags; 11458 } 11459 11460 /** 11461 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 11462 * info to fw 11463 * @wmi_handle: wmi handle 11464 * @param: pointer to hold packet power info param 11465 * 11466 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11467 */ 11468 static QDF_STATUS 11469 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 11470 struct packet_power_info_params *param) 11471 { 11472 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 11473 wmi_buf_t wmibuf; 11474 uint8_t *buf_ptr; 11475 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 11476 11477 wmibuf = wmi_buf_alloc(wmi_handle, len); 11478 if (wmibuf == NULL) 11479 return QDF_STATUS_E_NOMEM; 11480 11481 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 11482 11483 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 11484 WMITLV_SET_HDR(&cmd->tlv_header, 11485 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 11486 WMITLV_GET_STRUCT_TLVLEN( 11487 wmi_pdev_get_tpc_cmd_fixed_param)); 11488 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11489 param->pdev_id); 11490 cmd->rate_flags = convert_to_power_info_rate_flags(param); 11491 cmd->nss = param->nss; 11492 cmd->preamble = param->preamble; 11493 cmd->hw_rate = param->hw_rate; 11494 11495 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 11496 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 11497 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 11498 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 11499 11500 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 11501 WMI_PDEV_GET_TPC_CMDID)) { 11502 WMI_LOGE(FL("Failed to get tpc command\n")); 11503 wmi_buf_free(wmibuf); 11504 return QDF_STATUS_E_FAILURE; 11505 } 11506 11507 return QDF_STATUS_SUCCESS; 11508 } 11509 11510 /** 11511 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 11512 * @wmi_handle: wmi handle 11513 * @param: pointer to hold config ratemask params 11514 * 11515 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11516 */ 11517 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 11518 struct config_ratemask_params *param) 11519 { 11520 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 11521 wmi_buf_t buf; 11522 int32_t len = sizeof(*cmd); 11523 11524 buf = wmi_buf_alloc(wmi_handle, len); 11525 if (!buf) { 11526 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11527 return QDF_STATUS_E_FAILURE; 11528 } 11529 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 11530 WMITLV_SET_HDR(&cmd->tlv_header, 11531 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 11532 WMITLV_GET_STRUCT_TLVLEN( 11533 wmi_vdev_config_ratemask_cmd_fixed_param)); 11534 cmd->vdev_id = param->vdev_id; 11535 cmd->type = param->type; 11536 cmd->mask_lower32 = param->lower32; 11537 cmd->mask_higher32 = param->higher32; 11538 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n", 11539 param->vdev_id, param->type, param->lower32, param->higher32); 11540 11541 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11542 WMI_VDEV_RATEMASK_CMDID)) { 11543 WMI_LOGE("Seting vdev ratemask failed\n"); 11544 wmi_buf_free(buf); 11545 return QDF_STATUS_E_FAILURE; 11546 } 11547 11548 return QDF_STATUS_SUCCESS; 11549 } 11550 11551 /** 11552 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 11553 * @param: param sent from the host side 11554 * @cmd: param to be sent to the fw side 11555 */ 11556 static inline void copy_custom_aggr_bitmap( 11557 struct set_custom_aggr_size_params *param, 11558 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 11559 { 11560 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 11561 param->ac); 11562 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 11563 param->aggr_type); 11564 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11565 param->tx_aggr_size_disable); 11566 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11567 param->rx_aggr_size_disable); 11568 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 11569 param->tx_ac_enable); 11570 } 11571 11572 /** 11573 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 11574 * @wmi_handle: wmi handle 11575 * @param: pointer to hold custom aggr size params 11576 * 11577 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11578 */ 11579 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 11580 wmi_unified_t wmi_handle, 11581 struct set_custom_aggr_size_params *param) 11582 { 11583 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 11584 wmi_buf_t buf; 11585 int32_t len = sizeof(*cmd); 11586 11587 buf = wmi_buf_alloc(wmi_handle, len); 11588 if (!buf) { 11589 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11590 return QDF_STATUS_E_FAILURE; 11591 } 11592 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 11593 wmi_buf_data(buf); 11594 WMITLV_SET_HDR(&cmd->tlv_header, 11595 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 11596 WMITLV_GET_STRUCT_TLVLEN( 11597 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 11598 cmd->vdev_id = param->vdev_id; 11599 cmd->tx_aggr_size = param->tx_aggr_size; 11600 cmd->rx_aggr_size = param->rx_aggr_size; 11601 copy_custom_aggr_bitmap(param, cmd); 11602 11603 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 11604 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 11605 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 11606 "tx_ac_enable=0x%X\n", 11607 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 11608 param->ac, param->aggr_type, param->tx_aggr_size_disable, 11609 param->rx_aggr_size_disable, param->tx_ac_enable); 11610 11611 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11612 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 11613 WMI_LOGE("Seting custom aggregation size failed\n"); 11614 wmi_buf_free(buf); 11615 return QDF_STATUS_E_FAILURE; 11616 } 11617 11618 return QDF_STATUS_SUCCESS; 11619 } 11620 11621 /** 11622 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 11623 * @param wmi_handle : handle to WMI. 11624 * @param param : pointer to tx antenna param 11625 * 11626 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11627 */ 11628 11629 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 11630 struct set_qdepth_thresh_params *param) 11631 { 11632 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 11633 wmi_msduq_qdepth_thresh_update *cmd_update; 11634 wmi_buf_t buf; 11635 int32_t len = 0; 11636 int i; 11637 uint8_t *buf_ptr; 11638 QDF_STATUS ret; 11639 11640 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 11641 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 11642 return QDF_STATUS_E_INVAL; 11643 } 11644 11645 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11646 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 11647 param->num_of_msduq_updates); 11648 buf = wmi_buf_alloc(wmi_handle, len); 11649 11650 if (!buf) { 11651 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11652 return QDF_STATUS_E_NOMEM; 11653 } 11654 11655 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11656 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 11657 buf_ptr; 11658 11659 WMITLV_SET_HDR(&cmd->tlv_header, 11660 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 11661 , WMITLV_GET_STRUCT_TLVLEN( 11662 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 11663 11664 cmd->pdev_id = 11665 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11666 cmd->vdev_id = param->vdev_id; 11667 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 11668 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 11669 11670 buf_ptr += sizeof( 11671 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 11672 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11673 param->num_of_msduq_updates * 11674 sizeof(wmi_msduq_qdepth_thresh_update)); 11675 buf_ptr += WMI_TLV_HDR_SIZE; 11676 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 11677 11678 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 11679 WMITLV_SET_HDR(&cmd_update->tlv_header, 11680 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 11681 WMITLV_GET_STRUCT_TLVLEN( 11682 wmi_msduq_qdepth_thresh_update)); 11683 cmd_update->tid_num = param->update_params[i].tid_num; 11684 cmd_update->msduq_update_mask = 11685 param->update_params[i].msduq_update_mask; 11686 cmd_update->qdepth_thresh_value = 11687 param->update_params[i].qdepth_thresh_value; 11688 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 11689 "mac_addr_upper4=%X, mac_addr_lower2:%X," 11690 " update mask=0x%X thresh val=0x%X\n", 11691 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 11692 cmd->peer_mac_address.mac_addr31to0, 11693 cmd->peer_mac_address.mac_addr47to32, 11694 cmd_update->msduq_update_mask, 11695 cmd_update->qdepth_thresh_value); 11696 cmd_update++; 11697 } 11698 11699 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11700 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 11701 11702 if (ret != 0) { 11703 WMI_LOGE(" %s :WMI Failed\n", __func__); 11704 wmi_buf_free(buf); 11705 } 11706 11707 return ret; 11708 } 11709 11710 /** 11711 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11712 * @wmi_handle: wmi handle 11713 * @param: pointer to hold vap dscp tid map param 11714 * 11715 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11716 */ 11717 static QDF_STATUS 11718 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11719 struct vap_dscp_tid_map_params *param) 11720 { 11721 wmi_buf_t buf; 11722 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11723 int32_t len = sizeof(*cmd); 11724 11725 buf = wmi_buf_alloc(wmi_handle, len); 11726 if (!buf) { 11727 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11728 return QDF_STATUS_E_FAILURE; 11729 } 11730 11731 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11732 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11733 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 11734 11735 cmd->vdev_id = param->vdev_id; 11736 cmd->enable_override = 0; 11737 11738 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11739 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11740 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11741 WMI_LOGE("Failed to set dscp cmd\n"); 11742 wmi_buf_free(buf); 11743 return QDF_STATUS_E_FAILURE; 11744 } 11745 11746 return QDF_STATUS_SUCCESS; 11747 } 11748 11749 /** 11750 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11751 * @wmi_handle: wmi handle 11752 * @macaddr: vdev mac address 11753 * @param: pointer to hold neigbour rx param 11754 * 11755 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11756 */ 11757 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11758 uint8_t macaddr[IEEE80211_ADDR_LEN], 11759 struct set_neighbour_rx_params *param) 11760 { 11761 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11762 wmi_buf_t buf; 11763 int32_t len = sizeof(*cmd); 11764 11765 buf = wmi_buf_alloc(wmi_handle, len); 11766 if (!buf) { 11767 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11768 return QDF_STATUS_E_FAILURE; 11769 } 11770 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11771 WMITLV_SET_HDR(&cmd->tlv_header, 11772 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11773 WMITLV_GET_STRUCT_TLVLEN( 11774 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11775 cmd->vdev_id = param->vdev_id; 11776 cmd->bssid_idx = param->idx; 11777 cmd->action = param->action; 11778 cmd->type = param->type; 11779 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11780 cmd->flag = 0; 11781 11782 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11783 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11784 WMI_LOGE("Failed to set neighbour rx param\n"); 11785 wmi_buf_free(buf); 11786 return QDF_STATUS_E_FAILURE; 11787 } 11788 11789 return QDF_STATUS_SUCCESS; 11790 } 11791 11792 /** 11793 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11794 * @param wmi_handle : handle to WMI. 11795 * @param macaddr : vdev mac address 11796 * @param param : pointer to tx antenna param 11797 * 11798 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11799 */ 11800 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11801 uint8_t macaddr[IEEE80211_ADDR_LEN], 11802 struct smart_ant_tx_ant_params *param) 11803 { 11804 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11805 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11806 wmi_buf_t buf; 11807 int32_t len = 0; 11808 int i; 11809 uint8_t *buf_ptr; 11810 QDF_STATUS ret; 11811 11812 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11813 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11814 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11815 buf = wmi_buf_alloc(wmi_handle, len); 11816 11817 if (!buf) { 11818 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11819 return QDF_STATUS_E_NOMEM; 11820 } 11821 11822 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11823 qdf_mem_zero(buf_ptr, len); 11824 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11825 11826 WMITLV_SET_HDR(&cmd->tlv_header, 11827 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11828 WMITLV_GET_STRUCT_TLVLEN( 11829 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11830 11831 cmd->vdev_id = param->vdev_id; 11832 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11833 11834 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11835 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11836 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11837 buf_ptr += WMI_TLV_HDR_SIZE; 11838 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11839 11840 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11841 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11842 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11843 WMITLV_GET_STRUCT_TLVLEN( 11844 wmi_peer_smart_ant_set_tx_antenna_series)); 11845 ant_tx_series->antenna_series = param->antenna_array[i]; 11846 ant_tx_series++; 11847 } 11848 11849 ret = wmi_unified_cmd_send(wmi_handle, 11850 buf, 11851 len, 11852 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11853 11854 if (ret != 0) { 11855 WMI_LOGE(" %s :WMI Failed\n", __func__); 11856 wmi_buf_free(buf); 11857 } 11858 11859 return ret; 11860 } 11861 11862 /** 11863 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11864 * @wmi_handle: wmi handle 11865 * @param: pointer to hold ant switch tbl param 11866 * 11867 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11868 */ 11869 static QDF_STATUS 11870 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11871 struct ant_switch_tbl_params *param) 11872 { 11873 uint8_t len; 11874 wmi_buf_t buf; 11875 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11876 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11877 uint8_t *buf_ptr; 11878 11879 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11880 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11881 buf = wmi_buf_alloc(wmi_handle, len); 11882 11883 if (!buf) { 11884 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11885 return QDF_STATUS_E_NOMEM; 11886 } 11887 11888 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11889 qdf_mem_zero(buf_ptr, len); 11890 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11891 11892 WMITLV_SET_HDR(&cmd->tlv_header, 11893 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11894 WMITLV_GET_STRUCT_TLVLEN( 11895 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11896 11897 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11898 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11899 cmd->mac_id = 11900 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11901 11902 /* TLV indicating array of structures to follow */ 11903 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11904 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11905 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11906 buf_ptr += WMI_TLV_HDR_SIZE; 11907 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11908 11909 ctrl_chain->pdev_id = 11910 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11911 ctrl_chain->antCtrlChain = param->antCtrlChain; 11912 11913 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11914 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11915 wmi_buf_free(buf); 11916 return QDF_STATUS_E_FAILURE; 11917 } 11918 11919 return QDF_STATUS_SUCCESS; 11920 } 11921 11922 /** 11923 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11924 * training information function 11925 * @param wmi_handle : handle to WMI. 11926 * @macaddr : vdev mac address 11927 * @param param : pointer to tx antenna param 11928 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11929 */ 11930 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11931 wmi_unified_t wmi_handle, 11932 uint8_t macaddr[IEEE80211_ADDR_LEN], 11933 struct smart_ant_training_info_params *param) 11934 { 11935 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11936 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11937 wmi_buf_t buf; 11938 uint8_t *buf_ptr; 11939 int32_t len = 0; 11940 QDF_STATUS ret; 11941 int loop; 11942 11943 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11944 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11945 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11946 buf = wmi_buf_alloc(wmi_handle, len); 11947 11948 if (!buf) { 11949 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11950 return QDF_STATUS_E_NOMEM; 11951 } 11952 11953 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11954 qdf_mem_zero(buf_ptr, len); 11955 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11956 11957 WMITLV_SET_HDR(&cmd->tlv_header, 11958 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11959 WMITLV_GET_STRUCT_TLVLEN( 11960 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11961 11962 cmd->vdev_id = param->vdev_id; 11963 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11964 cmd->num_pkts = param->numpkts; 11965 11966 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11967 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11968 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11969 WMI_SMART_ANT_MAX_RATE_SERIES); 11970 11971 buf_ptr += WMI_TLV_HDR_SIZE; 11972 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11973 11974 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11975 WMITLV_SET_HDR(&train_param->tlv_header, 11976 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11977 WMITLV_GET_STRUCT_TLVLEN( 11978 wmi_peer_smart_ant_set_train_antenna_param)); 11979 train_param->train_rate_series = param->rate_array[loop]; 11980 train_param->train_antenna_series = param->antenna_array[loop]; 11981 train_param->rc_flags = 0; 11982 WMI_LOGI(FL("Series number:%d\n"), loop); 11983 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11984 train_param->train_rate_series, 11985 train_param->train_antenna_series); 11986 train_param++; 11987 } 11988 11989 ret = wmi_unified_cmd_send(wmi_handle, 11990 buf, 11991 len, 11992 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 11993 11994 if (ret != 0) { 11995 WMI_LOGE(" %s :WMI Failed\n", __func__); 11996 wmi_buf_free(buf); 11997 return QDF_STATUS_E_FAILURE; 11998 } 11999 12000 return ret; 12001 } 12002 12003 /** 12004 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 12005 * configuration function 12006 * @param wmi_handle : handle to WMI. 12007 * @macaddr : vdev mad address 12008 * @param param : pointer to tx antenna param 12009 * 12010 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12011 */ 12012 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 12013 wmi_unified_t wmi_handle, 12014 uint8_t macaddr[IEEE80211_ADDR_LEN], 12015 struct smart_ant_node_config_params *param) 12016 { 12017 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 12018 wmi_buf_t buf; 12019 uint8_t *buf_ptr; 12020 int32_t len = 0, args_tlv_len; 12021 int ret; 12022 int i = 0; 12023 uint32_t *node_config_args; 12024 12025 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 12026 len = sizeof(*cmd) + args_tlv_len; 12027 12028 if (param->args_count == 0) { 12029 WMI_LOGE("%s: Can't send a command with %d arguments\n", 12030 __func__, param->args_count); 12031 return QDF_STATUS_E_FAILURE; 12032 } 12033 12034 buf = wmi_buf_alloc(wmi_handle, len); 12035 if (!buf) { 12036 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12037 return QDF_STATUS_E_NOMEM; 12038 } 12039 12040 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 12041 wmi_buf_data(buf); 12042 buf_ptr = (uint8_t *)cmd; 12043 WMITLV_SET_HDR(&cmd->tlv_header, 12044 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 12045 WMITLV_GET_STRUCT_TLVLEN( 12046 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 12047 cmd->vdev_id = param->vdev_id; 12048 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12049 cmd->cmd_id = param->cmd_id; 12050 cmd->args_count = param->args_count; 12051 buf_ptr += sizeof( 12052 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 12053 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12054 (cmd->args_count * sizeof(uint32_t))); 12055 buf_ptr += WMI_TLV_HDR_SIZE; 12056 node_config_args = (uint32_t *)buf_ptr; 12057 12058 for (i = 0; i < param->args_count; i++) { 12059 node_config_args[i] = param->args_arr[i]; 12060 WMI_LOGI("%d", param->args_arr[i]); 12061 } 12062 12063 ret = wmi_unified_cmd_send(wmi_handle, 12064 buf, 12065 len, 12066 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 12067 12068 if (ret != 0) { 12069 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 12070 __func__, param->cmd_id, macaddr[0], 12071 macaddr[1], macaddr[2], macaddr[3], 12072 macaddr[4], macaddr[5], ret); 12073 wmi_buf_free(buf); 12074 } 12075 12076 return ret; 12077 } 12078 12079 /** 12080 * send_set_atf_cmd_tlv() - send set atf command to fw 12081 * @wmi_handle: wmi handle 12082 * @param: pointer to set atf param 12083 * 12084 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12085 */ 12086 static QDF_STATUS 12087 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 12088 struct set_atf_params *param) 12089 { 12090 wmi_atf_peer_info *peer_info; 12091 wmi_peer_atf_request_fixed_param *cmd; 12092 wmi_buf_t buf; 12093 uint8_t *buf_ptr; 12094 int i; 12095 int32_t len = 0; 12096 QDF_STATUS retval; 12097 12098 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12099 len += param->num_peers * sizeof(wmi_atf_peer_info); 12100 buf = wmi_buf_alloc(wmi_handle, len); 12101 if (!buf) { 12102 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12103 return QDF_STATUS_E_FAILURE; 12104 } 12105 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12106 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 12107 WMITLV_SET_HDR(&cmd->tlv_header, 12108 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 12109 WMITLV_GET_STRUCT_TLVLEN( 12110 wmi_peer_atf_request_fixed_param)); 12111 cmd->num_peers = param->num_peers; 12112 12113 buf_ptr += sizeof(*cmd); 12114 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12115 sizeof(wmi_atf_peer_info) * 12116 cmd->num_peers); 12117 buf_ptr += WMI_TLV_HDR_SIZE; 12118 peer_info = (wmi_atf_peer_info *)buf_ptr; 12119 12120 for (i = 0; i < cmd->num_peers; i++) { 12121 WMITLV_SET_HDR(&peer_info->tlv_header, 12122 WMITLV_TAG_STRUC_wmi_atf_peer_info, 12123 WMITLV_GET_STRUCT_TLVLEN( 12124 wmi_atf_peer_info)); 12125 qdf_mem_copy(&(peer_info->peer_macaddr), 12126 &(param->peer_info[i].peer_macaddr), 12127 sizeof(wmi_mac_addr)); 12128 peer_info->atf_units = param->peer_info[i].percentage_peer; 12129 peer_info->vdev_id = param->peer_info[i].vdev_id; 12130 peer_info->pdev_id = 12131 wmi_handle->ops->convert_pdev_id_host_to_target( 12132 param->peer_info[i].pdev_id); 12133 /* 12134 * TLV definition for peer atf request fixed param combines 12135 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 12136 * stats and atf extension stats as two different 12137 * implementations. 12138 * Need to discuss with FW on this. 12139 * 12140 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 12141 * peer_info->atf_units_reserved = 12142 * param->peer_ext_info[i].atf_index_reserved; 12143 */ 12144 peer_info++; 12145 } 12146 12147 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12148 WMI_PEER_ATF_REQUEST_CMDID); 12149 12150 if (retval != QDF_STATUS_SUCCESS) { 12151 WMI_LOGE("%s : WMI Failed\n", __func__); 12152 wmi_buf_free(buf); 12153 } 12154 12155 return retval; 12156 } 12157 12158 /** 12159 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 12160 * @wmi_handle: wmi handle 12161 * @param: pointer to hold fwtest param 12162 * 12163 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12164 */ 12165 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 12166 struct set_fwtest_params *param) 12167 { 12168 wmi_fwtest_set_param_cmd_fixed_param *cmd; 12169 wmi_buf_t buf; 12170 int32_t len = sizeof(*cmd); 12171 12172 buf = wmi_buf_alloc(wmi_handle, len); 12173 12174 if (!buf) { 12175 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12176 return QDF_STATUS_E_FAILURE; 12177 } 12178 12179 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 12180 WMITLV_SET_HDR(&cmd->tlv_header, 12181 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 12182 WMITLV_GET_STRUCT_TLVLEN( 12183 wmi_fwtest_set_param_cmd_fixed_param)); 12184 cmd->param_id = param->arg; 12185 cmd->param_value = param->value; 12186 12187 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 12188 WMI_LOGE("Setting FW test param failed\n"); 12189 wmi_buf_free(buf); 12190 return QDF_STATUS_E_FAILURE; 12191 } 12192 12193 return QDF_STATUS_SUCCESS; 12194 } 12195 12196 /** 12197 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 12198 * @wmi_handle: wmi handle 12199 * @param: pointer to qboost params 12200 * @macaddr: vdev mac address 12201 * 12202 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12203 */ 12204 static QDF_STATUS 12205 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 12206 uint8_t macaddr[IEEE80211_ADDR_LEN], 12207 struct set_qboost_params *param) 12208 { 12209 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 12210 wmi_buf_t buf; 12211 int32_t len; 12212 QDF_STATUS ret; 12213 12214 len = sizeof(*cmd); 12215 12216 buf = wmi_buf_alloc(wmi_handle, len); 12217 if (!buf) { 12218 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12219 return QDF_STATUS_E_FAILURE; 12220 } 12221 12222 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 12223 WMITLV_SET_HDR(&cmd->tlv_header, 12224 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 12225 WMITLV_GET_STRUCT_TLVLEN( 12226 WMI_QBOOST_CFG_CMD_fixed_param)); 12227 cmd->vdev_id = param->vdev_id; 12228 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12229 cmd->qb_enable = param->value; 12230 12231 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12232 WMI_QBOOST_CFG_CMDID); 12233 12234 if (ret != 0) { 12235 WMI_LOGE("Setting qboost cmd failed\n"); 12236 wmi_buf_free(buf); 12237 } 12238 12239 return ret; 12240 } 12241 12242 /** 12243 * send_gpio_config_cmd_tlv() - send gpio config to fw 12244 * @wmi_handle: wmi handle 12245 * @param: pointer to hold gpio config param 12246 * 12247 * Return: 0 for success or error code 12248 */ 12249 static QDF_STATUS 12250 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 12251 struct gpio_config_params *param) 12252 { 12253 wmi_gpio_config_cmd_fixed_param *cmd; 12254 wmi_buf_t buf; 12255 int32_t len; 12256 QDF_STATUS ret; 12257 12258 len = sizeof(*cmd); 12259 12260 /* Sanity Checks */ 12261 if (param->pull_type > WMI_GPIO_PULL_DOWN || 12262 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 12263 return QDF_STATUS_E_FAILURE; 12264 } 12265 12266 buf = wmi_buf_alloc(wmi_handle, len); 12267 if (!buf) { 12268 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12269 return QDF_STATUS_E_FAILURE; 12270 } 12271 12272 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 12273 WMITLV_SET_HDR(&cmd->tlv_header, 12274 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 12275 WMITLV_GET_STRUCT_TLVLEN( 12276 wmi_gpio_config_cmd_fixed_param)); 12277 cmd->gpio_num = param->gpio_num; 12278 cmd->input = param->input; 12279 cmd->pull_type = param->pull_type; 12280 cmd->intr_mode = param->intr_mode; 12281 12282 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12283 WMI_GPIO_CONFIG_CMDID); 12284 12285 if (ret != 0) { 12286 WMI_LOGE("Sending GPIO config cmd failed\n"); 12287 wmi_buf_free(buf); 12288 } 12289 12290 return ret; 12291 } 12292 12293 /** 12294 * send_gpio_output_cmd_tlv() - send gpio output to fw 12295 * @wmi_handle: wmi handle 12296 * @param: pointer to hold gpio output param 12297 * 12298 * Return: 0 for success or error code 12299 */ 12300 static QDF_STATUS 12301 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 12302 struct gpio_output_params *param) 12303 { 12304 wmi_gpio_output_cmd_fixed_param *cmd; 12305 wmi_buf_t buf; 12306 int32_t len; 12307 QDF_STATUS ret; 12308 12309 len = sizeof(*cmd); 12310 12311 buf = wmi_buf_alloc(wmi_handle, len); 12312 if (!buf) { 12313 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12314 return QDF_STATUS_E_FAILURE; 12315 } 12316 12317 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 12318 WMITLV_SET_HDR(&cmd->tlv_header, 12319 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 12320 WMITLV_GET_STRUCT_TLVLEN( 12321 wmi_gpio_output_cmd_fixed_param)); 12322 cmd->gpio_num = param->gpio_num; 12323 cmd->set = param->set; 12324 12325 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12326 WMI_GPIO_OUTPUT_CMDID); 12327 12328 if (ret != 0) { 12329 WMI_LOGE("Sending GPIO output cmd failed\n"); 12330 wmi_buf_free(buf); 12331 } 12332 12333 return ret; 12334 12335 } 12336 12337 /** 12338 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 12339 * 12340 * @param wmi_handle : handle to WMI. 12341 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12342 */ 12343 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 12344 { 12345 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 12346 wmi_buf_t buf; 12347 QDF_STATUS ret; 12348 int32_t len; 12349 12350 len = sizeof(*cmd); 12351 12352 buf = wmi_buf_alloc(wmi_handle, len); 12353 if (!buf) { 12354 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12355 return QDF_STATUS_E_FAILURE; 12356 } 12357 12358 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 12359 WMITLV_SET_HDR(&cmd->tlv_header, 12360 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 12361 WMITLV_GET_STRUCT_TLVLEN( 12362 wmi_pdev_dfs_disable_cmd_fixed_param)); 12363 /* Filling it with WMI_PDEV_ID_SOC for now */ 12364 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12365 WMI_HOST_PDEV_ID_SOC); 12366 12367 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12368 WMI_PDEV_DFS_DISABLE_CMDID); 12369 12370 if (ret != 0) { 12371 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 12372 wmi_buf_free(buf); 12373 } 12374 12375 return ret; 12376 } 12377 12378 /** 12379 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 12380 * 12381 * @param wmi_handle : handle to WMI. 12382 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12383 */ 12384 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 12385 { 12386 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 12387 wmi_buf_t buf; 12388 QDF_STATUS ret; 12389 int32_t len; 12390 12391 len = sizeof(*cmd); 12392 12393 buf = wmi_buf_alloc(wmi_handle, len); 12394 if (!buf) { 12395 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12396 return QDF_STATUS_E_FAILURE; 12397 } 12398 12399 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 12400 WMITLV_SET_HDR(&cmd->tlv_header, 12401 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 12402 WMITLV_GET_STRUCT_TLVLEN( 12403 wmi_pdev_dfs_enable_cmd_fixed_param)); 12404 /* Reserved for future use */ 12405 cmd->reserved0 = 0; 12406 12407 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12408 WMI_PDEV_DFS_ENABLE_CMDID); 12409 12410 if (ret != 0) { 12411 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 12412 wmi_buf_free(buf); 12413 } 12414 12415 return ret; 12416 } 12417 12418 /** 12419 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 12420 * to fw 12421 * @wmi_handle: wmi handle 12422 * @param: pointer to hold periodic chan stats param 12423 * 12424 * Return: 0 for success or error code 12425 */ 12426 static QDF_STATUS 12427 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 12428 struct periodic_chan_stats_params *param) 12429 { 12430 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 12431 wmi_buf_t buf; 12432 QDF_STATUS ret; 12433 int32_t len; 12434 12435 len = sizeof(*cmd); 12436 12437 buf = wmi_buf_alloc(wmi_handle, len); 12438 if (!buf) { 12439 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12440 return QDF_STATUS_E_FAILURE; 12441 } 12442 12443 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 12444 wmi_buf_data(buf); 12445 WMITLV_SET_HDR(&cmd->tlv_header, 12446 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 12447 WMITLV_GET_STRUCT_TLVLEN( 12448 wmi_set_periodic_channel_stats_config_fixed_param)); 12449 cmd->enable = param->enable; 12450 cmd->stats_period = param->stats_period; 12451 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12452 param->pdev_id); 12453 12454 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12455 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 12456 12457 if (ret != 0) { 12458 WMI_LOGE("Sending periodic chan stats config failed"); 12459 wmi_buf_free(buf); 12460 } 12461 12462 return ret; 12463 } 12464 12465 /** 12466 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 12467 * @wmi_handle: wmi handle 12468 * @mac_id: radio context 12469 * 12470 * Return: 0 for success or error code 12471 */ 12472 static QDF_STATUS 12473 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 12474 { 12475 wmi_buf_t buf; 12476 QDF_STATUS ret; 12477 wmi_pdev_get_nfcal_power_fixed_param *cmd; 12478 int32_t len = sizeof(*cmd); 12479 12480 buf = wmi_buf_alloc(wmi_handle, len); 12481 if (buf == NULL) 12482 return QDF_STATUS_E_NOMEM; 12483 12484 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 12485 WMITLV_SET_HDR(&cmd->tlv_header, 12486 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 12487 WMITLV_GET_STRUCT_TLVLEN 12488 (wmi_pdev_get_nfcal_power_fixed_param)); 12489 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 12490 12491 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12492 WMI_PDEV_GET_NFCAL_POWER_CMDID); 12493 if (ret != 0) { 12494 WMI_LOGE("Sending get nfcal power cmd failed\n"); 12495 wmi_buf_free(buf); 12496 } 12497 12498 return ret; 12499 } 12500 12501 /** 12502 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 12503 * @wmi_handle: wmi handle 12504 * @param: pointer to ht ie param 12505 * 12506 * Return: 0 for success or error code 12507 */ 12508 static QDF_STATUS 12509 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12510 struct ht_ie_params *param) 12511 { 12512 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 12513 wmi_buf_t buf; 12514 QDF_STATUS ret; 12515 int32_t len; 12516 uint8_t *buf_ptr; 12517 12518 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12519 roundup(param->ie_len, sizeof(uint32_t)); 12520 12521 buf = wmi_buf_alloc(wmi_handle, len); 12522 if (!buf) { 12523 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12524 return QDF_STATUS_E_FAILURE; 12525 } 12526 12527 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12528 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 12529 WMITLV_SET_HDR(&cmd->tlv_header, 12530 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 12531 WMITLV_GET_STRUCT_TLVLEN( 12532 wmi_pdev_set_ht_ie_cmd_fixed_param)); 12533 cmd->reserved0 = 0; 12534 cmd->ie_len = param->ie_len; 12535 cmd->tx_streams = param->tx_streams; 12536 cmd->rx_streams = param->rx_streams; 12537 12538 buf_ptr += sizeof(*cmd); 12539 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12540 buf_ptr += WMI_TLV_HDR_SIZE; 12541 if (param->ie_len) 12542 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12543 cmd->ie_len); 12544 12545 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12546 WMI_PDEV_SET_HT_CAP_IE_CMDID); 12547 12548 if (ret != 0) { 12549 WMI_LOGE("Sending set ht ie cmd failed\n"); 12550 wmi_buf_free(buf); 12551 } 12552 12553 return ret; 12554 } 12555 12556 /** 12557 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 12558 * @wmi_handle: wmi handle 12559 * @param: pointer to vht ie param 12560 * 12561 * Return: 0 for success or error code 12562 */ 12563 static QDF_STATUS 12564 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12565 struct vht_ie_params *param) 12566 { 12567 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 12568 wmi_buf_t buf; 12569 QDF_STATUS ret; 12570 int32_t len; 12571 uint8_t *buf_ptr; 12572 12573 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12574 roundup(param->ie_len, sizeof(uint32_t)); 12575 12576 buf = wmi_buf_alloc(wmi_handle, len); 12577 if (!buf) { 12578 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12579 return QDF_STATUS_E_FAILURE; 12580 } 12581 12582 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12583 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 12584 WMITLV_SET_HDR(&cmd->tlv_header, 12585 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 12586 WMITLV_GET_STRUCT_TLVLEN( 12587 wmi_pdev_set_vht_ie_cmd_fixed_param)); 12588 cmd->reserved0 = 0; 12589 cmd->ie_len = param->ie_len; 12590 cmd->tx_streams = param->tx_streams; 12591 cmd->rx_streams = param->rx_streams; 12592 12593 buf_ptr += sizeof(*cmd); 12594 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12595 buf_ptr += WMI_TLV_HDR_SIZE; 12596 if (param->ie_len) 12597 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12598 cmd->ie_len); 12599 12600 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12601 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 12602 12603 if (ret != 0) { 12604 WMI_LOGE("Sending set vht ie cmd failed\n"); 12605 wmi_buf_free(buf); 12606 } 12607 12608 return ret; 12609 } 12610 12611 /** 12612 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 12613 * @wmi_handle: wmi handle 12614 * @param: pointer to quiet mode params 12615 * 12616 * Return: 0 for success or error code 12617 */ 12618 static QDF_STATUS 12619 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 12620 struct set_quiet_mode_params *param) 12621 { 12622 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 12623 wmi_buf_t buf; 12624 QDF_STATUS ret; 12625 int32_t len; 12626 12627 len = sizeof(*quiet_cmd); 12628 buf = wmi_buf_alloc(wmi_handle, len); 12629 if (!buf) { 12630 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12631 return QDF_STATUS_E_FAILURE; 12632 } 12633 12634 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12635 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 12636 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 12637 WMITLV_GET_STRUCT_TLVLEN( 12638 wmi_pdev_set_quiet_cmd_fixed_param)); 12639 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12640 quiet_cmd->enabled = param->enabled; 12641 quiet_cmd->period = (param->period)*(param->intval); 12642 quiet_cmd->duration = param->duration; 12643 quiet_cmd->next_start = param->offset; 12644 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12645 WMI_HOST_PDEV_ID_SOC); 12646 12647 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12648 WMI_PDEV_SET_QUIET_MODE_CMDID); 12649 12650 if (ret != 0) { 12651 WMI_LOGE("Sending set quiet cmd failed\n"); 12652 wmi_buf_free(buf); 12653 } 12654 12655 return ret; 12656 } 12657 12658 /** 12659 * send_set_bwf_cmd_tlv() - send set bwf command to fw 12660 * @wmi_handle: wmi handle 12661 * @param: pointer to set bwf param 12662 * 12663 * Return: 0 for success or error code 12664 */ 12665 static QDF_STATUS 12666 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12667 struct set_bwf_params *param) 12668 { 12669 wmi_bwf_peer_info *peer_info; 12670 wmi_peer_bwf_request_fixed_param *cmd; 12671 wmi_buf_t buf; 12672 QDF_STATUS retval; 12673 int32_t len; 12674 uint8_t *buf_ptr; 12675 int i; 12676 12677 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12678 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12679 buf = wmi_buf_alloc(wmi_handle, len); 12680 if (!buf) { 12681 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12682 return QDF_STATUS_E_FAILURE; 12683 } 12684 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12685 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12686 WMITLV_SET_HDR(&cmd->tlv_header, 12687 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12688 WMITLV_GET_STRUCT_TLVLEN( 12689 wmi_peer_bwf_request_fixed_param)); 12690 cmd->num_peers = param->num_peers; 12691 12692 buf_ptr += sizeof(*cmd); 12693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12694 sizeof(wmi_bwf_peer_info) * 12695 cmd->num_peers); 12696 buf_ptr += WMI_TLV_HDR_SIZE; 12697 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12698 12699 for (i = 0; i < cmd->num_peers; i++) { 12700 WMITLV_SET_HDR(&peer_info->tlv_header, 12701 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12702 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12703 peer_info->bwf_guaranteed_bandwidth = 12704 param->peer_info[i].throughput; 12705 peer_info->bwf_max_airtime = 12706 param->peer_info[i].max_airtime; 12707 peer_info->bwf_peer_priority = 12708 param->peer_info[i].priority; 12709 qdf_mem_copy(&peer_info->peer_macaddr, 12710 ¶m->peer_info[i].peer_macaddr, 12711 sizeof(param->peer_info[i].peer_macaddr)); 12712 peer_info->vdev_id = 12713 param->peer_info[i].vdev_id; 12714 peer_info->pdev_id = 12715 wmi_handle->ops->convert_pdev_id_host_to_target( 12716 param->peer_info[i].pdev_id); 12717 peer_info++; 12718 } 12719 12720 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12721 WMI_PEER_BWF_REQUEST_CMDID); 12722 12723 if (retval != QDF_STATUS_SUCCESS) { 12724 WMI_LOGE("%s : WMI Failed\n", __func__); 12725 wmi_buf_free(buf); 12726 } 12727 12728 return retval; 12729 } 12730 12731 /** 12732 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12733 * @wmi_handle: wmi handle 12734 * @param: pointer to hold mcast update param 12735 * 12736 * Return: 0 for success or error code 12737 */ 12738 static QDF_STATUS 12739 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12740 struct mcast_group_update_params *param) 12741 { 12742 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12743 wmi_buf_t buf; 12744 QDF_STATUS ret; 12745 int32_t len; 12746 int offset = 0; 12747 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12748 12749 len = sizeof(*cmd); 12750 buf = wmi_buf_alloc(wmi_handle, len); 12751 if (!buf) { 12752 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12753 return QDF_STATUS_E_FAILURE; 12754 } 12755 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12756 WMITLV_SET_HDR(&cmd->tlv_header, 12757 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12758 WMITLV_GET_STRUCT_TLVLEN( 12759 wmi_peer_mcast_group_cmd_fixed_param)); 12760 /* confirm the buffer is 4-byte aligned */ 12761 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12762 qdf_mem_zero(cmd, sizeof(*cmd)); 12763 12764 cmd->vdev_id = param->vap_id; 12765 /* construct the message assuming our endianness matches the target */ 12766 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12767 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12768 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12769 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12770 if (param->is_action_delete) 12771 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12772 12773 if (param->is_mcast_addr_len) 12774 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12775 12776 if (param->is_filter_mode_snoop) 12777 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12778 12779 /* unicast address spec only applies for non-wildcard cases */ 12780 if (!param->wildcard && param->ucast_mac_addr) { 12781 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12782 &cmd->ucast_mac_addr); 12783 } 12784 12785 if (param->mcast_ip_addr) { 12786 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12787 sizeof(cmd->mcast_ip_addr)); 12788 offset = sizeof(cmd->mcast_ip_addr) - 12789 param->mcast_ip_addr_bytes; 12790 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12791 param->mcast_ip_addr, 12792 param->mcast_ip_addr_bytes); 12793 } 12794 if (!param->mask) 12795 param->mask = &dummymask[0]; 12796 12797 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12798 param->mask, 12799 param->mcast_ip_addr_bytes); 12800 12801 if (param->srcs && param->nsrcs) { 12802 cmd->num_filter_addr = param->nsrcs; 12803 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12804 sizeof(cmd->filter_addr)); 12805 12806 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12807 param->nsrcs * param->mcast_ip_addr_bytes); 12808 } 12809 12810 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12811 WMI_PEER_MCAST_GROUP_CMDID); 12812 12813 if (ret != QDF_STATUS_SUCCESS) { 12814 WMI_LOGE("%s : WMI Failed\n", __func__); 12815 wmi_buf_free(buf); 12816 } 12817 12818 return ret; 12819 } 12820 12821 /** 12822 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12823 * command to fw 12824 * @wmi_handle: wmi handle 12825 * @param: pointer to hold spectral config parameter 12826 * 12827 * Return: 0 for success or error code 12828 */ 12829 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12830 struct vdev_spectral_configure_params *param) 12831 { 12832 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12833 wmi_buf_t buf; 12834 QDF_STATUS ret; 12835 int32_t len; 12836 12837 len = sizeof(*cmd); 12838 buf = wmi_buf_alloc(wmi_handle, len); 12839 if (!buf) { 12840 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12841 return QDF_STATUS_E_FAILURE; 12842 } 12843 12844 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12845 WMITLV_SET_HDR(&cmd->tlv_header, 12846 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12847 WMITLV_GET_STRUCT_TLVLEN( 12848 wmi_vdev_spectral_configure_cmd_fixed_param)); 12849 12850 cmd->vdev_id = param->vdev_id; 12851 cmd->spectral_scan_count = param->count; 12852 cmd->spectral_scan_period = param->period; 12853 cmd->spectral_scan_priority = param->spectral_pri; 12854 cmd->spectral_scan_fft_size = param->fft_size; 12855 cmd->spectral_scan_gc_ena = param->gc_enable; 12856 cmd->spectral_scan_restart_ena = param->restart_enable; 12857 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12858 cmd->spectral_scan_init_delay = param->init_delay; 12859 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12860 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12861 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12862 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12863 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12864 cmd->spectral_scan_pwr_format = param->pwr_format; 12865 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12866 cmd->spectral_scan_bin_scale = param->bin_scale; 12867 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12868 cmd->spectral_scan_chn_mask = param->chn_mask; 12869 12870 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12871 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12872 12873 if (ret != 0) { 12874 WMI_LOGE("Sending set quiet cmd failed\n"); 12875 wmi_buf_free(buf); 12876 } 12877 12878 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12879 __func__); 12880 12881 WMI_LOGI("vdev_id = %u\n" 12882 "spectral_scan_count = %u\n" 12883 "spectral_scan_period = %u\n" 12884 "spectral_scan_priority = %u\n" 12885 "spectral_scan_fft_size = %u\n" 12886 "spectral_scan_gc_ena = %u\n" 12887 "spectral_scan_restart_ena = %u\n" 12888 "spectral_scan_noise_floor_ref = %u\n" 12889 "spectral_scan_init_delay = %u\n" 12890 "spectral_scan_nb_tone_thr = %u\n" 12891 "spectral_scan_str_bin_thr = %u\n" 12892 "spectral_scan_wb_rpt_mode = %u\n" 12893 "spectral_scan_rssi_rpt_mode = %u\n" 12894 "spectral_scan_rssi_thr = %u\n" 12895 "spectral_scan_pwr_format = %u\n" 12896 "spectral_scan_rpt_mode = %u\n" 12897 "spectral_scan_bin_scale = %u\n" 12898 "spectral_scan_dBm_adj = %u\n" 12899 "spectral_scan_chn_mask = %u\n", 12900 param->vdev_id, 12901 param->count, 12902 param->period, 12903 param->spectral_pri, 12904 param->fft_size, 12905 param->gc_enable, 12906 param->restart_enable, 12907 param->noise_floor_ref, 12908 param->init_delay, 12909 param->nb_tone_thr, 12910 param->str_bin_thr, 12911 param->wb_rpt_mode, 12912 param->rssi_rpt_mode, 12913 param->rssi_thr, 12914 param->pwr_format, 12915 param->rpt_mode, 12916 param->bin_scale, 12917 param->dbm_adj, 12918 param->chn_mask); 12919 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12920 12921 return ret; 12922 } 12923 12924 /** 12925 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12926 * command to fw 12927 * @wmi_handle: wmi handle 12928 * @param: pointer to hold spectral enable parameter 12929 * 12930 * Return: 0 for success or error code 12931 */ 12932 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12933 struct vdev_spectral_enable_params *param) 12934 { 12935 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12936 wmi_buf_t buf; 12937 QDF_STATUS ret; 12938 int32_t len; 12939 12940 len = sizeof(*cmd); 12941 buf = wmi_buf_alloc(wmi_handle, len); 12942 if (!buf) { 12943 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12944 return QDF_STATUS_E_FAILURE; 12945 } 12946 12947 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12948 WMITLV_SET_HDR(&cmd->tlv_header, 12949 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12950 WMITLV_GET_STRUCT_TLVLEN( 12951 wmi_vdev_spectral_enable_cmd_fixed_param)); 12952 12953 cmd->vdev_id = param->vdev_id; 12954 12955 if (param->active_valid) { 12956 cmd->trigger_cmd = param->active ? 1 : 2; 12957 /* 1: Trigger, 2: Clear Trigger */ 12958 } else { 12959 cmd->trigger_cmd = 0; /* 0: Ignore */ 12960 } 12961 12962 if (param->enabled_valid) { 12963 cmd->enable_cmd = param->enabled ? 1 : 2; 12964 /* 1: Enable 2: Disable */ 12965 } else { 12966 cmd->enable_cmd = 0; /* 0: Ignore */ 12967 } 12968 12969 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12970 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12971 12972 if (ret != 0) { 12973 WMI_LOGE("Sending scan enable CMD failed\n"); 12974 wmi_buf_free(buf); 12975 } 12976 12977 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12978 12979 WMI_LOGI("vdev_id = %u\n" 12980 "trigger_cmd = %u\n" 12981 "enable_cmd = %u\n", 12982 cmd->vdev_id, 12983 cmd->trigger_cmd, 12984 cmd->enable_cmd); 12985 12986 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12987 12988 return ret; 12989 } 12990 12991 /** 12992 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12993 * @param wmi_handle : handle to WMI. 12994 * @param param : pointer to hold thermal mitigation param 12995 * 12996 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12997 */ 12998 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12999 wmi_unified_t wmi_handle, 13000 struct thermal_mitigation_params *param) 13001 { 13002 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 13003 wmi_therm_throt_level_config_info *lvl_conf = NULL; 13004 wmi_buf_t buf = NULL; 13005 uint8_t *buf_ptr = NULL; 13006 int error; 13007 int32_t len; 13008 int i; 13009 13010 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 13011 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 13012 13013 buf = wmi_buf_alloc(wmi_handle, len); 13014 if (!buf) { 13015 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13016 return QDF_STATUS_E_NOMEM; 13017 } 13018 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 13019 13020 /* init fixed params */ 13021 WMITLV_SET_HDR(tt_conf, 13022 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 13023 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 13024 13025 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13026 param->pdev_id); 13027 tt_conf->enable = param->enable; 13028 tt_conf->dc = param->dc; 13029 tt_conf->dc_per_event = param->dc_per_event; 13030 tt_conf->therm_throt_levels = THERMAL_LEVELS; 13031 13032 buf_ptr = (uint8_t *) ++tt_conf; 13033 /* init TLV params */ 13034 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13035 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 13036 13037 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 13038 for (i = 0; i < THERMAL_LEVELS; i++) { 13039 WMITLV_SET_HDR(&lvl_conf->tlv_header, 13040 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 13041 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 13042 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 13043 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 13044 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 13045 lvl_conf->prio = param->levelconf[i].priority; 13046 lvl_conf++; 13047 } 13048 13049 error = wmi_unified_cmd_send(wmi_handle, buf, len, 13050 WMI_THERM_THROT_SET_CONF_CMDID); 13051 if (QDF_IS_STATUS_ERROR(error)) { 13052 wmi_buf_free(buf); 13053 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 13054 } 13055 13056 return error; 13057 } 13058 13059 /** 13060 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 13061 * @wmi_handle: wmi handle 13062 * @param: pointer to pdev_qvit_params 13063 * 13064 * Return: 0 for success or error code 13065 */ 13066 static QDF_STATUS 13067 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 13068 struct pdev_qvit_params *param) 13069 { 13070 wmi_buf_t buf; 13071 QDF_STATUS ret = QDF_STATUS_E_INVAL; 13072 uint8_t *cmd; 13073 static uint8_t msgref = 1; 13074 uint8_t segnumber = 0, seginfo, numsegments; 13075 uint16_t chunk_len, total_bytes; 13076 uint8_t *bufpos; 13077 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 13078 13079 bufpos = param->utf_payload; 13080 total_bytes = param->len; 13081 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 13082 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 13083 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 13084 13085 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 13086 numsegments++; 13087 13088 while (param->len) { 13089 if (param->len > MAX_WMI_QVIT_LEN) 13090 chunk_len = MAX_WMI_QVIT_LEN; /* MAX messsage */ 13091 else 13092 chunk_len = param->len; 13093 13094 buf = wmi_buf_alloc(wmi_handle, 13095 (chunk_len + sizeof(seghdrinfo) + 13096 WMI_TLV_HDR_SIZE)); 13097 if (!buf) { 13098 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 13099 return QDF_STATUS_E_NOMEM; 13100 } 13101 13102 cmd = (uint8_t *) wmi_buf_data(buf); 13103 13104 seghdrinfo.len = total_bytes; 13105 seghdrinfo.msgref = msgref; 13106 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 13107 seghdrinfo.segmentInfo = seginfo; 13108 13109 segnumber++; 13110 13111 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 13112 (chunk_len + sizeof(seghdrinfo))); 13113 cmd += WMI_TLV_HDR_SIZE; 13114 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 13115 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 13116 13117 ret = wmi_unified_cmd_send(wmi_handle, buf, 13118 (chunk_len + sizeof(seghdrinfo) + 13119 WMI_TLV_HDR_SIZE), 13120 WMI_PDEV_QVIT_CMDID); 13121 13122 if (ret != 0) { 13123 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 13124 wmi_buf_free(buf); 13125 break; 13126 } 13127 13128 param->len -= chunk_len; 13129 bufpos += chunk_len; 13130 } 13131 msgref++; 13132 13133 return ret; 13134 } 13135 13136 /** 13137 * send_wmm_update_cmd_tlv() - send wmm update command to fw 13138 * @wmi_handle: wmi handle 13139 * @param: pointer to wmm update param 13140 * 13141 * Return: 0 for success or error code 13142 */ 13143 static QDF_STATUS 13144 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 13145 struct wmm_update_params *param) 13146 { 13147 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 13148 wmi_wmm_params *wmm_param; 13149 wmi_buf_t buf; 13150 QDF_STATUS ret; 13151 int32_t len; 13152 int ac = 0; 13153 struct wmi_host_wmeParams *wmep; 13154 uint8_t *buf_ptr; 13155 13156 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 13157 buf = wmi_buf_alloc(wmi_handle, len); 13158 if (!buf) { 13159 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13160 return QDF_STATUS_E_FAILURE; 13161 } 13162 13163 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13164 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 13165 WMITLV_SET_HDR(&cmd->tlv_header, 13166 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 13167 WMITLV_GET_STRUCT_TLVLEN 13168 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 13169 13170 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 13171 13172 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 13173 13174 for (ac = 0; ac < WME_NUM_AC; ac++) { 13175 wmep = ¶m->wmep_array[ac]; 13176 wmm_param = (wmi_wmm_params *)buf_ptr; 13177 WMITLV_SET_HDR(&wmm_param->tlv_header, 13178 WMITLV_TAG_STRUC_wmi_wmm_params, 13179 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 13180 wmm_param->aifs = wmep->wmep_aifsn; 13181 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 13182 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 13183 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 13184 wmm_param->acm = wmep->wmep_acm; 13185 wmm_param->no_ack = wmep->wmep_noackPolicy; 13186 buf_ptr += sizeof(wmi_wmm_params); 13187 } 13188 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13189 WMI_PDEV_SET_WMM_PARAMS_CMDID); 13190 13191 if (ret != 0) { 13192 WMI_LOGE("Sending WMM update CMD failed\n"); 13193 wmi_buf_free(buf); 13194 } 13195 13196 return ret; 13197 } 13198 13199 /** 13200 * send_coex_config_cmd_tlv() - send coex config command to fw 13201 * @wmi_handle: wmi handle 13202 * @param: pointer to coex config param 13203 * 13204 * Return: 0 for success or error code 13205 */ 13206 static QDF_STATUS 13207 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 13208 struct coex_config_params *param) 13209 { 13210 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 13211 wmi_buf_t buf; 13212 QDF_STATUS ret; 13213 int32_t len; 13214 13215 len = sizeof(*cmd); 13216 buf = wmi_buf_alloc(wmi_handle, len); 13217 if (!buf) { 13218 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 13219 return QDF_STATUS_E_FAILURE; 13220 } 13221 13222 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 13223 WMITLV_SET_HDR(&cmd->tlv_header, 13224 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 13225 WMITLV_GET_STRUCT_TLVLEN( 13226 WMI_COEX_CONFIG_CMD_fixed_param)); 13227 13228 cmd->vdev_id = param->vdev_id; 13229 cmd->config_type = param->config_type; 13230 cmd->config_arg1 = param->config_arg1; 13231 cmd->config_arg2 = param->config_arg2; 13232 cmd->config_arg3 = param->config_arg3; 13233 cmd->config_arg4 = param->config_arg4; 13234 cmd->config_arg5 = param->config_arg5; 13235 cmd->config_arg6 = param->config_arg6; 13236 13237 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13238 WMI_COEX_CONFIG_CMDID); 13239 13240 if (ret != 0) { 13241 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 13242 wmi_buf_free(buf); 13243 } 13244 13245 return ret; 13246 } 13247 13248 13249 #ifdef WLAN_SUPPORT_TWT 13250 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 13251 target_resource_config *tgt_res_cfg) 13252 { 13253 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 13254 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 13255 } 13256 #else 13257 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 13258 target_resource_config *tgt_res_cfg) 13259 { 13260 resource_cfg->twt_ap_pdev_count = 0; 13261 resource_cfg->twt_ap_sta_count = 0; 13262 } 13263 #endif 13264 13265 static 13266 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 13267 target_resource_config *tgt_res_cfg) 13268 { 13269 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 13270 resource_cfg->num_peers = tgt_res_cfg->num_peers; 13271 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 13272 resource_cfg->num_offload_reorder_buffs = 13273 tgt_res_cfg->num_offload_reorder_buffs; 13274 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 13275 resource_cfg->num_tids = tgt_res_cfg->num_tids; 13276 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 13277 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 13278 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 13279 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 13280 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 13281 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 13282 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 13283 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 13284 resource_cfg->scan_max_pending_req = 13285 tgt_res_cfg->scan_max_pending_req; 13286 resource_cfg->bmiss_offload_max_vdev = 13287 tgt_res_cfg->bmiss_offload_max_vdev; 13288 resource_cfg->roam_offload_max_vdev = 13289 tgt_res_cfg->roam_offload_max_vdev; 13290 resource_cfg->roam_offload_max_ap_profiles = 13291 tgt_res_cfg->roam_offload_max_ap_profiles; 13292 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 13293 resource_cfg->num_mcast_table_elems = 13294 tgt_res_cfg->num_mcast_table_elems; 13295 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 13296 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 13297 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 13298 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 13299 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 13300 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 13301 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 13302 resource_cfg->vow_config = tgt_res_cfg->vow_config; 13303 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 13304 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 13305 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 13306 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 13307 resource_cfg->num_tdls_conn_table_entries = 13308 tgt_res_cfg->num_tdls_conn_table_entries; 13309 resource_cfg->beacon_tx_offload_max_vdev = 13310 tgt_res_cfg->beacon_tx_offload_max_vdev; 13311 resource_cfg->num_multicast_filter_entries = 13312 tgt_res_cfg->num_multicast_filter_entries; 13313 resource_cfg->num_wow_filters = 13314 tgt_res_cfg->num_wow_filters; 13315 resource_cfg->num_keep_alive_pattern = 13316 tgt_res_cfg->num_keep_alive_pattern; 13317 resource_cfg->keep_alive_pattern_size = 13318 tgt_res_cfg->keep_alive_pattern_size; 13319 resource_cfg->max_tdls_concurrent_sleep_sta = 13320 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 13321 resource_cfg->max_tdls_concurrent_buffer_sta = 13322 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 13323 resource_cfg->wmi_send_separate = 13324 tgt_res_cfg->wmi_send_separate; 13325 resource_cfg->num_ocb_vdevs = 13326 tgt_res_cfg->num_ocb_vdevs; 13327 resource_cfg->num_ocb_channels = 13328 tgt_res_cfg->num_ocb_channels; 13329 resource_cfg->num_ocb_schedules = 13330 tgt_res_cfg->num_ocb_schedules; 13331 resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size; 13332 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 13333 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 13334 resource_cfg->max_num_dbs_scan_duty_cycle = 13335 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 13336 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 13337 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 13338 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 13339 13340 if (tgt_res_cfg->atf_config) 13341 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 13342 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 13343 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 13344 resource_cfg->flag1, 1); 13345 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 13346 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 13347 resource_cfg->flag1, 1); 13348 if (tgt_res_cfg->cce_disable) 13349 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 13350 13351 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 13352 } 13353 13354 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 13355 * @wmi_handle: pointer to wmi handle 13356 * @buf_ptr: pointer to current position in init command buffer 13357 * @len: pointer to length. This will be updated with current length of cmd 13358 * @param: point host parameters for init command 13359 * 13360 * Return: Updated pointer of buf_ptr. 13361 */ 13362 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 13363 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 13364 { 13365 uint16_t idx; 13366 13367 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 13368 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 13369 wmi_pdev_band_to_mac *band_to_mac; 13370 13371 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 13372 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 13373 sizeof(wmi_resource_config) + 13374 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 13375 sizeof(wlan_host_memory_chunk))); 13376 13377 WMITLV_SET_HDR(&hw_mode->tlv_header, 13378 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13379 (WMITLV_GET_STRUCT_TLVLEN 13380 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 13381 13382 hw_mode->hw_mode_index = param->hw_mode_id; 13383 hw_mode->num_band_to_mac = param->num_band_to_mac; 13384 13385 buf_ptr = (uint8_t *) (hw_mode + 1); 13386 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 13387 WMI_TLV_HDR_SIZE); 13388 for (idx = 0; idx < param->num_band_to_mac; idx++) { 13389 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 13390 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 13391 WMITLV_GET_STRUCT_TLVLEN 13392 (wmi_pdev_band_to_mac)); 13393 band_to_mac[idx].pdev_id = 13394 wmi_handle->ops->convert_pdev_id_host_to_target( 13395 param->band_to_mac[idx].pdev_id); 13396 band_to_mac[idx].start_freq = 13397 param->band_to_mac[idx].start_freq; 13398 band_to_mac[idx].end_freq = 13399 param->band_to_mac[idx].end_freq; 13400 } 13401 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 13402 (param->num_band_to_mac * 13403 sizeof(wmi_pdev_band_to_mac)) + 13404 WMI_TLV_HDR_SIZE; 13405 13406 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13407 (param->num_band_to_mac * 13408 sizeof(wmi_pdev_band_to_mac))); 13409 } 13410 13411 return buf_ptr; 13412 } 13413 13414 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 13415 wmi_init_cmd_fixed_param *cmd) 13416 { 13417 int num_whitelist; 13418 wmi_abi_version my_vers; 13419 13420 num_whitelist = sizeof(version_whitelist) / 13421 sizeof(wmi_whitelist_version_info); 13422 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 13423 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 13424 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 13425 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 13426 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 13427 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 13428 13429 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 13430 &my_vers, 13431 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 13432 &cmd->host_abi_vers); 13433 13434 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 13435 __func__, 13436 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 13437 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 13438 cmd->host_abi_vers.abi_version_ns_0, 13439 cmd->host_abi_vers.abi_version_ns_1, 13440 cmd->host_abi_vers.abi_version_ns_2, 13441 cmd->host_abi_vers.abi_version_ns_3); 13442 13443 /* Save version sent from host - 13444 * Will be used to check ready event 13445 */ 13446 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 13447 sizeof(wmi_abi_version)); 13448 } 13449 13450 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13451 { 13452 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13453 wmi_service_ready_event_fixed_param *ev; 13454 13455 13456 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13457 13458 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13459 if (!ev) 13460 return QDF_STATUS_E_FAILURE; 13461 13462 /*Save fw version from service ready message */ 13463 /*This will be used while sending INIT message */ 13464 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13465 sizeof(wmi_handle->fw_abi_version)); 13466 13467 return QDF_STATUS_SUCCESS; 13468 } 13469 13470 /** 13471 * wmi_unified_save_fw_version_cmd() - save fw version 13472 * @wmi_handle: pointer to wmi handle 13473 * @res_cfg: resource config 13474 * @num_mem_chunks: no of mem chunck 13475 * @mem_chunk: pointer to mem chunck structure 13476 * 13477 * This function sends IE information to firmware 13478 * 13479 * Return: QDF_STATUS_SUCCESS for success otherwise failure 13480 * 13481 */ 13482 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 13483 void *evt_buf) 13484 { 13485 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13486 wmi_ready_event_fixed_param *ev = NULL; 13487 13488 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13489 ev = param_buf->fixed_param; 13490 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 13491 &wmi_handle->final_abi_vers, 13492 &ev->fw_abi_vers)) { 13493 /* 13494 * Error: Our host version and the given firmware version 13495 * are incompatible. 13496 **/ 13497 WMI_LOGD("%s: Error: Incompatible WMI version." 13498 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 13499 __func__, 13500 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 13501 abi_version_0), 13502 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 13503 abi_version_0), 13504 wmi_handle->final_abi_vers.abi_version_ns_0, 13505 wmi_handle->final_abi_vers.abi_version_ns_1, 13506 wmi_handle->final_abi_vers.abi_version_ns_2, 13507 wmi_handle->final_abi_vers.abi_version_ns_3, 13508 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 13509 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 13510 ev->fw_abi_vers.abi_version_ns_0, 13511 ev->fw_abi_vers.abi_version_ns_1, 13512 ev->fw_abi_vers.abi_version_ns_2, 13513 ev->fw_abi_vers.abi_version_ns_3); 13514 13515 return QDF_STATUS_E_FAILURE; 13516 } 13517 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 13518 sizeof(wmi_abi_version)); 13519 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13520 sizeof(wmi_abi_version)); 13521 13522 return QDF_STATUS_SUCCESS; 13523 } 13524 13525 /** 13526 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 13527 * @wmi_handle: wmi handle 13528 * @custom_addr: base mac address 13529 * 13530 * Return: QDF_STATUS_SUCCESS for success or error code 13531 */ 13532 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 13533 uint8_t *custom_addr) 13534 { 13535 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 13536 wmi_buf_t buf; 13537 int err; 13538 13539 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13540 if (!buf) { 13541 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 13542 return QDF_STATUS_E_NOMEM; 13543 } 13544 13545 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 13546 qdf_mem_zero(cmd, sizeof(*cmd)); 13547 13548 WMITLV_SET_HDR(&cmd->tlv_header, 13549 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 13550 WMITLV_GET_STRUCT_TLVLEN 13551 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 13552 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 13553 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13554 WMI_HOST_PDEV_ID_SOC); 13555 err = wmi_unified_cmd_send(wmi_handle, buf, 13556 sizeof(*cmd), 13557 WMI_PDEV_SET_BASE_MACADDR_CMDID); 13558 if (err) { 13559 WMI_LOGE("Failed to send set_base_macaddr cmd"); 13560 wmi_buf_free(buf); 13561 return QDF_STATUS_E_FAILURE; 13562 } 13563 13564 return 0; 13565 } 13566 13567 /** 13568 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 13569 * @handle: wmi handle 13570 * @event: Event received from FW 13571 * @len: Length of the event 13572 * 13573 * Enables the low frequency events and disables the high frequency 13574 * events. Bit 17 indicates if the event if low/high frequency. 13575 * 1 - high frequency, 0 - low frequency 13576 * 13577 * Return: 0 on successfully enabling/disabling the events 13578 */ 13579 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 13580 uint8_t *event, 13581 uint32_t len) 13582 { 13583 uint32_t num_of_diag_events_logs; 13584 wmi_diag_event_log_config_fixed_param *cmd; 13585 wmi_buf_t buf; 13586 uint8_t *buf_ptr; 13587 uint32_t *cmd_args, *evt_args; 13588 uint32_t buf_len, i; 13589 13590 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 13591 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 13592 13593 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 13594 13595 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 13596 if (!param_buf) { 13597 WMI_LOGE("Invalid log supported event buffer"); 13598 return QDF_STATUS_E_INVAL; 13599 } 13600 wmi_event = param_buf->fixed_param; 13601 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 13602 13603 if (num_of_diag_events_logs > 13604 param_buf->num_diag_events_logs_list) { 13605 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 13606 num_of_diag_events_logs, 13607 param_buf->num_diag_events_logs_list); 13608 return QDF_STATUS_E_INVAL; 13609 } 13610 13611 evt_args = param_buf->diag_events_logs_list; 13612 if (!evt_args) { 13613 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 13614 __func__, num_of_diag_events_logs); 13615 return QDF_STATUS_E_INVAL; 13616 } 13617 13618 WMI_LOGD("%s: num_of_diag_events_logs=%d", 13619 __func__, num_of_diag_events_logs); 13620 13621 /* Free any previous allocation */ 13622 if (wmi_handle->events_logs_list) 13623 qdf_mem_free(wmi_handle->events_logs_list); 13624 13625 if (num_of_diag_events_logs > 13626 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 13627 WMI_LOGE("%s: excess num of logs:%d", __func__, 13628 num_of_diag_events_logs); 13629 QDF_ASSERT(0); 13630 return QDF_STATUS_E_INVAL; 13631 } 13632 /* Store the event list for run time enable/disable */ 13633 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 13634 sizeof(uint32_t)); 13635 if (!wmi_handle->events_logs_list) { 13636 WMI_LOGE("%s: event log list memory allocation failed", 13637 __func__); 13638 return QDF_STATUS_E_NOMEM; 13639 } 13640 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 13641 13642 /* Prepare the send buffer */ 13643 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13644 (num_of_diag_events_logs * sizeof(uint32_t)); 13645 13646 buf = wmi_buf_alloc(wmi_handle, buf_len); 13647 if (!buf) { 13648 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13649 qdf_mem_free(wmi_handle->events_logs_list); 13650 wmi_handle->events_logs_list = NULL; 13651 return QDF_STATUS_E_NOMEM; 13652 } 13653 13654 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13655 buf_ptr = (uint8_t *) cmd; 13656 13657 WMITLV_SET_HDR(&cmd->tlv_header, 13658 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13659 WMITLV_GET_STRUCT_TLVLEN( 13660 wmi_diag_event_log_config_fixed_param)); 13661 13662 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13663 13664 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13665 13666 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13667 (num_of_diag_events_logs * sizeof(uint32_t))); 13668 13669 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13670 13671 /* Populate the events */ 13672 for (i = 0; i < num_of_diag_events_logs; i++) { 13673 /* Low freq (0) - Enable (1) the event 13674 * High freq (1) - Disable (0) the event 13675 */ 13676 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13677 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13678 /* Set the event ID */ 13679 WMI_DIAG_ID_SET(cmd_args[i], 13680 WMI_DIAG_ID_GET(evt_args[i])); 13681 /* Set the type */ 13682 WMI_DIAG_TYPE_SET(cmd_args[i], 13683 WMI_DIAG_TYPE_GET(evt_args[i])); 13684 /* Storing the event/log list in WMI */ 13685 wmi_handle->events_logs_list[i] = evt_args[i]; 13686 } 13687 13688 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13689 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13690 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13691 __func__); 13692 wmi_buf_free(buf); 13693 /* Not clearing events_logs_list, though wmi cmd failed. 13694 * Host can still have this list 13695 */ 13696 return QDF_STATUS_E_INVAL; 13697 } 13698 13699 return 0; 13700 } 13701 13702 /** 13703 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13704 * @wmi_handle: wmi handle 13705 * @start_log: Start logging related parameters 13706 * 13707 * Send the command to the FW based on which specific logging of diag 13708 * event/log id can be started/stopped 13709 * 13710 * Return: None 13711 */ 13712 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13713 struct wmi_wifi_start_log *start_log) 13714 { 13715 wmi_diag_event_log_config_fixed_param *cmd; 13716 wmi_buf_t buf; 13717 uint8_t *buf_ptr; 13718 uint32_t len, count, log_level, i; 13719 uint32_t *cmd_args; 13720 uint32_t total_len; 13721 count = 0; 13722 13723 if (!wmi_handle->events_logs_list) { 13724 WMI_LOGE("%s: Not received event/log list from FW, yet", 13725 __func__); 13726 return QDF_STATUS_E_NOMEM; 13727 } 13728 /* total_len stores the number of events where BITS 17 and 18 are set. 13729 * i.e., events of high frequency (17) and for extended debugging (18) 13730 */ 13731 total_len = 0; 13732 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13733 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13734 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13735 total_len++; 13736 } 13737 13738 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13739 (total_len * sizeof(uint32_t)); 13740 13741 buf = wmi_buf_alloc(wmi_handle, len); 13742 if (!buf) { 13743 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13744 return QDF_STATUS_E_NOMEM; 13745 } 13746 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13747 buf_ptr = (uint8_t *) cmd; 13748 13749 WMITLV_SET_HDR(&cmd->tlv_header, 13750 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13751 WMITLV_GET_STRUCT_TLVLEN( 13752 wmi_diag_event_log_config_fixed_param)); 13753 13754 cmd->num_of_diag_events_logs = total_len; 13755 13756 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13757 13758 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13759 (total_len * sizeof(uint32_t))); 13760 13761 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13762 13763 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13764 log_level = 1; 13765 else 13766 log_level = 0; 13767 13768 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13769 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13770 uint32_t val = wmi_handle->events_logs_list[i]; 13771 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13772 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13773 13774 WMI_DIAG_ID_SET(cmd_args[count], 13775 WMI_DIAG_ID_GET(val)); 13776 WMI_DIAG_TYPE_SET(cmd_args[count], 13777 WMI_DIAG_TYPE_GET(val)); 13778 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13779 log_level); 13780 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13781 count++; 13782 } 13783 } 13784 13785 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13786 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13787 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13788 __func__); 13789 wmi_buf_free(buf); 13790 return QDF_STATUS_E_INVAL; 13791 } 13792 13793 return QDF_STATUS_SUCCESS; 13794 } 13795 13796 /** 13797 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13798 * @wmi_handle: WMI handle 13799 * 13800 * This function is used to send the flush command to the FW, 13801 * that will flush the fw logs that are residue in the FW 13802 * 13803 * Return: None 13804 */ 13805 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13806 { 13807 wmi_debug_mesg_flush_fixed_param *cmd; 13808 wmi_buf_t buf; 13809 int len = sizeof(*cmd); 13810 QDF_STATUS ret; 13811 13812 buf = wmi_buf_alloc(wmi_handle, len); 13813 if (!buf) { 13814 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13815 return QDF_STATUS_E_NOMEM; 13816 } 13817 13818 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13819 WMITLV_SET_HDR(&cmd->tlv_header, 13820 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13821 WMITLV_GET_STRUCT_TLVLEN( 13822 wmi_debug_mesg_flush_fixed_param)); 13823 cmd->reserved0 = 0; 13824 13825 ret = wmi_unified_cmd_send(wmi_handle, 13826 buf, 13827 len, 13828 WMI_DEBUG_MESG_FLUSH_CMDID); 13829 if (QDF_IS_STATUS_ERROR(ret)) { 13830 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13831 wmi_buf_free(buf); 13832 return QDF_STATUS_E_INVAL; 13833 } 13834 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13835 13836 return ret; 13837 } 13838 13839 /** 13840 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13841 * @wmi_handle: wmi handle 13842 * @msg: PCL structure containing the PCL and the number of channels 13843 * 13844 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13845 * firmware. The DBS Manager is the consumer of this information in the WLAN 13846 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13847 * to migrate to a new channel without host driver involvement. An example of 13848 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13849 * manage the channel selection without firmware involvement. 13850 * 13851 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13852 * channel list. The weights corresponds to the channels sent in 13853 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13854 * weightage compared to the non PCL channels. 13855 * 13856 * Return: Success if the cmd is sent successfully to the firmware 13857 */ 13858 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13859 struct wmi_pcl_chan_weights *msg) 13860 { 13861 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13862 wmi_buf_t buf; 13863 uint8_t *buf_ptr; 13864 uint32_t *cmd_args, i, len; 13865 uint32_t chan_len; 13866 13867 chan_len = msg->saved_num_chan; 13868 13869 len = sizeof(*cmd) + 13870 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13871 13872 buf = wmi_buf_alloc(wmi_handle, len); 13873 if (!buf) { 13874 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13875 return QDF_STATUS_E_NOMEM; 13876 } 13877 13878 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13879 buf_ptr = (uint8_t *) cmd; 13880 WMITLV_SET_HDR(&cmd->tlv_header, 13881 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13882 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13883 13884 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13885 WMI_HOST_PDEV_ID_SOC); 13886 cmd->num_chan = chan_len; 13887 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13888 13889 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13890 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13891 (chan_len * sizeof(uint32_t))); 13892 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13893 for (i = 0; i < chan_len ; i++) { 13894 cmd_args[i] = msg->weighed_valid_list[i]; 13895 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13896 msg->saved_chan_list[i], cmd_args[i]); 13897 } 13898 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13899 WMI_PDEV_SET_PCL_CMDID)) { 13900 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13901 wmi_buf_free(buf); 13902 return QDF_STATUS_E_FAILURE; 13903 } 13904 return QDF_STATUS_SUCCESS; 13905 } 13906 13907 /** 13908 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13909 * @wmi_handle: wmi handle 13910 * @msg: Structure containing the following parameters 13911 * 13912 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13913 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13914 * 13915 * Provides notification to the WLAN firmware that host driver is requesting a 13916 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13917 * configurations that include the Dual Band Simultaneous (DBS) feature. 13918 * 13919 * Return: Success if the cmd is sent successfully to the firmware 13920 */ 13921 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13922 uint32_t hw_mode_index) 13923 { 13924 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13925 wmi_buf_t buf; 13926 uint32_t len; 13927 13928 len = sizeof(*cmd); 13929 13930 buf = wmi_buf_alloc(wmi_handle, len); 13931 if (!buf) { 13932 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13933 return QDF_STATUS_E_NOMEM; 13934 } 13935 13936 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13937 WMITLV_SET_HDR(&cmd->tlv_header, 13938 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13939 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13940 13941 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13942 WMI_HOST_PDEV_ID_SOC); 13943 cmd->hw_mode_index = hw_mode_index; 13944 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13945 13946 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13947 WMI_PDEV_SET_HW_MODE_CMDID)) { 13948 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13949 __func__); 13950 wmi_buf_free(buf); 13951 return QDF_STATUS_E_FAILURE; 13952 } 13953 13954 return QDF_STATUS_SUCCESS; 13955 } 13956 13957 #ifdef WLAN_POLICY_MGR_ENABLE 13958 /** 13959 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13960 * @wmi_handle: wmi handle 13961 * @msg: Dual MAC config parameters 13962 * 13963 * Configures WLAN firmware with the dual MAC features 13964 * 13965 * Return: QDF_STATUS. 0 on success. 13966 */ 13967 static 13968 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13969 struct policy_mgr_dual_mac_config *msg) 13970 { 13971 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13972 wmi_buf_t buf; 13973 uint32_t len; 13974 13975 len = sizeof(*cmd); 13976 13977 buf = wmi_buf_alloc(wmi_handle, len); 13978 if (!buf) { 13979 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13980 return QDF_STATUS_E_FAILURE; 13981 } 13982 13983 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13984 WMITLV_SET_HDR(&cmd->tlv_header, 13985 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13986 WMITLV_GET_STRUCT_TLVLEN( 13987 wmi_pdev_set_mac_config_cmd_fixed_param)); 13988 13989 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13990 WMI_HOST_PDEV_ID_SOC); 13991 cmd->concurrent_scan_config_bits = msg->scan_config; 13992 cmd->fw_mode_config_bits = msg->fw_mode_config; 13993 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 13994 __func__, msg->scan_config, msg->fw_mode_config); 13995 13996 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13997 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13998 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13999 __func__); 14000 wmi_buf_free(buf); 14001 } 14002 return QDF_STATUS_SUCCESS; 14003 } 14004 #endif 14005 14006 #ifdef BIG_ENDIAN_HOST 14007 /** 14008 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14009 * @param data_len - data length 14010 * @param data - pointer to data 14011 * 14012 * Return: QDF_STATUS - success or error status 14013 */ 14014 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14015 struct fips_params *param) 14016 { 14017 unsigned char *key_unaligned, *data_unaligned; 14018 int c; 14019 u_int8_t *key_aligned = NULL; 14020 u_int8_t *data_aligned = NULL; 14021 14022 /* Assigning unaligned space to copy the key */ 14023 key_unaligned = qdf_mem_malloc( 14024 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 14025 data_unaligned = qdf_mem_malloc( 14026 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 14027 14028 /* Checking if kmalloc is succesful to allocate space */ 14029 if (key_unaligned == NULL) 14030 return QDF_STATUS_SUCCESS; 14031 /* Checking if space is aligned */ 14032 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 14033 /* align to 4 */ 14034 key_aligned = 14035 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 14036 FIPS_ALIGN); 14037 } else { 14038 key_aligned = (u_int8_t *)key_unaligned; 14039 } 14040 14041 /* memset and copy content from key to key aligned */ 14042 OS_MEMSET(key_aligned, 0, param->key_len); 14043 OS_MEMCPY(key_aligned, param->key, param->key_len); 14044 14045 /* print a hexdump for host debug */ 14046 print_hex_dump(KERN_DEBUG, 14047 "\t Aligned and Copied Key:@@@@ ", 14048 DUMP_PREFIX_NONE, 14049 16, 1, key_aligned, param->key_len, true); 14050 14051 /* Checking if kmalloc is succesful to allocate space */ 14052 if (data_unaligned == NULL) 14053 return QDF_STATUS_SUCCESS; 14054 /* Checking of space is aligned */ 14055 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14056 /* align to 4 */ 14057 data_aligned = 14058 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 14059 FIPS_ALIGN); 14060 } else { 14061 data_aligned = (u_int8_t *)data_unaligned; 14062 } 14063 14064 /* memset and copy content from data to data aligned */ 14065 OS_MEMSET(data_aligned, 0, param->data_len); 14066 OS_MEMCPY(data_aligned, param->data, param->data_len); 14067 14068 /* print a hexdump for host debug */ 14069 print_hex_dump(KERN_DEBUG, 14070 "\t Properly Aligned and Copied Data:@@@@ ", 14071 DUMP_PREFIX_NONE, 14072 16, 1, data_aligned, param->data_len, true); 14073 14074 /* converting to little Endian both key_aligned and 14075 * data_aligned*/ 14076 for (c = 0; c < param->key_len/4; c++) { 14077 *((u_int32_t *)key_aligned+c) = 14078 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 14079 } 14080 for (c = 0; c < param->data_len/4; c++) { 14081 *((u_int32_t *)data_aligned+c) = 14082 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 14083 } 14084 14085 /* update endian data to key and data vectors */ 14086 OS_MEMCPY(param->key, key_aligned, param->key_len); 14087 OS_MEMCPY(param->data, data_aligned, param->data_len); 14088 14089 /* clean up allocated spaces */ 14090 qdf_mem_free(key_unaligned); 14091 key_unaligned = NULL; 14092 key_aligned = NULL; 14093 14094 qdf_mem_free(data_unaligned); 14095 data_unaligned = NULL; 14096 data_aligned = NULL; 14097 14098 return QDF_STATUS_SUCCESS; 14099 } 14100 #else 14101 /** 14102 * fips_align_data_be() - DUMMY for LE platform 14103 * 14104 * Return: QDF_STATUS - success 14105 */ 14106 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 14107 struct fips_params *param) 14108 { 14109 return QDF_STATUS_SUCCESS; 14110 } 14111 #endif 14112 14113 14114 /** 14115 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 14116 * @wmi_handle: wmi handle 14117 * @param: pointer to hold pdev fips param 14118 * 14119 * Return: 0 for success or error code 14120 */ 14121 static QDF_STATUS 14122 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 14123 struct fips_params *param) 14124 { 14125 wmi_pdev_fips_cmd_fixed_param *cmd; 14126 wmi_buf_t buf; 14127 uint8_t *buf_ptr; 14128 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 14129 QDF_STATUS retval = QDF_STATUS_SUCCESS; 14130 14131 /* Length TLV placeholder for array of bytes */ 14132 len += WMI_TLV_HDR_SIZE; 14133 if (param->data_len) 14134 len += (param->data_len*sizeof(uint8_t)); 14135 14136 /* 14137 * Data length must be multiples of 16 bytes - checked against 0xF - 14138 * and must be less than WMI_SVC_MSG_SIZE - static size of 14139 * wmi_pdev_fips_cmd structure 14140 */ 14141 14142 /* do sanity on the input */ 14143 if (!(((param->data_len & 0xF) == 0) && 14144 ((param->data_len > 0) && 14145 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 14146 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 14147 return QDF_STATUS_E_INVAL; 14148 } 14149 14150 buf = wmi_buf_alloc(wmi_handle, len); 14151 if (!buf) { 14152 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 14153 return QDF_STATUS_E_FAILURE; 14154 } 14155 14156 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14157 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 14158 WMITLV_SET_HDR(&cmd->tlv_header, 14159 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 14160 WMITLV_GET_STRUCT_TLVLEN 14161 (wmi_pdev_fips_cmd_fixed_param)); 14162 14163 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 14164 param->pdev_id); 14165 if (param->key != NULL && param->data != NULL) { 14166 cmd->key_len = param->key_len; 14167 cmd->data_len = param->data_len; 14168 cmd->fips_cmd = !!(param->op); 14169 14170 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 14171 return QDF_STATUS_E_FAILURE; 14172 14173 qdf_mem_copy(cmd->key, param->key, param->key_len); 14174 14175 if (param->mode == FIPS_ENGINE_AES_CTR || 14176 param->mode == FIPS_ENGINE_AES_MIC) { 14177 cmd->mode = param->mode; 14178 } else { 14179 cmd->mode = FIPS_ENGINE_AES_CTR; 14180 } 14181 qdf_print(KERN_ERR "Key len = %d, Data len = %d\n", 14182 cmd->key_len, cmd->data_len); 14183 14184 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 14185 cmd->key, cmd->key_len, true); 14186 buf_ptr += sizeof(*cmd); 14187 14188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 14189 14190 buf_ptr += WMI_TLV_HDR_SIZE; 14191 if (param->data_len) 14192 qdf_mem_copy(buf_ptr, 14193 (uint8_t *) param->data, param->data_len); 14194 14195 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 14196 16, 1, buf_ptr, cmd->data_len, true); 14197 14198 buf_ptr += param->data_len; 14199 14200 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 14201 WMI_PDEV_FIPS_CMDID); 14202 qdf_print("%s return value %d\n", __func__, retval); 14203 } else { 14204 qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__); 14205 wmi_buf_free(buf); 14206 retval = -QDF_STATUS_E_BADMSG; 14207 } 14208 14209 return retval; 14210 } 14211 14212 #ifdef WLAN_PMO_ENABLE 14213 /** 14214 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 14215 * @wmi_handle: wmi handle 14216 * @vdev_id: vdev id 14217 * @bitmap: Event bitmap 14218 * @enable: enable/disable 14219 * 14220 * Return: CDF status 14221 */ 14222 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 14223 uint32_t vdev_id, 14224 uint32_t *bitmap, 14225 bool enable) 14226 { 14227 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 14228 uint16_t len; 14229 wmi_buf_t buf; 14230 int ret; 14231 14232 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 14233 buf = wmi_buf_alloc(wmi_handle, len); 14234 if (!buf) { 14235 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14236 return QDF_STATUS_E_NOMEM; 14237 } 14238 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 14239 WMITLV_SET_HDR(&cmd->tlv_header, 14240 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 14241 WMITLV_GET_STRUCT_TLVLEN 14242 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 14243 cmd->vdev_id = vdev_id; 14244 cmd->is_add = enable; 14245 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 14246 WMI_WOW_MAX_EVENT_BM_LEN); 14247 14248 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 14249 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 14250 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 14251 14252 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14253 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 14254 if (ret) { 14255 WMI_LOGE("Failed to config wow wakeup event"); 14256 wmi_buf_free(buf); 14257 return QDF_STATUS_E_FAILURE; 14258 } 14259 14260 return QDF_STATUS_SUCCESS; 14261 } 14262 14263 /** 14264 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 14265 * @wmi_handle: wmi handle 14266 * @vdev_id: vdev id 14267 * @ptrn_id: pattern id 14268 * @ptrn: pattern 14269 * @ptrn_len: pattern length 14270 * @ptrn_offset: pattern offset 14271 * @mask: mask 14272 * @mask_len: mask length 14273 * @user: true for user configured pattern and false for default pattern 14274 * @default_patterns: default patterns 14275 * 14276 * Return: CDF status 14277 */ 14278 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 14279 uint8_t vdev_id, uint8_t ptrn_id, 14280 const uint8_t *ptrn, uint8_t ptrn_len, 14281 uint8_t ptrn_offset, const uint8_t *mask, 14282 uint8_t mask_len, bool user, 14283 uint8_t default_patterns) 14284 { 14285 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14286 WOW_BITMAP_PATTERN_T *bitmap_pattern; 14287 wmi_buf_t buf; 14288 uint8_t *buf_ptr; 14289 int32_t len; 14290 int ret; 14291 14292 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14293 WMI_TLV_HDR_SIZE + 14294 1 * sizeof(WOW_BITMAP_PATTERN_T) + 14295 WMI_TLV_HDR_SIZE + 14296 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14297 WMI_TLV_HDR_SIZE + 14298 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14299 WMI_TLV_HDR_SIZE + 14300 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14301 WMI_TLV_HDR_SIZE + 14302 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14303 14304 buf = wmi_buf_alloc(wmi_handle, len); 14305 if (!buf) { 14306 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14307 return QDF_STATUS_E_NOMEM; 14308 } 14309 14310 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14311 buf_ptr = (uint8_t *) cmd; 14312 14313 WMITLV_SET_HDR(&cmd->tlv_header, 14314 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14315 WMITLV_GET_STRUCT_TLVLEN 14316 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14317 cmd->vdev_id = vdev_id; 14318 cmd->pattern_id = ptrn_id; 14319 14320 cmd->pattern_type = WOW_BITMAP_PATTERN; 14321 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14322 14323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14324 sizeof(WOW_BITMAP_PATTERN_T)); 14325 buf_ptr += WMI_TLV_HDR_SIZE; 14326 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 14327 14328 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 14329 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 14330 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 14331 14332 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 14333 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 14334 14335 bitmap_pattern->pattern_offset = ptrn_offset; 14336 bitmap_pattern->pattern_len = ptrn_len; 14337 14338 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 14339 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 14340 14341 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 14342 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 14343 14344 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 14345 bitmap_pattern->pattern_id = ptrn_id; 14346 14347 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 14348 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 14349 bitmap_pattern->pattern_offset, user); 14350 WMI_LOGI("Pattern : "); 14351 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14352 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 14353 14354 WMI_LOGI("Mask : "); 14355 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 14356 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 14357 14358 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 14359 14360 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14361 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14362 buf_ptr += WMI_TLV_HDR_SIZE; 14363 14364 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14366 buf_ptr += WMI_TLV_HDR_SIZE; 14367 14368 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14369 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14370 buf_ptr += WMI_TLV_HDR_SIZE; 14371 14372 /* Fill TLV for pattern_info_timeout but no data. */ 14373 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14374 buf_ptr += WMI_TLV_HDR_SIZE; 14375 14376 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 14377 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 14378 buf_ptr += WMI_TLV_HDR_SIZE; 14379 *(uint32_t *) buf_ptr = 0; 14380 14381 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14382 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14383 if (ret) { 14384 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 14385 wmi_buf_free(buf); 14386 return QDF_STATUS_E_FAILURE; 14387 } 14388 14389 return QDF_STATUS_SUCCESS; 14390 } 14391 14392 /** 14393 * fill_arp_offload_params_tlv() - Fill ARP offload data 14394 * @wmi_handle: wmi handle 14395 * @offload_req: offload request 14396 * @buf_ptr: buffer pointer 14397 * 14398 * To fill ARP offload data to firmware 14399 * when target goes to wow mode. 14400 * 14401 * Return: None 14402 */ 14403 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 14404 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 14405 { 14406 14407 int i; 14408 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 14409 bool enable_or_disable = offload_req->enable; 14410 14411 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14412 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 14413 *buf_ptr += WMI_TLV_HDR_SIZE; 14414 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 14415 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 14416 WMITLV_SET_HDR(&arp_tuple->tlv_header, 14417 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 14418 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 14419 14420 /* Fill data for ARP and NS in the first tupple for LA */ 14421 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 14422 /* Copy the target ip addr and flags */ 14423 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 14424 qdf_mem_copy(&arp_tuple->target_ipaddr, 14425 offload_req->host_ipv4_addr, 14426 WMI_IPV4_ADDR_LEN); 14427 WMI_LOGD("ARPOffload IP4 address: %pI4", 14428 offload_req->host_ipv4_addr); 14429 } 14430 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 14431 } 14432 } 14433 14434 #ifdef WLAN_NS_OFFLOAD 14435 /** 14436 * fill_ns_offload_params_tlv() - Fill NS offload data 14437 * @wmi|_handle: wmi handle 14438 * @offload_req: offload request 14439 * @buf_ptr: buffer pointer 14440 * 14441 * To fill NS offload data to firmware 14442 * when target goes to wow mode. 14443 * 14444 * Return: None 14445 */ 14446 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14447 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14448 { 14449 14450 int i; 14451 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14452 14453 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14454 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14455 *buf_ptr += WMI_TLV_HDR_SIZE; 14456 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 14457 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14458 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14459 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14460 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 14461 14462 /* 14463 * Fill data only for NS offload in the first ARP tuple for LA 14464 */ 14465 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14466 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14467 /* Copy the target/solicitation/remote ip addr */ 14468 if (ns_req->target_ipv6_addr_valid[i]) 14469 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14470 &ns_req->target_ipv6_addr[i], 14471 sizeof(WMI_IPV6_ADDR)); 14472 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14473 &ns_req->self_ipv6_addr[i], 14474 sizeof(WMI_IPV6_ADDR)); 14475 if (ns_req->target_ipv6_addr_ac_type[i]) { 14476 ns_tuple->flags |= 14477 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14478 } 14479 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14480 i, &ns_req->self_ipv6_addr[i], 14481 &ns_req->target_ipv6_addr[i]); 14482 14483 /* target MAC is optional, check if it is valid, 14484 * if this is not valid, the target will use the known 14485 * local MAC address rather than the tuple 14486 */ 14487 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14488 ns_req->self_macaddr.bytes, 14489 &ns_tuple->target_mac); 14490 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14491 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14492 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14493 } 14494 } 14495 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14496 } 14497 } 14498 14499 14500 /** 14501 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 14502 * @wmi: wmi handle 14503 * @offload_req: offload request 14504 * @buf_ptr: buffer pointer 14505 * 14506 * To fill extended NS offload extended data to firmware 14507 * when target goes to wow mode. 14508 * 14509 * Return: None 14510 */ 14511 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14512 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14513 { 14514 int i; 14515 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14516 uint32_t count, num_ns_ext_tuples; 14517 14518 count = ns_req->num_ns_offload_count; 14519 num_ns_ext_tuples = ns_req->num_ns_offload_count - 14520 WMI_MAX_NS_OFFLOADS; 14521 14522 /* Populate extended NS offload tuples */ 14523 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14524 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14525 *buf_ptr += WMI_TLV_HDR_SIZE; 14526 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 14527 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14528 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14529 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14530 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 14531 14532 /* 14533 * Fill data only for NS offload in the first ARP tuple for LA 14534 */ 14535 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14536 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14537 /* Copy the target/solicitation/remote ip addr */ 14538 if (ns_req->target_ipv6_addr_valid[i]) 14539 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14540 &ns_req->target_ipv6_addr[i], 14541 sizeof(WMI_IPV6_ADDR)); 14542 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14543 &ns_req->self_ipv6_addr[i], 14544 sizeof(WMI_IPV6_ADDR)); 14545 if (ns_req->target_ipv6_addr_ac_type[i]) { 14546 ns_tuple->flags |= 14547 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14548 } 14549 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14550 i, &ns_req->self_ipv6_addr[i], 14551 &ns_req->target_ipv6_addr[i]); 14552 14553 /* target MAC is optional, check if it is valid, 14554 * if this is not valid, the target will use the 14555 * known local MAC address rather than the tuple 14556 */ 14557 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14558 ns_req->self_macaddr.bytes, 14559 &ns_tuple->target_mac); 14560 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14561 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14562 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14563 } 14564 } 14565 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14566 } 14567 } 14568 #else 14569 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14570 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14571 { 14572 } 14573 14574 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14575 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14576 { 14577 } 14578 #endif 14579 14580 /** 14581 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 14582 * @wma: wmi handle 14583 * @arp_offload_req: arp offload request 14584 * @ns_offload_req: ns offload request 14585 * @arp_only: flag 14586 * 14587 * To configure ARP NS off load data to firmware 14588 * when target goes to wow mode. 14589 * 14590 * Return: QDF Status 14591 */ 14592 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 14593 struct pmo_arp_offload_params *arp_offload_req, 14594 struct pmo_ns_offload_params *ns_offload_req, 14595 uint8_t vdev_id) 14596 { 14597 int32_t res; 14598 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 14599 uint8_t *buf_ptr; 14600 wmi_buf_t buf; 14601 int32_t len; 14602 uint32_t count = 0, num_ns_ext_tuples = 0; 14603 14604 count = ns_offload_req->num_ns_offload_count; 14605 14606 /* 14607 * TLV place holder size for array of NS tuples 14608 * TLV place holder size for array of ARP tuples 14609 */ 14610 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 14611 WMI_TLV_HDR_SIZE + 14612 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 14613 WMI_TLV_HDR_SIZE + 14614 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 14615 14616 /* 14617 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 14618 * extra length for extended NS offload tuples which follows ARP offload 14619 * tuples. Host needs to fill this structure in following format: 14620 * 2 NS ofload tuples 14621 * 2 ARP offload tuples 14622 * N numbers of extended NS offload tuples if HDD has given more than 14623 * 2 NS offload addresses 14624 */ 14625 if (count > WMI_MAX_NS_OFFLOADS) { 14626 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 14627 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 14628 * sizeof(WMI_NS_OFFLOAD_TUPLE); 14629 } 14630 14631 buf = wmi_buf_alloc(wmi_handle, len); 14632 if (!buf) { 14633 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14634 return QDF_STATUS_E_NOMEM; 14635 } 14636 14637 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14638 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 14639 WMITLV_SET_HDR(&cmd->tlv_header, 14640 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 14641 WMITLV_GET_STRUCT_TLVLEN 14642 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 14643 cmd->flags = 0; 14644 cmd->vdev_id = vdev_id; 14645 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 14646 14647 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 14648 14649 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 14650 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14651 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 14652 if (num_ns_ext_tuples) 14653 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14654 14655 res = wmi_unified_cmd_send(wmi_handle, buf, len, 14656 WMI_SET_ARP_NS_OFFLOAD_CMDID); 14657 if (res) { 14658 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 14659 wmi_buf_free(buf); 14660 return QDF_STATUS_E_FAILURE; 14661 } 14662 14663 return QDF_STATUS_SUCCESS; 14664 } 14665 14666 /** 14667 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14668 * @wmi_handle: wmi handle 14669 * @vdev_id: vdev id 14670 * @action: true for enable else false 14671 * 14672 * To enable enhance multicast offload to firmware 14673 * when target goes to wow mode. 14674 * 14675 * Return: QDF Status 14676 */ 14677 14678 static 14679 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14680 wmi_unified_t wmi_handle, 14681 uint8_t vdev_id, bool action) 14682 { 14683 QDF_STATUS status; 14684 wmi_buf_t buf; 14685 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14686 14687 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14688 if (!buf) { 14689 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14690 return QDF_STATUS_E_NOMEM; 14691 } 14692 14693 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14694 wmi_buf_data(buf); 14695 14696 WMITLV_SET_HDR(&cmd->tlv_header, 14697 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14698 WMITLV_GET_STRUCT_TLVLEN( 14699 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14700 14701 cmd->vdev_id = vdev_id; 14702 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14703 ENHANCED_MCAST_FILTER_ENABLED); 14704 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14705 __func__, action, vdev_id); 14706 status = wmi_unified_cmd_send(wmi_handle, buf, 14707 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14708 if (status != QDF_STATUS_SUCCESS) { 14709 qdf_nbuf_free(buf); 14710 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14711 __func__); 14712 } 14713 14714 return status; 14715 } 14716 14717 /** 14718 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14719 * @wmi_handle: wmi handle 14720 * @param evt_buf: pointer to event buffer 14721 * @param hdr: Pointer to hold header 14722 * @param bufp: Pointer to hold pointer to rx param buffer 14723 * 14724 * Return: QDF_STATUS_SUCCESS for success or error code 14725 */ 14726 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14727 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14728 { 14729 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14730 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14731 14732 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14733 if (!param_buf) { 14734 WMI_LOGE("gtk param_buf is NULL"); 14735 return QDF_STATUS_E_INVAL; 14736 } 14737 14738 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14739 WMI_LOGE("Invalid length for GTK status"); 14740 return QDF_STATUS_E_INVAL; 14741 } 14742 14743 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14744 param_buf->fixed_param; 14745 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14746 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14747 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14748 qdf_mem_copy(>k_rsp_param->replay_counter, 14749 &fixed_param->replay_counter, 14750 GTK_REPLAY_COUNTER_BYTES); 14751 14752 return QDF_STATUS_SUCCESS; 14753 14754 } 14755 14756 #ifdef FEATURE_WLAN_RA_FILTERING 14757 /** 14758 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14759 * @wmi_handle: wmi handle 14760 * @vdev_id: vdev id 14761 * 14762 * Return: CDF status 14763 */ 14764 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14765 uint8_t vdev_id, uint8_t default_pattern, 14766 uint16_t rate_limit_interval) 14767 { 14768 14769 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14770 wmi_buf_t buf; 14771 uint8_t *buf_ptr; 14772 int32_t len; 14773 int ret; 14774 14775 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14776 WMI_TLV_HDR_SIZE + 14777 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14778 WMI_TLV_HDR_SIZE + 14779 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14780 WMI_TLV_HDR_SIZE + 14781 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14782 WMI_TLV_HDR_SIZE + 14783 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14784 WMI_TLV_HDR_SIZE + 14785 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14786 14787 buf = wmi_buf_alloc(wmi_handle, len); 14788 if (!buf) { 14789 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14790 return QDF_STATUS_E_NOMEM; 14791 } 14792 14793 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14794 buf_ptr = (uint8_t *) cmd; 14795 14796 WMITLV_SET_HDR(&cmd->tlv_header, 14797 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14798 WMITLV_GET_STRUCT_TLVLEN 14799 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14800 cmd->vdev_id = vdev_id; 14801 cmd->pattern_id = default_pattern, 14802 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14803 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14804 14805 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14806 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14807 buf_ptr += WMI_TLV_HDR_SIZE; 14808 14809 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14810 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14811 buf_ptr += WMI_TLV_HDR_SIZE; 14812 14813 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14814 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14815 buf_ptr += WMI_TLV_HDR_SIZE; 14816 14817 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14818 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14819 buf_ptr += WMI_TLV_HDR_SIZE; 14820 14821 /* Fill TLV for pattern_info_timeout but no data. */ 14822 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14823 buf_ptr += WMI_TLV_HDR_SIZE; 14824 14825 /* Fill TLV for ra_ratelimit_interval. */ 14826 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14827 buf_ptr += WMI_TLV_HDR_SIZE; 14828 14829 *((uint32_t *) buf_ptr) = rate_limit_interval; 14830 14831 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14832 rate_limit_interval, vdev_id); 14833 14834 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14835 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14836 if (ret) { 14837 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14838 wmi_buf_free(buf); 14839 return QDF_STATUS_E_FAILURE; 14840 } 14841 14842 return QDF_STATUS_SUCCESS; 14843 14844 } 14845 #endif /* FEATURE_WLAN_RA_FILTERING */ 14846 14847 /** 14848 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14849 * @wmi_handle: wmi handle 14850 * @vdev_id: vdev id 14851 * @multicastAddr: mcast address 14852 * @clearList: clear list flag 14853 * 14854 * Return: QDF_STATUS_SUCCESS for success or error code 14855 */ 14856 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14857 uint8_t vdev_id, 14858 struct qdf_mac_addr multicast_addr, 14859 bool clearList) 14860 { 14861 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14862 wmi_buf_t buf; 14863 int err; 14864 14865 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14866 if (!buf) { 14867 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14868 return QDF_STATUS_E_NOMEM; 14869 } 14870 14871 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14872 qdf_mem_zero(cmd, sizeof(*cmd)); 14873 14874 WMITLV_SET_HDR(&cmd->tlv_header, 14875 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14876 WMITLV_GET_STRUCT_TLVLEN 14877 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14878 cmd->action = 14879 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14880 cmd->vdev_id = vdev_id; 14881 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14882 14883 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14884 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14885 14886 err = wmi_unified_cmd_send(wmi_handle, buf, 14887 sizeof(*cmd), 14888 WMI_SET_MCASTBCAST_FILTER_CMDID); 14889 if (err) { 14890 WMI_LOGE("Failed to send set_param cmd"); 14891 wmi_buf_free(buf); 14892 return QDF_STATUS_E_FAILURE; 14893 } 14894 14895 return QDF_STATUS_SUCCESS; 14896 } 14897 14898 /** 14899 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14900 * command to fw 14901 * @wmi_handle: wmi handle 14902 * @vdev_id: vdev id 14903 * @mcast_filter_params: mcast filter params 14904 * 14905 * Return: QDF_STATUS_SUCCESS for success or error code 14906 */ 14907 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14908 wmi_unified_t wmi_handle, 14909 uint8_t vdev_id, 14910 struct pmo_mcast_filter_params *filter_param) 14911 14912 { 14913 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14914 uint8_t *buf_ptr; 14915 wmi_buf_t buf; 14916 int err; 14917 int i; 14918 uint8_t *mac_addr_src_ptr = NULL; 14919 wmi_mac_addr *mac_addr_dst_ptr; 14920 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14921 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14922 14923 buf = wmi_buf_alloc(wmi_handle, len); 14924 if (!buf) { 14925 WMI_LOGE("Failed to allocate memory"); 14926 return QDF_STATUS_E_NOMEM; 14927 } 14928 14929 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14930 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14931 wmi_buf_data(buf); 14932 qdf_mem_zero(cmd, sizeof(*cmd)); 14933 14934 WMITLV_SET_HDR(&cmd->tlv_header, 14935 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14936 WMITLV_GET_STRUCT_TLVLEN 14937 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14938 cmd->operation = 14939 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14940 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14941 cmd->vdev_id = vdev_id; 14942 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14943 14944 buf_ptr += sizeof(*cmd); 14945 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14946 sizeof(wmi_mac_addr) * 14947 filter_param->multicast_addr_cnt); 14948 14949 if (filter_param->multicast_addr_cnt == 0) 14950 goto send_cmd; 14951 14952 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14953 mac_addr_dst_ptr = (wmi_mac_addr *) 14954 (buf_ptr + WMI_TLV_HDR_SIZE); 14955 14956 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14957 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14958 mac_addr_src_ptr += ATH_MAC_LEN; 14959 mac_addr_dst_ptr++; 14960 } 14961 14962 send_cmd: 14963 err = wmi_unified_cmd_send(wmi_handle, buf, 14964 len, 14965 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14966 if (err) { 14967 WMI_LOGE("Failed to send set_param cmd"); 14968 wmi_buf_free(buf); 14969 return QDF_STATUS_E_FAILURE; 14970 } 14971 14972 return QDF_STATUS_SUCCESS; 14973 } 14974 14975 14976 /** 14977 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14978 * @wmi_handle: wmi handle 14979 * @vdev_id: vdev id 14980 * @params: GTK offload parameters 14981 * 14982 * Return: CDF status 14983 */ 14984 static 14985 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14986 struct pmo_gtk_req *params, 14987 bool enable_offload, 14988 uint32_t gtk_offload_opcode) 14989 { 14990 int len; 14991 wmi_buf_t buf; 14992 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14993 wmi_gtk_offload_fils_tlv_param *ext_param; 14994 QDF_STATUS status = QDF_STATUS_SUCCESS; 14995 uint8_t *buf_ptr; 14996 14997 WMI_LOGD("%s Enter", __func__); 14998 14999 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param); 15000 15001 /* alloc wmi buffer */ 15002 buf = wmi_buf_alloc(wmi_handle, len); 15003 if (!buf) { 15004 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15005 status = QDF_STATUS_E_NOMEM; 15006 goto out; 15007 } 15008 15009 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15010 buf_ptr = (uint8_t *)cmd; 15011 WMITLV_SET_HDR(&cmd->tlv_header, 15012 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15013 WMITLV_GET_STRUCT_TLVLEN 15014 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15015 15016 cmd->vdev_id = vdev_id; 15017 15018 /* Request target to enable GTK offload */ 15019 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 15020 cmd->flags = gtk_offload_opcode; 15021 15022 /* Copy the keys and replay counter */ 15023 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 15024 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 15025 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 15026 GTK_REPLAY_COUNTER_BYTES); 15027 } else { 15028 cmd->flags = gtk_offload_opcode; 15029 } 15030 15031 buf_ptr += sizeof(*cmd); 15032 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param)); 15033 buf_ptr += WMI_TLV_HDR_SIZE; 15034 15035 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 15036 WMITLV_SET_HDR(&ext_param->tlv_header, 15037 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 15038 WMITLV_GET_STRUCT_TLVLEN( 15039 wmi_gtk_offload_fils_tlv_param)); 15040 ext_param->vdev_id = vdev_id; 15041 ext_param->flags = cmd->flags; 15042 ext_param->kek_len = params->kek_len; 15043 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 15044 qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES); 15045 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 15046 GTK_REPLAY_COUNTER_BYTES); 15047 15048 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 15049 /* send the wmi command */ 15050 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15051 WMI_GTK_OFFLOAD_CMDID)) { 15052 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 15053 wmi_buf_free(buf); 15054 status = QDF_STATUS_E_FAILURE; 15055 } 15056 15057 out: 15058 WMI_LOGD("%s Exit", __func__); 15059 return status; 15060 } 15061 15062 /** 15063 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 15064 * @wmi_handle: wmi handle 15065 * @params: GTK offload params 15066 * 15067 * Return: CDF status 15068 */ 15069 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 15070 wmi_unified_t wmi_handle, 15071 uint8_t vdev_id, 15072 uint64_t offload_req_opcode) 15073 { 15074 int len; 15075 wmi_buf_t buf; 15076 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 15077 QDF_STATUS status = QDF_STATUS_SUCCESS; 15078 15079 len = sizeof(*cmd); 15080 15081 /* alloc wmi buffer */ 15082 buf = wmi_buf_alloc(wmi_handle, len); 15083 if (!buf) { 15084 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 15085 status = QDF_STATUS_E_NOMEM; 15086 goto out; 15087 } 15088 15089 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 15090 WMITLV_SET_HDR(&cmd->tlv_header, 15091 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 15092 WMITLV_GET_STRUCT_TLVLEN 15093 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 15094 15095 /* Request for GTK offload status */ 15096 cmd->flags = offload_req_opcode; 15097 cmd->vdev_id = vdev_id; 15098 15099 /* send the wmi command */ 15100 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15101 WMI_GTK_OFFLOAD_CMDID)) { 15102 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 15103 wmi_buf_free(buf); 15104 status = QDF_STATUS_E_FAILURE; 15105 } 15106 15107 out: 15108 return status; 15109 } 15110 15111 /** 15112 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 15113 * @wmi_handle: wmi handler 15114 * @action_params: pointer to action_params 15115 * 15116 * Return: 0 for success, otherwise appropriate error code 15117 */ 15118 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 15119 struct pmo_action_wakeup_set_params *action_params) 15120 { 15121 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 15122 wmi_buf_t buf; 15123 int i; 15124 int32_t err; 15125 uint32_t len = 0, *cmd_args; 15126 uint8_t *buf_ptr; 15127 15128 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 15129 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 15130 buf = wmi_buf_alloc(wmi_handle, len); 15131 if (!buf) { 15132 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 15133 return QDF_STATUS_E_NOMEM; 15134 } 15135 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 15136 buf_ptr = (uint8_t *)cmd; 15137 WMITLV_SET_HDR(&cmd->tlv_header, 15138 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 15139 WMITLV_GET_STRUCT_TLVLEN( 15140 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 15141 15142 cmd->vdev_id = action_params->vdev_id; 15143 cmd->operation = action_params->operation; 15144 15145 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 15146 cmd->action_category_map[i] = 15147 action_params->action_category_map[i]; 15148 15149 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 15150 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15151 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 15152 buf_ptr += WMI_TLV_HDR_SIZE; 15153 cmd_args = (uint32_t *) buf_ptr; 15154 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 15155 cmd_args[i] = action_params->action_per_category[i]; 15156 15157 err = wmi_unified_cmd_send(wmi_handle, buf, 15158 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 15159 if (err) { 15160 WMI_LOGE("Failed to send ap_ps_egap cmd"); 15161 wmi_buf_free(buf); 15162 return QDF_STATUS_E_FAILURE; 15163 } 15164 15165 return QDF_STATUS_SUCCESS; 15166 } 15167 15168 #ifdef FEATURE_WLAN_LPHB 15169 15170 /** 15171 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 15172 * @wmi_handle: wmi handle 15173 * @lphb_conf_req: configuration info 15174 * 15175 * Return: CDF status 15176 */ 15177 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 15178 wmi_hb_set_enable_cmd_fixed_param *params) 15179 { 15180 QDF_STATUS status; 15181 wmi_buf_t buf = NULL; 15182 uint8_t *buf_ptr; 15183 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 15184 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 15185 15186 15187 buf = wmi_buf_alloc(wmi_handle, len); 15188 if (!buf) { 15189 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15190 return QDF_STATUS_E_NOMEM; 15191 } 15192 15193 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15194 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 15195 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 15196 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 15197 WMITLV_GET_STRUCT_TLVLEN 15198 (wmi_hb_set_enable_cmd_fixed_param)); 15199 15200 /* fill in values */ 15201 hb_enable_fp->vdev_id = params->session; 15202 hb_enable_fp->enable = params->enable; 15203 hb_enable_fp->item = params->item; 15204 hb_enable_fp->session = params->session; 15205 15206 status = wmi_unified_cmd_send(wmi_handle, buf, 15207 len, WMI_HB_SET_ENABLE_CMDID); 15208 if (QDF_IS_STATUS_ERROR(status)) { 15209 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 15210 status); 15211 wmi_buf_free(buf); 15212 } 15213 15214 return status; 15215 } 15216 15217 /** 15218 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 15219 * @wmi_handle: wmi handle 15220 * @lphb_conf_req: lphb config request 15221 * 15222 * Return: CDF status 15223 */ 15224 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 15225 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 15226 { 15227 QDF_STATUS status; 15228 wmi_buf_t buf = NULL; 15229 uint8_t *buf_ptr; 15230 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 15231 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 15232 15233 buf = wmi_buf_alloc(wmi_handle, len); 15234 if (!buf) { 15235 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15236 return QDF_STATUS_E_NOMEM; 15237 } 15238 15239 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15240 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 15241 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 15242 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 15243 WMITLV_GET_STRUCT_TLVLEN 15244 (wmi_hb_set_tcp_params_cmd_fixed_param)); 15245 15246 /* fill in values */ 15247 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15248 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15249 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15250 hb_tcp_params_fp->seq = lphb_conf_req->seq; 15251 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 15252 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 15253 hb_tcp_params_fp->interval = lphb_conf_req->interval; 15254 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 15255 hb_tcp_params_fp->session = lphb_conf_req->session; 15256 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 15257 &lphb_conf_req->gateway_mac, 15258 sizeof(hb_tcp_params_fp->gateway_mac)); 15259 15260 status = wmi_unified_cmd_send(wmi_handle, buf, 15261 len, WMI_HB_SET_TCP_PARAMS_CMDID); 15262 if (QDF_IS_STATUS_ERROR(status)) { 15263 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 15264 status); 15265 wmi_buf_free(buf); 15266 } 15267 15268 return status; 15269 } 15270 15271 /** 15272 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 15273 * @wmi_handle: wmi handle 15274 * @lphb_conf_req: lphb config request 15275 * 15276 * Return: CDF status 15277 */ 15278 static 15279 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15280 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 15281 { 15282 QDF_STATUS status; 15283 wmi_buf_t buf = NULL; 15284 uint8_t *buf_ptr; 15285 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 15286 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 15287 15288 buf = wmi_buf_alloc(wmi_handle, len); 15289 if (!buf) { 15290 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15291 return QDF_STATUS_E_NOMEM; 15292 } 15293 15294 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15295 hb_tcp_filter_fp = 15296 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 15297 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 15298 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 15299 WMITLV_GET_STRUCT_TLVLEN 15300 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 15301 15302 /* fill in values */ 15303 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 15304 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 15305 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 15306 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 15307 memcpy((void *)&hb_tcp_filter_fp->filter, 15308 (void *)&g_hb_tcp_filter_fp->filter, 15309 WMI_WLAN_HB_MAX_FILTER_SIZE); 15310 15311 status = wmi_unified_cmd_send(wmi_handle, buf, 15312 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 15313 if (QDF_IS_STATUS_ERROR(status)) { 15314 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 15315 status); 15316 wmi_buf_free(buf); 15317 } 15318 15319 return status; 15320 } 15321 15322 /** 15323 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 15324 * @wmi_handle: wmi handle 15325 * @lphb_conf_req: lphb config request 15326 * 15327 * Return: CDF status 15328 */ 15329 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 15330 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 15331 { 15332 QDF_STATUS status; 15333 wmi_buf_t buf = NULL; 15334 uint8_t *buf_ptr; 15335 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 15336 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 15337 15338 buf = wmi_buf_alloc(wmi_handle, len); 15339 if (!buf) { 15340 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15341 return QDF_STATUS_E_NOMEM; 15342 } 15343 15344 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15345 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 15346 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 15347 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 15348 WMITLV_GET_STRUCT_TLVLEN 15349 (wmi_hb_set_udp_params_cmd_fixed_param)); 15350 15351 /* fill in values */ 15352 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15353 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15354 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15355 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 15356 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 15357 hb_udp_params_fp->interval = lphb_conf_req->interval; 15358 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 15359 hb_udp_params_fp->session = lphb_conf_req->session; 15360 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 15361 &lphb_conf_req->gateway_mac, 15362 sizeof(lphb_conf_req->gateway_mac)); 15363 15364 status = wmi_unified_cmd_send(wmi_handle, buf, 15365 len, WMI_HB_SET_UDP_PARAMS_CMDID); 15366 if (QDF_IS_STATUS_ERROR(status)) { 15367 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 15368 status); 15369 wmi_buf_free(buf); 15370 } 15371 15372 return status; 15373 } 15374 15375 /** 15376 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 15377 * @wmi_handle: wmi handle 15378 * @lphb_conf_req: lphb config request 15379 * 15380 * Return: CDF status 15381 */ 15382 static 15383 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15384 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 15385 { 15386 QDF_STATUS status; 15387 wmi_buf_t buf = NULL; 15388 uint8_t *buf_ptr; 15389 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 15390 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 15391 15392 buf = wmi_buf_alloc(wmi_handle, len); 15393 if (!buf) { 15394 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15395 return QDF_STATUS_E_NOMEM; 15396 } 15397 15398 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15399 hb_udp_filter_fp = 15400 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 15401 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 15402 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 15403 WMITLV_GET_STRUCT_TLVLEN 15404 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 15405 15406 /* fill in values */ 15407 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 15408 hb_udp_filter_fp->length = lphb_conf_req->length; 15409 hb_udp_filter_fp->offset = lphb_conf_req->offset; 15410 hb_udp_filter_fp->session = lphb_conf_req->session; 15411 memcpy((void *)&hb_udp_filter_fp->filter, 15412 (void *)&lphb_conf_req->filter, 15413 WMI_WLAN_HB_MAX_FILTER_SIZE); 15414 15415 status = wmi_unified_cmd_send(wmi_handle, buf, 15416 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 15417 if (QDF_IS_STATUS_ERROR(status)) { 15418 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 15419 status); 15420 wmi_buf_free(buf); 15421 } 15422 15423 return status; 15424 } 15425 #endif /* FEATURE_WLAN_LPHB */ 15426 15427 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 15428 struct pmo_hw_filter_params *req) 15429 { 15430 QDF_STATUS status; 15431 wmi_hw_data_filter_cmd_fixed_param *cmd; 15432 wmi_buf_t wmi_buf; 15433 15434 if (!req) { 15435 WMI_LOGE("req is null"); 15436 return QDF_STATUS_E_INVAL; 15437 } 15438 15439 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 15440 if (!wmi_buf) { 15441 WMI_LOGE(FL("Out of memory")); 15442 return QDF_STATUS_E_NOMEM; 15443 } 15444 15445 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15446 WMITLV_SET_HDR(&cmd->tlv_header, 15447 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 15448 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 15449 cmd->vdev_id = req->vdev_id; 15450 cmd->enable = req->mode != PMO_HW_FILTER_DISABLED; 15451 cmd->hw_filter_bitmap = req->mode; 15452 15453 WMI_LOGD("configure hw filter (vdev_id: %d, mode: %d)", 15454 req->vdev_id, req->mode); 15455 15456 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 15457 WMI_HW_DATA_FILTER_CMDID); 15458 if (QDF_IS_STATUS_ERROR(status)) { 15459 WMI_LOGE("Failed to configure hw filter"); 15460 wmi_buf_free(wmi_buf); 15461 } 15462 15463 return status; 15464 } 15465 15466 /** 15467 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 15468 * @wmi_handle: wmi handle 15469 * @vdev_id: vdev id 15470 * @enable: Flag to enable/disable packet filter 15471 * 15472 * Return: QDF_STATUS_SUCCESS for success or error code 15473 */ 15474 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 15475 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 15476 { 15477 int32_t len; 15478 int ret = 0; 15479 wmi_buf_t buf; 15480 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 15481 15482 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 15483 15484 buf = wmi_buf_alloc(wmi_handle, len); 15485 if (!buf) { 15486 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 15487 return QDF_STATUS_E_NOMEM; 15488 } 15489 15490 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 15491 WMITLV_SET_HDR(&cmd->tlv_header, 15492 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 15493 WMITLV_GET_STRUCT_TLVLEN( 15494 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 15495 15496 cmd->vdev_id = vdev_id; 15497 if (enable) 15498 cmd->enable = PACKET_FILTER_SET_ENABLE; 15499 else 15500 cmd->enable = PACKET_FILTER_SET_DISABLE; 15501 15502 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 15503 __func__, cmd->enable, vdev_id); 15504 15505 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15506 WMI_PACKET_FILTER_ENABLE_CMDID); 15507 if (ret) { 15508 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 15509 wmi_buf_free(buf); 15510 } 15511 15512 return ret; 15513 } 15514 15515 /** 15516 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 15517 * @wmi_handle: wmi handle 15518 * @vdev_id: vdev id 15519 * @rcv_filter_param: Packet filter parameters 15520 * @filter_id: Filter id 15521 * @enable: Flag to add/delete packet filter configuration 15522 * 15523 * Return: QDF_STATUS_SUCCESS for success or error code 15524 */ 15525 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 15526 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 15527 uint8_t filter_id, bool enable) 15528 { 15529 int len, i; 15530 int err = 0; 15531 wmi_buf_t buf; 15532 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 15533 15534 15535 /* allocate the memory */ 15536 len = sizeof(*cmd); 15537 buf = wmi_buf_alloc(wmi_handle, len); 15538 if (!buf) { 15539 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 15540 return QDF_STATUS_E_NOMEM; 15541 } 15542 15543 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 15544 WMITLV_SET_HDR(&cmd->tlv_header, 15545 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 15546 WMITLV_GET_STRUCT_TLVLEN 15547 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 15548 15549 cmd->vdev_id = vdev_id; 15550 cmd->filter_id = filter_id; 15551 if (enable) 15552 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 15553 else 15554 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 15555 15556 if (enable) { 15557 cmd->num_params = QDF_MIN( 15558 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 15559 rcv_filter_param->num_params); 15560 cmd->filter_type = rcv_filter_param->filter_type; 15561 cmd->coalesce_time = rcv_filter_param->coalesce_time; 15562 15563 for (i = 0; i < cmd->num_params; i++) { 15564 cmd->paramsData[i].proto_type = 15565 rcv_filter_param->params_data[i].protocol_layer; 15566 cmd->paramsData[i].cmp_type = 15567 rcv_filter_param->params_data[i].compare_flag; 15568 cmd->paramsData[i].data_length = 15569 rcv_filter_param->params_data[i].data_length; 15570 cmd->paramsData[i].data_offset = 15571 rcv_filter_param->params_data[i].data_offset; 15572 memcpy(&cmd->paramsData[i].compareData, 15573 rcv_filter_param->params_data[i].compare_data, 15574 sizeof(cmd->paramsData[i].compareData)); 15575 memcpy(&cmd->paramsData[i].dataMask, 15576 rcv_filter_param->params_data[i].data_mask, 15577 sizeof(cmd->paramsData[i].dataMask)); 15578 } 15579 } 15580 15581 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 15582 cmd->filter_action, cmd->filter_id, cmd->num_params); 15583 /* send the command along with data */ 15584 err = wmi_unified_cmd_send(wmi_handle, buf, len, 15585 WMI_PACKET_FILTER_CONFIG_CMDID); 15586 if (err) { 15587 WMI_LOGE("Failed to send pkt_filter cmd"); 15588 wmi_buf_free(buf); 15589 return QDF_STATUS_E_FAILURE; 15590 } 15591 15592 return QDF_STATUS_SUCCESS; 15593 } 15594 #endif /* End of WLAN_PMO_ENABLE */ 15595 15596 /** 15597 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 15598 * @wmi_handle: wmi handle 15599 * @request: SSID hotlist set request 15600 * 15601 * Return: QDF_STATUS enumeration 15602 */ 15603 static QDF_STATUS 15604 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 15605 struct ssid_hotlist_request_params *request) 15606 { 15607 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 15608 wmi_buf_t wmi_buf; 15609 uint32_t len; 15610 uint32_t array_size; 15611 uint8_t *buf_ptr; 15612 15613 /* length of fixed portion */ 15614 len = sizeof(*cmd); 15615 15616 /* length of variable portion */ 15617 array_size = 15618 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 15619 len += WMI_TLV_HDR_SIZE + array_size; 15620 15621 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15622 if (!wmi_buf) { 15623 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15624 return QDF_STATUS_E_NOMEM; 15625 } 15626 15627 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 15628 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 15629 buf_ptr; 15630 WMITLV_SET_HDR 15631 (&cmd->tlv_header, 15632 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 15633 WMITLV_GET_STRUCT_TLVLEN 15634 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 15635 15636 cmd->request_id = request->request_id; 15637 cmd->requestor_id = 0; 15638 cmd->vdev_id = request->session_id; 15639 cmd->table_id = 0; 15640 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 15641 cmd->total_entries = request->ssid_count; 15642 cmd->num_entries_in_page = request->ssid_count; 15643 cmd->first_entry_index = 0; 15644 15645 buf_ptr += sizeof(*cmd); 15646 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15647 15648 if (request->ssid_count) { 15649 wmi_extscan_hotlist_ssid_entry *entry; 15650 int i; 15651 15652 buf_ptr += WMI_TLV_HDR_SIZE; 15653 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15654 for (i = 0; i < request->ssid_count; i++) { 15655 WMITLV_SET_HDR 15656 (entry, 15657 WMITLV_TAG_ARRAY_STRUC, 15658 WMITLV_GET_STRUCT_TLVLEN 15659 (wmi_extscan_hotlist_ssid_entry)); 15660 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15661 qdf_mem_copy(entry->ssid.ssid, 15662 request->ssids[i].ssid.mac_ssid, 15663 request->ssids[i].ssid.length); 15664 entry->band = request->ssids[i].band; 15665 entry->min_rssi = request->ssids[i].rssi_low; 15666 entry->max_rssi = request->ssids[i].rssi_high; 15667 entry++; 15668 } 15669 cmd->mode = WMI_EXTSCAN_MODE_START; 15670 } else { 15671 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15672 } 15673 15674 if (wmi_unified_cmd_send 15675 (wmi_handle, wmi_buf, len, 15676 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15677 WMI_LOGE("%s: failed to send command", __func__); 15678 wmi_buf_free(wmi_buf); 15679 return QDF_STATUS_E_FAILURE; 15680 } 15681 15682 return QDF_STATUS_SUCCESS; 15683 } 15684 15685 /** 15686 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 15687 * @wmi_handle: wmi handle 15688 * @vdev_id: vdev id 15689 * 15690 * This function sends roam synch complete event to fw. 15691 * 15692 * Return: CDF STATUS 15693 */ 15694 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 15695 uint8_t vdev_id) 15696 { 15697 wmi_roam_synch_complete_fixed_param *cmd; 15698 wmi_buf_t wmi_buf; 15699 uint8_t *buf_ptr; 15700 uint16_t len; 15701 len = sizeof(wmi_roam_synch_complete_fixed_param); 15702 15703 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15704 if (!wmi_buf) { 15705 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15706 return QDF_STATUS_E_NOMEM; 15707 } 15708 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15709 buf_ptr = (uint8_t *) cmd; 15710 WMITLV_SET_HDR(&cmd->tlv_header, 15711 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15712 WMITLV_GET_STRUCT_TLVLEN 15713 (wmi_roam_synch_complete_fixed_param)); 15714 cmd->vdev_id = vdev_id; 15715 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15716 WMI_ROAM_SYNCH_COMPLETE)) { 15717 WMI_LOGP("%s: failed to send roam synch confirmation", 15718 __func__); 15719 wmi_buf_free(wmi_buf); 15720 return QDF_STATUS_E_FAILURE; 15721 } 15722 15723 return QDF_STATUS_SUCCESS; 15724 } 15725 15726 /** 15727 * send_fw_test_cmd_tlv() - send fw test command to fw. 15728 * @wmi_handle: wmi handle 15729 * @wmi_fwtest: fw test command 15730 * 15731 * This function sends fw test command to fw. 15732 * 15733 * Return: CDF STATUS 15734 */ 15735 static 15736 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15737 struct set_fwtest_params *wmi_fwtest) 15738 { 15739 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15740 wmi_buf_t wmi_buf; 15741 uint16_t len; 15742 15743 len = sizeof(*cmd); 15744 15745 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15746 if (!wmi_buf) { 15747 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15748 return QDF_STATUS_E_NOMEM; 15749 } 15750 15751 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15752 WMITLV_SET_HDR(&cmd->tlv_header, 15753 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15754 WMITLV_GET_STRUCT_TLVLEN( 15755 wmi_fwtest_set_param_cmd_fixed_param)); 15756 cmd->param_id = wmi_fwtest->arg; 15757 cmd->param_value = wmi_fwtest->value; 15758 15759 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15760 WMI_FWTEST_CMDID)) { 15761 WMI_LOGP("%s: failed to send fw test command", __func__); 15762 qdf_nbuf_free(wmi_buf); 15763 return QDF_STATUS_E_FAILURE; 15764 } 15765 15766 return QDF_STATUS_SUCCESS; 15767 } 15768 15769 /** 15770 * send_unit_test_cmd_tlv() - send unit test command to fw. 15771 * @wmi_handle: wmi handle 15772 * @wmi_utest: unit test command 15773 * 15774 * This function send unit test command to fw. 15775 * 15776 * Return: CDF STATUS 15777 */ 15778 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15779 struct wmi_unit_test_cmd *wmi_utest) 15780 { 15781 wmi_unit_test_cmd_fixed_param *cmd; 15782 wmi_buf_t wmi_buf; 15783 uint8_t *buf_ptr; 15784 int i; 15785 uint16_t len, args_tlv_len; 15786 uint32_t *unit_test_cmd_args; 15787 15788 args_tlv_len = 15789 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15790 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15791 15792 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15793 if (!wmi_buf) { 15794 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15795 return QDF_STATUS_E_NOMEM; 15796 } 15797 15798 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15799 buf_ptr = (uint8_t *) cmd; 15800 WMITLV_SET_HDR(&cmd->tlv_header, 15801 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15802 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15803 cmd->vdev_id = wmi_utest->vdev_id; 15804 cmd->module_id = wmi_utest->module_id; 15805 cmd->num_args = wmi_utest->num_args; 15806 cmd->diag_token = wmi_utest->diag_token; 15807 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15808 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15809 (wmi_utest->num_args * sizeof(uint32_t))); 15810 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15811 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15812 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15813 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15814 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15815 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15816 unit_test_cmd_args[i] = wmi_utest->args[i]; 15817 WMI_LOGI("%d,", wmi_utest->args[i]); 15818 } 15819 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15820 WMI_UNIT_TEST_CMDID)) { 15821 WMI_LOGP("%s: failed to send unit test command", __func__); 15822 wmi_buf_free(wmi_buf); 15823 return QDF_STATUS_E_FAILURE; 15824 } 15825 15826 return QDF_STATUS_SUCCESS; 15827 } 15828 15829 /** 15830 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15831 * @wmi_handle: wma handle 15832 * @roaminvoke: roam invoke command 15833 * 15834 * Send roam invoke command to fw for fastreassoc. 15835 * 15836 * Return: CDF STATUS 15837 */ 15838 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15839 struct wmi_roam_invoke_cmd *roaminvoke, 15840 uint32_t ch_hz) 15841 { 15842 wmi_roam_invoke_cmd_fixed_param *cmd; 15843 wmi_buf_t wmi_buf; 15844 u_int8_t *buf_ptr; 15845 u_int16_t len, args_tlv_len; 15846 uint32_t *channel_list; 15847 wmi_mac_addr *bssid_list; 15848 wmi_tlv_buf_len_param *buf_len_tlv; 15849 15850 /* Host sends only one channel and one bssid */ 15851 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15852 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15853 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15854 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15855 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15856 if (!wmi_buf) { 15857 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15858 return QDF_STATUS_E_NOMEM; 15859 } 15860 15861 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15862 buf_ptr = (u_int8_t *) cmd; 15863 WMITLV_SET_HDR(&cmd->tlv_header, 15864 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15865 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15866 cmd->vdev_id = roaminvoke->vdev_id; 15867 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15868 if (roaminvoke->is_same_bssid) 15869 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15870 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15871 15872 if (roaminvoke->frame_len) { 15873 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15874 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15875 cmd->num_buf = 1; 15876 } else { 15877 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15878 cmd->num_buf = 0; 15879 } 15880 15881 cmd->roam_ap_sel_mode = 0; 15882 cmd->roam_delay = 0; 15883 cmd->num_chan = 1; 15884 cmd->num_bssid = 1; 15885 15886 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15887 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15888 (sizeof(u_int32_t))); 15889 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15890 *channel_list = ch_hz; 15891 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15892 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15893 (sizeof(wmi_mac_addr))); 15894 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15895 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15896 15897 /* move to next tlv i.e. bcn_prb_buf_list */ 15898 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15899 15900 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15901 sizeof(wmi_tlv_buf_len_param)); 15902 15903 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15904 buf_len_tlv->buf_len = roaminvoke->frame_len; 15905 15906 /* move to next tlv i.e. bcn_prb_frm */ 15907 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15908 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15909 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15910 15911 /* copy frame after the header */ 15912 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15913 roaminvoke->frame_buf, 15914 roaminvoke->frame_len); 15915 15916 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15917 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 15918 buf_ptr + WMI_TLV_HDR_SIZE, 15919 roaminvoke->frame_len); 15920 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15921 cmd->flags, cmd->roam_scan_mode, 15922 cmd->roam_ap_sel_mode, cmd->roam_delay, 15923 cmd->num_chan, cmd->num_bssid); 15924 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15925 15926 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15927 WMI_ROAM_INVOKE_CMDID)) { 15928 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15929 wmi_buf_free(wmi_buf); 15930 return QDF_STATUS_E_FAILURE; 15931 } 15932 15933 return QDF_STATUS_SUCCESS; 15934 } 15935 15936 /** 15937 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15938 * @wmi_handle: wmi handle 15939 * @command: command 15940 * @vdev_id: vdev id 15941 * 15942 * This function set roam offload command to fw. 15943 * 15944 * Return: CDF status 15945 */ 15946 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15947 uint32_t command, uint32_t vdev_id) 15948 { 15949 QDF_STATUS status; 15950 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15951 wmi_buf_t buf = NULL; 15952 int len; 15953 uint8_t *buf_ptr; 15954 15955 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15956 buf = wmi_buf_alloc(wmi_handle, len); 15957 if (!buf) { 15958 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15959 return QDF_STATUS_E_NOMEM; 15960 } 15961 15962 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15963 15964 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15965 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15966 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15967 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15968 cmd_fp->vdev_id = vdev_id; 15969 cmd_fp->command_arg = command; 15970 15971 status = wmi_unified_cmd_send(wmi_handle, buf, 15972 len, WMI_ROAM_SCAN_CMD); 15973 if (QDF_IS_STATUS_ERROR(status)) { 15974 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15975 status); 15976 goto error; 15977 } 15978 15979 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15980 return QDF_STATUS_SUCCESS; 15981 15982 error: 15983 wmi_buf_free(buf); 15984 15985 return status; 15986 } 15987 15988 /** 15989 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15990 * @wmi_handle: wmi handle 15991 * @ap_profile_p: ap profile 15992 * @vdev_id: vdev id 15993 * 15994 * Send WMI_ROAM_AP_PROFILE to firmware 15995 * 15996 * Return: CDF status 15997 */ 15998 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15999 struct ap_profile_params *ap_profile) 16000 { 16001 wmi_buf_t buf = NULL; 16002 QDF_STATUS status; 16003 int len; 16004 uint8_t *buf_ptr; 16005 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 16006 wmi_roam_cnd_scoring_param *score_param; 16007 wmi_ap_profile *profile; 16008 16009 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 16010 len += sizeof(*score_param); 16011 buf = wmi_buf_alloc(wmi_handle, len); 16012 if (!buf) { 16013 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16014 return QDF_STATUS_E_NOMEM; 16015 } 16016 16017 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16018 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 16019 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 16020 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 16021 WMITLV_GET_STRUCT_TLVLEN 16022 (wmi_roam_ap_profile_fixed_param)); 16023 /* fill in threshold values */ 16024 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 16025 roam_ap_profile_fp->id = 0; 16026 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 16027 16028 profile = (wmi_ap_profile *)buf_ptr; 16029 WMITLV_SET_HDR(&profile->tlv_header, 16030 WMITLV_TAG_STRUC_wmi_ap_profile, 16031 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 16032 profile->flags = ap_profile->profile.flags; 16033 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 16034 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 16035 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 16036 profile->ssid.ssid_len); 16037 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 16038 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 16039 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 16040 profile->rsn_mcastmgmtcipherset = 16041 ap_profile->profile.rsn_mcastmgmtcipherset; 16042 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 16043 16044 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", 16045 profile->flags, profile->rssi_threshold, 16046 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 16047 profile->rsn_authmode, profile->rsn_ucastcipherset, 16048 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 16049 profile->rssi_abs_thresh); 16050 16051 buf_ptr += sizeof(wmi_ap_profile); 16052 16053 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 16054 WMITLV_SET_HDR(&score_param->tlv_header, 16055 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 16056 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 16057 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 16058 score_param->rssi_weightage_pcnt = 16059 ap_profile->param.rssi_weightage; 16060 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 16061 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 16062 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 16063 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 16064 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 16065 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 16066 score_param->esp_qbss_weightage_pcnt = 16067 ap_profile->param.esp_qbss_weightage; 16068 score_param->beamforming_weightage_pcnt = 16069 ap_profile->param.beamforming_weightage; 16070 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 16071 score_param->oce_wan_weightage_pcnt = 16072 ap_profile->param.oce_wan_weightage; 16073 16074 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", 16075 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 16076 score_param->ht_weightage_pcnt, 16077 score_param->vht_weightage_pcnt, 16078 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 16079 score_param->band_weightage_pcnt, 16080 score_param->nss_weightage_pcnt, 16081 score_param->esp_qbss_weightage_pcnt, 16082 score_param->beamforming_weightage_pcnt, 16083 score_param->pcl_weightage_pcnt, 16084 score_param->oce_wan_weightage_pcnt); 16085 16086 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 16087 score_param->band_scoring.score_pcnt = 16088 ap_profile->param.band_index_score; 16089 score_param->nss_scoring.score_pcnt = 16090 ap_profile->param.nss_index_score; 16091 16092 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 16093 score_param->bw_scoring.score_pcnt, 16094 score_param->band_scoring.score_pcnt, 16095 score_param->nss_scoring.score_pcnt); 16096 16097 score_param->rssi_scoring.best_rssi_threshold = 16098 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 16099 score_param->rssi_scoring.good_rssi_threshold = 16100 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 16101 score_param->rssi_scoring.bad_rssi_threshold = 16102 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 16103 score_param->rssi_scoring.good_rssi_pcnt = 16104 ap_profile->param.rssi_scoring.good_rssi_pcnt; 16105 score_param->rssi_scoring.bad_rssi_pcnt = 16106 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 16107 score_param->rssi_scoring.good_bucket_size = 16108 ap_profile->param.rssi_scoring.good_bucket_size; 16109 score_param->rssi_scoring.bad_bucket_size = 16110 ap_profile->param.rssi_scoring.bad_bucket_size; 16111 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 16112 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 16113 16114 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 16115 score_param->rssi_scoring.best_rssi_threshold, 16116 score_param->rssi_scoring.good_rssi_threshold, 16117 score_param->rssi_scoring.bad_rssi_threshold, 16118 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 16119 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 16120 score_param->rssi_scoring.good_rssi_pcnt, 16121 score_param->rssi_scoring.bad_rssi_pcnt, 16122 score_param->rssi_scoring.good_bucket_size, 16123 score_param->rssi_scoring.bad_bucket_size); 16124 16125 score_param->esp_qbss_scoring.num_slot = 16126 ap_profile->param.esp_qbss_scoring.num_slot; 16127 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 16128 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 16129 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 16130 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 16131 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 16132 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 16133 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 16134 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 16135 16136 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16137 score_param->esp_qbss_scoring.num_slot, 16138 score_param->esp_qbss_scoring.score_pcnt3_to_0, 16139 score_param->esp_qbss_scoring.score_pcnt7_to_4, 16140 score_param->esp_qbss_scoring.score_pcnt11_to_8, 16141 score_param->esp_qbss_scoring.score_pcnt15_to_12); 16142 16143 score_param->oce_wan_scoring.num_slot = 16144 ap_profile->param.oce_wan_scoring.num_slot; 16145 score_param->oce_wan_scoring.score_pcnt3_to_0 = 16146 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 16147 score_param->oce_wan_scoring.score_pcnt7_to_4 = 16148 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 16149 score_param->oce_wan_scoring.score_pcnt11_to_8 = 16150 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 16151 score_param->oce_wan_scoring.score_pcnt15_to_12 = 16152 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 16153 16154 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 16155 score_param->oce_wan_scoring.num_slot, 16156 score_param->oce_wan_scoring.score_pcnt3_to_0, 16157 score_param->oce_wan_scoring.score_pcnt7_to_4, 16158 score_param->oce_wan_scoring.score_pcnt11_to_8, 16159 score_param->oce_wan_scoring.score_pcnt15_to_12); 16160 16161 status = wmi_unified_cmd_send(wmi_handle, buf, 16162 len, WMI_ROAM_AP_PROFILE); 16163 if (QDF_IS_STATUS_ERROR(status)) { 16164 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 16165 status); 16166 wmi_buf_free(buf); 16167 } 16168 16169 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 16170 16171 return status; 16172 } 16173 16174 /** 16175 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 16176 * @wmi_handle: wmi handle 16177 * @scan_period: scan period 16178 * @scan_age: scan age 16179 * @vdev_id: vdev id 16180 * 16181 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 16182 * 16183 * Return: CDF status 16184 */ 16185 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 16186 uint32_t scan_period, 16187 uint32_t scan_age, 16188 uint32_t vdev_id) 16189 { 16190 QDF_STATUS status; 16191 wmi_buf_t buf = NULL; 16192 int len; 16193 uint8_t *buf_ptr; 16194 wmi_roam_scan_period_fixed_param *scan_period_fp; 16195 16196 /* Send scan period values */ 16197 len = sizeof(wmi_roam_scan_period_fixed_param); 16198 buf = wmi_buf_alloc(wmi_handle, len); 16199 if (!buf) { 16200 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16201 return QDF_STATUS_E_NOMEM; 16202 } 16203 16204 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16205 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 16206 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 16207 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 16208 WMITLV_GET_STRUCT_TLVLEN 16209 (wmi_roam_scan_period_fixed_param)); 16210 /* fill in scan period values */ 16211 scan_period_fp->vdev_id = vdev_id; 16212 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 16213 scan_period_fp->roam_scan_age = scan_age; 16214 16215 status = wmi_unified_cmd_send(wmi_handle, buf, 16216 len, WMI_ROAM_SCAN_PERIOD); 16217 if (QDF_IS_STATUS_ERROR(status)) { 16218 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 16219 status); 16220 goto error; 16221 } 16222 16223 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 16224 __func__, scan_period, scan_age); 16225 return QDF_STATUS_SUCCESS; 16226 error: 16227 wmi_buf_free(buf); 16228 16229 return status; 16230 } 16231 16232 /** 16233 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 16234 * @wmi_handle: wmi handle 16235 * @chan_count: channel count 16236 * @chan_list: channel list 16237 * @list_type: list type 16238 * @vdev_id: vdev id 16239 * 16240 * Set roam offload channel list. 16241 * 16242 * Return: CDF status 16243 */ 16244 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 16245 uint8_t chan_count, 16246 uint32_t *chan_list, 16247 uint8_t list_type, uint32_t vdev_id) 16248 { 16249 wmi_buf_t buf = NULL; 16250 QDF_STATUS status; 16251 int len, list_tlv_len; 16252 int i; 16253 uint8_t *buf_ptr; 16254 wmi_roam_chan_list_fixed_param *chan_list_fp; 16255 uint32_t *roam_chan_list_array; 16256 16257 if (chan_count == 0) { 16258 WMI_LOGD("%s : invalid number of channels %d", __func__, 16259 chan_count); 16260 return QDF_STATUS_E_EMPTY; 16261 } 16262 /* Channel list is a table of 2 TLV's */ 16263 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 16264 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 16265 buf = wmi_buf_alloc(wmi_handle, len); 16266 if (!buf) { 16267 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16268 return QDF_STATUS_E_NOMEM; 16269 } 16270 16271 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16272 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 16273 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 16274 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 16275 WMITLV_GET_STRUCT_TLVLEN 16276 (wmi_roam_chan_list_fixed_param)); 16277 chan_list_fp->vdev_id = vdev_id; 16278 chan_list_fp->num_chan = chan_count; 16279 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 16280 /* external app is controlling channel list */ 16281 chan_list_fp->chan_list_type = 16282 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 16283 } else { 16284 /* umac supplied occupied channel list in LFR */ 16285 chan_list_fp->chan_list_type = 16286 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 16287 } 16288 16289 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 16290 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16291 (chan_list_fp->num_chan * sizeof(uint32_t))); 16292 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16293 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 16294 for (i = 0; ((i < chan_list_fp->num_chan) && 16295 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 16296 roam_chan_list_array[i] = chan_list[i]; 16297 WMI_LOGI("%d,", roam_chan_list_array[i]); 16298 } 16299 16300 status = wmi_unified_cmd_send(wmi_handle, buf, 16301 len, WMI_ROAM_CHAN_LIST); 16302 if (QDF_IS_STATUS_ERROR(status)) { 16303 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 16304 status); 16305 goto error; 16306 } 16307 16308 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 16309 return QDF_STATUS_SUCCESS; 16310 error: 16311 wmi_buf_free(buf); 16312 16313 return status; 16314 } 16315 16316 /** 16317 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 16318 * @wmi_handle: wmi handle 16319 * @req_buf: per roam config buffer 16320 * 16321 * Return: QDF status 16322 */ 16323 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 16324 struct wmi_per_roam_config_req *req_buf) 16325 { 16326 wmi_buf_t buf = NULL; 16327 QDF_STATUS status; 16328 int len; 16329 uint8_t *buf_ptr; 16330 wmi_roam_per_config_fixed_param *wmi_per_config; 16331 16332 len = sizeof(wmi_roam_per_config_fixed_param); 16333 buf = wmi_buf_alloc(wmi_handle, len); 16334 if (!buf) { 16335 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16336 return QDF_STATUS_E_NOMEM; 16337 } 16338 16339 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16340 wmi_per_config = 16341 (wmi_roam_per_config_fixed_param *) buf_ptr; 16342 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 16343 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 16344 WMITLV_GET_STRUCT_TLVLEN 16345 (wmi_roam_per_config_fixed_param)); 16346 16347 /* fill in per roam config values */ 16348 wmi_per_config->vdev_id = req_buf->vdev_id; 16349 16350 wmi_per_config->enable = req_buf->per_config.enable; 16351 wmi_per_config->high_rate_thresh = 16352 (req_buf->per_config.tx_high_rate_thresh << 16) | 16353 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 16354 wmi_per_config->low_rate_thresh = 16355 (req_buf->per_config.tx_low_rate_thresh << 16) | 16356 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 16357 wmi_per_config->pkt_err_rate_thresh_pct = 16358 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 16359 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 16360 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 16361 wmi_per_config->pkt_err_rate_mon_time = 16362 (req_buf->per_config.tx_per_mon_time << 16) | 16363 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 16364 wmi_per_config->min_candidate_rssi = 16365 req_buf->per_config.min_candidate_rssi; 16366 16367 /* Send per roam config parameters */ 16368 status = wmi_unified_cmd_send(wmi_handle, buf, 16369 len, WMI_ROAM_PER_CONFIG_CMDID); 16370 if (QDF_IS_STATUS_ERROR(status)) { 16371 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 16372 status); 16373 wmi_buf_free(buf); 16374 return status; 16375 } 16376 16377 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 16378 req_buf->per_config.enable, req_buf->vdev_id); 16379 return QDF_STATUS_SUCCESS; 16380 } 16381 16382 /** 16383 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 16384 * @wmi_handle: wmi handle 16385 * @rssi_change_thresh: RSSI Change threshold 16386 * @bcn_rssi_weight: beacon RSSI weight 16387 * @vdev_id: vdev id 16388 * 16389 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 16390 * 16391 * Return: CDF status 16392 */ 16393 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 16394 uint32_t vdev_id, 16395 int32_t rssi_change_thresh, 16396 uint32_t bcn_rssi_weight, 16397 uint32_t hirssi_delay_btw_scans) 16398 { 16399 wmi_buf_t buf = NULL; 16400 QDF_STATUS status; 16401 int len; 16402 uint8_t *buf_ptr; 16403 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 16404 16405 /* Send rssi change parameters */ 16406 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 16407 buf = wmi_buf_alloc(wmi_handle, len); 16408 if (!buf) { 16409 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16410 return QDF_STATUS_E_NOMEM; 16411 } 16412 16413 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16414 rssi_change_fp = 16415 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 16416 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 16417 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 16418 WMITLV_GET_STRUCT_TLVLEN 16419 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 16420 /* fill in rssi change threshold (hysteresis) values */ 16421 rssi_change_fp->vdev_id = vdev_id; 16422 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 16423 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 16424 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 16425 16426 status = wmi_unified_cmd_send(wmi_handle, buf, 16427 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 16428 if (QDF_IS_STATUS_ERROR(status)) { 16429 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 16430 status); 16431 goto error; 16432 } 16433 16434 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 16435 rssi_change_thresh, bcn_rssi_weight); 16436 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 16437 return QDF_STATUS_SUCCESS; 16438 error: 16439 wmi_buf_free(buf); 16440 16441 return status; 16442 } 16443 16444 /** wmi_get_hotlist_entries_per_page() - hotlist entries per page 16445 * @wmi_handle: wmi handle. 16446 * @cmd: size of command structure. 16447 * @per_entry_size: per entry size. 16448 * 16449 * This utility function calculates how many hotlist entries can 16450 * fit in one page. 16451 * 16452 * Return: number of entries 16453 */ 16454 static inline int wmi_get_hotlist_entries_per_page(wmi_unified_t wmi_handle, 16455 size_t cmd_size, 16456 size_t per_entry_size) 16457 { 16458 uint32_t avail_space = 0; 16459 int num_entries = 0; 16460 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle); 16461 16462 /* Calculate number of hotlist entries that can 16463 * be passed in wma message request. 16464 */ 16465 avail_space = max_msg_len - cmd_size; 16466 num_entries = avail_space / per_entry_size; 16467 return num_entries; 16468 } 16469 16470 /** 16471 * send_get_buf_extscan_hotlist_cmd_tlv() - prepare hotlist command 16472 * @wmi_handle: wmi handle 16473 * @photlist: hotlist command params 16474 * @buf_len: buffer length 16475 * 16476 * This function fills individual elements for hotlist request and 16477 * TLV for bssid entries 16478 * 16479 * Return: CDF Status. 16480 */ 16481 static QDF_STATUS send_get_buf_extscan_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 16482 struct ext_scan_setbssi_hotlist_params * 16483 photlist, int *buf_len) 16484 { 16485 wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd = NULL; 16486 wmi_extscan_hotlist_entry *dest_hotlist; 16487 struct ap_threshold_params *src_ap = photlist->ap; 16488 wmi_buf_t buf; 16489 uint8_t *buf_ptr; 16490 16491 int j, index = 0; 16492 int cmd_len = 0; 16493 int num_entries; 16494 int min_entries = 0; 16495 uint32_t numap = photlist->numAp; 16496 int len = sizeof(*cmd); 16497 16498 len += WMI_TLV_HDR_SIZE; 16499 cmd_len = len; 16500 16501 num_entries = wmi_get_hotlist_entries_per_page(wmi_handle, 16502 cmd_len, 16503 sizeof(*dest_hotlist)); 16504 /* setbssid hotlist expects the bssid list 16505 * to be non zero value 16506 */ 16507 if (!numap || (numap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS)) { 16508 WMI_LOGE("Invalid number of APs: %d", numap); 16509 return QDF_STATUS_E_INVAL; 16510 } 16511 16512 /* Split the hot list entry pages and send multiple command 16513 * requests if the buffer reaches the maximum request size 16514 */ 16515 while (index < numap) { 16516 min_entries = QDF_MIN(num_entries, numap); 16517 len += min_entries * sizeof(wmi_extscan_hotlist_entry); 16518 buf = wmi_buf_alloc(wmi_handle, len); 16519 if (!buf) { 16520 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 16521 return QDF_STATUS_E_FAILURE; 16522 } 16523 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16524 cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) 16525 buf_ptr; 16526 WMITLV_SET_HDR(&cmd->tlv_header, 16527 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, 16528 WMITLV_GET_STRUCT_TLVLEN 16529 (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); 16530 16531 /* Multiple requests are sent until the num_entries_in_page 16532 * matches the total_entries 16533 */ 16534 cmd->request_id = photlist->requestId; 16535 cmd->vdev_id = photlist->sessionId; 16536 cmd->total_entries = numap; 16537 cmd->mode = 1; 16538 cmd->num_entries_in_page = min_entries; 16539 cmd->lost_ap_scan_count = photlist->lost_ap_sample_size; 16540 cmd->first_entry_index = index; 16541 16542 WMI_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d lost_ap_sample_size: %d", 16543 __func__, cmd->vdev_id, cmd->total_entries, 16544 cmd->num_entries_in_page, 16545 cmd->lost_ap_scan_count); 16546 16547 buf_ptr += sizeof(*cmd); 16548 WMITLV_SET_HDR(buf_ptr, 16549 WMITLV_TAG_ARRAY_STRUC, 16550 min_entries * sizeof(wmi_extscan_hotlist_entry)); 16551 dest_hotlist = (wmi_extscan_hotlist_entry *) 16552 (buf_ptr + WMI_TLV_HDR_SIZE); 16553 16554 /* Populate bssid, channel info and rssi 16555 * for the bssid's that are sent as hotlists. 16556 */ 16557 for (j = 0; j < min_entries; j++) { 16558 WMITLV_SET_HDR(dest_hotlist, 16559 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, 16560 WMITLV_GET_STRUCT_TLVLEN 16561 (wmi_extscan_hotlist_entry)); 16562 16563 dest_hotlist->min_rssi = src_ap->low; 16564 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes, 16565 &dest_hotlist->bssid); 16566 16567 WMI_LOGD("%s:channel:%d min_rssi %d", 16568 __func__, dest_hotlist->channel, 16569 dest_hotlist->min_rssi); 16570 WMI_LOGD 16571 ("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16572 __func__, dest_hotlist->bssid.mac_addr31to0, 16573 dest_hotlist->bssid.mac_addr47to32); 16574 dest_hotlist++; 16575 src_ap++; 16576 } 16577 buf_ptr += WMI_TLV_HDR_SIZE + 16578 (min_entries * sizeof(wmi_extscan_hotlist_entry)); 16579 16580 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16581 WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { 16582 WMI_LOGE("%s: failed to send command", __func__); 16583 wmi_buf_free(buf); 16584 return QDF_STATUS_E_FAILURE; 16585 } 16586 index = index + min_entries; 16587 num_entries = numap - min_entries; 16588 len = cmd_len; 16589 } 16590 return QDF_STATUS_SUCCESS; 16591 } 16592 16593 /** 16594 * send_set_active_bpf_mode_cmd_tlv() - configure active BPF mode in FW 16595 * @wmi_handle: the WMI handle 16596 * @vdev_id: the Id of the vdev to apply the configuration to 16597 * @ucast_mode: the active BPF mode to configure for unicast packets 16598 * @mcast_bcast_mode: the active BPF mode to configure for multicast/broadcast 16599 * packets 16600 * 16601 * Return: QDF status 16602 */ 16603 static QDF_STATUS send_set_active_bpf_mode_cmd_tlv(wmi_unified_t wmi_handle, 16604 uint8_t vdev_id, 16605 enum wmi_host_active_bpf_mode ucast_mode, 16606 enum wmi_host_active_bpf_mode mcast_bcast_mode) 16607 { 16608 const WMITLV_TAG_ID tag_id = 16609 WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param; 16610 const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN( 16611 wmi_bpf_set_vdev_active_mode_cmd_fixed_param); 16612 QDF_STATUS status; 16613 wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd; 16614 wmi_buf_t buf; 16615 16616 WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)", 16617 vdev_id, ucast_mode, mcast_bcast_mode); 16618 16619 /* allocate command buffer */ 16620 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 16621 if (!buf) { 16622 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 16623 return QDF_STATUS_E_NOMEM; 16624 } 16625 16626 /* set TLV header */ 16627 cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf); 16628 WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len); 16629 16630 /* populate data */ 16631 cmd->vdev_id = vdev_id; 16632 cmd->uc_mode = ucast_mode; 16633 cmd->mcbc_mode = mcast_bcast_mode; 16634 16635 /* send to FW */ 16636 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 16637 WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID); 16638 if (QDF_IS_STATUS_ERROR(status)) { 16639 WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d", 16640 status); 16641 wmi_buf_free(buf); 16642 return status; 16643 } 16644 16645 WMI_LOGD("Sent WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID successfully"); 16646 16647 return QDF_STATUS_SUCCESS; 16648 } 16649 16650 /** 16651 * send_power_dbg_cmd_tlv() - send power debug commands 16652 * @wmi_handle: wmi handle 16653 * @param: wmi power debug parameter 16654 * 16655 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 16656 * 16657 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16658 */ 16659 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 16660 struct wmi_power_dbg_params *param) 16661 { 16662 wmi_buf_t buf = NULL; 16663 QDF_STATUS status; 16664 int len, args_tlv_len; 16665 uint8_t *buf_ptr; 16666 uint8_t i; 16667 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 16668 uint32_t *cmd_args; 16669 16670 /* Prepare and send power debug cmd parameters */ 16671 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 16672 len = sizeof(*cmd) + args_tlv_len; 16673 buf = wmi_buf_alloc(wmi_handle, len); 16674 if (!buf) { 16675 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16676 return QDF_STATUS_E_NOMEM; 16677 } 16678 16679 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16680 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 16681 WMITLV_SET_HDR(&cmd->tlv_header, 16682 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 16683 WMITLV_GET_STRUCT_TLVLEN 16684 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 16685 16686 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16687 param->pdev_id); 16688 cmd->module_id = param->module_id; 16689 cmd->num_args = param->num_args; 16690 buf_ptr += sizeof(*cmd); 16691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16692 (param->num_args * sizeof(uint32_t))); 16693 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16694 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 16695 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 16696 cmd_args[i] = param->args[i]; 16697 WMI_LOGI("%d,", param->args[i]); 16698 } 16699 16700 status = wmi_unified_cmd_send(wmi_handle, buf, 16701 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 16702 if (QDF_IS_STATUS_ERROR(status)) { 16703 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 16704 status); 16705 goto error; 16706 } 16707 16708 return QDF_STATUS_SUCCESS; 16709 error: 16710 wmi_buf_free(buf); 16711 16712 return status; 16713 } 16714 16715 /** 16716 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 16717 * @wmi_handle: wmi handle 16718 * @param: wmi multiple vdev restart req param 16719 * 16720 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 16721 * 16722 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16723 */ 16724 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 16725 wmi_unified_t wmi_handle, 16726 struct multiple_vdev_restart_params *param) 16727 { 16728 wmi_buf_t buf; 16729 QDF_STATUS qdf_status; 16730 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 16731 int i; 16732 uint8_t *buf_ptr; 16733 uint32_t *vdev_ids; 16734 wmi_channel *chan_info; 16735 struct channel_param *tchan_info; 16736 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 16737 16738 len += sizeof(wmi_channel); 16739 if (param->num_vdevs) 16740 len += sizeof(uint32_t) * param->num_vdevs; 16741 16742 buf = wmi_buf_alloc(wmi_handle, len); 16743 if (!buf) { 16744 WMI_LOGE("Failed to allocate memory\n"); 16745 qdf_status = QDF_STATUS_E_NOMEM; 16746 goto end; 16747 } 16748 16749 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16750 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 16751 buf_ptr; 16752 16753 WMITLV_SET_HDR(&cmd->tlv_header, 16754 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 16755 WMITLV_GET_STRUCT_TLVLEN 16756 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 16757 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16758 param->pdev_id); 16759 cmd->requestor_id = param->requestor_id; 16760 cmd->disable_hw_ack = param->disable_hw_ack; 16761 cmd->cac_duration_ms = param->cac_duration_ms; 16762 cmd->num_vdevs = param->num_vdevs; 16763 16764 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 16765 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 16766 " cmd->num_vdevs: %d ", 16767 __func__, cmd->pdev_id, cmd->requestor_id, 16768 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 16769 buf_ptr += sizeof(*cmd); 16770 16771 WMITLV_SET_HDR(buf_ptr, 16772 WMITLV_TAG_ARRAY_UINT32, 16773 sizeof(uint32_t) * param->num_vdevs); 16774 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 16775 for (i = 0; i < param->num_vdevs; i++) { 16776 vdev_ids[i] = param->vdev_ids[i]; 16777 } 16778 16779 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 16780 16781 WMITLV_SET_HDR(buf_ptr, 16782 WMITLV_TAG_STRUC_wmi_channel, 16783 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16784 chan_info = (wmi_channel *)buf_ptr; 16785 tchan_info = &(param->ch_param); 16786 chan_info->mhz = tchan_info->mhz; 16787 chan_info->band_center_freq1 = tchan_info->cfreq1; 16788 chan_info->band_center_freq2 = tchan_info->cfreq2; 16789 if (tchan_info->is_chan_passive) 16790 WMI_SET_CHANNEL_FLAG(chan_info, 16791 WMI_CHAN_FLAG_PASSIVE); 16792 if (tchan_info->dfs_set) 16793 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 16794 16795 if (tchan_info->allow_vht) 16796 WMI_SET_CHANNEL_FLAG(chan_info, 16797 WMI_CHAN_FLAG_ALLOW_VHT); 16798 else if (tchan_info->allow_ht) 16799 WMI_SET_CHANNEL_FLAG(chan_info, 16800 WMI_CHAN_FLAG_ALLOW_HT); 16801 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 16802 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 16803 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 16804 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 16805 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 16806 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 16807 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 16808 16809 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 16810 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 16811 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 16812 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 16813 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 16814 "tchan_info->reg_class_id: %d ," 16815 "tchan_info->maxregpower : %d ", __func__, 16816 tchan_info->is_chan_passive, tchan_info->dfs_set, 16817 tchan_info->allow_vht, tchan_info->allow_ht, 16818 tchan_info->antennamax, tchan_info->phy_mode, 16819 tchan_info->minpower, tchan_info->maxpower, 16820 tchan_info->maxregpower, tchan_info->reg_class_id, 16821 tchan_info->maxregpower); 16822 16823 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 16824 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 16825 16826 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16827 WMI_LOGE("%s: Failed to send\n", __func__); 16828 wmi_buf_free(buf); 16829 } 16830 16831 end: 16832 return qdf_status; 16833 } 16834 16835 /** 16836 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 16837 * @wmi_handle: wmi handle 16838 * @pdev_id: pdev id 16839 * 16840 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 16841 * 16842 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16843 */ 16844 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 16845 uint32_t pdev_id) 16846 { 16847 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 16848 wmi_buf_t buf; 16849 uint16_t len; 16850 QDF_STATUS ret; 16851 16852 len = sizeof(*cmd); 16853 buf = wmi_buf_alloc(wmi_handle, len); 16854 16855 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16856 16857 if (!buf) { 16858 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16859 return QDF_STATUS_E_NOMEM; 16860 } 16861 16862 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16863 wmi_buf_data(buf); 16864 16865 WMITLV_SET_HDR(&cmd->tlv_header, 16866 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16867 WMITLV_GET_STRUCT_TLVLEN( 16868 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16869 16870 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16871 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16872 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16873 if (QDF_IS_STATUS_ERROR(ret)) { 16874 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16875 __func__, ret, pdev_id); 16876 wmi_buf_free(buf); 16877 return QDF_STATUS_E_FAILURE; 16878 } 16879 16880 return QDF_STATUS_SUCCESS; 16881 } 16882 16883 /** 16884 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16885 * @wmi_handle: wmi handle 16886 * @pdev_id: pdev id 16887 * 16888 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16889 * 16890 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16891 */ 16892 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16893 uint32_t pdev_id) 16894 { 16895 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16896 wmi_buf_t buf; 16897 uint16_t len; 16898 QDF_STATUS ret; 16899 16900 len = sizeof(*cmd); 16901 buf = wmi_buf_alloc(wmi_handle, len); 16902 16903 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16904 16905 if (!buf) { 16906 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16907 return QDF_STATUS_E_NOMEM; 16908 } 16909 16910 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16911 wmi_buf_data(buf); 16912 16913 WMITLV_SET_HDR(&cmd->tlv_header, 16914 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16915 WMITLV_GET_STRUCT_TLVLEN( 16916 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16917 16918 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16919 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16920 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16921 if (QDF_IS_STATUS_ERROR(ret)) { 16922 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16923 __func__, ret, pdev_id); 16924 wmi_buf_free(buf); 16925 return QDF_STATUS_E_FAILURE; 16926 } 16927 16928 return QDF_STATUS_SUCCESS; 16929 } 16930 16931 /** 16932 * init_cmd_send_tlv() - send initialization cmd to fw 16933 * @wmi_handle: wmi handle 16934 * @param param: pointer to wmi init param 16935 * 16936 * Return: QDF_STATUS_SUCCESS for success or error code 16937 */ 16938 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16939 struct wmi_init_cmd_param *param) 16940 { 16941 wmi_buf_t buf; 16942 wmi_init_cmd_fixed_param *cmd; 16943 uint8_t *buf_ptr; 16944 wmi_resource_config *resource_cfg; 16945 wlan_host_memory_chunk *host_mem_chunks; 16946 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16947 uint16_t idx; 16948 int len; 16949 QDF_STATUS ret; 16950 16951 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16952 WMI_TLV_HDR_SIZE; 16953 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16954 16955 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16956 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16957 WMI_TLV_HDR_SIZE + 16958 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16959 16960 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16961 if (!buf) { 16962 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16963 return QDF_STATUS_E_FAILURE; 16964 } 16965 16966 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16967 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16968 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16969 16970 host_mem_chunks = (wlan_host_memory_chunk *) 16971 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16972 + WMI_TLV_HDR_SIZE); 16973 16974 WMITLV_SET_HDR(&cmd->tlv_header, 16975 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16976 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16977 16978 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16979 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16980 WMITLV_TAG_STRUC_wmi_resource_config, 16981 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16982 16983 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16984 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16985 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16986 WMITLV_GET_STRUCT_TLVLEN 16987 (wlan_host_memory_chunk)); 16988 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16989 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16990 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16991 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16992 "chunk %d len %d requested ,ptr 0x%x ", 16993 idx, host_mem_chunks[idx].size, 16994 host_mem_chunks[idx].ptr); 16995 } 16996 cmd->num_host_mem_chunks = param->num_mem_chunks; 16997 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16998 16999 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 17000 WMITLV_TAG_ARRAY_STRUC, 17001 (sizeof(wlan_host_memory_chunk) * 17002 param->num_mem_chunks)); 17003 17004 /* Fill hw mode id config */ 17005 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 17006 17007 /* Fill fw_abi_vers */ 17008 copy_fw_abi_version_tlv(wmi_handle, cmd); 17009 17010 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 17011 if (QDF_IS_STATUS_ERROR(ret)) { 17012 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 17013 ret); 17014 wmi_buf_free(buf); 17015 } 17016 17017 return ret; 17018 17019 } 17020 17021 /** 17022 * send_addba_send_cmd_tlv() - send addba send command to fw 17023 * @wmi_handle: wmi handle 17024 * @param: pointer to delba send params 17025 * @macaddr: peer mac address 17026 * 17027 * Send WMI_ADDBA_SEND_CMDID command to firmware 17028 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17029 */ 17030 static QDF_STATUS 17031 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 17032 uint8_t macaddr[IEEE80211_ADDR_LEN], 17033 struct addba_send_params *param) 17034 { 17035 wmi_addba_send_cmd_fixed_param *cmd; 17036 wmi_buf_t buf; 17037 uint16_t len; 17038 QDF_STATUS ret; 17039 17040 len = sizeof(*cmd); 17041 17042 buf = wmi_buf_alloc(wmi_handle, len); 17043 if (!buf) { 17044 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17045 return QDF_STATUS_E_NOMEM; 17046 } 17047 17048 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 17049 17050 WMITLV_SET_HDR(&cmd->tlv_header, 17051 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 17052 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 17053 17054 cmd->vdev_id = param->vdev_id; 17055 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17056 cmd->tid = param->tidno; 17057 cmd->buffersize = param->buffersize; 17058 17059 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 17060 if (QDF_IS_STATUS_ERROR(ret)) { 17061 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17062 wmi_buf_free(buf); 17063 return QDF_STATUS_E_FAILURE; 17064 } 17065 17066 return QDF_STATUS_SUCCESS; 17067 } 17068 17069 /** 17070 * send_delba_send_cmd_tlv() - send delba send command to fw 17071 * @wmi_handle: wmi handle 17072 * @param: pointer to delba send params 17073 * @macaddr: peer mac address 17074 * 17075 * Send WMI_DELBA_SEND_CMDID command to firmware 17076 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 17077 */ 17078 static QDF_STATUS 17079 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 17080 uint8_t macaddr[IEEE80211_ADDR_LEN], 17081 struct delba_send_params *param) 17082 { 17083 wmi_delba_send_cmd_fixed_param *cmd; 17084 wmi_buf_t buf; 17085 uint16_t len; 17086 QDF_STATUS ret; 17087 17088 len = sizeof(*cmd); 17089 17090 buf = wmi_buf_alloc(wmi_handle, len); 17091 if (!buf) { 17092 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 17093 return QDF_STATUS_E_NOMEM; 17094 } 17095 17096 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 17097 17098 WMITLV_SET_HDR(&cmd->tlv_header, 17099 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 17100 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 17101 17102 cmd->vdev_id = param->vdev_id; 17103 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17104 cmd->tid = param->tidno; 17105 cmd->initiator = param->initiator; 17106 cmd->reasoncode = param->reasoncode; 17107 17108 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 17109 if (QDF_IS_STATUS_ERROR(ret)) { 17110 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17111 wmi_buf_free(buf); 17112 return QDF_STATUS_E_FAILURE; 17113 } 17114 17115 return QDF_STATUS_SUCCESS; 17116 } 17117 17118 /** 17119 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 17120 * to fw 17121 * @wmi_handle: wmi handle 17122 * @param: pointer to addba clearresp params 17123 * @macaddr: peer mac address 17124 * Return: 0 for success or error code 17125 */ 17126 static QDF_STATUS 17127 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 17128 uint8_t macaddr[IEEE80211_ADDR_LEN], 17129 struct addba_clearresponse_params *param) 17130 { 17131 wmi_addba_clear_resp_cmd_fixed_param *cmd; 17132 wmi_buf_t buf; 17133 uint16_t len; 17134 QDF_STATUS ret; 17135 17136 len = sizeof(*cmd); 17137 17138 buf = wmi_buf_alloc(wmi_handle, len); 17139 if (!buf) { 17140 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 17141 return QDF_STATUS_E_FAILURE; 17142 } 17143 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 17144 17145 WMITLV_SET_HDR(&cmd->tlv_header, 17146 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 17147 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 17148 17149 cmd->vdev_id = param->vdev_id; 17150 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 17151 17152 ret = wmi_unified_cmd_send(wmi_handle, 17153 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 17154 if (QDF_IS_STATUS_ERROR(ret)) { 17155 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 17156 wmi_buf_free(buf); 17157 return QDF_STATUS_E_FAILURE; 17158 } 17159 17160 return QDF_STATUS_SUCCESS; 17161 } 17162 17163 /** 17164 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 17165 * @wmi_handle: wmi handle 17166 * @bcn_ctrl_param: pointer to bcn_offload_control param 17167 * 17168 * Return: QDF_STATUS_SUCCESS for success or error code 17169 */ 17170 static 17171 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 17172 struct bcn_offload_control *bcn_ctrl_param) 17173 { 17174 wmi_buf_t buf; 17175 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 17176 QDF_STATUS ret; 17177 uint32_t len; 17178 17179 len = sizeof(*cmd); 17180 17181 buf = wmi_buf_alloc(wmi_handle, len); 17182 if (!buf) { 17183 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17184 return QDF_STATUS_E_FAILURE; 17185 } 17186 17187 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 17188 WMITLV_SET_HDR(&cmd->tlv_header, 17189 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 17190 WMITLV_GET_STRUCT_TLVLEN 17191 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 17192 cmd->vdev_id = bcn_ctrl_param->vdev_id; 17193 switch (bcn_ctrl_param->bcn_ctrl_op) { 17194 case BCN_OFFLD_CTRL_TX_DISABLE: 17195 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 17196 break; 17197 case BCN_OFFLD_CTRL_TX_ENABLE: 17198 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 17199 break; 17200 case BCN_OFFLD_CTRL_SWBA_DISABLE: 17201 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 17202 break; 17203 case BCN_OFFLD_CTRL_SWBA_ENABLE: 17204 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 17205 break; 17206 default: 17207 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 17208 bcn_ctrl_param->bcn_ctrl_op); 17209 wmi_buf_free(buf); 17210 return QDF_STATUS_E_FAILURE; 17211 break; 17212 } 17213 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17214 WMI_BCN_OFFLOAD_CTRL_CMDID); 17215 17216 if (QDF_IS_STATUS_ERROR(ret)) { 17217 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 17218 ret); 17219 wmi_buf_free(buf); 17220 } 17221 17222 return ret; 17223 } 17224 17225 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 17226 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 17227 struct nan_datapath_initiator_req *ndp_req) 17228 { 17229 uint16_t len; 17230 wmi_buf_t buf; 17231 uint8_t *tlv_ptr; 17232 QDF_STATUS status; 17233 wmi_channel *ch_tlv; 17234 wmi_ndp_initiator_req_fixed_param *cmd; 17235 uint32_t passphrase_len, service_name_len; 17236 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 17237 17238 /* 17239 * WMI command expects 4 byte alligned len: 17240 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17241 */ 17242 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 17243 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 17244 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 17245 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 17246 service_name_len = 17247 qdf_roundup(ndp_req->service_name.service_name_len, 4); 17248 /* allocated memory for fixed params as well as variable size data */ 17249 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 17250 + ndp_cfg_len + ndp_app_info_len + pmk_len 17251 + passphrase_len + service_name_len; 17252 17253 buf = wmi_buf_alloc(wmi_handle, len); 17254 if (!buf) { 17255 WMI_LOGE("wmi_buf_alloc failed"); 17256 return QDF_STATUS_E_NOMEM; 17257 } 17258 17259 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 17260 WMITLV_SET_HDR(&cmd->tlv_header, 17261 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 17262 WMITLV_GET_STRUCT_TLVLEN( 17263 wmi_ndp_initiator_req_fixed_param)); 17264 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 17265 cmd->transaction_id = ndp_req->transaction_id; 17266 cmd->service_instance_id = ndp_req->service_instance_id; 17267 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 17268 &cmd->peer_discovery_mac_addr); 17269 17270 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 17271 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 17272 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 17273 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 17274 cmd->nan_csid = ndp_req->ncs_sk_type; 17275 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 17276 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 17277 17278 ch_tlv = (wmi_channel *)&cmd[1]; 17279 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 17280 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 17281 ch_tlv->mhz = ndp_req->channel; 17282 tlv_ptr = (uint8_t *)&ch_tlv[1]; 17283 17284 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17285 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17286 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17287 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17288 17289 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17290 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17291 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 17292 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17293 17294 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17295 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 17296 cmd->nan_pmk_len); 17297 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17298 17299 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17300 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 17301 cmd->nan_passphrase_len); 17302 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17303 17304 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17305 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17306 ndp_req->service_name.service_name, 17307 cmd->nan_servicename_len); 17308 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17309 17310 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 17311 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 17312 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 17313 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 17314 cmd->peer_discovery_mac_addr.mac_addr31to0, 17315 cmd->peer_discovery_mac_addr.mac_addr47to32); 17316 17317 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 17318 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17319 ndp_req->ndp_config.ndp_cfg, 17320 ndp_req->ndp_config.ndp_cfg_len); 17321 17322 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 17323 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17324 ndp_req->ndp_info.ndp_app_info, 17325 ndp_req->ndp_info.ndp_app_info_len); 17326 17327 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17328 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17329 ndp_req->pmk.pmk, cmd->nan_pmk_len); 17330 17331 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17332 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17333 ndp_req->passphrase.passphrase, 17334 cmd->nan_passphrase_len); 17335 17336 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17337 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17338 ndp_req->service_name.service_name, 17339 cmd->nan_servicename_len); 17340 17341 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 17342 WMI_NDP_INITIATOR_REQ_CMDID); 17343 17344 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17345 WMI_NDP_INITIATOR_REQ_CMDID); 17346 if (QDF_IS_STATUS_ERROR(status)) { 17347 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 17348 wmi_buf_free(buf); 17349 } 17350 17351 return status; 17352 } 17353 17354 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 17355 struct nan_datapath_responder_req *req) 17356 { 17357 uint16_t len; 17358 wmi_buf_t buf; 17359 uint8_t *tlv_ptr; 17360 QDF_STATUS status; 17361 wmi_ndp_responder_req_fixed_param *cmd; 17362 uint32_t passphrase_len, service_name_len; 17363 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 17364 17365 vdev_id = wlan_vdev_get_id(req->vdev); 17366 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 17367 vdev_id, req->transaction_id, 17368 req->ndp_rsp, 17369 req->ndp_instance_id, 17370 req->ndp_info.ndp_app_info_len); 17371 17372 /* 17373 * WMI command expects 4 byte alligned len: 17374 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 17375 */ 17376 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 17377 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 17378 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 17379 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 17380 service_name_len = 17381 qdf_roundup(req->service_name.service_name_len, 4); 17382 17383 /* allocated memory for fixed params as well as variable size data */ 17384 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 17385 + pmk_len + passphrase_len + service_name_len; 17386 17387 buf = wmi_buf_alloc(wmi_handle, len); 17388 if (!buf) { 17389 WMI_LOGE("wmi_buf_alloc failed"); 17390 return QDF_STATUS_E_NOMEM; 17391 } 17392 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 17393 WMITLV_SET_HDR(&cmd->tlv_header, 17394 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 17395 WMITLV_GET_STRUCT_TLVLEN( 17396 wmi_ndp_responder_req_fixed_param)); 17397 cmd->vdev_id = vdev_id; 17398 cmd->transaction_id = req->transaction_id; 17399 cmd->ndp_instance_id = req->ndp_instance_id; 17400 cmd->rsp_code = req->ndp_rsp; 17401 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 17402 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 17403 cmd->nan_pmk_len = req->pmk.pmk_len; 17404 cmd->nan_csid = req->ncs_sk_type; 17405 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 17406 cmd->nan_servicename_len = req->service_name.service_name_len; 17407 17408 tlv_ptr = (uint8_t *)&cmd[1]; 17409 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 17410 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17411 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 17412 17413 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 17414 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 17415 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17416 req->ndp_info.ndp_app_info, 17417 req->ndp_info.ndp_app_info_len); 17418 17419 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 17420 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 17421 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 17422 cmd->nan_pmk_len); 17423 17424 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 17425 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 17426 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17427 req->passphrase.passphrase, 17428 cmd->nan_passphrase_len); 17429 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 17430 17431 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 17432 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 17433 req->service_name.service_name, 17434 cmd->nan_servicename_len); 17435 17436 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 17437 17438 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 17439 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 17440 17441 WMI_LOGD("ndp_config len: %d", 17442 req->ndp_config.ndp_cfg_len); 17443 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17444 req->ndp_config.ndp_cfg, 17445 req->ndp_config.ndp_cfg_len); 17446 17447 WMI_LOGD("ndp_app_info len: %d", 17448 req->ndp_info.ndp_app_info_len); 17449 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17450 req->ndp_info.ndp_app_info, 17451 req->ndp_info.ndp_app_info_len); 17452 17453 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17454 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17455 req->pmk.pmk, cmd->nan_pmk_len); 17456 17457 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17458 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17459 req->passphrase.passphrase, 17460 cmd->nan_passphrase_len); 17461 17462 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17463 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17464 req->service_name.service_name, 17465 cmd->nan_servicename_len); 17466 17467 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 17468 WMI_NDP_RESPONDER_REQ_CMDID); 17469 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17470 WMI_NDP_RESPONDER_REQ_CMDID); 17471 if (QDF_IS_STATUS_ERROR(status)) { 17472 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 17473 wmi_buf_free(buf); 17474 } 17475 return status; 17476 } 17477 17478 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 17479 struct nan_datapath_end_req *req) 17480 { 17481 uint16_t len; 17482 wmi_buf_t buf; 17483 QDF_STATUS status; 17484 uint32_t ndp_end_req_len, i; 17485 wmi_ndp_end_req *ndp_end_req_lst; 17486 wmi_ndp_end_req_fixed_param *cmd; 17487 17488 /* len of tlv following fixed param */ 17489 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 17490 /* above comes out to 4 byte alligned already, no need of padding */ 17491 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 17492 buf = wmi_buf_alloc(wmi_handle, len); 17493 if (!buf) { 17494 WMI_LOGE("Malloc failed"); 17495 return QDF_STATUS_E_NOMEM; 17496 } 17497 17498 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 17499 WMITLV_SET_HDR(&cmd->tlv_header, 17500 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 17501 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 17502 17503 cmd->transaction_id = req->transaction_id; 17504 17505 /* set tlv pointer to end of fixed param */ 17506 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 17507 ndp_end_req_len); 17508 17509 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 17510 WMI_TLV_HDR_SIZE); 17511 for (i = 0; i < req->num_ndp_instances; i++) { 17512 WMITLV_SET_HDR(&ndp_end_req_lst[i], 17513 WMITLV_TAG_ARRAY_FIXED_STRUC, 17514 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 17515 17516 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 17517 } 17518 17519 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 17520 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17521 WMI_NDP_END_REQ_CMDID); 17522 if (QDF_IS_STATUS_ERROR(status)) { 17523 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 17524 wmi_buf_free(buf); 17525 } 17526 17527 return status; 17528 } 17529 17530 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 17531 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 17532 { 17533 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 17534 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 17535 17536 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 17537 fixed_params = event->fixed_param; 17538 17539 rsp->vdev = 17540 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17541 fixed_params->vdev_id, 17542 WLAN_NAN_ID); 17543 if (!rsp->vdev) { 17544 WMI_LOGE("vdev is null"); 17545 return QDF_STATUS_E_INVAL; 17546 } 17547 17548 rsp->transaction_id = fixed_params->transaction_id; 17549 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17550 rsp->status = fixed_params->rsp_status; 17551 rsp->reason = fixed_params->reason_code; 17552 17553 return QDF_STATUS_SUCCESS; 17554 } 17555 17556 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 17557 uint8_t *data, struct nan_datapath_indication_event *rsp) 17558 { 17559 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 17560 wmi_ndp_indication_event_fixed_param *fixed_params; 17561 17562 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 17563 fixed_params = 17564 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 17565 17566 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17567 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17568 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17569 return QDF_STATUS_E_INVAL; 17570 } 17571 17572 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17573 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17574 fixed_params->ndp_app_info_len, 17575 event->num_ndp_app_info); 17576 return QDF_STATUS_E_INVAL; 17577 } 17578 17579 rsp->vdev = 17580 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17581 fixed_params->vdev_id, 17582 WLAN_NAN_ID); 17583 if (!rsp->vdev) { 17584 WMI_LOGE("vdev is null"); 17585 return QDF_STATUS_E_INVAL; 17586 } 17587 rsp->service_instance_id = fixed_params->service_instance_id; 17588 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17589 rsp->role = fixed_params->self_ndp_role; 17590 rsp->policy = fixed_params->accept_policy; 17591 17592 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17593 rsp->peer_mac_addr.bytes); 17594 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 17595 rsp->peer_discovery_mac_addr.bytes); 17596 17597 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 17598 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 17599 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 17600 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 17601 fixed_params->service_instance_id, 17602 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 17603 fixed_params->accept_policy, 17604 fixed_params->nan_csid, fixed_params->nan_scid_len, 17605 rsp->peer_mac_addr.bytes, 17606 rsp->peer_discovery_mac_addr.bytes); 17607 17608 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17609 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17610 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17611 17612 WMI_LOGD("ndp_app_info - %d bytes", 17613 fixed_params->ndp_app_info_len); 17614 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17615 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17616 17617 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 17618 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17619 rsp->ncs_sk_type = fixed_params->nan_csid; 17620 rsp->scid.scid_len = fixed_params->nan_scid_len; 17621 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 17622 rsp->ndp_config.ndp_cfg_len); 17623 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17624 rsp->ndp_info.ndp_app_info_len); 17625 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 17626 WMI_LOGD("scid hex dump:"); 17627 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17628 rsp->scid.scid, rsp->scid.scid_len); 17629 17630 return QDF_STATUS_SUCCESS; 17631 } 17632 17633 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 17634 uint8_t *data, struct nan_datapath_confirm_event *rsp) 17635 { 17636 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 17637 wmi_ndp_confirm_event_fixed_param *fixed_params; 17638 17639 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 17640 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 17641 WMI_LOGD("WMI_NDP_CONFIRM_EVENTID(0x%X) received. vdev %d, ndp_instance %d, rsp_code %d, reason_code: %d, num_active_ndps_on_peer: %d", 17642 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 17643 fixed_params->ndp_instance_id, fixed_params->rsp_code, 17644 fixed_params->reason_code, 17645 fixed_params->num_active_ndps_on_peer); 17646 17647 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17648 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17649 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17650 return QDF_STATUS_E_INVAL; 17651 } 17652 17653 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17654 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17655 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17656 17657 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17658 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17659 fixed_params->ndp_app_info_len, 17660 event->num_ndp_app_info); 17661 return QDF_STATUS_E_INVAL; 17662 } 17663 17664 WMI_LOGD("ndp_app_info - %d bytes", 17665 fixed_params->ndp_app_info_len); 17666 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, 17667 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17668 17669 rsp->vdev = 17670 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17671 fixed_params->vdev_id, 17672 WLAN_NAN_ID); 17673 if (!rsp->vdev) { 17674 WMI_LOGE("vdev is null"); 17675 return QDF_STATUS_E_INVAL; 17676 } 17677 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17678 rsp->rsp_code = fixed_params->rsp_code; 17679 rsp->reason_code = fixed_params->reason_code; 17680 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 17681 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17682 rsp->peer_ndi_mac_addr.bytes); 17683 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17684 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17685 rsp->ndp_info.ndp_app_info_len); 17686 17687 return QDF_STATUS_SUCCESS; 17688 } 17689 17690 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 17691 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 17692 { 17693 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17694 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17695 17696 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17697 fixed_params = event->fixed_param; 17698 17699 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", 17700 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17701 rsp->peer_mac_addr.bytes, rsp->transaction_id, 17702 rsp->status, rsp->reason, rsp->create_peer); 17703 17704 rsp->vdev = 17705 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17706 fixed_params->vdev_id, 17707 WLAN_NAN_ID); 17708 if (!rsp->vdev) { 17709 WMI_LOGE("vdev is null"); 17710 return QDF_STATUS_E_INVAL; 17711 } 17712 rsp->transaction_id = fixed_params->transaction_id; 17713 rsp->reason = fixed_params->reason_code; 17714 rsp->status = fixed_params->rsp_status; 17715 rsp->create_peer = fixed_params->create_peer; 17716 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17717 rsp->peer_mac_addr.bytes); 17718 17719 return QDF_STATUS_SUCCESS; 17720 } 17721 17722 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17723 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 17724 { 17725 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17726 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17727 17728 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17729 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17730 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 17731 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17732 fixed_params->rsp_status, fixed_params->reason_code); 17733 17734 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17735 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17736 if (!rsp->vdev) { 17737 WMI_LOGE("vdev is null"); 17738 return QDF_STATUS_E_INVAL; 17739 } 17740 rsp->transaction_id = fixed_params->transaction_id; 17741 rsp->reason = fixed_params->reason_code; 17742 rsp->status = fixed_params->rsp_status; 17743 17744 return QDF_STATUS_SUCCESS; 17745 } 17746 17747 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17748 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17749 { 17750 uint32_t i, buf_size; 17751 wmi_ndp_end_indication *ind; 17752 struct qdf_mac_addr peer_addr; 17753 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17754 17755 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17756 ind = event->ndp_end_indication_list; 17757 17758 if (event->num_ndp_end_indication_list == 0) { 17759 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17760 return QDF_STATUS_E_INVAL; 17761 } 17762 17763 WMI_LOGD("number of ndp instances = %d", 17764 event->num_ndp_end_indication_list); 17765 17766 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17767 sizeof((*rsp)->ndp_map[0]))) { 17768 WMI_LOGE("num_ndp_end_ind_list %d too large", 17769 event->num_ndp_end_indication_list); 17770 return QDF_STATUS_E_INVAL; 17771 } 17772 17773 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17774 sizeof((*rsp)->ndp_map[0]); 17775 *rsp = qdf_mem_malloc(buf_size); 17776 if (!(*rsp)) { 17777 WMI_LOGE("Failed to allocate memory"); 17778 return QDF_STATUS_E_NOMEM; 17779 } 17780 17781 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17782 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17783 if (!(*rsp)->vdev) { 17784 WMI_LOGE("vdev is null"); 17785 qdf_mem_free(*rsp); 17786 *rsp = NULL; 17787 return QDF_STATUS_E_INVAL; 17788 } 17789 17790 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17791 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17792 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17793 peer_addr.bytes); 17794 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17795 i, ind[i].type, ind[i].reason_code, 17796 ind[i].ndp_instance_id, 17797 ind[i].num_active_ndps_on_peer); 17798 /* Add each instance entry to the list */ 17799 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17800 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17801 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17802 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17803 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17804 ind[i].num_active_ndps_on_peer; 17805 (*rsp)->ndp_map[i].type = ind[i].type; 17806 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17807 } 17808 17809 return QDF_STATUS_SUCCESS; 17810 } 17811 #endif 17812 17813 #ifdef QCA_SUPPORT_CP_STATS 17814 /** 17815 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17816 * @wmi_handle: wma handle 17817 * @evt_buf: event buffer 17818 * @out_buff: buffer to populated after stats extraction 17819 * 17820 * Return: status of operation 17821 */ 17822 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17823 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17824 { 17825 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17826 wmi_congestion_stats *congestion_stats; 17827 17828 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17829 congestion_stats = param_buf->congestion_stats; 17830 if (!congestion_stats) { 17831 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17832 return QDF_STATUS_E_INVAL; 17833 } 17834 17835 out_buff->vdev_id = congestion_stats->vdev_id; 17836 out_buff->congestion = congestion_stats->congestion; 17837 17838 WMI_LOGD("%s: cca stats event processed", __func__); 17839 return QDF_STATUS_SUCCESS; 17840 } 17841 #endif /* QCA_SUPPORT_CP_STATS */ 17842 17843 /** 17844 * save_service_bitmap_tlv() - save service bitmap 17845 * @wmi_handle: wmi handle 17846 * @param evt_buf: pointer to event buffer 17847 * @param bitmap_buf: bitmap buffer, for converged legacy support 17848 * 17849 * Return: QDF_STATUS 17850 */ 17851 static 17852 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17853 void *bitmap_buf) 17854 { 17855 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17856 struct wmi_soc *soc = wmi_handle->soc; 17857 17858 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17859 17860 /* If it is already allocated, use that buffer. This can happen 17861 * during target stop/start scenarios where host allocation is skipped. 17862 */ 17863 if (!soc->wmi_service_bitmap) { 17864 soc->wmi_service_bitmap = 17865 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17866 if (!soc->wmi_service_bitmap) { 17867 WMI_LOGE("Failed memory allocation for service bitmap"); 17868 return QDF_STATUS_E_NOMEM; 17869 } 17870 } 17871 17872 qdf_mem_copy(soc->wmi_service_bitmap, 17873 param_buf->wmi_service_bitmap, 17874 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17875 17876 if (bitmap_buf) 17877 qdf_mem_copy(bitmap_buf, 17878 param_buf->wmi_service_bitmap, 17879 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17880 17881 return QDF_STATUS_SUCCESS; 17882 } 17883 17884 /** 17885 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17886 * @wmi_handle: wmi handle 17887 * @param evt_buf: pointer to event buffer 17888 * @param bitmap_buf: bitmap buffer, for converged legacy support 17889 * 17890 * Return: QDF_STATUS 17891 */ 17892 static 17893 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17894 void *bitmap_buf) 17895 { 17896 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17897 wmi_service_available_event_fixed_param *ev; 17898 struct wmi_soc *soc = wmi_handle->soc; 17899 17900 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17901 17902 ev = param_buf->fixed_param; 17903 17904 /* If it is already allocated, use that buffer. This can happen 17905 * during target stop/start scenarios where host allocation is skipped. 17906 */ 17907 if (!soc->wmi_ext_service_bitmap) { 17908 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17909 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17910 if (!soc->wmi_ext_service_bitmap) { 17911 WMI_LOGE("Failed memory allocation for service bitmap"); 17912 return QDF_STATUS_E_NOMEM; 17913 } 17914 } 17915 17916 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17917 ev->wmi_service_segment_bitmap, 17918 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17919 17920 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17921 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17922 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17923 17924 if (bitmap_buf) 17925 qdf_mem_copy(bitmap_buf, 17926 soc->wmi_ext_service_bitmap, 17927 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17928 17929 return QDF_STATUS_SUCCESS; 17930 } 17931 /** 17932 * is_service_enabled_tlv() - Check if service enabled 17933 * @param wmi_handle: wmi handle 17934 * @param service_id: service identifier 17935 * 17936 * Return: 1 enabled, 0 disabled 17937 */ 17938 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17939 uint32_t service_id) 17940 { 17941 struct wmi_soc *soc = wmi_handle->soc; 17942 17943 if (!soc->wmi_service_bitmap) { 17944 WMI_LOGE("WMI service bit map is not saved yet\n"); 17945 return false; 17946 } 17947 17948 /* if wmi_service_enabled was received with extended bitmap, 17949 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17950 */ 17951 if (soc->wmi_ext_service_bitmap) 17952 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17953 soc->wmi_ext_service_bitmap, 17954 service_id); 17955 17956 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17957 service_id); 17958 } 17959 17960 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17961 struct wlan_psoc_target_capability_info *cap) 17962 { 17963 /* except LDPC all flags are common betwen legacy and here 17964 * also IBFEER is not defined for TLV 17965 */ 17966 cap->ht_cap_info |= ev_target_cap & ( 17967 WMI_HT_CAP_ENABLED 17968 | WMI_HT_CAP_HT20_SGI 17969 | WMI_HT_CAP_DYNAMIC_SMPS 17970 | WMI_HT_CAP_TX_STBC 17971 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17972 | WMI_HT_CAP_RX_STBC 17973 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17974 | WMI_HT_CAP_LDPC 17975 | WMI_HT_CAP_L_SIG_TXOP_PROT 17976 | WMI_HT_CAP_MPDU_DENSITY 17977 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17978 | WMI_HT_CAP_HT40_SGI); 17979 if (ev_target_cap & WMI_HT_CAP_LDPC) 17980 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17981 WMI_HOST_HT_CAP_TX_LDPC; 17982 } 17983 /** 17984 * extract_service_ready_tlv() - extract service ready event 17985 * @wmi_handle: wmi handle 17986 * @param evt_buf: pointer to received event buffer 17987 * @param cap: pointer to hold target capability information extracted from even 17988 * 17989 * Return: QDF_STATUS_SUCCESS for success or error code 17990 */ 17991 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17992 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17993 { 17994 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17995 wmi_service_ready_event_fixed_param *ev; 17996 17997 17998 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17999 18000 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18001 if (!ev) { 18002 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18003 return QDF_STATUS_E_FAILURE; 18004 } 18005 18006 cap->phy_capability = ev->phy_capability; 18007 cap->max_frag_entry = ev->max_frag_entry; 18008 cap->num_rf_chains = ev->num_rf_chains; 18009 copy_ht_cap_info(ev->ht_cap_info, cap); 18010 cap->vht_cap_info = ev->vht_cap_info; 18011 cap->vht_supp_mcs = ev->vht_supp_mcs; 18012 cap->hw_min_tx_power = ev->hw_min_tx_power; 18013 cap->hw_max_tx_power = ev->hw_max_tx_power; 18014 cap->sys_cap_info = ev->sys_cap_info; 18015 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 18016 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 18017 cap->max_num_scan_channels = ev->max_num_scan_channels; 18018 cap->max_supported_macs = ev->max_supported_macs; 18019 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 18020 cap->txrx_chainmask = ev->txrx_chainmask; 18021 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 18022 cap->num_msdu_desc = ev->num_msdu_desc; 18023 cap->fw_version = ev->fw_build_vers; 18024 /* fw_version_1 is not available in TLV. */ 18025 cap->fw_version_1 = 0; 18026 18027 return QDF_STATUS_SUCCESS; 18028 } 18029 18030 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 18031 * to host internal WMI_HOST_REGDMN_MODE values. 18032 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 18033 * host currently. Add this in the future if required. 18034 * 11AX (Phase II) : 11ax related values are not currently 18035 * advertised separately by FW. As part of phase II regulatory bring-up, 18036 * finalize the advertisement mechanism. 18037 * @target_wireless_mode: target wireless mode received in message 18038 * 18039 * Return: returns the host internal wireless mode. 18040 */ 18041 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 18042 { 18043 18044 uint32_t wireless_modes = 0; 18045 18046 if (target_wireless_mode & REGDMN_MODE_11A) 18047 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 18048 18049 if (target_wireless_mode & REGDMN_MODE_TURBO) 18050 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 18051 18052 if (target_wireless_mode & REGDMN_MODE_11B) 18053 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 18054 18055 if (target_wireless_mode & REGDMN_MODE_PUREG) 18056 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 18057 18058 if (target_wireless_mode & REGDMN_MODE_11G) 18059 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 18060 18061 if (target_wireless_mode & REGDMN_MODE_108G) 18062 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 18063 18064 if (target_wireless_mode & REGDMN_MODE_108A) 18065 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 18066 18067 if (target_wireless_mode & REGDMN_MODE_XR) 18068 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 18069 18070 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 18071 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 18072 18073 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 18074 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 18075 18076 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 18077 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 18078 18079 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 18080 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 18081 18082 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 18083 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 18084 18085 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 18086 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 18087 18088 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 18089 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 18090 18091 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 18092 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 18093 18094 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 18095 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 18096 18097 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 18098 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 18099 18100 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 18101 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 18102 18103 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 18104 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 18105 18106 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 18107 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 18108 18109 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 18110 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 18111 18112 return wireless_modes; 18113 } 18114 18115 /** 18116 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 18117 * @wmi_handle: wmi handle 18118 * @param evt_buf: Pointer to event buffer 18119 * @param cap: pointer to hold HAL reg capabilities 18120 * 18121 * Return: QDF_STATUS_SUCCESS for success or error code 18122 */ 18123 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 18124 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 18125 { 18126 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18127 18128 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18129 18130 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 18131 sizeof(uint32_t)), 18132 sizeof(struct wlan_psoc_hal_reg_capability)); 18133 18134 cap->wireless_modes = convert_wireless_modes_tlv( 18135 param_buf->hal_reg_capabilities->wireless_modes); 18136 18137 return QDF_STATUS_SUCCESS; 18138 } 18139 18140 /** 18141 * extract_host_mem_req_tlv() - Extract host memory request event 18142 * @wmi_handle: wmi handle 18143 * @param evt_buf: pointer to event buffer 18144 * @param num_entries: pointer to hold number of entries requested 18145 * 18146 * Return: Number of entries requested 18147 */ 18148 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 18149 void *evt_buf, uint8_t *num_entries) 18150 { 18151 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18152 wmi_service_ready_event_fixed_param *ev; 18153 18154 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18155 18156 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18157 if (!ev) { 18158 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18159 return NULL; 18160 } 18161 18162 *num_entries = ev->num_mem_reqs; 18163 18164 return (host_mem_req *)param_buf->mem_reqs; 18165 } 18166 18167 /** 18168 * save_fw_version_in_service_ready_tlv() - Save fw version in service 18169 * ready function 18170 * @wmi_handle: wmi handle 18171 * @param evt_buf: pointer to event buffer 18172 * 18173 * Return: QDF_STATUS_SUCCESS for success or error code 18174 */ 18175 static QDF_STATUS 18176 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 18177 { 18178 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 18179 wmi_service_ready_event_fixed_param *ev; 18180 18181 18182 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 18183 18184 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 18185 if (!ev) { 18186 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 18187 return QDF_STATUS_E_FAILURE; 18188 } 18189 18190 /*Save fw version from service ready message */ 18191 /*This will be used while sending INIT message */ 18192 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 18193 sizeof(wmi_handle->fw_abi_version)); 18194 18195 return QDF_STATUS_SUCCESS; 18196 } 18197 18198 /** 18199 * ready_extract_init_status_tlv() - Extract init status from ready event 18200 * @wmi_handle: wmi handle 18201 * @param evt_buf: Pointer to event buffer 18202 * 18203 * Return: ready status 18204 */ 18205 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 18206 void *evt_buf) 18207 { 18208 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18209 wmi_ready_event_fixed_param *ev = NULL; 18210 18211 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18212 ev = param_buf->fixed_param; 18213 18214 qdf_print("%s:%d\n", __func__, ev->status); 18215 18216 return ev->status; 18217 } 18218 18219 /** 18220 * ready_extract_mac_addr_tlv() - extract mac address from ready event 18221 * @wmi_handle: wmi handle 18222 * @param evt_buf: pointer to event buffer 18223 * @param macaddr: Pointer to hold MAC address 18224 * 18225 * Return: QDF_STATUS_SUCCESS for success or error code 18226 */ 18227 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 18228 void *evt_buf, uint8_t *macaddr) 18229 { 18230 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18231 wmi_ready_event_fixed_param *ev = NULL; 18232 18233 18234 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18235 ev = param_buf->fixed_param; 18236 18237 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 18238 18239 return QDF_STATUS_SUCCESS; 18240 } 18241 18242 /** 18243 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 18244 * @wmi_handle: wmi handle 18245 * @param evt_buf: pointer to event buffer 18246 * @param macaddr: Pointer to hold number of MAC addresses 18247 * 18248 * Return: Pointer to addr list 18249 */ 18250 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 18251 void *evt_buf, uint8_t *num_mac) 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 *num_mac = ev->num_extra_mac_addr; 18260 18261 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 18262 } 18263 18264 /** 18265 * extract_ready_params_tlv() - Extract data from ready event apart from 18266 * status, macaddr and version. 18267 * @wmi_handle: Pointer to WMI handle. 18268 * @evt_buf: Pointer to Ready event buffer. 18269 * @ev_param: Pointer to host defined struct to copy the data from event. 18270 * 18271 * Return: QDF_STATUS_SUCCESS on success. 18272 */ 18273 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 18274 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 18275 { 18276 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18277 wmi_ready_event_fixed_param *ev = NULL; 18278 18279 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18280 ev = param_buf->fixed_param; 18281 18282 ev_param->status = ev->status; 18283 ev_param->num_dscp_table = ev->num_dscp_table; 18284 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 18285 ev_param->num_total_peer = ev->num_total_peers; 18286 ev_param->num_extra_peer = ev->num_extra_peers; 18287 /* Agile_cap in ready event is not supported in TLV target */ 18288 ev_param->agile_capability = false; 18289 18290 return QDF_STATUS_SUCCESS; 18291 } 18292 18293 /** 18294 * extract_dbglog_data_len_tlv() - extract debuglog data length 18295 * @wmi_handle: wmi handle 18296 * @param evt_buf: pointer to event buffer 18297 * 18298 * Return: length 18299 */ 18300 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 18301 void *evt_buf, uint32_t *len) 18302 { 18303 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 18304 18305 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 18306 18307 *len = param_buf->num_bufp; 18308 18309 return param_buf->bufp; 18310 } 18311 18312 /** 18313 * extract_vdev_start_resp_tlv() - extract vdev start response 18314 * @wmi_handle: wmi handle 18315 * @param evt_buf: pointer to event buffer 18316 * @param vdev_rsp: Pointer to hold vdev response 18317 * 18318 * Return: QDF_STATUS_SUCCESS for success or error code 18319 */ 18320 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 18321 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 18322 { 18323 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 18324 wmi_vdev_start_response_event_fixed_param *ev; 18325 18326 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 18327 if (!param_buf) { 18328 qdf_print("Invalid start response event buffer\n"); 18329 return QDF_STATUS_E_INVAL; 18330 } 18331 18332 ev = param_buf->fixed_param; 18333 if (!ev) { 18334 qdf_print("Invalid start response event buffer\n"); 18335 return QDF_STATUS_E_INVAL; 18336 } 18337 18338 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 18339 18340 vdev_rsp->vdev_id = ev->vdev_id; 18341 vdev_rsp->requestor_id = ev->requestor_id; 18342 switch (ev->resp_type) { 18343 case WMI_VDEV_START_RESP_EVENT: 18344 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 18345 break; 18346 case WMI_VDEV_RESTART_RESP_EVENT: 18347 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 18348 break; 18349 default: 18350 qdf_print("Invalid start response event buffer\n"); 18351 break; 18352 }; 18353 vdev_rsp->status = ev->status; 18354 vdev_rsp->chain_mask = ev->chain_mask; 18355 vdev_rsp->smps_mode = ev->smps_mode; 18356 vdev_rsp->mac_id = ev->mac_id; 18357 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 18358 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 18359 18360 return QDF_STATUS_SUCCESS; 18361 } 18362 18363 /** 18364 * extract_vdev_delete_resp_tlv() - extract vdev delete response 18365 * @wmi_handle: wmi handle 18366 * @param evt_buf: pointer to event buffer 18367 * @param delete_rsp: Pointer to hold vdev delete response 18368 * 18369 * Return: QDF_STATUS_SUCCESS for success or error code 18370 */ 18371 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 18372 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 18373 { 18374 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 18375 wmi_vdev_delete_resp_event_fixed_param *ev; 18376 18377 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 18378 if (!param_buf) { 18379 WMI_LOGE("Invalid vdev delete response event buffer\n"); 18380 return QDF_STATUS_E_INVAL; 18381 } 18382 18383 ev = param_buf->fixed_param; 18384 if (!ev) { 18385 WMI_LOGE("Invalid vdev delete response event\n"); 18386 return QDF_STATUS_E_INVAL; 18387 } 18388 18389 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 18390 delete_rsp->vdev_id = ev->vdev_id; 18391 18392 return QDF_STATUS_SUCCESS; 18393 } 18394 18395 18396 /** 18397 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 18398 * @wmi_handle: wmi handle 18399 * @param evt_buf: pointer to event buffer 18400 * @param num_vdevs: Pointer to hold num vdev 18401 * 18402 * Return: QDF_STATUS_SUCCESS for success or error code 18403 */ 18404 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18405 void *evt_buf, uint32_t *num_vdevs) 18406 { 18407 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18408 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18409 uint32_t vdev_map; 18410 18411 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 18412 if (!param_buf) { 18413 qdf_print("Invalid tbtt update ext event buffer\n"); 18414 return QDF_STATUS_E_INVAL; 18415 } 18416 tbtt_offset_event = param_buf->fixed_param; 18417 vdev_map = tbtt_offset_event->vdev_map; 18418 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18419 18420 return QDF_STATUS_SUCCESS; 18421 } 18422 18423 /** 18424 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 18425 * @wmi_handle: wmi handle 18426 * @param evt_buf: pointer to event buffer 18427 * @param num_vdevs: Pointer to hold num vdev 18428 * 18429 * Return: QDF_STATUS_SUCCESS for success or error code 18430 */ 18431 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18432 void *evt_buf, uint32_t *num_vdevs) 18433 { 18434 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18435 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 18436 18437 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18438 if (!param_buf) { 18439 qdf_print("Invalid tbtt update ext event buffer\n"); 18440 return QDF_STATUS_E_INVAL; 18441 } 18442 tbtt_offset_ext_event = param_buf->fixed_param; 18443 18444 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 18445 18446 return QDF_STATUS_SUCCESS; 18447 } 18448 18449 /** 18450 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 18451 * @wmi_handle: wmi handle 18452 * @param evt_buf: pointer to event buffer 18453 * @param idx: Index refering to a vdev 18454 * @param tbtt_param: Pointer to tbttoffset event param 18455 * 18456 * Return: QDF_STATUS_SUCCESS for success or error code 18457 */ 18458 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 18459 void *evt_buf, uint8_t idx, 18460 struct tbttoffset_params *tbtt_param) 18461 { 18462 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18463 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18464 uint32_t vdev_map; 18465 18466 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 18467 if (!param_buf) { 18468 qdf_print("Invalid tbtt update event buffer\n"); 18469 return QDF_STATUS_E_INVAL; 18470 } 18471 18472 tbtt_offset_event = param_buf->fixed_param; 18473 vdev_map = tbtt_offset_event->vdev_map; 18474 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 18475 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 18476 return QDF_STATUS_E_INVAL; 18477 tbtt_param->tbttoffset = 18478 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 18479 18480 return QDF_STATUS_SUCCESS; 18481 } 18482 18483 /** 18484 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 18485 * @wmi_handle: wmi handle 18486 * @param evt_buf: pointer to event buffer 18487 * @param idx: Index refering to a vdev 18488 * @param tbtt_param: Pointer to tbttoffset event param 18489 * 18490 * Return: QDF_STATUS_SUCCESS for success or error code 18491 */ 18492 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 18493 void *evt_buf, uint8_t idx, 18494 struct tbttoffset_params *tbtt_param) 18495 { 18496 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18497 wmi_tbtt_offset_info *tbtt_offset_info; 18498 18499 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18500 if (!param_buf) { 18501 qdf_print("Invalid tbtt update event buffer\n"); 18502 return QDF_STATUS_E_INVAL; 18503 } 18504 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 18505 18506 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 18507 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 18508 18509 return QDF_STATUS_SUCCESS; 18510 } 18511 18512 /** 18513 * extract_mgmt_rx_params_tlv() - extract management rx params from event 18514 * @wmi_handle: wmi handle 18515 * @param evt_buf: pointer to event buffer 18516 * @param hdr: Pointer to hold header 18517 * @param bufp: Pointer to hold pointer to rx param buffer 18518 * 18519 * Return: QDF_STATUS_SUCCESS for success or error code 18520 */ 18521 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 18522 void *evt_buf, struct mgmt_rx_event_params *hdr, 18523 uint8_t **bufp) 18524 { 18525 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 18526 wmi_mgmt_rx_hdr *ev_hdr = NULL; 18527 int i; 18528 18529 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 18530 if (!param_tlvs) { 18531 WMI_LOGE("Get NULL point message from FW"); 18532 return QDF_STATUS_E_INVAL; 18533 } 18534 18535 ev_hdr = param_tlvs->hdr; 18536 if (!hdr) { 18537 WMI_LOGE("Rx event is NULL"); 18538 return QDF_STATUS_E_INVAL; 18539 } 18540 18541 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18542 ev_hdr->pdev_id); 18543 18544 hdr->channel = ev_hdr->channel; 18545 hdr->snr = ev_hdr->snr; 18546 hdr->rate = ev_hdr->rate; 18547 hdr->phy_mode = ev_hdr->phy_mode; 18548 hdr->buf_len = ev_hdr->buf_len; 18549 hdr->status = ev_hdr->status; 18550 hdr->flags = ev_hdr->flags; 18551 hdr->rssi = ev_hdr->rssi; 18552 hdr->tsf_delta = ev_hdr->tsf_delta; 18553 for (i = 0; i < ATH_MAX_ANTENNA; i++) 18554 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 18555 18556 *bufp = param_tlvs->bufp; 18557 18558 return QDF_STATUS_SUCCESS; 18559 } 18560 18561 /** 18562 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 18563 * @wmi_handle: wmi handle 18564 * @param evt_buf: pointer to event buffer 18565 * @param vdev_id: Pointer to hold vdev identifier 18566 * 18567 * Return: QDF_STATUS_SUCCESS for success or error code 18568 */ 18569 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 18570 void *evt_buf, uint32_t *vdev_id) 18571 { 18572 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 18573 wmi_vdev_stopped_event_fixed_param *resp_event; 18574 18575 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 18576 if (!param_buf) { 18577 WMI_LOGE("Invalid event buffer"); 18578 return QDF_STATUS_E_INVAL; 18579 } 18580 resp_event = param_buf->fixed_param; 18581 *vdev_id = resp_event->vdev_id; 18582 18583 return QDF_STATUS_SUCCESS; 18584 } 18585 18586 /** 18587 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 18588 * @wmi_handle: wmi handle 18589 * @param evt_buf: pointer to event buffer 18590 * @param param: Pointer to hold roam param 18591 * 18592 * Return: QDF_STATUS_SUCCESS for success or error code 18593 */ 18594 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 18595 void *evt_buf, wmi_host_roam_event *param) 18596 { 18597 WMI_ROAM_EVENTID_param_tlvs *param_buf; 18598 wmi_roam_event_fixed_param *evt; 18599 18600 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 18601 if (!param_buf) { 18602 WMI_LOGE("Invalid roam event buffer"); 18603 return QDF_STATUS_E_INVAL; 18604 } 18605 18606 evt = param_buf->fixed_param; 18607 qdf_mem_zero(param, sizeof(*param)); 18608 18609 param->vdev_id = evt->vdev_id; 18610 param->reason = evt->reason; 18611 param->rssi = evt->rssi; 18612 18613 return QDF_STATUS_SUCCESS; 18614 } 18615 18616 /** 18617 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 18618 * @wmi_handle: wmi handle 18619 * @param evt_buf: pointer to event buffer 18620 * @param param: Pointer to hold vdev scan param 18621 * 18622 * Return: QDF_STATUS_SUCCESS for success or error code 18623 */ 18624 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18625 void *evt_buf, struct scan_event *param) 18626 { 18627 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18628 wmi_scan_event_fixed_param *evt = NULL; 18629 18630 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18631 evt = param_buf->fixed_param; 18632 18633 qdf_mem_zero(param, sizeof(*param)); 18634 18635 switch (evt->event) { 18636 case WMI_SCAN_EVENT_STARTED: 18637 param->type = SCAN_EVENT_TYPE_STARTED; 18638 break; 18639 case WMI_SCAN_EVENT_COMPLETED: 18640 param->type = SCAN_EVENT_TYPE_COMPLETED; 18641 break; 18642 case WMI_SCAN_EVENT_BSS_CHANNEL: 18643 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18644 break; 18645 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18646 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18647 break; 18648 case WMI_SCAN_EVENT_DEQUEUED: 18649 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18650 break; 18651 case WMI_SCAN_EVENT_PREEMPTED: 18652 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18653 break; 18654 case WMI_SCAN_EVENT_START_FAILED: 18655 param->type = SCAN_EVENT_TYPE_START_FAILED; 18656 break; 18657 case WMI_SCAN_EVENT_RESTARTED: 18658 param->type = SCAN_EVENT_TYPE_RESTARTED; 18659 break; 18660 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18661 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18662 break; 18663 case WMI_SCAN_EVENT_MAX: 18664 default: 18665 param->type = SCAN_EVENT_TYPE_MAX; 18666 break; 18667 }; 18668 18669 switch (evt->reason) { 18670 case WMI_SCAN_REASON_NONE: 18671 param->reason = SCAN_REASON_NONE; 18672 break; 18673 case WMI_SCAN_REASON_COMPLETED: 18674 param->reason = SCAN_REASON_COMPLETED; 18675 break; 18676 case WMI_SCAN_REASON_CANCELLED: 18677 param->reason = SCAN_REASON_CANCELLED; 18678 break; 18679 case WMI_SCAN_REASON_PREEMPTED: 18680 param->reason = SCAN_REASON_PREEMPTED; 18681 break; 18682 case WMI_SCAN_REASON_TIMEDOUT: 18683 param->reason = SCAN_REASON_TIMEDOUT; 18684 break; 18685 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18686 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18687 break; 18688 case WMI_SCAN_REASON_SUSPENDED: 18689 param->reason = SCAN_REASON_SUSPENDED; 18690 break; 18691 case WMI_SCAN_REASON_MAX: 18692 param->reason = SCAN_REASON_MAX; 18693 break; 18694 default: 18695 param->reason = SCAN_REASON_MAX; 18696 break; 18697 }; 18698 18699 param->chan_freq = evt->channel_freq; 18700 param->requester = evt->requestor; 18701 param->scan_id = evt->scan_id; 18702 param->vdev_id = evt->vdev_id; 18703 param->timestamp = evt->tsf_timestamp; 18704 18705 return QDF_STATUS_SUCCESS; 18706 } 18707 18708 #ifdef CONVERGED_TDLS_ENABLE 18709 /** 18710 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18711 * @wmi_handle: wmi handle 18712 * @param evt_buf: pointer to event buffer 18713 * @param param: Pointer to hold vdev tdls param 18714 * 18715 * Return: QDF_STATUS_SUCCESS for success or error code 18716 */ 18717 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18718 void *evt_buf, struct tdls_event_info *param) 18719 { 18720 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18721 wmi_tdls_peer_event_fixed_param *evt; 18722 18723 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18724 if (!param_buf) { 18725 WMI_LOGE("%s: NULL param_buf", __func__); 18726 return QDF_STATUS_E_NULL_VALUE; 18727 } 18728 18729 evt = param_buf->fixed_param; 18730 18731 qdf_mem_zero(param, sizeof(*param)); 18732 18733 param->vdev_id = evt->vdev_id; 18734 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18735 param->peermac.bytes); 18736 switch (evt->peer_status) { 18737 case WMI_TDLS_SHOULD_DISCOVER: 18738 param->message_type = TDLS_SHOULD_DISCOVER; 18739 break; 18740 case WMI_TDLS_SHOULD_TEARDOWN: 18741 param->message_type = TDLS_SHOULD_TEARDOWN; 18742 break; 18743 case WMI_TDLS_PEER_DISCONNECTED: 18744 param->message_type = TDLS_PEER_DISCONNECTED; 18745 break; 18746 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18747 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18748 break; 18749 default: 18750 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18751 __func__, evt->peer_status); 18752 return QDF_STATUS_E_INVAL; 18753 }; 18754 18755 switch (evt->peer_reason) { 18756 case WMI_TDLS_TEARDOWN_REASON_TX: 18757 param->peer_reason = TDLS_TEARDOWN_TX; 18758 break; 18759 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18760 param->peer_reason = TDLS_TEARDOWN_RSSI; 18761 break; 18762 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18763 param->peer_reason = TDLS_TEARDOWN_SCAN; 18764 break; 18765 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18766 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18767 break; 18768 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18769 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18770 break; 18771 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18772 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18773 break; 18774 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18775 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18776 break; 18777 case WMI_TDLS_ENTER_BUF_STA: 18778 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18779 break; 18780 case WMI_TDLS_EXIT_BUF_STA: 18781 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18782 break; 18783 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18784 param->peer_reason = TDLS_ENTER_BT_BUSY; 18785 break; 18786 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18787 param->peer_reason = TDLS_EXIT_BT_BUSY; 18788 break; 18789 case WMI_TDLS_SCAN_STARTED_EVENT: 18790 param->peer_reason = TDLS_SCAN_STARTED; 18791 break; 18792 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18793 param->peer_reason = TDLS_SCAN_COMPLETED; 18794 break; 18795 18796 default: 18797 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18798 __func__, evt->peer_reason, evt->peer_status); 18799 return QDF_STATUS_E_INVAL; 18800 }; 18801 18802 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18803 __func__, param->peermac.bytes, param->message_type, 18804 param->peer_reason, param->vdev_id); 18805 18806 return QDF_STATUS_SUCCESS; 18807 } 18808 #endif 18809 18810 /** 18811 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18812 * @wmi_handle: wmi handle 18813 * @param evt_buf: pointer to event buffer 18814 * @param param: Pointer to hold MGMT TX completion params 18815 * 18816 * Return: QDF_STATUS_SUCCESS for success or error code 18817 */ 18818 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18819 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18820 { 18821 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18822 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18823 18824 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18825 evt_buf; 18826 if (!param_buf) { 18827 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18828 return QDF_STATUS_E_INVAL; 18829 } 18830 cmpl_params = param_buf->fixed_param; 18831 18832 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18833 cmpl_params->pdev_id); 18834 param->desc_id = cmpl_params->desc_id; 18835 param->status = cmpl_params->status; 18836 param->ppdu_id = cmpl_params->ppdu_id; 18837 18838 return QDF_STATUS_SUCCESS; 18839 } 18840 18841 /** 18842 * extract_offchan_data_tx_compl_param_tlv() - 18843 * extract Offchan data tx completion event params 18844 * @wmi_handle: wmi handle 18845 * @param evt_buf: pointer to event buffer 18846 * @param param: Pointer to hold offchan data TX completion params 18847 * 18848 * Return: QDF_STATUS_SUCCESS for success or error code 18849 */ 18850 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18851 wmi_unified_t wmi_handle, void *evt_buf, 18852 struct wmi_host_offchan_data_tx_compl_event *param) 18853 { 18854 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18855 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18856 18857 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18858 evt_buf; 18859 if (!param_buf) { 18860 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18861 return QDF_STATUS_E_INVAL; 18862 } 18863 cmpl_params = param_buf->fixed_param; 18864 18865 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18866 cmpl_params->pdev_id); 18867 param->desc_id = cmpl_params->desc_id; 18868 param->status = cmpl_params->status; 18869 18870 return QDF_STATUS_SUCCESS; 18871 } 18872 18873 /** 18874 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18875 * status tlv 18876 * @wmi_handle: wmi handle 18877 * @param evt_buf: pointer to event buffer 18878 * @param param: Pointer to hold csa switch count status event param 18879 * 18880 * Return: QDF_STATUS_SUCCESS for success or error code 18881 */ 18882 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18883 wmi_unified_t wmi_handle, 18884 void *evt_buf, 18885 struct pdev_csa_switch_count_status *param) 18886 { 18887 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18888 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18889 18890 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18891 evt_buf; 18892 if (!param_buf) { 18893 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18894 return QDF_STATUS_E_INVAL; 18895 } 18896 18897 csa_status = param_buf->fixed_param; 18898 18899 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18900 csa_status->pdev_id); 18901 param->current_switch_count = csa_status->current_switch_count; 18902 param->num_vdevs = csa_status->num_vdevs; 18903 param->vdev_ids = param_buf->vdev_ids; 18904 18905 return QDF_STATUS_SUCCESS; 18906 } 18907 18908 /** 18909 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18910 * param from event 18911 * @wmi_handle: wmi handle 18912 * @param evt_buf: pointer to event buffer 18913 * @param param: Pointer to hold tpc configuration 18914 * 18915 * Return: 0 for success or error code 18916 */ 18917 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18918 void *evt_buf, 18919 wmi_host_pdev_tpc_config_event *param) 18920 { 18921 wmi_pdev_tpc_config_event_fixed_param *event = 18922 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18923 18924 if (!event) { 18925 WMI_LOGE("Invalid event buffer"); 18926 return QDF_STATUS_E_INVAL; 18927 } 18928 18929 param->pdev_id = event->pdev_id; 18930 param->regDomain = event->regDomain; 18931 param->chanFreq = event->chanFreq; 18932 param->phyMode = event->phyMode; 18933 param->twiceAntennaReduction = event->twiceAntennaReduction; 18934 param->twiceMaxRDPower = event->twiceMaxRDPower; 18935 param->powerLimit = event->powerLimit; 18936 param->rateMax = event->rateMax; 18937 param->numTxChain = event->numTxChain; 18938 param->ctl = event->ctl; 18939 param->flags = event->flags; 18940 18941 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18942 sizeof(param->maxRegAllowedPower)); 18943 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18944 event->maxRegAllowedPowerAGCDD, 18945 sizeof(param->maxRegAllowedPowerAGCDD)); 18946 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18947 event->maxRegAllowedPowerAGSTBC, 18948 sizeof(param->maxRegAllowedPowerAGSTBC)); 18949 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18950 event->maxRegAllowedPowerAGTXBF, 18951 sizeof(param->maxRegAllowedPowerAGTXBF)); 18952 WMI_LOGD("%s:extract success", __func__); 18953 18954 return QDF_STATUS_SUCCESS; 18955 } 18956 18957 /** 18958 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18959 * @wmi_handle: wmi handle 18960 * @param evt_buf: pointer to event buffer 18961 * @param num_vdevs: Pointer to hold num vdevs 18962 * 18963 * Return: QDF_STATUS_SUCCESS for success or error code 18964 */ 18965 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18966 void *evt_buf, uint32_t *num_vdevs) 18967 { 18968 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18969 wmi_host_swba_event_fixed_param *swba_event; 18970 uint32_t vdev_map; 18971 18972 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18973 if (!param_buf) { 18974 WMI_LOGE("Invalid swba event buffer"); 18975 return QDF_STATUS_E_INVAL; 18976 } 18977 18978 swba_event = param_buf->fixed_param; 18979 *num_vdevs = swba_event->num_vdevs; 18980 if (!(*num_vdevs)) { 18981 vdev_map = swba_event->vdev_map; 18982 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18983 } 18984 18985 return QDF_STATUS_SUCCESS; 18986 } 18987 18988 /** 18989 * extract_swba_tim_info_tlv() - extract swba tim info from event 18990 * @wmi_handle: wmi handle 18991 * @param evt_buf: pointer to event buffer 18992 * @param idx: Index to bcn info 18993 * @param tim_info: Pointer to hold tim info 18994 * 18995 * Return: QDF_STATUS_SUCCESS for success or error code 18996 */ 18997 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18998 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18999 { 19000 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 19001 wmi_tim_info *tim_info_ev; 19002 19003 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 19004 if (!param_buf) { 19005 WMI_LOGE("Invalid swba event buffer"); 19006 return QDF_STATUS_E_INVAL; 19007 } 19008 19009 tim_info_ev = ¶m_buf->tim_info[idx]; 19010 19011 tim_info->tim_len = tim_info_ev->tim_len; 19012 tim_info->tim_mcast = tim_info_ev->tim_mcast; 19013 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 19014 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 19015 tim_info->tim_changed = tim_info_ev->tim_changed; 19016 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 19017 tim_info->vdev_id = tim_info_ev->vdev_id; 19018 19019 return QDF_STATUS_SUCCESS; 19020 } 19021 19022 /** 19023 * extract_swba_noa_info_tlv() - extract swba NoA information from event 19024 * @wmi_handle: wmi handle 19025 * @param evt_buf: pointer to event buffer 19026 * @param idx: Index to bcn info 19027 * @param p2p_desc: Pointer to hold p2p NoA info 19028 * 19029 * Return: QDF_STATUS_SUCCESS for success or error code 19030 */ 19031 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 19032 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 19033 { 19034 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 19035 wmi_p2p_noa_info *p2p_noa_info; 19036 uint8_t i = 0; 19037 19038 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 19039 if (!param_buf) { 19040 WMI_LOGE("Invalid swba event buffer"); 19041 return QDF_STATUS_E_INVAL; 19042 } 19043 19044 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 19045 19046 p2p_desc->modified = false; 19047 p2p_desc->num_descriptors = 0; 19048 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 19049 p2p_desc->modified = true; 19050 p2p_desc->index = 19051 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 19052 p2p_desc->oppPS = 19053 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 19054 p2p_desc->ctwindow = 19055 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 19056 p2p_desc->num_descriptors = 19057 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 19058 (p2p_noa_info); 19059 for (i = 0; i < p2p_desc->num_descriptors; i++) { 19060 p2p_desc->noa_descriptors[i].type_count = 19061 (uint8_t) p2p_noa_info->noa_descriptors[i]. 19062 type_count; 19063 p2p_desc->noa_descriptors[i].duration = 19064 p2p_noa_info->noa_descriptors[i].duration; 19065 p2p_desc->noa_descriptors[i].interval = 19066 p2p_noa_info->noa_descriptors[i].interval; 19067 p2p_desc->noa_descriptors[i].start_time = 19068 p2p_noa_info->noa_descriptors[i].start_time; 19069 } 19070 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 19071 } 19072 19073 return QDF_STATUS_SUCCESS; 19074 } 19075 19076 #ifdef CONVERGED_P2P_ENABLE 19077 /** 19078 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 19079 * @wmi_handle: wmi handle 19080 * @param evt_buf: pointer to event buffer 19081 * @param param: Pointer to hold p2p noa info 19082 * 19083 * Return: QDF_STATUS_SUCCESS for success or error code 19084 */ 19085 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 19086 wmi_unified_t wmi_handle, void *evt_buf, 19087 struct p2p_noa_info *param) 19088 { 19089 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 19090 wmi_p2p_noa_event_fixed_param *fixed_param; 19091 uint8_t i; 19092 wmi_p2p_noa_info *wmi_noa_info; 19093 uint8_t *buf_ptr; 19094 uint32_t descriptors; 19095 19096 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 19097 if (!param_tlvs) { 19098 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 19099 return QDF_STATUS_E_INVAL; 19100 } 19101 19102 if (!param) { 19103 WMI_LOGE("noa information param is null"); 19104 return QDF_STATUS_E_INVAL; 19105 } 19106 19107 fixed_param = param_tlvs->fixed_param; 19108 buf_ptr = (uint8_t *) fixed_param; 19109 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 19110 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 19111 19112 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 19113 WMI_LOGE("%s: noa attr is not modified", __func__); 19114 return QDF_STATUS_E_INVAL; 19115 } 19116 19117 param->vdev_id = fixed_param->vdev_id; 19118 param->index = 19119 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 19120 param->opps_ps = 19121 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 19122 param->ct_window = 19123 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 19124 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 19125 param->num_desc = (uint8_t) descriptors; 19126 19127 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 19128 param->index, param->opps_ps, param->ct_window, 19129 param->num_desc); 19130 for (i = 0; i < param->num_desc; i++) { 19131 param->noa_desc[i].type_count = 19132 (uint8_t) wmi_noa_info->noa_descriptors[i]. 19133 type_count; 19134 param->noa_desc[i].duration = 19135 wmi_noa_info->noa_descriptors[i].duration; 19136 param->noa_desc[i].interval = 19137 wmi_noa_info->noa_descriptors[i].interval; 19138 param->noa_desc[i].start_time = 19139 wmi_noa_info->noa_descriptors[i].start_time; 19140 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 19141 __func__, i, param->noa_desc[i].type_count, 19142 param->noa_desc[i].duration, 19143 param->noa_desc[i].interval, 19144 param->noa_desc[i].start_time); 19145 } 19146 19147 return QDF_STATUS_SUCCESS; 19148 } 19149 19150 /** 19151 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 19152 * information from event 19153 * @wmi_handle: wmi handle 19154 * @param evt_buf: pointer to event buffer 19155 * @param param: Pointer to hold p2p lo stop event information 19156 * 19157 * Return: QDF_STATUS_SUCCESS for success or error code 19158 */ 19159 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 19160 wmi_unified_t wmi_handle, void *evt_buf, 19161 struct p2p_lo_event *param) 19162 { 19163 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 19164 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 19165 19166 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 19167 evt_buf; 19168 if (!param_tlvs) { 19169 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 19170 return QDF_STATUS_E_INVAL; 19171 } 19172 19173 if (!param) { 19174 WMI_LOGE("lo stop event param is null"); 19175 return QDF_STATUS_E_INVAL; 19176 } 19177 19178 lo_param = param_tlvs->fixed_param; 19179 param->vdev_id = lo_param->vdev_id; 19180 param->reason_code = lo_param->reason; 19181 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 19182 param->vdev_id, param->reason_code); 19183 19184 return QDF_STATUS_SUCCESS; 19185 } 19186 #endif /* End of CONVERGED_P2P_ENABLE */ 19187 19188 /** 19189 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 19190 * @wmi_handle: wmi handle 19191 * @param evt_buf: pointer to event buffer 19192 * @param ev: Pointer to hold peer param 19193 * 19194 * Return: QDF_STATUS_SUCCESS for success or error code 19195 */ 19196 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 19197 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 19198 { 19199 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 19200 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 19201 19202 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 19203 kickout_event = param_buf->fixed_param; 19204 19205 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 19206 ev->peer_macaddr); 19207 19208 ev->reason = kickout_event->reason; 19209 ev->rssi = kickout_event->rssi; 19210 19211 return QDF_STATUS_SUCCESS; 19212 } 19213 19214 /** 19215 * extract_all_stats_counts_tlv() - extract all stats count from event 19216 * @wmi_handle: wmi handle 19217 * @param evt_buf: pointer to event buffer 19218 * @param stats_param: Pointer to hold stats count 19219 * 19220 * Return: QDF_STATUS_SUCCESS for success or error code 19221 */ 19222 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 19223 void *evt_buf, wmi_host_stats_event *stats_param) 19224 { 19225 wmi_stats_event_fixed_param *ev; 19226 wmi_per_chain_rssi_stats *rssi_event; 19227 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19228 19229 qdf_mem_zero(stats_param, sizeof(*stats_param)); 19230 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19231 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19232 rssi_event = param_buf->chain_stats; 19233 if (!ev) { 19234 WMI_LOGE("%s: event fixed param NULL\n", __func__); 19235 return QDF_STATUS_E_FAILURE; 19236 } 19237 19238 switch (ev->stats_id) { 19239 case WMI_REQUEST_PEER_STAT: 19240 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 19241 break; 19242 19243 case WMI_REQUEST_AP_STAT: 19244 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 19245 break; 19246 19247 case WMI_REQUEST_PDEV_STAT: 19248 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 19249 break; 19250 19251 case WMI_REQUEST_VDEV_STAT: 19252 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 19253 break; 19254 19255 case WMI_REQUEST_BCNFLT_STAT: 19256 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 19257 break; 19258 19259 case WMI_REQUEST_VDEV_RATE_STAT: 19260 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 19261 break; 19262 19263 case WMI_REQUEST_BCN_STAT: 19264 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 19265 break; 19266 19267 default: 19268 stats_param->stats_id = 0; 19269 break; 19270 19271 } 19272 19273 stats_param->num_pdev_stats = ev->num_pdev_stats; 19274 stats_param->num_pdev_ext_stats = 0; 19275 stats_param->num_vdev_stats = ev->num_vdev_stats; 19276 stats_param->num_peer_stats = ev->num_peer_stats; 19277 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 19278 stats_param->num_chan_stats = ev->num_chan_stats; 19279 stats_param->num_bcn_stats = ev->num_bcn_stats; 19280 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19281 ev->pdev_id); 19282 19283 /* if chain_stats is not populated */ 19284 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 19285 return QDF_STATUS_SUCCESS; 19286 19287 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 19288 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 19289 return QDF_STATUS_SUCCESS; 19290 19291 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 19292 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 19293 return QDF_STATUS_SUCCESS; 19294 19295 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 19296 19297 return QDF_STATUS_SUCCESS; 19298 } 19299 19300 /** 19301 * extract_pdev_tx_stats() - extract pdev tx stats from event 19302 */ 19303 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 19304 { 19305 /* Tx Stats */ 19306 tx->comp_queued = tx_stats->comp_queued; 19307 tx->comp_delivered = tx_stats->comp_delivered; 19308 tx->msdu_enqued = tx_stats->msdu_enqued; 19309 tx->mpdu_enqued = tx_stats->mpdu_enqued; 19310 tx->wmm_drop = tx_stats->wmm_drop; 19311 tx->local_enqued = tx_stats->local_enqued; 19312 tx->local_freed = tx_stats->local_freed; 19313 tx->hw_queued = tx_stats->hw_queued; 19314 tx->hw_reaped = tx_stats->hw_reaped; 19315 tx->underrun = tx_stats->underrun; 19316 tx->tx_abort = tx_stats->tx_abort; 19317 tx->mpdus_requed = tx_stats->mpdus_requed; 19318 tx->data_rc = tx_stats->data_rc; 19319 tx->self_triggers = tx_stats->self_triggers; 19320 tx->sw_retry_failure = tx_stats->sw_retry_failure; 19321 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 19322 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 19323 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 19324 tx->pdev_resets = tx_stats->pdev_resets; 19325 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 19326 tx->phy_underrun = tx_stats->phy_underrun; 19327 tx->txop_ovf = tx_stats->txop_ovf; 19328 19329 return; 19330 } 19331 19332 19333 /** 19334 * extract_pdev_rx_stats() - extract pdev rx stats from event 19335 */ 19336 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 19337 { 19338 /* Rx Stats */ 19339 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 19340 rx->status_rcvd = rx_stats->status_rcvd; 19341 rx->r0_frags = rx_stats->r0_frags; 19342 rx->r1_frags = rx_stats->r1_frags; 19343 rx->r2_frags = rx_stats->r2_frags; 19344 /* Only TLV */ 19345 rx->r3_frags = 0; 19346 rx->htt_msdus = rx_stats->htt_msdus; 19347 rx->htt_mpdus = rx_stats->htt_mpdus; 19348 rx->loc_msdus = rx_stats->loc_msdus; 19349 rx->loc_mpdus = rx_stats->loc_mpdus; 19350 rx->oversize_amsdu = rx_stats->oversize_amsdu; 19351 rx->phy_errs = rx_stats->phy_errs; 19352 rx->phy_err_drop = rx_stats->phy_err_drop; 19353 rx->mpdu_errs = rx_stats->mpdu_errs; 19354 19355 return; 19356 } 19357 19358 /** 19359 * extract_pdev_stats_tlv() - extract pdev stats from event 19360 * @wmi_handle: wmi handle 19361 * @param evt_buf: pointer to event buffer 19362 * @param index: Index into pdev stats 19363 * @param pdev_stats: Pointer to hold pdev stats 19364 * 19365 * Return: QDF_STATUS_SUCCESS for success or error code 19366 */ 19367 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 19368 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 19369 { 19370 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19371 wmi_stats_event_fixed_param *ev_param; 19372 uint8_t *data; 19373 19374 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19375 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19376 19377 data = param_buf->data; 19378 19379 if (index < ev_param->num_pdev_stats) { 19380 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 19381 (index * sizeof(wmi_pdev_stats))); 19382 19383 pdev_stats->chan_nf = ev->chan_nf; 19384 pdev_stats->tx_frame_count = ev->tx_frame_count; 19385 pdev_stats->rx_frame_count = ev->rx_frame_count; 19386 pdev_stats->rx_clear_count = ev->rx_clear_count; 19387 pdev_stats->cycle_count = ev->cycle_count; 19388 pdev_stats->phy_err_count = ev->phy_err_count; 19389 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 19390 19391 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 19392 &(ev->pdev_stats.tx)); 19393 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 19394 &(ev->pdev_stats.rx)); 19395 } 19396 19397 return QDF_STATUS_SUCCESS; 19398 } 19399 19400 /** 19401 * extract_unit_test_tlv() - extract unit test data 19402 * @wmi_handle: wmi handle 19403 * @param evt_buf: pointer to event buffer 19404 * @param unit_test: pointer to hold unit test data 19405 * @param maxspace: Amount of space in evt_buf 19406 * 19407 * Return: QDF_STATUS_SUCCESS for success or error code 19408 */ 19409 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 19410 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 19411 { 19412 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 19413 wmi_unit_test_event_fixed_param *ev_param; 19414 uint32_t num_bufp; 19415 uint32_t copy_size; 19416 uint8_t *bufp; 19417 19418 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 19419 ev_param = param_buf->fixed_param; 19420 bufp = param_buf->bufp; 19421 num_bufp = param_buf->num_bufp; 19422 unit_test->vdev_id = ev_param->vdev_id; 19423 unit_test->module_id = ev_param->module_id; 19424 unit_test->diag_token = ev_param->diag_token; 19425 unit_test->flag = ev_param->flag; 19426 unit_test->payload_len = ev_param->payload_len; 19427 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 19428 ev_param->vdev_id, 19429 ev_param->module_id, 19430 ev_param->diag_token, 19431 ev_param->flag); 19432 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 19433 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 19434 bufp, num_bufp); 19435 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 19436 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 19437 unit_test->buffer_len = copy_size; 19438 19439 return QDF_STATUS_SUCCESS; 19440 } 19441 19442 /** 19443 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 19444 * @wmi_handle: wmi handle 19445 * @param evt_buf: pointer to event buffer 19446 * @param index: Index into extended pdev stats 19447 * @param pdev_ext_stats: Pointer to hold extended pdev stats 19448 * 19449 * Return: QDF_STATUS_SUCCESS for success or error code 19450 */ 19451 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 19452 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 19453 { 19454 return QDF_STATUS_SUCCESS; 19455 } 19456 19457 /** 19458 * extract_vdev_stats_tlv() - extract vdev stats from event 19459 * @wmi_handle: wmi handle 19460 * @param evt_buf: pointer to event buffer 19461 * @param index: Index into vdev stats 19462 * @param vdev_stats: Pointer to hold vdev stats 19463 * 19464 * Return: QDF_STATUS_SUCCESS for success or error code 19465 */ 19466 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 19467 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 19468 { 19469 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19470 wmi_stats_event_fixed_param *ev_param; 19471 uint8_t *data; 19472 19473 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19474 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19475 data = (uint8_t *) param_buf->data; 19476 19477 if (index < ev_param->num_vdev_stats) { 19478 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 19479 ((ev_param->num_pdev_stats) * 19480 sizeof(wmi_pdev_stats)) + 19481 (index * sizeof(wmi_vdev_stats))); 19482 19483 vdev_stats->vdev_id = ev->vdev_id; 19484 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 19485 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 19486 19487 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 19488 sizeof(ev->tx_frm_cnt)); 19489 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 19490 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 19491 ev->multiple_retry_cnt, 19492 sizeof(ev->multiple_retry_cnt)); 19493 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 19494 sizeof(ev->fail_cnt)); 19495 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 19496 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 19497 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 19498 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 19499 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 19500 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 19501 sizeof(ev->tx_rate_history)); 19502 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 19503 sizeof(ev->bcn_rssi_history)); 19504 19505 } 19506 19507 return QDF_STATUS_SUCCESS; 19508 } 19509 19510 /** 19511 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 19512 * buffer 19513 * @wmi_handle: wmi handle 19514 * @evt_buf: pointer to event buffer 19515 * @index: Index into vdev stats 19516 * @rssi_stats: Pointer to hold rssi stats 19517 * 19518 * Return: QDF_STATUS_SUCCESS for success or error code 19519 */ 19520 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 19521 void *evt_buf, uint32_t index, 19522 struct wmi_host_per_chain_rssi_stats *rssi_stats) 19523 { 19524 uint8_t *data; 19525 wmi_rssi_stats *fw_rssi_stats; 19526 wmi_per_chain_rssi_stats *rssi_event; 19527 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19528 19529 if (!evt_buf) { 19530 WMI_LOGE("evt_buf is null"); 19531 return QDF_STATUS_E_NULL_VALUE; 19532 } 19533 19534 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19535 rssi_event = param_buf->chain_stats; 19536 19537 if (index >= rssi_event->num_per_chain_rssi_stats) { 19538 WMI_LOGE("invalid index"); 19539 return QDF_STATUS_E_INVAL; 19540 } 19541 19542 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 19543 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 19544 19545 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 19546 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 19547 fw_rssi_stats->rssi_avg_beacon, 19548 sizeof(fw_rssi_stats->rssi_avg_beacon)); 19549 qdf_mem_copy(rssi_stats->rssi_avg_data, 19550 fw_rssi_stats->rssi_avg_data, 19551 sizeof(fw_rssi_stats->rssi_avg_data)); 19552 qdf_mem_copy(&rssi_stats->peer_macaddr, 19553 &fw_rssi_stats->peer_macaddr, 19554 sizeof(fw_rssi_stats->peer_macaddr)); 19555 19556 return QDF_STATUS_SUCCESS; 19557 } 19558 19559 19560 19561 /** 19562 * extract_bcn_stats_tlv() - extract bcn stats from event 19563 * @wmi_handle: wmi handle 19564 * @param evt_buf: pointer to event buffer 19565 * @param index: Index into vdev stats 19566 * @param bcn_stats: Pointer to hold bcn stats 19567 * 19568 * Return: QDF_STATUS_SUCCESS for success or error code 19569 */ 19570 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 19571 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 19572 { 19573 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19574 wmi_stats_event_fixed_param *ev_param; 19575 uint8_t *data; 19576 19577 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19578 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19579 data = (uint8_t *) param_buf->data; 19580 19581 if (index < ev_param->num_bcn_stats) { 19582 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 19583 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19584 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19585 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19586 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 19587 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 19588 (index * sizeof(wmi_bcn_stats))); 19589 19590 bcn_stats->vdev_id = ev->vdev_id; 19591 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 19592 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 19593 } 19594 19595 return QDF_STATUS_SUCCESS; 19596 } 19597 19598 /** 19599 * extract_peer_stats_tlv() - extract peer stats from event 19600 * @wmi_handle: wmi handle 19601 * @param evt_buf: pointer to event buffer 19602 * @param index: Index into peer stats 19603 * @param peer_stats: Pointer to hold peer stats 19604 * 19605 * Return: QDF_STATUS_SUCCESS for success or error code 19606 */ 19607 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 19608 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 19609 { 19610 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19611 wmi_stats_event_fixed_param *ev_param; 19612 uint8_t *data; 19613 19614 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19615 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19616 data = (uint8_t *) param_buf->data; 19617 19618 if (index < ev_param->num_peer_stats) { 19619 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 19620 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19621 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19622 (index * sizeof(wmi_peer_stats))); 19623 19624 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19625 19626 OS_MEMCPY(&(peer_stats->peer_macaddr), 19627 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19628 19629 peer_stats->peer_rssi = ev->peer_rssi; 19630 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19631 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19632 } 19633 19634 return QDF_STATUS_SUCCESS; 19635 } 19636 19637 /** 19638 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19639 * @wmi_handle: wmi handle 19640 * @param evt_buf: pointer to event buffer 19641 * @param index: Index into bcn fault stats 19642 * @param bcnflt_stats: Pointer to hold bcn fault stats 19643 * 19644 * Return: QDF_STATUS_SUCCESS for success or error code 19645 */ 19646 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19647 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19648 { 19649 return QDF_STATUS_SUCCESS; 19650 } 19651 19652 /** 19653 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19654 * @wmi_handle: wmi handle 19655 * @param evt_buf: pointer to event buffer 19656 * @param index: Index into extended peer stats 19657 * @param peer_extd_stats: Pointer to hold extended peer stats 19658 * 19659 * Return: QDF_STATUS_SUCCESS for success or error code 19660 */ 19661 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19662 void *evt_buf, uint32_t index, 19663 wmi_host_peer_extd_stats *peer_extd_stats) 19664 { 19665 return QDF_STATUS_SUCCESS; 19666 } 19667 19668 /** 19669 * extract_chan_stats_tlv() - extract chan stats from event 19670 * @wmi_handle: wmi handle 19671 * @param evt_buf: pointer to event buffer 19672 * @param index: Index into chan stats 19673 * @param vdev_extd_stats: Pointer to hold chan stats 19674 * 19675 * Return: QDF_STATUS_SUCCESS for success or error code 19676 */ 19677 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19678 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19679 { 19680 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19681 wmi_stats_event_fixed_param *ev_param; 19682 uint8_t *data; 19683 19684 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19685 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19686 data = (uint8_t *) param_buf->data; 19687 19688 if (index < ev_param->num_chan_stats) { 19689 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19690 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19691 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19692 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19693 (index * sizeof(wmi_chan_stats))); 19694 19695 19696 /* Non-TLV doesn't have num_chan_stats */ 19697 chan_stats->chan_mhz = ev->chan_mhz; 19698 chan_stats->sampling_period_us = ev->sampling_period_us; 19699 chan_stats->rx_clear_count = ev->rx_clear_count; 19700 chan_stats->tx_duration_us = ev->tx_duration_us; 19701 chan_stats->rx_duration_us = ev->rx_duration_us; 19702 } 19703 19704 return QDF_STATUS_SUCCESS; 19705 } 19706 19707 /** 19708 * extract_profile_ctx_tlv() - extract profile context from event 19709 * @wmi_handle: wmi handle 19710 * @param evt_buf: pointer to event buffer 19711 * @idx: profile stats index to extract 19712 * @param profile_ctx: Pointer to hold profile context 19713 * 19714 * Return: QDF_STATUS_SUCCESS for success or error code 19715 */ 19716 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19717 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19718 { 19719 return QDF_STATUS_SUCCESS; 19720 } 19721 19722 /** 19723 * extract_profile_data_tlv() - extract profile data from event 19724 * @wmi_handle: wmi handle 19725 * @param evt_buf: pointer to event buffer 19726 * @param profile_data: Pointer to hold profile data 19727 * 19728 * Return: QDF_STATUS_SUCCESS for success or error code 19729 */ 19730 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19731 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19732 { 19733 19734 return QDF_STATUS_SUCCESS; 19735 } 19736 19737 /** 19738 * extract_chan_info_event_tlv() - extract chan information from event 19739 * @wmi_handle: wmi handle 19740 * @param evt_buf: pointer to event buffer 19741 * @param chan_info: Pointer to hold chan information 19742 * 19743 * Return: QDF_STATUS_SUCCESS for success or error code 19744 */ 19745 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19746 void *evt_buf, wmi_host_chan_info_event *chan_info) 19747 { 19748 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19749 wmi_chan_info_event_fixed_param *ev; 19750 19751 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19752 19753 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19754 if (!ev) { 19755 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19756 return QDF_STATUS_E_FAILURE; 19757 } 19758 19759 chan_info->err_code = ev->err_code; 19760 chan_info->freq = ev->freq; 19761 chan_info->cmd_flags = ev->cmd_flags; 19762 chan_info->noise_floor = ev->noise_floor; 19763 chan_info->rx_clear_count = ev->rx_clear_count; 19764 chan_info->cycle_count = ev->cycle_count; 19765 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19766 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19767 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19768 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19769 ev->vdev_id, WLAN_SCAN_ID); 19770 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19771 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19772 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19773 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19774 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19775 chan_info->rx_frame_count = ev->rx_frame_count; 19776 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19777 chan_info->vdev_id = ev->vdev_id; 19778 19779 return QDF_STATUS_SUCCESS; 19780 } 19781 19782 /** 19783 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19784 * @wmi_handle: WMI handle 19785 * @param evt_buf: Pointer to event buffer 19786 * @param param: Pointer to hold data 19787 * 19788 * Return : QDF_STATUS_SUCCESS for success or error code 19789 */ 19790 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19791 uint8_t *evt_buf, 19792 struct wmi_host_pdev_utf_event *event) 19793 { 19794 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19795 struct wmi_host_utf_seg_header_info *seg_hdr; 19796 19797 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19798 event->data = param_buf->data; 19799 event->datalen = param_buf->num_data; 19800 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19801 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19802 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19803 seg_hdr->pdev_id); 19804 19805 return QDF_STATUS_SUCCESS; 19806 } 19807 19808 /** 19809 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19810 * @wmi_handle: wmi handle 19811 * @param evt_buf: pointer to event buffer 19812 * @param param: Pointer to hold evt buf 19813 * 19814 * Return: QDF_STATUS_SUCCESS for success or error code 19815 */ 19816 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19817 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19818 { 19819 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19820 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19821 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19822 uint8_t i = 0, j = 0; 19823 19824 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19825 if (!param_buf) 19826 return QDF_STATUS_E_INVAL; 19827 19828 hw_caps = param_buf->soc_hw_mode_caps; 19829 if (!hw_caps) 19830 return QDF_STATUS_E_INVAL; 19831 19832 if (!hw_caps->num_chainmask_tables) 19833 return QDF_STATUS_E_INVAL; 19834 19835 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19836 19837 if (chainmask_caps == NULL) 19838 return QDF_STATUS_E_INVAL; 19839 19840 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19841 19842 qdf_print("Dumping chain mask combo data for table : %d\n", i); 19843 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19844 19845 chainmask_table[i].cap_list[j].chainmask = 19846 chainmask_caps->chainmask; 19847 19848 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19849 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19850 19851 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19852 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19853 19854 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19855 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19856 19857 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19858 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19859 19860 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19861 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19862 19863 chainmask_table[i].cap_list[j].chain_mask_2G = 19864 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19865 19866 chainmask_table[i].cap_list[j].chain_mask_5G = 19867 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19868 19869 chainmask_table[i].cap_list[j].chain_mask_tx = 19870 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19871 19872 chainmask_table[i].cap_list[j].chain_mask_rx = 19873 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19874 19875 chainmask_table[i].cap_list[j].supports_aDFS = 19876 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19877 19878 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x\n", 19879 chainmask_caps->supported_flags, 19880 chainmask_caps->chainmask 19881 ); 19882 chainmask_caps++; 19883 } 19884 } 19885 19886 return QDF_STATUS_SUCCESS; 19887 } 19888 19889 /** 19890 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19891 * from event 19892 * @wmi_handle: wmi handle 19893 * @param evt_buf: pointer to event buffer 19894 * @param param: Pointer to hold evt buf 19895 * 19896 * Return: QDF_STATUS_SUCCESS for success or error code 19897 */ 19898 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19899 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19900 { 19901 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19902 wmi_service_ready_ext_event_fixed_param *ev; 19903 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19904 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19905 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19906 uint8_t i = 0; 19907 19908 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19909 if (!param_buf) 19910 return QDF_STATUS_E_INVAL; 19911 19912 ev = param_buf->fixed_param; 19913 if (!ev) 19914 return QDF_STATUS_E_INVAL; 19915 19916 /* Move this to host based bitmap */ 19917 param->default_conc_scan_config_bits = 19918 ev->default_conc_scan_config_bits; 19919 param->default_fw_config_bits = ev->default_fw_config_bits; 19920 param->he_cap_info = ev->he_cap_info; 19921 param->mpdu_density = ev->mpdu_density; 19922 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19923 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19924 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19925 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19926 19927 hw_caps = param_buf->soc_hw_mode_caps; 19928 if (hw_caps) 19929 param->num_hw_modes = hw_caps->num_hw_modes; 19930 else 19931 param->num_hw_modes = 0; 19932 19933 reg_caps = param_buf->soc_hal_reg_caps; 19934 if (reg_caps) 19935 param->num_phy = reg_caps->num_phy; 19936 else 19937 param->num_phy = 0; 19938 19939 if (hw_caps) { 19940 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19941 qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables); 19942 } else 19943 param->num_chainmask_tables = 0; 19944 19945 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19946 19947 if (chain_mask_combo == NULL) 19948 return QDF_STATUS_SUCCESS; 19949 19950 qdf_print("Dumping chain mask combo data\n"); 19951 19952 for (i = 0; i < param->num_chainmask_tables; i++) { 19953 19954 qdf_print("table_id : %d Num valid chainmasks: %d\n", 19955 chain_mask_combo->chainmask_table_id, 19956 chain_mask_combo->num_valid_chainmask 19957 ); 19958 19959 param->chainmask_table[i].table_id = 19960 chain_mask_combo->chainmask_table_id; 19961 param->chainmask_table[i].num_valid_chainmasks = 19962 chain_mask_combo->num_valid_chainmask; 19963 chain_mask_combo++; 19964 } 19965 qdf_print("chain mask combo end\n"); 19966 19967 return QDF_STATUS_SUCCESS; 19968 } 19969 19970 /** 19971 * extract_hw_mode_cap_service_ready_ext_tlv() - 19972 * extract HW mode cap from service ready event 19973 * @wmi_handle: wmi handle 19974 * @param evt_buf: pointer to event buffer 19975 * @param param: Pointer to hold evt buf 19976 * @param hw_mode_idx: hw mode idx should be less than num_mode 19977 * 19978 * Return: QDF_STATUS_SUCCESS for success or error code 19979 */ 19980 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19981 wmi_unified_t wmi_handle, 19982 uint8_t *event, uint8_t hw_mode_idx, 19983 struct wlan_psoc_host_hw_mode_caps *param) 19984 { 19985 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19986 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19987 19988 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19989 if (!param_buf) 19990 return QDF_STATUS_E_INVAL; 19991 19992 hw_caps = param_buf->soc_hw_mode_caps; 19993 if (!hw_caps) 19994 return QDF_STATUS_E_INVAL; 19995 19996 if (hw_mode_idx >= hw_caps->num_hw_modes) 19997 return QDF_STATUS_E_INVAL; 19998 19999 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 20000 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 20001 20002 param->hw_mode_config_type = 20003 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 20004 20005 return QDF_STATUS_SUCCESS; 20006 } 20007 20008 /** 20009 * extract_mac_phy_cap_service_ready_ext_tlv() - 20010 * extract MAC phy cap from service ready event 20011 * @wmi_handle: wmi handle 20012 * @param evt_buf: pointer to event buffer 20013 * @param param: Pointer to hold evt buf 20014 * @param hw_mode_idx: hw mode idx should be less than num_mode 20015 * @param phy_id: phy id within hw_mode 20016 * 20017 * Return: QDF_STATUS_SUCCESS for success or error code 20018 */ 20019 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 20020 wmi_unified_t wmi_handle, 20021 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 20022 struct wlan_psoc_host_mac_phy_caps *param) 20023 { 20024 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20025 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 20026 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 20027 uint32_t phy_map; 20028 uint8_t hw_idx, phy_idx = 0; 20029 20030 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 20031 if (!param_buf) 20032 return QDF_STATUS_E_INVAL; 20033 20034 hw_caps = param_buf->soc_hw_mode_caps; 20035 if (!hw_caps) 20036 return QDF_STATUS_E_INVAL; 20037 20038 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 20039 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 20040 break; 20041 20042 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 20043 while (phy_map) { 20044 phy_map >>= 1; 20045 phy_idx++; 20046 } 20047 } 20048 20049 if (hw_idx == hw_caps->num_hw_modes) 20050 return QDF_STATUS_E_INVAL; 20051 20052 phy_idx += phy_id; 20053 if (phy_idx >= param_buf->num_mac_phy_caps) 20054 return QDF_STATUS_E_INVAL; 20055 20056 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 20057 20058 param->hw_mode_id = mac_phy_caps->hw_mode_id; 20059 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20060 mac_phy_caps->pdev_id); 20061 param->phy_id = mac_phy_caps->phy_id; 20062 param->supports_11b = 20063 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 20064 param->supports_11g = 20065 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 20066 param->supports_11a = 20067 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 20068 param->supports_11n = 20069 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 20070 param->supports_11ac = 20071 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 20072 param->supports_11ax = 20073 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 20074 20075 param->supported_bands = mac_phy_caps->supported_bands; 20076 param->ampdu_density = mac_phy_caps->ampdu_density; 20077 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 20078 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 20079 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 20080 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 20081 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 20082 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 20083 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 20084 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 20085 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 20086 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 20087 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 20088 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 20089 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 20090 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 20091 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 20092 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 20093 qdf_mem_copy(¶m->he_cap_phy_info_2G, 20094 &mac_phy_caps->he_cap_phy_info_2G, 20095 sizeof(param->he_cap_phy_info_2G)); 20096 qdf_mem_copy(¶m->he_cap_phy_info_5G, 20097 &mac_phy_caps->he_cap_phy_info_5G, 20098 sizeof(param->he_cap_phy_info_5G)); 20099 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 20100 sizeof(param->he_ppet2G)); 20101 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 20102 sizeof(param->he_ppet5G)); 20103 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 20104 20105 return QDF_STATUS_SUCCESS; 20106 } 20107 20108 /** 20109 * extract_reg_cap_service_ready_ext_tlv() - 20110 * extract REG cap from service ready event 20111 * @wmi_handle: wmi handle 20112 * @param evt_buf: pointer to event buffer 20113 * @param param: Pointer to hold evt buf 20114 * @param phy_idx: phy idx should be less than num_mode 20115 * 20116 * Return: QDF_STATUS_SUCCESS for success or error code 20117 */ 20118 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 20119 wmi_unified_t wmi_handle, 20120 uint8_t *event, uint8_t phy_idx, 20121 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 20122 { 20123 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20124 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 20125 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 20126 20127 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 20128 if (!param_buf) 20129 return QDF_STATUS_E_INVAL; 20130 20131 reg_caps = param_buf->soc_hal_reg_caps; 20132 if (!reg_caps) 20133 return QDF_STATUS_E_INVAL; 20134 20135 if (phy_idx >= reg_caps->num_phy) 20136 return QDF_STATUS_E_INVAL; 20137 20138 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 20139 20140 param->phy_id = ext_reg_cap->phy_id; 20141 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 20142 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 20143 param->regcap1 = ext_reg_cap->regcap1; 20144 param->regcap2 = ext_reg_cap->regcap2; 20145 param->wireless_modes = convert_wireless_modes_tlv( 20146 ext_reg_cap->wireless_modes); 20147 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 20148 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 20149 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 20150 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 20151 20152 return QDF_STATUS_SUCCESS; 20153 } 20154 20155 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 20156 wmi_unified_t wmi_handle, 20157 uint8_t *event, uint8_t idx, 20158 struct wlan_psoc_host_dbr_ring_caps *param) 20159 { 20160 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20161 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 20162 20163 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 20164 if (!param_buf) 20165 return QDF_STATUS_E_INVAL; 20166 20167 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 20168 20169 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20170 dbr_ring_caps->pdev_id); 20171 param->mod_id = dbr_ring_caps->mod_id; 20172 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 20173 param->min_buf_size = dbr_ring_caps->min_buf_size; 20174 param->min_buf_align = dbr_ring_caps->min_buf_align; 20175 20176 return QDF_STATUS_SUCCESS; 20177 } 20178 20179 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 20180 uint8_t *event, struct direct_buf_rx_rsp *param) 20181 { 20182 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20183 wmi_dma_buf_release_fixed_param *ev; 20184 20185 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20186 if (!param_buf) 20187 return QDF_STATUS_E_INVAL; 20188 20189 ev = param_buf->fixed_param; 20190 if (!ev) 20191 return QDF_STATUS_E_INVAL; 20192 20193 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20194 ev->pdev_id); 20195 param->mod_id = ev->mod_id; 20196 param->num_buf_release_entry = ev->num_buf_release_entry; 20197 param->num_meta_data_entry = ev->num_meta_data_entry; 20198 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 20199 param->pdev_id, param->mod_id, param->num_buf_release_entry); 20200 20201 return QDF_STATUS_SUCCESS; 20202 } 20203 20204 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 20205 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 20206 { 20207 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20208 wmi_dma_buf_release_entry *entry; 20209 20210 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20211 if (!param_buf) 20212 return QDF_STATUS_E_INVAL; 20213 20214 entry = ¶m_buf->entries[idx]; 20215 20216 if (!entry) { 20217 WMI_LOGE("%s: Entry is NULL\n", __func__); 20218 return QDF_STATUS_E_FAILURE; 20219 } 20220 20221 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 20222 20223 param->paddr_lo = entry->paddr_lo; 20224 param->paddr_hi = entry->paddr_hi; 20225 20226 return QDF_STATUS_SUCCESS; 20227 } 20228 20229 static QDF_STATUS extract_dbr_buf_metadata_tlv( 20230 wmi_unified_t wmi_handle, uint8_t *event, 20231 uint8_t idx, struct direct_buf_rx_metadata *param) 20232 { 20233 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20234 wmi_dma_buf_release_spectral_meta_data *entry; 20235 20236 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20237 if (!param_buf) 20238 return QDF_STATUS_E_INVAL; 20239 20240 entry = ¶m_buf->meta_data[idx]; 20241 20242 if (!entry) { 20243 WMI_LOGE("%s: Entry is NULL\n", __func__); 20244 return QDF_STATUS_E_FAILURE; 20245 } 20246 20247 qdf_mem_copy(param->noisefloor, entry->noise_floor, 20248 sizeof(entry->noise_floor)); 20249 return QDF_STATUS_SUCCESS; 20250 } 20251 20252 /** 20253 * extract_dcs_interference_type_tlv() - extract dcs interference type 20254 * from event 20255 * @wmi_handle: wmi handle 20256 * @param evt_buf: pointer to event buffer 20257 * @param param: Pointer to hold dcs interference param 20258 * 20259 * Return: 0 for success or error code 20260 */ 20261 static QDF_STATUS extract_dcs_interference_type_tlv( 20262 wmi_unified_t wmi_handle, 20263 void *evt_buf, struct wmi_host_dcs_interference_param *param) 20264 { 20265 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20266 20267 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20268 if (!param_buf) 20269 return QDF_STATUS_E_INVAL; 20270 20271 param->interference_type = param_buf->fixed_param->interference_type; 20272 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20273 param_buf->fixed_param->pdev_id); 20274 20275 return QDF_STATUS_SUCCESS; 20276 } 20277 20278 /* 20279 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 20280 * @wmi_handle: wmi handle 20281 * @param evt_buf: pointer to event buffer 20282 * @param cw_int: Pointer to hold cw interference 20283 * 20284 * Return: 0 for success or error code 20285 */ 20286 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 20287 void *evt_buf, 20288 wmi_host_ath_dcs_cw_int *cw_int) 20289 { 20290 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20291 wlan_dcs_cw_int *ev; 20292 20293 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20294 if (!param_buf) 20295 return QDF_STATUS_E_INVAL; 20296 20297 ev = param_buf->cw_int; 20298 20299 cw_int->channel = ev->channel; 20300 20301 return QDF_STATUS_SUCCESS; 20302 } 20303 20304 /** 20305 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 20306 * @wmi_handle: wmi handle 20307 * @param evt_buf: pointer to event buffer 20308 * @param wlan_stat: Pointer to hold wlan stats 20309 * 20310 * Return: 0 for success or error code 20311 */ 20312 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 20313 void *evt_buf, 20314 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 20315 { 20316 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20317 wlan_dcs_im_tgt_stats_t *ev; 20318 20319 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20320 if (!param_buf) 20321 return QDF_STATUS_E_INVAL; 20322 20323 ev = param_buf->wlan_stat; 20324 wlan_stat->reg_tsf32 = ev->reg_tsf32; 20325 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 20326 wlan_stat->tx_waste_time = ev->tx_waste_time; 20327 wlan_stat->rx_time = ev->rx_time; 20328 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 20329 wlan_stat->mib_stats.listen_time = ev->listen_time; 20330 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 20331 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 20332 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 20333 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 20334 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 20335 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 20336 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 20337 wlan_stat->chan_nf = ev->chan_nf; 20338 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 20339 20340 return QDF_STATUS_SUCCESS; 20341 } 20342 20343 /** 20344 * extract_thermal_stats_tlv() - extract thermal stats from event 20345 * @wmi_handle: wmi handle 20346 * @param evt_buf: Pointer to event buffer 20347 * @param temp: Pointer to hold extracted temperature 20348 * @param level: Pointer to hold extracted level 20349 * 20350 * Return: 0 for success or error code 20351 */ 20352 static QDF_STATUS 20353 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 20354 void *evt_buf, uint32_t *temp, 20355 uint32_t *level, uint32_t *pdev_id) 20356 { 20357 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20358 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 20359 20360 param_buf = 20361 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20362 if (!param_buf) 20363 return QDF_STATUS_E_INVAL; 20364 20365 tt_stats_event = param_buf->fixed_param; 20366 20367 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20368 tt_stats_event->pdev_id); 20369 *temp = tt_stats_event->temp; 20370 *level = tt_stats_event->level; 20371 20372 return QDF_STATUS_SUCCESS; 20373 } 20374 20375 /** 20376 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 20377 * @wmi_handle: wmi handle 20378 * @param evt_buf: pointer to event buffer 20379 * @param idx: Index to level stats 20380 * @param levelcount: Pointer to hold levelcount 20381 * @param dccount: Pointer to hold dccount 20382 * 20383 * Return: 0 for success or error code 20384 */ 20385 static QDF_STATUS 20386 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 20387 void *evt_buf, uint8_t idx, uint32_t *levelcount, 20388 uint32_t *dccount) 20389 { 20390 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20391 wmi_therm_throt_level_stats_info *tt_level_info; 20392 20393 param_buf = 20394 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20395 if (!param_buf) 20396 return QDF_STATUS_E_INVAL; 20397 20398 tt_level_info = param_buf->therm_throt_level_stats_info; 20399 20400 if (idx < THERMAL_LEVELS) { 20401 *levelcount = tt_level_info[idx].level_count; 20402 *dccount = tt_level_info[idx].dc_count; 20403 return QDF_STATUS_SUCCESS; 20404 } 20405 20406 return QDF_STATUS_E_FAILURE; 20407 } 20408 #ifdef BIG_ENDIAN_HOST 20409 /** 20410 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 20411 * @param data_len - data length 20412 * @param data - pointer to data 20413 * 20414 * Return: QDF_STATUS - success or error status 20415 */ 20416 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20417 { 20418 uint8_t *data_aligned = NULL; 20419 int c; 20420 unsigned char *data_unaligned; 20421 20422 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 20423 FIPS_ALIGN)); 20424 /* Assigning unaligned space to copy the data */ 20425 /* Checking if kmalloc does succesful allocation */ 20426 if (data_unaligned == NULL) 20427 return QDF_STATUS_E_FAILURE; 20428 20429 /* Checking if space is alligned */ 20430 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 20431 /* align the data space */ 20432 data_aligned = 20433 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 20434 } else { 20435 data_aligned = (u_int8_t *)data_unaligned; 20436 } 20437 20438 /* memset and copy content from data to data aligned */ 20439 OS_MEMSET(data_aligned, 0, data_len); 20440 OS_MEMCPY(data_aligned, data, data_len); 20441 /* Endianness to LE */ 20442 for (c = 0; c < data_len/4; c++) { 20443 *((u_int32_t *)data_aligned + c) = 20444 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 20445 } 20446 20447 /* Copy content to event->data */ 20448 OS_MEMCPY(data, data_aligned, data_len); 20449 20450 /* clean up allocated space */ 20451 qdf_mem_free(data_unaligned); 20452 data_aligned = NULL; 20453 data_unaligned = NULL; 20454 20455 /*************************************************************/ 20456 20457 return QDF_STATUS_SUCCESS; 20458 } 20459 #else 20460 /** 20461 * fips_conv_data_be() - DUMMY for LE platform 20462 * 20463 * Return: QDF_STATUS - success 20464 */ 20465 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20466 { 20467 return QDF_STATUS_SUCCESS; 20468 } 20469 #endif 20470 20471 /** 20472 * extract_fips_event_data_tlv() - extract fips event data 20473 * @wmi_handle: wmi handle 20474 * @param evt_buf: pointer to event buffer 20475 * @param param: pointer FIPS event params 20476 * 20477 * Return: 0 for success or error code 20478 */ 20479 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 20480 void *evt_buf, struct wmi_host_fips_event_param *param) 20481 { 20482 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 20483 wmi_pdev_fips_event_fixed_param *event; 20484 20485 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 20486 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 20487 20488 if (fips_conv_data_be(event->data_len, param_buf->data) != 20489 QDF_STATUS_SUCCESS) 20490 return QDF_STATUS_E_FAILURE; 20491 20492 param->data = (uint32_t *)param_buf->data; 20493 param->data_len = event->data_len; 20494 param->error_status = event->error_status; 20495 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20496 event->pdev_id); 20497 20498 return QDF_STATUS_SUCCESS; 20499 } 20500 20501 /* 20502 * extract_peer_delete_response_event_tlv() - extract peer delete response event 20503 * @wmi_handle: wmi handle 20504 * @param evt_buf: pointer to event buffer 20505 * @param vdev_id: Pointer to hold vdev_id 20506 * @param mac_addr: Pointer to hold peer mac address 20507 * 20508 * Return: QDF_STATUS_SUCCESS for success or error code 20509 */ 20510 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 20511 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 20512 { 20513 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 20514 wmi_peer_delete_resp_event_fixed_param *ev; 20515 20516 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 20517 20518 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 20519 if (!ev) { 20520 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 20521 return QDF_STATUS_E_FAILURE; 20522 } 20523 20524 param->vdev_id = ev->vdev_id; 20525 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 20526 ¶m->mac_address.bytes[0]); 20527 20528 return QDF_STATUS_SUCCESS; 20529 } 20530 20531 static bool is_management_record_tlv(uint32_t cmd_id) 20532 { 20533 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 20534 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 20535 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 20536 return true; 20537 } 20538 20539 return false; 20540 } 20541 20542 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20543 { 20544 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 20545 20546 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20547 20548 switch (set_cmd->param_id) { 20549 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 20550 case WMI_VDEV_PARAM_DTIM_POLICY: 20551 return HTC_TX_PACKET_TAG_AUTO_PM; 20552 default: 20553 break; 20554 } 20555 20556 return 0; 20557 } 20558 20559 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20560 { 20561 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 20562 20563 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 20564 20565 switch (ps_cmd->param) { 20566 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 20567 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 20568 case WMI_STA_PS_ENABLE_QPOWER: 20569 return HTC_TX_PACKET_TAG_AUTO_PM; 20570 default: 20571 break; 20572 } 20573 20574 return 0; 20575 } 20576 20577 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 20578 uint32_t cmd_id) 20579 { 20580 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 20581 return 0; 20582 20583 switch (cmd_id) { 20584 case WMI_VDEV_SET_PARAM_CMDID: 20585 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 20586 case WMI_STA_POWERSAVE_PARAM_CMDID: 20587 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 20588 default: 20589 break; 20590 } 20591 20592 return 0; 20593 } 20594 20595 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20596 { 20597 uint16_t tag = 0; 20598 20599 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20600 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20601 __func__); 20602 return tag; 20603 } 20604 20605 if (wmi_handle->tag_crash_inject) 20606 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20607 20608 wmi_handle->tag_crash_inject = false; 20609 return tag; 20610 } 20611 20612 /** 20613 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20614 * @wmi_handle: WMI handle 20615 * @buf: WMI buffer 20616 * @cmd_id: WMI command Id 20617 * 20618 * Return htc_tx_tag 20619 */ 20620 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20621 wmi_buf_t buf, 20622 uint32_t cmd_id) 20623 { 20624 uint16_t htc_tx_tag = 0; 20625 20626 switch (cmd_id) { 20627 case WMI_WOW_ENABLE_CMDID: 20628 case WMI_PDEV_SUSPEND_CMDID: 20629 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20630 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20631 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20632 case WMI_PDEV_RESUME_CMDID: 20633 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20634 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20635 #ifdef FEATURE_WLAN_D0WOW 20636 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20637 #endif 20638 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20639 break; 20640 case WMI_FORCE_FW_HANG_CMDID: 20641 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20642 break; 20643 case WMI_VDEV_SET_PARAM_CMDID: 20644 case WMI_STA_POWERSAVE_PARAM_CMDID: 20645 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20646 default: 20647 break; 20648 } 20649 20650 return htc_tx_tag; 20651 } 20652 20653 /** 20654 * extract_channel_hopping_event_tlv() - extract channel hopping param 20655 * from event 20656 * @wmi_handle: wmi handle 20657 * @param evt_buf: pointer to event buffer 20658 * @param ch_hopping: Pointer to hold channel hopping param 20659 * 20660 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20661 */ 20662 static QDF_STATUS extract_channel_hopping_event_tlv( 20663 wmi_unified_t wmi_handle, void *evt_buf, 20664 wmi_host_pdev_channel_hopping_event *ch_hopping) 20665 { 20666 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20667 wmi_pdev_channel_hopping_event_fixed_param *event; 20668 20669 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20670 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20671 param_buf->fixed_param; 20672 20673 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20674 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20675 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20676 event->pdev_id); 20677 20678 return QDF_STATUS_SUCCESS; 20679 } 20680 20681 /** 20682 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20683 * @wmi_handle: wmi handle 20684 * @param evt_buf: pointer to event buffer 20685 * @param param: Pointer to hold tpc param 20686 * 20687 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20688 */ 20689 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20690 void *evt_buf, 20691 wmi_host_pdev_tpc_event *param) 20692 { 20693 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20694 wmi_pdev_tpc_event_fixed_param *event; 20695 20696 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20697 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20698 20699 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20700 event->pdev_id); 20701 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20702 20703 return QDF_STATUS_SUCCESS; 20704 } 20705 20706 /** 20707 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20708 * power param from event 20709 * @wmi_handle: wmi handle 20710 * @param evt_buf: pointer to event buffer 20711 * @param param: Pointer to hold nf cal power param 20712 * 20713 * Return: 0 for success or error code 20714 */ 20715 static QDF_STATUS 20716 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20717 void *evt_buf, 20718 wmi_host_pdev_nfcal_power_all_channels_event *param) 20719 { 20720 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20721 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20722 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20723 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20724 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20725 uint32_t i; 20726 20727 param_buf = 20728 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20729 event = param_buf->fixed_param; 20730 ch_nfdbr = param_buf->nfdbr; 20731 ch_nfdbm = param_buf->nfdbm; 20732 ch_freqnum = param_buf->freqnum; 20733 20734 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20735 event->pdev_id, param_buf->num_nfdbr, 20736 param_buf->num_nfdbm, param_buf->num_freqnum); 20737 20738 if (param_buf->num_nfdbr > 20739 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20740 WMI_LOGE("invalid number of nfdBr"); 20741 return QDF_STATUS_E_FAILURE; 20742 } 20743 20744 if (param_buf->num_nfdbm > 20745 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20746 WMI_LOGE("invalid number of nfdBm"); 20747 return QDF_STATUS_E_FAILURE; 20748 } 20749 20750 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20751 WMI_LOGE("invalid number of freqNum"); 20752 return QDF_STATUS_E_FAILURE; 20753 } 20754 20755 for (i = 0; i < param_buf->num_nfdbr; i++) { 20756 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20757 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20758 ch_nfdbr++; 20759 ch_nfdbm++; 20760 } 20761 20762 for (i = 0; i < param_buf->num_freqnum; i++) { 20763 param->freqnum[i] = ch_freqnum->freqNum; 20764 ch_freqnum++; 20765 } 20766 20767 param->pdev_id = event->pdev_id; 20768 20769 return QDF_STATUS_SUCCESS; 20770 } 20771 20772 20773 #ifdef BIG_ENDIAN_HOST 20774 /** 20775 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20776 * @param data_len - data length 20777 * @param data - pointer to data 20778 * 20779 * Return: QDF_STATUS - success or error status 20780 */ 20781 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20782 { 20783 uint8_t *datap = (uint8_t *)ev; 20784 int i; 20785 /* Skip swapping the first word */ 20786 datap += sizeof(uint32_t); 20787 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20788 i++, datap += sizeof(uint32_t)) { 20789 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20790 } 20791 20792 return QDF_STATUS_SUCCESS; 20793 } 20794 #else 20795 /** 20796 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20797 * @param data_len - data length 20798 * @param data - pointer to data 20799 * 20800 * Return: QDF_STATUS - success or error status 20801 */ 20802 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20803 { 20804 return QDF_STATUS_SUCCESS; 20805 } 20806 #endif 20807 20808 /** 20809 * extract_wds_addr_event_tlv() - extract wds address from event 20810 * @wmi_handle: wmi handle 20811 * @param evt_buf: pointer to event buffer 20812 * @param wds_ev: Pointer to hold wds address 20813 * 20814 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20815 */ 20816 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20817 void *evt_buf, 20818 uint16_t len, wds_addr_event_t *wds_ev) 20819 { 20820 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20821 wmi_wds_addr_event_fixed_param *ev; 20822 int i; 20823 20824 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20825 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20826 20827 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20828 return QDF_STATUS_E_FAILURE; 20829 20830 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20831 sizeof(wds_ev->event_type)); 20832 for (i = 0; i < 4; i++) { 20833 wds_ev->peer_mac[i] = 20834 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20835 wds_ev->dest_mac[i] = 20836 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20837 } 20838 for (i = 0; i < 2; i++) { 20839 wds_ev->peer_mac[4+i] = 20840 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20841 wds_ev->dest_mac[4+i] = 20842 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20843 } 20844 return QDF_STATUS_SUCCESS; 20845 } 20846 20847 /** 20848 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20849 * from event 20850 * @wmi_handle: wmi handle 20851 * @param evt_buf: pointer to event buffer 20852 * @param ev: Pointer to hold peer param and ps state 20853 * 20854 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20855 */ 20856 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20857 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20858 { 20859 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20860 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20861 20862 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20863 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20864 param_buf->fixed_param; 20865 20866 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20867 ev->peer_ps_state = event->peer_ps_state; 20868 20869 return QDF_STATUS_SUCCESS; 20870 } 20871 20872 /** 20873 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20874 * @wmi_handle: wmi handle 20875 * @param evt_buf: pointer to event buffer 20876 * @param inst_rssi_resp: Pointer to hold inst rssi response 20877 * 20878 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20879 */ 20880 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20881 wmi_unified_t wmi_handle, void *evt_buf, 20882 wmi_host_inst_stats_resp *inst_rssi_resp) 20883 { 20884 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20885 wmi_inst_rssi_stats_resp_fixed_param *event; 20886 20887 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20888 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20889 20890 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20891 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20892 inst_rssi_resp->iRSSI = event->iRSSI; 20893 20894 return QDF_STATUS_SUCCESS; 20895 } 20896 20897 static struct cur_reg_rule 20898 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20899 wmi_regulatory_rule_struct *wmi_reg_rule) 20900 { 20901 struct cur_reg_rule *reg_rule_ptr; 20902 uint32_t count; 20903 20904 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20905 20906 if (NULL == reg_rule_ptr) { 20907 WMI_LOGE("memory allocation failure"); 20908 return NULL; 20909 } 20910 20911 for (count = 0; count < num_reg_rules; count++) { 20912 reg_rule_ptr[count].start_freq = 20913 WMI_REG_RULE_START_FREQ_GET( 20914 wmi_reg_rule[count].freq_info); 20915 reg_rule_ptr[count].end_freq = 20916 WMI_REG_RULE_END_FREQ_GET( 20917 wmi_reg_rule[count].freq_info); 20918 reg_rule_ptr[count].max_bw = 20919 WMI_REG_RULE_MAX_BW_GET( 20920 wmi_reg_rule[count].bw_pwr_info); 20921 reg_rule_ptr[count].reg_power = 20922 WMI_REG_RULE_REG_POWER_GET( 20923 wmi_reg_rule[count].bw_pwr_info); 20924 reg_rule_ptr[count].ant_gain = 20925 WMI_REG_RULE_ANTENNA_GAIN_GET( 20926 wmi_reg_rule[count].bw_pwr_info); 20927 reg_rule_ptr[count].flags = 20928 WMI_REG_RULE_FLAGS_GET( 20929 wmi_reg_rule[count].flag_info); 20930 } 20931 20932 return reg_rule_ptr; 20933 } 20934 20935 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20936 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20937 struct cur_regulatory_info *reg_info, uint32_t len) 20938 { 20939 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20940 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20941 wmi_regulatory_rule_struct *wmi_reg_rule; 20942 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20943 20944 WMI_LOGD("processing regulatory channel list"); 20945 20946 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20947 if (!param_buf) { 20948 WMI_LOGE("invalid channel list event buf"); 20949 return QDF_STATUS_E_FAILURE; 20950 } 20951 20952 chan_list_event_hdr = param_buf->fixed_param; 20953 20954 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20955 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20956 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20957 REG_ALPHA2_LEN); 20958 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20959 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20960 reg_info->offload_enabled = true; 20961 reg_info->num_phy = chan_list_event_hdr->num_phy; 20962 reg_info->phy_id = chan_list_event_hdr->phy_id; 20963 reg_info->ctry_code = chan_list_event_hdr->country_id; 20964 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20965 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20966 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20967 else if (chan_list_event_hdr->status_code == 20968 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20969 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20970 else if (chan_list_event_hdr->status_code == 20971 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20972 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20973 else if (chan_list_event_hdr->status_code == 20974 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20975 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20976 else if (chan_list_event_hdr->status_code == 20977 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20978 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20979 else if (chan_list_event_hdr->status_code == 20980 WMI_REG_SET_CC_STATUS_FAIL) 20981 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20982 20983 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20984 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20985 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20986 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20987 20988 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20989 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20990 20991 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20992 __func__, reg_info->alpha2, reg_info->dfs_region, 20993 reg_info->min_bw_2g, reg_info->max_bw_2g, 20994 reg_info->min_bw_5g, reg_info->max_bw_5g); 20995 20996 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20997 num_2g_reg_rules, num_5g_reg_rules); 20998 wmi_reg_rule = 20999 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 21000 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 21001 + WMI_TLV_HDR_SIZE); 21002 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 21003 wmi_reg_rule); 21004 wmi_reg_rule += num_2g_reg_rules; 21005 21006 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 21007 wmi_reg_rule); 21008 21009 WMI_LOGD("processed regulatory channel list"); 21010 21011 return QDF_STATUS_SUCCESS; 21012 } 21013 21014 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 21015 wmi_unified_t wmi_handle, uint8_t *evt_buf, 21016 struct reg_11d_new_country *reg_11d_country, uint32_t len) 21017 { 21018 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 21019 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 21020 21021 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 21022 if (!param_buf) { 21023 WMI_LOGE("invalid 11d country event buf"); 21024 return QDF_STATUS_E_FAILURE; 21025 } 21026 21027 reg_11d_country_event = param_buf->fixed_param; 21028 21029 qdf_mem_copy(reg_11d_country->alpha2, 21030 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 21031 21032 WMI_LOGD("processed 11d country event, new cc %s", 21033 reg_11d_country->alpha2); 21034 21035 return QDF_STATUS_SUCCESS; 21036 } 21037 21038 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 21039 wmi_unified_t wmi_handle, uint8_t *evt_buf, 21040 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 21041 { 21042 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 21043 wmi_avoid_freq_range_desc *afr_desc; 21044 uint32_t num_freq_ranges, freq_range_idx; 21045 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 21046 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 21047 21048 if (!param_buf) { 21049 WMI_LOGE("Invalid channel avoid event buffer"); 21050 return QDF_STATUS_E_INVAL; 21051 } 21052 21053 afr_fixed_param = param_buf->fixed_param; 21054 if (!afr_fixed_param) { 21055 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 21056 return QDF_STATUS_E_INVAL; 21057 } 21058 21059 if (!ch_avoid_ind) { 21060 WMI_LOGE("Invalid channel avoid indication buffer"); 21061 return QDF_STATUS_E_INVAL; 21062 } 21063 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 21064 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 21065 afr_fixed_param->num_freq_ranges; 21066 21067 WMI_LOGD("Channel avoid event received with %d ranges", 21068 num_freq_ranges); 21069 21070 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 21071 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 21072 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 21073 freq_range_idx++) { 21074 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 21075 afr_desc->start_freq; 21076 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 21077 afr_desc->end_freq; 21078 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 21079 freq_range_idx, afr_desc->tlv_header, 21080 afr_desc->start_freq, afr_desc->end_freq); 21081 afr_desc++; 21082 } 21083 21084 return QDF_STATUS_SUCCESS; 21085 } 21086 #ifdef DFS_COMPONENT_ENABLE 21087 /** 21088 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 21089 * @wmi_handle: wma handle 21090 * @evt_buf: event buffer 21091 * @vdev_id: vdev id 21092 * @len: length of buffer 21093 * 21094 * Return: 0 for success or error code 21095 */ 21096 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 21097 uint8_t *evt_buf, 21098 uint32_t *vdev_id, 21099 uint32_t len) 21100 { 21101 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 21102 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 21103 21104 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 21105 if (!param_tlvs) { 21106 WMI_LOGE("invalid cac complete event buf"); 21107 return QDF_STATUS_E_FAILURE; 21108 } 21109 21110 cac_event = param_tlvs->fixed_param; 21111 *vdev_id = cac_event->vdev_id; 21112 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 21113 21114 return QDF_STATUS_SUCCESS; 21115 } 21116 21117 /** 21118 * extract_dfs_radar_detection_event_tlv() - extract radar found event 21119 * @wmi_handle: wma handle 21120 * @evt_buf: event buffer 21121 * @radar_found: radar found event info 21122 * @len: length of buffer 21123 * 21124 * Return: 0 for success or error code 21125 */ 21126 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 21127 wmi_unified_t wmi_handle, 21128 uint8_t *evt_buf, 21129 struct radar_found_info *radar_found, 21130 uint32_t len) 21131 { 21132 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 21133 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 21134 21135 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 21136 if (!param_tlv) { 21137 WMI_LOGE("invalid radar detection event buf"); 21138 return QDF_STATUS_E_FAILURE; 21139 } 21140 21141 radar_event = param_tlv->fixed_param; 21142 radar_found->pdev_id = wmi_handle->ops-> 21143 convert_pdev_id_target_to_host(radar_event->pdev_id); 21144 radar_found->detection_mode = radar_event->detection_mode; 21145 radar_found->chan_freq = radar_event->chan_freq; 21146 radar_found->chan_width = radar_event->chan_width; 21147 radar_found->detector_id = radar_event->detector_id; 21148 radar_found->segment_id = radar_event->segment_id; 21149 radar_found->timestamp = radar_event->timestamp; 21150 radar_found->is_chirp = radar_event->is_chirp; 21151 radar_found->freq_offset = radar_event->freq_offset; 21152 radar_found->sidx = radar_event->sidx; 21153 21154 WMI_LOGI("processed radar found event pdev %d," 21155 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 21156 "chan_width (RSSI) %d,detector_id (false_radar) %d," 21157 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 21158 "is_chirp %d,detection mode %d\n", 21159 radar_event->pdev_id, radar_event->pdev_id, 21160 radar_event->timestamp, radar_event->chan_freq, 21161 radar_event->chan_width, radar_event->detector_id, 21162 radar_event->freq_offset, radar_event->segment_id, 21163 radar_event->sidx, radar_event->is_chirp, 21164 radar_event->detection_mode); 21165 21166 return QDF_STATUS_SUCCESS; 21167 } 21168 21169 #ifdef QCA_MCL_DFS_SUPPORT 21170 /** 21171 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 21172 * @wmi_handle: wma handle 21173 * @evt_buf: event buffer 21174 * @wlan_radar_event: Pointer to struct radar_event_info 21175 * @len: length of buffer 21176 * 21177 * Return: QDF_STATUS 21178 */ 21179 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21180 wmi_unified_t wmi_handle, 21181 uint8_t *evt_buf, 21182 struct radar_event_info *wlan_radar_event, 21183 uint32_t len) 21184 { 21185 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 21186 wmi_dfs_radar_event_fixed_param *radar_event; 21187 21188 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 21189 if (!param_tlv) { 21190 WMI_LOGE("invalid wlan radar event buf"); 21191 return QDF_STATUS_E_FAILURE; 21192 } 21193 21194 radar_event = param_tlv->fixed_param; 21195 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 21196 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 21197 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 21198 wlan_radar_event->rssi = radar_event->rssi; 21199 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 21200 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 21201 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 21202 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 21203 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 21204 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 21205 wlan_radar_event->pdev_id = radar_event->pdev_id; 21206 21207 return QDF_STATUS_SUCCESS; 21208 } 21209 #else 21210 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21211 wmi_unified_t wmi_handle, 21212 uint8_t *evt_buf, 21213 struct radar_event_info *wlan_radar_event, 21214 uint32_t len) 21215 { 21216 return QDF_STATUS_SUCCESS; 21217 } 21218 #endif 21219 #endif 21220 21221 /** 21222 * send_get_rcpi_cmd_tlv() - send request for rcpi value 21223 * @wmi_handle: wmi handle 21224 * @get_rcpi_param: rcpi params 21225 * 21226 * Return: QDF status 21227 */ 21228 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 21229 struct rcpi_req *get_rcpi_param) 21230 { 21231 wmi_buf_t buf; 21232 wmi_request_rcpi_cmd_fixed_param *cmd; 21233 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 21234 21235 buf = wmi_buf_alloc(wmi_handle, len); 21236 if (!buf) { 21237 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21238 return QDF_STATUS_E_NOMEM; 21239 } 21240 21241 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 21242 WMITLV_SET_HDR(&cmd->tlv_header, 21243 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 21244 WMITLV_GET_STRUCT_TLVLEN 21245 (wmi_request_rcpi_cmd_fixed_param)); 21246 21247 cmd->vdev_id = get_rcpi_param->vdev_id; 21248 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 21249 &cmd->peer_macaddr); 21250 21251 switch (get_rcpi_param->measurement_type) { 21252 21253 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21254 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21255 break; 21256 21257 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 21258 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 21259 break; 21260 21261 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21262 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21263 break; 21264 21265 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 21266 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 21267 break; 21268 21269 default: 21270 /* 21271 * invalid rcpi measurement type, fall back to 21272 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 21273 */ 21274 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21275 break; 21276 } 21277 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 21278 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21279 WMI_REQUEST_RCPI_CMDID)) { 21280 21281 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 21282 __func__); 21283 wmi_buf_free(buf); 21284 return QDF_STATUS_E_FAILURE; 21285 } 21286 21287 return QDF_STATUS_SUCCESS; 21288 } 21289 21290 /** 21291 * extract_rcpi_response_event_tlv() - Extract RCPI event params 21292 * @wmi_handle: wmi handle 21293 * @evt_buf: pointer to event buffer 21294 * @res: pointer to hold rcpi response from firmware 21295 * 21296 * Return: QDF_STATUS_SUCCESS for successful event parse 21297 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 21298 */ 21299 static QDF_STATUS 21300 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 21301 void *evt_buf, struct rcpi_res *res) 21302 { 21303 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 21304 wmi_update_rcpi_event_fixed_param *event; 21305 21306 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 21307 if (!param_buf) { 21308 WMI_LOGE(FL("Invalid rcpi event")); 21309 return QDF_STATUS_E_INVAL; 21310 } 21311 21312 event = param_buf->fixed_param; 21313 res->vdev_id = event->vdev_id; 21314 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 21315 21316 switch (event->measurement_type) { 21317 21318 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21319 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21320 break; 21321 21322 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 21323 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 21324 break; 21325 21326 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21327 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21328 break; 21329 21330 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 21331 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 21332 break; 21333 21334 default: 21335 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 21336 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 21337 return QDF_STATUS_E_FAILURE; 21338 } 21339 21340 if (event->status) 21341 return QDF_STATUS_E_FAILURE; 21342 else 21343 return QDF_STATUS_SUCCESS; 21344 } 21345 21346 /** 21347 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 21348 * host to target defines. For legacy there is not conversion 21349 * required. Just return pdev_id as it is. 21350 * @param pdev_id: host pdev_id to be converted. 21351 * Return: target pdev_id after conversion. 21352 */ 21353 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 21354 uint32_t pdev_id) 21355 { 21356 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 21357 return WMI_PDEV_ID_SOC; 21358 21359 /*No conversion required*/ 21360 return pdev_id; 21361 } 21362 21363 /** 21364 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 21365 * target to host defines. For legacy there is not conversion 21366 * required. Just return pdev_id as it is. 21367 * @param pdev_id: target pdev_id to be converted. 21368 * Return: host pdev_id after conversion. 21369 */ 21370 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 21371 uint32_t pdev_id) 21372 { 21373 /*No conversion required*/ 21374 return pdev_id; 21375 } 21376 21377 /** 21378 * send_set_country_cmd_tlv() - WMI scan channel list function 21379 * @param wmi_handle : handle to WMI. 21380 * @param param : pointer to hold scan channel list parameter 21381 * 21382 * Return: 0 on success and -ve on failure. 21383 */ 21384 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 21385 struct set_country *params) 21386 { 21387 wmi_buf_t buf; 21388 QDF_STATUS qdf_status; 21389 wmi_set_current_country_cmd_fixed_param *cmd; 21390 uint16_t len = sizeof(*cmd); 21391 21392 buf = wmi_buf_alloc(wmi_handle, len); 21393 if (!buf) { 21394 WMI_LOGE("Failed to allocate memory"); 21395 qdf_status = QDF_STATUS_E_NOMEM; 21396 goto end; 21397 } 21398 21399 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 21400 WMITLV_SET_HDR(&cmd->tlv_header, 21401 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 21402 WMITLV_GET_STRUCT_TLVLEN 21403 (wmi_set_current_country_cmd_fixed_param)); 21404 21405 WMI_LOGD("setting cuurnet country to %s", params->country); 21406 21407 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 21408 21409 cmd->pdev_id = params->pdev_id; 21410 21411 qdf_status = wmi_unified_cmd_send(wmi_handle, 21412 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 21413 21414 if (QDF_IS_STATUS_ERROR(qdf_status)) { 21415 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 21416 wmi_buf_free(buf); 21417 } 21418 21419 end: 21420 return qdf_status; 21421 } 21422 21423 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 21424 WMI_SET_BITS(alpha, 0, 8, val0); \ 21425 WMI_SET_BITS(alpha, 8, 8, val1); \ 21426 WMI_SET_BITS(alpha, 16, 8, val2); \ 21427 } while (0) 21428 21429 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 21430 uint8_t pdev_id, struct cc_regdmn_s *rd) 21431 { 21432 wmi_set_init_country_cmd_fixed_param *cmd; 21433 uint16_t len; 21434 wmi_buf_t buf; 21435 int ret; 21436 21437 len = sizeof(wmi_set_init_country_cmd_fixed_param); 21438 buf = wmi_buf_alloc(wmi_handle, len); 21439 if (!buf) { 21440 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 21441 return QDF_STATUS_E_NOMEM; 21442 } 21443 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 21444 WMITLV_SET_HDR(&cmd->tlv_header, 21445 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 21446 WMITLV_GET_STRUCT_TLVLEN 21447 (wmi_set_init_country_cmd_fixed_param)); 21448 21449 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 21450 21451 if (rd->flags == CC_IS_SET) { 21452 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 21453 cmd->country_code.country_id = rd->cc.country_code; 21454 } else if (rd->flags == ALPHA_IS_SET) { 21455 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 21456 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 21457 rd->cc.alpha[0], 21458 rd->cc.alpha[1], 21459 rd->cc.alpha[2]); 21460 } else if (rd->flags == REGDMN_IS_SET) { 21461 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 21462 cmd->country_code.domain_code = rd->cc.regdmn_id; 21463 } 21464 21465 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21466 WMI_SET_INIT_COUNTRY_CMDID); 21467 if (ret) { 21468 WMI_LOGE("Failed to config wow wakeup event"); 21469 wmi_buf_free(buf); 21470 return QDF_STATUS_E_FAILURE; 21471 } 21472 21473 return QDF_STATUS_SUCCESS; 21474 } 21475 21476 /** 21477 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 21478 * configuration params 21479 * @wmi_handle: wmi handler 21480 * @limit_off_chan_param: pointer to wmi_off_chan_param 21481 * 21482 * Return: 0 for success and non zero for failure 21483 */ 21484 static 21485 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 21486 struct wmi_limit_off_chan_param *limit_off_chan_param) 21487 { 21488 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 21489 wmi_buf_t buf; 21490 uint32_t len = sizeof(*cmd); 21491 int err; 21492 21493 buf = wmi_buf_alloc(wmi_handle, len); 21494 if (!buf) { 21495 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 21496 __func__); 21497 return QDF_STATUS_E_NOMEM; 21498 } 21499 21500 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 21501 21502 WMITLV_SET_HDR(&cmd->tlv_header, 21503 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 21504 WMITLV_GET_STRUCT_TLVLEN( 21505 wmi_vdev_limit_offchan_cmd_fixed_param)); 21506 21507 cmd->vdev_id = limit_off_chan_param->vdev_id; 21508 21509 cmd->flags &= 0; 21510 if (limit_off_chan_param->status) 21511 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 21512 if (limit_off_chan_param->skip_dfs_chans) 21513 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 21514 21515 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 21516 cmd->rest_time = limit_off_chan_param->rest_time; 21517 21518 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 21519 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 21520 cmd->rest_time); 21521 21522 err = wmi_unified_cmd_send(wmi_handle, buf, 21523 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 21524 if (QDF_IS_STATUS_ERROR(err)) { 21525 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 21526 wmi_buf_free(buf); 21527 return QDF_STATUS_E_FAILURE; 21528 } 21529 21530 return QDF_STATUS_SUCCESS; 21531 } 21532 21533 /** 21534 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 21535 * @wmi_handle: wmi handler 21536 * @req_buf: set arp stats request buffer 21537 * 21538 * Return: 0 for success and non zero for failure 21539 */ 21540 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21541 struct set_arp_stats *req_buf) 21542 { 21543 wmi_buf_t buf = NULL; 21544 QDF_STATUS status; 21545 int len; 21546 uint8_t *buf_ptr; 21547 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 21548 21549 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21550 if (req_buf->pkt_type_bitmap) { 21551 len += WMI_TLV_HDR_SIZE; 21552 len += sizeof(wmi_vdev_set_connectivity_check_stats); 21553 } 21554 buf = wmi_buf_alloc(wmi_handle, len); 21555 if (!buf) { 21556 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21557 return QDF_STATUS_E_NOMEM; 21558 } 21559 21560 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21561 wmi_set_arp = 21562 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 21563 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 21564 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 21565 WMITLV_GET_STRUCT_TLVLEN 21566 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 21567 21568 /* fill in per roam config values */ 21569 wmi_set_arp->vdev_id = req_buf->vdev_id; 21570 21571 wmi_set_arp->set_clr = req_buf->flag; 21572 wmi_set_arp->pkt_type = req_buf->pkt_type; 21573 wmi_set_arp->ipv4 = req_buf->ip_addr; 21574 21575 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 21576 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 21577 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 21578 21579 /* 21580 * pkt_type_bitmap should be non-zero to ensure 21581 * presence of additional stats. 21582 */ 21583 if (req_buf->pkt_type_bitmap) { 21584 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21585 21586 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21587 WMITLV_SET_HDR(buf_ptr, 21588 WMITLV_TAG_ARRAY_STRUC, 21589 sizeof(wmi_vdev_set_connectivity_check_stats)); 21590 buf_ptr += WMI_TLV_HDR_SIZE; 21591 wmi_set_connect_stats = 21592 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21593 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21594 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21595 WMITLV_GET_STRUCT_TLVLEN( 21596 wmi_vdev_set_connectivity_check_stats)); 21597 wmi_set_connect_stats->pkt_type_bitmap = 21598 req_buf->pkt_type_bitmap; 21599 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21600 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21601 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21602 21603 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21604 wmi_set_connect_stats->pkt_type_bitmap, 21605 wmi_set_connect_stats->tcp_src_port, 21606 wmi_set_connect_stats->tcp_dst_port, 21607 wmi_set_connect_stats->icmp_ipv4); 21608 } 21609 21610 /* Send per roam config parameters */ 21611 status = wmi_unified_cmd_send(wmi_handle, buf, 21612 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21613 if (QDF_IS_STATUS_ERROR(status)) { 21614 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21615 status); 21616 goto error; 21617 } 21618 21619 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 21620 req_buf->flag, req_buf->vdev_id); 21621 return QDF_STATUS_SUCCESS; 21622 error: 21623 wmi_buf_free(buf); 21624 21625 return status; 21626 } 21627 21628 /** 21629 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21630 * @wmi_handle: wmi handler 21631 * @req_buf: get arp stats request buffer 21632 * 21633 * Return: 0 for success and non zero for failure 21634 */ 21635 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21636 struct get_arp_stats *req_buf) 21637 { 21638 wmi_buf_t buf = NULL; 21639 QDF_STATUS status; 21640 int len; 21641 uint8_t *buf_ptr; 21642 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21643 21644 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21645 buf = wmi_buf_alloc(wmi_handle, len); 21646 if (!buf) { 21647 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21648 return QDF_STATUS_E_NOMEM; 21649 } 21650 21651 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21652 get_arp_stats = 21653 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21654 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21655 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21656 WMITLV_GET_STRUCT_TLVLEN 21657 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21658 21659 /* fill in arp stats req cmd values */ 21660 get_arp_stats->vdev_id = req_buf->vdev_id; 21661 21662 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21663 /* Send per roam config parameters */ 21664 status = wmi_unified_cmd_send(wmi_handle, buf, 21665 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21666 if (QDF_IS_STATUS_ERROR(status)) { 21667 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21668 status); 21669 goto error; 21670 } 21671 21672 return QDF_STATUS_SUCCESS; 21673 error: 21674 wmi_buf_free(buf); 21675 21676 return status; 21677 } 21678 21679 /** 21680 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21681 * @wmi_handle: wmi handler 21682 * @pmk_info: pointer to PMK cache entry 21683 * @vdev_id: vdev id 21684 * 21685 * Return: 0 for success and non zero for failure 21686 */ 21687 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21688 struct wmi_unified_pmk_cache *pmk_info) 21689 { 21690 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21691 wmi_buf_t buf; 21692 QDF_STATUS status; 21693 uint8_t *buf_ptr; 21694 wmi_pmk_cache *pmksa; 21695 uint32_t len = sizeof(*cmd); 21696 21697 if (pmk_info->pmk_len) 21698 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21699 21700 buf = wmi_buf_alloc(wmi_handle, len); 21701 if (!buf) { 21702 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21703 __func__); 21704 return QDF_STATUS_E_NOMEM; 21705 } 21706 21707 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21708 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21709 21710 WMITLV_SET_HDR(&cmd->tlv_header, 21711 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21712 WMITLV_GET_STRUCT_TLVLEN( 21713 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21714 21715 cmd->vdev_id = pmk_info->session_id; 21716 21717 /* If pmk_info->pmk_len is 0, this is a flush request */ 21718 if (!pmk_info->pmk_len) { 21719 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21720 cmd->num_cache = 0; 21721 goto send_cmd; 21722 } 21723 21724 cmd->num_cache = 1; 21725 buf_ptr += sizeof(*cmd); 21726 21727 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21728 sizeof(*pmksa)); 21729 buf_ptr += WMI_TLV_HDR_SIZE; 21730 21731 pmksa = (wmi_pmk_cache *)buf_ptr; 21732 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21733 WMITLV_GET_STRUCT_TLVLEN 21734 (wmi_pmk_cache)); 21735 pmksa->pmk_len = pmk_info->pmk_len; 21736 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21737 pmksa->pmkid_len = pmk_info->pmkid_len; 21738 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21739 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21740 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21741 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21742 pmksa->ssid.ssid_len); 21743 pmksa->cache_id = pmk_info->cache_id; 21744 pmksa->cat_flag = pmk_info->cat_flag; 21745 pmksa->action_flag = pmk_info->action_flag; 21746 21747 send_cmd: 21748 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21749 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21750 if (status != QDF_STATUS_SUCCESS) { 21751 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21752 __func__, status); 21753 wmi_buf_free(buf); 21754 } 21755 21756 return status; 21757 } 21758 21759 /** 21760 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21761 * @wmi_handle: wmi handle 21762 * @param: reserved param 21763 * 21764 * Return: 0 for success or error code 21765 */ 21766 static QDF_STATUS 21767 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21768 uint32_t param) 21769 { 21770 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21771 wmi_buf_t buf; 21772 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21773 21774 buf = wmi_buf_alloc(wmi_handle, len); 21775 if (!buf) { 21776 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21777 return QDF_STATUS_E_FAILURE; 21778 } 21779 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21780 WMITLV_SET_HDR(&cmd->tlv_header, 21781 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21782 WMITLV_GET_STRUCT_TLVLEN 21783 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21784 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21785 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21786 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21787 wmi_buf_free(buf); 21788 return QDF_STATUS_E_FAILURE; 21789 } 21790 21791 return QDF_STATUS_SUCCESS; 21792 } 21793 21794 /** 21795 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 21796 * host to target defines. 21797 * @param pdev_id: host pdev_id to be converted. 21798 * Return: target pdev_id after conversion. 21799 */ 21800 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 21801 { 21802 switch (pdev_id) { 21803 case WMI_HOST_PDEV_ID_SOC: 21804 return WMI_PDEV_ID_SOC; 21805 case WMI_HOST_PDEV_ID_0: 21806 return WMI_PDEV_ID_1ST; 21807 case WMI_HOST_PDEV_ID_1: 21808 return WMI_PDEV_ID_2ND; 21809 case WMI_HOST_PDEV_ID_2: 21810 return WMI_PDEV_ID_3RD; 21811 } 21812 21813 QDF_ASSERT(0); 21814 21815 return WMI_PDEV_ID_SOC; 21816 } 21817 21818 /** 21819 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 21820 * target to host defines. 21821 * @param pdev_id: target pdev_id to be converted. 21822 * Return: host pdev_id after conversion. 21823 */ 21824 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 21825 { 21826 switch (pdev_id) { 21827 case WMI_PDEV_ID_SOC: 21828 return WMI_HOST_PDEV_ID_SOC; 21829 case WMI_PDEV_ID_1ST: 21830 return WMI_HOST_PDEV_ID_0; 21831 case WMI_PDEV_ID_2ND: 21832 return WMI_HOST_PDEV_ID_1; 21833 case WMI_PDEV_ID_3RD: 21834 return WMI_HOST_PDEV_ID_2; 21835 } 21836 21837 QDF_ASSERT(0); 21838 21839 return WMI_HOST_PDEV_ID_SOC; 21840 } 21841 21842 /** 21843 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 21844 * 21845 * Return None. 21846 */ 21847 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 21848 { 21849 wmi_handle->ops->convert_pdev_id_host_to_target = 21850 convert_host_pdev_id_to_target_pdev_id; 21851 wmi_handle->ops->convert_pdev_id_target_to_host = 21852 convert_target_pdev_id_to_host_pdev_id; 21853 } 21854 21855 /** 21856 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21857 * @wmi_handle: wmi handle 21858 * @param evt_buf: pointer to event buffer 21859 * @param param: Pointer to hold peer caldata version data 21860 * 21861 * Return: 0 for success or error code 21862 */ 21863 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21864 wmi_unified_t wmi_handle, 21865 void *evt_buf, 21866 wmi_host_pdev_check_cal_version_event *param) 21867 { 21868 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21869 wmi_pdev_check_cal_version_event_fixed_param *event; 21870 21871 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21872 if (!param_tlvs) { 21873 WMI_LOGE("invalid cal version event buf"); 21874 return QDF_STATUS_E_FAILURE; 21875 } 21876 event = param_tlvs->fixed_param; 21877 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21878 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21879 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21880 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21881 21882 param->software_cal_version = event->software_cal_version; 21883 param->board_cal_version = event->board_cal_version; 21884 param->cal_ok = event->cal_status; 21885 21886 return QDF_STATUS_SUCCESS; 21887 } 21888 21889 /* 21890 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21891 * @wmi_handle: wmi handle 21892 * @params: pointer to wmi_btm_config 21893 * 21894 * Return: QDF_STATUS 21895 */ 21896 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21897 struct wmi_btm_config *params) 21898 { 21899 21900 wmi_btm_config_fixed_param *cmd; 21901 wmi_buf_t buf; 21902 uint32_t len; 21903 21904 len = sizeof(*cmd); 21905 buf = wmi_buf_alloc(wmi_handle, len); 21906 if (!buf) { 21907 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21908 return QDF_STATUS_E_NOMEM; 21909 } 21910 21911 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21912 WMITLV_SET_HDR(&cmd->tlv_header, 21913 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21914 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21915 cmd->vdev_id = params->vdev_id; 21916 cmd->flags = params->btm_offload_config; 21917 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21918 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21919 cmd->stick_time_seconds = params->btm_sticky_time; 21920 21921 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21922 WMI_ROAM_BTM_CONFIG_CMDID)) { 21923 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21924 __func__); 21925 wmi_buf_free(buf); 21926 return QDF_STATUS_E_FAILURE; 21927 } 21928 21929 return QDF_STATUS_SUCCESS; 21930 } 21931 21932 /** 21933 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21934 * configurations to firmware. 21935 * @wmi_handle: wmi handle 21936 * @obss_cfg_param: obss detection configurations 21937 * 21938 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21939 * 21940 * Return: QDF_STATUS 21941 */ 21942 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21943 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21944 { 21945 wmi_buf_t buf; 21946 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21947 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21948 21949 buf = wmi_buf_alloc(wmi_handle, len); 21950 if (!buf) { 21951 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21952 return QDF_STATUS_E_NOMEM; 21953 } 21954 21955 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21956 WMITLV_SET_HDR(&cmd->tlv_header, 21957 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21958 WMITLV_GET_STRUCT_TLVLEN 21959 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21960 21961 cmd->vdev_id = obss_cfg_param->vdev_id; 21962 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21963 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21964 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21965 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21966 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21967 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21968 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21969 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21970 21971 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21972 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21973 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21974 wmi_buf_free(buf); 21975 return QDF_STATUS_E_FAILURE; 21976 } 21977 21978 return QDF_STATUS_SUCCESS; 21979 } 21980 21981 /** 21982 * extract_obss_detection_info_tlv() - Extract obss detection info 21983 * received from firmware. 21984 * @evt_buf: pointer to event buffer 21985 * @obss_detection: Pointer to hold obss detection info 21986 * 21987 * Return: QDF_STATUS 21988 */ 21989 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21990 struct wmi_obss_detect_info 21991 *obss_detection) 21992 { 21993 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21994 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21995 21996 if (!obss_detection) { 21997 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21998 return QDF_STATUS_E_INVAL; 21999 } 22000 22001 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 22002 if (!param_buf) { 22003 WMI_LOGE("%s: Invalid evt_buf", __func__); 22004 return QDF_STATUS_E_INVAL; 22005 } 22006 22007 fix_param = param_buf->fixed_param; 22008 obss_detection->vdev_id = fix_param->vdev_id; 22009 obss_detection->matched_detection_masks = 22010 fix_param->matched_detection_masks; 22011 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 22012 &obss_detection->matched_bssid_addr[0]); 22013 switch (fix_param->reason) { 22014 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 22015 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 22016 break; 22017 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 22018 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 22019 break; 22020 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 22021 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 22022 break; 22023 default: 22024 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 22025 return QDF_STATUS_E_INVAL; 22026 } 22027 22028 return QDF_STATUS_SUCCESS; 22029 } 22030 22031 /** 22032 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 22033 * @wmi_handle: wmi handler 22034 * @params: pointer to 11k offload params 22035 * 22036 * Return: 0 for success and non zero for failure 22037 */ 22038 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 22039 struct wmi_11k_offload_params *params) 22040 { 22041 wmi_11k_offload_report_fixed_param *cmd; 22042 wmi_buf_t buf; 22043 QDF_STATUS status; 22044 uint8_t *buf_ptr; 22045 wmi_neighbor_report_11k_offload_tlv_param 22046 *neighbor_report_offload_params; 22047 wmi_neighbor_report_offload *neighbor_report_offload; 22048 22049 uint32_t len = sizeof(*cmd); 22050 22051 if (params->offload_11k_bitmask & 22052 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 22053 len += WMI_TLV_HDR_SIZE + 22054 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 22055 22056 buf = wmi_buf_alloc(wmi_handle, len); 22057 if (!buf) { 22058 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 22059 __func__); 22060 return QDF_STATUS_E_NOMEM; 22061 } 22062 22063 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22064 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 22065 22066 WMITLV_SET_HDR(&cmd->tlv_header, 22067 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 22068 WMITLV_GET_STRUCT_TLVLEN( 22069 wmi_11k_offload_report_fixed_param)); 22070 22071 cmd->vdev_id = params->vdev_id; 22072 cmd->offload_11k = params->offload_11k_bitmask; 22073 22074 if (params->offload_11k_bitmask & 22075 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 22076 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 22077 22078 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 22079 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 22080 buf_ptr += WMI_TLV_HDR_SIZE; 22081 22082 neighbor_report_offload_params = 22083 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 22084 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 22085 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 22086 WMITLV_GET_STRUCT_TLVLEN( 22087 wmi_neighbor_report_11k_offload_tlv_param)); 22088 22089 neighbor_report_offload = &neighbor_report_offload_params-> 22090 neighbor_rep_ofld_params; 22091 22092 neighbor_report_offload->time_offset = 22093 params->neighbor_report_params.time_offset; 22094 neighbor_report_offload->low_rssi_offset = 22095 params->neighbor_report_params.low_rssi_offset; 22096 neighbor_report_offload->bmiss_count_trigger = 22097 params->neighbor_report_params.bmiss_count_trigger; 22098 neighbor_report_offload->per_threshold_offset = 22099 params->neighbor_report_params.per_threshold_offset; 22100 neighbor_report_offload->neighbor_report_cache_timeout = 22101 params->neighbor_report_params. 22102 neighbor_report_cache_timeout; 22103 neighbor_report_offload->max_neighbor_report_req_cap = 22104 params->neighbor_report_params. 22105 max_neighbor_report_req_cap; 22106 neighbor_report_offload->ssid.ssid_len = 22107 params->neighbor_report_params.ssid.length; 22108 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 22109 ¶ms->neighbor_report_params.ssid.mac_ssid, 22110 neighbor_report_offload->ssid.ssid_len); 22111 } 22112 22113 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22114 WMI_11K_OFFLOAD_REPORT_CMDID); 22115 if (status != QDF_STATUS_SUCCESS) { 22116 WMI_LOGE("%s: failed to send 11k offload command %d", 22117 __func__, status); 22118 wmi_buf_free(buf); 22119 } 22120 22121 return status; 22122 } 22123 22124 /** 22125 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 22126 * command 22127 * @wmi_handle: wmi handler 22128 * @params: pointer to neighbor report invoke params 22129 * 22130 * Return: 0 for success and non zero for failure 22131 */ 22132 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 22133 struct wmi_invoke_neighbor_report_params *params) 22134 { 22135 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 22136 wmi_buf_t buf; 22137 QDF_STATUS status; 22138 uint8_t *buf_ptr; 22139 uint32_t len = sizeof(*cmd); 22140 22141 buf = wmi_buf_alloc(wmi_handle, len); 22142 if (!buf) { 22143 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 22144 __func__); 22145 return QDF_STATUS_E_NOMEM; 22146 } 22147 22148 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22149 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 22150 22151 WMITLV_SET_HDR(&cmd->tlv_header, 22152 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 22153 WMITLV_GET_STRUCT_TLVLEN( 22154 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 22155 22156 cmd->vdev_id = params->vdev_id; 22157 cmd->flags = params->send_resp_to_host; 22158 22159 cmd->ssid.ssid_len = params->ssid.length; 22160 qdf_mem_copy(cmd->ssid.ssid, 22161 ¶ms->ssid.mac_ssid, 22162 cmd->ssid.ssid_len); 22163 22164 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22165 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 22166 if (status != QDF_STATUS_SUCCESS) { 22167 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 22168 __func__, status); 22169 wmi_buf_free(buf); 22170 } 22171 22172 return status; 22173 } 22174 22175 #ifdef WLAN_SUPPORT_GREEN_AP 22176 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 22177 uint8_t *evt_buf, 22178 struct wlan_green_ap_egap_status_info *egap_status_info_params) 22179 { 22180 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 22181 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 22182 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 22183 22184 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 22185 if (!param_buf) { 22186 WMI_LOGE("Invalid EGAP Info status event buffer"); 22187 return QDF_STATUS_E_INVAL; 22188 } 22189 22190 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 22191 param_buf->fixed_param; 22192 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 22193 param_buf->chainmask_list; 22194 22195 egap_status_info_params->status = egap_info_event->status; 22196 egap_status_info_params->mac_id = chainmask_event->mac_id; 22197 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 22198 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 22199 22200 return QDF_STATUS_SUCCESS; 22201 } 22202 #endif 22203 22204 /* 22205 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 22206 * updating bss color change within firmware when AP announces bss color change. 22207 * @wmi_handle: wmi handle 22208 * @vdev_id: vdev ID 22209 * @enable: enable bss color change within firmware 22210 * 22211 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 22212 * 22213 * Return: QDF_STATUS 22214 */ 22215 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 22216 uint32_t vdev_id, 22217 bool enable) 22218 { 22219 wmi_buf_t buf; 22220 wmi_bss_color_change_enable_fixed_param *cmd; 22221 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 22222 22223 buf = wmi_buf_alloc(wmi_handle, len); 22224 if (!buf) { 22225 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22226 return QDF_STATUS_E_NOMEM; 22227 } 22228 22229 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 22230 WMITLV_SET_HDR(&cmd->tlv_header, 22231 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 22232 WMITLV_GET_STRUCT_TLVLEN 22233 (wmi_bss_color_change_enable_fixed_param)); 22234 cmd->vdev_id = vdev_id; 22235 cmd->enable = enable; 22236 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22237 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 22238 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 22239 wmi_buf_free(buf); 22240 return QDF_STATUS_E_FAILURE; 22241 } 22242 22243 return QDF_STATUS_SUCCESS; 22244 } 22245 22246 /** 22247 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 22248 * configurations to firmware. 22249 * @wmi_handle: wmi handle 22250 * @cfg_param: obss detection configurations 22251 * 22252 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 22253 * 22254 * Return: QDF_STATUS 22255 */ 22256 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 22257 wmi_unified_t wmi_handle, 22258 struct wmi_obss_color_collision_cfg_param *cfg_param) 22259 { 22260 wmi_buf_t buf; 22261 wmi_obss_color_collision_det_config_fixed_param *cmd; 22262 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 22263 22264 buf = wmi_buf_alloc(wmi_handle, len); 22265 if (!buf) { 22266 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22267 return QDF_STATUS_E_NOMEM; 22268 } 22269 22270 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 22271 buf); 22272 WMITLV_SET_HDR(&cmd->tlv_header, 22273 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 22274 WMITLV_GET_STRUCT_TLVLEN 22275 (wmi_obss_color_collision_det_config_fixed_param)); 22276 cmd->vdev_id = cfg_param->vdev_id; 22277 cmd->flags = cfg_param->flags; 22278 cmd->current_bss_color = cfg_param->current_bss_color; 22279 cmd->detection_period_ms = cfg_param->detection_period_ms; 22280 cmd->scan_period_ms = cfg_param->scan_period_ms; 22281 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 22282 22283 switch (cfg_param->evt_type) { 22284 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 22285 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 22286 break; 22287 case OBSS_COLOR_COLLISION_DETECTION: 22288 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 22289 break; 22290 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22291 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22292 break; 22293 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 22294 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 22295 break; 22296 default: 22297 WMI_LOGE("%s: invalid event type: %d", 22298 __func__, cfg_param->evt_type); 22299 wmi_buf_free(buf); 22300 return QDF_STATUS_E_FAILURE; 22301 } 22302 22303 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22304 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 22305 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 22306 __func__, cfg_param->vdev_id); 22307 wmi_buf_free(buf); 22308 return QDF_STATUS_E_FAILURE; 22309 } 22310 22311 return QDF_STATUS_SUCCESS; 22312 } 22313 22314 /** 22315 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 22316 * received from firmware. 22317 * @evt_buf: pointer to event buffer 22318 * @info: Pointer to hold bss collision info 22319 * 22320 * Return: QDF_STATUS 22321 */ 22322 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 22323 struct wmi_obss_color_collision_info *info) 22324 { 22325 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 22326 wmi_obss_color_collision_evt_fixed_param *fix_param; 22327 22328 if (!info) { 22329 WMI_LOGE("%s: Invalid obss color buffer", __func__); 22330 return QDF_STATUS_E_INVAL; 22331 } 22332 22333 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 22334 evt_buf; 22335 if (!param_buf) { 22336 WMI_LOGE("%s: Invalid evt_buf", __func__); 22337 return QDF_STATUS_E_INVAL; 22338 } 22339 22340 fix_param = param_buf->fixed_param; 22341 info->vdev_id = fix_param->vdev_id; 22342 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 22343 info->obss_color_bitmap_bit32to63 = 22344 fix_param->bss_color_bitmap_bit32to63; 22345 22346 switch (fix_param->evt_type) { 22347 case WMI_BSS_COLOR_COLLISION_DISABLE: 22348 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 22349 break; 22350 case WMI_BSS_COLOR_COLLISION_DETECTION: 22351 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 22352 break; 22353 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22354 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22355 break; 22356 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 22357 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 22358 break; 22359 default: 22360 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 22361 __func__, fix_param->evt_type, fix_param->vdev_id); 22362 return QDF_STATUS_E_FAILURE; 22363 } 22364 22365 return QDF_STATUS_SUCCESS; 22366 } 22367 22368 /* 22369 * extract_comb_phyerr_tlv() - extract comb phy error from event 22370 * @wmi_handle: wmi handle 22371 * @evt_buf: pointer to event buffer 22372 * @datalen: data length of event buffer 22373 * @buf_offset: Pointer to hold value of current event buffer offset 22374 * post extraction 22375 * @phyerr: Pointer to hold phyerr 22376 * 22377 * Return: QDF_STATUS 22378 */ 22379 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 22380 void *evt_buf, 22381 uint16_t datalen, 22382 uint16_t *buf_offset, 22383 wmi_host_phyerr_t *phyerr) 22384 { 22385 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 22386 wmi_comb_phyerr_rx_hdr *pe_hdr; 22387 22388 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 22389 if (!param_tlvs) { 22390 WMI_LOGD("%s: Received null data from FW", __func__); 22391 return QDF_STATUS_E_FAILURE; 22392 } 22393 22394 pe_hdr = param_tlvs->hdr; 22395 if (!pe_hdr) { 22396 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 22397 return QDF_STATUS_E_FAILURE; 22398 } 22399 22400 /* Ensure it's at least the size of the header */ 22401 if (datalen < sizeof(*pe_hdr)) { 22402 WMI_LOGD("%s: Expected minimum size %zu, received %d", 22403 __func__, sizeof(*pe_hdr), datalen); 22404 return QDF_STATUS_E_FAILURE; 22405 } 22406 22407 phyerr->pdev_id = wmi_handle->ops-> 22408 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 22409 phyerr->tsf64 = pe_hdr->tsf_l32; 22410 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 22411 phyerr->bufp = param_tlvs->bufp; 22412 phyerr->buf_len = pe_hdr->buf_len; 22413 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 22414 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 22415 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 22416 22417 return QDF_STATUS_SUCCESS; 22418 } 22419 22420 /** 22421 * extract_single_phyerr_tlv() - extract single phy error from event 22422 * @wmi_handle: wmi handle 22423 * @evt_buf: pointer to event buffer 22424 * @datalen: data length of event buffer 22425 * @buf_offset: Pointer to hold value of current event buffer offset 22426 * post extraction 22427 * @phyerr: Pointer to hold phyerr 22428 * 22429 * Return: QDF_STATUS 22430 */ 22431 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 22432 void *evt_buf, 22433 uint16_t datalen, 22434 uint16_t *buf_offset, 22435 wmi_host_phyerr_t *phyerr) 22436 { 22437 wmi_single_phyerr_rx_event *ev; 22438 uint16_t n = *buf_offset; 22439 uint8_t *data = (uint8_t *)evt_buf; 22440 22441 if (n < datalen) { 22442 if ((datalen - n) < sizeof(ev->hdr)) { 22443 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 22444 __func__, datalen, n, sizeof(ev->hdr)); 22445 return QDF_STATUS_E_FAILURE; 22446 } 22447 22448 /* 22449 * Obtain a pointer to the beginning of the current event. 22450 * data[0] is the beginning of the WMI payload. 22451 */ 22452 ev = (wmi_single_phyerr_rx_event *)&data[n]; 22453 22454 /* 22455 * Sanity check the buffer length of the event against 22456 * what we currently have. 22457 * 22458 * Since buf_len is 32 bits, we check if it overflows 22459 * a large 32 bit value. It's not 0x7fffffff because 22460 * we increase n by (buf_len + sizeof(hdr)), which would 22461 * in itself cause n to overflow. 22462 * 22463 * If "int" is 64 bits then this becomes a moot point. 22464 */ 22465 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 22466 WMI_LOGD("%s: buf_len is garbage 0x%x", 22467 __func__, ev->hdr.buf_len); 22468 return QDF_STATUS_E_FAILURE; 22469 } 22470 22471 if ((n + ev->hdr.buf_len) > datalen) { 22472 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 22473 __func__, n, ev->hdr.buf_len, datalen); 22474 return QDF_STATUS_E_FAILURE; 22475 } 22476 22477 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 22478 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 22479 phyerr->bufp = &ev->bufp[0]; 22480 phyerr->buf_len = ev->hdr.buf_len; 22481 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 22482 22483 /* 22484 * Advance the buffer pointer to the next PHY error. 22485 * buflen is the length of this payload, so we need to 22486 * advance past the current header _AND_ the payload. 22487 */ 22488 n += sizeof(*ev) + ev->hdr.buf_len; 22489 } 22490 *buf_offset = n; 22491 22492 return QDF_STATUS_SUCCESS; 22493 } 22494 22495 struct wmi_ops tlv_ops = { 22496 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 22497 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 22498 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 22499 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 22500 .send_hidden_ssid_vdev_restart_cmd = 22501 send_hidden_ssid_vdev_restart_cmd_tlv, 22502 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 22503 .send_peer_param_cmd = send_peer_param_cmd_tlv, 22504 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 22505 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 22506 .send_peer_create_cmd = send_peer_create_cmd_tlv, 22507 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 22508 .send_peer_rx_reorder_queue_setup_cmd = 22509 send_peer_rx_reorder_queue_setup_cmd_tlv, 22510 .send_peer_rx_reorder_queue_remove_cmd = 22511 send_peer_rx_reorder_queue_remove_cmd_tlv, 22512 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 22513 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 22514 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 22515 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 22516 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 22517 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 22518 .send_suspend_cmd = send_suspend_cmd_tlv, 22519 .send_resume_cmd = send_resume_cmd_tlv, 22520 #ifdef FEATURE_WLAN_D0WOW 22521 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 22522 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 22523 #endif 22524 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 22525 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 22526 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 22527 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 22528 .send_dbglog_cmd = send_dbglog_cmd_tlv, 22529 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 22530 .send_stats_request_cmd = send_stats_request_cmd_tlv, 22531 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 22532 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 22533 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 22534 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 22535 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 22536 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 22537 .send_scan_start_cmd = send_scan_start_cmd_tlv, 22538 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 22539 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 22540 .send_mgmt_cmd = send_mgmt_cmd_tlv, 22541 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 22542 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 22543 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 22544 .send_set_sta_uapsd_auto_trig_cmd = 22545 send_set_sta_uapsd_auto_trig_cmd_tlv, 22546 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 22547 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 22548 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 22549 #ifdef CONVERGED_P2P_ENABLE 22550 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 22551 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 22552 #endif 22553 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 22554 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 22555 #ifdef WLAN_FEATURE_DSRC 22556 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 22557 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 22558 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 22559 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 22560 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 22561 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 22562 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 22563 .send_ocb_start_timing_advert_cmd = 22564 send_ocb_start_timing_advert_cmd_tlv, 22565 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 22566 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 22567 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 22568 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 22569 #endif 22570 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 22571 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 22572 .send_set_mcc_channel_time_latency_cmd = 22573 send_set_mcc_channel_time_latency_cmd_tlv, 22574 .send_set_mcc_channel_time_quota_cmd = 22575 send_set_mcc_channel_time_quota_cmd_tlv, 22576 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 22577 .send_lro_config_cmd = send_lro_config_cmd_tlv, 22578 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 22579 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 22580 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 22581 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 22582 .send_probe_rsp_tmpl_send_cmd = 22583 send_probe_rsp_tmpl_send_cmd_tlv, 22584 .send_p2p_go_set_beacon_ie_cmd = 22585 send_p2p_go_set_beacon_ie_cmd_tlv, 22586 .send_setup_install_key_cmd = 22587 send_setup_install_key_cmd_tlv, 22588 .send_set_gateway_params_cmd = 22589 send_set_gateway_params_cmd_tlv, 22590 .send_set_rssi_monitoring_cmd = 22591 send_set_rssi_monitoring_cmd_tlv, 22592 .send_scan_probe_setoui_cmd = 22593 send_scan_probe_setoui_cmd_tlv, 22594 .send_reset_passpoint_network_list_cmd = 22595 send_reset_passpoint_network_list_cmd_tlv, 22596 .send_set_passpoint_network_list_cmd = 22597 send_set_passpoint_network_list_cmd_tlv, 22598 .send_roam_scan_offload_rssi_thresh_cmd = 22599 send_roam_scan_offload_rssi_thresh_cmd_tlv, 22600 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 22601 .send_roam_scan_filter_cmd = 22602 send_roam_scan_filter_cmd_tlv, 22603 .send_set_epno_network_list_cmd = 22604 send_set_epno_network_list_cmd_tlv, 22605 #ifdef IPA_OFFLOAD 22606 .send_ipa_offload_control_cmd = 22607 send_ipa_offload_control_cmd_tlv, 22608 #endif 22609 .send_extscan_get_capabilities_cmd = 22610 send_extscan_get_capabilities_cmd_tlv, 22611 .send_extscan_get_cached_results_cmd = 22612 send_extscan_get_cached_results_cmd_tlv, 22613 .send_extscan_stop_change_monitor_cmd = 22614 send_extscan_stop_change_monitor_cmd_tlv, 22615 .send_extscan_start_change_monitor_cmd = 22616 send_extscan_start_change_monitor_cmd_tlv, 22617 .send_extscan_stop_hotlist_monitor_cmd = 22618 send_extscan_stop_hotlist_monitor_cmd_tlv, 22619 .send_stop_extscan_cmd = send_stop_extscan_cmd_tlv, 22620 .send_start_extscan_cmd = send_start_extscan_cmd_tlv, 22621 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 22622 .send_plm_start_cmd = send_plm_start_cmd_tlv, 22623 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 22624 .send_pno_start_cmd = send_pno_start_cmd_tlv, 22625 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 22626 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 22627 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 22628 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 22629 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 22630 .send_congestion_cmd = send_congestion_cmd_tlv, 22631 .send_snr_request_cmd = send_snr_request_cmd_tlv, 22632 .send_snr_cmd = send_snr_cmd_tlv, 22633 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 22634 #ifdef WLAN_PMO_ENABLE 22635 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 22636 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 22637 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 22638 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 22639 .send_multiple_add_clear_mcbc_filter_cmd = 22640 send_multiple_add_clear_mcbc_filter_cmd_tlv, 22641 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 22642 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 22643 .send_process_gtk_offload_getinfo_cmd = 22644 send_process_gtk_offload_getinfo_cmd_tlv, 22645 .send_enable_enhance_multicast_offload_cmd = 22646 send_enable_enhance_multicast_offload_tlv, 22647 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 22648 #ifdef FEATURE_WLAN_RA_FILTERING 22649 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 22650 #endif 22651 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 22652 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 22653 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 22654 .send_lphb_config_tcp_pkt_filter_cmd = 22655 send_lphb_config_tcp_pkt_filter_cmd_tlv, 22656 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22657 .send_lphb_config_udp_pkt_filter_cmd = 22658 send_lphb_config_udp_pkt_filter_cmd_tlv, 22659 .send_enable_disable_packet_filter_cmd = 22660 send_enable_disable_packet_filter_cmd_tlv, 22661 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22662 #endif /* End of WLAN_PMO_ENABLE */ 22663 #ifdef CONFIG_MCL 22664 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22665 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22666 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22667 .send_roam_scan_offload_mode_cmd = 22668 send_roam_scan_offload_mode_cmd_tlv, 22669 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22670 .send_roam_scan_offload_ap_profile_cmd = 22671 send_roam_scan_offload_ap_profile_cmd_tlv, 22672 #endif 22673 #ifdef WLAN_SUPPORT_GREEN_AP 22674 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22675 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22676 .extract_green_ap_egap_status_info = 22677 extract_green_ap_egap_status_info_tlv, 22678 #endif 22679 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22680 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22681 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22682 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22683 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22684 #ifdef WLAN_FEATURE_CIF_CFR 22685 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22686 #endif 22687 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22688 .send_dfs_phyerr_filter_offload_en_cmd = 22689 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22690 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22691 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22692 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22693 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22694 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22695 .send_process_add_periodic_tx_ptrn_cmd = 22696 send_process_add_periodic_tx_ptrn_cmd_tlv, 22697 .send_process_del_periodic_tx_ptrn_cmd = 22698 send_process_del_periodic_tx_ptrn_cmd_tlv, 22699 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22700 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22701 .send_set_app_type2_params_in_fw_cmd = 22702 send_set_app_type2_params_in_fw_cmd_tlv, 22703 .send_set_auto_shutdown_timer_cmd = 22704 send_set_auto_shutdown_timer_cmd_tlv, 22705 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22706 .send_process_dhcpserver_offload_cmd = 22707 send_process_dhcpserver_offload_cmd_tlv, 22708 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22709 .send_process_ch_avoid_update_cmd = 22710 send_process_ch_avoid_update_cmd_tlv, 22711 .send_pdev_set_regdomain_cmd = 22712 send_pdev_set_regdomain_cmd_tlv, 22713 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22714 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22715 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22716 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22717 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22718 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22719 .check_and_update_fw_version = 22720 check_and_update_fw_version_cmd_tlv, 22721 .send_set_base_macaddr_indicate_cmd = 22722 send_set_base_macaddr_indicate_cmd_tlv, 22723 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22724 .send_enable_specific_fw_logs_cmd = 22725 send_enable_specific_fw_logs_cmd_tlv, 22726 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22727 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22728 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22729 #ifdef WLAN_POLICY_MGR_ENABLE 22730 .send_pdev_set_dual_mac_config_cmd = 22731 send_pdev_set_dual_mac_config_cmd_tlv, 22732 #endif 22733 .send_app_type1_params_in_fw_cmd = 22734 send_app_type1_params_in_fw_cmd_tlv, 22735 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22736 .send_process_roam_synch_complete_cmd = 22737 send_process_roam_synch_complete_cmd_tlv, 22738 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22739 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22740 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22741 .send_roam_scan_offload_scan_period_cmd = 22742 send_roam_scan_offload_scan_period_cmd_tlv, 22743 .send_roam_scan_offload_chan_list_cmd = 22744 send_roam_scan_offload_chan_list_cmd_tlv, 22745 .send_roam_scan_offload_rssi_change_cmd = 22746 send_roam_scan_offload_rssi_change_cmd_tlv, 22747 .send_get_buf_extscan_hotlist_cmd = 22748 send_get_buf_extscan_hotlist_cmd_tlv, 22749 .send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv, 22750 .send_adapt_dwelltime_params_cmd = 22751 send_adapt_dwelltime_params_cmd_tlv, 22752 .send_dbs_scan_sel_params_cmd = 22753 send_dbs_scan_sel_params_cmd_tlv, 22754 .init_cmd_send = init_cmd_send_tlv, 22755 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22756 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22757 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22758 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22759 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22760 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22761 .send_vdev_set_custom_aggr_size_cmd = 22762 send_vdev_set_custom_aggr_size_cmd_tlv, 22763 .send_vdev_set_qdepth_thresh_cmd = 22764 send_vdev_set_qdepth_thresh_cmd_tlv, 22765 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22766 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22767 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22768 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22769 .send_smart_ant_set_training_info_cmd = 22770 send_smart_ant_set_training_info_cmd_tlv, 22771 .send_smart_ant_set_node_config_cmd = 22772 send_smart_ant_set_node_config_cmd_tlv, 22773 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22774 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22775 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22776 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22777 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22778 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22779 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22780 .send_periodic_chan_stats_config_cmd = 22781 send_periodic_chan_stats_config_cmd_tlv, 22782 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22783 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22784 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22785 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22786 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22787 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22788 .send_vdev_spectral_configure_cmd = 22789 send_vdev_spectral_configure_cmd_tlv, 22790 .send_vdev_spectral_enable_cmd = 22791 send_vdev_spectral_enable_cmd_tlv, 22792 .send_thermal_mitigation_param_cmd = 22793 send_thermal_mitigation_param_cmd_tlv, 22794 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22795 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22796 .send_process_update_edca_param_cmd = 22797 send_process_update_edca_param_cmd_tlv, 22798 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22799 .send_set_country_cmd = send_set_country_cmd_tlv, 22800 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22801 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22802 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22803 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22804 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22805 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22806 .extract_host_mem_req = extract_host_mem_req_tlv, 22807 .save_service_bitmap = save_service_bitmap_tlv, 22808 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22809 .is_service_enabled = is_service_enabled_tlv, 22810 .save_fw_version = save_fw_version_in_service_ready_tlv, 22811 .ready_extract_init_status = ready_extract_init_status_tlv, 22812 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22813 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22814 .extract_ready_event_params = extract_ready_event_params_tlv, 22815 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22816 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22817 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22818 .extract_tbttoffset_update_params = 22819 extract_tbttoffset_update_params_tlv, 22820 .extract_ext_tbttoffset_update_params = 22821 extract_ext_tbttoffset_update_params_tlv, 22822 .extract_tbttoffset_num_vdevs = 22823 extract_tbttoffset_num_vdevs_tlv, 22824 .extract_ext_tbttoffset_num_vdevs = 22825 extract_ext_tbttoffset_num_vdevs_tlv, 22826 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22827 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22828 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22829 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22830 #ifdef CONVERGED_TDLS_ENABLE 22831 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22832 #endif 22833 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22834 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22835 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22836 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22837 #ifdef CONVERGED_P2P_ENABLE 22838 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22839 .extract_p2p_lo_stop_ev_param = 22840 extract_p2p_lo_stop_ev_param_tlv, 22841 #endif 22842 .extract_offchan_data_tx_compl_param = 22843 extract_offchan_data_tx_compl_param_tlv, 22844 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22845 .extract_all_stats_count = extract_all_stats_counts_tlv, 22846 .extract_pdev_stats = extract_pdev_stats_tlv, 22847 .extract_unit_test = extract_unit_test_tlv, 22848 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22849 .extract_vdev_stats = extract_vdev_stats_tlv, 22850 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22851 .extract_peer_stats = extract_peer_stats_tlv, 22852 .extract_bcn_stats = extract_bcn_stats_tlv, 22853 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22854 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22855 .extract_chan_stats = extract_chan_stats_tlv, 22856 .extract_profile_ctx = extract_profile_ctx_tlv, 22857 .extract_profile_data = extract_profile_data_tlv, 22858 .extract_chan_info_event = extract_chan_info_event_tlv, 22859 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22860 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22861 #ifdef WLAN_FEATURE_DISA 22862 .send_encrypt_decrypt_send_cmd = 22863 send_encrypt_decrypt_send_cmd_tlv, 22864 .extract_encrypt_decrypt_resp_event = 22865 extract_encrypt_decrypt_resp_event_tlv, 22866 #endif 22867 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22868 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22869 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22870 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22871 .send_multiple_vdev_restart_req_cmd = 22872 send_multiple_vdev_restart_req_cmd_tlv, 22873 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22874 .extract_hw_mode_cap_service_ready_ext = 22875 extract_hw_mode_cap_service_ready_ext_tlv, 22876 .extract_mac_phy_cap_service_ready_ext = 22877 extract_mac_phy_cap_service_ready_ext_tlv, 22878 .extract_reg_cap_service_ready_ext = 22879 extract_reg_cap_service_ready_ext_tlv, 22880 .extract_dbr_ring_cap_service_ready_ext = 22881 extract_dbr_ring_cap_service_ready_ext_tlv, 22882 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22883 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22884 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22885 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22886 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22887 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22888 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22889 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22890 .extract_fips_event_data = extract_fips_event_data_tlv, 22891 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22892 .extract_peer_delete_response_event = 22893 extract_peer_delete_response_event_tlv, 22894 .is_management_record = is_management_record_tlv, 22895 .extract_pdev_csa_switch_count_status = 22896 extract_pdev_csa_switch_count_status_tlv, 22897 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22898 .extract_pdev_tpc_config_ev_param = 22899 extract_pdev_tpc_config_ev_param_tlv, 22900 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22901 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22902 .extract_peer_sta_ps_statechange_ev = 22903 extract_peer_sta_ps_statechange_ev_tlv, 22904 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22905 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22906 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22907 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22908 .extract_reg_chan_list_update_event = 22909 extract_reg_chan_list_update_event_tlv, 22910 .extract_chainmask_tables = 22911 extract_chainmask_tables_tlv, 22912 .extract_thermal_stats = extract_thermal_stats_tlv, 22913 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22914 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22915 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22916 #ifdef DFS_COMPONENT_ENABLE 22917 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22918 .extract_dfs_radar_detection_event = 22919 extract_dfs_radar_detection_event_tlv, 22920 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22921 #endif 22922 .convert_pdev_id_host_to_target = 22923 convert_host_pdev_id_to_target_pdev_id_legacy, 22924 .convert_pdev_id_target_to_host = 22925 convert_target_pdev_id_to_host_pdev_id_legacy, 22926 22927 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22928 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22929 .extract_reg_11d_new_country_event = 22930 extract_reg_11d_new_country_event_tlv, 22931 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22932 .send_limit_off_chan_cmd = 22933 send_limit_off_chan_cmd_tlv, 22934 .extract_reg_ch_avoid_event = 22935 extract_reg_ch_avoid_event_tlv, 22936 .send_pdev_caldata_version_check_cmd = 22937 send_pdev_caldata_version_check_cmd_tlv, 22938 .extract_pdev_caldata_version_check_ev_param = 22939 extract_pdev_caldata_version_check_ev_param_tlv, 22940 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22941 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22942 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22943 #if defined(WLAN_FEATURE_FILS_SK) 22944 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22945 #endif 22946 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22947 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22948 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22949 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22950 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22951 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22952 .extract_ndp_ind = extract_ndp_ind_tlv, 22953 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22954 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22955 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22956 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22957 #endif 22958 .send_btm_config = send_btm_config_cmd_tlv, 22959 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22960 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22961 #ifdef WLAN_SUPPORT_FILS 22962 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22963 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22964 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22965 #endif /* WLAN_SUPPORT_FILS */ 22966 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22967 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22968 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22969 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22970 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22971 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22972 .send_bss_color_change_enable_cmd = 22973 send_bss_color_change_enable_cmd_tlv, 22974 .send_obss_color_collision_cfg_cmd = 22975 send_obss_color_collision_cfg_cmd_tlv, 22976 .extract_obss_color_collision_info = 22977 extract_obss_color_collision_info_tlv, 22978 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22979 .extract_single_phyerr = extract_single_phyerr_tlv, 22980 #ifdef QCA_SUPPORT_CP_STATS 22981 .extract_cca_stats = extract_cca_stats_tlv, 22982 #endif 22983 }; 22984 22985 /** 22986 * populate_tlv_event_id() - populates wmi event ids 22987 * 22988 * @param event_ids: Pointer to hold event ids 22989 * Return: None 22990 */ 22991 static void populate_tlv_events_id(uint32_t *event_ids) 22992 { 22993 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22994 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22995 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22996 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22997 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22998 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22999 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 23000 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 23001 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 23002 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 23003 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 23004 event_ids[wmi_service_ready_ext_event_id] = 23005 WMI_SERVICE_READY_EXT_EVENTID; 23006 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 23007 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 23008 event_ids[wmi_vdev_install_key_complete_event_id] = 23009 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 23010 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 23011 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 23012 23013 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 23014 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 23015 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 23016 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 23017 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 23018 event_ids[wmi_peer_estimated_linkspeed_event_id] = 23019 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 23020 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 23021 event_ids[wmi_peer_delete_response_event_id] = 23022 WMI_PEER_DELETE_RESP_EVENTID; 23023 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 23024 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 23025 event_ids[wmi_tbttoffset_update_event_id] = 23026 WMI_TBTTOFFSET_UPDATE_EVENTID; 23027 event_ids[wmi_ext_tbttoffset_update_event_id] = 23028 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 23029 event_ids[wmi_offload_bcn_tx_status_event_id] = 23030 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 23031 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 23032 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 23033 event_ids[wmi_mgmt_tx_completion_event_id] = 23034 WMI_MGMT_TX_COMPLETION_EVENTID; 23035 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 23036 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 23037 event_ids[wmi_tx_delba_complete_event_id] = 23038 WMI_TX_DELBA_COMPLETE_EVENTID; 23039 event_ids[wmi_tx_addba_complete_event_id] = 23040 WMI_TX_ADDBA_COMPLETE_EVENTID; 23041 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 23042 23043 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 23044 23045 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 23046 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 23047 23048 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 23049 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 23050 23051 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 23052 23053 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 23054 event_ids[wmi_p2p_lo_stop_event_id] = 23055 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 23056 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 23057 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 23058 event_ids[wmi_d0_wow_disable_ack_event_id] = 23059 WMI_D0_WOW_DISABLE_ACK_EVENTID; 23060 event_ids[wmi_wow_initial_wakeup_event_id] = 23061 WMI_WOW_INITIAL_WAKEUP_EVENTID; 23062 23063 event_ids[wmi_rtt_meas_report_event_id] = 23064 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 23065 event_ids[wmi_tsf_meas_report_event_id] = 23066 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 23067 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 23068 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 23069 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 23070 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 23071 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 23072 event_ids[wmi_diag_event_id_log_supported_event_id] = 23073 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 23074 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 23075 event_ids[wmi_nlo_scan_complete_event_id] = 23076 WMI_NLO_SCAN_COMPLETE_EVENTID; 23077 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 23078 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 23079 23080 event_ids[wmi_gtk_offload_status_event_id] = 23081 WMI_GTK_OFFLOAD_STATUS_EVENTID; 23082 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 23083 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 23084 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 23085 23086 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 23087 23088 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 23089 23090 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 23091 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 23092 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 23093 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 23094 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 23095 event_ids[wmi_wlan_profile_data_event_id] = 23096 WMI_WLAN_PROFILE_DATA_EVENTID; 23097 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 23098 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 23099 event_ids[wmi_vdev_get_keepalive_event_id] = 23100 WMI_VDEV_GET_KEEPALIVE_EVENTID; 23101 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 23102 23103 event_ids[wmi_diag_container_event_id] = 23104 WMI_DIAG_DATA_CONTAINER_EVENTID; 23105 23106 event_ids[wmi_host_auto_shutdown_event_id] = 23107 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 23108 23109 event_ids[wmi_update_whal_mib_stats_event_id] = 23110 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 23111 23112 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 23113 event_ids[wmi_update_vdev_rate_stats_event_id] = 23114 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 23115 23116 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 23117 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 23118 23119 /** Set OCB Sched Response, deprecated */ 23120 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 23121 23122 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 23123 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 23124 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 23125 23126 /* GPIO Event */ 23127 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 23128 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 23129 23130 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 23131 event_ids[wmi_rfkill_state_change_event_id] = 23132 WMI_RFKILL_STATE_CHANGE_EVENTID; 23133 23134 /* TDLS Event */ 23135 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 23136 23137 event_ids[wmi_batch_scan_enabled_event_id] = 23138 WMI_BATCH_SCAN_ENABLED_EVENTID; 23139 event_ids[wmi_batch_scan_result_event_id] = 23140 WMI_BATCH_SCAN_RESULT_EVENTID; 23141 /* OEM Event */ 23142 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 23143 event_ids[wmi_oem_meas_report_event_id] = 23144 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 23145 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 23146 23147 /* NAN Event */ 23148 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 23149 23150 /* LPI Event */ 23151 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 23152 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 23153 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 23154 23155 /* ExtScan events */ 23156 event_ids[wmi_extscan_start_stop_event_id] = 23157 WMI_EXTSCAN_START_STOP_EVENTID; 23158 event_ids[wmi_extscan_operation_event_id] = 23159 WMI_EXTSCAN_OPERATION_EVENTID; 23160 event_ids[wmi_extscan_table_usage_event_id] = 23161 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 23162 event_ids[wmi_extscan_cached_results_event_id] = 23163 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 23164 event_ids[wmi_extscan_wlan_change_results_event_id] = 23165 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 23166 event_ids[wmi_extscan_hotlist_match_event_id] = 23167 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 23168 event_ids[wmi_extscan_capabilities_event_id] = 23169 WMI_EXTSCAN_CAPABILITIES_EVENTID; 23170 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 23171 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 23172 23173 /* mDNS offload events */ 23174 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 23175 23176 /* SAP Authentication offload events */ 23177 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 23178 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 23179 23180 /** Out-of-context-of-bss (OCB) events */ 23181 event_ids[wmi_ocb_set_config_resp_event_id] = 23182 WMI_OCB_SET_CONFIG_RESP_EVENTID; 23183 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 23184 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 23185 event_ids[wmi_dcc_get_stats_resp_event_id] = 23186 WMI_DCC_GET_STATS_RESP_EVENTID; 23187 event_ids[wmi_dcc_update_ndl_resp_event_id] = 23188 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 23189 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 23190 /* System-On-Chip events */ 23191 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 23192 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 23193 event_ids[wmi_soc_hw_mode_transition_event_id] = 23194 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 23195 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 23196 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 23197 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 23198 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 23199 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 23200 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 23201 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 23202 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23203 event_ids[wmi_peer_sta_ps_statechg_event_id] = 23204 WMI_PEER_STA_PS_STATECHG_EVENTID; 23205 event_ids[wmi_pdev_channel_hopping_event_id] = 23206 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 23207 event_ids[wmi_offchan_data_tx_completion_event] = 23208 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 23209 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 23210 event_ids[wmi_dfs_radar_detection_event_id] = 23211 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 23212 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 23213 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 23214 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 23215 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 23216 event_ids[wmi_service_available_event_id] = 23217 WMI_SERVICE_AVAILABLE_EVENTID; 23218 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 23219 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 23220 /* NDP events */ 23221 event_ids[wmi_ndp_initiator_rsp_event_id] = 23222 WMI_NDP_INITIATOR_RSP_EVENTID; 23223 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 23224 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 23225 event_ids[wmi_ndp_responder_rsp_event_id] = 23226 WMI_NDP_RESPONDER_RSP_EVENTID; 23227 event_ids[wmi_ndp_end_indication_event_id] = 23228 WMI_NDP_END_INDICATION_EVENTID; 23229 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 23230 23231 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 23232 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 23233 event_ids[wmi_pdev_chip_power_stats_event_id] = 23234 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 23235 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 23236 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 23237 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 23238 event_ids[wmi_bpf_capability_info_event_id] = 23239 WMI_BPF_CAPABILIY_INFO_EVENTID; 23240 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 23241 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 23242 event_ids[wmi_report_rx_aggr_failure_event_id] = 23243 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 23244 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 23245 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 23246 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 23247 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 23248 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 23249 event_ids[wmi_pdev_hw_mode_transition_event_id] = 23250 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 23251 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 23252 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 23253 event_ids[wmi_coex_bt_activity_event_id] = 23254 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 23255 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 23256 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 23257 event_ids[wmi_radio_tx_power_level_stats_event_id] = 23258 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 23259 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 23260 event_ids[wmi_dma_buf_release_event_id] = 23261 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 23262 event_ids[wmi_sap_obss_detection_report_event_id] = 23263 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 23264 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 23265 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 23266 event_ids[wmi_obss_color_collision_report_event_id] = 23267 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 23268 event_ids[wmi_pdev_div_rssi_antid_event_id] = 23269 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 23270 } 23271 23272 /** 23273 * populate_tlv_service() - populates wmi services 23274 * 23275 * @param wmi_service: Pointer to hold wmi_service 23276 * Return: None 23277 */ 23278 static void populate_tlv_service(uint32_t *wmi_service) 23279 { 23280 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 23281 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 23282 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 23283 wmi_service[wmi_service_roam_scan_offload] = 23284 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 23285 wmi_service[wmi_service_bcn_miss_offload] = 23286 WMI_SERVICE_BCN_MISS_OFFLOAD; 23287 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 23288 wmi_service[wmi_service_sta_advanced_pwrsave] = 23289 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 23290 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 23291 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 23292 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 23293 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 23294 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 23295 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 23296 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 23297 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 23298 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 23299 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 23300 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 23301 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 23302 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 23303 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 23304 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 23305 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 23306 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 23307 wmi_service[wmi_service_packet_power_save] = 23308 WMI_SERVICE_PACKET_POWER_SAVE; 23309 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 23310 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 23311 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 23312 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 23313 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 23314 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 23315 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 23316 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 23317 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 23318 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 23319 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 23320 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 23321 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 23322 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 23323 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 23324 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 23325 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 23326 wmi_service[wmi_service_mcc_bcn_interval_change] = 23327 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 23328 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 23329 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 23330 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 23331 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 23332 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 23333 wmi_service[wmi_service_lte_ant_share_support] = 23334 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 23335 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 23336 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 23337 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 23338 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 23339 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 23340 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 23341 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 23342 wmi_service[wmi_service_bcn_txrate_override] = 23343 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 23344 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 23345 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 23346 wmi_service[wmi_service_estimate_linkspeed] = 23347 WMI_SERVICE_ESTIMATE_LINKSPEED; 23348 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 23349 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 23350 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 23351 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 23352 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 23353 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 23354 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 23355 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 23356 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 23357 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 23358 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 23359 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 23360 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 23361 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 23362 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 23363 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 23364 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 23365 wmi_service[wmi_service_sap_auth_offload] = 23366 WMI_SERVICE_SAP_AUTH_OFFLOAD; 23367 wmi_service[wmi_service_dual_band_simultaneous_support] = 23368 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 23369 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 23370 wmi_service[wmi_service_ap_arpns_offload] = 23371 WMI_SERVICE_AP_ARPNS_OFFLOAD; 23372 wmi_service[wmi_service_per_band_chainmask_support] = 23373 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 23374 wmi_service[wmi_service_packet_filter_offload] = 23375 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 23376 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 23377 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 23378 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 23379 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 23380 wmi_service[wmi_service_multiple_vdev_restart] = 23381 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 23382 23383 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 23384 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 23385 wmi_service[wmi_service_smart_antenna_sw_support] = 23386 WMI_SERVICE_UNAVAILABLE; 23387 wmi_service[wmi_service_smart_antenna_hw_support] = 23388 WMI_SERVICE_UNAVAILABLE; 23389 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 23390 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 23391 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 23392 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 23393 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 23394 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 23395 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 23396 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 23397 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 23398 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 23399 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 23400 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 23401 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 23402 wmi_service[wmi_service_periodic_chan_stat_support] = 23403 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 23404 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 23405 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 23406 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 23407 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 23408 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 23409 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23410 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 23411 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 23412 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 23413 wmi_service[wmi_service_unified_wow_capability] = 23414 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 23415 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23416 wmi_service[wmi_service_bpf_offload] = WMI_SERVICE_BPF_OFFLOAD; 23417 wmi_service[wmi_service_sync_delete_cmds] = 23418 WMI_SERVICE_SYNC_DELETE_CMDS; 23419 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 23420 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 23421 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 23422 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 23423 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 23424 wmi_service[wmi_service_deprecated_replace] = 23425 WMI_SERVICE_DEPRECATED_REPLACE; 23426 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 23427 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 23428 wmi_service[wmi_service_enhanced_mcast_filter] = 23429 WMI_SERVICE_ENHANCED_MCAST_FILTER; 23430 wmi_service[wmi_service_half_rate_quarter_rate_support] = 23431 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 23432 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 23433 wmi_service[wmi_service_p2p_listen_offload_support] = 23434 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 23435 wmi_service[wmi_service_mark_first_wakeup_packet] = 23436 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 23437 wmi_service[wmi_service_multiple_mcast_filter_set] = 23438 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 23439 wmi_service[wmi_service_host_managed_rx_reorder] = 23440 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 23441 wmi_service[wmi_service_flash_rdwr_support] = 23442 WMI_SERVICE_FLASH_RDWR_SUPPORT; 23443 wmi_service[wmi_service_wlan_stats_report] = 23444 WMI_SERVICE_WLAN_STATS_REPORT; 23445 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 23446 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 23447 wmi_service[wmi_service_dfs_phyerr_offload] = 23448 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 23449 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 23450 wmi_service[wmi_service_fw_mem_dump_support] = 23451 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 23452 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 23453 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 23454 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 23455 wmi_service[wmi_service_hw_data_filtering] = 23456 WMI_SERVICE_HW_DATA_FILTERING; 23457 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 23458 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 23459 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 23460 wmi_service[wmi_service_extended_nss_support] = 23461 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 23462 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 23463 wmi_service[wmi_service_bcn_offload_start_stop_support] = 23464 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 23465 wmi_service[wmi_service_offchan_data_tid_support] = 23466 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 23467 wmi_service[wmi_service_support_dma] = 23468 WMI_SERVICE_SUPPORT_DIRECT_DMA; 23469 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 23470 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 23471 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 23472 wmi_service[wmi_service_11k_neighbour_report_support] = 23473 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 23474 wmi_service[wmi_service_ap_obss_detection_offload] = 23475 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 23476 wmi_service[wmi_service_bss_color_offload] = 23477 WMI_SERVICE_BSS_COLOR_OFFLOAD; 23478 wmi_service[wmi_service_gmac_offload_support] = 23479 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 23480 23481 } 23482 23483 #ifndef CONFIG_MCL 23484 23485 /** 23486 * populate_pdev_param_tlv() - populates pdev params 23487 * 23488 * @param pdev_param: Pointer to hold pdev params 23489 * Return: None 23490 */ 23491 static void populate_pdev_param_tlv(uint32_t *pdev_param) 23492 { 23493 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 23494 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 23495 pdev_param[wmi_pdev_param_txpower_limit2g] = 23496 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 23497 pdev_param[wmi_pdev_param_txpower_limit5g] = 23498 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 23499 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 23500 pdev_param[wmi_pdev_param_beacon_gen_mode] = 23501 WMI_PDEV_PARAM_BEACON_GEN_MODE; 23502 pdev_param[wmi_pdev_param_beacon_tx_mode] = 23503 WMI_PDEV_PARAM_BEACON_TX_MODE; 23504 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 23505 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 23506 pdev_param[wmi_pdev_param_protection_mode] = 23507 WMI_PDEV_PARAM_PROTECTION_MODE; 23508 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 23509 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 23510 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 23511 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 23512 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 23513 pdev_param[wmi_pdev_param_sta_kickout_th] = 23514 WMI_PDEV_PARAM_STA_KICKOUT_TH; 23515 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 23516 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 23517 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 23518 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 23519 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 23520 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 23521 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 23522 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 23523 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 23524 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 23525 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 23526 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 23527 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 23528 pdev_param[wmi_pdev_param_ltr_sleep_override] = 23529 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 23530 pdev_param[wmi_pdev_param_ltr_rx_override] = 23531 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 23532 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 23533 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 23534 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 23535 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 23536 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 23537 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 23538 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 23539 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 23540 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 23541 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 23542 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 23543 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 23544 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 23545 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 23546 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 23547 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 23548 pdev_param[wmi_pdev_param_peer_stats_update_period] = 23549 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 23550 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 23551 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 23552 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 23553 pdev_param[wmi_pdev_param_arp_ac_override] = 23554 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 23555 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 23556 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 23557 pdev_param[wmi_pdev_param_ani_poll_period] = 23558 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 23559 pdev_param[wmi_pdev_param_ani_listen_period] = 23560 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 23561 pdev_param[wmi_pdev_param_ani_ofdm_level] = 23562 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 23563 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 23564 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 23565 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 23566 pdev_param[wmi_pdev_param_idle_ps_config] = 23567 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 23568 pdev_param[wmi_pdev_param_power_gating_sleep] = 23569 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 23570 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 23571 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 23572 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 23573 pdev_param[wmi_pdev_param_hw_rfkill_config] = 23574 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 23575 pdev_param[wmi_pdev_param_low_power_rf_enable] = 23576 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 23577 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 23578 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 23579 pdev_param[wmi_pdev_param_power_collapse_enable] = 23580 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 23581 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 23582 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 23583 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 23584 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 23585 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 23586 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 23587 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 23588 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 23589 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 23590 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 23591 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 23592 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 23593 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 23594 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 23595 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 23596 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 23597 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 23598 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 23599 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 23600 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 23601 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 23602 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 23603 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 23604 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 23605 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 23606 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 23607 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 23608 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 23609 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 23610 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 23611 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 23612 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 23613 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 23614 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 23615 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 23616 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 23617 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 23618 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 23619 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 23620 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 23621 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 23622 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 23623 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23624 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23625 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23626 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23627 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23628 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23629 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23630 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23631 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23632 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23633 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23634 WMI_PDEV_PARAM_PROXY_STA_MODE; 23635 pdev_param[wmi_pdev_param_mu_group_policy] = 23636 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23637 pdev_param[wmi_pdev_param_noise_detection] = 23638 WMI_PDEV_PARAM_NOISE_DETECTION; 23639 pdev_param[wmi_pdev_param_noise_threshold] = 23640 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23641 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23642 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23643 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23644 pdev_param[wmi_pdev_param_atf_strict_sch] = 23645 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23646 pdev_param[wmi_pdev_param_atf_sched_duration] = 23647 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23648 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23649 pdev_param[wmi_pdev_param_sensitivity_level] = 23650 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23651 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23652 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23653 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23654 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23655 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23656 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23657 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23658 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23659 pdev_param[wmi_pdev_param_cca_threshold] = 23660 WMI_PDEV_PARAM_CCA_THRESHOLD; 23661 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23662 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23663 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23664 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23665 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23666 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23667 pdev_param[wmi_pdev_param_arp_srcaddr] = 23668 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23669 pdev_param[wmi_pdev_param_arp_dstaddr] = 23670 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23671 pdev_param[wmi_pdev_param_txpower_decr_db] = 23672 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23673 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23674 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23675 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23676 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23677 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23678 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23679 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23680 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23681 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23682 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23683 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23684 WMI_UNAVAILABLE_PARAM; 23685 pdev_param[wmi_pdev_param_igmpmld_override] = WMI_UNAVAILABLE_PARAM; 23686 pdev_param[wmi_pdev_param_igmpmld_tid] = WMI_UNAVAILABLE_PARAM; 23687 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23688 pdev_param[wmi_pdev_param_block_interbss] = 23689 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23690 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23691 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23692 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23693 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23694 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23695 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23696 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23697 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23698 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23699 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23700 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23701 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23702 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23703 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23704 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23705 pdev_param[wmi_pdev_param_igmpmld_ac_override] = 23706 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23707 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23708 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23709 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23710 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23711 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23712 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23713 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23714 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23715 pdev_param[wmi_pdev_param_fast_channel_reset] = 23716 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23717 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23718 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23719 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23720 } 23721 23722 /** 23723 * populate_vdev_param_tlv() - populates vdev params 23724 * 23725 * @param vdev_param: Pointer to hold vdev params 23726 * Return: None 23727 */ 23728 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23729 { 23730 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23731 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23732 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23733 vdev_param[wmi_vdev_param_beacon_interval] = 23734 WMI_VDEV_PARAM_BEACON_INTERVAL; 23735 vdev_param[wmi_vdev_param_listen_interval] = 23736 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23737 vdev_param[wmi_vdev_param_multicast_rate] = 23738 WMI_VDEV_PARAM_MULTICAST_RATE; 23739 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23740 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23741 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23742 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23743 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23744 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23745 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23746 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23747 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23748 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23749 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23750 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23751 vdev_param[wmi_vdev_param_bmiss_count_max] = 23752 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23753 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23754 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23755 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23756 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23757 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23758 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23759 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23760 vdev_param[wmi_vdev_param_disable_htprotection] = 23761 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23762 vdev_param[wmi_vdev_param_sta_quickkickout] = 23763 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23764 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23765 vdev_param[wmi_vdev_param_protection_mode] = 23766 WMI_VDEV_PARAM_PROTECTION_MODE; 23767 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23768 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23769 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23770 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23771 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23772 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23773 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23774 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23775 vdev_param[wmi_vdev_param_bcast_data_rate] = 23776 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23777 vdev_param[wmi_vdev_param_mcast_data_rate] = 23778 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23779 vdev_param[wmi_vdev_param_mcast_indicate] = 23780 WMI_VDEV_PARAM_MCAST_INDICATE; 23781 vdev_param[wmi_vdev_param_dhcp_indicate] = 23782 WMI_VDEV_PARAM_DHCP_INDICATE; 23783 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23784 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23785 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23786 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23787 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23788 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23789 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23790 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23791 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23792 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23793 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23794 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23795 vdev_param[wmi_vdev_param_packet_powersave] = 23796 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23797 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23798 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23799 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23800 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23801 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23802 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23803 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23804 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23805 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23806 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23807 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23808 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23809 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23810 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23811 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23812 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23813 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23814 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23815 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23816 vdev_param[wmi_vdev_param_roam_fw_offload] = 23817 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23818 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23819 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23820 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23821 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23822 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23823 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23824 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23825 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23826 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23827 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23828 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23829 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23830 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23831 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23832 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23833 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23834 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23835 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23836 vdev_param[wmi_vdev_param_inactivity_cnt] = 23837 WMI_VDEV_PARAM_INACTIVITY_CNT; 23838 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23839 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23840 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23841 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23842 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23843 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23844 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23845 vdev_param[wmi_vdev_param_rx_leak_window] = 23846 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23847 vdev_param[wmi_vdev_param_stats_avg_factor] = 23848 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23849 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23850 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23851 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23852 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23853 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23854 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23855 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23856 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23857 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23858 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23859 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23860 WMI_VDEV_PARAM_HE_RANGE_EXT; 23861 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23862 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23863 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23864 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23865 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23866 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23867 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23868 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23869 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23870 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23871 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23872 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23873 vdev_param[wmi_vdev_param_rc_num_retries] = 23874 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23875 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23876 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23877 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23878 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23879 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23880 vdev_param[wmi_vdev_param_vht80_ratemask] = 23881 WMI_VDEV_PARAM_VHT80_RATEMASK; 23882 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23883 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23884 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23885 vdev_param[wmi_vdev_param_set_he_ltf] = 23886 WMI_VDEV_PARAM_HE_LTF; 23887 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23888 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23889 vdev_param[wmi_vdev_param_set_ba_mode] = 23890 WMI_VDEV_PARAM_BA_MODE; 23891 vdev_param[wmi_vdev_param_capabilities] = 23892 WMI_VDEV_PARAM_CAPABILITIES; 23893 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 23894 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 23895 } 23896 #endif 23897 23898 /** 23899 * populate_target_defines_tlv() - Populate target defines and params 23900 * @wmi_handle: pointer to wmi handle 23901 * 23902 * Return: None 23903 */ 23904 #ifndef CONFIG_MCL 23905 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23906 { 23907 populate_pdev_param_tlv(wmi_handle->pdev_param); 23908 populate_vdev_param_tlv(wmi_handle->vdev_param); 23909 } 23910 #else 23911 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23912 { } 23913 #endif 23914 23915 /** 23916 * wmi_ocb_ut_attach() - Attach OCB test framework 23917 * @wmi_handle: wmi handle 23918 * 23919 * Return: None 23920 */ 23921 #ifdef WLAN_OCB_UT 23922 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23923 #else 23924 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23925 { 23926 return; 23927 } 23928 #endif 23929 23930 #ifdef WLAN_SUPPORT_TWT 23931 void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle); 23932 #else 23933 static void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle) 23934 { 23935 return; 23936 } 23937 #endif 23938 /** 23939 * wmi_tlv_attach() - Attach TLV APIs 23940 * 23941 * Return: None 23942 */ 23943 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23944 { 23945 wmi_handle->ops = &tlv_ops; 23946 wmi_ocb_ut_attach(wmi_handle); 23947 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23948 #ifdef WMI_INTERFACE_EVENT_LOGGING 23949 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23950 wmi_handle->log_info.buf_offset_command = 8; 23951 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23952 wmi_handle->log_info.buf_offset_event = 4; 23953 #endif 23954 populate_tlv_events_id(wmi_handle->wmi_events); 23955 populate_tlv_service(wmi_handle->services); 23956 populate_target_defines_tlv(wmi_handle); 23957 wmi_twt_attach_tlv(wmi_handle); 23958 } 23959 qdf_export_symbol(wmi_tlv_attach); 23960 23961 /** 23962 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23963 * 23964 * Return: None 23965 */ 23966 void wmi_tlv_init(void) 23967 { 23968 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23969 } 23970