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 #ifdef FEATURE_WLAN_APF 28 #include "wmi_unified_apf_tlv.h" 29 #endif 30 #ifdef CONVERGED_P2P_ENABLE 31 #include "wlan_p2p_public_struct.h" 32 #endif 33 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 34 #include "wlan_pmo_hw_filter_public_struct.h" 35 #endif 36 #include <wlan_utility.h> 37 #ifdef WLAN_SUPPORT_GREEN_AP 38 #include "wlan_green_ap_api.h" 39 #endif 40 41 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 42 #include "nan_public_structs.h" 43 #endif 44 #include "wmi_unified_twt_api.h" 45 46 #ifdef WLAN_POLICY_MGR_ENABLE 47 #include "wlan_policy_mgr_public_struct.h" 48 #endif 49 50 /* HTC service ids for WMI for multi-radio */ 51 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 52 WMI_CONTROL_SVC_WMAC1, 53 WMI_CONTROL_SVC_WMAC2}; 54 55 /** 56 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 57 * host to target defines. 58 * @param pdev_id: host pdev_id to be converted. 59 * Return: target pdev_id after conversion. 60 */ 61 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 62 { 63 switch (pdev_id) { 64 case WMI_HOST_PDEV_ID_SOC: 65 return WMI_PDEV_ID_SOC; 66 case WMI_HOST_PDEV_ID_0: 67 return WMI_PDEV_ID_1ST; 68 case WMI_HOST_PDEV_ID_1: 69 return WMI_PDEV_ID_2ND; 70 case WMI_HOST_PDEV_ID_2: 71 return WMI_PDEV_ID_3RD; 72 } 73 74 QDF_ASSERT(0); 75 76 return WMI_PDEV_ID_SOC; 77 } 78 79 /** 80 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 81 * target to host defines. 82 * @param pdev_id: target pdev_id to be converted. 83 * Return: host pdev_id after conversion. 84 */ 85 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 86 { 87 switch (pdev_id) { 88 case WMI_PDEV_ID_SOC: 89 return WMI_HOST_PDEV_ID_SOC; 90 case WMI_PDEV_ID_1ST: 91 return WMI_HOST_PDEV_ID_0; 92 case WMI_PDEV_ID_2ND: 93 return WMI_HOST_PDEV_ID_1; 94 case WMI_PDEV_ID_3RD: 95 return WMI_HOST_PDEV_ID_2; 96 } 97 98 QDF_ASSERT(0); 99 100 return WMI_HOST_PDEV_ID_SOC; 101 } 102 103 /** 104 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 105 * 106 * Return None. 107 */ 108 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 109 { 110 wmi_handle->ops->convert_pdev_id_host_to_target = 111 convert_host_pdev_id_to_target_pdev_id; 112 wmi_handle->ops->convert_pdev_id_target_to_host = 113 convert_target_pdev_id_to_host_pdev_id; 114 } 115 116 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 117 * buffer. 118 * @wmi_handle: pointer to wmi_handle 119 * @cmd: pointer target vdev create command buffer 120 * @param: pointer host params for vdev create 121 * 122 * Return: None 123 */ 124 #ifdef CONFIG_MCL 125 static inline void copy_vdev_create_pdev_id( 126 struct wmi_unified *wmi_handle, 127 wmi_vdev_create_cmd_fixed_param * cmd, 128 struct vdev_create_params *param) 129 { 130 cmd->pdev_id = WMI_PDEV_ID_SOC; 131 } 132 #else 133 static inline void copy_vdev_create_pdev_id( 134 struct wmi_unified *wmi_handle, 135 wmi_vdev_create_cmd_fixed_param * cmd, 136 struct vdev_create_params *param) 137 { 138 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 139 param->pdev_id); 140 } 141 #endif 142 143 /** 144 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 145 * @wmi_handle: wmi handle 146 * @param: pointer to hold vdev create parameter 147 * @macaddr: vdev mac address 148 * 149 * Return: QDF_STATUS_SUCCESS for success or error code 150 */ 151 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 152 uint8_t macaddr[IEEE80211_ADDR_LEN], 153 struct vdev_create_params *param) 154 { 155 wmi_vdev_create_cmd_fixed_param *cmd; 156 wmi_buf_t buf; 157 int32_t len = sizeof(*cmd); 158 QDF_STATUS ret; 159 int num_bands = 2; 160 uint8_t *buf_ptr; 161 wmi_vdev_txrx_streams *txrx_streams; 162 163 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 164 buf = wmi_buf_alloc(wmi_handle, len); 165 if (!buf) { 166 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 167 return QDF_STATUS_E_NOMEM; 168 } 169 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 170 WMITLV_SET_HDR(&cmd->tlv_header, 171 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 172 WMITLV_GET_STRUCT_TLVLEN 173 (wmi_vdev_create_cmd_fixed_param)); 174 cmd->vdev_id = param->if_id; 175 cmd->vdev_type = param->type; 176 cmd->vdev_subtype = param->subtype; 177 cmd->num_cfg_txrx_streams = num_bands; 178 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 179 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 180 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 181 __func__, param->if_id, cmd->pdev_id, 182 macaddr[0], macaddr[1], macaddr[2], 183 macaddr[3], macaddr[4], macaddr[5]); 184 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 185 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 186 (num_bands * sizeof(wmi_vdev_txrx_streams))); 187 buf_ptr += WMI_TLV_HDR_SIZE; 188 189 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 190 param->type, param->subtype, 191 param->nss_2g, param->nss_5g); 192 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 193 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 194 txrx_streams->supported_tx_streams = param->nss_2g; 195 txrx_streams->supported_rx_streams = param->nss_2g; 196 WMITLV_SET_HDR(&txrx_streams->tlv_header, 197 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 198 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 199 200 txrx_streams++; 201 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 202 txrx_streams->supported_tx_streams = param->nss_5g; 203 txrx_streams->supported_rx_streams = param->nss_5g; 204 WMITLV_SET_HDR(&txrx_streams->tlv_header, 205 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 206 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 207 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 208 if (QDF_IS_STATUS_ERROR(ret)) { 209 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 210 wmi_buf_free(buf); 211 } 212 213 return ret; 214 } 215 216 /** 217 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 218 * @wmi_handle: wmi handle 219 * @if_id: vdev id 220 * 221 * Return: QDF_STATUS_SUCCESS for success or error code 222 */ 223 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 224 uint8_t if_id) 225 { 226 wmi_vdev_delete_cmd_fixed_param *cmd; 227 wmi_buf_t buf; 228 QDF_STATUS ret; 229 230 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 231 if (!buf) { 232 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 233 return QDF_STATUS_E_NOMEM; 234 } 235 236 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 237 WMITLV_SET_HDR(&cmd->tlv_header, 238 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 239 WMITLV_GET_STRUCT_TLVLEN 240 (wmi_vdev_delete_cmd_fixed_param)); 241 cmd->vdev_id = if_id; 242 ret = wmi_unified_cmd_send(wmi_handle, buf, 243 sizeof(wmi_vdev_delete_cmd_fixed_param), 244 WMI_VDEV_DELETE_CMDID); 245 if (QDF_IS_STATUS_ERROR(ret)) { 246 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 247 wmi_buf_free(buf); 248 } 249 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 250 251 return ret; 252 } 253 254 /** 255 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 256 * @wmi: wmi handle 257 * @vdev_id: vdev id 258 * 259 * Return: QDF_STATUS_SUCCESS for success or erro code 260 */ 261 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 262 uint8_t vdev_id) 263 { 264 wmi_vdev_stop_cmd_fixed_param *cmd; 265 wmi_buf_t buf; 266 int32_t len = sizeof(*cmd); 267 268 buf = wmi_buf_alloc(wmi, len); 269 if (!buf) { 270 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 271 return QDF_STATUS_E_NOMEM; 272 } 273 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 274 WMITLV_SET_HDR(&cmd->tlv_header, 275 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 276 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 277 cmd->vdev_id = vdev_id; 278 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 279 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 280 wmi_buf_free(buf); 281 return QDF_STATUS_E_FAILURE; 282 } 283 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 284 285 return 0; 286 } 287 288 /** 289 * send_vdev_down_cmd_tlv() - send vdev down command to fw 290 * @wmi: wmi handle 291 * @vdev_id: vdev id 292 * 293 * Return: QDF_STATUS_SUCCESS for success or error code 294 */ 295 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 296 { 297 wmi_vdev_down_cmd_fixed_param *cmd; 298 wmi_buf_t buf; 299 int32_t len = sizeof(*cmd); 300 301 buf = wmi_buf_alloc(wmi, len); 302 if (!buf) { 303 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 304 return QDF_STATUS_E_NOMEM; 305 } 306 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 307 WMITLV_SET_HDR(&cmd->tlv_header, 308 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 309 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 310 cmd->vdev_id = vdev_id; 311 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 312 WMI_LOGP("%s: Failed to send vdev down", __func__); 313 wmi_buf_free(buf); 314 return QDF_STATUS_E_FAILURE; 315 } 316 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 317 318 return 0; 319 } 320 321 #ifdef CONFIG_MCL 322 static inline void copy_channel_info( 323 wmi_vdev_start_request_cmd_fixed_param * cmd, 324 wmi_channel *chan, 325 struct vdev_start_params *req) 326 { 327 chan->mhz = req->chan_freq; 328 329 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 330 331 chan->band_center_freq1 = req->band_center_freq1; 332 chan->band_center_freq2 = req->band_center_freq2; 333 334 if (req->is_half_rate) 335 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 336 else if (req->is_quarter_rate) 337 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 338 339 if (req->is_dfs && req->flag_dfs) { 340 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 341 cmd->disable_hw_ack = req->dis_hw_ack; 342 } 343 344 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 345 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 346 347 } 348 #else 349 static inline void copy_channel_info( 350 wmi_vdev_start_request_cmd_fixed_param * cmd, 351 wmi_channel *chan, 352 struct vdev_start_params *req) 353 { 354 chan->mhz = req->channel.mhz; 355 356 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 357 358 chan->band_center_freq1 = req->channel.cfreq1; 359 chan->band_center_freq2 = req->channel.cfreq2; 360 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 361 362 if (req->channel.half_rate) 363 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 364 else if (req->channel.quarter_rate) 365 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 366 367 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 368 369 if (req->channel.dfs_set) { 370 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 371 cmd->disable_hw_ack = req->disable_hw_ack; 372 } 373 374 if (req->channel.dfs_set_cfreq2) 375 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 376 377 /* According to firmware both reg power and max tx power 378 * on set channel power is used and set it to max reg 379 * power from regulatory. 380 */ 381 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 382 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 383 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 384 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 385 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 386 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 387 388 } 389 #endif 390 /** 391 * send_vdev_start_cmd_tlv() - send vdev start request to fw 392 * @wmi_handle: wmi handle 393 * @req: vdev start params 394 * 395 * Return: QDF status 396 */ 397 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 398 struct vdev_start_params *req) 399 { 400 wmi_vdev_start_request_cmd_fixed_param *cmd; 401 wmi_buf_t buf; 402 wmi_channel *chan; 403 int32_t len, ret; 404 uint8_t *buf_ptr; 405 406 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 407 buf = wmi_buf_alloc(wmi_handle, len); 408 if (!buf) { 409 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 410 return QDF_STATUS_E_NOMEM; 411 } 412 buf_ptr = (uint8_t *) wmi_buf_data(buf); 413 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 414 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 415 WMITLV_SET_HDR(&cmd->tlv_header, 416 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 417 WMITLV_GET_STRUCT_TLVLEN 418 (wmi_vdev_start_request_cmd_fixed_param)); 419 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 420 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 421 cmd->vdev_id = req->vdev_id; 422 423 /* Fill channel info */ 424 copy_channel_info(cmd, chan, req); 425 426 cmd->beacon_interval = req->beacon_intval; 427 cmd->dtim_period = req->dtim_period; 428 429 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 430 if (req->bcn_tx_rate_code) 431 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 432 433 if (!req->is_restart) { 434 cmd->beacon_interval = req->beacon_intval; 435 cmd->dtim_period = req->dtim_period; 436 437 /* Copy the SSID */ 438 if (req->ssid.length) { 439 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 440 cmd->ssid.ssid_len = req->ssid.length; 441 else 442 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 443 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 444 cmd->ssid.ssid_len); 445 } 446 447 if (req->hidden_ssid) 448 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 449 450 if (req->pmf_enabled) 451 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 452 } 453 454 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 455 cmd->num_noa_descriptors = req->num_noa_descriptors; 456 cmd->preferred_rx_streams = req->preferred_rx_streams; 457 cmd->preferred_tx_streams = req->preferred_tx_streams; 458 cmd->cac_duration_ms = req->cac_duration_ms; 459 cmd->regdomain = req->regdomain; 460 cmd->he_ops = req->he_ops; 461 462 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 463 sizeof(wmi_channel)); 464 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 465 cmd->num_noa_descriptors * 466 sizeof(wmi_p2p_noa_descriptor)); 467 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 468 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 469 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 470 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 471 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 472 chan->mhz, req->chan_mode, chan->info, 473 req->is_dfs, req->beacon_intval, cmd->dtim_period, 474 chan->band_center_freq1, chan->band_center_freq2, 475 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 476 req->preferred_tx_streams, req->preferred_rx_streams, 477 req->ldpc_rx_enabled, req->cac_duration_ms, 478 req->regdomain, req->he_ops, 479 req->dis_hw_ack); 480 481 if (req->is_restart) 482 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 483 WMI_VDEV_RESTART_REQUEST_CMDID); 484 else 485 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 486 WMI_VDEV_START_REQUEST_CMDID); 487 if (ret) { 488 WMI_LOGP("%s: Failed to send vdev start command", __func__); 489 wmi_buf_free(buf); 490 return QDF_STATUS_E_FAILURE; 491 } 492 493 return QDF_STATUS_SUCCESS; 494 } 495 496 /** 497 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 498 * @wmi_handle: wmi handle 499 * @restart_params: vdev restart params 500 * 501 * Return: QDF_STATUS_SUCCESS for success or error code 502 */ 503 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 504 struct hidden_ssid_vdev_restart_params *restart_params) 505 { 506 wmi_vdev_start_request_cmd_fixed_param *cmd; 507 wmi_buf_t buf; 508 wmi_channel *chan; 509 int32_t len; 510 uint8_t *buf_ptr; 511 QDF_STATUS ret = 0; 512 513 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 514 buf = wmi_buf_alloc(wmi_handle, len); 515 if (!buf) { 516 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 517 return QDF_STATUS_E_NOMEM; 518 } 519 buf_ptr = (uint8_t *) wmi_buf_data(buf); 520 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 521 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 522 523 WMITLV_SET_HDR(&cmd->tlv_header, 524 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 525 WMITLV_GET_STRUCT_TLVLEN 526 (wmi_vdev_start_request_cmd_fixed_param)); 527 528 WMITLV_SET_HDR(&chan->tlv_header, 529 WMITLV_TAG_STRUC_wmi_channel, 530 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 531 532 cmd->vdev_id = restart_params->session_id; 533 cmd->ssid.ssid_len = restart_params->ssid_len; 534 qdf_mem_copy(cmd->ssid.ssid, 535 restart_params->ssid, 536 cmd->ssid.ssid_len); 537 cmd->flags = restart_params->flags; 538 cmd->requestor_id = restart_params->requestor_id; 539 cmd->disable_hw_ack = restart_params->disable_hw_ack; 540 541 chan->mhz = restart_params->mhz; 542 chan->band_center_freq1 = 543 restart_params->band_center_freq1; 544 chan->band_center_freq2 = 545 restart_params->band_center_freq2; 546 chan->info = restart_params->info; 547 chan->reg_info_1 = restart_params->reg_info_1; 548 chan->reg_info_2 = restart_params->reg_info_2; 549 550 cmd->num_noa_descriptors = 0; 551 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 552 sizeof(wmi_channel)); 553 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 554 cmd->num_noa_descriptors * 555 sizeof(wmi_p2p_noa_descriptor)); 556 557 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 558 WMI_VDEV_RESTART_REQUEST_CMDID); 559 if (QDF_IS_STATUS_ERROR(ret)) { 560 wmi_buf_free(buf); 561 return QDF_STATUS_E_FAILURE; 562 } 563 return QDF_STATUS_SUCCESS; 564 } 565 566 567 /** 568 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 569 * @wmi: wmi handle 570 * @peer_addr: peer mac address 571 * @param: pointer to hold peer flush tid parameter 572 * 573 * Return: 0 for success or error code 574 */ 575 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 576 uint8_t peer_addr[IEEE80211_ADDR_LEN], 577 struct peer_flush_params *param) 578 { 579 wmi_peer_flush_tids_cmd_fixed_param *cmd; 580 wmi_buf_t buf; 581 int32_t len = sizeof(*cmd); 582 583 buf = wmi_buf_alloc(wmi, len); 584 if (!buf) { 585 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 586 return QDF_STATUS_E_NOMEM; 587 } 588 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 589 WMITLV_SET_HDR(&cmd->tlv_header, 590 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 591 WMITLV_GET_STRUCT_TLVLEN 592 (wmi_peer_flush_tids_cmd_fixed_param)); 593 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 594 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 595 cmd->vdev_id = param->vdev_id; 596 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 597 peer_addr, param->vdev_id, 598 param->peer_tid_bitmap); 599 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 600 WMI_LOGP("%s: Failed to send flush tid command", __func__); 601 wmi_buf_free(buf); 602 return QDF_STATUS_E_FAILURE; 603 } 604 605 return 0; 606 } 607 608 /** 609 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 610 * @wmi: wmi handle 611 * @peer_addr: peer mac addr 612 * @vdev_id: vdev id 613 * 614 * Return: QDF_STATUS_SUCCESS for success or error code 615 */ 616 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 617 uint8_t peer_addr[IEEE80211_ADDR_LEN], 618 uint8_t vdev_id) 619 { 620 wmi_peer_delete_cmd_fixed_param *cmd; 621 wmi_buf_t buf; 622 int32_t len = sizeof(*cmd); 623 buf = wmi_buf_alloc(wmi, len); 624 if (!buf) { 625 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 626 return QDF_STATUS_E_NOMEM; 627 } 628 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 629 WMITLV_SET_HDR(&cmd->tlv_header, 630 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 631 WMITLV_GET_STRUCT_TLVLEN 632 (wmi_peer_delete_cmd_fixed_param)); 633 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 634 cmd->vdev_id = vdev_id; 635 636 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 637 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 638 WMI_LOGP("%s: Failed to send peer delete command", __func__); 639 wmi_buf_free(buf); 640 return QDF_STATUS_E_FAILURE; 641 } 642 643 return 0; 644 } 645 646 /** 647 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 648 * to target id. 649 * @targ_paramid: Target parameter id to hold the result. 650 * @peer_param_id: host param id. 651 * 652 * Return: QDF_STATUS_SUCCESS for success 653 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 654 */ 655 #ifdef CONFIG_MCL 656 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 657 uint32_t *targ_paramid, 658 uint32_t peer_param_id) 659 { 660 *targ_paramid = peer_param_id; 661 return QDF_STATUS_SUCCESS; 662 } 663 #else 664 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 665 uint32_t *targ_paramid, 666 uint32_t peer_param_id) 667 { 668 switch (peer_param_id) { 669 case WMI_HOST_PEER_MIMO_PS_STATE: 670 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 671 break; 672 case WMI_HOST_PEER_AMPDU: 673 *targ_paramid = WMI_PEER_AMPDU; 674 break; 675 case WMI_HOST_PEER_AUTHORIZE: 676 *targ_paramid = WMI_PEER_AUTHORIZE; 677 break; 678 case WMI_HOST_PEER_CHWIDTH: 679 *targ_paramid = WMI_PEER_CHWIDTH; 680 break; 681 case WMI_HOST_PEER_NSS: 682 *targ_paramid = WMI_PEER_NSS; 683 break; 684 case WMI_HOST_PEER_USE_4ADDR: 685 *targ_paramid = WMI_PEER_USE_4ADDR; 686 break; 687 case WMI_HOST_PEER_MEMBERSHIP: 688 *targ_paramid = WMI_PEER_MEMBERSHIP; 689 break; 690 case WMI_HOST_PEER_USERPOS: 691 *targ_paramid = WMI_PEER_USERPOS; 692 break; 693 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 694 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 695 break; 696 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 697 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 698 break; 699 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 700 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 701 break; 702 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 703 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 704 break; 705 case WMI_HOST_PEER_PHYMODE: 706 *targ_paramid = WMI_PEER_PHYMODE; 707 break; 708 case WMI_HOST_PEER_USE_FIXED_PWR: 709 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 710 break; 711 case WMI_HOST_PEER_PARAM_FIXED_RATE: 712 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 713 break; 714 case WMI_HOST_PEER_SET_MU_WHITELIST: 715 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 716 break; 717 case WMI_HOST_PEER_SET_MAC_TX_RATE: 718 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 719 break; 720 case WMI_HOST_PEER_SET_MIN_TX_RATE: 721 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 722 break; 723 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 724 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 725 break; 726 case WMI_HOST_PEER_NSS_VHT160: 727 *targ_paramid = WMI_PEER_NSS_VHT160; 728 break; 729 case WMI_HOST_PEER_NSS_VHT80_80: 730 *targ_paramid = WMI_PEER_NSS_VHT80_80; 731 break; 732 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 733 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 734 break; 735 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 736 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 737 break; 738 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 739 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 740 break; 741 case WMI_HOST_PEER_PARAM_MU_ENABLE: 742 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 743 break; 744 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 745 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 746 break; 747 default: 748 return QDF_STATUS_E_NOSUPPORT; 749 } 750 751 return QDF_STATUS_SUCCESS; 752 } 753 #endif 754 /** 755 * send_peer_param_cmd_tlv() - set peer parameter in fw 756 * @wmi: wmi handle 757 * @peer_addr: peer mac address 758 * @param : pointer to hold peer set parameter 759 * 760 * Return: QDF_STATUS_SUCCESS for success or error code 761 */ 762 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 763 uint8_t peer_addr[IEEE80211_ADDR_LEN], 764 struct peer_set_params *param) 765 { 766 wmi_peer_set_param_cmd_fixed_param *cmd; 767 wmi_buf_t buf; 768 int32_t err; 769 uint32_t param_id; 770 771 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 772 param->param_id) != QDF_STATUS_SUCCESS) 773 return QDF_STATUS_E_NOSUPPORT; 774 775 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 776 if (!buf) { 777 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 778 return QDF_STATUS_E_NOMEM; 779 } 780 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 781 WMITLV_SET_HDR(&cmd->tlv_header, 782 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 783 WMITLV_GET_STRUCT_TLVLEN 784 (wmi_peer_set_param_cmd_fixed_param)); 785 cmd->vdev_id = param->vdev_id; 786 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 787 cmd->param_id = param_id; 788 cmd->param_value = param->param_value; 789 err = wmi_unified_cmd_send(wmi, buf, 790 sizeof(wmi_peer_set_param_cmd_fixed_param), 791 WMI_PEER_SET_PARAM_CMDID); 792 if (err) { 793 WMI_LOGE("Failed to send set_param cmd"); 794 wmi_buf_free(buf); 795 return QDF_STATUS_E_FAILURE; 796 } 797 798 return 0; 799 } 800 801 /** 802 * send_vdev_up_cmd_tlv() - send vdev up command in fw 803 * @wmi: wmi handle 804 * @bssid: bssid 805 * @vdev_up_params: pointer to hold vdev up parameter 806 * 807 * Return: QDF_STATUS_SUCCESS for success or error code 808 */ 809 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 810 uint8_t bssid[IEEE80211_ADDR_LEN], 811 struct vdev_up_params *params) 812 { 813 wmi_vdev_up_cmd_fixed_param *cmd; 814 wmi_buf_t buf; 815 int32_t len = sizeof(*cmd); 816 817 WMI_LOGD("%s: VDEV_UP", __func__); 818 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 819 params->vdev_id, params->assoc_id, bssid); 820 buf = wmi_buf_alloc(wmi, len); 821 if (!buf) { 822 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 823 return QDF_STATUS_E_NOMEM; 824 } 825 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 826 WMITLV_SET_HDR(&cmd->tlv_header, 827 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 828 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 829 cmd->vdev_id = params->vdev_id; 830 cmd->vdev_assoc_id = params->assoc_id; 831 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 832 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 833 WMI_LOGP("%s: Failed to send vdev up command", __func__); 834 wmi_buf_free(buf); 835 return QDF_STATUS_E_FAILURE; 836 } 837 838 return 0; 839 } 840 841 /** 842 * send_peer_create_cmd_tlv() - send peer create command to fw 843 * @wmi: wmi handle 844 * @peer_addr: peer mac address 845 * @peer_type: peer type 846 * @vdev_id: vdev id 847 * 848 * Return: QDF_STATUS_SUCCESS for success or error code 849 */ 850 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 851 struct peer_create_params *param) 852 { 853 wmi_peer_create_cmd_fixed_param *cmd; 854 wmi_buf_t buf; 855 int32_t len = sizeof(*cmd); 856 857 buf = wmi_buf_alloc(wmi, len); 858 if (!buf) { 859 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 860 return QDF_STATUS_E_NOMEM; 861 } 862 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 863 WMITLV_SET_HDR(&cmd->tlv_header, 864 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 865 WMITLV_GET_STRUCT_TLVLEN 866 (wmi_peer_create_cmd_fixed_param)); 867 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 868 cmd->peer_type = param->peer_type; 869 cmd->vdev_id = param->vdev_id; 870 871 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 872 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 873 wmi_buf_free(buf); 874 return QDF_STATUS_E_FAILURE; 875 } 876 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 877 param->vdev_id); 878 879 return 0; 880 } 881 882 /** 883 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 884 * command to fw 885 * @wmi: wmi handle 886 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 887 * 888 * Return: 0 for success or error code 889 */ 890 static 891 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 892 struct rx_reorder_queue_setup_params *param) 893 { 894 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 895 wmi_buf_t buf; 896 int32_t len = sizeof(*cmd); 897 898 buf = wmi_buf_alloc(wmi, len); 899 if (!buf) { 900 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 901 return QDF_STATUS_E_NOMEM; 902 } 903 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 904 WMITLV_SET_HDR(&cmd->tlv_header, 905 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 906 WMITLV_GET_STRUCT_TLVLEN 907 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 908 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 909 cmd->vdev_id = param->vdev_id; 910 cmd->tid = param->tid; 911 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 912 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 913 cmd->queue_no = param->queue_no; 914 915 if (wmi_unified_cmd_send(wmi, buf, len, 916 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 917 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 918 __func__); 919 qdf_nbuf_free(buf); 920 return QDF_STATUS_E_FAILURE; 921 } 922 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 923 param->peer_macaddr, param->vdev_id, param->tid); 924 925 return QDF_STATUS_SUCCESS; 926 } 927 928 /** 929 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 930 * command to fw 931 * @wmi: wmi handle 932 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 933 * 934 * Return: 0 for success or error code 935 */ 936 static 937 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 938 struct rx_reorder_queue_remove_params *param) 939 { 940 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 941 wmi_buf_t buf; 942 int32_t len = sizeof(*cmd); 943 944 buf = wmi_buf_alloc(wmi, len); 945 if (!buf) { 946 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 947 return QDF_STATUS_E_NOMEM; 948 } 949 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 950 wmi_buf_data(buf); 951 WMITLV_SET_HDR(&cmd->tlv_header, 952 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 953 WMITLV_GET_STRUCT_TLVLEN 954 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 955 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 956 cmd->vdev_id = param->vdev_id; 957 cmd->tid_mask = param->peer_tid_bitmap; 958 959 if (wmi_unified_cmd_send(wmi, buf, len, 960 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 961 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 962 __func__); 963 qdf_nbuf_free(buf); 964 return QDF_STATUS_E_FAILURE; 965 } 966 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 967 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 968 969 return QDF_STATUS_SUCCESS; 970 } 971 972 /** 973 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 974 * @wmi_handle: wmi handle 975 * @param: pointer holding peer details 976 * 977 * Return: 0 for success or error code 978 */ 979 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 980 struct peer_add_wds_entry_params *param) 981 { 982 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 983 wmi_buf_t buf; 984 int len = sizeof(*cmd); 985 986 buf = wmi_buf_alloc(wmi_handle, len); 987 if (!buf) { 988 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 989 return QDF_STATUS_E_FAILURE; 990 } 991 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 992 WMITLV_SET_HDR(&cmd->tlv_header, 993 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 994 WMITLV_GET_STRUCT_TLVLEN 995 (wmi_peer_add_wds_entry_cmd_fixed_param)); 996 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 997 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 998 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 999 cmd->vdev_id = param->vdev_id; 1000 1001 return wmi_unified_cmd_send(wmi_handle, buf, len, 1002 WMI_PEER_ADD_WDS_ENTRY_CMDID); 1003 } 1004 1005 /** 1006 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 1007 * @wmi_handle: wmi handle 1008 * @param: pointer holding peer details 1009 * 1010 * Return: 0 for success or error code 1011 */ 1012 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1013 struct peer_del_wds_entry_params *param) 1014 { 1015 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 1016 wmi_buf_t buf; 1017 int len = sizeof(*cmd); 1018 1019 buf = wmi_buf_alloc(wmi_handle, len); 1020 if (!buf) { 1021 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 1022 return QDF_STATUS_E_NOMEM; 1023 } 1024 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1025 WMITLV_SET_HDR(&cmd->tlv_header, 1026 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 1027 WMITLV_GET_STRUCT_TLVLEN 1028 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 1029 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 1030 cmd->vdev_id = param->vdev_id; 1031 return wmi_unified_cmd_send(wmi_handle, buf, len, 1032 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 1033 } 1034 1035 /** 1036 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 1037 * @wmi_handle: wmi handle 1038 * @param: pointer holding peer details 1039 * 1040 * Return: 0 for success or error code 1041 */ 1042 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1043 struct peer_update_wds_entry_params *param) 1044 { 1045 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 1046 wmi_buf_t buf; 1047 int len = sizeof(*cmd); 1048 1049 buf = wmi_buf_alloc(wmi_handle, len); 1050 if (!buf) { 1051 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 1052 return QDF_STATUS_E_NOMEM; 1053 } 1054 1055 /* wmi_buf_alloc returns zeroed command buffer */ 1056 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1057 WMITLV_SET_HDR(&cmd->tlv_header, 1058 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 1059 WMITLV_GET_STRUCT_TLVLEN 1060 (wmi_peer_update_wds_entry_cmd_fixed_param)); 1061 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1062 cmd->vdev_id = param->vdev_id; 1063 if (param->wds_macaddr) 1064 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1065 &cmd->wds_macaddr); 1066 if (param->peer_macaddr) 1067 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1068 &cmd->peer_macaddr); 1069 return wmi_unified_cmd_send(wmi_handle, buf, len, 1070 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1071 } 1072 1073 /** 1074 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1075 * @wmi_handle: wmi handle 1076 * @param: pointer to get tpc config params 1077 * 1078 * Return: 0 for success or error code 1079 */ 1080 static QDF_STATUS 1081 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1082 uint32_t param) 1083 { 1084 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1085 wmi_buf_t buf; 1086 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1087 1088 buf = wmi_buf_alloc(wmi_handle, len); 1089 if (!buf) { 1090 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1091 return QDF_STATUS_E_NOMEM; 1092 } 1093 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1094 WMITLV_SET_HDR(&cmd->tlv_header, 1095 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1096 WMITLV_GET_STRUCT_TLVLEN 1097 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1098 1099 cmd->param = param; 1100 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1101 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1102 WMI_LOGE("Send pdev get tpc config cmd failed"); 1103 wmi_buf_free(buf); 1104 return QDF_STATUS_E_FAILURE; 1105 1106 } 1107 WMI_LOGD("%s:send success", __func__); 1108 1109 return QDF_STATUS_SUCCESS; 1110 } 1111 1112 #ifdef WLAN_SUPPORT_GREEN_AP 1113 /** 1114 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1115 * @wmi_handle: wmi handle 1116 * @value: value 1117 * @pdev_id: pdev id to have radio context 1118 * 1119 * Return: QDF_STATUS_SUCCESS for success or error code 1120 */ 1121 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1122 uint32_t value, uint8_t pdev_id) 1123 { 1124 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1125 wmi_buf_t buf; 1126 int32_t len = sizeof(*cmd); 1127 1128 WMI_LOGD("Set Green AP PS val %d", value); 1129 1130 buf = wmi_buf_alloc(wmi_handle, len); 1131 if (!buf) { 1132 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1133 return QDF_STATUS_E_NOMEM; 1134 } 1135 1136 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1137 WMITLV_SET_HDR(&cmd->tlv_header, 1138 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1139 WMITLV_GET_STRUCT_TLVLEN 1140 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1141 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1142 cmd->enable = value; 1143 1144 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1145 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1146 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1147 wmi_buf_free(buf); 1148 return QDF_STATUS_E_FAILURE; 1149 } 1150 1151 return 0; 1152 } 1153 #endif 1154 1155 /** 1156 * send_pdev_utf_cmd_tlv() - send utf command to fw 1157 * @wmi_handle: wmi handle 1158 * @param: pointer to pdev_utf_params 1159 * @mac_id: mac id to have radio context 1160 * 1161 * Return: QDF_STATUS_SUCCESS for success or error code 1162 */ 1163 static QDF_STATUS 1164 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1165 struct pdev_utf_params *param, 1166 uint8_t mac_id) 1167 { 1168 wmi_buf_t buf; 1169 uint8_t *cmd; 1170 /* if param->len is 0 no data is sent, return error */ 1171 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1172 static uint8_t msgref = 1; 1173 uint8_t segNumber = 0, segInfo, numSegments; 1174 uint16_t chunk_len, total_bytes; 1175 uint8_t *bufpos; 1176 struct seg_hdr_info segHdrInfo; 1177 1178 bufpos = param->utf_payload; 1179 total_bytes = param->len; 1180 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1181 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1182 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1183 1184 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1185 numSegments++; 1186 1187 while (param->len) { 1188 if (param->len > MAX_WMI_UTF_LEN) 1189 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1190 else 1191 chunk_len = param->len; 1192 1193 buf = wmi_buf_alloc(wmi_handle, 1194 (chunk_len + sizeof(segHdrInfo) + 1195 WMI_TLV_HDR_SIZE)); 1196 if (!buf) { 1197 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1198 return QDF_STATUS_E_NOMEM; 1199 } 1200 1201 cmd = (uint8_t *) wmi_buf_data(buf); 1202 1203 segHdrInfo.len = total_bytes; 1204 segHdrInfo.msgref = msgref; 1205 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1206 segHdrInfo.segmentInfo = segInfo; 1207 segHdrInfo.pad = 0; 1208 1209 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1210 " segHdrInfo.segmentInfo = %d", 1211 __func__, segHdrInfo.len, segHdrInfo.msgref, 1212 segHdrInfo.segmentInfo); 1213 1214 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1215 "chunk len %d", __func__, total_bytes, segNumber, 1216 numSegments, chunk_len); 1217 1218 segNumber++; 1219 1220 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1221 (chunk_len + sizeof(segHdrInfo))); 1222 cmd += WMI_TLV_HDR_SIZE; 1223 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1224 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1225 1226 ret = wmi_unified_cmd_send(wmi_handle, buf, 1227 (chunk_len + sizeof(segHdrInfo) + 1228 WMI_TLV_HDR_SIZE), 1229 WMI_PDEV_UTF_CMDID); 1230 1231 if (QDF_IS_STATUS_ERROR(ret)) { 1232 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1233 wmi_buf_free(buf); 1234 break; 1235 } 1236 1237 param->len -= chunk_len; 1238 bufpos += chunk_len; 1239 } 1240 1241 msgref++; 1242 1243 return ret; 1244 } 1245 #ifdef CONFIG_MCL 1246 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1247 uint32_t host_param) 1248 { 1249 return host_param; 1250 } 1251 #else 1252 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1253 uint32_t host_param) 1254 { 1255 if (host_param < wmi_pdev_param_max) 1256 return wmi_handle->pdev_param[host_param]; 1257 1258 return WMI_UNAVAILABLE_PARAM; 1259 } 1260 #endif 1261 /** 1262 * send_pdev_param_cmd_tlv() - set pdev parameters 1263 * @wmi_handle: wmi handle 1264 * @param: pointer to pdev parameter 1265 * @mac_id: radio context 1266 * 1267 * Return: 0 on success, errno on failure 1268 */ 1269 static QDF_STATUS 1270 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1271 struct pdev_params *param, 1272 uint8_t mac_id) 1273 { 1274 QDF_STATUS ret; 1275 wmi_pdev_set_param_cmd_fixed_param *cmd; 1276 wmi_buf_t buf; 1277 uint16_t len = sizeof(*cmd); 1278 uint32_t pdev_param; 1279 1280 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1281 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1282 WMI_LOGW("%s: Unavailable param %d\n", 1283 __func__, param->param_id); 1284 return QDF_STATUS_E_INVAL; 1285 } 1286 1287 buf = wmi_buf_alloc(wmi_handle, len); 1288 if (!buf) { 1289 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1290 return QDF_STATUS_E_NOMEM; 1291 } 1292 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1293 WMITLV_SET_HDR(&cmd->tlv_header, 1294 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1295 WMITLV_GET_STRUCT_TLVLEN 1296 (wmi_pdev_set_param_cmd_fixed_param)); 1297 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1298 cmd->param_id = pdev_param; 1299 cmd->param_value = param->param_value; 1300 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1301 param->param_value); 1302 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1303 WMI_PDEV_SET_PARAM_CMDID); 1304 if (QDF_IS_STATUS_ERROR(ret)) { 1305 WMI_LOGE("Failed to send set param command ret = %d", ret); 1306 wmi_buf_free(buf); 1307 } 1308 return ret; 1309 } 1310 1311 /** 1312 * send_suspend_cmd_tlv() - WMI suspend function 1313 * @param wmi_handle : handle to WMI. 1314 * @param param : pointer to hold suspend parameter 1315 * @mac_id: radio context 1316 * 1317 * Return 0 on success and -ve on failure. 1318 */ 1319 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1320 struct suspend_params *param, 1321 uint8_t mac_id) 1322 { 1323 wmi_pdev_suspend_cmd_fixed_param *cmd; 1324 wmi_buf_t wmibuf; 1325 uint32_t len = sizeof(*cmd); 1326 int32_t ret; 1327 1328 /* 1329 * send the command to Target to ignore the 1330 * PCIE reset so as to ensure that Host and target 1331 * states are in sync 1332 */ 1333 wmibuf = wmi_buf_alloc(wmi_handle, len); 1334 if (wmibuf == NULL) 1335 return QDF_STATUS_E_NOMEM; 1336 1337 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1338 WMITLV_SET_HDR(&cmd->tlv_header, 1339 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1340 WMITLV_GET_STRUCT_TLVLEN 1341 (wmi_pdev_suspend_cmd_fixed_param)); 1342 if (param->disable_target_intr) 1343 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1344 else 1345 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1346 1347 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1348 1349 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1350 WMI_PDEV_SUSPEND_CMDID); 1351 if (ret) { 1352 wmi_buf_free(wmibuf); 1353 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1354 } 1355 1356 return ret; 1357 } 1358 1359 /** 1360 * send_resume_cmd_tlv() - WMI resume function 1361 * @param wmi_handle : handle to WMI. 1362 * @mac_id: radio context 1363 * 1364 * Return: 0 on success and -ve on failure. 1365 */ 1366 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1367 uint8_t mac_id) 1368 { 1369 wmi_buf_t wmibuf; 1370 wmi_pdev_resume_cmd_fixed_param *cmd; 1371 QDF_STATUS ret; 1372 1373 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1374 if (wmibuf == NULL) 1375 return QDF_STATUS_E_NOMEM; 1376 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1377 WMITLV_SET_HDR(&cmd->tlv_header, 1378 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1379 WMITLV_GET_STRUCT_TLVLEN 1380 (wmi_pdev_resume_cmd_fixed_param)); 1381 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1382 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1383 WMI_PDEV_RESUME_CMDID); 1384 if (QDF_IS_STATUS_ERROR(ret)) { 1385 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1386 wmi_buf_free(wmibuf); 1387 } 1388 1389 return ret; 1390 } 1391 1392 #ifdef FEATURE_WLAN_D0WOW 1393 /** 1394 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1395 * @param wmi_handle: handle to WMI. 1396 * @mac_id: radio context 1397 * 1398 * Return: 0 on success and error code on failure. 1399 */ 1400 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1401 uint8_t mac_id) 1402 { 1403 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1404 wmi_buf_t buf; 1405 int32_t len; 1406 QDF_STATUS status; 1407 1408 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1409 1410 buf = wmi_buf_alloc(wmi_handle, len); 1411 if (!buf) { 1412 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1413 return QDF_STATUS_E_NOMEM; 1414 } 1415 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1416 WMITLV_SET_HDR(&cmd->tlv_header, 1417 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1418 WMITLV_GET_STRUCT_TLVLEN 1419 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1420 1421 cmd->enable = true; 1422 1423 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1424 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1425 if (QDF_IS_STATUS_ERROR(status)) 1426 wmi_buf_free(buf); 1427 1428 return status; 1429 } 1430 1431 /** 1432 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1433 * @param wmi_handle: handle to WMI. 1434 * @mac_id: radio context 1435 * 1436 * Return: 0 on success and error code on failure. 1437 */ 1438 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1439 uint8_t mac_id) 1440 { 1441 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1442 wmi_buf_t buf; 1443 int32_t len; 1444 QDF_STATUS status; 1445 1446 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1447 1448 buf = wmi_buf_alloc(wmi_handle, len); 1449 if (!buf) { 1450 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1451 return QDF_STATUS_E_NOMEM; 1452 } 1453 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1454 WMITLV_SET_HDR(&cmd->tlv_header, 1455 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1456 WMITLV_GET_STRUCT_TLVLEN 1457 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1458 1459 cmd->enable = false; 1460 1461 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1462 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1463 if (QDF_IS_STATUS_ERROR(status)) 1464 wmi_buf_free(buf); 1465 1466 return status; 1467 } 1468 #endif 1469 1470 /** 1471 * send_wow_enable_cmd_tlv() - WMI wow enable function 1472 * @param wmi_handle : handle to WMI. 1473 * @param param : pointer to hold wow enable parameter 1474 * @mac_id: radio context 1475 * 1476 * Return: 0 on success and -ve on failure. 1477 */ 1478 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1479 struct wow_cmd_params *param, 1480 uint8_t mac_id) 1481 { 1482 wmi_wow_enable_cmd_fixed_param *cmd; 1483 wmi_buf_t buf; 1484 int32_t len; 1485 int32_t ret; 1486 1487 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1488 1489 buf = wmi_buf_alloc(wmi_handle, len); 1490 if (!buf) { 1491 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1492 return QDF_STATUS_E_NOMEM; 1493 } 1494 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1495 WMITLV_SET_HDR(&cmd->tlv_header, 1496 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1497 WMITLV_GET_STRUCT_TLVLEN 1498 (wmi_wow_enable_cmd_fixed_param)); 1499 cmd->enable = param->enable; 1500 if (param->can_suspend_link) 1501 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1502 else 1503 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1504 cmd->flags = param->flags; 1505 1506 WMI_LOGI("suspend type: %s", 1507 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1508 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1509 1510 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1511 WMI_WOW_ENABLE_CMDID); 1512 if (ret) 1513 wmi_buf_free(buf); 1514 1515 return ret; 1516 } 1517 1518 /** 1519 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1520 * @wmi_handle: wmi handle 1521 * @peer_addr: peer mac address 1522 * @param: pointer to ap_ps parameter structure 1523 * 1524 * Return: QDF_STATUS_SUCCESS for success or error code 1525 */ 1526 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1527 uint8_t *peer_addr, 1528 struct ap_ps_params *param) 1529 { 1530 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1531 wmi_buf_t buf; 1532 int32_t err; 1533 1534 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1535 if (!buf) { 1536 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1537 return QDF_STATUS_E_NOMEM; 1538 } 1539 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1540 WMITLV_SET_HDR(&cmd->tlv_header, 1541 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1542 WMITLV_GET_STRUCT_TLVLEN 1543 (wmi_ap_ps_peer_cmd_fixed_param)); 1544 cmd->vdev_id = param->vdev_id; 1545 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1546 cmd->param = param->param; 1547 cmd->value = param->value; 1548 err = wmi_unified_cmd_send(wmi_handle, buf, 1549 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1550 if (err) { 1551 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1552 wmi_buf_free(buf); 1553 return QDF_STATUS_E_FAILURE; 1554 } 1555 1556 return 0; 1557 } 1558 1559 /** 1560 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1561 * @wmi_handle: wmi handle 1562 * @peer_addr: peer mac address 1563 * @param: pointer to sta_ps parameter structure 1564 * 1565 * Return: QDF_STATUS_SUCCESS for success or error code 1566 */ 1567 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1568 struct sta_ps_params *param) 1569 { 1570 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1571 wmi_buf_t buf; 1572 int32_t len = sizeof(*cmd); 1573 1574 buf = wmi_buf_alloc(wmi_handle, len); 1575 if (!buf) { 1576 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1577 return QDF_STATUS_E_NOMEM; 1578 } 1579 1580 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1581 WMITLV_SET_HDR(&cmd->tlv_header, 1582 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1583 WMITLV_GET_STRUCT_TLVLEN 1584 (wmi_sta_powersave_param_cmd_fixed_param)); 1585 cmd->vdev_id = param->vdev_id; 1586 cmd->param = param->param; 1587 cmd->value = param->value; 1588 1589 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1590 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1591 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1592 param->vdev_id, param->param, param->value); 1593 wmi_buf_free(buf); 1594 return QDF_STATUS_E_FAILURE; 1595 } 1596 1597 return 0; 1598 } 1599 1600 /** 1601 * send_crash_inject_cmd_tlv() - inject fw crash 1602 * @wmi_handle: wmi handle 1603 * @param: ponirt to crash inject parameter structure 1604 * 1605 * Return: QDF_STATUS_SUCCESS for success or return error 1606 */ 1607 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1608 struct crash_inject *param) 1609 { 1610 int32_t ret = 0; 1611 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1612 uint16_t len = sizeof(*cmd); 1613 wmi_buf_t buf; 1614 1615 buf = wmi_buf_alloc(wmi_handle, len); 1616 if (!buf) { 1617 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1618 return QDF_STATUS_E_NOMEM; 1619 } 1620 1621 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1622 WMITLV_SET_HDR(&cmd->tlv_header, 1623 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1624 WMITLV_GET_STRUCT_TLVLEN 1625 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1626 cmd->type = param->type; 1627 cmd->delay_time_ms = param->delay_time_ms; 1628 1629 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1630 WMI_FORCE_FW_HANG_CMDID); 1631 if (ret) { 1632 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1633 __func__, ret); 1634 wmi_buf_free(buf); 1635 } 1636 1637 return ret; 1638 } 1639 1640 #ifdef FEATURE_FW_LOG_PARSING 1641 /** 1642 * send_dbglog_cmd_tlv() - set debug log level 1643 * @param wmi_handle : handle to WMI. 1644 * @param param : pointer to hold dbglog level parameter 1645 * 1646 * Return: 0 on success and -ve on failure. 1647 */ 1648 static QDF_STATUS 1649 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1650 struct dbglog_params *dbglog_param) 1651 { 1652 wmi_buf_t buf; 1653 wmi_debug_log_config_cmd_fixed_param *configmsg; 1654 QDF_STATUS status; 1655 int32_t i; 1656 int32_t len; 1657 int8_t *buf_ptr; 1658 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1659 1660 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1661 1662 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1663 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1664 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1665 buf = wmi_buf_alloc(wmi_handle, len); 1666 if (buf == NULL) 1667 return QDF_STATUS_E_NOMEM; 1668 1669 configmsg = 1670 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1671 buf_ptr = (int8_t *) configmsg; 1672 WMITLV_SET_HDR(&configmsg->tlv_header, 1673 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1674 WMITLV_GET_STRUCT_TLVLEN 1675 (wmi_debug_log_config_cmd_fixed_param)); 1676 configmsg->dbg_log_param = dbglog_param->param; 1677 configmsg->value = dbglog_param->val; 1678 /* Filling in the data part of second tlv -- should 1679 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1680 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1681 sizeof 1682 (wmi_debug_log_config_cmd_fixed_param) 1683 + WMI_TLV_HDR_SIZE); 1684 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1685 WMITLV_TAG_ARRAY_UINT32, 1686 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1687 if (dbglog_param->module_id_bitmap) { 1688 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1689 module_id_bitmap_array[i] = 1690 dbglog_param->module_id_bitmap[i]; 1691 } 1692 } 1693 1694 status = wmi_unified_cmd_send(wmi_handle, buf, 1695 len, WMI_DBGLOG_CFG_CMDID); 1696 1697 if (status != QDF_STATUS_SUCCESS) 1698 wmi_buf_free(buf); 1699 1700 return status; 1701 } 1702 #endif 1703 1704 #ifdef CONFIG_MCL 1705 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1706 uint32_t host_param) 1707 { 1708 return host_param; 1709 } 1710 #else 1711 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1712 uint32_t host_param) 1713 { 1714 if (host_param < wmi_vdev_param_max) 1715 return wmi_handle->vdev_param[host_param]; 1716 1717 return WMI_UNAVAILABLE_PARAM; 1718 } 1719 #endif 1720 /** 1721 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1722 * @param wmi_handle : handle to WMI. 1723 * @param macaddr : MAC address 1724 * @param param : pointer to hold vdev set parameter 1725 * 1726 * Return: 0 on success and -ve on failure. 1727 */ 1728 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1729 struct vdev_set_params *param) 1730 { 1731 QDF_STATUS ret; 1732 wmi_vdev_set_param_cmd_fixed_param *cmd; 1733 wmi_buf_t buf; 1734 uint16_t len = sizeof(*cmd); 1735 uint32_t vdev_param; 1736 1737 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1738 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1739 WMI_LOGW("%s:Vdev param %d not available", __func__, 1740 param->param_id); 1741 return QDF_STATUS_E_INVAL; 1742 1743 } 1744 1745 buf = wmi_buf_alloc(wmi_handle, len); 1746 if (!buf) { 1747 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1748 return QDF_STATUS_E_NOMEM; 1749 } 1750 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1751 WMITLV_SET_HDR(&cmd->tlv_header, 1752 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1753 WMITLV_GET_STRUCT_TLVLEN 1754 (wmi_vdev_set_param_cmd_fixed_param)); 1755 cmd->vdev_id = param->if_id; 1756 cmd->param_id = vdev_param; 1757 cmd->param_value = param->param_value; 1758 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1759 cmd->vdev_id, cmd->param_id, cmd->param_value); 1760 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1761 WMI_VDEV_SET_PARAM_CMDID); 1762 if (QDF_IS_STATUS_ERROR(ret)) { 1763 WMI_LOGE("Failed to send set param command ret = %d", ret); 1764 wmi_buf_free(buf); 1765 } 1766 1767 return ret; 1768 } 1769 1770 /** 1771 * send_stats_request_cmd_tlv() - WMI request stats function 1772 * @param wmi_handle : handle to WMI. 1773 * @param macaddr : MAC address 1774 * @param param : pointer to hold stats request parameter 1775 * 1776 * Return: 0 on success and -ve on failure. 1777 */ 1778 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1779 uint8_t macaddr[IEEE80211_ADDR_LEN], 1780 struct stats_request_params *param) 1781 { 1782 int32_t ret; 1783 wmi_request_stats_cmd_fixed_param *cmd; 1784 wmi_buf_t buf; 1785 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1786 1787 buf = wmi_buf_alloc(wmi_handle, len); 1788 if (!buf) { 1789 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1790 return -QDF_STATUS_E_NOMEM; 1791 } 1792 1793 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1794 WMITLV_SET_HDR(&cmd->tlv_header, 1795 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1796 WMITLV_GET_STRUCT_TLVLEN 1797 (wmi_request_stats_cmd_fixed_param)); 1798 cmd->stats_id = param->stats_id; 1799 cmd->vdev_id = param->vdev_id; 1800 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1801 param->pdev_id); 1802 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1803 1804 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1805 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1806 1807 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1808 WMI_REQUEST_STATS_CMDID); 1809 1810 if (ret) { 1811 WMI_LOGE("Failed to send status request to fw =%d", ret); 1812 wmi_buf_free(buf); 1813 } 1814 1815 return ret; 1816 } 1817 1818 #ifdef CONFIG_WIN 1819 /** 1820 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1821 * @param wmi_handle : handle to WMI. 1822 * @param PKTLOG_EVENT : packet log event 1823 * @mac_id: mac id to have radio context 1824 * 1825 * Return: 0 on success and -ve on failure. 1826 */ 1827 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1828 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1829 { 1830 int32_t ret; 1831 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1832 wmi_buf_t buf; 1833 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1834 1835 buf = wmi_buf_alloc(wmi_handle, len); 1836 if (!buf) { 1837 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1838 return -QDF_STATUS_E_NOMEM; 1839 } 1840 1841 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1842 WMITLV_SET_HDR(&cmd->tlv_header, 1843 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1844 WMITLV_GET_STRUCT_TLVLEN 1845 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1846 cmd->evlist = PKTLOG_EVENT; 1847 cmd->pdev_id = mac_id; 1848 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1849 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1850 if (ret) { 1851 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1852 wmi_buf_free(buf); 1853 } 1854 1855 return ret; 1856 } 1857 1858 /** 1859 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1860 * @param wmi_handle : handle to WMI. 1861 * @mac_id: mac id to have radio context 1862 * 1863 * Return: 0 on success and -ve on failure. 1864 */ 1865 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1866 uint8_t mac_id) 1867 { 1868 int32_t ret; 1869 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1870 wmi_buf_t buf; 1871 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1872 1873 buf = wmi_buf_alloc(wmi_handle, len); 1874 if (!buf) { 1875 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1876 return -QDF_STATUS_E_NOMEM; 1877 } 1878 1879 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1880 WMITLV_SET_HDR(&cmd->tlv_header, 1881 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1882 WMITLV_GET_STRUCT_TLVLEN 1883 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1884 cmd->pdev_id = mac_id; 1885 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1886 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1887 if (ret) { 1888 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1889 wmi_buf_free(buf); 1890 } 1891 1892 return ret; 1893 } 1894 #else 1895 /** 1896 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1897 * packet-log 1898 * @param wmi_handle : handle to WMI. 1899 * @param macaddr : MAC address 1900 * @param param : pointer to hold stats request parameter 1901 * 1902 * Return: 0 on success and -ve on failure. 1903 */ 1904 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1905 uint8_t macaddr[IEEE80211_ADDR_LEN], 1906 struct packet_enable_params *param) 1907 { 1908 return 0; 1909 } 1910 /** 1911 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1912 * packet-log 1913 * @param wmi_handle : handle to WMI. 1914 * @mac_id: mac id to have radio context 1915 * 1916 * Return: 0 on success and -ve on failure. 1917 */ 1918 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1919 uint8_t mac_id) 1920 { 1921 return 0; 1922 } 1923 #endif 1924 1925 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1926 /** 1927 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1928 * sync time between bwtween host and firmware 1929 * @param wmi_handle : handle to WMI. 1930 * 1931 * Return: None 1932 */ 1933 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1934 { 1935 wmi_buf_t buf; 1936 QDF_STATUS status = QDF_STATUS_SUCCESS; 1937 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1938 int32_t len; 1939 qdf_time_t time_ms; 1940 1941 len = sizeof(*time_stamp); 1942 buf = wmi_buf_alloc(wmi_handle, len); 1943 1944 if (!buf) { 1945 WMI_LOGP(FL("wmi_buf_alloc failed")); 1946 return; 1947 } 1948 time_stamp = 1949 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1950 (wmi_buf_data(buf)); 1951 WMITLV_SET_HDR(&time_stamp->tlv_header, 1952 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1953 WMITLV_GET_STRUCT_TLVLEN( 1954 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1955 1956 time_ms = qdf_get_time_of_the_day_ms(); 1957 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1958 time_stamp->time_stamp_low = time_ms & 1959 WMI_FW_TIME_STAMP_LOW_MASK; 1960 /* 1961 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1962 * wont exceed 27 bit 1963 */ 1964 time_stamp->time_stamp_high = 0; 1965 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1966 time_stamp->mode, time_stamp->time_stamp_low, 1967 time_stamp->time_stamp_high); 1968 1969 status = wmi_unified_cmd_send(wmi_handle, buf, 1970 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 1971 if (status) { 1972 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 1973 wmi_buf_free(buf); 1974 } 1975 1976 } 1977 1978 #ifdef WLAN_SUPPORT_FILS 1979 /** 1980 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 1981 * @wmi_handle: wmi handle 1982 * @evt_buf: pointer to event buffer 1983 * @vdev_id: pointer to hold vdev id 1984 * 1985 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 1986 */ 1987 static QDF_STATUS 1988 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 1989 void *evt_buf, uint32_t *vdev_id) 1990 { 1991 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 1992 wmi_host_swfda_event_fixed_param *swfda_event; 1993 1994 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 1995 if (!param_buf) { 1996 WMI_LOGE("Invalid swfda event buffer"); 1997 return QDF_STATUS_E_INVAL; 1998 } 1999 swfda_event = param_buf->fixed_param; 2000 *vdev_id = swfda_event->vdev_id; 2001 2002 return QDF_STATUS_SUCCESS; 2003 } 2004 2005 /** 2006 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 2007 * @wmi_handle: wmi handle 2008 * @param: pointer to hold FILS discovery enable param 2009 * 2010 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 2011 */ 2012 static QDF_STATUS 2013 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 2014 struct config_fils_params *param) 2015 { 2016 wmi_enable_fils_cmd_fixed_param *cmd; 2017 wmi_buf_t buf; 2018 QDF_STATUS status; 2019 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 2020 2021 buf = wmi_buf_alloc(wmi_handle, len); 2022 if (!buf) { 2023 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2024 return QDF_STATUS_E_NOMEM; 2025 } 2026 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 2027 WMITLV_SET_HDR(&cmd->tlv_header, 2028 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 2029 WMITLV_GET_STRUCT_TLVLEN( 2030 wmi_enable_fils_cmd_fixed_param)); 2031 cmd->vdev_id = param->vdev_id; 2032 cmd->fd_period = param->fd_period; 2033 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 2034 param->fd_period, param->vdev_id); 2035 2036 status = wmi_unified_cmd_send(wmi_handle, buf, len, 2037 WMI_ENABLE_FILS_CMDID); 2038 if (status != QDF_STATUS_SUCCESS) { 2039 wmi_buf_free(buf); 2040 return QDF_STATUS_E_FAILURE; 2041 } 2042 2043 return QDF_STATUS_SUCCESS; 2044 } 2045 2046 /** 2047 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 2048 * @wmi_handle: wmi handle 2049 * @param: pointer to hold FD send cmd parameter 2050 * 2051 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 2052 */ 2053 static QDF_STATUS 2054 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 2055 struct fd_params *param) 2056 { 2057 QDF_STATUS ret; 2058 wmi_fd_send_from_host_cmd_fixed_param *cmd; 2059 wmi_buf_t wmi_buf; 2060 qdf_dma_addr_t dma_addr; 2061 2062 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2063 if (!wmi_buf) { 2064 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2065 return QDF_STATUS_E_NOMEM; 2066 } 2067 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2068 WMITLV_SET_HDR(&cmd->tlv_header, 2069 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2070 WMITLV_GET_STRUCT_TLVLEN( 2071 wmi_fd_send_from_host_cmd_fixed_param)); 2072 cmd->vdev_id = param->vdev_id; 2073 cmd->data_len = qdf_nbuf_len(param->wbuf); 2074 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2075 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2076 cmd->frame_ctrl = param->frame_ctrl; 2077 2078 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2079 WMI_PDEV_SEND_FD_CMDID); 2080 if (ret != QDF_STATUS_SUCCESS) { 2081 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2082 __func__, ret); 2083 wmi_buf_free(wmi_buf); 2084 } 2085 2086 return ret; 2087 } 2088 #endif /* WLAN_SUPPORT_FILS */ 2089 2090 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2091 struct beacon_params *param) 2092 { 2093 QDF_STATUS ret; 2094 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2095 wmi_buf_t wmi_buf; 2096 qdf_dma_addr_t dma_addr; 2097 uint32_t dtim_flag = 0; 2098 2099 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2100 if (!wmi_buf) { 2101 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2102 return QDF_STATUS_E_NOMEM; 2103 } 2104 if (param->is_dtim_count_zero) { 2105 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2106 if (param->is_bitctl_reqd) { 2107 /* deliver CAB traffic in next DTIM beacon */ 2108 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2109 } 2110 } 2111 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2112 WMITLV_SET_HDR(&cmd->tlv_header, 2113 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2114 WMITLV_GET_STRUCT_TLVLEN 2115 (wmi_bcn_send_from_host_cmd_fixed_param)); 2116 cmd->vdev_id = param->vdev_id; 2117 cmd->data_len = qdf_nbuf_len(param->wbuf); 2118 cmd->frame_ctrl = param->frame_ctrl; 2119 cmd->dtim_flag = dtim_flag; 2120 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2121 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2122 #if defined(HTT_PADDR64) 2123 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2124 #endif 2125 cmd->bcn_antenna = param->bcn_txant; 2126 2127 ret = wmi_unified_cmd_send(wmi_handle, 2128 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2129 if (ret != QDF_STATUS_SUCCESS) { 2130 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2131 wmi_buf_free(wmi_buf); 2132 } 2133 2134 return ret; 2135 } 2136 2137 /** 2138 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2139 * @param wmi_handle : handle to WMI. 2140 * @param param : pointer to hold beacon send cmd parameter 2141 * 2142 * Return: 0 on success and -ve on failure. 2143 */ 2144 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2145 struct beacon_tmpl_params *param) 2146 { 2147 int32_t ret; 2148 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2149 wmi_bcn_prb_info *bcn_prb_info; 2150 wmi_buf_t wmi_buf; 2151 uint8_t *buf_ptr; 2152 uint32_t wmi_buf_len; 2153 2154 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2155 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2156 param->tmpl_len_aligned; 2157 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2158 if (!wmi_buf) { 2159 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2160 return QDF_STATUS_E_NOMEM; 2161 } 2162 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2163 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2164 WMITLV_SET_HDR(&cmd->tlv_header, 2165 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2166 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2167 cmd->vdev_id = param->vdev_id; 2168 cmd->tim_ie_offset = param->tim_ie_offset; 2169 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2170 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2171 cmd->buf_len = param->tmpl_len; 2172 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2173 2174 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2175 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2176 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2177 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2178 bcn_prb_info->caps = 0; 2179 bcn_prb_info->erp = 0; 2180 buf_ptr += sizeof(wmi_bcn_prb_info); 2181 2182 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2183 buf_ptr += WMI_TLV_HDR_SIZE; 2184 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2185 2186 ret = wmi_unified_cmd_send(wmi_handle, 2187 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2188 if (ret) { 2189 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2190 wmi_buf_free(wmi_buf); 2191 } 2192 2193 return 0; 2194 } 2195 2196 #ifdef CONFIG_MCL 2197 static inline void copy_peer_flags_tlv( 2198 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2199 struct peer_assoc_params *param) 2200 { 2201 cmd->peer_flags = param->peer_flags; 2202 } 2203 #else 2204 static inline void copy_peer_flags_tlv( 2205 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2206 struct peer_assoc_params *param) 2207 { 2208 /* 2209 * The target only needs a subset of the flags maintained in the host. 2210 * Just populate those flags and send it down 2211 */ 2212 cmd->peer_flags = 0; 2213 2214 /* 2215 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2216 */ 2217 if (param->is_wme_set) { 2218 2219 if (param->qos_flag) 2220 cmd->peer_flags |= WMI_PEER_QOS; 2221 if (param->apsd_flag) 2222 cmd->peer_flags |= WMI_PEER_APSD; 2223 if (param->ht_flag) 2224 cmd->peer_flags |= WMI_PEER_HT; 2225 if (param->bw_40) 2226 cmd->peer_flags |= WMI_PEER_40MHZ; 2227 if (param->bw_80) 2228 cmd->peer_flags |= WMI_PEER_80MHZ; 2229 if (param->bw_160) 2230 cmd->peer_flags |= WMI_PEER_160MHZ; 2231 2232 /* Typically if STBC is enabled for VHT it should be enabled 2233 * for HT as well 2234 **/ 2235 if (param->stbc_flag) 2236 cmd->peer_flags |= WMI_PEER_STBC; 2237 2238 /* Typically if LDPC is enabled for VHT it should be enabled 2239 * for HT as well 2240 **/ 2241 if (param->ldpc_flag) 2242 cmd->peer_flags |= WMI_PEER_LDPC; 2243 2244 if (param->static_mimops_flag) 2245 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2246 if (param->dynamic_mimops_flag) 2247 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2248 if (param->spatial_mux_flag) 2249 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2250 if (param->vht_flag) 2251 cmd->peer_flags |= WMI_PEER_VHT; 2252 if (param->he_flag) 2253 cmd->peer_flags |= WMI_PEER_HE; 2254 } 2255 2256 if (param->is_pmf_enabled) 2257 cmd->peer_flags |= WMI_PEER_PMF; 2258 /* 2259 * Suppress authorization for all AUTH modes that need 4-way handshake 2260 * (during re-association). 2261 * Authorization will be done for these modes on key installation. 2262 */ 2263 if (param->auth_flag) 2264 cmd->peer_flags |= WMI_PEER_AUTH; 2265 if (param->need_ptk_4_way) 2266 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2267 else 2268 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2269 if (param->need_gtk_2_way) 2270 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2271 /* safe mode bypass the 4-way handshake */ 2272 if (param->safe_mode_enabled) 2273 cmd->peer_flags &= 2274 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2275 /* Disable AMSDU for station transmit, if user configures it */ 2276 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2277 * it 2278 * if (param->amsdu_disable) Add after FW support 2279 **/ 2280 2281 /* Target asserts if node is marked HT and all MCS is set to 0. 2282 * Mark the node as non-HT if all the mcs rates are disabled through 2283 * iwpriv 2284 **/ 2285 if (param->peer_ht_rates.num_rates == 0) 2286 cmd->peer_flags &= ~WMI_PEER_HT; 2287 } 2288 #endif 2289 2290 #ifdef CONFIG_MCL 2291 static inline void copy_peer_mac_addr_tlv( 2292 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2293 struct peer_assoc_params *param) 2294 { 2295 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2296 sizeof(param->peer_macaddr)); 2297 } 2298 #else 2299 static inline void copy_peer_mac_addr_tlv( 2300 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2301 struct peer_assoc_params *param) 2302 { 2303 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2304 } 2305 #endif 2306 2307 /** 2308 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2309 * @param wmi_handle : handle to WMI. 2310 * @param param : pointer to peer assoc parameter 2311 * 2312 * Return: 0 on success and -ve on failure. 2313 */ 2314 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2315 struct peer_assoc_params *param) 2316 { 2317 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2318 wmi_vht_rate_set *mcs; 2319 wmi_he_rate_set *he_mcs; 2320 wmi_buf_t buf; 2321 int32_t len; 2322 uint8_t *buf_ptr; 2323 QDF_STATUS ret; 2324 uint32_t peer_legacy_rates_align; 2325 uint32_t peer_ht_rates_align; 2326 int32_t i; 2327 2328 2329 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2330 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2331 2332 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2333 (peer_legacy_rates_align * sizeof(uint8_t)) + 2334 WMI_TLV_HDR_SIZE + 2335 (peer_ht_rates_align * sizeof(uint8_t)) + 2336 sizeof(wmi_vht_rate_set) + 2337 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2338 + WMI_TLV_HDR_SIZE); 2339 2340 buf = wmi_buf_alloc(wmi_handle, len); 2341 if (!buf) { 2342 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2343 return QDF_STATUS_E_NOMEM; 2344 } 2345 2346 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2347 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2348 WMITLV_SET_HDR(&cmd->tlv_header, 2349 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2350 WMITLV_GET_STRUCT_TLVLEN 2351 (wmi_peer_assoc_complete_cmd_fixed_param)); 2352 2353 cmd->vdev_id = param->vdev_id; 2354 2355 cmd->peer_new_assoc = param->peer_new_assoc; 2356 cmd->peer_associd = param->peer_associd; 2357 2358 copy_peer_flags_tlv(cmd, param); 2359 copy_peer_mac_addr_tlv(cmd, param); 2360 2361 cmd->peer_rate_caps = param->peer_rate_caps; 2362 cmd->peer_caps = param->peer_caps; 2363 cmd->peer_listen_intval = param->peer_listen_intval; 2364 cmd->peer_ht_caps = param->peer_ht_caps; 2365 cmd->peer_max_mpdu = param->peer_max_mpdu; 2366 cmd->peer_mpdu_density = param->peer_mpdu_density; 2367 cmd->peer_vht_caps = param->peer_vht_caps; 2368 cmd->peer_phymode = param->peer_phymode; 2369 2370 /* Update 11ax capabilities */ 2371 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2372 cmd->peer_he_ops = param->peer_he_ops; 2373 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2374 sizeof(param->peer_he_cap_phyinfo)); 2375 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2376 sizeof(param->peer_ppet)); 2377 2378 /* Update peer legacy rate information */ 2379 buf_ptr += sizeof(*cmd); 2380 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2381 peer_legacy_rates_align); 2382 buf_ptr += WMI_TLV_HDR_SIZE; 2383 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2384 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2385 param->peer_legacy_rates.num_rates); 2386 2387 /* Update peer HT rate information */ 2388 buf_ptr += peer_legacy_rates_align; 2389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2390 peer_ht_rates_align); 2391 buf_ptr += WMI_TLV_HDR_SIZE; 2392 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2393 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2394 param->peer_ht_rates.num_rates); 2395 2396 /* VHT Rates */ 2397 buf_ptr += peer_ht_rates_align; 2398 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2399 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2400 2401 cmd->peer_nss = param->peer_nss; 2402 2403 /* Update bandwidth-NSS mapping */ 2404 cmd->peer_bw_rxnss_override = 0; 2405 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2406 2407 mcs = (wmi_vht_rate_set *) buf_ptr; 2408 if (param->vht_capable) { 2409 mcs->rx_max_rate = param->rx_max_rate; 2410 mcs->rx_mcs_set = param->rx_mcs_set; 2411 mcs->tx_max_rate = param->tx_max_rate; 2412 mcs->tx_mcs_set = param->tx_mcs_set; 2413 } 2414 2415 /* HE Rates */ 2416 cmd->peer_he_mcs = param->peer_he_mcs_count; 2417 buf_ptr += sizeof(wmi_vht_rate_set); 2418 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2419 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2420 buf_ptr += WMI_TLV_HDR_SIZE; 2421 2422 /* Loop through the HE rate set */ 2423 for (i = 0; i < param->peer_he_mcs_count; i++) { 2424 he_mcs = (wmi_he_rate_set *) buf_ptr; 2425 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2426 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2427 2428 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2429 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2430 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2431 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2432 buf_ptr += sizeof(wmi_he_rate_set); 2433 } 2434 2435 2436 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2437 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2438 "nss %d phymode %d peer_mpdu_density %d " 2439 "cmd->peer_vht_caps %x " 2440 "HE cap_info %x ops %x " 2441 "HE phy %x %x %x " 2442 "peer_bw_rxnss_override %x", __func__, 2443 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2444 cmd->peer_rate_caps, cmd->peer_caps, 2445 cmd->peer_listen_intval, cmd->peer_ht_caps, 2446 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2447 cmd->peer_mpdu_density, 2448 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2449 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2450 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2451 cmd->peer_bw_rxnss_override); 2452 2453 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2454 WMI_PEER_ASSOC_CMDID); 2455 if (QDF_IS_STATUS_ERROR(ret)) { 2456 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2457 __func__, ret); 2458 wmi_buf_free(buf); 2459 } 2460 2461 return ret; 2462 } 2463 2464 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2465 */ 2466 static inline void copy_scan_event_cntrl_flags( 2467 wmi_start_scan_cmd_fixed_param * cmd, 2468 struct scan_req_params *param) 2469 { 2470 2471 /* Scan events subscription */ 2472 if (param->scan_ev_started) 2473 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2474 if (param->scan_ev_completed) 2475 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2476 if (param->scan_ev_bss_chan) 2477 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2478 if (param->scan_ev_foreign_chan) 2479 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2480 if (param->scan_ev_dequeued) 2481 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2482 if (param->scan_ev_preempted) 2483 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2484 if (param->scan_ev_start_failed) 2485 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2486 if (param->scan_ev_restarted) 2487 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2488 if (param->scan_ev_foreign_chn_exit) 2489 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2490 if (param->scan_ev_suspended) 2491 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2492 if (param->scan_ev_resumed) 2493 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2494 2495 /** Set scan control flags */ 2496 cmd->scan_ctrl_flags = 0; 2497 if (param->scan_f_passive) 2498 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2499 if (param->scan_f_strict_passive_pch) 2500 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2501 if (param->scan_f_promisc_mode) 2502 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2503 if (param->scan_f_capture_phy_err) 2504 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2505 if (param->scan_f_half_rate) 2506 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2507 if (param->scan_f_quarter_rate) 2508 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2509 if (param->scan_f_cck_rates) 2510 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2511 if (param->scan_f_ofdm_rates) 2512 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2513 if (param->scan_f_chan_stat_evnt) 2514 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2515 if (param->scan_f_filter_prb_req) 2516 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2517 if (param->scan_f_bcast_probe) 2518 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2519 if (param->scan_f_offchan_mgmt_tx) 2520 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2521 if (param->scan_f_offchan_data_tx) 2522 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2523 if (param->scan_f_force_active_dfs_chn) 2524 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2525 if (param->scan_f_add_tpc_ie_in_probe) 2526 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2527 if (param->scan_f_add_ds_ie_in_probe) 2528 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2529 if (param->scan_f_add_spoofed_mac_in_probe) 2530 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2531 if (param->scan_f_add_rand_seq_in_probe) 2532 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2533 if (param->scan_f_en_ie_whitelist_in_probe) 2534 cmd->scan_ctrl_flags |= 2535 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2536 2537 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2538 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2539 param->adaptive_dwell_time_mode); 2540 } 2541 2542 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2543 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2544 struct scan_req_params *params) 2545 { 2546 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2547 } 2548 2549 /** 2550 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2551 * @mac: random mac addr 2552 * @mask: random mac mask 2553 * @mac_addr: wmi random mac 2554 * @mac_mask: wmi random mac mask 2555 * 2556 * Return None. 2557 */ 2558 static inline 2559 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2560 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2561 { 2562 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2563 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2564 } 2565 2566 /* 2567 * wmi_fill_vendor_oui() - fill vendor OUIs 2568 * @buf_ptr: pointer to wmi tlv buffer 2569 * @num_vendor_oui: number of vendor OUIs to be filled 2570 * @param_voui: pointer to OUI buffer 2571 * 2572 * This function populates the wmi tlv buffer when vendor specific OUIs are 2573 * present. 2574 * 2575 * Return: None 2576 */ 2577 static inline 2578 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2579 uint32_t *pvoui) 2580 { 2581 wmi_vendor_oui *voui = NULL; 2582 uint32_t i; 2583 2584 voui = (wmi_vendor_oui *)buf_ptr; 2585 2586 for (i = 0; i < num_vendor_oui; i++) { 2587 WMITLV_SET_HDR(&voui[i].tlv_header, 2588 WMITLV_TAG_STRUC_wmi_vendor_oui, 2589 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2590 voui[i].oui_type_subtype = pvoui[i]; 2591 } 2592 } 2593 2594 /* 2595 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2596 * @ie_bitmap: output pointer to ie bit map in cmd 2597 * @num_vendor_oui: output pointer to num vendor OUIs 2598 * @ie_whitelist: input parameter 2599 * 2600 * This function populates the IE whitelist attrs of scan, pno and 2601 * scan oui commands for ie_whitelist parameter. 2602 * 2603 * Return: None 2604 */ 2605 static inline 2606 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2607 uint32_t *num_vendor_oui, 2608 struct probe_req_whitelist_attr *ie_whitelist) 2609 { 2610 uint32_t i = 0; 2611 2612 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2613 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2614 2615 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2616 } 2617 2618 /** 2619 * send_scan_start_cmd_tlv() - WMI scan start function 2620 * @param wmi_handle : handle to WMI. 2621 * @param param : pointer to hold scan start cmd parameter 2622 * 2623 * Return: 0 on success and -ve on failure. 2624 */ 2625 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2626 struct scan_req_params *params) 2627 { 2628 int32_t ret = 0; 2629 int32_t i; 2630 wmi_buf_t wmi_buf; 2631 wmi_start_scan_cmd_fixed_param *cmd; 2632 uint8_t *buf_ptr; 2633 uint32_t *tmp_ptr; 2634 wmi_ssid *ssid = NULL; 2635 wmi_mac_addr *bssid; 2636 int len = sizeof(*cmd); 2637 uint8_t extraie_len_with_pad = 0; 2638 uint8_t phymode_roundup = 0; 2639 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2640 2641 /* Length TLV placeholder for array of uint32_t */ 2642 len += WMI_TLV_HDR_SIZE; 2643 /* calculate the length of buffer required */ 2644 if (params->chan_list.num_chan) 2645 len += params->chan_list.num_chan * sizeof(uint32_t); 2646 2647 /* Length TLV placeholder for array of wmi_ssid structures */ 2648 len += WMI_TLV_HDR_SIZE; 2649 if (params->num_ssids) 2650 len += params->num_ssids * sizeof(wmi_ssid); 2651 2652 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2653 len += WMI_TLV_HDR_SIZE; 2654 if (params->num_bssid) 2655 len += sizeof(wmi_mac_addr) * params->num_bssid; 2656 2657 /* Length TLV placeholder for array of bytes */ 2658 len += WMI_TLV_HDR_SIZE; 2659 if (params->extraie.len) 2660 extraie_len_with_pad = 2661 roundup(params->extraie.len, sizeof(uint32_t)); 2662 len += extraie_len_with_pad; 2663 2664 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2665 if (ie_whitelist->num_vendor_oui) 2666 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2667 2668 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2669 if (params->scan_f_wide_band) 2670 phymode_roundup = 2671 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2672 sizeof(uint32_t)); 2673 len += phymode_roundup; 2674 2675 /* Allocate the memory */ 2676 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2677 if (!wmi_buf) { 2678 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2679 __func__); 2680 return QDF_STATUS_E_FAILURE; 2681 } 2682 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2683 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2684 WMITLV_SET_HDR(&cmd->tlv_header, 2685 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2686 WMITLV_GET_STRUCT_TLVLEN 2687 (wmi_start_scan_cmd_fixed_param)); 2688 2689 cmd->scan_id = params->scan_id; 2690 cmd->scan_req_id = params->scan_req_id; 2691 cmd->vdev_id = params->vdev_id; 2692 cmd->scan_priority = params->scan_priority; 2693 2694 copy_scan_event_cntrl_flags(cmd, params); 2695 2696 cmd->dwell_time_active = params->dwell_time_active; 2697 cmd->dwell_time_passive = params->dwell_time_passive; 2698 cmd->min_rest_time = params->min_rest_time; 2699 cmd->max_rest_time = params->max_rest_time; 2700 cmd->repeat_probe_time = params->repeat_probe_time; 2701 cmd->probe_spacing_time = params->probe_spacing_time; 2702 cmd->idle_time = params->idle_time; 2703 cmd->max_scan_time = params->max_scan_time; 2704 cmd->probe_delay = params->probe_delay; 2705 cmd->burst_duration = params->burst_duration; 2706 cmd->num_chan = params->chan_list.num_chan; 2707 cmd->num_bssid = params->num_bssid; 2708 cmd->num_ssids = params->num_ssids; 2709 cmd->ie_len = params->extraie.len; 2710 cmd->n_probes = params->n_probes; 2711 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2712 2713 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2714 2715 if (params->scan_random.randomize) 2716 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2717 params->scan_random.mac_mask, 2718 &cmd->mac_addr, 2719 &cmd->mac_mask); 2720 2721 if (ie_whitelist->white_list) 2722 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2723 &cmd->num_vendor_oui, 2724 ie_whitelist); 2725 2726 buf_ptr += sizeof(*cmd); 2727 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2728 for (i = 0; i < params->chan_list.num_chan; ++i) 2729 tmp_ptr[i] = params->chan_list.chan[i].freq; 2730 2731 WMITLV_SET_HDR(buf_ptr, 2732 WMITLV_TAG_ARRAY_UINT32, 2733 (params->chan_list.num_chan * sizeof(uint32_t))); 2734 buf_ptr += WMI_TLV_HDR_SIZE + 2735 (params->chan_list.num_chan * sizeof(uint32_t)); 2736 2737 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2738 WMI_LOGE("Invalid value for numSsid"); 2739 goto error; 2740 } 2741 2742 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2743 (params->num_ssids * sizeof(wmi_ssid))); 2744 2745 if (params->num_ssids) { 2746 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2747 for (i = 0; i < params->num_ssids; ++i) { 2748 ssid->ssid_len = params->ssid[i].length; 2749 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2750 params->ssid[i].length); 2751 ssid++; 2752 } 2753 } 2754 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2755 2756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2757 (params->num_bssid * sizeof(wmi_mac_addr))); 2758 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2759 2760 if (params->num_bssid) { 2761 for (i = 0; i < params->num_bssid; ++i) { 2762 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2763 ¶ms->bssid_list[i].bytes[0], bssid); 2764 bssid++; 2765 } 2766 } 2767 2768 buf_ptr += WMI_TLV_HDR_SIZE + 2769 (params->num_bssid * sizeof(wmi_mac_addr)); 2770 2771 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2772 if (params->extraie.len) 2773 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2774 params); 2775 2776 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2777 2778 /* probe req ie whitelisting */ 2779 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2780 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2781 2782 buf_ptr += WMI_TLV_HDR_SIZE; 2783 2784 if (cmd->num_vendor_oui) { 2785 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2786 ie_whitelist->voui); 2787 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2788 } 2789 2790 /* Add phy mode TLV if it's a wide band scan */ 2791 if (params->scan_f_wide_band) { 2792 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2793 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2794 for (i = 0; i < params->chan_list.num_chan; ++i) 2795 buf_ptr[i] = 2796 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2797 buf_ptr += phymode_roundup; 2798 } else { 2799 /* Add ZERO legth phy mode TLV */ 2800 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2801 } 2802 2803 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2804 len, WMI_START_SCAN_CMDID); 2805 if (ret) { 2806 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2807 wmi_buf_free(wmi_buf); 2808 } 2809 return ret; 2810 error: 2811 wmi_buf_free(wmi_buf); 2812 return QDF_STATUS_E_FAILURE; 2813 } 2814 2815 /** 2816 * send_scan_stop_cmd_tlv() - WMI scan start function 2817 * @param wmi_handle : handle to WMI. 2818 * @param param : pointer to hold scan cancel cmd parameter 2819 * 2820 * Return: 0 on success and -ve on failure. 2821 */ 2822 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2823 struct scan_cancel_param *param) 2824 { 2825 wmi_stop_scan_cmd_fixed_param *cmd; 2826 int ret; 2827 int len = sizeof(*cmd); 2828 wmi_buf_t wmi_buf; 2829 2830 /* Allocate the memory */ 2831 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2832 if (!wmi_buf) { 2833 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2834 __func__); 2835 ret = QDF_STATUS_E_NOMEM; 2836 goto error; 2837 } 2838 2839 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2840 WMITLV_SET_HDR(&cmd->tlv_header, 2841 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2842 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2843 cmd->vdev_id = param->vdev_id; 2844 cmd->requestor = param->requester; 2845 cmd->scan_id = param->scan_id; 2846 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2847 param->pdev_id); 2848 /* stop the scan with the corresponding scan_id */ 2849 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2850 /* Cancelling all scans */ 2851 cmd->req_type = WMI_SCAN_STOP_ALL; 2852 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2853 /* Cancelling VAP scans */ 2854 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2855 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2856 /* Cancelling specific scan */ 2857 cmd->req_type = WMI_SCAN_STOP_ONE; 2858 } else { 2859 WMI_LOGE("%s: Invalid Command : ", __func__); 2860 wmi_buf_free(wmi_buf); 2861 return QDF_STATUS_E_INVAL; 2862 } 2863 2864 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2865 len, WMI_STOP_SCAN_CMDID); 2866 if (ret) { 2867 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2868 wmi_buf_free(wmi_buf); 2869 } 2870 2871 error: 2872 return ret; 2873 } 2874 2875 #ifdef CONFIG_MCL 2876 /** 2877 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2878 * @param wmi_handle : handle to WMI. 2879 * @param param : pointer to hold scan channel list parameter 2880 * 2881 * Return: 0 on success and -ve on failure. 2882 */ 2883 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2884 struct scan_chan_list_params *chan_list) 2885 { 2886 wmi_buf_t buf; 2887 QDF_STATUS qdf_status; 2888 wmi_scan_chan_list_cmd_fixed_param *cmd; 2889 int i; 2890 uint8_t *buf_ptr; 2891 wmi_channel_param *chan_info, *tchan_info; 2892 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2893 2894 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2895 buf = wmi_buf_alloc(wmi_handle, len); 2896 if (!buf) { 2897 WMI_LOGE("Failed to allocate memory"); 2898 qdf_status = QDF_STATUS_E_NOMEM; 2899 goto end; 2900 } 2901 2902 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2903 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2904 WMITLV_SET_HDR(&cmd->tlv_header, 2905 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2906 WMITLV_GET_STRUCT_TLVLEN 2907 (wmi_scan_chan_list_cmd_fixed_param)); 2908 2909 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2910 2911 cmd->num_scan_chans = chan_list->num_scan_chans; 2912 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2913 WMITLV_TAG_ARRAY_STRUC, 2914 sizeof(wmi_channel) * chan_list->num_scan_chans); 2915 chan_info = (wmi_channel_param *) 2916 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2917 tchan_info = chan_list->chan_info; 2918 2919 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2920 WMITLV_SET_HDR(&chan_info->tlv_header, 2921 WMITLV_TAG_STRUC_wmi_channel, 2922 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2923 chan_info->mhz = tchan_info->mhz; 2924 chan_info->band_center_freq1 = 2925 tchan_info->band_center_freq1; 2926 chan_info->band_center_freq2 = 2927 tchan_info->band_center_freq2; 2928 chan_info->info = tchan_info->info; 2929 chan_info->reg_info_1 = tchan_info->reg_info_1; 2930 chan_info->reg_info_2 = tchan_info->reg_info_2; 2931 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2932 2933 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2934 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2935 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2936 tchan_info++; 2937 chan_info++; 2938 } 2939 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2940 chan_list->pdev_id); 2941 2942 qdf_status = wmi_unified_cmd_send(wmi_handle, 2943 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2944 2945 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2946 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2947 wmi_buf_free(buf); 2948 } 2949 2950 end: 2951 return qdf_status; 2952 } 2953 #else 2954 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2955 struct scan_chan_list_params *chan_list) 2956 { 2957 wmi_buf_t buf; 2958 QDF_STATUS qdf_status; 2959 wmi_scan_chan_list_cmd_fixed_param *cmd; 2960 int i; 2961 uint8_t *buf_ptr; 2962 wmi_channel *chan_info; 2963 struct channel_param *tchan_info; 2964 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2965 2966 len += sizeof(wmi_channel) * chan_list->nallchans; 2967 buf = wmi_buf_alloc(wmi_handle, len); 2968 if (!buf) { 2969 WMI_LOGE("Failed to allocate memory"); 2970 qdf_status = QDF_STATUS_E_NOMEM; 2971 goto end; 2972 } 2973 2974 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2975 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2976 WMITLV_SET_HDR(&cmd->tlv_header, 2977 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2978 WMITLV_GET_STRUCT_TLVLEN 2979 (wmi_scan_chan_list_cmd_fixed_param)); 2980 2981 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 2982 2983 if (chan_list->append) 2984 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 2985 2986 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2987 chan_list->pdev_id); 2988 cmd->num_scan_chans = chan_list->nallchans; 2989 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2990 WMITLV_TAG_ARRAY_STRUC, 2991 sizeof(wmi_channel) * chan_list->nallchans); 2992 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2993 tchan_info = &(chan_list->ch_param[0]); 2994 2995 for (i = 0; i < chan_list->nallchans; ++i) { 2996 WMITLV_SET_HDR(&chan_info->tlv_header, 2997 WMITLV_TAG_STRUC_wmi_channel, 2998 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2999 chan_info->mhz = tchan_info->mhz; 3000 chan_info->band_center_freq1 = 3001 tchan_info->cfreq1; 3002 chan_info->band_center_freq2 = 3003 tchan_info->cfreq2; 3004 3005 if (tchan_info->is_chan_passive) 3006 WMI_SET_CHANNEL_FLAG(chan_info, 3007 WMI_CHAN_FLAG_PASSIVE); 3008 3009 if (tchan_info->allow_vht) 3010 WMI_SET_CHANNEL_FLAG(chan_info, 3011 WMI_CHAN_FLAG_ALLOW_VHT); 3012 else if (tchan_info->allow_ht) 3013 WMI_SET_CHANNEL_FLAG(chan_info, 3014 WMI_CHAN_FLAG_ALLOW_HT); 3015 WMI_SET_CHANNEL_MODE(chan_info, 3016 tchan_info->phy_mode); 3017 3018 if (tchan_info->half_rate) 3019 WMI_SET_CHANNEL_FLAG(chan_info, 3020 WMI_CHAN_FLAG_HALF_RATE); 3021 3022 if (tchan_info->quarter_rate) 3023 WMI_SET_CHANNEL_FLAG(chan_info, 3024 WMI_CHAN_FLAG_QUARTER_RATE); 3025 3026 /* also fill in power information */ 3027 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3028 tchan_info->minpower); 3029 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3030 tchan_info->maxpower); 3031 WMI_SET_CHANNEL_REG_POWER(chan_info, 3032 tchan_info->maxregpower); 3033 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3034 tchan_info->antennamax); 3035 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3036 tchan_info->reg_class_id); 3037 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3038 tchan_info->maxregpower); 3039 3040 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 3041 3042 tchan_info++; 3043 chan_info++; 3044 } 3045 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3046 chan_list->pdev_id); 3047 3048 qdf_status = wmi_unified_cmd_send( 3049 wmi_handle, 3050 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3051 3052 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3053 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3054 wmi_buf_free(buf); 3055 } 3056 3057 end: 3058 return qdf_status; 3059 } 3060 #endif 3061 3062 /** 3063 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3064 * 3065 * @bufp: Pointer to buffer 3066 * @param: Pointer to tx param 3067 * 3068 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3069 */ 3070 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3071 struct tx_send_params param) 3072 { 3073 wmi_tx_send_params *tx_param; 3074 QDF_STATUS status = QDF_STATUS_SUCCESS; 3075 3076 if (!bufp) { 3077 status = QDF_STATUS_E_FAILURE; 3078 return status; 3079 } 3080 tx_param = (wmi_tx_send_params *)bufp; 3081 WMITLV_SET_HDR(&tx_param->tlv_header, 3082 WMITLV_TAG_STRUC_wmi_tx_send_params, 3083 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3084 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3085 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3086 param.mcs_mask); 3087 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3088 param.nss_mask); 3089 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3090 param.retry_limit); 3091 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3092 param.chain_mask); 3093 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3094 param.bw_mask); 3095 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3096 param.preamble_type); 3097 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3098 param.frame_type); 3099 3100 return status; 3101 } 3102 3103 #ifdef CONFIG_HL_SUPPORT 3104 /** 3105 * send_mgmt_cmd_tlv() - WMI scan start function 3106 * @wmi_handle : handle to WMI. 3107 * @param : pointer to hold mgmt cmd parameter 3108 * 3109 * Return: 0 on success and -ve on failure. 3110 */ 3111 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3112 struct wmi_mgmt_params *param) 3113 { 3114 wmi_buf_t buf; 3115 uint8_t *bufp; 3116 int32_t cmd_len; 3117 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3118 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3119 mgmt_tx_dl_frm_len; 3120 3121 if (param->frm_len > mgmt_tx_dl_frm_len) { 3122 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 3123 __func__, param->frm_len, mgmt_tx_dl_frm_len); 3124 return QDF_STATUS_E_INVAL; 3125 } 3126 3127 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3128 WMI_TLV_HDR_SIZE + 3129 roundup(bufp_len, sizeof(uint32_t)); 3130 3131 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3132 if (!buf) { 3133 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3134 return QDF_STATUS_E_NOMEM; 3135 } 3136 3137 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3138 bufp = (uint8_t *) cmd; 3139 WMITLV_SET_HDR(&cmd->tlv_header, 3140 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3141 WMITLV_GET_STRUCT_TLVLEN 3142 (wmi_mgmt_tx_send_cmd_fixed_param)); 3143 3144 cmd->vdev_id = param->vdev_id; 3145 3146 cmd->desc_id = param->desc_id; 3147 cmd->chanfreq = param->chanfreq; 3148 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3149 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3150 sizeof(uint32_t))); 3151 bufp += WMI_TLV_HDR_SIZE; 3152 qdf_mem_copy(bufp, param->pdata, bufp_len); 3153 3154 cmd->frame_len = param->frm_len; 3155 cmd->buf_len = bufp_len; 3156 cmd->tx_params_valid = param->tx_params_valid; 3157 3158 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3159 bufp, cmd->vdev_id, cmd->chanfreq); 3160 3161 bufp += roundup(bufp_len, sizeof(uint32_t)); 3162 if (param->tx_params_valid) { 3163 if (populate_tx_send_params(bufp, param->tx_param) != 3164 QDF_STATUS_SUCCESS) { 3165 WMI_LOGE("%s: Populate TX send params failed", 3166 __func__); 3167 goto free_buf; 3168 } 3169 cmd_len += sizeof(wmi_tx_send_params); 3170 } 3171 3172 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3173 WMI_MGMT_TX_SEND_CMDID)) { 3174 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3175 goto free_buf; 3176 } 3177 return QDF_STATUS_SUCCESS; 3178 3179 free_buf: 3180 wmi_buf_free(buf); 3181 return QDF_STATUS_E_FAILURE; 3182 } 3183 #else 3184 /** 3185 * send_mgmt_cmd_tlv() - WMI scan start function 3186 * @wmi_handle : handle to WMI. 3187 * @param : pointer to hold mgmt cmd parameter 3188 * 3189 * Return: 0 on success and -ve on failure. 3190 */ 3191 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3192 struct wmi_mgmt_params *param) 3193 { 3194 wmi_buf_t buf; 3195 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3196 int32_t cmd_len; 3197 uint64_t dma_addr; 3198 void *qdf_ctx = param->qdf_ctx; 3199 uint8_t *bufp; 3200 QDF_STATUS status = QDF_STATUS_SUCCESS; 3201 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3202 mgmt_tx_dl_frm_len; 3203 3204 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3205 WMI_TLV_HDR_SIZE + 3206 roundup(bufp_len, sizeof(uint32_t)); 3207 3208 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3209 if (!buf) { 3210 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3211 return QDF_STATUS_E_NOMEM; 3212 } 3213 3214 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3215 bufp = (uint8_t *) cmd; 3216 WMITLV_SET_HDR(&cmd->tlv_header, 3217 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3218 WMITLV_GET_STRUCT_TLVLEN 3219 (wmi_mgmt_tx_send_cmd_fixed_param)); 3220 3221 cmd->vdev_id = param->vdev_id; 3222 3223 cmd->desc_id = param->desc_id; 3224 cmd->chanfreq = param->chanfreq; 3225 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3226 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3227 sizeof(uint32_t))); 3228 bufp += WMI_TLV_HDR_SIZE; 3229 qdf_mem_copy(bufp, param->pdata, bufp_len); 3230 3231 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3232 QDF_DMA_TO_DEVICE); 3233 if (status != QDF_STATUS_SUCCESS) { 3234 WMI_LOGE("%s: wmi buf map failed", __func__); 3235 goto free_buf; 3236 } 3237 3238 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3239 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3240 #if defined(HTT_PADDR64) 3241 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3242 #endif 3243 cmd->frame_len = param->frm_len; 3244 cmd->buf_len = bufp_len; 3245 cmd->tx_params_valid = param->tx_params_valid; 3246 3247 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3248 bufp, cmd->vdev_id, cmd->chanfreq); 3249 3250 bufp += roundup(bufp_len, sizeof(uint32_t)); 3251 if (param->tx_params_valid) { 3252 status = populate_tx_send_params(bufp, param->tx_param); 3253 if (status != QDF_STATUS_SUCCESS) { 3254 WMI_LOGE("%s: Populate TX send params failed", 3255 __func__); 3256 goto unmap_tx_frame; 3257 } 3258 cmd_len += sizeof(wmi_tx_send_params); 3259 } 3260 3261 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3262 WMI_MGMT_TX_SEND_CMDID)) { 3263 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3264 goto unmap_tx_frame; 3265 } 3266 return QDF_STATUS_SUCCESS; 3267 3268 unmap_tx_frame: 3269 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3270 QDF_DMA_TO_DEVICE); 3271 free_buf: 3272 wmi_buf_free(buf); 3273 return QDF_STATUS_E_FAILURE; 3274 } 3275 #endif /* CONFIG_HL_SUPPORT */ 3276 3277 /** 3278 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3279 * @wmi_handle : handle to WMI. 3280 * @param : pointer to offchan data tx cmd parameter 3281 * 3282 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3283 */ 3284 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3285 struct wmi_offchan_data_tx_params *param) 3286 { 3287 wmi_buf_t buf; 3288 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3289 int32_t cmd_len; 3290 uint64_t dma_addr; 3291 void *qdf_ctx = param->qdf_ctx; 3292 uint8_t *bufp; 3293 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3294 param->frm_len : mgmt_tx_dl_frm_len; 3295 QDF_STATUS status = QDF_STATUS_SUCCESS; 3296 3297 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3298 WMI_TLV_HDR_SIZE + 3299 roundup(bufp_len, sizeof(uint32_t)); 3300 3301 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3302 if (!buf) { 3303 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3304 return QDF_STATUS_E_NOMEM; 3305 } 3306 3307 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3308 bufp = (uint8_t *) cmd; 3309 WMITLV_SET_HDR(&cmd->tlv_header, 3310 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3311 WMITLV_GET_STRUCT_TLVLEN 3312 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3313 3314 cmd->vdev_id = param->vdev_id; 3315 3316 cmd->desc_id = param->desc_id; 3317 cmd->chanfreq = param->chanfreq; 3318 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3319 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3320 sizeof(uint32_t))); 3321 bufp += WMI_TLV_HDR_SIZE; 3322 qdf_mem_copy(bufp, param->pdata, bufp_len); 3323 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3324 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3325 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3326 #if defined(HTT_PADDR64) 3327 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3328 #endif 3329 cmd->frame_len = param->frm_len; 3330 cmd->buf_len = bufp_len; 3331 cmd->tx_params_valid = param->tx_params_valid; 3332 3333 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3334 bufp, cmd->vdev_id, cmd->chanfreq); 3335 3336 bufp += roundup(bufp_len, sizeof(uint32_t)); 3337 if (param->tx_params_valid) { 3338 status = populate_tx_send_params(bufp, param->tx_param); 3339 if (status != QDF_STATUS_SUCCESS) { 3340 WMI_LOGE("%s: Populate TX send params failed", 3341 __func__); 3342 goto err1; 3343 } 3344 cmd_len += sizeof(wmi_tx_send_params); 3345 } 3346 3347 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3348 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3349 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3350 goto err1; 3351 } 3352 3353 return QDF_STATUS_SUCCESS; 3354 3355 err1: 3356 wmi_buf_free(buf); 3357 return QDF_STATUS_E_FAILURE; 3358 } 3359 3360 /** 3361 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3362 * @wmi_handle: wmi handle 3363 * @param_value: parameter value 3364 * 3365 * Return: QDF_STATUS_SUCCESS for success or error code 3366 */ 3367 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3368 uint32_t param_value) 3369 { 3370 QDF_STATUS ret; 3371 wmi_modem_power_state_cmd_param *cmd; 3372 wmi_buf_t buf; 3373 uint16_t len = sizeof(*cmd); 3374 3375 buf = wmi_buf_alloc(wmi_handle, len); 3376 if (!buf) { 3377 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3378 return QDF_STATUS_E_NOMEM; 3379 } 3380 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3381 WMITLV_SET_HDR(&cmd->tlv_header, 3382 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3383 WMITLV_GET_STRUCT_TLVLEN 3384 (wmi_modem_power_state_cmd_param)); 3385 cmd->modem_power_state = param_value; 3386 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3387 param_value); 3388 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3389 WMI_MODEM_POWER_STATE_CMDID); 3390 if (QDF_IS_STATUS_ERROR(ret)) { 3391 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3392 wmi_buf_free(buf); 3393 } 3394 3395 return ret; 3396 } 3397 3398 /** 3399 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3400 * @wmi_handle: wmi handle 3401 * @vdev_id: vdev id 3402 * @val: value 3403 * 3404 * Return: QDF_STATUS_SUCCESS for success or error code. 3405 */ 3406 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3407 uint32_t vdev_id, uint8_t val) 3408 { 3409 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3410 wmi_buf_t buf; 3411 int32_t len = sizeof(*cmd); 3412 3413 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3414 3415 buf = wmi_buf_alloc(wmi_handle, len); 3416 if (!buf) { 3417 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3418 return QDF_STATUS_E_NOMEM; 3419 } 3420 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3421 WMITLV_SET_HDR(&cmd->tlv_header, 3422 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3423 WMITLV_GET_STRUCT_TLVLEN 3424 (wmi_sta_powersave_mode_cmd_fixed_param)); 3425 cmd->vdev_id = vdev_id; 3426 if (val) 3427 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3428 else 3429 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3430 3431 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3432 WMI_STA_POWERSAVE_MODE_CMDID)) { 3433 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3434 vdev_id, val); 3435 wmi_buf_free(buf); 3436 return QDF_STATUS_E_FAILURE; 3437 } 3438 return 0; 3439 } 3440 3441 /** 3442 * send_set_mimops_cmd_tlv() - set MIMO powersave 3443 * @wmi_handle: wmi handle 3444 * @vdev_id: vdev id 3445 * @value: value 3446 * 3447 * Return: QDF_STATUS_SUCCESS for success or error code. 3448 */ 3449 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3450 uint8_t vdev_id, int value) 3451 { 3452 QDF_STATUS ret; 3453 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3454 wmi_buf_t buf; 3455 uint16_t len = sizeof(*cmd); 3456 3457 buf = wmi_buf_alloc(wmi_handle, len); 3458 if (!buf) { 3459 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3460 return QDF_STATUS_E_NOMEM; 3461 } 3462 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3463 WMITLV_SET_HDR(&cmd->tlv_header, 3464 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3465 WMITLV_GET_STRUCT_TLVLEN 3466 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3467 3468 cmd->vdev_id = vdev_id; 3469 3470 /* WMI_SMPS_FORCED_MODE values do not directly map 3471 * to SM power save values defined in the specification. 3472 * Make sure to send the right mapping. 3473 */ 3474 switch (value) { 3475 case 0: 3476 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3477 break; 3478 case 1: 3479 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3480 break; 3481 case 2: 3482 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3483 break; 3484 case 3: 3485 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3486 break; 3487 default: 3488 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3489 wmi_buf_free(buf); 3490 return QDF_STATUS_E_FAILURE; 3491 } 3492 3493 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3494 3495 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3496 WMI_STA_SMPS_FORCE_MODE_CMDID); 3497 if (QDF_IS_STATUS_ERROR(ret)) { 3498 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3499 wmi_buf_free(buf); 3500 } 3501 3502 return ret; 3503 } 3504 3505 /** 3506 * send_set_smps_params_cmd_tlv() - set smps params 3507 * @wmi_handle: wmi handle 3508 * @vdev_id: vdev id 3509 * @value: value 3510 * 3511 * Return: QDF_STATUS_SUCCESS for success or error code. 3512 */ 3513 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3514 int value) 3515 { 3516 QDF_STATUS ret; 3517 wmi_sta_smps_param_cmd_fixed_param *cmd; 3518 wmi_buf_t buf; 3519 uint16_t len = sizeof(*cmd); 3520 3521 buf = wmi_buf_alloc(wmi_handle, len); 3522 if (!buf) { 3523 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3524 return QDF_STATUS_E_NOMEM; 3525 } 3526 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3527 WMITLV_SET_HDR(&cmd->tlv_header, 3528 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3529 WMITLV_GET_STRUCT_TLVLEN 3530 (wmi_sta_smps_param_cmd_fixed_param)); 3531 3532 cmd->vdev_id = vdev_id; 3533 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3534 cmd->param = 3535 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3536 3537 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3538 cmd->param); 3539 3540 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3541 WMI_STA_SMPS_PARAM_CMDID); 3542 if (QDF_IS_STATUS_ERROR(ret)) { 3543 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3544 wmi_buf_free(buf); 3545 } 3546 3547 return ret; 3548 } 3549 3550 /** 3551 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3552 * @wmi_handle: wmi handle 3553 * @noa: p2p power save parameters 3554 * 3555 * Return: CDF status 3556 */ 3557 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3558 struct p2p_ps_params *noa) 3559 { 3560 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3561 wmi_p2p_noa_descriptor *noa_discriptor; 3562 wmi_buf_t buf; 3563 uint8_t *buf_ptr; 3564 uint16_t len; 3565 QDF_STATUS status; 3566 uint32_t duration; 3567 3568 WMI_LOGD("%s: Enter", __func__); 3569 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3570 buf = wmi_buf_alloc(wmi_handle, len); 3571 if (!buf) { 3572 WMI_LOGE("Failed to allocate memory"); 3573 status = QDF_STATUS_E_FAILURE; 3574 goto end; 3575 } 3576 3577 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3578 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3579 WMITLV_SET_HDR(&cmd->tlv_header, 3580 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3581 WMITLV_GET_STRUCT_TLVLEN 3582 (wmi_p2p_set_noa_cmd_fixed_param)); 3583 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3584 cmd->vdev_id = noa->session_id; 3585 cmd->enable = (duration) ? true : false; 3586 cmd->num_noa = 1; 3587 3588 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3589 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3590 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3591 sizeof 3592 (wmi_p2p_set_noa_cmd_fixed_param) 3593 + WMI_TLV_HDR_SIZE); 3594 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3595 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3596 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3597 noa_discriptor->type_count = noa->count; 3598 noa_discriptor->duration = duration; 3599 noa_discriptor->interval = noa->interval; 3600 noa_discriptor->start_time = 0; 3601 3602 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3603 cmd->vdev_id, noa->count, noa_discriptor->duration, 3604 noa->interval); 3605 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3606 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3607 if (QDF_IS_STATUS_ERROR(status)) { 3608 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3609 wmi_buf_free(buf); 3610 } 3611 3612 end: 3613 WMI_LOGD("%s: Exit", __func__); 3614 return status; 3615 } 3616 3617 3618 /** 3619 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3620 * @wmi_handle: wmi handle 3621 * @noa: p2p opp power save parameters 3622 * 3623 * Return: CDF status 3624 */ 3625 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3626 struct p2p_ps_params *oppps) 3627 { 3628 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3629 wmi_buf_t buf; 3630 QDF_STATUS status; 3631 3632 WMI_LOGD("%s: Enter", __func__); 3633 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3634 if (!buf) { 3635 WMI_LOGE("Failed to allocate memory"); 3636 status = QDF_STATUS_E_FAILURE; 3637 goto end; 3638 } 3639 3640 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3641 WMITLV_SET_HDR(&cmd->tlv_header, 3642 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3643 WMITLV_GET_STRUCT_TLVLEN 3644 (wmi_p2p_set_oppps_cmd_fixed_param)); 3645 cmd->vdev_id = oppps->session_id; 3646 if (oppps->ctwindow) 3647 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3648 3649 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3650 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3651 cmd->vdev_id, oppps->ctwindow); 3652 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3653 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3654 if (QDF_IS_STATUS_ERROR(status)) { 3655 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3656 wmi_buf_free(buf); 3657 } 3658 3659 end: 3660 WMI_LOGD("%s: Exit", __func__); 3661 return status; 3662 } 3663 3664 #ifdef CONVERGED_P2P_ENABLE 3665 /** 3666 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3667 * @wmi_handle: wmi handle 3668 * @param: p2p listen offload start parameters 3669 * 3670 * Return: QDF status 3671 */ 3672 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3673 struct p2p_lo_start *param) 3674 { 3675 wmi_buf_t buf; 3676 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3677 int32_t len = sizeof(*cmd); 3678 uint8_t *buf_ptr; 3679 QDF_STATUS status; 3680 int device_types_len_aligned; 3681 int probe_resp_len_aligned; 3682 3683 if (!param) { 3684 WMI_LOGE("lo start param is null"); 3685 return QDF_STATUS_E_INVAL; 3686 } 3687 3688 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3689 3690 device_types_len_aligned = 3691 qdf_roundup(param->dev_types_len, 3692 sizeof(uint32_t)); 3693 probe_resp_len_aligned = 3694 qdf_roundup(param->probe_resp_len, 3695 sizeof(uint32_t)); 3696 3697 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3698 probe_resp_len_aligned; 3699 3700 buf = wmi_buf_alloc(wmi_handle, len); 3701 if (!buf) { 3702 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3703 __func__); 3704 return QDF_STATUS_E_NOMEM; 3705 } 3706 3707 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3708 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3709 3710 WMITLV_SET_HDR(&cmd->tlv_header, 3711 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3712 WMITLV_GET_STRUCT_TLVLEN( 3713 wmi_p2p_lo_start_cmd_fixed_param)); 3714 3715 cmd->vdev_id = param->vdev_id; 3716 cmd->ctl_flags = param->ctl_flags; 3717 cmd->channel = param->freq; 3718 cmd->period = param->period; 3719 cmd->interval = param->interval; 3720 cmd->count = param->count; 3721 cmd->device_types_len = param->dev_types_len; 3722 cmd->prob_resp_len = param->probe_resp_len; 3723 3724 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3726 device_types_len_aligned); 3727 buf_ptr += WMI_TLV_HDR_SIZE; 3728 qdf_mem_copy(buf_ptr, param->device_types, 3729 param->dev_types_len); 3730 3731 buf_ptr += device_types_len_aligned; 3732 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3733 probe_resp_len_aligned); 3734 buf_ptr += WMI_TLV_HDR_SIZE; 3735 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3736 param->probe_resp_len); 3737 3738 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3739 cmd->channel, cmd->period, cmd->interval, cmd->count); 3740 3741 status = wmi_unified_cmd_send(wmi_handle, 3742 buf, len, 3743 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3744 if (status != QDF_STATUS_SUCCESS) { 3745 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3746 __func__, status); 3747 wmi_buf_free(buf); 3748 return status; 3749 } 3750 3751 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3752 3753 return QDF_STATUS_SUCCESS; 3754 } 3755 3756 /** 3757 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3758 * @wmi_handle: wmi handle 3759 * @param: p2p listen offload stop parameters 3760 * 3761 * Return: QDF status 3762 */ 3763 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3764 uint8_t vdev_id) 3765 { 3766 wmi_buf_t buf; 3767 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3768 int32_t len; 3769 QDF_STATUS status; 3770 3771 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3772 3773 len = sizeof(*cmd); 3774 buf = wmi_buf_alloc(wmi_handle, len); 3775 if (!buf) { 3776 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3777 __func__); 3778 return QDF_STATUS_E_NOMEM; 3779 } 3780 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3781 3782 WMITLV_SET_HDR(&cmd->tlv_header, 3783 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3784 WMITLV_GET_STRUCT_TLVLEN( 3785 wmi_p2p_lo_stop_cmd_fixed_param)); 3786 3787 cmd->vdev_id = vdev_id; 3788 3789 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3790 3791 status = wmi_unified_cmd_send(wmi_handle, 3792 buf, len, 3793 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3794 if (status != QDF_STATUS_SUCCESS) { 3795 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3796 __func__, status); 3797 wmi_buf_free(buf); 3798 return status; 3799 } 3800 3801 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3802 3803 return QDF_STATUS_SUCCESS; 3804 } 3805 #endif /* End of CONVERGED_P2P_ENABLE */ 3806 3807 /** 3808 * send_get_temperature_cmd_tlv() - get pdev temperature req 3809 * @wmi_handle: wmi handle 3810 * 3811 * Return: QDF_STATUS_SUCCESS for success or error code. 3812 */ 3813 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3814 { 3815 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3816 wmi_buf_t wmi_buf; 3817 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3818 uint8_t *buf_ptr; 3819 3820 if (!wmi_handle) { 3821 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3822 return QDF_STATUS_E_INVAL; 3823 } 3824 3825 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3826 if (!wmi_buf) { 3827 WMI_LOGE(FL("wmi_buf_alloc failed")); 3828 return QDF_STATUS_E_NOMEM; 3829 } 3830 3831 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3832 3833 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3834 WMITLV_SET_HDR(&cmd->tlv_header, 3835 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3836 WMITLV_GET_STRUCT_TLVLEN 3837 (wmi_pdev_get_temperature_cmd_fixed_param)); 3838 3839 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3840 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3841 WMI_LOGE(FL("failed to send get temperature command")); 3842 wmi_buf_free(wmi_buf); 3843 return QDF_STATUS_E_FAILURE; 3844 } 3845 3846 return QDF_STATUS_SUCCESS; 3847 } 3848 3849 /** 3850 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3851 * @wmi_handle: wmi handle 3852 * @vdevid: vdev id 3853 * @peer_addr: peer mac address 3854 * @auto_triggerparam: auto trigger parameters 3855 * @num_ac: number of access category 3856 * 3857 * This function sets the trigger 3858 * uapsd params such as service interval, delay interval 3859 * and suspend interval which will be used by the firmware 3860 * to send trigger frames periodically when there is no 3861 * traffic on the transmit side. 3862 * 3863 * Return: QDF_STATUS_SUCCESS for success or error code. 3864 */ 3865 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3866 struct sta_uapsd_trig_params *param) 3867 { 3868 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3869 QDF_STATUS ret; 3870 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3871 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3872 uint32_t i; 3873 wmi_buf_t buf; 3874 uint8_t *buf_ptr; 3875 struct sta_uapsd_params *uapsd_param; 3876 wmi_sta_uapsd_auto_trig_param *trig_param; 3877 3878 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3879 if (!buf) { 3880 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3881 return QDF_STATUS_E_NOMEM; 3882 } 3883 3884 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3885 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3886 WMITLV_SET_HDR(&cmd->tlv_header, 3887 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3888 WMITLV_GET_STRUCT_TLVLEN 3889 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3890 cmd->vdev_id = param->vdevid; 3891 cmd->num_ac = param->num_ac; 3892 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3893 3894 /* TLV indicating array of structures to follow */ 3895 buf_ptr += sizeof(*cmd); 3896 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3897 3898 buf_ptr += WMI_TLV_HDR_SIZE; 3899 3900 /* 3901 * Update tag and length for uapsd auto trigger params (this will take 3902 * care of updating tag and length if it is not pre-filled by caller). 3903 */ 3904 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3905 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3906 for (i = 0; i < param->num_ac; i++) { 3907 WMITLV_SET_HDR((buf_ptr + 3908 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3909 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3910 WMITLV_GET_STRUCT_TLVLEN 3911 (wmi_sta_uapsd_auto_trig_param)); 3912 trig_param->wmm_ac = uapsd_param->wmm_ac; 3913 trig_param->user_priority = uapsd_param->user_priority; 3914 trig_param->service_interval = uapsd_param->service_interval; 3915 trig_param->suspend_interval = uapsd_param->suspend_interval; 3916 trig_param->delay_interval = uapsd_param->delay_interval; 3917 trig_param++; 3918 uapsd_param++; 3919 } 3920 3921 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3922 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3923 if (QDF_IS_STATUS_ERROR(ret)) { 3924 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3925 wmi_buf_free(buf); 3926 } 3927 3928 return ret; 3929 } 3930 3931 #ifdef WLAN_FEATURE_DSRC 3932 /** 3933 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3934 * @wmi_handle: pointer to the wmi handle 3935 * @utc: pointer to the UTC time struct 3936 * 3937 * Return: 0 on succes 3938 */ 3939 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3940 struct ocb_utc_param *utc) 3941 { 3942 QDF_STATUS ret; 3943 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3944 uint8_t *buf_ptr; 3945 uint32_t len, i; 3946 wmi_buf_t buf; 3947 3948 len = sizeof(*cmd); 3949 buf = wmi_buf_alloc(wmi_handle, len); 3950 if (!buf) { 3951 WMI_LOGE(FL("wmi_buf_alloc failed")); 3952 return QDF_STATUS_E_NOMEM; 3953 } 3954 3955 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3956 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3957 WMITLV_SET_HDR(&cmd->tlv_header, 3958 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3959 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3960 cmd->vdev_id = utc->vdev_id; 3961 3962 for (i = 0; i < SIZE_UTC_TIME; i++) 3963 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 3964 3965 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 3966 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 3967 3968 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3969 WMI_OCB_SET_UTC_TIME_CMDID); 3970 if (QDF_IS_STATUS_ERROR(ret)) { 3971 WMI_LOGE(FL("Failed to set OCB UTC time")); 3972 wmi_buf_free(buf); 3973 } 3974 3975 return ret; 3976 } 3977 3978 /** 3979 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 3980 * frames on a channel 3981 * @wmi_handle: pointer to the wmi handle 3982 * @timing_advert: pointer to the timing advertisement struct 3983 * 3984 * Return: 0 on succes 3985 */ 3986 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 3987 struct ocb_timing_advert_param *timing_advert) 3988 { 3989 QDF_STATUS ret; 3990 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 3991 uint8_t *buf_ptr; 3992 uint32_t len, len_template; 3993 wmi_buf_t buf; 3994 3995 len = sizeof(*cmd) + 3996 WMI_TLV_HDR_SIZE; 3997 3998 len_template = timing_advert->template_length; 3999 /* Add padding to the template if needed */ 4000 if (len_template % 4 != 0) 4001 len_template += 4 - (len_template % 4); 4002 len += len_template; 4003 4004 buf = wmi_buf_alloc(wmi_handle, len); 4005 if (!buf) { 4006 WMI_LOGE(FL("wmi_buf_alloc failed")); 4007 return QDF_STATUS_E_NOMEM; 4008 } 4009 4010 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4011 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 4012 WMITLV_SET_HDR(&cmd->tlv_header, 4013 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 4014 WMITLV_GET_STRUCT_TLVLEN( 4015 wmi_ocb_start_timing_advert_cmd_fixed_param)); 4016 cmd->vdev_id = timing_advert->vdev_id; 4017 cmd->repeat_rate = timing_advert->repeat_rate; 4018 cmd->channel_freq = timing_advert->chan_freq; 4019 cmd->timestamp_offset = timing_advert->timestamp_offset; 4020 cmd->time_value_offset = timing_advert->time_value_offset; 4021 cmd->timing_advert_template_length = timing_advert->template_length; 4022 buf_ptr += sizeof(*cmd); 4023 4024 /* Add the timing advert template */ 4025 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4026 len_template); 4027 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 4028 (uint8_t *)timing_advert->template_value, 4029 timing_advert->template_length); 4030 4031 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4032 WMI_OCB_START_TIMING_ADVERT_CMDID); 4033 if (QDF_IS_STATUS_ERROR(ret)) { 4034 WMI_LOGE(FL("Failed to start OCB timing advert")); 4035 wmi_buf_free(buf); 4036 } 4037 4038 return ret; 4039 } 4040 4041 /** 4042 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 4043 * on a channel 4044 * @wmi_handle: pointer to the wmi handle 4045 * @timing_advert: pointer to the timing advertisement struct 4046 * 4047 * Return: 0 on succes 4048 */ 4049 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 4050 struct ocb_timing_advert_param *timing_advert) 4051 { 4052 QDF_STATUS ret; 4053 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 4054 uint8_t *buf_ptr; 4055 uint32_t len; 4056 wmi_buf_t buf; 4057 4058 len = sizeof(*cmd); 4059 buf = wmi_buf_alloc(wmi_handle, len); 4060 if (!buf) { 4061 WMI_LOGE(FL("wmi_buf_alloc failed")); 4062 return QDF_STATUS_E_NOMEM; 4063 } 4064 4065 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4066 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 4067 WMITLV_SET_HDR(&cmd->tlv_header, 4068 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 4069 WMITLV_GET_STRUCT_TLVLEN( 4070 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 4071 cmd->vdev_id = timing_advert->vdev_id; 4072 cmd->channel_freq = timing_advert->chan_freq; 4073 4074 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4075 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 4076 if (QDF_IS_STATUS_ERROR(ret)) { 4077 WMI_LOGE(FL("Failed to stop OCB timing advert")); 4078 wmi_buf_free(buf); 4079 } 4080 4081 return ret; 4082 } 4083 4084 /** 4085 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 4086 * @wmi_handle: pointer to the wmi handle 4087 * @request: pointer to the request 4088 * 4089 * Return: 0 on succes 4090 */ 4091 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 4092 uint8_t vdev_id) 4093 { 4094 QDF_STATUS ret; 4095 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 4096 uint8_t *buf_ptr; 4097 wmi_buf_t buf; 4098 int32_t len; 4099 4100 len = sizeof(*cmd); 4101 buf = wmi_buf_alloc(wmi_handle, len); 4102 if (!buf) { 4103 WMI_LOGE(FL("wmi_buf_alloc failed")); 4104 return QDF_STATUS_E_NOMEM; 4105 } 4106 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4107 4108 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 4109 qdf_mem_zero(cmd, len); 4110 WMITLV_SET_HDR(&cmd->tlv_header, 4111 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 4112 WMITLV_GET_STRUCT_TLVLEN( 4113 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 4114 cmd->vdev_id = vdev_id; 4115 4116 /* Send the WMI command */ 4117 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4118 WMI_OCB_GET_TSF_TIMER_CMDID); 4119 /* If there is an error, set the completion event */ 4120 if (QDF_IS_STATUS_ERROR(ret)) { 4121 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4122 wmi_buf_free(buf); 4123 } 4124 4125 return ret; 4126 } 4127 4128 /** 4129 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 4130 * @wmi_handle: pointer to the wmi handle 4131 * @get_stats_param: pointer to the dcc stats 4132 * 4133 * Return: 0 on succes 4134 */ 4135 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 4136 struct ocb_dcc_get_stats_param *get_stats_param) 4137 { 4138 QDF_STATUS ret; 4139 wmi_dcc_get_stats_cmd_fixed_param *cmd; 4140 wmi_dcc_channel_stats_request *channel_stats_array; 4141 wmi_buf_t buf; 4142 uint8_t *buf_ptr; 4143 uint32_t len; 4144 uint32_t i; 4145 4146 /* Validate the input */ 4147 if (get_stats_param->request_array_len != 4148 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4149 WMI_LOGE(FL("Invalid parameter")); 4150 return QDF_STATUS_E_INVAL; 4151 } 4152 4153 /* Allocate memory for the WMI command */ 4154 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4155 get_stats_param->request_array_len; 4156 4157 buf = wmi_buf_alloc(wmi_handle, len); 4158 if (!buf) { 4159 WMI_LOGE(FL("wmi_buf_alloc failed")); 4160 return QDF_STATUS_E_NOMEM; 4161 } 4162 4163 buf_ptr = wmi_buf_data(buf); 4164 qdf_mem_zero(buf_ptr, len); 4165 4166 /* Populate the WMI command */ 4167 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4168 buf_ptr += sizeof(*cmd); 4169 4170 WMITLV_SET_HDR(&cmd->tlv_header, 4171 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4172 WMITLV_GET_STRUCT_TLVLEN( 4173 wmi_dcc_get_stats_cmd_fixed_param)); 4174 cmd->vdev_id = get_stats_param->vdev_id; 4175 cmd->num_channels = get_stats_param->channel_count; 4176 4177 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4178 get_stats_param->request_array_len); 4179 buf_ptr += WMI_TLV_HDR_SIZE; 4180 4181 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4182 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4183 get_stats_param->request_array_len); 4184 for (i = 0; i < cmd->num_channels; i++) 4185 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4186 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4187 WMITLV_GET_STRUCT_TLVLEN( 4188 wmi_dcc_channel_stats_request)); 4189 4190 /* Send the WMI command */ 4191 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4192 WMI_DCC_GET_STATS_CMDID); 4193 4194 if (QDF_IS_STATUS_ERROR(ret)) { 4195 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4196 wmi_buf_free(buf); 4197 } 4198 4199 return ret; 4200 } 4201 4202 /** 4203 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4204 * @wmi_handle: pointer to the wmi handle 4205 * @vdev_id: vdev id 4206 * @dcc_stats_bitmap: dcc status bitmap 4207 * 4208 * Return: 0 on succes 4209 */ 4210 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4211 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4212 { 4213 QDF_STATUS ret; 4214 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4215 wmi_buf_t buf; 4216 uint8_t *buf_ptr; 4217 uint32_t len; 4218 4219 /* Allocate memory for the WMI command */ 4220 len = sizeof(*cmd); 4221 4222 buf = wmi_buf_alloc(wmi_handle, len); 4223 if (!buf) { 4224 WMI_LOGE(FL("wmi_buf_alloc failed")); 4225 return QDF_STATUS_E_NOMEM; 4226 } 4227 4228 buf_ptr = wmi_buf_data(buf); 4229 qdf_mem_zero(buf_ptr, len); 4230 4231 /* Populate the WMI command */ 4232 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4233 4234 WMITLV_SET_HDR(&cmd->tlv_header, 4235 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4236 WMITLV_GET_STRUCT_TLVLEN( 4237 wmi_dcc_clear_stats_cmd_fixed_param)); 4238 cmd->vdev_id = vdev_id; 4239 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4240 4241 /* Send the WMI command */ 4242 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4243 WMI_DCC_CLEAR_STATS_CMDID); 4244 if (QDF_IS_STATUS_ERROR(ret)) { 4245 WMI_LOGE(FL("Failed to send the WMI command")); 4246 wmi_buf_free(buf); 4247 } 4248 4249 return ret; 4250 } 4251 4252 /** 4253 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4254 * @wmi_handle: pointer to the wmi handle 4255 * @update_ndl_param: pointer to the request parameters 4256 * 4257 * Return: 0 on success 4258 */ 4259 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4260 struct ocb_dcc_update_ndl_param *update_ndl_param) 4261 { 4262 QDF_STATUS qdf_status; 4263 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4264 wmi_dcc_ndl_chan *ndl_chan_array; 4265 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4266 uint32_t active_state_count; 4267 wmi_buf_t buf; 4268 uint8_t *buf_ptr; 4269 uint32_t len; 4270 uint32_t i; 4271 4272 /* validate the input */ 4273 if (update_ndl_param->dcc_ndl_chan_list_len != 4274 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4275 WMI_LOGE(FL("Invalid parameter")); 4276 return QDF_STATUS_E_INVAL; 4277 } 4278 active_state_count = 0; 4279 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4280 for (i = 0; i < update_ndl_param->channel_count; i++) 4281 active_state_count += 4282 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4283 if (update_ndl_param->dcc_ndl_active_state_list_len != 4284 active_state_count * sizeof(*ndl_active_state_array)) { 4285 WMI_LOGE(FL("Invalid parameter")); 4286 return QDF_STATUS_E_INVAL; 4287 } 4288 4289 /* Allocate memory for the WMI command */ 4290 len = sizeof(*cmd) + 4291 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4292 WMI_TLV_HDR_SIZE + 4293 update_ndl_param->dcc_ndl_active_state_list_len; 4294 4295 buf = wmi_buf_alloc(wmi_handle, len); 4296 if (!buf) { 4297 WMI_LOGE(FL("wmi_buf_alloc failed")); 4298 return QDF_STATUS_E_NOMEM; 4299 } 4300 4301 buf_ptr = wmi_buf_data(buf); 4302 qdf_mem_zero(buf_ptr, len); 4303 4304 /* Populate the WMI command */ 4305 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4306 buf_ptr += sizeof(*cmd); 4307 4308 WMITLV_SET_HDR(&cmd->tlv_header, 4309 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4310 WMITLV_GET_STRUCT_TLVLEN( 4311 wmi_dcc_update_ndl_cmd_fixed_param)); 4312 cmd->vdev_id = update_ndl_param->vdev_id; 4313 cmd->num_channel = update_ndl_param->channel_count; 4314 4315 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4316 update_ndl_param->dcc_ndl_chan_list_len); 4317 buf_ptr += WMI_TLV_HDR_SIZE; 4318 4319 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4320 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4321 update_ndl_param->dcc_ndl_chan_list_len); 4322 for (i = 0; i < cmd->num_channel; i++) 4323 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4324 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4325 WMITLV_GET_STRUCT_TLVLEN( 4326 wmi_dcc_ndl_chan)); 4327 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4328 4329 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4330 update_ndl_param->dcc_ndl_active_state_list_len); 4331 buf_ptr += WMI_TLV_HDR_SIZE; 4332 4333 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4334 qdf_mem_copy(ndl_active_state_array, 4335 update_ndl_param->dcc_ndl_active_state_list, 4336 update_ndl_param->dcc_ndl_active_state_list_len); 4337 for (i = 0; i < active_state_count; i++) { 4338 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4339 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4340 WMITLV_GET_STRUCT_TLVLEN( 4341 wmi_dcc_ndl_active_state_config)); 4342 } 4343 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4344 4345 /* Send the WMI command */ 4346 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4347 WMI_DCC_UPDATE_NDL_CMDID); 4348 /* If there is an error, set the completion event */ 4349 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4350 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4351 wmi_buf_free(buf); 4352 } 4353 4354 return qdf_status; 4355 } 4356 4357 /** 4358 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4359 * @wmi_handle: pointer to the wmi handle 4360 * @config: the OCB configuration 4361 * 4362 * Return: 0 on success 4363 */ 4364 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4365 struct ocb_config *config) 4366 { 4367 QDF_STATUS ret; 4368 wmi_ocb_set_config_cmd_fixed_param *cmd; 4369 wmi_channel *chan; 4370 wmi_ocb_channel *ocb_chan; 4371 wmi_qos_parameter *qos_param; 4372 wmi_dcc_ndl_chan *ndl_chan; 4373 wmi_dcc_ndl_active_state_config *ndl_active_config; 4374 wmi_ocb_schedule_element *sched_elem; 4375 uint8_t *buf_ptr; 4376 wmi_buf_t buf; 4377 int32_t len; 4378 int32_t i, j, active_state_count; 4379 4380 /* 4381 * Validate the dcc_ndl_chan_list_len and count the number of active 4382 * states. Validate dcc_ndl_active_state_list_len. 4383 */ 4384 active_state_count = 0; 4385 if (config->dcc_ndl_chan_list_len) { 4386 if (!config->dcc_ndl_chan_list || 4387 config->dcc_ndl_chan_list_len != 4388 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4389 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4390 config->dcc_ndl_chan_list_len); 4391 return QDF_STATUS_E_INVAL; 4392 } 4393 4394 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4395 i < config->channel_count; ++i, ++ndl_chan) 4396 active_state_count += 4397 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4398 4399 if (active_state_count) { 4400 if (!config->dcc_ndl_active_state_list || 4401 config->dcc_ndl_active_state_list_len != 4402 active_state_count * 4403 sizeof(wmi_dcc_ndl_active_state_config)) { 4404 WMI_LOGE(FL("NDL active state is invalid.")); 4405 return QDF_STATUS_E_INVAL; 4406 } 4407 } 4408 } 4409 4410 len = sizeof(*cmd) + 4411 WMI_TLV_HDR_SIZE + config->channel_count * 4412 sizeof(wmi_channel) + 4413 WMI_TLV_HDR_SIZE + config->channel_count * 4414 sizeof(wmi_ocb_channel) + 4415 WMI_TLV_HDR_SIZE + config->channel_count * 4416 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4417 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4418 WMI_TLV_HDR_SIZE + active_state_count * 4419 sizeof(wmi_dcc_ndl_active_state_config) + 4420 WMI_TLV_HDR_SIZE + config->schedule_size * 4421 sizeof(wmi_ocb_schedule_element); 4422 buf = wmi_buf_alloc(wmi_handle, len); 4423 if (!buf) { 4424 WMI_LOGE(FL("wmi_buf_alloc failed")); 4425 return QDF_STATUS_E_NOMEM; 4426 } 4427 4428 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4429 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4430 WMITLV_SET_HDR(&cmd->tlv_header, 4431 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4432 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4433 cmd->vdev_id = config->vdev_id; 4434 cmd->channel_count = config->channel_count; 4435 cmd->schedule_size = config->schedule_size; 4436 cmd->flags = config->flags; 4437 buf_ptr += sizeof(*cmd); 4438 4439 /* Add the wmi_channel info */ 4440 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4441 config->channel_count*sizeof(wmi_channel)); 4442 buf_ptr += WMI_TLV_HDR_SIZE; 4443 for (i = 0; i < config->channel_count; i++) { 4444 chan = (wmi_channel *)buf_ptr; 4445 WMITLV_SET_HDR(&chan->tlv_header, 4446 WMITLV_TAG_STRUC_wmi_channel, 4447 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4448 chan->mhz = config->channels[i].chan_freq; 4449 chan->band_center_freq1 = config->channels[i].chan_freq; 4450 chan->band_center_freq2 = 0; 4451 chan->info = 0; 4452 4453 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4454 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4455 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4456 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4457 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4458 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4459 config->channels[i].antenna_max); 4460 4461 if (config->channels[i].bandwidth < 10) 4462 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4463 else if (config->channels[i].bandwidth < 20) 4464 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4465 buf_ptr += sizeof(*chan); 4466 } 4467 4468 /* Add the wmi_ocb_channel info */ 4469 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4470 config->channel_count*sizeof(wmi_ocb_channel)); 4471 buf_ptr += WMI_TLV_HDR_SIZE; 4472 for (i = 0; i < config->channel_count; i++) { 4473 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4474 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4475 WMITLV_TAG_STRUC_wmi_ocb_channel, 4476 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4477 ocb_chan->bandwidth = config->channels[i].bandwidth; 4478 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4479 config->channels[i].mac_address.bytes, 4480 &ocb_chan->mac_address); 4481 buf_ptr += sizeof(*ocb_chan); 4482 } 4483 4484 /* Add the wmi_qos_parameter info */ 4485 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4486 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4487 buf_ptr += WMI_TLV_HDR_SIZE; 4488 /* WMI_MAX_NUM_AC parameters for each channel */ 4489 for (i = 0; i < config->channel_count; i++) { 4490 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4491 qos_param = (wmi_qos_parameter *)buf_ptr; 4492 WMITLV_SET_HDR(&qos_param->tlv_header, 4493 WMITLV_TAG_STRUC_wmi_qos_parameter, 4494 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4495 qos_param->aifsn = 4496 config->channels[i].qos_params[j].aifsn; 4497 qos_param->cwmin = 4498 config->channels[i].qos_params[j].cwmin; 4499 qos_param->cwmax = 4500 config->channels[i].qos_params[j].cwmax; 4501 buf_ptr += sizeof(*qos_param); 4502 } 4503 } 4504 4505 /* Add the wmi_dcc_ndl_chan (per channel) */ 4506 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4507 config->dcc_ndl_chan_list_len); 4508 buf_ptr += WMI_TLV_HDR_SIZE; 4509 if (config->dcc_ndl_chan_list_len) { 4510 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4511 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4512 config->dcc_ndl_chan_list_len); 4513 for (i = 0; i < config->channel_count; i++) 4514 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4515 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4516 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4517 buf_ptr += config->dcc_ndl_chan_list_len; 4518 } 4519 4520 /* Add the wmi_dcc_ndl_active_state_config */ 4521 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4522 sizeof(wmi_dcc_ndl_active_state_config)); 4523 buf_ptr += WMI_TLV_HDR_SIZE; 4524 if (active_state_count) { 4525 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4526 qdf_mem_copy(ndl_active_config, 4527 config->dcc_ndl_active_state_list, 4528 active_state_count * sizeof(*ndl_active_config)); 4529 for (i = 0; i < active_state_count; ++i) 4530 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4531 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4532 WMITLV_GET_STRUCT_TLVLEN( 4533 wmi_dcc_ndl_active_state_config)); 4534 buf_ptr += active_state_count * 4535 sizeof(*ndl_active_config); 4536 } 4537 4538 /* Add the wmi_ocb_schedule_element info */ 4539 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4540 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4541 buf_ptr += WMI_TLV_HDR_SIZE; 4542 for (i = 0; i < config->schedule_size; i++) { 4543 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4544 WMITLV_SET_HDR(&sched_elem->tlv_header, 4545 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4546 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4547 sched_elem->channel_freq = config->schedule[i].chan_freq; 4548 sched_elem->total_duration = config->schedule[i].total_duration; 4549 sched_elem->guard_interval = config->schedule[i].guard_interval; 4550 buf_ptr += sizeof(*sched_elem); 4551 } 4552 4553 4554 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4555 WMI_OCB_SET_CONFIG_CMDID); 4556 if (QDF_IS_STATUS_ERROR(ret)) { 4557 WMI_LOGE("Failed to set OCB config"); 4558 wmi_buf_free(buf); 4559 } 4560 4561 return ret; 4562 } 4563 4564 /** 4565 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4566 * @wmi_handle: wmi handle 4567 * @evt_buf: wmi event buffer 4568 * @status: status buffer 4569 * 4570 * Return: QDF_STATUS_SUCCESS on success 4571 */ 4572 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4573 void *evt_buf, 4574 uint32_t *status) 4575 { 4576 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4577 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4578 4579 param_tlvs = evt_buf; 4580 fix_param = param_tlvs->fixed_param; 4581 4582 *status = fix_param->status; 4583 return QDF_STATUS_SUCCESS; 4584 } 4585 4586 /** 4587 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4588 * @wmi_handle: wmi handle 4589 * @evt_buf: wmi event buffer 4590 * @resp: response buffer 4591 * 4592 * Return: QDF_STATUS_SUCCESS on success 4593 */ 4594 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4595 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4596 { 4597 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4598 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4599 4600 param_tlvs = evt_buf; 4601 fix_param = param_tlvs->fixed_param; 4602 resp->vdev_id = fix_param->vdev_id; 4603 resp->timer_high = fix_param->tsf_timer_high; 4604 resp->timer_low = fix_param->tsf_timer_low; 4605 4606 return QDF_STATUS_SUCCESS; 4607 } 4608 4609 /** 4610 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4611 * @wmi_handle: wmi handle 4612 * @evt_buf: wmi event buffer 4613 * @resp: response buffer 4614 * 4615 * Return: QDF_STATUS_SUCCESS on success 4616 */ 4617 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4618 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4619 { 4620 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4621 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4622 4623 param_tlvs = evt_buf; 4624 fix_param = param_tlvs->fixed_param; 4625 resp->vdev_id = fix_param->vdev_id; 4626 resp->status = fix_param->status; 4627 return QDF_STATUS_SUCCESS; 4628 } 4629 4630 /** 4631 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4632 * @wmi_handle: wmi handle 4633 * @evt_buf: wmi event buffer 4634 * @resp: response buffer 4635 * 4636 * Since length of stats is variable, buffer for DCC stats will be allocated 4637 * in this function. The caller must free the buffer. 4638 * 4639 * Return: QDF_STATUS_SUCCESS on success 4640 */ 4641 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4642 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4643 { 4644 struct ocb_dcc_get_stats_response *response; 4645 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4646 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4647 4648 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4649 fix_param = param_tlvs->fixed_param; 4650 4651 /* Allocate and populate the response */ 4652 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4653 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4654 WMI_LOGE("%s: too many channels:%d", __func__, 4655 fix_param->num_channels); 4656 QDF_ASSERT(0); 4657 *resp = NULL; 4658 return QDF_STATUS_E_INVAL; 4659 } 4660 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4661 sizeof(wmi_dcc_ndl_stats_per_channel)); 4662 *resp = response; 4663 if (!response) 4664 return QDF_STATUS_E_NOMEM; 4665 4666 response->vdev_id = fix_param->vdev_id; 4667 response->num_channels = fix_param->num_channels; 4668 response->channel_stats_array_len = 4669 fix_param->num_channels * 4670 sizeof(wmi_dcc_ndl_stats_per_channel); 4671 response->channel_stats_array = ((uint8_t *)response) + 4672 sizeof(*response); 4673 qdf_mem_copy(response->channel_stats_array, 4674 param_tlvs->stats_per_channel_list, 4675 response->channel_stats_array_len); 4676 4677 return QDF_STATUS_SUCCESS; 4678 } 4679 #endif 4680 4681 /** 4682 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4683 * @wmi_handle: wmi handle 4684 * @mcc_adaptive_scheduler: enable/disable 4685 * 4686 * This function enable/disable mcc adaptive scheduler in fw. 4687 * 4688 * Return: QDF_STATUS_SUCCESS for success or error code 4689 */ 4690 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4691 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4692 uint32_t pdev_id) 4693 { 4694 QDF_STATUS ret; 4695 wmi_buf_t buf = 0; 4696 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4697 uint16_t len = 4698 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4699 4700 buf = wmi_buf_alloc(wmi_handle, len); 4701 if (!buf) { 4702 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4703 return QDF_STATUS_E_NOMEM; 4704 } 4705 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4706 wmi_buf_data(buf); 4707 4708 WMITLV_SET_HDR(&cmd->tlv_header, 4709 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4710 WMITLV_GET_STRUCT_TLVLEN 4711 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4712 cmd->enable = mcc_adaptive_scheduler; 4713 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4714 4715 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4716 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4717 if (QDF_IS_STATUS_ERROR(ret)) { 4718 WMI_LOGP("%s: Failed to send enable/disable MCC" 4719 " adaptive scheduler command", __func__); 4720 wmi_buf_free(buf); 4721 } 4722 4723 return ret; 4724 } 4725 4726 /** 4727 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4728 * @wmi: wmi handle 4729 * @mcc_channel: mcc channel 4730 * @mcc_channel_time_latency: MCC channel time latency. 4731 * 4732 * Currently used to set time latency for an MCC vdev/adapter using operating 4733 * channel of it and channel number. The info is provided run time using 4734 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4735 * 4736 * Return: CDF status 4737 */ 4738 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4739 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4740 { 4741 QDF_STATUS ret; 4742 wmi_buf_t buf = 0; 4743 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4744 uint16_t len = 0; 4745 uint8_t *buf_ptr = NULL; 4746 wmi_resmgr_chan_latency chan_latency; 4747 /* Note: we only support MCC time latency for a single channel */ 4748 uint32_t num_channels = 1; 4749 uint32_t chan1_freq = mcc_channel_freq; 4750 uint32_t latency_chan1 = mcc_channel_time_latency; 4751 4752 4753 /* If 0ms latency is provided, then FW will set to a default. 4754 * Otherwise, latency must be at least 30ms. 4755 */ 4756 if ((latency_chan1 > 0) && 4757 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4758 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4759 "Minimum is 30ms (or 0 to use default value by " 4760 "firmware)", __func__, latency_chan1); 4761 return QDF_STATUS_E_INVAL; 4762 } 4763 4764 /* Set WMI CMD for channel time latency here */ 4765 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4766 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4767 num_channels * sizeof(wmi_resmgr_chan_latency); 4768 buf = wmi_buf_alloc(wmi_handle, len); 4769 if (!buf) { 4770 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4771 return QDF_STATUS_E_NOMEM; 4772 } 4773 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4774 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4775 wmi_buf_data(buf); 4776 WMITLV_SET_HDR(&cmdTL->tlv_header, 4777 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4778 WMITLV_GET_STRUCT_TLVLEN 4779 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4780 cmdTL->num_chans = num_channels; 4781 /* Update channel time latency information for home channel(s) */ 4782 buf_ptr += sizeof(*cmdTL); 4783 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4784 num_channels * sizeof(wmi_resmgr_chan_latency)); 4785 buf_ptr += WMI_TLV_HDR_SIZE; 4786 chan_latency.chan_mhz = chan1_freq; 4787 chan_latency.latency = latency_chan1; 4788 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4789 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4790 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4791 if (QDF_IS_STATUS_ERROR(ret)) { 4792 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4793 __func__); 4794 wmi_buf_free(buf); 4795 QDF_ASSERT(0); 4796 } 4797 4798 return ret; 4799 } 4800 4801 /** 4802 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4803 * @wmi: wmi handle 4804 * @adapter_1_chan_number: adapter 1 channel number 4805 * @adapter_1_quota: adapter 1 quota 4806 * @adapter_2_chan_number: adapter 2 channel number 4807 * 4808 * Return: CDF status 4809 */ 4810 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4811 uint32_t adapter_1_chan_freq, 4812 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4813 { 4814 QDF_STATUS ret; 4815 wmi_buf_t buf = 0; 4816 uint16_t len = 0; 4817 uint8_t *buf_ptr = NULL; 4818 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4819 wmi_resmgr_chan_time_quota chan_quota; 4820 uint32_t quota_chan1 = adapter_1_quota; 4821 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4822 uint32_t quota_chan2 = 100 - quota_chan1; 4823 /* Note: setting time quota for MCC requires info for 2 channels */ 4824 uint32_t num_channels = 2; 4825 uint32_t chan1_freq = adapter_1_chan_freq; 4826 uint32_t chan2_freq = adapter_2_chan_freq; 4827 4828 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4829 "freq2:%dMHz, Quota2:%dms", __func__, 4830 chan1_freq, quota_chan1, chan2_freq, 4831 quota_chan2); 4832 4833 /* 4834 * Perform sanity check on time quota values provided. 4835 */ 4836 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4837 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4838 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4839 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4840 return QDF_STATUS_E_INVAL; 4841 } 4842 /* Set WMI CMD for channel time quota here */ 4843 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4844 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4845 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4846 buf = wmi_buf_alloc(wmi_handle, len); 4847 if (!buf) { 4848 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4849 QDF_ASSERT(0); 4850 return QDF_STATUS_E_NOMEM; 4851 } 4852 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4853 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4854 wmi_buf_data(buf); 4855 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4856 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4857 WMITLV_GET_STRUCT_TLVLEN 4858 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4859 cmdTQ->num_chans = num_channels; 4860 4861 /* Update channel time quota information for home channel(s) */ 4862 buf_ptr += sizeof(*cmdTQ); 4863 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4864 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4865 buf_ptr += WMI_TLV_HDR_SIZE; 4866 chan_quota.chan_mhz = chan1_freq; 4867 chan_quota.channel_time_quota = quota_chan1; 4868 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4869 /* Construct channel and quota record for the 2nd MCC mode. */ 4870 buf_ptr += sizeof(chan_quota); 4871 chan_quota.chan_mhz = chan2_freq; 4872 chan_quota.channel_time_quota = quota_chan2; 4873 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4874 4875 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4876 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4877 if (QDF_IS_STATUS_ERROR(ret)) { 4878 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4879 wmi_buf_free(buf); 4880 QDF_ASSERT(0); 4881 } 4882 4883 return ret; 4884 } 4885 4886 /** 4887 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4888 * @wmi_handle: Pointer to wmi handle 4889 * @thermal_info: Thermal command information 4890 * 4891 * This function sends the thermal management command 4892 * to the firmware 4893 * 4894 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4895 */ 4896 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4897 struct thermal_cmd_params *thermal_info) 4898 { 4899 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4900 wmi_buf_t buf = NULL; 4901 QDF_STATUS status; 4902 uint32_t len = 0; 4903 4904 len = sizeof(*cmd); 4905 4906 buf = wmi_buf_alloc(wmi_handle, len); 4907 if (!buf) { 4908 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4909 return QDF_STATUS_E_FAILURE; 4910 } 4911 4912 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4913 4914 WMITLV_SET_HDR(&cmd->tlv_header, 4915 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4916 WMITLV_GET_STRUCT_TLVLEN 4917 (wmi_thermal_mgmt_cmd_fixed_param)); 4918 4919 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4920 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4921 cmd->enable = thermal_info->thermal_enable; 4922 4923 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4924 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4925 4926 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4927 WMI_THERMAL_MGMT_CMDID); 4928 if (QDF_IS_STATUS_ERROR(status)) { 4929 wmi_buf_free(buf); 4930 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4931 } 4932 4933 return status; 4934 } 4935 4936 4937 /** 4938 * send_lro_config_cmd_tlv() - process the LRO config command 4939 * @wmi_handle: Pointer to WMI handle 4940 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4941 * 4942 * This function sends down the LRO configuration parameters to 4943 * the firmware to enable LRO, sets the TCP flags and sets the 4944 * seed values for the toeplitz hash generation 4945 * 4946 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4947 */ 4948 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4949 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4950 { 4951 wmi_lro_info_cmd_fixed_param *cmd; 4952 wmi_buf_t buf; 4953 QDF_STATUS status; 4954 4955 4956 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4957 if (!buf) { 4958 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4959 return QDF_STATUS_E_FAILURE; 4960 } 4961 4962 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4963 4964 WMITLV_SET_HDR(&cmd->tlv_header, 4965 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4966 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4967 4968 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4969 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4970 wmi_lro_cmd->tcp_flag); 4971 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4972 wmi_lro_cmd->tcp_flag_mask); 4973 cmd->toeplitz_hash_ipv4_0_3 = 4974 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4975 cmd->toeplitz_hash_ipv4_4_7 = 4976 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4977 cmd->toeplitz_hash_ipv4_8_11 = 4978 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4979 cmd->toeplitz_hash_ipv4_12_15 = 4980 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4981 cmd->toeplitz_hash_ipv4_16 = 4982 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4983 4984 cmd->toeplitz_hash_ipv6_0_3 = 4985 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4986 cmd->toeplitz_hash_ipv6_4_7 = 4987 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4988 cmd->toeplitz_hash_ipv6_8_11 = 4989 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4990 cmd->toeplitz_hash_ipv6_12_15 = 4991 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4992 cmd->toeplitz_hash_ipv6_16_19 = 4993 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4994 cmd->toeplitz_hash_ipv6_20_23 = 4995 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4996 cmd->toeplitz_hash_ipv6_24_27 = 4997 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4998 cmd->toeplitz_hash_ipv6_28_31 = 4999 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5000 cmd->toeplitz_hash_ipv6_32_35 = 5001 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5002 cmd->toeplitz_hash_ipv6_36_39 = 5003 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5004 cmd->toeplitz_hash_ipv6_40 = 5005 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5006 5007 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 5008 cmd->lro_enable, cmd->tcp_flag_u32); 5009 5010 status = wmi_unified_cmd_send(wmi_handle, buf, 5011 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5012 if (QDF_IS_STATUS_ERROR(status)) { 5013 wmi_buf_free(buf); 5014 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 5015 } 5016 5017 return status; 5018 } 5019 5020 /** 5021 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5022 * @wmi_handle: Pointer to wmi handle 5023 * @rate_report_params: Pointer to peer rate report parameters 5024 * 5025 * 5026 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5027 */ 5028 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5029 struct wmi_peer_rate_report_params *rate_report_params) 5030 { 5031 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5032 wmi_buf_t buf = NULL; 5033 QDF_STATUS status = 0; 5034 uint32_t len = 0; 5035 uint32_t i, j; 5036 5037 len = sizeof(*cmd); 5038 5039 buf = wmi_buf_alloc(wmi_handle, len); 5040 if (!buf) { 5041 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 5042 return QDF_STATUS_E_FAILURE; 5043 } 5044 5045 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5046 wmi_buf_data(buf); 5047 5048 WMITLV_SET_HDR( 5049 &cmd->tlv_header, 5050 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5051 WMITLV_GET_STRUCT_TLVLEN( 5052 wmi_peer_set_rate_report_condition_fixed_param)); 5053 5054 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5055 cmd->report_backoff_time = rate_report_params->backoff_time; 5056 cmd->report_timer_period = rate_report_params->timer_period; 5057 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5058 cmd->cond_per_phy[i].val_cond_flags = 5059 rate_report_params->report_per_phy[i].cond_flags; 5060 cmd->cond_per_phy[i].rate_delta.min_delta = 5061 rate_report_params->report_per_phy[i].delta.delta_min; 5062 cmd->cond_per_phy[i].rate_delta.percentage = 5063 rate_report_params->report_per_phy[i].delta.percent; 5064 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5065 cmd->cond_per_phy[i].rate_threshold[j] = 5066 rate_report_params->report_per_phy[i]. 5067 report_rate_threshold[j]; 5068 } 5069 } 5070 5071 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 5072 cmd->enable_rate_report, 5073 cmd->report_backoff_time, cmd->report_timer_period); 5074 5075 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5076 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5077 if (QDF_IS_STATUS_ERROR(status)) { 5078 wmi_buf_free(buf); 5079 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 5080 __func__); 5081 } 5082 return status; 5083 } 5084 5085 /** 5086 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 5087 * @wmi_handle: wmi handle 5088 * @param: bcn ll cmd parameter 5089 * 5090 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5091 */ 5092 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 5093 wmi_bcn_send_from_host_cmd_fixed_param *param) 5094 { 5095 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 5096 wmi_buf_t wmi_buf; 5097 QDF_STATUS ret; 5098 5099 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5100 if (!wmi_buf) { 5101 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5102 return QDF_STATUS_E_FAILURE; 5103 } 5104 5105 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 5106 WMITLV_SET_HDR(&cmd->tlv_header, 5107 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 5108 WMITLV_GET_STRUCT_TLVLEN 5109 (wmi_bcn_send_from_host_cmd_fixed_param)); 5110 cmd->vdev_id = param->vdev_id; 5111 cmd->data_len = param->data_len; 5112 cmd->frame_ctrl = param->frame_ctrl; 5113 cmd->frag_ptr = param->frag_ptr; 5114 cmd->dtim_flag = param->dtim_flag; 5115 5116 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 5117 WMI_PDEV_SEND_BCN_CMDID); 5118 5119 if (QDF_IS_STATUS_ERROR(ret)) { 5120 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 5121 wmi_buf_free(wmi_buf); 5122 } 5123 5124 return ret; 5125 } 5126 5127 /** 5128 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 5129 * @wmi_handle: wmi handle 5130 * @vdev_id: vdev id 5131 * @max_retries: max retries 5132 * @retry_interval: retry interval 5133 * This function sets sta query related parameters in fw. 5134 * 5135 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5136 */ 5137 5138 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 5139 uint8_t vdev_id, uint32_t max_retries, 5140 uint32_t retry_interval) 5141 { 5142 wmi_buf_t buf; 5143 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 5144 int len; 5145 5146 len = sizeof(*cmd); 5147 buf = wmi_buf_alloc(wmi_handle, len); 5148 if (!buf) { 5149 WMI_LOGE(FL("wmi_buf_alloc failed")); 5150 return QDF_STATUS_E_FAILURE; 5151 } 5152 5153 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5154 WMITLV_SET_HDR(&cmd->tlv_header, 5155 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5156 WMITLV_GET_STRUCT_TLVLEN 5157 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5158 5159 5160 cmd->vdev_id = vdev_id; 5161 cmd->sa_query_max_retry_count = max_retries; 5162 cmd->sa_query_retry_interval = retry_interval; 5163 5164 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5165 vdev_id, retry_interval, max_retries); 5166 5167 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5168 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5169 WMI_LOGE(FL("Failed to offload STA SA Query")); 5170 wmi_buf_free(buf); 5171 return QDF_STATUS_E_FAILURE; 5172 } 5173 5174 WMI_LOGD(FL("Exit :")); 5175 return 0; 5176 } 5177 5178 /** 5179 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5180 * @wmi_handle: wmi handle 5181 * @params: sta keep alive parameter 5182 * 5183 * This function sets keep alive related parameters in fw. 5184 * 5185 * Return: CDF status 5186 */ 5187 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5188 struct sta_params *params) 5189 { 5190 wmi_buf_t buf; 5191 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5192 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5193 uint8_t *buf_ptr; 5194 int len; 5195 QDF_STATUS ret; 5196 5197 WMI_LOGD("%s: Enter", __func__); 5198 5199 len = sizeof(*cmd) + sizeof(*arp_rsp); 5200 buf = wmi_buf_alloc(wmi_handle, len); 5201 if (!buf) { 5202 WMI_LOGE("wmi_buf_alloc failed"); 5203 return QDF_STATUS_E_FAILURE; 5204 } 5205 5206 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5207 buf_ptr = (uint8_t *) cmd; 5208 WMITLV_SET_HDR(&cmd->tlv_header, 5209 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5210 WMITLV_GET_STRUCT_TLVLEN 5211 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5212 cmd->interval = params->timeperiod; 5213 cmd->enable = (params->timeperiod) ? 1 : 0; 5214 cmd->vdev_id = params->vdev_id; 5215 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5216 params->timeperiod, params->method); 5217 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5218 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5219 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5220 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5221 5222 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5223 (params->method == 5224 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5225 if ((NULL == params->hostv4addr) || 5226 (NULL == params->destv4addr) || 5227 (NULL == params->destmac)) { 5228 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5229 "destv4addr:%pK destmac:%pK ", __func__, 5230 params->hostv4addr, params->destv4addr, params->destmac); 5231 wmi_buf_free(buf); 5232 return QDF_STATUS_E_FAILURE; 5233 } 5234 cmd->method = params->method; 5235 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5236 WMI_IPV4_ADDR_LEN); 5237 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5238 WMI_IPV4_ADDR_LEN); 5239 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5240 } else { 5241 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5242 } 5243 5244 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5245 WMI_STA_KEEPALIVE_CMDID); 5246 if (QDF_IS_STATUS_ERROR(ret)) { 5247 WMI_LOGE("Failed to set KeepAlive"); 5248 wmi_buf_free(buf); 5249 } 5250 5251 WMI_LOGD("%s: Exit", __func__); 5252 return ret; 5253 } 5254 5255 /** 5256 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5257 * @wmi_handle: wmi handle 5258 * @if_id: vdev id 5259 * @gtx_info: GTX config params 5260 * 5261 * This function set GTX related params in firmware. 5262 * 5263 * Return: QDF_STATUS_SUCCESS for success or error code 5264 */ 5265 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5266 struct wmi_gtx_config *gtx_info) 5267 { 5268 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5269 wmi_buf_t buf; 5270 QDF_STATUS ret; 5271 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5272 5273 buf = wmi_buf_alloc(wmi_handle, len); 5274 if (!buf) { 5275 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5276 return QDF_STATUS_E_NOMEM; 5277 } 5278 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5279 WMITLV_SET_HDR(&cmd->tlv_header, 5280 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5281 WMITLV_GET_STRUCT_TLVLEN 5282 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5283 cmd->vdev_id = if_id; 5284 5285 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5286 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5287 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5288 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5289 cmd->gtxPERMargin = gtx_info->gtx_margin; 5290 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5291 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5292 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5293 5294 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5295 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5296 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5297 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5298 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5299 5300 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5301 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5302 if (QDF_IS_STATUS_ERROR(ret)) { 5303 WMI_LOGE("Failed to set GTX PARAMS"); 5304 wmi_buf_free(buf); 5305 } 5306 return ret; 5307 } 5308 5309 /** 5310 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5311 * @wmi_handle: wmi handle 5312 * @vdev_id: vdev id. 5313 * @wmm_vparams: edca parameters 5314 * 5315 * This function updates EDCA parameters to the target 5316 * 5317 * Return: CDF Status 5318 */ 5319 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5320 uint8_t vdev_id, bool mu_edca_param, 5321 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5322 { 5323 uint8_t *buf_ptr; 5324 wmi_buf_t buf; 5325 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5326 wmi_wmm_vparams *wmm_param; 5327 struct wmi_host_wme_vparams *twmm_param; 5328 int len = sizeof(*cmd); 5329 int ac; 5330 5331 buf = wmi_buf_alloc(wmi_handle, len); 5332 5333 if (!buf) { 5334 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5335 return QDF_STATUS_E_NOMEM; 5336 } 5337 5338 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5339 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5340 WMITLV_SET_HDR(&cmd->tlv_header, 5341 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5342 WMITLV_GET_STRUCT_TLVLEN 5343 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5344 cmd->vdev_id = vdev_id; 5345 cmd->wmm_param_type = mu_edca_param; 5346 5347 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5348 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5349 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5350 WMITLV_SET_HDR(&wmm_param->tlv_header, 5351 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5352 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5353 wmm_param->cwmin = twmm_param->cwmin; 5354 wmm_param->cwmax = twmm_param->cwmax; 5355 wmm_param->aifs = twmm_param->aifs; 5356 if (mu_edca_param) 5357 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5358 else 5359 wmm_param->txoplimit = twmm_param->txoplimit; 5360 wmm_param->acm = twmm_param->acm; 5361 wmm_param->no_ack = twmm_param->noackpolicy; 5362 } 5363 5364 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5365 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5366 goto fail; 5367 5368 return QDF_STATUS_SUCCESS; 5369 5370 fail: 5371 wmi_buf_free(buf); 5372 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5373 return QDF_STATUS_E_FAILURE; 5374 } 5375 5376 /** 5377 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5378 * @wmi_handle: wmi handle 5379 * @vdev_id: vdev id 5380 * @probe_rsp_info: probe response info 5381 * 5382 * Return: QDF_STATUS_SUCCESS for success or error code 5383 */ 5384 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5385 uint8_t vdev_id, 5386 struct wmi_probe_resp_params *probe_rsp_info) 5387 { 5388 wmi_prb_tmpl_cmd_fixed_param *cmd; 5389 wmi_bcn_prb_info *bcn_prb_info; 5390 wmi_buf_t wmi_buf; 5391 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5392 uint8_t *buf_ptr; 5393 QDF_STATUS ret; 5394 5395 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5396 5397 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5398 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5399 5400 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5401 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5402 tmpl_len_aligned; 5403 5404 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5405 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5406 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5407 return QDF_STATUS_E_INVAL; 5408 } 5409 5410 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5411 if (!wmi_buf) { 5412 WMI_LOGE(FL("wmi_buf_alloc failed")); 5413 return QDF_STATUS_E_NOMEM; 5414 } 5415 5416 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5417 5418 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5419 WMITLV_SET_HDR(&cmd->tlv_header, 5420 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5421 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5422 cmd->vdev_id = vdev_id; 5423 cmd->buf_len = tmpl_len; 5424 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5425 5426 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5427 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5428 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5429 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5430 bcn_prb_info->caps = 0; 5431 bcn_prb_info->erp = 0; 5432 buf_ptr += sizeof(wmi_bcn_prb_info); 5433 5434 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5435 buf_ptr += WMI_TLV_HDR_SIZE; 5436 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5437 5438 ret = wmi_unified_cmd_send(wmi_handle, 5439 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5440 if (QDF_IS_STATUS_ERROR(ret)) { 5441 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5442 wmi_buf_free(wmi_buf); 5443 } 5444 5445 return ret; 5446 } 5447 5448 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5449 #define WPI_IV_LEN 16 5450 5451 /** 5452 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5453 * 5454 * @dest_tx: destination address of tsc key counter 5455 * @src_tx: source address of tsc key counter 5456 * @dest_rx: destination address of rsc key counter 5457 * @src_rx: source address of rsc key counter 5458 * 5459 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5460 * 5461 * Return: None 5462 * 5463 */ 5464 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5465 uint8_t *dest_rx, uint8_t *src_rx) 5466 { 5467 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5468 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5469 } 5470 #else 5471 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5472 uint8_t *dest_rx, uint8_t *src_rx) 5473 { 5474 return; 5475 } 5476 #endif 5477 5478 /** 5479 * send_setup_install_key_cmd_tlv() - set key parameters 5480 * @wmi_handle: wmi handle 5481 * @key_params: key parameters 5482 * 5483 * This function fills structure from information 5484 * passed in key_params. 5485 * 5486 * Return: QDF_STATUS_SUCCESS - success 5487 * QDF_STATUS_E_FAILURE - failure 5488 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5489 */ 5490 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5491 struct set_key_params *key_params) 5492 { 5493 wmi_vdev_install_key_cmd_fixed_param *cmd; 5494 wmi_buf_t buf; 5495 uint8_t *buf_ptr; 5496 uint32_t len; 5497 uint8_t *key_data; 5498 QDF_STATUS status; 5499 5500 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5501 WMI_TLV_HDR_SIZE; 5502 5503 buf = wmi_buf_alloc(wmi_handle, len); 5504 if (!buf) { 5505 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5506 return QDF_STATUS_E_NOMEM; 5507 } 5508 5509 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5510 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5511 WMITLV_SET_HDR(&cmd->tlv_header, 5512 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5513 WMITLV_GET_STRUCT_TLVLEN 5514 (wmi_vdev_install_key_cmd_fixed_param)); 5515 cmd->vdev_id = key_params->vdev_id; 5516 cmd->key_ix = key_params->key_idx; 5517 5518 5519 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5520 cmd->key_flags |= key_params->key_flags; 5521 cmd->key_cipher = key_params->key_cipher; 5522 if ((key_params->key_txmic_len) && 5523 (key_params->key_rxmic_len)) { 5524 cmd->key_txmic_len = key_params->key_txmic_len; 5525 cmd->key_rxmic_len = key_params->key_rxmic_len; 5526 } 5527 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5528 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5529 key_params->tx_iv, 5530 cmd->wpi_key_rsc_counter, 5531 key_params->rx_iv); 5532 #endif 5533 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5534 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5535 roundup(key_params->key_len, sizeof(uint32_t))); 5536 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5537 qdf_mem_copy((void *)key_data, 5538 (const void *)key_params->key_data, key_params->key_len); 5539 if (key_params->key_rsc_counter) 5540 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5541 sizeof(wmi_key_seq_counter)); 5542 cmd->key_len = key_params->key_len; 5543 5544 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5545 WMI_VDEV_INSTALL_KEY_CMDID); 5546 if (QDF_IS_STATUS_ERROR(status)) 5547 wmi_buf_free(buf); 5548 5549 return status; 5550 } 5551 5552 /** 5553 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5554 * @wmi_handle: wmi handle 5555 * @params: sar limit params 5556 * 5557 * Return: QDF_STATUS_SUCCESS for success or error code 5558 */ 5559 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5560 struct sar_limit_cmd_params *sar_limit_params) 5561 { 5562 wmi_buf_t buf; 5563 QDF_STATUS qdf_status; 5564 wmi_sar_limits_cmd_fixed_param *cmd; 5565 int i; 5566 uint8_t *buf_ptr; 5567 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5568 struct sar_limit_cmd_row *sar_rows_list; 5569 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5570 5571 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5572 buf = wmi_buf_alloc(wmi_handle, len); 5573 if (!buf) { 5574 WMI_LOGE("Failed to allocate memory"); 5575 qdf_status = QDF_STATUS_E_NOMEM; 5576 goto end; 5577 } 5578 5579 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5580 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5581 WMITLV_SET_HDR(&cmd->tlv_header, 5582 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5583 WMITLV_GET_STRUCT_TLVLEN 5584 (wmi_sar_limits_cmd_fixed_param)); 5585 cmd->sar_enable = sar_limit_params->sar_enable; 5586 cmd->commit_limits = sar_limit_params->commit_limits; 5587 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5588 5589 WMI_LOGD("no of sar rows = %d, len = %d", 5590 sar_limit_params->num_limit_rows, len); 5591 buf_ptr += sizeof(*cmd); 5592 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5593 sizeof(wmi_sar_limit_cmd_row) * 5594 sar_limit_params->num_limit_rows); 5595 if (cmd->num_limit_rows == 0) 5596 goto send_sar_limits; 5597 5598 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5599 (buf_ptr + WMI_TLV_HDR_SIZE); 5600 sar_rows_list = sar_limit_params->sar_limit_row_list; 5601 5602 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5603 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5604 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5605 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5606 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5607 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5608 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5609 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5610 wmi_sar_rows_list->validity_bitmap = 5611 sar_rows_list->validity_bitmap; 5612 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5613 i, wmi_sar_rows_list->band_id, 5614 wmi_sar_rows_list->chain_id, 5615 wmi_sar_rows_list->mod_id, 5616 wmi_sar_rows_list->limit_value, 5617 wmi_sar_rows_list->validity_bitmap); 5618 sar_rows_list++; 5619 wmi_sar_rows_list++; 5620 } 5621 send_sar_limits: 5622 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5623 WMI_SAR_LIMITS_CMDID); 5624 5625 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5626 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5627 wmi_buf_free(buf); 5628 } 5629 5630 end: 5631 return qdf_status; 5632 } 5633 5634 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5635 { 5636 wmi_sar_get_limits_cmd_fixed_param *cmd; 5637 wmi_buf_t wmi_buf; 5638 uint32_t len; 5639 QDF_STATUS status; 5640 5641 WMI_LOGD(FL("Enter")); 5642 5643 len = sizeof(*cmd); 5644 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5645 if (!wmi_buf) { 5646 WMI_LOGP(FL("failed to allocate memory for msg")); 5647 return QDF_STATUS_E_NOMEM; 5648 } 5649 5650 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5651 5652 WMITLV_SET_HDR(&cmd->tlv_header, 5653 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5654 WMITLV_GET_STRUCT_TLVLEN 5655 (wmi_sar_get_limits_cmd_fixed_param)); 5656 5657 cmd->reserved = 0; 5658 5659 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5660 WMI_SAR_GET_LIMITS_CMDID); 5661 if (QDF_IS_STATUS_ERROR(status)) { 5662 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5663 wmi_buf_free(wmi_buf); 5664 } 5665 5666 WMI_LOGD(FL("Exit")); 5667 5668 return status; 5669 } 5670 5671 /** 5672 * wmi_sar2_result_string() - return string conversion of sar2 result 5673 * @result: sar2 result value 5674 * 5675 * This utility function helps log string conversion of sar2 result. 5676 * 5677 * Return: string conversion of sar 2 result, if match found; 5678 * "Unknown response" otherwise. 5679 */ 5680 static const char *wmi_sar2_result_string(uint32_t result) 5681 { 5682 switch (result) { 5683 CASE_RETURN_STRING(WMI_SAR2_SUCCESS); 5684 CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX); 5685 CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX); 5686 CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR); 5687 CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE); 5688 default: 5689 return "Unknown response"; 5690 } 5691 } 5692 5693 /** 5694 * extract_sar2_result_event_tlv() - process sar response event from FW. 5695 * @handle: wma handle 5696 * @event: event buffer 5697 * @len: buffer length 5698 * 5699 * Return: 0 for success or error code 5700 */ 5701 static QDF_STATUS extract_sar2_result_event_tlv(void *handle, 5702 uint8_t *event, 5703 uint32_t len) 5704 { 5705 wmi_sar2_result_event_fixed_param *sar2_fixed_param; 5706 5707 WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf = 5708 (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event; 5709 5710 if (!param_buf) { 5711 WMI_LOGI("Invalid sar2 result event buffer"); 5712 return QDF_STATUS_E_INVAL; 5713 } 5714 5715 sar2_fixed_param = param_buf->fixed_param; 5716 if (!sar2_fixed_param) { 5717 WMI_LOGI("Invalid sar2 result event fixed param buffer"); 5718 return QDF_STATUS_E_INVAL; 5719 } 5720 5721 WMI_LOGI("SAR2 result: %s", 5722 wmi_sar2_result_string(sar2_fixed_param->result)); 5723 5724 return QDF_STATUS_SUCCESS; 5725 } 5726 5727 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5728 uint8_t *evt_buf, 5729 struct sar_limit_event *event) 5730 { 5731 wmi_sar_get_limits_event_fixed_param *fixed_param; 5732 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5733 wmi_sar_get_limit_event_row *row_in; 5734 struct sar_limit_event_row *row_out; 5735 uint32_t row; 5736 5737 if (!evt_buf) { 5738 WMI_LOGE(FL("input event is NULL")); 5739 return QDF_STATUS_E_INVAL; 5740 } 5741 if (!event) { 5742 WMI_LOGE(FL("output event is NULL")); 5743 return QDF_STATUS_E_INVAL; 5744 } 5745 5746 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5747 5748 fixed_param = param_buf->fixed_param; 5749 if (!fixed_param) { 5750 WMI_LOGE(FL("Invalid fixed param")); 5751 return QDF_STATUS_E_INVAL; 5752 } 5753 5754 event->sar_enable = fixed_param->sar_enable; 5755 event->num_limit_rows = fixed_param->num_limit_rows; 5756 5757 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5758 QDF_ASSERT(0); 5759 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5760 event->num_limit_rows, 5761 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5762 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5763 } 5764 5765 row_in = param_buf->sar_get_limits; 5766 row_out = &event->sar_limit_row[0]; 5767 for (row = 0; row < event->num_limit_rows; row++) { 5768 row_out->band_id = row_in->band_id; 5769 row_out->chain_id = row_in->chain_id; 5770 row_out->mod_id = row_in->mod_id; 5771 row_out->limit_value = row_in->limit_value; 5772 row_out++; 5773 row_in++; 5774 } 5775 5776 return QDF_STATUS_SUCCESS; 5777 } 5778 5779 #ifdef WLAN_FEATURE_DISA 5780 /** 5781 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5782 * @wmi_handle: wmi handle 5783 * @params: encrypt/decrypt params 5784 * 5785 * Return: QDF_STATUS_SUCCESS for success or error code 5786 */ 5787 static 5788 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5789 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5790 { 5791 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5792 wmi_buf_t wmi_buf; 5793 uint8_t *buf_ptr; 5794 QDF_STATUS ret; 5795 uint32_t len; 5796 5797 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5798 5799 len = sizeof(*cmd) + 5800 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5801 WMI_TLV_HDR_SIZE; 5802 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5803 if (!wmi_buf) { 5804 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5805 __func__); 5806 return QDF_STATUS_E_NOMEM; 5807 } 5808 5809 buf_ptr = wmi_buf_data(wmi_buf); 5810 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5811 5812 WMITLV_SET_HDR(&cmd->tlv_header, 5813 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5814 WMITLV_GET_STRUCT_TLVLEN( 5815 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5816 5817 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5818 cmd->key_flag = encrypt_decrypt_params->key_flag; 5819 cmd->key_idx = encrypt_decrypt_params->key_idx; 5820 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5821 cmd->key_len = encrypt_decrypt_params->key_len; 5822 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5823 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5824 5825 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5826 encrypt_decrypt_params->key_len); 5827 5828 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5829 MAX_MAC_HEADER_LEN); 5830 5831 cmd->data_len = encrypt_decrypt_params->data_len; 5832 5833 if (cmd->data_len) { 5834 buf_ptr += sizeof(*cmd); 5835 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5836 roundup(encrypt_decrypt_params->data_len, 5837 sizeof(uint32_t))); 5838 buf_ptr += WMI_TLV_HDR_SIZE; 5839 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5840 encrypt_decrypt_params->data_len); 5841 } 5842 5843 /* This conversion is to facilitate data to FW in little endian */ 5844 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5845 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5846 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5847 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5848 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5849 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5850 5851 ret = wmi_unified_cmd_send(wmi_handle, 5852 wmi_buf, len, 5853 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5854 if (QDF_IS_STATUS_ERROR(ret)) { 5855 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5856 wmi_buf_free(wmi_buf); 5857 } 5858 5859 return ret; 5860 } 5861 5862 /** 5863 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5864 * params from event 5865 * @wmi_handle: wmi handle 5866 * @evt_buf: pointer to event buffer 5867 * @resp: Pointer to hold resp parameters 5868 * 5869 * Return: QDF_STATUS_SUCCESS for success or error code 5870 */ 5871 static 5872 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5873 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5874 { 5875 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5876 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5877 5878 param_buf = evt_buf; 5879 if (!param_buf) { 5880 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5881 return QDF_STATUS_E_INVAL; 5882 } 5883 5884 data_event = param_buf->fixed_param; 5885 5886 resp->vdev_id = data_event->vdev_id; 5887 resp->status = data_event->status; 5888 5889 if ((data_event->data_length > param_buf->num_enc80211_frame) || 5890 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE - 5891 sizeof(*data_event))) { 5892 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5893 data_event->data_length, 5894 param_buf->num_enc80211_frame); 5895 return QDF_STATUS_E_INVAL; 5896 } 5897 5898 resp->data_len = data_event->data_length; 5899 5900 if (resp->data_len) 5901 resp->data = (uint8_t *)param_buf->enc80211_frame; 5902 5903 return QDF_STATUS_SUCCESS; 5904 } 5905 #endif 5906 5907 /** 5908 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5909 * @wmi_handle: wmi handle 5910 * @vdev_id: vdev id 5911 * @p2p_ie: p2p IE 5912 * 5913 * Return: QDF_STATUS_SUCCESS for success or error code 5914 */ 5915 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5916 uint32_t vdev_id, uint8_t *p2p_ie) 5917 { 5918 QDF_STATUS ret; 5919 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5920 wmi_buf_t wmi_buf; 5921 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5922 uint8_t *buf_ptr; 5923 5924 ie_len = (uint32_t) (p2p_ie[1] + 2); 5925 5926 /* More than one P2P IE may be included in a single frame. 5927 If multiple P2P IEs are present, the complete P2P attribute 5928 data consists of the concatenation of the P2P Attribute 5929 fields of the P2P IEs. The P2P Attributes field of each 5930 P2P IE may be any length up to the maximum (251 octets). 5931 In this case host sends one P2P IE to firmware so the length 5932 should not exceed more than 251 bytes 5933 */ 5934 if (ie_len > 251) { 5935 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5936 return QDF_STATUS_E_INVAL; 5937 } 5938 5939 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5940 5941 wmi_buf_len = 5942 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5943 WMI_TLV_HDR_SIZE; 5944 5945 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5946 if (!wmi_buf) { 5947 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5948 return QDF_STATUS_E_NOMEM; 5949 } 5950 5951 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5952 5953 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5954 WMITLV_SET_HDR(&cmd->tlv_header, 5955 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5956 WMITLV_GET_STRUCT_TLVLEN 5957 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5958 cmd->vdev_id = vdev_id; 5959 cmd->ie_buf_len = ie_len; 5960 5961 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5962 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5963 buf_ptr += WMI_TLV_HDR_SIZE; 5964 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5965 5966 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 5967 5968 ret = wmi_unified_cmd_send(wmi_handle, 5969 wmi_buf, wmi_buf_len, 5970 WMI_P2P_GO_SET_BEACON_IE); 5971 if (QDF_IS_STATUS_ERROR(ret)) { 5972 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 5973 wmi_buf_free(wmi_buf); 5974 } 5975 5976 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 5977 return ret; 5978 } 5979 5980 /** 5981 * send_set_gateway_params_cmd_tlv() - set gateway parameters 5982 * @wmi_handle: wmi handle 5983 * @req: gateway parameter update request structure 5984 * 5985 * This function reads the incoming @req and fill in the destination 5986 * WMI structure and sends down the gateway configs down to the firmware 5987 * 5988 * Return: QDF_STATUS 5989 */ 5990 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 5991 struct gateway_update_req_param *req) 5992 { 5993 wmi_roam_subnet_change_config_fixed_param *cmd; 5994 wmi_buf_t buf; 5995 QDF_STATUS ret; 5996 int len = sizeof(*cmd); 5997 5998 buf = wmi_buf_alloc(wmi_handle, len); 5999 if (!buf) { 6000 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6001 return QDF_STATUS_E_NOMEM; 6002 } 6003 6004 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 6005 WMITLV_SET_HDR(&cmd->tlv_header, 6006 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 6007 WMITLV_GET_STRUCT_TLVLEN( 6008 wmi_roam_subnet_change_config_fixed_param)); 6009 6010 cmd->vdev_id = req->session_id; 6011 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 6012 QDF_IPV4_ADDR_SIZE); 6013 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 6014 QDF_IPV6_ADDR_SIZE); 6015 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 6016 &cmd->inet_gw_mac_addr); 6017 cmd->max_retries = req->max_retries; 6018 cmd->timeout = req->timeout; 6019 cmd->num_skip_subnet_change_detection_bssid_list = 0; 6020 cmd->flag = 0; 6021 if (req->ipv4_addr_type) 6022 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 6023 6024 if (req->ipv6_addr_type) 6025 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 6026 6027 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6028 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 6029 if (QDF_IS_STATUS_ERROR(ret)) { 6030 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 6031 ret); 6032 wmi_buf_free(buf); 6033 } 6034 6035 return ret; 6036 } 6037 6038 /** 6039 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 6040 * @wmi_handle: wmi handle 6041 * @req: rssi monitoring request structure 6042 * 6043 * This function reads the incoming @req and fill in the destination 6044 * WMI structure and send down the rssi monitoring configs down to the firmware 6045 * 6046 * Return: 0 on success; error number otherwise 6047 */ 6048 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 6049 struct rssi_monitor_param *req) 6050 { 6051 wmi_rssi_breach_monitor_config_fixed_param *cmd; 6052 wmi_buf_t buf; 6053 QDF_STATUS ret; 6054 uint32_t len = sizeof(*cmd); 6055 6056 buf = wmi_buf_alloc(wmi_handle, len); 6057 if (!buf) { 6058 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6059 return QDF_STATUS_E_NOMEM; 6060 } 6061 6062 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 6063 WMITLV_SET_HDR(&cmd->tlv_header, 6064 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 6065 WMITLV_GET_STRUCT_TLVLEN( 6066 wmi_rssi_breach_monitor_config_fixed_param)); 6067 6068 cmd->vdev_id = req->session_id; 6069 cmd->request_id = req->request_id; 6070 cmd->lo_rssi_reenable_hysteresis = 0; 6071 cmd->hi_rssi_reenable_histeresis = 0; 6072 cmd->min_report_interval = 0; 6073 cmd->max_num_report = 1; 6074 if (req->control) { 6075 /* enable one threshold for each min/max */ 6076 cmd->enabled_bitmap = 0x09; 6077 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 6078 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 6079 } else { 6080 cmd->enabled_bitmap = 0; 6081 cmd->low_rssi_breach_threshold[0] = 0; 6082 cmd->hi_rssi_breach_threshold[0] = 0; 6083 } 6084 6085 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6086 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 6087 if (QDF_IS_STATUS_ERROR(ret)) { 6088 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 6089 wmi_buf_free(buf); 6090 } 6091 6092 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 6093 6094 return ret; 6095 } 6096 6097 /** 6098 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6099 * @wmi_handle: wmi handle 6100 * @psetoui: OUI parameters 6101 * 6102 * set scan probe OUI parameters in firmware 6103 * 6104 * Return: CDF status 6105 */ 6106 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6107 struct scan_mac_oui *psetoui) 6108 { 6109 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6110 wmi_buf_t wmi_buf; 6111 uint32_t len; 6112 uint8_t *buf_ptr; 6113 uint32_t *oui_buf; 6114 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 6115 6116 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6117 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 6118 6119 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6120 if (!wmi_buf) { 6121 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 6122 return QDF_STATUS_E_NOMEM; 6123 } 6124 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6125 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6126 WMITLV_SET_HDR(&cmd->tlv_header, 6127 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6128 WMITLV_GET_STRUCT_TLVLEN 6129 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6130 6131 oui_buf = &cmd->prob_req_oui; 6132 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6133 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6134 | psetoui->oui[2]; 6135 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 6136 cmd->prob_req_oui); 6137 6138 cmd->vdev_id = psetoui->vdev_id; 6139 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6140 if (psetoui->enb_probe_req_sno_randomization) 6141 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6142 6143 if (ie_whitelist->white_list) { 6144 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 6145 &cmd->num_vendor_oui, 6146 ie_whitelist); 6147 cmd->flags |= 6148 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6149 } 6150 6151 buf_ptr += sizeof(*cmd); 6152 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6153 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6154 buf_ptr += WMI_TLV_HDR_SIZE; 6155 6156 if (cmd->num_vendor_oui != 0) { 6157 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6158 ie_whitelist->voui); 6159 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6160 } 6161 6162 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6163 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6164 WMI_LOGE("%s: failed to send command", __func__); 6165 wmi_buf_free(wmi_buf); 6166 return QDF_STATUS_E_FAILURE; 6167 } 6168 return QDF_STATUS_SUCCESS; 6169 } 6170 6171 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6172 /** 6173 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6174 * @wmi_handle: wmi handle 6175 * @roam_req: Roam scan offload params 6176 * @buf_ptr: command buffer to send 6177 * @fils_tlv_len: fils tlv length 6178 * 6179 * Return: Updated buffer pointer 6180 */ 6181 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6182 struct roam_offload_scan_params *roam_req, 6183 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6184 { 6185 wmi_roam_fils_offload_tlv_param *fils_tlv; 6186 wmi_erp_info *erp_info; 6187 struct roam_fils_params *roam_fils_params; 6188 6189 if (!roam_req->add_fils_tlv) 6190 return buf_ptr; 6191 6192 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6193 sizeof(*fils_tlv)); 6194 buf_ptr += WMI_TLV_HDR_SIZE; 6195 6196 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6197 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6198 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6199 WMITLV_GET_STRUCT_TLVLEN 6200 (wmi_roam_fils_offload_tlv_param)); 6201 6202 roam_fils_params = &roam_req->roam_fils_params; 6203 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6204 6205 erp_info->username_length = roam_fils_params->username_length; 6206 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6207 erp_info->username_length); 6208 6209 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6210 6211 erp_info->rRk_length = roam_fils_params->rrk_length; 6212 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6213 erp_info->rRk_length); 6214 6215 erp_info->rIk_length = roam_fils_params->rik_length; 6216 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6217 erp_info->rIk_length); 6218 6219 erp_info->realm_len = roam_fils_params->realm_len; 6220 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6221 erp_info->realm_len); 6222 6223 buf_ptr += sizeof(*fils_tlv); 6224 return buf_ptr; 6225 } 6226 #else 6227 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6228 struct roam_offload_scan_params *roam_req, 6229 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6230 { 6231 return buf_ptr; 6232 } 6233 #endif 6234 /** 6235 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6236 * @wmi_handle: wmi handle 6237 * @scan_cmd_fp: start scan command ptr 6238 * @roam_req: roam request param 6239 * 6240 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6241 * of WMI_ROAM_SCAN_MODE. 6242 * 6243 * Return: QDF status 6244 */ 6245 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6246 wmi_start_scan_cmd_fixed_param * 6247 scan_cmd_fp, 6248 struct roam_offload_scan_params *roam_req) 6249 { 6250 wmi_buf_t buf = NULL; 6251 QDF_STATUS status; 6252 int len; 6253 uint8_t *buf_ptr; 6254 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6255 6256 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6257 int auth_mode = roam_req->auth_mode; 6258 wmi_roam_offload_tlv_param *roam_offload_params; 6259 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6260 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6261 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6262 wmi_tlv_buf_len_param *assoc_ies; 6263 uint32_t fils_tlv_len = 0; 6264 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6265 /* Need to create a buf with roam_scan command at 6266 * front and piggyback with scan command */ 6267 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6268 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6269 (2 * WMI_TLV_HDR_SIZE) + 6270 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6271 sizeof(wmi_start_scan_cmd_fixed_param); 6272 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6273 WMI_LOGD("auth_mode = %d", auth_mode); 6274 if (roam_req->is_roam_req_valid && 6275 roam_req->roam_offload_enabled) { 6276 len += sizeof(wmi_roam_offload_tlv_param); 6277 len += WMI_TLV_HDR_SIZE; 6278 if ((auth_mode != WMI_AUTH_NONE) && 6279 ((auth_mode != WMI_AUTH_OPEN) || 6280 (auth_mode == WMI_AUTH_OPEN && 6281 roam_req->mdid.mdie_present && 6282 roam_req->is_11r_assoc) || 6283 roam_req->is_ese_assoc)) { 6284 len += WMI_TLV_HDR_SIZE; 6285 if (roam_req->is_ese_assoc) 6286 len += 6287 sizeof(wmi_roam_ese_offload_tlv_param); 6288 else if (auth_mode == WMI_AUTH_FT_RSNA || 6289 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6290 (auth_mode == WMI_AUTH_OPEN && 6291 roam_req->mdid.mdie_present && 6292 roam_req->is_11r_assoc)) 6293 len += 6294 sizeof(wmi_roam_11r_offload_tlv_param); 6295 else 6296 len += 6297 sizeof(wmi_roam_11i_offload_tlv_param); 6298 } else { 6299 len += WMI_TLV_HDR_SIZE; 6300 } 6301 6302 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6303 + roundup(roam_req->assoc_ie_length, 6304 sizeof(uint32_t))); 6305 6306 if (roam_req->add_fils_tlv) { 6307 fils_tlv_len = sizeof( 6308 wmi_roam_fils_offload_tlv_param); 6309 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6310 } 6311 } else { 6312 if (roam_req->is_roam_req_valid) 6313 WMI_LOGD("%s : roam offload = %d", 6314 __func__, roam_req->roam_offload_enabled); 6315 else 6316 WMI_LOGD("%s : roam_req is NULL", __func__); 6317 len += (4 * WMI_TLV_HDR_SIZE); 6318 } 6319 if (roam_req->is_roam_req_valid && 6320 roam_req->roam_offload_enabled) { 6321 roam_req->mode = roam_req->mode | 6322 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6323 } 6324 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6325 6326 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6327 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6328 len = sizeof(wmi_roam_scan_mode_fixed_param); 6329 6330 buf = wmi_buf_alloc(wmi_handle, len); 6331 if (!buf) { 6332 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6333 return QDF_STATUS_E_NOMEM; 6334 } 6335 6336 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6337 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6338 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6339 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6340 WMITLV_GET_STRUCT_TLVLEN 6341 (wmi_roam_scan_mode_fixed_param)); 6342 6343 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6344 roam_req->roam_trigger_reason_bitmask; 6345 roam_scan_mode_fp->min_delay_btw_scans = 6346 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6347 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6348 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6349 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6350 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6351 roam_scan_mode_fp->flags |= 6352 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6353 goto send_roam_scan_mode_cmd; 6354 } 6355 6356 /* Fill in scan parameters suitable for roaming scan */ 6357 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6358 6359 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6360 sizeof(wmi_start_scan_cmd_fixed_param)); 6361 /* Ensure there is no additional IEs */ 6362 scan_cmd_fp->ie_len = 0; 6363 WMITLV_SET_HDR(buf_ptr, 6364 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6365 WMITLV_GET_STRUCT_TLVLEN 6366 (wmi_start_scan_cmd_fixed_param)); 6367 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6368 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6369 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6371 sizeof(wmi_roam_offload_tlv_param)); 6372 buf_ptr += WMI_TLV_HDR_SIZE; 6373 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6374 WMITLV_SET_HDR(buf_ptr, 6375 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6376 WMITLV_GET_STRUCT_TLVLEN 6377 (wmi_roam_offload_tlv_param)); 6378 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6379 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6380 roam_offload_params->select_5g_margin = 6381 roam_req->select_5ghz_margin; 6382 roam_offload_params->handoff_delay_for_rx = 6383 roam_req->roam_offload_params.ho_delay_for_rx; 6384 roam_offload_params->reassoc_failure_timeout = 6385 roam_req->reassoc_failure_timeout; 6386 6387 /* Fill the capabilities */ 6388 roam_offload_params->capability = 6389 roam_req->roam_offload_params.capability; 6390 roam_offload_params->ht_caps_info = 6391 roam_req->roam_offload_params.ht_caps_info; 6392 roam_offload_params->ampdu_param = 6393 roam_req->roam_offload_params.ampdu_param; 6394 roam_offload_params->ht_ext_cap = 6395 roam_req->roam_offload_params.ht_ext_cap; 6396 roam_offload_params->ht_txbf = 6397 roam_req->roam_offload_params.ht_txbf; 6398 roam_offload_params->asel_cap = 6399 roam_req->roam_offload_params.asel_cap; 6400 roam_offload_params->qos_caps = 6401 roam_req->roam_offload_params.qos_caps; 6402 roam_offload_params->qos_enabled = 6403 roam_req->roam_offload_params.qos_enabled; 6404 roam_offload_params->wmm_caps = 6405 roam_req->roam_offload_params.wmm_caps; 6406 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6407 (uint8_t *)roam_req->roam_offload_params.mcsset, 6408 ROAM_OFFLOAD_NUM_MCS_SET); 6409 6410 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6411 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6412 * they are filled in the same order.Depending on the 6413 * authentication type, the other mode TLV's are nullified 6414 * and only headers are filled.*/ 6415 if ((auth_mode != WMI_AUTH_NONE) && 6416 ((auth_mode != WMI_AUTH_OPEN) || 6417 (auth_mode == WMI_AUTH_OPEN 6418 && roam_req->mdid.mdie_present && 6419 roam_req->is_11r_assoc) || 6420 roam_req->is_ese_assoc)) { 6421 if (roam_req->is_ese_assoc) { 6422 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6423 WMITLV_GET_STRUCT_TLVLEN(0)); 6424 buf_ptr += WMI_TLV_HDR_SIZE; 6425 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6426 WMITLV_GET_STRUCT_TLVLEN(0)); 6427 buf_ptr += WMI_TLV_HDR_SIZE; 6428 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6429 sizeof(wmi_roam_ese_offload_tlv_param)); 6430 buf_ptr += WMI_TLV_HDR_SIZE; 6431 roam_offload_ese = 6432 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6433 qdf_mem_copy(roam_offload_ese->krk, 6434 roam_req->krk, 6435 sizeof(roam_req->krk)); 6436 qdf_mem_copy(roam_offload_ese->btk, 6437 roam_req->btk, 6438 sizeof(roam_req->btk)); 6439 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6440 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6441 WMITLV_GET_STRUCT_TLVLEN 6442 (wmi_roam_ese_offload_tlv_param)); 6443 buf_ptr += 6444 sizeof(wmi_roam_ese_offload_tlv_param); 6445 } else if (auth_mode == WMI_AUTH_FT_RSNA 6446 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6447 || (auth_mode == WMI_AUTH_OPEN 6448 && roam_req->mdid.mdie_present && 6449 roam_req->is_11r_assoc)) { 6450 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6451 0); 6452 buf_ptr += WMI_TLV_HDR_SIZE; 6453 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6454 sizeof(wmi_roam_11r_offload_tlv_param)); 6455 buf_ptr += WMI_TLV_HDR_SIZE; 6456 roam_offload_11r = 6457 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6458 roam_offload_11r->r0kh_id_len = 6459 roam_req->rokh_id_length; 6460 qdf_mem_copy(roam_offload_11r->r0kh_id, 6461 roam_req->rokh_id, 6462 roam_offload_11r->r0kh_id_len); 6463 qdf_mem_copy(roam_offload_11r->psk_msk, 6464 roam_req->psk_pmk, 6465 sizeof(roam_req->psk_pmk)); 6466 roam_offload_11r->psk_msk_len = 6467 roam_req->pmk_len; 6468 roam_offload_11r->mdie_present = 6469 roam_req->mdid.mdie_present; 6470 roam_offload_11r->mdid = 6471 roam_req->mdid.mobility_domain; 6472 if (auth_mode == WMI_AUTH_OPEN) { 6473 /* If FT-Open ensure pmk length 6474 and r0khid len are zero */ 6475 roam_offload_11r->r0kh_id_len = 0; 6476 roam_offload_11r->psk_msk_len = 0; 6477 } 6478 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6479 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6480 WMITLV_GET_STRUCT_TLVLEN 6481 (wmi_roam_11r_offload_tlv_param)); 6482 buf_ptr += 6483 sizeof(wmi_roam_11r_offload_tlv_param); 6484 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6485 WMITLV_GET_STRUCT_TLVLEN(0)); 6486 buf_ptr += WMI_TLV_HDR_SIZE; 6487 WMI_LOGD("psk_msk_len = %d", 6488 roam_offload_11r->psk_msk_len); 6489 if (roam_offload_11r->psk_msk_len) 6490 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6491 QDF_TRACE_LEVEL_DEBUG, 6492 roam_offload_11r->psk_msk, 6493 roam_offload_11r->psk_msk_len); 6494 } else { 6495 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6496 sizeof(wmi_roam_11i_offload_tlv_param)); 6497 buf_ptr += WMI_TLV_HDR_SIZE; 6498 roam_offload_11i = 6499 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6500 6501 if (roam_req->roam_key_mgmt_offload_enabled && 6502 roam_req->fw_okc) { 6503 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6504 (roam_offload_11i->flags); 6505 WMI_LOGI("LFR3:OKC enabled"); 6506 } else { 6507 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6508 (roam_offload_11i->flags); 6509 WMI_LOGI("LFR3:OKC disabled"); 6510 } 6511 if (roam_req->roam_key_mgmt_offload_enabled && 6512 roam_req->fw_pmksa_cache) { 6513 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6514 (roam_offload_11i->flags); 6515 WMI_LOGI("LFR3:PMKSA caching enabled"); 6516 } else { 6517 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6518 (roam_offload_11i->flags); 6519 WMI_LOGI("LFR3:PMKSA caching disabled"); 6520 } 6521 6522 qdf_mem_copy(roam_offload_11i->pmk, 6523 roam_req->psk_pmk, 6524 sizeof(roam_req->psk_pmk)); 6525 roam_offload_11i->pmk_len = roam_req->pmk_len; 6526 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6527 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6528 WMITLV_GET_STRUCT_TLVLEN 6529 (wmi_roam_11i_offload_tlv_param)); 6530 buf_ptr += 6531 sizeof(wmi_roam_11i_offload_tlv_param); 6532 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6533 0); 6534 buf_ptr += WMI_TLV_HDR_SIZE; 6535 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6536 0); 6537 buf_ptr += WMI_TLV_HDR_SIZE; 6538 WMI_LOGD("pmk_len = %d", 6539 roam_offload_11i->pmk_len); 6540 if (roam_offload_11i->pmk_len) 6541 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6542 QDF_TRACE_LEVEL_DEBUG, 6543 roam_offload_11i->pmk, 6544 roam_offload_11i->pmk_len); 6545 } 6546 } else { 6547 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6548 WMITLV_GET_STRUCT_TLVLEN(0)); 6549 buf_ptr += WMI_TLV_HDR_SIZE; 6550 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6551 WMITLV_GET_STRUCT_TLVLEN(0)); 6552 buf_ptr += WMI_TLV_HDR_SIZE; 6553 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6554 WMITLV_GET_STRUCT_TLVLEN(0)); 6555 buf_ptr += WMI_TLV_HDR_SIZE; 6556 } 6557 6558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6559 sizeof(*assoc_ies)); 6560 buf_ptr += WMI_TLV_HDR_SIZE; 6561 6562 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6563 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6564 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6565 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6566 assoc_ies->buf_len = roam_req->assoc_ie_length; 6567 6568 buf_ptr += sizeof(*assoc_ies); 6569 6570 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6571 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6572 buf_ptr += WMI_TLV_HDR_SIZE; 6573 6574 if (assoc_ies->buf_len != 0) { 6575 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6576 assoc_ies->buf_len); 6577 } 6578 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6579 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6580 buf_ptr, fils_tlv_len); 6581 } else { 6582 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6583 WMITLV_GET_STRUCT_TLVLEN(0)); 6584 buf_ptr += WMI_TLV_HDR_SIZE; 6585 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6586 WMITLV_GET_STRUCT_TLVLEN(0)); 6587 buf_ptr += WMI_TLV_HDR_SIZE; 6588 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6589 WMITLV_GET_STRUCT_TLVLEN(0)); 6590 buf_ptr += WMI_TLV_HDR_SIZE; 6591 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6592 WMITLV_GET_STRUCT_TLVLEN(0)); 6593 buf_ptr += WMI_TLV_HDR_SIZE; 6594 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6595 WMITLV_GET_STRUCT_TLVLEN(0)); 6596 buf_ptr += WMI_TLV_HDR_SIZE; 6597 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6598 WMITLV_GET_STRUCT_TLVLEN(0)); 6599 } 6600 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6601 6602 send_roam_scan_mode_cmd: 6603 status = wmi_unified_cmd_send(wmi_handle, buf, 6604 len, WMI_ROAM_SCAN_MODE); 6605 if (QDF_IS_STATUS_ERROR(status)) { 6606 WMI_LOGE( 6607 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6608 status); 6609 wmi_buf_free(buf); 6610 } 6611 6612 return status; 6613 } 6614 6615 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6616 struct wmi_mawc_roam_params *params) 6617 { 6618 wmi_buf_t buf = NULL; 6619 QDF_STATUS status; 6620 int len; 6621 uint8_t *buf_ptr; 6622 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6623 6624 len = sizeof(*wmi_roam_mawc_params); 6625 buf = wmi_buf_alloc(wmi_handle, len); 6626 if (!buf) { 6627 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6628 return QDF_STATUS_E_NOMEM; 6629 } 6630 6631 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6632 wmi_roam_mawc_params = 6633 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6634 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6635 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6636 WMITLV_GET_STRUCT_TLVLEN 6637 (wmi_roam_configure_mawc_cmd_fixed_param)); 6638 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6639 if (params->enable) 6640 wmi_roam_mawc_params->enable = 1; 6641 else 6642 wmi_roam_mawc_params->enable = 0; 6643 wmi_roam_mawc_params->traffic_load_threshold = 6644 params->traffic_load_threshold; 6645 wmi_roam_mawc_params->best_ap_rssi_threshold = 6646 params->best_ap_rssi_threshold; 6647 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6648 params->rssi_stationary_high_adjust; 6649 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6650 params->rssi_stationary_low_adjust; 6651 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6652 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6653 wmi_roam_mawc_params->traffic_load_threshold, 6654 wmi_roam_mawc_params->best_ap_rssi_threshold, 6655 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6656 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6657 6658 status = wmi_unified_cmd_send(wmi_handle, buf, 6659 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6660 if (QDF_IS_STATUS_ERROR(status)) { 6661 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6662 status); 6663 wmi_buf_free(buf); 6664 return status; 6665 } 6666 6667 return QDF_STATUS_SUCCESS; 6668 } 6669 6670 /** 6671 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6672 * rssi threashold 6673 * @wmi_handle: wmi handle 6674 * @roam_req: Roaming request buffer 6675 * 6676 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6677 * 6678 * Return: QDF status 6679 */ 6680 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6681 struct roam_offload_scan_rssi_params *roam_req) 6682 { 6683 wmi_buf_t buf = NULL; 6684 QDF_STATUS status; 6685 int len; 6686 uint8_t *buf_ptr; 6687 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6688 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6689 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6690 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6691 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6692 6693 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6694 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6695 len += sizeof(wmi_roam_scan_extended_threshold_param); 6696 len += WMI_TLV_HDR_SIZE; 6697 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6698 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6699 len += sizeof(wmi_roam_dense_thres_param); 6700 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6701 len += sizeof(wmi_roam_bg_scan_roaming_param); 6702 buf = wmi_buf_alloc(wmi_handle, len); 6703 if (!buf) { 6704 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6705 return QDF_STATUS_E_NOMEM; 6706 } 6707 6708 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6709 rssi_threshold_fp = 6710 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6711 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6712 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6713 WMITLV_GET_STRUCT_TLVLEN 6714 (wmi_roam_scan_rssi_threshold_fixed_param)); 6715 /* fill in threshold values */ 6716 rssi_threshold_fp->vdev_id = roam_req->session_id; 6717 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6718 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6719 rssi_threshold_fp->hirssi_scan_max_count = 6720 roam_req->hi_rssi_scan_max_count; 6721 rssi_threshold_fp->hirssi_scan_delta = 6722 roam_req->hi_rssi_scan_rssi_delta; 6723 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6724 rssi_threshold_fp->rssi_thresh_offset_5g = 6725 roam_req->rssi_thresh_offset_5g; 6726 6727 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6728 WMITLV_SET_HDR(buf_ptr, 6729 WMITLV_TAG_ARRAY_STRUC, 6730 sizeof(wmi_roam_scan_extended_threshold_param)); 6731 buf_ptr += WMI_TLV_HDR_SIZE; 6732 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6733 6734 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6735 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6736 ext_thresholds->boost_threshold_5g = 6737 roam_req->boost_threshold_5g; 6738 6739 ext_thresholds->boost_algorithm_5g = 6740 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6741 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6742 ext_thresholds->penalty_algorithm_5g = 6743 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6744 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6745 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6746 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6747 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6748 6749 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6750 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6751 WMITLV_GET_STRUCT_TLVLEN 6752 (wmi_roam_scan_extended_threshold_param)); 6753 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6754 WMITLV_SET_HDR(buf_ptr, 6755 WMITLV_TAG_ARRAY_STRUC, 6756 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6757 buf_ptr += WMI_TLV_HDR_SIZE; 6758 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6759 early_stop_thresholds->roam_earlystop_thres_min = 6760 roam_req->roam_earlystop_thres_min; 6761 early_stop_thresholds->roam_earlystop_thres_max = 6762 roam_req->roam_earlystop_thres_max; 6763 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6764 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6765 WMITLV_GET_STRUCT_TLVLEN 6766 (wmi_roam_earlystop_rssi_thres_param)); 6767 6768 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6769 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6770 sizeof(wmi_roam_dense_thres_param)); 6771 buf_ptr += WMI_TLV_HDR_SIZE; 6772 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6773 dense_thresholds->roam_dense_rssi_thres_offset = 6774 roam_req->dense_rssi_thresh_offset; 6775 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6776 dense_thresholds->roam_dense_traffic_thres = 6777 roam_req->traffic_threshold; 6778 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6779 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6780 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6781 WMITLV_GET_STRUCT_TLVLEN 6782 (wmi_roam_dense_thres_param)); 6783 6784 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6785 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6786 sizeof(wmi_roam_bg_scan_roaming_param)); 6787 buf_ptr += WMI_TLV_HDR_SIZE; 6788 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6789 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6790 roam_req->bg_scan_bad_rssi_thresh; 6791 bg_scan_params->roam_bg_scan_client_bitmap = 6792 roam_req->bg_scan_client_bitmap; 6793 bg_scan_params->bad_rssi_thresh_offset_2g = 6794 roam_req->roam_bad_rssi_thresh_offset_2g; 6795 bg_scan_params->flags = roam_req->flags; 6796 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6797 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6798 WMITLV_GET_STRUCT_TLVLEN 6799 (wmi_roam_bg_scan_roaming_param)); 6800 6801 status = wmi_unified_cmd_send(wmi_handle, buf, 6802 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6803 if (QDF_IS_STATUS_ERROR(status)) { 6804 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6805 status); 6806 wmi_buf_free(buf); 6807 } 6808 6809 return status; 6810 } 6811 6812 /** 6813 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6814 * configuration params 6815 * @wma_handle: wma handler 6816 * @dwelltime_params: pointer to dwelltime_params 6817 * 6818 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6819 */ 6820 static 6821 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6822 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6823 { 6824 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6825 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6826 wmi_buf_t buf; 6827 uint8_t *buf_ptr; 6828 int32_t err; 6829 int len; 6830 6831 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6832 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6833 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6834 buf = wmi_buf_alloc(wmi_handle, len); 6835 if (!buf) { 6836 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6837 __func__); 6838 return QDF_STATUS_E_NOMEM; 6839 } 6840 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6841 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6842 WMITLV_SET_HDR(&dwell_param->tlv_header, 6843 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6844 WMITLV_GET_STRUCT_TLVLEN 6845 (wmi_scan_adaptive_dwell_config_fixed_param)); 6846 6847 dwell_param->enable = dwelltime_params->is_enabled; 6848 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6849 WMITLV_SET_HDR(buf_ptr, 6850 WMITLV_TAG_ARRAY_STRUC, 6851 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6852 buf_ptr += WMI_TLV_HDR_SIZE; 6853 6854 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6855 WMITLV_SET_HDR(&cmd->tlv_header, 6856 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6857 WMITLV_GET_STRUCT_TLVLEN( 6858 wmi_scan_adaptive_dwell_parameters_tlv)); 6859 6860 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6861 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6862 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6863 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6864 err = wmi_unified_cmd_send(wmi_handle, buf, 6865 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6866 if (err) { 6867 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6868 wmi_buf_free(buf); 6869 return QDF_STATUS_E_FAILURE; 6870 } 6871 6872 return QDF_STATUS_SUCCESS; 6873 } 6874 6875 /** 6876 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6877 * configuration params 6878 * @wmi_handle: wmi handler 6879 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6880 * 6881 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6882 */ 6883 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6884 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6885 { 6886 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6887 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6888 wmi_buf_t buf; 6889 uint8_t *buf_ptr; 6890 QDF_STATUS err; 6891 uint32_t i; 6892 int len; 6893 6894 len = sizeof(*dbs_scan_param); 6895 len += WMI_TLV_HDR_SIZE; 6896 len += dbs_scan_params->num_clients * sizeof(*cmd); 6897 6898 buf = wmi_buf_alloc(wmi_handle, len); 6899 if (!buf) { 6900 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6901 return QDF_STATUS_E_NOMEM; 6902 } 6903 6904 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6905 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6906 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6907 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6908 WMITLV_GET_STRUCT_TLVLEN 6909 (wmi_scan_dbs_duty_cycle_fixed_param)); 6910 6911 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6912 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6913 buf_ptr += sizeof(*dbs_scan_param); 6914 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6915 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6916 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6917 6918 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6919 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6920 WMITLV_SET_HDR(&cmd->tlv_header, 6921 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6922 WMITLV_GET_STRUCT_TLVLEN( 6923 wmi_scan_dbs_duty_cycle_tlv_param)); 6924 cmd->module_id = dbs_scan_params->module_id[i]; 6925 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6926 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6927 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6928 } 6929 6930 err = wmi_unified_cmd_send(wmi_handle, buf, 6931 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6932 if (QDF_IS_STATUS_ERROR(err)) { 6933 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6934 wmi_buf_free(buf); 6935 return QDF_STATUS_E_FAILURE; 6936 } 6937 6938 return QDF_STATUS_SUCCESS; 6939 } 6940 6941 /** 6942 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6943 * @wmi_handle: wmi handle 6944 * @roam_req: Request which contains the filters 6945 * 6946 * There are filters such as whitelist, blacklist and preferred 6947 * list that need to be applied to the scan results to form the 6948 * probable candidates for roaming. 6949 * 6950 * Return: Return success upon successfully passing the 6951 * parameters to the firmware, otherwise failure. 6952 */ 6953 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6954 struct roam_scan_filter_params *roam_req) 6955 { 6956 wmi_buf_t buf = NULL; 6957 QDF_STATUS status; 6958 uint32_t i; 6959 uint32_t len, blist_len = 0; 6960 uint8_t *buf_ptr; 6961 wmi_roam_filter_fixed_param *roam_filter; 6962 uint8_t *bssid_src_ptr = NULL; 6963 wmi_mac_addr *bssid_dst_ptr = NULL; 6964 wmi_ssid *ssid_ptr = NULL; 6965 uint32_t *bssid_preferred_factor_ptr = NULL; 6966 wmi_roam_lca_disallow_config_tlv_param *blist_param; 6967 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 6968 6969 len = sizeof(wmi_roam_filter_fixed_param); 6970 6971 len += WMI_TLV_HDR_SIZE; 6972 if (roam_req->num_bssid_black_list) 6973 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 6974 len += WMI_TLV_HDR_SIZE; 6975 if (roam_req->num_ssid_white_list) 6976 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 6977 len += 2 * WMI_TLV_HDR_SIZE; 6978 if (roam_req->num_bssid_preferred_list) { 6979 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 6980 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 6981 } 6982 len += WMI_TLV_HDR_SIZE; 6983 if (roam_req->lca_disallow_config_present) { 6984 len += sizeof(*blist_param); 6985 blist_len = sizeof(*blist_param); 6986 } 6987 6988 len += WMI_TLV_HDR_SIZE; 6989 if (roam_req->num_rssi_rejection_ap) 6990 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 6991 6992 buf = wmi_buf_alloc(wmi_handle, len); 6993 if (!buf) { 6994 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6995 return QDF_STATUS_E_NOMEM; 6996 } 6997 6998 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 6999 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 7000 WMITLV_SET_HDR(&roam_filter->tlv_header, 7001 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 7002 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 7003 /* fill in fixed values */ 7004 roam_filter->vdev_id = roam_req->session_id; 7005 roam_filter->flags = 0; 7006 roam_filter->op_bitmap = roam_req->op_bitmap; 7007 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 7008 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 7009 roam_filter->num_bssid_preferred_list = 7010 roam_req->num_bssid_preferred_list; 7011 roam_filter->num_rssi_rejection_ap = 7012 roam_req->num_rssi_rejection_ap; 7013 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 7014 7015 WMITLV_SET_HDR((buf_ptr), 7016 WMITLV_TAG_ARRAY_FIXED_STRUC, 7017 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 7018 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 7019 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7020 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 7021 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 7022 bssid_src_ptr += ATH_MAC_LEN; 7023 bssid_dst_ptr++; 7024 } 7025 buf_ptr += WMI_TLV_HDR_SIZE + 7026 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 7027 WMITLV_SET_HDR((buf_ptr), 7028 WMITLV_TAG_ARRAY_FIXED_STRUC, 7029 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 7030 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 7031 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 7032 qdf_mem_copy(&ssid_ptr->ssid, 7033 &roam_req->ssid_allowed_list[i].mac_ssid, 7034 roam_req->ssid_allowed_list[i].length); 7035 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 7036 ssid_ptr++; 7037 } 7038 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 7039 sizeof(wmi_ssid)); 7040 WMITLV_SET_HDR((buf_ptr), 7041 WMITLV_TAG_ARRAY_FIXED_STRUC, 7042 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 7043 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 7044 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7045 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7046 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 7047 (wmi_mac_addr *)bssid_dst_ptr); 7048 bssid_src_ptr += ATH_MAC_LEN; 7049 bssid_dst_ptr++; 7050 } 7051 buf_ptr += WMI_TLV_HDR_SIZE + 7052 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 7053 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7054 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 7055 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 7056 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7057 *bssid_preferred_factor_ptr = 7058 roam_req->bssid_favored_factor[i]; 7059 bssid_preferred_factor_ptr++; 7060 } 7061 buf_ptr += WMI_TLV_HDR_SIZE + 7062 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 7063 7064 WMITLV_SET_HDR(buf_ptr, 7065 WMITLV_TAG_ARRAY_STRUC, blist_len); 7066 buf_ptr += WMI_TLV_HDR_SIZE; 7067 if (roam_req->lca_disallow_config_present) { 7068 blist_param = 7069 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 7070 WMITLV_SET_HDR(&blist_param->tlv_header, 7071 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 7072 WMITLV_GET_STRUCT_TLVLEN( 7073 wmi_roam_lca_disallow_config_tlv_param)); 7074 7075 blist_param->disallow_duration = roam_req->disallow_duration; 7076 blist_param->rssi_channel_penalization = 7077 roam_req->rssi_channel_penalization; 7078 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 7079 blist_param->disallow_lca_enable_source_bitmap = 7080 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 7081 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 7082 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 7083 } 7084 7085 WMITLV_SET_HDR(buf_ptr, 7086 WMITLV_TAG_ARRAY_STRUC, 7087 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 7088 buf_ptr += WMI_TLV_HDR_SIZE; 7089 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 7090 rssi_rej = 7091 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 7092 WMITLV_SET_HDR(&rssi_rej->tlv_header, 7093 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7094 WMITLV_GET_STRUCT_TLVLEN( 7095 wmi_roam_rssi_rejection_oce_config_param)); 7096 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7097 roam_req->rssi_rejection_ap[i].bssid.bytes, 7098 &rssi_rej->bssid); 7099 rssi_rej->remaining_disallow_duration = 7100 roam_req->rssi_rejection_ap[i].remaining_duration; 7101 rssi_rej->requested_rssi = 7102 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 7103 buf_ptr += 7104 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7105 } 7106 7107 status = wmi_unified_cmd_send(wmi_handle, buf, 7108 len, WMI_ROAM_FILTER_CMDID); 7109 if (QDF_IS_STATUS_ERROR(status)) { 7110 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7111 status); 7112 wmi_buf_free(buf); 7113 } 7114 7115 return status; 7116 } 7117 7118 #if defined(WLAN_FEATURE_FILS_SK) 7119 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7120 struct hlp_params *params) 7121 { 7122 uint32_t len; 7123 uint8_t *buf_ptr; 7124 wmi_buf_t buf = NULL; 7125 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7126 7127 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7128 len += WMI_TLV_HDR_SIZE; 7129 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7130 7131 buf = wmi_buf_alloc(wmi_handle, len); 7132 if (!buf) { 7133 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7134 return QDF_STATUS_E_NOMEM; 7135 } 7136 7137 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7138 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7139 WMITLV_SET_HDR(&hlp_params->tlv_header, 7140 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7141 WMITLV_GET_STRUCT_TLVLEN( 7142 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7143 7144 hlp_params->vdev_id = params->vdev_id; 7145 hlp_params->size = params->hlp_ie_len; 7146 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7147 7148 buf_ptr += sizeof(*hlp_params); 7149 7150 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7151 round_up(params->hlp_ie_len, 7152 sizeof(uint32_t))); 7153 buf_ptr += WMI_TLV_HDR_SIZE; 7154 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7155 7156 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7157 hlp_params->vdev_id, hlp_params->size); 7158 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7159 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7160 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7161 wmi_buf_free(buf); 7162 return QDF_STATUS_E_FAILURE; 7163 } 7164 7165 return QDF_STATUS_SUCCESS; 7166 } 7167 #endif 7168 7169 #ifdef IPA_OFFLOAD 7170 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7171 * @wmi_handle: wmi handle 7172 * @ipa_offload: ipa offload control parameter 7173 * 7174 * Returns: 0 on success, error number otherwise 7175 */ 7176 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7177 struct ipa_uc_offload_control_params *ipa_offload) 7178 { 7179 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7180 wmi_buf_t wmi_buf; 7181 uint32_t len; 7182 u_int8_t *buf_ptr; 7183 7184 len = sizeof(*cmd); 7185 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7186 if (!wmi_buf) { 7187 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7188 return QDF_STATUS_E_NOMEM; 7189 } 7190 7191 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7192 ipa_offload->offload_type, ipa_offload->enable); 7193 7194 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7195 7196 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7197 WMITLV_SET_HDR(&cmd->tlv_header, 7198 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7199 WMITLV_GET_STRUCT_TLVLEN( 7200 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7201 7202 cmd->offload_type = ipa_offload->offload_type; 7203 cmd->vdev_id = ipa_offload->vdev_id; 7204 cmd->enable = ipa_offload->enable; 7205 7206 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7207 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7208 WMI_LOGE("%s: failed to command", __func__); 7209 wmi_buf_free(wmi_buf); 7210 return QDF_STATUS_E_FAILURE; 7211 } 7212 7213 return QDF_STATUS_SUCCESS; 7214 } 7215 #endif 7216 7217 /** 7218 * send_plm_stop_cmd_tlv() - plm stop request 7219 * @wmi_handle: wmi handle 7220 * @plm: plm request parameters 7221 * 7222 * This function request FW to stop PLM. 7223 * 7224 * Return: CDF status 7225 */ 7226 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7227 const struct plm_req_params *plm) 7228 { 7229 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7230 int32_t len; 7231 wmi_buf_t buf; 7232 uint8_t *buf_ptr; 7233 int ret; 7234 7235 len = sizeof(*cmd); 7236 buf = wmi_buf_alloc(wmi_handle, len); 7237 if (!buf) { 7238 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7239 return QDF_STATUS_E_NOMEM; 7240 } 7241 7242 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7243 7244 buf_ptr = (uint8_t *) cmd; 7245 7246 WMITLV_SET_HDR(&cmd->tlv_header, 7247 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7248 WMITLV_GET_STRUCT_TLVLEN 7249 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7250 7251 cmd->vdev_id = plm->session_id; 7252 7253 cmd->meas_token = plm->meas_token; 7254 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7255 7256 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7257 WMI_VDEV_PLMREQ_STOP_CMDID); 7258 if (ret) { 7259 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7260 wmi_buf_free(buf); 7261 return QDF_STATUS_E_FAILURE; 7262 } 7263 7264 return QDF_STATUS_SUCCESS; 7265 } 7266 7267 /** 7268 * send_plm_start_cmd_tlv() - plm start request 7269 * @wmi_handle: wmi handle 7270 * @plm: plm request parameters 7271 * 7272 * This function request FW to start PLM. 7273 * 7274 * Return: CDF status 7275 */ 7276 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7277 const struct plm_req_params *plm, 7278 uint32_t *gchannel_list) 7279 { 7280 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7281 uint32_t *channel_list; 7282 int32_t len; 7283 wmi_buf_t buf; 7284 uint8_t *buf_ptr; 7285 uint8_t count; 7286 int ret; 7287 7288 /* TLV place holder for channel_list */ 7289 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7290 len += sizeof(uint32_t) * plm->plm_num_ch; 7291 7292 buf = wmi_buf_alloc(wmi_handle, len); 7293 if (!buf) { 7294 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7295 return QDF_STATUS_E_NOMEM; 7296 } 7297 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 7298 7299 buf_ptr = (uint8_t *) cmd; 7300 7301 WMITLV_SET_HDR(&cmd->tlv_header, 7302 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 7303 WMITLV_GET_STRUCT_TLVLEN 7304 (wmi_vdev_plmreq_start_cmd_fixed_param)); 7305 7306 cmd->vdev_id = plm->session_id; 7307 7308 cmd->meas_token = plm->meas_token; 7309 cmd->dialog_token = plm->diag_token; 7310 cmd->number_bursts = plm->num_bursts; 7311 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 7312 cmd->off_duration = plm->meas_duration; 7313 cmd->burst_cycle = plm->burst_len; 7314 cmd->tx_power = plm->desired_tx_pwr; 7315 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 7316 cmd->num_chans = plm->plm_num_ch; 7317 7318 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 7319 7320 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 7321 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 7322 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 7323 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 7324 WMI_LOGD("off_duration: %d", cmd->off_duration); 7325 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 7326 WMI_LOGD("tx_power: %d", cmd->tx_power); 7327 WMI_LOGD("Number of channels : %d", cmd->num_chans); 7328 7329 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7330 (cmd->num_chans * sizeof(uint32_t))); 7331 7332 buf_ptr += WMI_TLV_HDR_SIZE; 7333 if (cmd->num_chans) { 7334 channel_list = (uint32_t *) buf_ptr; 7335 for (count = 0; count < cmd->num_chans; count++) { 7336 channel_list[count] = plm->plm_ch_list[count]; 7337 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 7338 channel_list[count] = 7339 gchannel_list[count]; 7340 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 7341 } 7342 buf_ptr += cmd->num_chans * sizeof(uint32_t); 7343 } 7344 7345 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7346 WMI_VDEV_PLMREQ_START_CMDID); 7347 if (ret) { 7348 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 7349 wmi_buf_free(buf); 7350 return QDF_STATUS_E_FAILURE; 7351 } 7352 7353 return QDF_STATUS_SUCCESS; 7354 } 7355 7356 /** 7357 * send_pno_stop_cmd_tlv() - PNO stop request 7358 * @wmi_handle: wmi handle 7359 * @vdev_id: vdev id 7360 * 7361 * This function request FW to stop ongoing PNO operation. 7362 * 7363 * Return: CDF status 7364 */ 7365 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7366 { 7367 wmi_nlo_config_cmd_fixed_param *cmd; 7368 int32_t len = sizeof(*cmd); 7369 wmi_buf_t buf; 7370 uint8_t *buf_ptr; 7371 int ret; 7372 7373 /* 7374 * TLV place holder for array of structures nlo_configured_parameters 7375 * TLV place holder for array of uint32_t channel_list 7376 * TLV place holder for chnl prediction cfg 7377 */ 7378 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7379 buf = wmi_buf_alloc(wmi_handle, len); 7380 if (!buf) { 7381 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7382 return QDF_STATUS_E_NOMEM; 7383 } 7384 7385 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7386 buf_ptr = (uint8_t *) cmd; 7387 7388 WMITLV_SET_HDR(&cmd->tlv_header, 7389 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7390 WMITLV_GET_STRUCT_TLVLEN 7391 (wmi_nlo_config_cmd_fixed_param)); 7392 7393 cmd->vdev_id = vdev_id; 7394 cmd->flags = WMI_NLO_CONFIG_STOP; 7395 buf_ptr += sizeof(*cmd); 7396 7397 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7398 buf_ptr += WMI_TLV_HDR_SIZE; 7399 7400 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7401 buf_ptr += WMI_TLV_HDR_SIZE; 7402 7403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7404 buf_ptr += WMI_TLV_HDR_SIZE; 7405 7406 7407 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7408 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7409 if (ret) { 7410 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7411 wmi_buf_free(buf); 7412 return QDF_STATUS_E_FAILURE; 7413 } 7414 7415 return QDF_STATUS_SUCCESS; 7416 } 7417 7418 /** 7419 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 7420 * @buf_ptr: Buffer passed by upper layers 7421 * @pno: Buffer to be sent to the firmware 7422 * 7423 * Copy the PNO Channel prediction configuration parameters 7424 * passed by the upper layers to a WMI format TLV and send it 7425 * down to the firmware. 7426 * 7427 * Return: None 7428 */ 7429 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 7430 struct pno_scan_req_params *pno) 7431 { 7432 nlo_channel_prediction_cfg *channel_prediction_cfg = 7433 (nlo_channel_prediction_cfg *) buf_ptr; 7434 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 7435 WMITLV_TAG_ARRAY_BYTE, 7436 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 7437 #ifdef FEATURE_WLAN_SCAN_PNO 7438 channel_prediction_cfg->enable = pno->pno_channel_prediction; 7439 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 7440 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 7441 channel_prediction_cfg->full_scan_period_ms = 7442 pno->channel_prediction_full_scan; 7443 #endif 7444 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7445 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 7446 channel_prediction_cfg->enable, 7447 channel_prediction_cfg->top_k_num, 7448 channel_prediction_cfg->stationary_threshold, 7449 channel_prediction_cfg->full_scan_period_ms); 7450 } 7451 7452 /** 7453 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 7454 * @wmi_handle: wmi handle 7455 * @params: configuration parameters 7456 * 7457 * Return: QDF_STATUS 7458 */ 7459 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 7460 struct nlo_mawc_params *params) 7461 { 7462 wmi_buf_t buf = NULL; 7463 QDF_STATUS status; 7464 int len; 7465 uint8_t *buf_ptr; 7466 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 7467 7468 len = sizeof(*wmi_nlo_mawc_params); 7469 buf = wmi_buf_alloc(wmi_handle, len); 7470 if (!buf) { 7471 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7472 return QDF_STATUS_E_NOMEM; 7473 } 7474 7475 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7476 wmi_nlo_mawc_params = 7477 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 7478 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 7479 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 7480 WMITLV_GET_STRUCT_TLVLEN 7481 (wmi_nlo_configure_mawc_cmd_fixed_param)); 7482 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 7483 if (params->enable) 7484 wmi_nlo_mawc_params->enable = 1; 7485 else 7486 wmi_nlo_mawc_params->enable = 0; 7487 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 7488 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 7489 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 7490 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 7491 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 7492 wmi_nlo_mawc_params->exp_backoff_ratio, 7493 wmi_nlo_mawc_params->init_scan_interval, 7494 wmi_nlo_mawc_params->max_scan_interval); 7495 7496 status = wmi_unified_cmd_send(wmi_handle, buf, 7497 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 7498 if (QDF_IS_STATUS_ERROR(status)) { 7499 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 7500 status); 7501 wmi_buf_free(buf); 7502 return QDF_STATUS_E_FAILURE; 7503 } 7504 7505 return QDF_STATUS_SUCCESS; 7506 } 7507 7508 /** 7509 * send_pno_start_cmd_tlv() - PNO start request 7510 * @wmi_handle: wmi handle 7511 * @pno: PNO request 7512 * 7513 * This function request FW to start PNO request. 7514 * Request: CDF status 7515 */ 7516 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 7517 struct pno_scan_req_params *pno) 7518 { 7519 wmi_nlo_config_cmd_fixed_param *cmd; 7520 nlo_configured_parameters *nlo_list; 7521 uint32_t *channel_list; 7522 int32_t len; 7523 wmi_buf_t buf; 7524 uint8_t *buf_ptr; 7525 uint8_t i; 7526 int ret; 7527 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 7528 connected_nlo_rssi_params *nlo_relative_rssi; 7529 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 7530 7531 /* 7532 * TLV place holder for array nlo_configured_parameters(nlo_list) 7533 * TLV place holder for array of uint32_t channel_list 7534 * TLV place holder for chnnl prediction cfg 7535 * TLV place holder for array of wmi_vendor_oui 7536 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 7537 */ 7538 len = sizeof(*cmd) + 7539 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 7540 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7541 7542 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 7543 WMI_NLO_MAX_CHAN); 7544 len += sizeof(nlo_configured_parameters) * 7545 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7546 len += sizeof(nlo_channel_prediction_cfg); 7547 len += sizeof(enlo_candidate_score_params); 7548 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 7549 len += sizeof(connected_nlo_rssi_params); 7550 len += sizeof(connected_nlo_bss_band_rssi_pref); 7551 7552 buf = wmi_buf_alloc(wmi_handle, len); 7553 if (!buf) { 7554 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7555 return QDF_STATUS_E_NOMEM; 7556 } 7557 7558 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7559 7560 buf_ptr = (uint8_t *) cmd; 7561 WMITLV_SET_HDR(&cmd->tlv_header, 7562 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7563 WMITLV_GET_STRUCT_TLVLEN 7564 (wmi_nlo_config_cmd_fixed_param)); 7565 cmd->vdev_id = pno->vdev_id; 7566 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 7567 7568 #ifdef FEATURE_WLAN_SCAN_PNO 7569 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 7570 pno->adaptive_dwell_mode); 7571 #endif 7572 /* Current FW does not support min-max range for dwell time */ 7573 cmd->active_dwell_time = pno->active_dwell_time; 7574 cmd->passive_dwell_time = pno->passive_dwell_time; 7575 7576 if (pno->do_passive_scan) 7577 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 7578 /* Copy scan interval */ 7579 cmd->fast_scan_period = pno->fast_scan_period; 7580 cmd->slow_scan_period = pno->slow_scan_period; 7581 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 7582 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 7583 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 7584 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 7585 cmd->fast_scan_period, cmd->slow_scan_period); 7586 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 7587 7588 /* mac randomization attributes */ 7589 if (pno->scan_random.randomize) { 7590 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 7591 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 7592 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 7593 pno->scan_random.mac_mask, 7594 &cmd->mac_addr, 7595 &cmd->mac_mask); 7596 } 7597 7598 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7599 7600 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7601 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 7602 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7603 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7604 buf_ptr += WMI_TLV_HDR_SIZE; 7605 7606 nlo_list = (nlo_configured_parameters *) buf_ptr; 7607 for (i = 0; i < cmd->no_of_ssids; i++) { 7608 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7609 WMITLV_TAG_ARRAY_BYTE, 7610 WMITLV_GET_STRUCT_TLVLEN 7611 (nlo_configured_parameters)); 7612 /* Copy ssid and it's length */ 7613 nlo_list[i].ssid.valid = true; 7614 nlo_list[i].ssid.ssid.ssid_len = 7615 pno->networks_list[i].ssid.length; 7616 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7617 pno->networks_list[i].ssid.ssid, 7618 nlo_list[i].ssid.ssid.ssid_len); 7619 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7620 nlo_list[i].ssid.ssid.ssid_len, 7621 (char *)nlo_list[i].ssid.ssid.ssid, 7622 nlo_list[i].ssid.ssid.ssid_len); 7623 7624 /* Copy rssi threshold */ 7625 if (pno->networks_list[i].rssi_thresh && 7626 pno->networks_list[i].rssi_thresh > 7627 WMI_RSSI_THOLD_DEFAULT) { 7628 nlo_list[i].rssi_cond.valid = true; 7629 nlo_list[i].rssi_cond.rssi = 7630 pno->networks_list[i].rssi_thresh; 7631 WMI_LOGD("RSSI threshold : %d dBm", 7632 nlo_list[i].rssi_cond.rssi); 7633 } 7634 nlo_list[i].bcast_nw_type.valid = true; 7635 nlo_list[i].bcast_nw_type.bcast_nw_type = 7636 pno->networks_list[i].bc_new_type; 7637 WMI_LOGD("Broadcast NW type (%u)", 7638 nlo_list[i].bcast_nw_type.bcast_nw_type); 7639 } 7640 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7641 7642 /* Copy channel info */ 7643 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 7644 WMI_NLO_MAX_CHAN); 7645 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 7646 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7647 (cmd->num_of_channels * sizeof(uint32_t))); 7648 buf_ptr += WMI_TLV_HDR_SIZE; 7649 7650 channel_list = (uint32_t *) buf_ptr; 7651 for (i = 0; i < cmd->num_of_channels; i++) { 7652 channel_list[i] = pno->networks_list[0].channels[i]; 7653 7654 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 7655 channel_list[i] = 7656 wlan_chan_to_freq(pno-> 7657 networks_list[0].channels[i]); 7658 7659 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 7660 } 7661 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 7662 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7663 sizeof(nlo_channel_prediction_cfg)); 7664 buf_ptr += WMI_TLV_HDR_SIZE; 7665 wmi_set_pno_channel_prediction(buf_ptr, pno); 7666 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7667 /** TODO: Discrete firmware doesn't have command/option to configure 7668 * App IE which comes from wpa_supplicant as of part PNO start request. 7669 */ 7670 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 7671 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7672 buf_ptr += sizeof(enlo_candidate_score_params); 7673 7674 if (ie_whitelist->white_list) { 7675 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 7676 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 7677 &cmd->num_vendor_oui, 7678 ie_whitelist); 7679 } 7680 7681 /* ie white list */ 7682 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7683 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 7684 buf_ptr += WMI_TLV_HDR_SIZE; 7685 if (cmd->num_vendor_oui != 0) { 7686 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 7687 ie_whitelist->voui); 7688 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 7689 } 7690 7691 if (pno->relative_rssi_set) 7692 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 7693 7694 /* 7695 * Firmware calculation using connected PNO params: 7696 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 7697 * deduction of rssi_pref for chosen band_pref and 7698 * addition of rssi_pref for remaining bands (other than chosen band). 7699 */ 7700 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 7701 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 7702 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 7703 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 7704 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 7705 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 7706 buf_ptr += sizeof(*nlo_relative_rssi); 7707 7708 /* 7709 * As of now Kernel and Host supports one band and rssi preference. 7710 * Firmware supports array of band and rssi preferences 7711 */ 7712 cmd->num_cnlo_band_pref = 1; 7713 WMITLV_SET_HDR(buf_ptr, 7714 WMITLV_TAG_ARRAY_STRUC, 7715 cmd->num_cnlo_band_pref * 7716 sizeof(connected_nlo_bss_band_rssi_pref)); 7717 buf_ptr += WMI_TLV_HDR_SIZE; 7718 7719 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 7720 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 7721 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 7722 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 7723 WMITLV_GET_STRUCT_TLVLEN( 7724 connected_nlo_bss_band_rssi_pref)); 7725 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 7726 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 7727 WMI_LOGI("band_pref %d, rssi_pref %d", 7728 nlo_band_rssi[i].band, 7729 nlo_band_rssi[i].rssi_pref); 7730 } 7731 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 7732 7733 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7734 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7735 if (ret) { 7736 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7737 wmi_buf_free(buf); 7738 return QDF_STATUS_E_FAILURE; 7739 } 7740 7741 return QDF_STATUS_SUCCESS; 7742 } 7743 7744 /* send_set_ric_req_cmd_tlv() - set ric request element 7745 * @wmi_handle: wmi handle 7746 * @msg: message 7747 * @is_add_ts: is addts required 7748 * 7749 * This function sets ric request element for 11r roaming. 7750 * 7751 * Return: CDF status 7752 */ 7753 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 7754 void *msg, uint8_t is_add_ts) 7755 { 7756 wmi_ric_request_fixed_param *cmd; 7757 wmi_ric_tspec *tspec_param; 7758 wmi_buf_t buf; 7759 uint8_t *buf_ptr; 7760 struct mac_tspec_ie *ptspecIE = NULL; 7761 int32_t len = sizeof(wmi_ric_request_fixed_param) + 7762 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 7763 7764 buf = wmi_buf_alloc(wmi_handle, len); 7765 if (!buf) { 7766 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 7767 return QDF_STATUS_E_NOMEM; 7768 } 7769 7770 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7771 7772 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 7773 WMITLV_SET_HDR(&cmd->tlv_header, 7774 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 7775 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 7776 if (is_add_ts) 7777 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 7778 else 7779 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 7780 cmd->num_ric_request = 1; 7781 cmd->is_add_ric = is_add_ts; 7782 7783 buf_ptr += sizeof(wmi_ric_request_fixed_param); 7784 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 7785 7786 buf_ptr += WMI_TLV_HDR_SIZE; 7787 tspec_param = (wmi_ric_tspec *) buf_ptr; 7788 WMITLV_SET_HDR(&tspec_param->tlv_header, 7789 WMITLV_TAG_STRUC_wmi_ric_tspec, 7790 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 7791 7792 if (is_add_ts) 7793 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 7794 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7795 else 7796 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 7797 #endif 7798 if (ptspecIE) { 7799 /* Fill the tsinfo in the format expected by firmware */ 7800 #ifndef ANI_LITTLE_BIT_ENDIAN 7801 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 7802 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7803 #else 7804 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 7805 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7806 #endif /* ANI_LITTLE_BIT_ENDIAN */ 7807 7808 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 7809 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 7810 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 7811 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 7812 tspec_param->inactivity_interval = ptspecIE->inactInterval; 7813 tspec_param->suspension_interval = ptspecIE->suspendInterval; 7814 tspec_param->svc_start_time = ptspecIE->svcStartTime; 7815 tspec_param->min_data_rate = ptspecIE->minDataRate; 7816 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 7817 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 7818 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 7819 tspec_param->delay_bound = ptspecIE->delayBound; 7820 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 7821 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 7822 tspec_param->medium_time = 0; 7823 } 7824 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 7825 7826 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7827 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 7828 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 7829 __func__); 7830 if (is_add_ts) 7831 ((struct add_ts_param *) msg)->status = 7832 QDF_STATUS_E_FAILURE; 7833 wmi_buf_free(buf); 7834 return QDF_STATUS_E_FAILURE; 7835 } 7836 7837 return QDF_STATUS_SUCCESS; 7838 } 7839 7840 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 7841 /** 7842 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 7843 * @wmi_handle: wmi handle 7844 * @clear_req: ll stats clear request command params 7845 * 7846 * Return: QDF_STATUS_SUCCESS for success or error code 7847 */ 7848 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 7849 const struct ll_stats_clear_params *clear_req, 7850 uint8_t addr[IEEE80211_ADDR_LEN]) 7851 { 7852 wmi_clear_link_stats_cmd_fixed_param *cmd; 7853 int32_t len; 7854 wmi_buf_t buf; 7855 uint8_t *buf_ptr; 7856 int ret; 7857 7858 len = sizeof(*cmd); 7859 buf = wmi_buf_alloc(wmi_handle, len); 7860 7861 if (!buf) { 7862 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7863 return QDF_STATUS_E_NOMEM; 7864 } 7865 7866 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7867 qdf_mem_zero(buf_ptr, len); 7868 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 7869 7870 WMITLV_SET_HDR(&cmd->tlv_header, 7871 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 7872 WMITLV_GET_STRUCT_TLVLEN 7873 (wmi_clear_link_stats_cmd_fixed_param)); 7874 7875 cmd->stop_stats_collection_req = clear_req->stop_req; 7876 cmd->vdev_id = clear_req->sta_id; 7877 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 7878 7879 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 7880 &cmd->peer_macaddr); 7881 7882 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 7883 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 7884 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 7885 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 7886 /* WMI_LOGD("Peer MAC Addr : %pM", 7887 cmd->peer_macaddr); */ 7888 7889 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7890 WMI_CLEAR_LINK_STATS_CMDID); 7891 if (ret) { 7892 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 7893 wmi_buf_free(buf); 7894 return QDF_STATUS_E_FAILURE; 7895 } 7896 7897 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 7898 return QDF_STATUS_SUCCESS; 7899 } 7900 7901 /** 7902 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 7903 * @wmi_handle: wmi handle 7904 * @setReq: ll stats set request command params 7905 * 7906 * Return: QDF_STATUS_SUCCESS for success or error code 7907 */ 7908 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7909 const struct ll_stats_set_params *set_req) 7910 { 7911 wmi_start_link_stats_cmd_fixed_param *cmd; 7912 int32_t len; 7913 wmi_buf_t buf; 7914 uint8_t *buf_ptr; 7915 int ret; 7916 7917 len = sizeof(*cmd); 7918 buf = wmi_buf_alloc(wmi_handle, len); 7919 7920 if (!buf) { 7921 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7922 return QDF_STATUS_E_NOMEM; 7923 } 7924 7925 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7926 qdf_mem_zero(buf_ptr, len); 7927 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7928 7929 WMITLV_SET_HDR(&cmd->tlv_header, 7930 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7931 WMITLV_GET_STRUCT_TLVLEN 7932 (wmi_start_link_stats_cmd_fixed_param)); 7933 7934 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7935 cmd->aggressive_statistics_gathering = 7936 set_req->aggressive_statistics_gathering; 7937 7938 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 7939 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 7940 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 7941 7942 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7943 WMI_START_LINK_STATS_CMDID); 7944 if (ret) { 7945 WMI_LOGE("%s: Failed to send set link stats request", __func__); 7946 wmi_buf_free(buf); 7947 return QDF_STATUS_E_FAILURE; 7948 } 7949 7950 return QDF_STATUS_SUCCESS; 7951 } 7952 7953 /** 7954 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7955 * @wmi_handle:wmi handle 7956 * @get_req:ll stats get request command params 7957 * @addr: mac address 7958 * 7959 * Return: QDF_STATUS_SUCCESS for success or error code 7960 */ 7961 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7962 const struct ll_stats_get_params *get_req, 7963 uint8_t addr[IEEE80211_ADDR_LEN]) 7964 { 7965 wmi_request_link_stats_cmd_fixed_param *cmd; 7966 int32_t len; 7967 wmi_buf_t buf; 7968 uint8_t *buf_ptr; 7969 int ret; 7970 7971 len = sizeof(*cmd); 7972 buf = wmi_buf_alloc(wmi_handle, len); 7973 7974 if (!buf) { 7975 WMI_LOGE("%s: buf allocation failed", __func__); 7976 return QDF_STATUS_E_NOMEM; 7977 } 7978 7979 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7980 qdf_mem_zero(buf_ptr, len); 7981 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 7982 7983 WMITLV_SET_HDR(&cmd->tlv_header, 7984 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 7985 WMITLV_GET_STRUCT_TLVLEN 7986 (wmi_request_link_stats_cmd_fixed_param)); 7987 7988 cmd->request_id = get_req->req_id; 7989 cmd->stats_type = get_req->param_id_mask; 7990 cmd->vdev_id = get_req->sta_id; 7991 7992 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 7993 &cmd->peer_macaddr); 7994 7995 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 7996 WMI_LOGD("Request ID : %u", cmd->request_id); 7997 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 7998 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 7999 WMI_LOGD("Peer MAC Addr : %pM", addr); 8000 8001 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8002 WMI_REQUEST_LINK_STATS_CMDID); 8003 if (ret) { 8004 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8005 wmi_buf_free(buf); 8006 return QDF_STATUS_E_FAILURE; 8007 } 8008 8009 return QDF_STATUS_SUCCESS; 8010 } 8011 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 8012 8013 /** 8014 * send_congestion_cmd_tlv() - send request to fw to get CCA 8015 * @wmi_handle: wmi handle 8016 * @vdev_id: vdev id 8017 * 8018 * Return: CDF status 8019 */ 8020 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8021 uint8_t vdev_id) 8022 { 8023 wmi_buf_t buf; 8024 wmi_request_stats_cmd_fixed_param *cmd; 8025 uint8_t len; 8026 uint8_t *buf_ptr; 8027 8028 len = sizeof(*cmd); 8029 buf = wmi_buf_alloc(wmi_handle, len); 8030 if (!buf) { 8031 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8032 return QDF_STATUS_E_FAILURE; 8033 } 8034 8035 buf_ptr = wmi_buf_data(buf); 8036 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8037 WMITLV_SET_HDR(&cmd->tlv_header, 8038 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8039 WMITLV_GET_STRUCT_TLVLEN 8040 (wmi_request_stats_cmd_fixed_param)); 8041 8042 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8043 cmd->vdev_id = vdev_id; 8044 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8045 cmd->vdev_id, cmd->stats_id); 8046 8047 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8048 WMI_REQUEST_STATS_CMDID)) { 8049 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8050 __func__); 8051 wmi_buf_free(buf); 8052 return QDF_STATUS_E_FAILURE; 8053 } 8054 8055 return QDF_STATUS_SUCCESS; 8056 } 8057 8058 /** 8059 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8060 * @wmi_handle: wmi handle 8061 * @rssi_req: get RSSI request 8062 * 8063 * Return: CDF status 8064 */ 8065 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8066 { 8067 wmi_buf_t buf; 8068 wmi_request_stats_cmd_fixed_param *cmd; 8069 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8070 8071 buf = wmi_buf_alloc(wmi_handle, len); 8072 if (!buf) { 8073 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8074 return QDF_STATUS_E_FAILURE; 8075 } 8076 8077 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8078 WMITLV_SET_HDR(&cmd->tlv_header, 8079 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8080 WMITLV_GET_STRUCT_TLVLEN 8081 (wmi_request_stats_cmd_fixed_param)); 8082 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8083 if (wmi_unified_cmd_send 8084 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8085 WMI_LOGE("Failed to send host stats request to fw"); 8086 wmi_buf_free(buf); 8087 return QDF_STATUS_E_FAILURE; 8088 } 8089 8090 return QDF_STATUS_SUCCESS; 8091 } 8092 8093 /** 8094 * send_snr_cmd_tlv() - get RSSI from fw 8095 * @wmi_handle: wmi handle 8096 * @vdev_id: vdev id 8097 * 8098 * Return: CDF status 8099 */ 8100 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8101 { 8102 wmi_buf_t buf; 8103 wmi_request_stats_cmd_fixed_param *cmd; 8104 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8105 8106 buf = wmi_buf_alloc(wmi_handle, len); 8107 if (!buf) { 8108 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8109 return QDF_STATUS_E_FAILURE; 8110 } 8111 8112 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8113 cmd->vdev_id = vdev_id; 8114 8115 WMITLV_SET_HDR(&cmd->tlv_header, 8116 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8117 WMITLV_GET_STRUCT_TLVLEN 8118 (wmi_request_stats_cmd_fixed_param)); 8119 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8120 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8121 WMI_REQUEST_STATS_CMDID)) { 8122 WMI_LOGE("Failed to send host stats request to fw"); 8123 wmi_buf_free(buf); 8124 return QDF_STATUS_E_FAILURE; 8125 } 8126 8127 return QDF_STATUS_SUCCESS; 8128 } 8129 8130 /** 8131 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8132 * @wmi_handle: wmi handle 8133 * @link_status: get link params 8134 * 8135 * Return: CDF status 8136 */ 8137 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8138 struct link_status_params *link_status) 8139 { 8140 wmi_buf_t buf; 8141 wmi_request_stats_cmd_fixed_param *cmd; 8142 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8143 8144 buf = wmi_buf_alloc(wmi_handle, len); 8145 if (!buf) { 8146 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8147 return QDF_STATUS_E_FAILURE; 8148 } 8149 8150 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8151 WMITLV_SET_HDR(&cmd->tlv_header, 8152 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8153 WMITLV_GET_STRUCT_TLVLEN 8154 (wmi_request_stats_cmd_fixed_param)); 8155 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8156 cmd->vdev_id = link_status->session_id; 8157 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8158 WMI_REQUEST_STATS_CMDID)) { 8159 WMI_LOGE("Failed to send WMI link status request to fw"); 8160 wmi_buf_free(buf); 8161 return QDF_STATUS_E_FAILURE; 8162 } 8163 8164 return QDF_STATUS_SUCCESS; 8165 } 8166 8167 /** 8168 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8169 * @wmi_handle: wmi handle 8170 * @ta_dhcp_ind: DHCP indication parameter 8171 * 8172 * Return: CDF Status 8173 */ 8174 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8175 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8176 { 8177 QDF_STATUS status; 8178 wmi_buf_t buf = NULL; 8179 uint8_t *buf_ptr; 8180 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8181 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8182 8183 8184 buf = wmi_buf_alloc(wmi_handle, len); 8185 if (!buf) { 8186 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8187 return QDF_STATUS_E_NOMEM; 8188 } 8189 8190 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8191 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8192 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8193 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8194 WMITLV_GET_STRUCT_TLVLEN 8195 (wmi_peer_set_param_cmd_fixed_param)); 8196 8197 /* fill in values */ 8198 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8199 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8200 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8201 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8202 &ta_dhcp_ind->peer_macaddr, 8203 sizeof(ta_dhcp_ind->peer_macaddr)); 8204 8205 status = wmi_unified_cmd_send(wmi_handle, buf, 8206 len, WMI_PEER_SET_PARAM_CMDID); 8207 if (QDF_IS_STATUS_ERROR(status)) { 8208 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8209 " returned Error %d", __func__, status); 8210 wmi_buf_free(buf); 8211 } 8212 8213 return status; 8214 } 8215 8216 /** 8217 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8218 * @wmi_handle: wmi handle 8219 * @pLinkSpeed: link speed info 8220 * 8221 * Return: CDF status 8222 */ 8223 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8224 wmi_mac_addr peer_macaddr) 8225 { 8226 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8227 wmi_buf_t wmi_buf; 8228 uint32_t len; 8229 uint8_t *buf_ptr; 8230 8231 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8232 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8233 if (!wmi_buf) { 8234 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8235 return QDF_STATUS_E_NOMEM; 8236 } 8237 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8238 8239 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8240 WMITLV_SET_HDR(&cmd->tlv_header, 8241 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8242 WMITLV_GET_STRUCT_TLVLEN 8243 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8244 8245 /* Copy the peer macaddress to the wma buffer */ 8246 qdf_mem_copy(&cmd->peer_macaddr, 8247 &peer_macaddr, 8248 sizeof(peer_macaddr)); 8249 8250 8251 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8252 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8253 WMI_LOGE("%s: failed to send link speed command", __func__); 8254 wmi_buf_free(wmi_buf); 8255 return QDF_STATUS_E_FAILURE; 8256 } 8257 return QDF_STATUS_SUCCESS; 8258 } 8259 8260 #ifdef WLAN_SUPPORT_GREEN_AP 8261 /** 8262 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8263 * @wmi_handle: wmi handler 8264 * @egap_params: pointer to egap_params 8265 * 8266 * Return: 0 for success, otherwise appropriate error code 8267 */ 8268 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8269 struct wlan_green_ap_egap_params *egap_params) 8270 { 8271 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8272 wmi_buf_t buf; 8273 int32_t err; 8274 8275 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8276 if (!buf) { 8277 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8278 return QDF_STATUS_E_NOMEM; 8279 } 8280 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8281 WMITLV_SET_HDR(&cmd->tlv_header, 8282 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8283 WMITLV_GET_STRUCT_TLVLEN( 8284 wmi_ap_ps_egap_param_cmd_fixed_param)); 8285 8286 cmd->enable = egap_params->host_enable_egap; 8287 cmd->inactivity_time = egap_params->egap_inactivity_time; 8288 cmd->wait_time = egap_params->egap_wait_time; 8289 cmd->flags = egap_params->egap_feature_flags; 8290 err = wmi_unified_cmd_send(wmi_handle, buf, 8291 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 8292 if (err) { 8293 WMI_LOGE("Failed to send ap_ps_egap cmd"); 8294 wmi_buf_free(buf); 8295 return QDF_STATUS_E_FAILURE; 8296 } 8297 8298 return QDF_STATUS_SUCCESS; 8299 } 8300 #endif 8301 8302 /** 8303 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 8304 * @wmi_handl: wmi handle 8305 * @cmd: Profiling command index 8306 * @value1: parameter1 value 8307 * @value2: parameter2 value 8308 * 8309 * Return: QDF_STATUS_SUCCESS for success else error code 8310 */ 8311 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 8312 uint32_t cmd, uint32_t value1, uint32_t value2) 8313 { 8314 wmi_buf_t buf; 8315 int32_t len = 0; 8316 int ret; 8317 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8318 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8319 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8320 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 8321 8322 switch (cmd) { 8323 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 8324 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8325 buf = wmi_buf_alloc(wmi_handle, len); 8326 if (!buf) { 8327 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8328 return QDF_STATUS_E_NOMEM; 8329 } 8330 prof_trig_cmd = 8331 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8332 wmi_buf_data(buf); 8333 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8334 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8335 WMITLV_GET_STRUCT_TLVLEN 8336 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8337 prof_trig_cmd->enable = value1; 8338 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8339 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8340 if (ret) { 8341 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 8342 value1); 8343 wmi_buf_free(buf); 8344 return ret; 8345 } 8346 break; 8347 8348 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 8349 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 8350 buf = wmi_buf_alloc(wmi_handle, len); 8351 if (!buf) { 8352 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8353 return QDF_STATUS_E_NOMEM; 8354 } 8355 profile_getdata_cmd = 8356 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 8357 wmi_buf_data(buf); 8358 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 8359 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 8360 WMITLV_GET_STRUCT_TLVLEN 8361 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 8362 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8363 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 8364 if (ret) { 8365 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 8366 value1, value2); 8367 wmi_buf_free(buf); 8368 return ret; 8369 } 8370 break; 8371 8372 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 8373 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8374 buf = wmi_buf_alloc(wmi_handle, len); 8375 if (!buf) { 8376 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8377 return QDF_STATUS_E_NOMEM; 8378 } 8379 hist_intvl_cmd = 8380 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8381 wmi_buf_data(buf); 8382 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8383 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8384 WMITLV_GET_STRUCT_TLVLEN 8385 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8386 hist_intvl_cmd->profile_id = value1; 8387 hist_intvl_cmd->value = value2; 8388 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8389 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8390 if (ret) { 8391 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 8392 value1, value2); 8393 wmi_buf_free(buf); 8394 return ret; 8395 } 8396 break; 8397 8398 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 8399 len = 8400 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8401 buf = wmi_buf_alloc(wmi_handle, len); 8402 if (!buf) { 8403 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8404 return QDF_STATUS_E_NOMEM; 8405 } 8406 profile_enable_cmd = 8407 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8408 wmi_buf_data(buf); 8409 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8410 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8411 WMITLV_GET_STRUCT_TLVLEN 8412 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8413 profile_enable_cmd->profile_id = value1; 8414 profile_enable_cmd->enable = value2; 8415 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8416 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8417 if (ret) { 8418 WMI_LOGE("enable cmd Failed for id %d value %d", 8419 value1, value2); 8420 wmi_buf_free(buf); 8421 return ret; 8422 } 8423 break; 8424 8425 default: 8426 WMI_LOGD("%s: invalid profiling command", __func__); 8427 break; 8428 } 8429 8430 return 0; 8431 } 8432 8433 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 8434 struct wlm_latency_level_param *params) 8435 { 8436 wmi_wlm_config_cmd_fixed_param *cmd; 8437 wmi_buf_t buf; 8438 uint32_t len = sizeof(*cmd); 8439 static uint32_t ll[4] = {100, 60, 40, 20}; 8440 8441 buf = wmi_buf_alloc(wmi_handle, len); 8442 if (!buf) { 8443 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8444 return QDF_STATUS_E_NOMEM; 8445 } 8446 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 8447 WMITLV_SET_HDR(&cmd->tlv_header, 8448 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 8449 WMITLV_GET_STRUCT_TLVLEN 8450 (wmi_wlm_config_cmd_fixed_param)); 8451 cmd->vdev_id = params->vdev_id; 8452 cmd->latency_level = params->wlm_latency_level; 8453 cmd->ul_latency = ll[params->wlm_latency_level]; 8454 cmd->dl_latency = ll[params->wlm_latency_level]; 8455 cmd->flags = params->wlm_latency_flags; 8456 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8457 WMI_WLM_CONFIG_CMDID)) { 8458 WMI_LOGE("%s: Failed to send setting latency config command", 8459 __func__); 8460 wmi_buf_free(buf); 8461 return QDF_STATUS_E_FAILURE; 8462 } 8463 8464 return 0; 8465 } 8466 /** 8467 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 8468 * @wmi_handle: wmi handle 8469 * @vdev_id: vdev id 8470 * 8471 * Return: QDF_STATUS_SUCCESS for success or error code 8472 */ 8473 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8474 { 8475 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 8476 wmi_buf_t buf; 8477 int32_t len = sizeof(*cmd); 8478 8479 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8480 buf = wmi_buf_alloc(wmi_handle, len); 8481 if (!buf) { 8482 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8483 return QDF_STATUS_E_NOMEM; 8484 } 8485 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 8486 wmi_buf_data(buf); 8487 WMITLV_SET_HDR(&cmd->tlv_header, 8488 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 8489 WMITLV_GET_STRUCT_TLVLEN 8490 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 8491 cmd->vdev_id = vdev_id; 8492 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 8493 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8494 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 8495 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 8496 __func__); 8497 wmi_buf_free(buf); 8498 return QDF_STATUS_E_FAILURE; 8499 } 8500 8501 return 0; 8502 } 8503 8504 /** 8505 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 8506 * @wmi_handle: wmi handle 8507 * @vdev_id: vdev id 8508 * 8509 * Return: QDF_STATUS_SUCCESS for success or error code 8510 */ 8511 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 8512 uint8_t vdev_id) 8513 { 8514 wmi_csa_offload_enable_cmd_fixed_param *cmd; 8515 wmi_buf_t buf; 8516 int32_t len = sizeof(*cmd); 8517 8518 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8519 buf = wmi_buf_alloc(wmi_handle, len); 8520 if (!buf) { 8521 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8522 return QDF_STATUS_E_NOMEM; 8523 } 8524 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 8525 WMITLV_SET_HDR(&cmd->tlv_header, 8526 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 8527 WMITLV_GET_STRUCT_TLVLEN 8528 (wmi_csa_offload_enable_cmd_fixed_param)); 8529 cmd->vdev_id = vdev_id; 8530 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 8531 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8532 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 8533 WMI_LOGP("%s: Failed to send CSA offload enable command", 8534 __func__); 8535 wmi_buf_free(buf); 8536 return QDF_STATUS_E_FAILURE; 8537 } 8538 8539 return 0; 8540 } 8541 8542 #ifdef WLAN_FEATURE_CIF_CFR 8543 /** 8544 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 8545 * @wmi_handle: wmi handle 8546 * @data_len: len of dma cfg req 8547 * @data: dma cfg req 8548 * 8549 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8550 */ 8551 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8552 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 8553 { 8554 wmi_buf_t buf; 8555 uint8_t *cmd; 8556 QDF_STATUS ret; 8557 8558 WMITLV_SET_HDR(cfg, 8559 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 8560 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 8561 8562 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 8563 if (!buf) { 8564 WMI_LOGE(FL("wmi_buf_alloc failed")); 8565 return QDF_STATUS_E_FAILURE; 8566 } 8567 8568 cmd = (uint8_t *) wmi_buf_data(buf); 8569 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 8570 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 8571 sizeof(*cfg)); 8572 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 8573 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 8574 if (QDF_IS_STATUS_ERROR(ret)) { 8575 WMI_LOGE(FL(":wmi cmd send failed")); 8576 wmi_buf_free(buf); 8577 } 8578 8579 return ret; 8580 } 8581 #endif 8582 8583 /** 8584 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 8585 * @wmi_handle: wmi handle 8586 * @data_len: len of dma cfg req 8587 * @data: dma cfg req 8588 * 8589 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8590 */ 8591 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8592 struct direct_buf_rx_cfg_req *cfg) 8593 { 8594 wmi_buf_t buf; 8595 wmi_dma_ring_cfg_req_fixed_param *cmd; 8596 QDF_STATUS ret; 8597 int32_t len = sizeof(*cmd); 8598 8599 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8600 if (!buf) { 8601 WMI_LOGE(FL("wmi_buf_alloc failed")); 8602 return QDF_STATUS_E_FAILURE; 8603 } 8604 8605 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 8606 8607 WMITLV_SET_HDR(&cmd->tlv_header, 8608 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 8609 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 8610 8611 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8612 cfg->pdev_id); 8613 cmd->mod_id = cfg->mod_id; 8614 cmd->base_paddr_lo = cfg->base_paddr_lo; 8615 cmd->base_paddr_hi = cfg->base_paddr_hi; 8616 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 8617 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 8618 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 8619 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 8620 cmd->num_elems = cfg->num_elems; 8621 cmd->buf_size = cfg->buf_size; 8622 cmd->num_resp_per_event = cfg->num_resp_per_event; 8623 cmd->event_timeout_ms = cfg->event_timeout_ms; 8624 8625 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 8626 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 8627 "head idx paddr hi %x tail idx paddr lo %x" 8628 "tail idx addr hi %x num elems %d buf size %d num resp %d" 8629 "event timeout %d\n", __func__, cmd->pdev_id, 8630 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 8631 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 8632 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 8633 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 8634 cmd->event_timeout_ms); 8635 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8636 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 8637 if (QDF_IS_STATUS_ERROR(ret)) { 8638 WMI_LOGE(FL(":wmi cmd send failed")); 8639 wmi_buf_free(buf); 8640 } 8641 8642 return ret; 8643 } 8644 8645 /** 8646 * send_start_11d_scan_cmd_tlv() - start 11d scan request 8647 * @wmi_handle: wmi handle 8648 * @start_11d_scan: 11d scan start request parameters 8649 * 8650 * This function request FW to start 11d scan. 8651 * 8652 * Return: QDF status 8653 */ 8654 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8655 struct reg_start_11d_scan_req *start_11d_scan) 8656 { 8657 wmi_11d_scan_start_cmd_fixed_param *cmd; 8658 int32_t len; 8659 wmi_buf_t buf; 8660 int ret; 8661 8662 len = sizeof(*cmd); 8663 buf = wmi_buf_alloc(wmi_handle, len); 8664 if (!buf) { 8665 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8666 return QDF_STATUS_E_NOMEM; 8667 } 8668 8669 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 8670 8671 WMITLV_SET_HDR(&cmd->tlv_header, 8672 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 8673 WMITLV_GET_STRUCT_TLVLEN 8674 (wmi_11d_scan_start_cmd_fixed_param)); 8675 8676 cmd->vdev_id = start_11d_scan->vdev_id; 8677 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 8678 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 8679 8680 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 8681 8682 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8683 WMI_11D_SCAN_START_CMDID); 8684 if (ret) { 8685 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 8686 wmi_buf_free(buf); 8687 return QDF_STATUS_E_FAILURE; 8688 } 8689 8690 return QDF_STATUS_SUCCESS; 8691 } 8692 8693 /** 8694 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 8695 * @wmi_handle: wmi handle 8696 * @start_11d_scan: 11d scan stop request parameters 8697 * 8698 * This function request FW to stop 11d scan. 8699 * 8700 * Return: QDF status 8701 */ 8702 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8703 struct reg_stop_11d_scan_req *stop_11d_scan) 8704 { 8705 wmi_11d_scan_stop_cmd_fixed_param *cmd; 8706 int32_t len; 8707 wmi_buf_t buf; 8708 int ret; 8709 8710 len = sizeof(*cmd); 8711 buf = wmi_buf_alloc(wmi_handle, len); 8712 if (!buf) { 8713 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8714 return QDF_STATUS_E_NOMEM; 8715 } 8716 8717 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 8718 8719 WMITLV_SET_HDR(&cmd->tlv_header, 8720 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 8721 WMITLV_GET_STRUCT_TLVLEN 8722 (wmi_11d_scan_stop_cmd_fixed_param)); 8723 8724 cmd->vdev_id = stop_11d_scan->vdev_id; 8725 8726 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 8727 8728 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8729 WMI_11D_SCAN_STOP_CMDID); 8730 if (ret) { 8731 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 8732 wmi_buf_free(buf); 8733 return QDF_STATUS_E_FAILURE; 8734 } 8735 8736 return QDF_STATUS_SUCCESS; 8737 } 8738 8739 /** 8740 * send_start_oem_data_cmd_tlv() - start OEM data request to target 8741 * @wmi_handle: wmi handle 8742 * @startOemDataReq: start request params 8743 * 8744 * Return: CDF status 8745 */ 8746 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 8747 uint32_t data_len, 8748 uint8_t *data) 8749 { 8750 wmi_buf_t buf; 8751 uint8_t *cmd; 8752 QDF_STATUS ret; 8753 8754 buf = wmi_buf_alloc(wmi_handle, 8755 (data_len + WMI_TLV_HDR_SIZE)); 8756 if (!buf) { 8757 WMI_LOGE(FL("wmi_buf_alloc failed")); 8758 return QDF_STATUS_E_FAILURE; 8759 } 8760 8761 cmd = (uint8_t *) wmi_buf_data(buf); 8762 8763 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 8764 cmd += WMI_TLV_HDR_SIZE; 8765 qdf_mem_copy(cmd, data, 8766 data_len); 8767 8768 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 8769 data_len); 8770 8771 ret = wmi_unified_cmd_send(wmi_handle, buf, 8772 (data_len + 8773 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 8774 8775 if (QDF_IS_STATUS_ERROR(ret)) { 8776 WMI_LOGE(FL(":wmi cmd send failed")); 8777 wmi_buf_free(buf); 8778 } 8779 8780 return ret; 8781 } 8782 8783 /** 8784 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 8785 * @wmi_handle: wmi handle 8786 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 8787 * 8788 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 8789 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 8790 * to firmware based on phyerr filtering 8791 * offload status. 8792 * 8793 * Return: 1 success, 0 failure 8794 */ 8795 static QDF_STATUS 8796 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8797 bool dfs_phyerr_filter_offload) 8798 { 8799 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 8800 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 8801 wmi_buf_t buf; 8802 uint16_t len; 8803 QDF_STATUS ret; 8804 8805 8806 if (false == dfs_phyerr_filter_offload) { 8807 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 8808 __func__); 8809 len = sizeof(*disable_phyerr_offload_cmd); 8810 buf = wmi_buf_alloc(wmi_handle, len); 8811 if (!buf) { 8812 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8813 return 0; 8814 } 8815 disable_phyerr_offload_cmd = 8816 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 8817 wmi_buf_data(buf); 8818 8819 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 8820 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 8821 WMITLV_GET_STRUCT_TLVLEN 8822 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 8823 8824 /* 8825 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 8826 * to the firmware to disable the phyerror 8827 * filtering offload. 8828 */ 8829 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8830 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 8831 if (QDF_IS_STATUS_ERROR(ret)) { 8832 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 8833 __func__, ret); 8834 wmi_buf_free(buf); 8835 return QDF_STATUS_E_FAILURE; 8836 } 8837 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 8838 __func__); 8839 } else { 8840 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 8841 __func__); 8842 8843 len = sizeof(*enable_phyerr_offload_cmd); 8844 buf = wmi_buf_alloc(wmi_handle, len); 8845 if (!buf) { 8846 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8847 return QDF_STATUS_E_FAILURE; 8848 } 8849 8850 enable_phyerr_offload_cmd = 8851 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 8852 wmi_buf_data(buf); 8853 8854 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 8855 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 8856 WMITLV_GET_STRUCT_TLVLEN 8857 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 8858 8859 /* 8860 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 8861 * to the firmware to enable the phyerror 8862 * filtering offload. 8863 */ 8864 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8865 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 8866 8867 if (QDF_IS_STATUS_ERROR(ret)) { 8868 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 8869 __func__, ret); 8870 wmi_buf_free(buf); 8871 return QDF_STATUS_E_FAILURE; 8872 } 8873 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 8874 __func__); 8875 } 8876 8877 return QDF_STATUS_SUCCESS; 8878 } 8879 8880 /** 8881 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 8882 * will wake up host after specified time is elapsed 8883 * @wmi_handle: wmi handle 8884 * @vdev_id: vdev id 8885 * @cookie: value to identify reason why host set up wake call. 8886 * @time: time in ms 8887 * 8888 * Return: QDF status 8889 */ 8890 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 8891 uint8_t vdev_id, uint32_t cookie, uint32_t time) 8892 { 8893 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 8894 wmi_buf_t buf; 8895 uint8_t *buf_ptr; 8896 int32_t len; 8897 int ret; 8898 8899 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 8900 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 8901 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 8902 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 8903 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 8904 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 8905 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 8906 8907 buf = wmi_buf_alloc(wmi_handle, len); 8908 if (!buf) { 8909 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8910 return QDF_STATUS_E_NOMEM; 8911 } 8912 8913 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 8914 buf_ptr = (uint8_t *) cmd; 8915 8916 WMITLV_SET_HDR(&cmd->tlv_header, 8917 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 8918 WMITLV_GET_STRUCT_TLVLEN 8919 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 8920 cmd->vdev_id = vdev_id; 8921 cmd->pattern_id = cookie, 8922 cmd->pattern_type = WOW_TIMER_PATTERN; 8923 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 8924 8925 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 8926 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8927 buf_ptr += WMI_TLV_HDR_SIZE; 8928 8929 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 8930 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8931 buf_ptr += WMI_TLV_HDR_SIZE; 8932 8933 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 8934 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8935 buf_ptr += WMI_TLV_HDR_SIZE; 8936 8937 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 8938 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8939 buf_ptr += WMI_TLV_HDR_SIZE; 8940 8941 /* Fill TLV for pattern_info_timeout, and time value */ 8942 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8943 buf_ptr += WMI_TLV_HDR_SIZE; 8944 *((uint32_t *) buf_ptr) = time; 8945 buf_ptr += sizeof(uint32_t); 8946 8947 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 8948 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8949 buf_ptr += WMI_TLV_HDR_SIZE; 8950 *((uint32_t *) buf_ptr) = 0; 8951 8952 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 8953 __func__, time, vdev_id); 8954 8955 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8956 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 8957 if (ret) { 8958 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 8959 __func__); 8960 wmi_buf_free(buf); 8961 return QDF_STATUS_E_FAILURE; 8962 } 8963 8964 return QDF_STATUS_SUCCESS; 8965 } 8966 8967 #if !defined(REMOVE_PKT_LOG) 8968 /** 8969 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 8970 * @wmi_handle: wmi handle 8971 * @pktlog_event: pktlog event 8972 * @cmd_id: pktlog cmd id 8973 * 8974 * Return: CDF status 8975 */ 8976 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 8977 WMI_PKTLOG_EVENT pktlog_event, 8978 WMI_CMD_ID cmd_id, uint8_t user_triggered) 8979 { 8980 WMI_PKTLOG_EVENT PKTLOG_EVENT; 8981 WMI_CMD_ID CMD_ID; 8982 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 8983 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 8984 int len = 0; 8985 wmi_buf_t buf; 8986 8987 PKTLOG_EVENT = pktlog_event; 8988 CMD_ID = cmd_id; 8989 8990 switch (CMD_ID) { 8991 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 8992 len = sizeof(*cmd); 8993 buf = wmi_buf_alloc(wmi_handle, len); 8994 if (!buf) { 8995 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8996 return QDF_STATUS_E_NOMEM; 8997 } 8998 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 8999 wmi_buf_data(buf); 9000 WMITLV_SET_HDR(&cmd->tlv_header, 9001 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9002 WMITLV_GET_STRUCT_TLVLEN 9003 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9004 cmd->evlist = PKTLOG_EVENT; 9005 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9006 : WMI_PKTLOG_ENABLE_AUTO; 9007 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9008 WMI_HOST_PDEV_ID_SOC); 9009 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9010 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9011 WMI_LOGE("failed to send pktlog enable cmdid"); 9012 goto wmi_send_failed; 9013 } 9014 break; 9015 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9016 len = sizeof(*disable_cmd); 9017 buf = wmi_buf_alloc(wmi_handle, len); 9018 if (!buf) { 9019 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9020 return QDF_STATUS_E_NOMEM; 9021 } 9022 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9023 wmi_buf_data(buf); 9024 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9025 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9026 WMITLV_GET_STRUCT_TLVLEN 9027 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9028 disable_cmd->pdev_id = 9029 wmi_handle->ops->convert_pdev_id_host_to_target( 9030 WMI_HOST_PDEV_ID_SOC); 9031 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9032 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9033 WMI_LOGE("failed to send pktlog disable cmdid"); 9034 goto wmi_send_failed; 9035 } 9036 break; 9037 default: 9038 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9039 break; 9040 } 9041 9042 return QDF_STATUS_SUCCESS; 9043 9044 wmi_send_failed: 9045 wmi_buf_free(buf); 9046 return QDF_STATUS_E_FAILURE; 9047 } 9048 #endif /* REMOVE_PKT_LOG */ 9049 9050 /** 9051 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9052 * @wmi_handle: wmi handle 9053 * @ptrn_id: pattern id 9054 * @vdev_id: vdev id 9055 * 9056 * Return: CDF status 9057 */ 9058 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9059 uint8_t ptrn_id, uint8_t vdev_id) 9060 { 9061 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9062 wmi_buf_t buf; 9063 int32_t len; 9064 int ret; 9065 9066 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9067 9068 9069 buf = wmi_buf_alloc(wmi_handle, len); 9070 if (!buf) { 9071 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9072 return QDF_STATUS_E_NOMEM; 9073 } 9074 9075 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9076 9077 WMITLV_SET_HDR(&cmd->tlv_header, 9078 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9079 WMITLV_GET_STRUCT_TLVLEN( 9080 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9081 cmd->vdev_id = vdev_id; 9082 cmd->pattern_id = ptrn_id; 9083 cmd->pattern_type = WOW_BITMAP_PATTERN; 9084 9085 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9086 cmd->pattern_id, vdev_id); 9087 9088 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9089 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9090 if (ret) { 9091 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9092 wmi_buf_free(buf); 9093 return QDF_STATUS_E_FAILURE; 9094 } 9095 9096 return QDF_STATUS_SUCCESS; 9097 } 9098 9099 /** 9100 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9101 * @wmi_handle: wmi handle 9102 * 9103 * Sends host wakeup indication to FW. On receiving this indication, 9104 * FW will come out of WOW. 9105 * 9106 * Return: CDF status 9107 */ 9108 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9109 { 9110 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9111 wmi_buf_t buf; 9112 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9113 int32_t len; 9114 int ret; 9115 9116 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9117 9118 buf = wmi_buf_alloc(wmi_handle, len); 9119 if (!buf) { 9120 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9121 return QDF_STATUS_E_NOMEM; 9122 } 9123 9124 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9125 wmi_buf_data(buf); 9126 WMITLV_SET_HDR(&cmd->tlv_header, 9127 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9128 WMITLV_GET_STRUCT_TLVLEN 9129 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9130 9131 9132 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9133 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9134 if (ret) { 9135 WMI_LOGE("Failed to send host wakeup indication to fw"); 9136 wmi_buf_free(buf); 9137 return QDF_STATUS_E_FAILURE; 9138 } 9139 9140 return qdf_status; 9141 } 9142 9143 /** 9144 * send_del_ts_cmd_tlv() - send DELTS request to fw 9145 * @wmi_handle: wmi handle 9146 * @msg: delts params 9147 * 9148 * Return: CDF status 9149 */ 9150 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9151 uint8_t ac) 9152 { 9153 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9154 wmi_buf_t buf; 9155 int32_t len = sizeof(*cmd); 9156 9157 buf = wmi_buf_alloc(wmi_handle, len); 9158 if (!buf) { 9159 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9160 return QDF_STATUS_E_NOMEM; 9161 } 9162 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9163 WMITLV_SET_HDR(&cmd->tlv_header, 9164 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9165 WMITLV_GET_STRUCT_TLVLEN 9166 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9167 cmd->vdev_id = vdev_id; 9168 cmd->ac = ac; 9169 9170 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9171 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9172 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9173 WMI_VDEV_WMM_DELTS_CMDID)) { 9174 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9175 wmi_buf_free(buf); 9176 return QDF_STATUS_E_FAILURE; 9177 } 9178 9179 return QDF_STATUS_SUCCESS; 9180 } 9181 9182 /** 9183 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9184 * @wmi_handle: handle to wmi 9185 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9186 * 9187 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9188 * ADD_TS requestes to firmware in loop for all the ACs with 9189 * active flow. 9190 * 9191 * Return: CDF status 9192 */ 9193 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9194 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9195 { 9196 int i = 0; 9197 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9198 wmi_buf_t buf; 9199 int32_t len = sizeof(*cmd); 9200 9201 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9202 /* if flow in this AC is active */ 9203 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9204 /* 9205 * as per implementation of wma_add_ts_req() we 9206 * are not waiting any response from firmware so 9207 * apart from sending ADDTS to firmware just send 9208 * success to upper layers 9209 */ 9210 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9211 9212 buf = wmi_buf_alloc(wmi_handle, len); 9213 if (!buf) { 9214 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9215 return QDF_STATUS_E_NOMEM; 9216 } 9217 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9218 wmi_buf_data(buf); 9219 WMITLV_SET_HDR(&cmd->tlv_header, 9220 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9221 WMITLV_GET_STRUCT_TLVLEN 9222 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9223 cmd->vdev_id = aggr_qos_rsp_msg->sessionId; 9224 cmd->ac = 9225 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9226 traffic.userPrio); 9227 cmd->medium_time_us = 9228 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9229 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9230 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9231 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9232 cmd->medium_time_us, cmd->downgrade_type); 9233 if (wmi_unified_cmd_send 9234 (wmi_handle, buf, len, 9235 WMI_VDEV_WMM_ADDTS_CMDID)) { 9236 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9237 __func__); 9238 aggr_qos_rsp_msg->status[i] = 9239 QDF_STATUS_E_FAILURE; 9240 wmi_buf_free(buf); 9241 return QDF_STATUS_E_FAILURE; 9242 } 9243 } 9244 } 9245 9246 return QDF_STATUS_SUCCESS; 9247 } 9248 9249 /** 9250 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9251 * @wmi_handle: wmi handle 9252 * @msg: ADDTS params 9253 * 9254 * Return: CDF status 9255 */ 9256 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9257 struct add_ts_param *msg) 9258 { 9259 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9260 wmi_buf_t buf; 9261 int32_t len = sizeof(*cmd); 9262 9263 msg->status = QDF_STATUS_SUCCESS; 9264 9265 buf = wmi_buf_alloc(wmi_handle, len); 9266 if (!buf) { 9267 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9268 return QDF_STATUS_E_NOMEM; 9269 } 9270 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9271 WMITLV_SET_HDR(&cmd->tlv_header, 9272 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9273 WMITLV_GET_STRUCT_TLVLEN 9274 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9275 cmd->vdev_id = msg->sme_session_id; 9276 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9277 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9278 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9279 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9280 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9281 cmd->downgrade_type, __func__, __LINE__); 9282 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9283 WMI_VDEV_WMM_ADDTS_CMDID)) { 9284 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9285 msg->status = QDF_STATUS_E_FAILURE; 9286 wmi_buf_free(buf); 9287 return QDF_STATUS_E_FAILURE; 9288 } 9289 9290 return QDF_STATUS_SUCCESS; 9291 } 9292 9293 /** 9294 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 9295 * @wmi_handle: wmi handle 9296 * @pAddPeriodicTxPtrnParams: tx ptrn params 9297 * 9298 * Retrun: CDF status 9299 */ 9300 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9301 struct periodic_tx_pattern * 9302 pAddPeriodicTxPtrnParams, 9303 uint8_t vdev_id) 9304 { 9305 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9306 wmi_buf_t wmi_buf; 9307 uint32_t len; 9308 uint8_t *buf_ptr; 9309 uint32_t ptrn_len, ptrn_len_aligned; 9310 int j; 9311 9312 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 9313 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 9314 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 9315 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 9316 9317 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9318 if (!wmi_buf) { 9319 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9320 return QDF_STATUS_E_NOMEM; 9321 } 9322 9323 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 9324 9325 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 9326 WMITLV_SET_HDR(&cmd->tlv_header, 9327 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9328 WMITLV_GET_STRUCT_TLVLEN 9329 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9330 9331 /* Pass the pattern id to delete for the corresponding vdev id */ 9332 cmd->vdev_id = vdev_id; 9333 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 9334 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 9335 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 9336 9337 /* Pattern info */ 9338 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9339 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 9340 buf_ptr += WMI_TLV_HDR_SIZE; 9341 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 9342 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 9343 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 9344 9345 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 9346 __func__, cmd->pattern_id, cmd->vdev_id); 9347 9348 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9349 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9350 WMI_LOGE("%s: failed to add pattern set state command", 9351 __func__); 9352 wmi_buf_free(wmi_buf); 9353 return QDF_STATUS_E_FAILURE; 9354 } 9355 return QDF_STATUS_SUCCESS; 9356 } 9357 9358 /** 9359 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 9360 * @wmi_handle: wmi handle 9361 * @vdev_id: vdev id 9362 * @pattern_id: pattern id 9363 * 9364 * Retrun: CDF status 9365 */ 9366 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9367 uint8_t vdev_id, 9368 uint8_t pattern_id) 9369 { 9370 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9371 wmi_buf_t wmi_buf; 9372 uint32_t len = 9373 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9374 9375 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9376 if (!wmi_buf) { 9377 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9378 return QDF_STATUS_E_NOMEM; 9379 } 9380 9381 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 9382 wmi_buf_data(wmi_buf); 9383 WMITLV_SET_HDR(&cmd->tlv_header, 9384 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9385 WMITLV_GET_STRUCT_TLVLEN 9386 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9387 9388 /* Pass the pattern id to delete for the corresponding vdev id */ 9389 cmd->vdev_id = vdev_id; 9390 cmd->pattern_id = pattern_id; 9391 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 9392 __func__, cmd->pattern_id, cmd->vdev_id); 9393 9394 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9395 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9396 WMI_LOGE("%s: failed to send del pattern command", __func__); 9397 wmi_buf_free(wmi_buf); 9398 return QDF_STATUS_E_FAILURE; 9399 } 9400 return QDF_STATUS_SUCCESS; 9401 } 9402 9403 /** 9404 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 9405 * @wmi_handle: wmi handle 9406 * @preq: stats ext params 9407 * 9408 * Return: CDF status 9409 */ 9410 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 9411 struct stats_ext_params *preq) 9412 { 9413 QDF_STATUS ret; 9414 wmi_req_stats_ext_cmd_fixed_param *cmd; 9415 wmi_buf_t buf; 9416 size_t len; 9417 uint8_t *buf_ptr; 9418 9419 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 9420 9421 buf = wmi_buf_alloc(wmi_handle, len); 9422 if (!buf) { 9423 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9424 return QDF_STATUS_E_NOMEM; 9425 } 9426 9427 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9428 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 9429 9430 WMITLV_SET_HDR(&cmd->tlv_header, 9431 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 9432 WMITLV_GET_STRUCT_TLVLEN 9433 (wmi_req_stats_ext_cmd_fixed_param)); 9434 cmd->vdev_id = preq->vdev_id; 9435 cmd->data_len = preq->request_data_len; 9436 9437 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 9438 __func__, preq->request_data_len, preq->vdev_id); 9439 9440 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 9441 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 9442 9443 buf_ptr += WMI_TLV_HDR_SIZE; 9444 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 9445 9446 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9447 WMI_REQUEST_STATS_EXT_CMDID); 9448 if (QDF_IS_STATUS_ERROR(ret)) { 9449 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 9450 ret); 9451 wmi_buf_free(buf); 9452 } 9453 9454 return ret; 9455 } 9456 9457 /** 9458 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 9459 * @wmi_handle: wmi handle 9460 * @params: ext wow params 9461 * 9462 * Return:0 for success or error code 9463 */ 9464 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 9465 struct ext_wow_params *params) 9466 { 9467 wmi_extwow_enable_cmd_fixed_param *cmd; 9468 wmi_buf_t buf; 9469 int32_t len; 9470 int ret; 9471 9472 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 9473 buf = wmi_buf_alloc(wmi_handle, len); 9474 if (!buf) { 9475 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9476 return QDF_STATUS_E_NOMEM; 9477 } 9478 9479 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 9480 9481 WMITLV_SET_HDR(&cmd->tlv_header, 9482 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 9483 WMITLV_GET_STRUCT_TLVLEN 9484 (wmi_extwow_enable_cmd_fixed_param)); 9485 9486 cmd->vdev_id = params->vdev_id; 9487 cmd->type = params->type; 9488 cmd->wakeup_pin_num = params->wakeup_pin_num; 9489 9490 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 9491 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 9492 9493 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9494 WMI_EXTWOW_ENABLE_CMDID); 9495 if (ret) { 9496 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 9497 wmi_buf_free(buf); 9498 return QDF_STATUS_E_FAILURE; 9499 } 9500 9501 return QDF_STATUS_SUCCESS; 9502 9503 } 9504 9505 /** 9506 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 9507 * @wmi_handle: wmi handle 9508 * @app_type1_params: app type1 params 9509 * 9510 * Return: CDF status 9511 */ 9512 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9513 struct app_type1_params *app_type1_params) 9514 { 9515 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 9516 wmi_buf_t buf; 9517 int32_t len; 9518 int ret; 9519 9520 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 9521 buf = wmi_buf_alloc(wmi_handle, len); 9522 if (!buf) { 9523 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9524 return QDF_STATUS_E_NOMEM; 9525 } 9526 9527 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 9528 wmi_buf_data(buf); 9529 9530 WMITLV_SET_HDR(&cmd->tlv_header, 9531 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 9532 WMITLV_GET_STRUCT_TLVLEN 9533 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 9534 9535 cmd->vdev_id = app_type1_params->vdev_id; 9536 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 9537 &cmd->wakee_mac); 9538 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 9539 cmd->ident_len = app_type1_params->id_length; 9540 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 9541 cmd->passwd_len = app_type1_params->pass_length; 9542 9543 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 9544 "identification_id %.8s id_length %u " 9545 "password %.16s pass_length %u", 9546 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 9547 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 9548 9549 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9550 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 9551 if (ret) { 9552 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 9553 wmi_buf_free(buf); 9554 return QDF_STATUS_E_FAILURE; 9555 } 9556 9557 return QDF_STATUS_SUCCESS; 9558 } 9559 9560 /** 9561 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 9562 * @wmi_handle: wmi handle 9563 * @appType2Params: app type2 params 9564 * 9565 * Return: CDF status 9566 */ 9567 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9568 struct app_type2_params *appType2Params) 9569 { 9570 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 9571 wmi_buf_t buf; 9572 int32_t len; 9573 int ret; 9574 9575 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 9576 buf = wmi_buf_alloc(wmi_handle, len); 9577 if (!buf) { 9578 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9579 return QDF_STATUS_E_NOMEM; 9580 } 9581 9582 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 9583 wmi_buf_data(buf); 9584 9585 WMITLV_SET_HDR(&cmd->tlv_header, 9586 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 9587 WMITLV_GET_STRUCT_TLVLEN 9588 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 9589 9590 cmd->vdev_id = appType2Params->vdev_id; 9591 9592 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 9593 cmd->rc4_key_len = appType2Params->rc4_key_len; 9594 9595 cmd->ip_id = appType2Params->ip_id; 9596 cmd->ip_device_ip = appType2Params->ip_device_ip; 9597 cmd->ip_server_ip = appType2Params->ip_server_ip; 9598 9599 cmd->tcp_src_port = appType2Params->tcp_src_port; 9600 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 9601 cmd->tcp_seq = appType2Params->tcp_seq; 9602 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 9603 9604 cmd->keepalive_init = appType2Params->keepalive_init; 9605 cmd->keepalive_min = appType2Params->keepalive_min; 9606 cmd->keepalive_max = appType2Params->keepalive_max; 9607 cmd->keepalive_inc = appType2Params->keepalive_inc; 9608 9609 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 9610 &cmd->gateway_mac); 9611 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 9612 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 9613 9614 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 9615 "rc4_key %.16s rc4_key_len %u " 9616 "ip_id %x ip_device_ip %x ip_server_ip %x " 9617 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 9618 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 9619 "keepalive_max %u keepalive_inc %u " 9620 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 9621 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 9622 cmd->rc4_key, cmd->rc4_key_len, 9623 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 9624 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 9625 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 9626 cmd->keepalive_max, cmd->keepalive_inc, 9627 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 9628 9629 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9630 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 9631 if (ret) { 9632 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 9633 wmi_buf_free(buf); 9634 return QDF_STATUS_E_FAILURE; 9635 } 9636 9637 return QDF_STATUS_SUCCESS; 9638 9639 } 9640 9641 /** 9642 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 9643 * @wmi_handle: wmi handle 9644 * @timer_val: auto shutdown timer value 9645 * 9646 * Return: CDF status 9647 */ 9648 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 9649 uint32_t timer_val) 9650 { 9651 QDF_STATUS status; 9652 wmi_buf_t buf = NULL; 9653 uint8_t *buf_ptr; 9654 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 9655 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 9656 9657 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 9658 __func__, timer_val); 9659 9660 buf = wmi_buf_alloc(wmi_handle, len); 9661 if (!buf) { 9662 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9663 return QDF_STATUS_E_NOMEM; 9664 } 9665 9666 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9667 wmi_auto_sh_cmd = 9668 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 9669 wmi_auto_sh_cmd->timer_value = timer_val; 9670 9671 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 9672 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 9673 WMITLV_GET_STRUCT_TLVLEN 9674 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 9675 9676 status = wmi_unified_cmd_send(wmi_handle, buf, 9677 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 9678 if (QDF_IS_STATUS_ERROR(status)) { 9679 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 9680 __func__, status); 9681 wmi_buf_free(buf); 9682 } 9683 9684 return status; 9685 } 9686 9687 /** 9688 * send_nan_req_cmd_tlv() - to send nan request to target 9689 * @wmi_handle: wmi handle 9690 * @nan_req: request data which will be non-null 9691 * 9692 * Return: CDF status 9693 */ 9694 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 9695 struct nan_req_params *nan_req) 9696 { 9697 QDF_STATUS ret; 9698 wmi_nan_cmd_param *cmd; 9699 wmi_buf_t buf; 9700 uint16_t len = sizeof(*cmd); 9701 uint16_t nan_data_len, nan_data_len_aligned; 9702 uint8_t *buf_ptr; 9703 9704 /* 9705 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 9706 * +------------+----------+-----------------------+--------------+ 9707 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 9708 * +------------+----------+-----------------------+--------------+ 9709 */ 9710 if (!nan_req) { 9711 WMI_LOGE("%s:nan req is not valid", __func__); 9712 return QDF_STATUS_E_FAILURE; 9713 } 9714 nan_data_len = nan_req->request_data_len; 9715 nan_data_len_aligned = roundup(nan_req->request_data_len, 9716 sizeof(uint32_t)); 9717 if (nan_data_len_aligned < nan_req->request_data_len) { 9718 WMI_LOGE("%s: integer overflow while rounding up data_len", 9719 __func__); 9720 return QDF_STATUS_E_FAILURE; 9721 } 9722 9723 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 9724 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 9725 __func__); 9726 return QDF_STATUS_E_FAILURE; 9727 } 9728 9729 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 9730 buf = wmi_buf_alloc(wmi_handle, len); 9731 if (!buf) { 9732 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9733 return QDF_STATUS_E_NOMEM; 9734 } 9735 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9736 cmd = (wmi_nan_cmd_param *) buf_ptr; 9737 WMITLV_SET_HDR(&cmd->tlv_header, 9738 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 9739 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 9740 cmd->data_len = nan_req->request_data_len; 9741 WMI_LOGD("%s: The data len value is %u", 9742 __func__, nan_req->request_data_len); 9743 buf_ptr += sizeof(wmi_nan_cmd_param); 9744 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 9745 buf_ptr += WMI_TLV_HDR_SIZE; 9746 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 9747 9748 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9749 WMI_NAN_CMDID); 9750 if (QDF_IS_STATUS_ERROR(ret)) { 9751 WMI_LOGE("%s Failed to send set param command ret = %d", 9752 __func__, ret); 9753 wmi_buf_free(buf); 9754 } 9755 9756 return ret; 9757 } 9758 9759 /** 9760 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 9761 * @wmi_handle: wmi handle 9762 * @params: DHCP server offload info 9763 * 9764 * Return: QDF_STATUS_SUCCESS for success or error code 9765 */ 9766 static QDF_STATUS 9767 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 9768 struct dhcp_offload_info_params *params) 9769 { 9770 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 9771 wmi_buf_t buf; 9772 QDF_STATUS status; 9773 9774 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9775 if (!buf) { 9776 WMI_LOGE("Failed to allocate buffer to send " 9777 "set_dhcp_server_offload cmd"); 9778 return QDF_STATUS_E_NOMEM; 9779 } 9780 9781 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 9782 9783 WMITLV_SET_HDR(&cmd->tlv_header, 9784 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 9785 WMITLV_GET_STRUCT_TLVLEN 9786 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 9787 cmd->vdev_id = params->vdev_id; 9788 cmd->enable = params->dhcp_offload_enabled; 9789 cmd->num_client = params->dhcp_client_num; 9790 cmd->srv_ipv4 = params->dhcp_srv_addr; 9791 cmd->start_lsb = 0; 9792 status = wmi_unified_cmd_send(wmi_handle, buf, 9793 sizeof(*cmd), 9794 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 9795 if (QDF_IS_STATUS_ERROR(status)) { 9796 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 9797 wmi_buf_free(buf); 9798 return QDF_STATUS_E_FAILURE; 9799 } 9800 WMI_LOGD("Set dhcp server offload to vdevId %d", 9801 params->vdev_id); 9802 9803 return status; 9804 } 9805 9806 /** 9807 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 9808 * @wmi_handle: wmi handle 9809 * @flashing: flashing request 9810 * 9811 * Return: CDF status 9812 */ 9813 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 9814 struct flashing_req_params *flashing) 9815 { 9816 wmi_set_led_flashing_cmd_fixed_param *cmd; 9817 QDF_STATUS status; 9818 wmi_buf_t buf; 9819 uint8_t *buf_ptr; 9820 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 9821 9822 buf = wmi_buf_alloc(wmi_handle, len); 9823 if (!buf) { 9824 WMI_LOGP(FL("wmi_buf_alloc failed")); 9825 return QDF_STATUS_E_NOMEM; 9826 } 9827 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9828 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 9829 WMITLV_SET_HDR(&cmd->tlv_header, 9830 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 9831 WMITLV_GET_STRUCT_TLVLEN 9832 (wmi_set_led_flashing_cmd_fixed_param)); 9833 cmd->pattern_id = flashing->pattern_id; 9834 cmd->led_x0 = flashing->led_x0; 9835 cmd->led_x1 = flashing->led_x1; 9836 9837 status = wmi_unified_cmd_send(wmi_handle, buf, len, 9838 WMI_PDEV_SET_LED_FLASHING_CMDID); 9839 if (QDF_IS_STATUS_ERROR(status)) { 9840 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 9841 " returned Error %d", __func__, status); 9842 wmi_buf_free(buf); 9843 } 9844 9845 return status; 9846 } 9847 9848 /** 9849 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 9850 * @wmi_handle: wmi handle 9851 * @ch_avoid_update_req: channel avoid update params 9852 * 9853 * Return: CDF status 9854 */ 9855 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 9856 { 9857 QDF_STATUS status; 9858 wmi_buf_t buf = NULL; 9859 uint8_t *buf_ptr; 9860 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 9861 int len = sizeof(wmi_chan_avoid_update_cmd_param); 9862 9863 9864 buf = wmi_buf_alloc(wmi_handle, len); 9865 if (!buf) { 9866 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9867 return QDF_STATUS_E_NOMEM; 9868 } 9869 9870 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9871 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 9872 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 9873 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 9874 WMITLV_GET_STRUCT_TLVLEN 9875 (wmi_chan_avoid_update_cmd_param)); 9876 9877 status = wmi_unified_cmd_send(wmi_handle, buf, 9878 len, WMI_CHAN_AVOID_UPDATE_CMDID); 9879 if (QDF_IS_STATUS_ERROR(status)) { 9880 WMI_LOGE("wmi_unified_cmd_send" 9881 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 9882 " returned Error %d", status); 9883 wmi_buf_free(buf); 9884 } 9885 9886 return status; 9887 } 9888 9889 /** 9890 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 9891 * @wmi_handle: wmi handle 9892 * @param: pointer to pdev regdomain params 9893 * 9894 * Return: 0 for success or error code 9895 */ 9896 static QDF_STATUS 9897 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 9898 struct pdev_set_regdomain_params *param) 9899 { 9900 wmi_buf_t buf; 9901 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9902 int32_t len = sizeof(*cmd); 9903 9904 9905 buf = wmi_buf_alloc(wmi_handle, len); 9906 if (!buf) { 9907 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9908 return QDF_STATUS_E_NOMEM; 9909 } 9910 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9911 WMITLV_SET_HDR(&cmd->tlv_header, 9912 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 9913 WMITLV_GET_STRUCT_TLVLEN 9914 (wmi_pdev_set_regdomain_cmd_fixed_param)); 9915 9916 cmd->reg_domain = param->currentRDinuse; 9917 cmd->reg_domain_2G = param->currentRD2G; 9918 cmd->reg_domain_5G = param->currentRD5G; 9919 cmd->conformance_test_limit_2G = param->ctl_2G; 9920 cmd->conformance_test_limit_5G = param->ctl_5G; 9921 cmd->dfs_domain = param->dfsDomain; 9922 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9923 param->pdev_id); 9924 9925 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9926 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 9927 WMI_LOGE("%s: Failed to send pdev set regdomain command", 9928 __func__); 9929 wmi_buf_free(buf); 9930 return QDF_STATUS_E_FAILURE; 9931 } 9932 9933 return QDF_STATUS_SUCCESS; 9934 } 9935 9936 /** 9937 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 9938 * @wmi_handle: wmi handle 9939 * @reg_dmn: reg domain 9940 * @regdmn2G: 2G reg domain 9941 * @regdmn5G: 5G reg domain 9942 * @ctl2G: 2G test limit 9943 * @ctl5G: 5G test limit 9944 * 9945 * Return: none 9946 */ 9947 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 9948 uint32_t reg_dmn, uint16_t regdmn2G, 9949 uint16_t regdmn5G, uint8_t ctl2G, 9950 uint8_t ctl5G) 9951 { 9952 wmi_buf_t buf; 9953 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9954 int32_t len = sizeof(*cmd); 9955 9956 9957 buf = wmi_buf_alloc(wmi_handle, len); 9958 if (!buf) { 9959 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9960 return QDF_STATUS_E_NOMEM; 9961 } 9962 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9963 WMITLV_SET_HDR(&cmd->tlv_header, 9964 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 9965 WMITLV_GET_STRUCT_TLVLEN 9966 (wmi_pdev_set_regdomain_cmd_fixed_param)); 9967 cmd->reg_domain = reg_dmn; 9968 cmd->reg_domain_2G = regdmn2G; 9969 cmd->reg_domain_5G = regdmn5G; 9970 cmd->conformance_test_limit_2G = ctl2G; 9971 cmd->conformance_test_limit_5G = ctl5G; 9972 9973 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9974 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 9975 WMI_LOGP("%s: Failed to send pdev set regdomain command", 9976 __func__); 9977 wmi_buf_free(buf); 9978 return QDF_STATUS_E_FAILURE; 9979 } 9980 9981 return QDF_STATUS_SUCCESS; 9982 } 9983 9984 9985 /** 9986 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 9987 * @wmi_handle: wmi handle 9988 * @chan_switch_params: Pointer to tdls channel switch parameter structure 9989 * 9990 * This function sets tdls off channel mode 9991 * 9992 * Return: 0 on success; Negative errno otherwise 9993 */ 9994 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 9995 struct tdls_channel_switch_params *chan_switch_params) 9996 { 9997 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 9998 wmi_buf_t wmi_buf; 9999 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10000 10001 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10002 if (!wmi_buf) { 10003 WMI_LOGE(FL("wmi_buf_alloc failed")); 10004 return QDF_STATUS_E_FAILURE; 10005 } 10006 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10007 wmi_buf_data(wmi_buf); 10008 WMITLV_SET_HDR(&cmd->tlv_header, 10009 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10010 WMITLV_GET_STRUCT_TLVLEN( 10011 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10012 10013 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10014 &cmd->peer_macaddr); 10015 cmd->vdev_id = chan_switch_params->vdev_id; 10016 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 10017 cmd->is_peer_responder = chan_switch_params->is_responder; 10018 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10019 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10020 cmd->offchan_oper_class = chan_switch_params->oper_class; 10021 10022 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10023 cmd->peer_macaddr.mac_addr31to0, 10024 cmd->peer_macaddr.mac_addr47to32); 10025 10026 WMI_LOGD(FL( 10027 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10028 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10029 ), 10030 cmd->vdev_id, 10031 cmd->offchan_mode, 10032 cmd->offchan_num, 10033 cmd->offchan_bw_bitmap, 10034 cmd->is_peer_responder, 10035 cmd->offchan_oper_class); 10036 10037 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10038 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10039 WMI_LOGP(FL("failed to send tdls off chan command")); 10040 wmi_buf_free(wmi_buf); 10041 return QDF_STATUS_E_FAILURE; 10042 } 10043 10044 10045 return QDF_STATUS_SUCCESS; 10046 } 10047 10048 /** 10049 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10050 * @wmi_handle: wmi handle 10051 * @pwmaTdlsparams: TDLS params 10052 * 10053 * Return: 0 for success or error code 10054 */ 10055 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10056 void *tdls_param, uint8_t tdls_state) 10057 { 10058 wmi_tdls_set_state_cmd_fixed_param *cmd; 10059 wmi_buf_t wmi_buf; 10060 10061 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10062 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10063 10064 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10065 if (!wmi_buf) { 10066 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10067 return QDF_STATUS_E_FAILURE; 10068 } 10069 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10070 WMITLV_SET_HDR(&cmd->tlv_header, 10071 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10072 WMITLV_GET_STRUCT_TLVLEN 10073 (wmi_tdls_set_state_cmd_fixed_param)); 10074 cmd->vdev_id = wmi_tdls->vdev_id; 10075 cmd->state = tdls_state; 10076 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10077 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10078 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10079 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10080 cmd->rssi_delta = wmi_tdls->rssi_delta; 10081 cmd->tdls_options = wmi_tdls->tdls_options; 10082 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10083 cmd->tdls_peer_traffic_response_timeout_ms = 10084 wmi_tdls->peer_traffic_response_timeout; 10085 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10086 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10087 cmd->tdls_puapsd_rx_frame_threshold = 10088 wmi_tdls->puapsd_rx_frame_threshold; 10089 cmd->teardown_notification_ms = 10090 wmi_tdls->teardown_notification_ms; 10091 cmd->tdls_peer_kickout_threshold = 10092 wmi_tdls->tdls_peer_kickout_threshold; 10093 10094 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10095 "notification_interval_ms: %d, " 10096 "tx_discovery_threshold: %d, " 10097 "tx_teardown_threshold: %d, " 10098 "rssi_teardown_threshold: %d, " 10099 "rssi_delta: %d, " 10100 "tdls_options: 0x%x, " 10101 "tdls_peer_traffic_ind_window: %d, " 10102 "tdls_peer_traffic_response_timeout: %d, " 10103 "tdls_puapsd_mask: 0x%x, " 10104 "tdls_puapsd_inactivity_time: %d, " 10105 "tdls_puapsd_rx_frame_threshold: %d, " 10106 "teardown_notification_ms: %d, " 10107 "tdls_peer_kickout_threshold: %d", 10108 __func__, tdls_state, cmd->state, 10109 cmd->notification_interval_ms, 10110 cmd->tx_discovery_threshold, 10111 cmd->tx_teardown_threshold, 10112 cmd->rssi_teardown_threshold, 10113 cmd->rssi_delta, 10114 cmd->tdls_options, 10115 cmd->tdls_peer_traffic_ind_window, 10116 cmd->tdls_peer_traffic_response_timeout_ms, 10117 cmd->tdls_puapsd_mask, 10118 cmd->tdls_puapsd_inactivity_time_ms, 10119 cmd->tdls_puapsd_rx_frame_threshold, 10120 cmd->teardown_notification_ms, 10121 cmd->tdls_peer_kickout_threshold); 10122 10123 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10124 WMI_TDLS_SET_STATE_CMDID)) { 10125 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10126 wmi_buf_free(wmi_buf); 10127 return QDF_STATUS_E_FAILURE; 10128 } 10129 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10130 10131 return QDF_STATUS_SUCCESS; 10132 } 10133 10134 /** 10135 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10136 * @wmi_handle: wmi handle 10137 * @peerStateParams: TDLS peer state params 10138 * 10139 * Return: QDF_STATUS_SUCCESS for success or error code 10140 */ 10141 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10142 struct tdls_peer_state_params *peerStateParams, 10143 uint32_t *ch_mhz) 10144 { 10145 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10146 wmi_tdls_peer_capabilities *peer_cap; 10147 wmi_channel *chan_info; 10148 wmi_buf_t wmi_buf; 10149 uint8_t *buf_ptr; 10150 uint32_t i; 10151 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10152 sizeof(wmi_tdls_peer_capabilities); 10153 10154 10155 len += WMI_TLV_HDR_SIZE + 10156 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10157 10158 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10159 if (!wmi_buf) { 10160 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10161 return QDF_STATUS_E_FAILURE; 10162 } 10163 10164 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10165 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10166 WMITLV_SET_HDR(&cmd->tlv_header, 10167 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10168 WMITLV_GET_STRUCT_TLVLEN 10169 (wmi_tdls_peer_update_cmd_fixed_param)); 10170 10171 cmd->vdev_id = peerStateParams->vdevId; 10172 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10173 &cmd->peer_macaddr); 10174 10175 10176 cmd->peer_state = peerStateParams->peerState; 10177 10178 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10179 "peer_macaddr.mac_addr31to0: 0x%x, " 10180 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10181 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10182 cmd->peer_macaddr.mac_addr31to0, 10183 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10184 10185 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10186 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10187 WMITLV_SET_HDR(&peer_cap->tlv_header, 10188 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10189 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10190 10191 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10192 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10193 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10194 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10195 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10196 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10197 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10198 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10199 10200 /* Ack and More Data Ack are sent as 0, so no need to set 10201 * but fill SP 10202 */ 10203 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10204 peerStateParams->peerCap.peerMaxSp); 10205 10206 peer_cap->buff_sta_support = 10207 peerStateParams->peerCap.peerBuffStaSupport; 10208 peer_cap->off_chan_support = 10209 peerStateParams->peerCap.peerOffChanSupport; 10210 peer_cap->peer_curr_operclass = 10211 peerStateParams->peerCap.peerCurrOperClass; 10212 /* self curr operclass is not being used and so pass op class for 10213 * preferred off chan in it. 10214 */ 10215 peer_cap->self_curr_operclass = 10216 peerStateParams->peerCap.opClassForPrefOffChan; 10217 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10218 peer_cap->peer_operclass_len = 10219 peerStateParams->peerCap.peerOperClassLen; 10220 10221 WMI_LOGD("%s: peer_operclass_len: %d", 10222 __func__, peer_cap->peer_operclass_len); 10223 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10224 peer_cap->peer_operclass[i] = 10225 peerStateParams->peerCap.peerOperClass[i]; 10226 WMI_LOGD("%s: peer_operclass[%d]: %d", 10227 __func__, i, peer_cap->peer_operclass[i]); 10228 } 10229 10230 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10231 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10232 peer_cap->pref_offchan_bw = 10233 peerStateParams->peerCap.prefOffChanBandwidth; 10234 10235 WMI_LOGD 10236 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10237 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10238 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10239 " %d, pref_offchan_bw: %d", 10240 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10241 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10242 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10243 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10244 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10245 10246 /* next fill variable size array of peer chan info */ 10247 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10248 WMITLV_SET_HDR(buf_ptr, 10249 WMITLV_TAG_ARRAY_STRUC, 10250 sizeof(wmi_channel) * 10251 peerStateParams->peerCap.peerChanLen); 10252 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10253 10254 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10255 WMITLV_SET_HDR(&chan_info->tlv_header, 10256 WMITLV_TAG_STRUC_wmi_channel, 10257 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10258 chan_info->mhz = ch_mhz[i]; 10259 chan_info->band_center_freq1 = chan_info->mhz; 10260 chan_info->band_center_freq2 = 0; 10261 10262 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10263 10264 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10265 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10266 WMI_LOGI("chan[%d] DFS[%d]\n", 10267 peerStateParams->peerCap.peerChan[i].chanId, 10268 peerStateParams->peerCap.peerChan[i].dfsSet); 10269 } 10270 10271 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10272 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10273 else 10274 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10275 10276 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10277 peerStateParams->peerCap. 10278 peerChan[i].pwr); 10279 10280 WMI_SET_CHANNEL_REG_POWER(chan_info, 10281 peerStateParams->peerCap.peerChan[i]. 10282 pwr); 10283 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10284 peerStateParams->peerCap.peerChan[i].pwr); 10285 10286 chan_info++; 10287 } 10288 10289 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10290 WMI_TDLS_PEER_UPDATE_CMDID)) { 10291 WMI_LOGE("%s: failed to send tdls peer update state command", 10292 __func__); 10293 wmi_buf_free(wmi_buf); 10294 return QDF_STATUS_E_FAILURE; 10295 } 10296 10297 10298 return QDF_STATUS_SUCCESS; 10299 } 10300 10301 /* 10302 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 10303 * @wmi_handle: Pointer to WMi handle 10304 * @ie_data: Pointer for ie data 10305 * 10306 * This function sends IE information to firmware 10307 * 10308 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10309 * 10310 */ 10311 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 10312 struct vdev_ie_info_param *ie_info) 10313 { 10314 wmi_vdev_set_ie_cmd_fixed_param *cmd; 10315 wmi_buf_t buf; 10316 uint8_t *buf_ptr; 10317 uint32_t len, ie_len_aligned; 10318 QDF_STATUS ret; 10319 10320 10321 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 10322 /* Allocate memory for the WMI command */ 10323 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 10324 10325 buf = wmi_buf_alloc(wmi_handle, len); 10326 if (!buf) { 10327 WMI_LOGE(FL("wmi_buf_alloc failed")); 10328 return QDF_STATUS_E_NOMEM; 10329 } 10330 10331 buf_ptr = wmi_buf_data(buf); 10332 qdf_mem_zero(buf_ptr, len); 10333 10334 /* Populate the WMI command */ 10335 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 10336 10337 WMITLV_SET_HDR(&cmd->tlv_header, 10338 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 10339 WMITLV_GET_STRUCT_TLVLEN( 10340 wmi_vdev_set_ie_cmd_fixed_param)); 10341 cmd->vdev_id = ie_info->vdev_id; 10342 cmd->ie_id = ie_info->ie_id; 10343 cmd->ie_len = ie_info->length; 10344 cmd->band = ie_info->band; 10345 10346 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 10347 ie_info->length, ie_info->vdev_id); 10348 10349 buf_ptr += sizeof(*cmd); 10350 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 10351 buf_ptr += WMI_TLV_HDR_SIZE; 10352 10353 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 10354 10355 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10356 WMI_VDEV_SET_IE_CMDID); 10357 if (QDF_IS_STATUS_ERROR(ret)) { 10358 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 10359 wmi_buf_free(buf); 10360 } 10361 10362 return ret; 10363 } 10364 10365 /** 10366 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 10367 * 10368 * @param wmi_handle : handle to WMI. 10369 * @param param : pointer to antenna param 10370 * 10371 * This function sends smart antenna enable command to FW 10372 * 10373 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10374 */ 10375 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 10376 struct smart_ant_enable_params *param) 10377 { 10378 /* Send WMI COMMAND to Enable */ 10379 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 10380 wmi_pdev_smart_ant_gpio_handle *gpio_param; 10381 wmi_buf_t buf; 10382 uint8_t *buf_ptr; 10383 int len = 0; 10384 QDF_STATUS ret; 10385 int loop = 0; 10386 10387 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10388 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 10389 buf = wmi_buf_alloc(wmi_handle, len); 10390 10391 if (!buf) { 10392 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10393 return QDF_STATUS_E_NOMEM; 10394 } 10395 10396 buf_ptr = wmi_buf_data(buf); 10397 qdf_mem_zero(buf_ptr, len); 10398 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 10399 10400 WMITLV_SET_HDR(&cmd->tlv_header, 10401 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 10402 WMITLV_GET_STRUCT_TLVLEN( 10403 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 10404 10405 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10406 param->pdev_id); 10407 cmd->enable = param->enable; 10408 cmd->mode = param->mode; 10409 cmd->rx_antenna = param->rx_antenna; 10410 cmd->tx_default_antenna = param->rx_antenna; 10411 10412 /* TLV indicating array of structures to follow */ 10413 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 10414 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10415 WMI_HAL_MAX_SANTENNA * 10416 sizeof(wmi_pdev_smart_ant_gpio_handle)); 10417 10418 buf_ptr += WMI_TLV_HDR_SIZE; 10419 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 10420 10421 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 10422 WMITLV_SET_HDR(&gpio_param->tlv_header, 10423 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 10424 WMITLV_GET_STRUCT_TLVLEN( 10425 wmi_pdev_smart_ant_gpio_handle)); 10426 if (param->mode == SMART_ANT_MODE_SERIAL) { 10427 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 10428 gpio_param->gpio_pin = param->gpio_pin[loop]; 10429 gpio_param->gpio_func = param->gpio_func[loop]; 10430 } else { 10431 gpio_param->gpio_pin = 0; 10432 gpio_param->gpio_func = 0; 10433 } 10434 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 10435 gpio_param->gpio_pin = param->gpio_pin[loop]; 10436 gpio_param->gpio_func = param->gpio_func[loop]; 10437 } 10438 /* Setting it to 0 for now */ 10439 gpio_param->pdev_id = 10440 wmi_handle->ops->convert_pdev_id_host_to_target( 10441 param->pdev_id); 10442 gpio_param++; 10443 } 10444 10445 ret = wmi_unified_cmd_send(wmi_handle, 10446 buf, 10447 len, 10448 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 10449 10450 if (ret != 0) { 10451 WMI_LOGE(" %s :WMI Failed\n", __func__); 10452 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 10453 cmd->enable, 10454 cmd->mode, 10455 cmd->rx_antenna, 10456 param->gpio_pin[0], param->gpio_pin[1], 10457 param->gpio_pin[2], param->gpio_pin[3], 10458 param->gpio_func[0], param->gpio_func[1], 10459 param->gpio_func[2], param->gpio_func[3], 10460 ret); 10461 wmi_buf_free(buf); 10462 } 10463 10464 return ret; 10465 } 10466 10467 /** 10468 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 10469 * 10470 * @param wmi_handle : handle to WMI. 10471 * @param param : pointer to rx antenna param 10472 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10473 */ 10474 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 10475 struct smart_ant_rx_ant_params *param) 10476 { 10477 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 10478 wmi_buf_t buf; 10479 uint8_t *buf_ptr; 10480 uint32_t len; 10481 QDF_STATUS ret; 10482 10483 len = sizeof(*cmd); 10484 buf = wmi_buf_alloc(wmi_handle, len); 10485 WMI_LOGD("%s:\n", __func__); 10486 if (!buf) { 10487 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10488 return QDF_STATUS_E_NOMEM; 10489 } 10490 10491 buf_ptr = wmi_buf_data(buf); 10492 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 10493 WMITLV_SET_HDR(&cmd->tlv_header, 10494 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 10495 WMITLV_GET_STRUCT_TLVLEN( 10496 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 10497 cmd->rx_antenna = param->antenna; 10498 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10499 param->pdev_id); 10500 10501 ret = wmi_unified_cmd_send(wmi_handle, 10502 buf, 10503 len, 10504 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 10505 10506 if (ret != 0) { 10507 WMI_LOGE(" %s :WMI Failed\n", __func__); 10508 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 10509 __func__, 10510 cmd->rx_antenna, 10511 ret); 10512 wmi_buf_free(buf); 10513 } 10514 10515 return ret; 10516 } 10517 10518 /** 10519 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 10520 * @wmi_handle: wmi handle 10521 * @param: pointer to hold ctl table param 10522 * 10523 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10524 */ 10525 static QDF_STATUS 10526 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 10527 struct ctl_table_params *param) 10528 { 10529 uint16_t len, ctl_tlv_len; 10530 uint8_t *buf_ptr; 10531 wmi_buf_t buf; 10532 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 10533 uint32_t *ctl_array; 10534 10535 if (!param->ctl_array) 10536 return QDF_STATUS_E_FAILURE; 10537 10538 ctl_tlv_len = WMI_TLV_HDR_SIZE + 10539 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 10540 len = sizeof(*cmd) + ctl_tlv_len; 10541 10542 buf = wmi_buf_alloc(wmi_handle, len); 10543 if (!buf) { 10544 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10545 return QDF_STATUS_E_FAILURE; 10546 } 10547 10548 buf_ptr = wmi_buf_data(buf); 10549 qdf_mem_zero(buf_ptr, len); 10550 10551 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 10552 10553 WMITLV_SET_HDR(&cmd->tlv_header, 10554 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 10555 WMITLV_GET_STRUCT_TLVLEN( 10556 wmi_pdev_set_ctl_table_cmd_fixed_param)); 10557 cmd->ctl_len = param->ctl_cmd_len; 10558 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10559 param->pdev_id); 10560 10561 buf_ptr += sizeof(*cmd); 10562 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10563 (cmd->ctl_len)); 10564 buf_ptr += WMI_TLV_HDR_SIZE; 10565 ctl_array = (uint32_t *)buf_ptr; 10566 10567 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 10568 sizeof(param->ctl_band)); 10569 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 10570 param->ctl_cmd_len - 10571 sizeof(param->ctl_band)); 10572 10573 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10574 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 10575 WMI_LOGE("%s:Failed to send command\n", __func__); 10576 wmi_buf_free(buf); 10577 return QDF_STATUS_E_FAILURE; 10578 } 10579 10580 return QDF_STATUS_SUCCESS; 10581 } 10582 10583 /** 10584 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 10585 * @wmi_handle: wmi handle 10586 * @param: pointer to hold mimogain table param 10587 * 10588 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10589 */ 10590 static QDF_STATUS 10591 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 10592 struct mimogain_table_params *param) 10593 { 10594 uint16_t len, table_tlv_len; 10595 wmi_buf_t buf; 10596 uint8_t *buf_ptr; 10597 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 10598 uint32_t *gain_table; 10599 10600 if (!param->array_gain) 10601 return QDF_STATUS_E_FAILURE; 10602 10603 /* len must be multiple of a single array gain table */ 10604 if (param->tbl_len % 10605 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 10606 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 10607 WMI_LOGE("Array gain table len not correct\n"); 10608 return QDF_STATUS_E_FAILURE; 10609 } 10610 10611 table_tlv_len = WMI_TLV_HDR_SIZE + 10612 roundup(param->tbl_len, sizeof(uint32_t)); 10613 len = sizeof(*cmd) + table_tlv_len; 10614 10615 buf = wmi_buf_alloc(wmi_handle, len); 10616 if (!buf) { 10617 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10618 return QDF_STATUS_E_FAILURE; 10619 } 10620 10621 buf_ptr = wmi_buf_data(buf); 10622 qdf_mem_zero(buf_ptr, len); 10623 10624 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 10625 10626 WMITLV_SET_HDR(&cmd->tlv_header, 10627 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 10628 WMITLV_GET_STRUCT_TLVLEN( 10629 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 10630 10631 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10632 param->pdev_id); 10633 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 10634 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 10635 param->multichain_gain_bypass); 10636 10637 buf_ptr += sizeof(*cmd); 10638 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10639 (param->tbl_len)); 10640 buf_ptr += WMI_TLV_HDR_SIZE; 10641 gain_table = (uint32_t *)buf_ptr; 10642 10643 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 10644 param->array_gain, 10645 param->tbl_len); 10646 10647 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10648 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 10649 return QDF_STATUS_E_FAILURE; 10650 } 10651 10652 return QDF_STATUS_SUCCESS; 10653 } 10654 10655 /** 10656 * enum packet_power_tlv_flags: target defined 10657 * packet power rate flags for TLV 10658 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 10659 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 10660 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 10661 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 10662 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 10663 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 10664 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 10665 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 10666 * @WMI_TLV_FLAG_STBC: STBC is set 10667 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 10668 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 10669 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 10670 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 10671 * @WMI_TLV_FLAG_RTSENA: RTS enabled 10672 * @WMI_TLV_FLAG_CTSENA: CTS enabled 10673 * @WMI_TLV_FLAG_LDPC: LDPC is set 10674 * @WMI_TLV_FLAG_SGI: Short gaurd interval 10675 * @WMI_TLV_FLAG_SU: SU Data 10676 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 10677 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 10678 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 10679 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 10680 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 10681 * 10682 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 10683 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 10684 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 10685 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 10686 */ 10687 enum packet_power_tlv_flags { 10688 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 10689 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 10690 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 10691 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 10692 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 10693 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 10694 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 10695 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 10696 WMI_TLV_FLAG_STBC = 0x00000100, 10697 WMI_TLV_FLAG_40MHZ = 0x00000200, 10698 WMI_TLV_FLAG_80MHZ = 0x00000300, 10699 WMI_TLV_FLAG_160MHZ = 0x00000400, 10700 WMI_TLV_FLAG_TXBF = 0x00000800, 10701 WMI_TLV_FLAG_RTSENA = 0x00001000, 10702 WMI_TLV_FLAG_CTSENA = 0x00002000, 10703 WMI_TLV_FLAG_LDPC = 0x00004000, 10704 WMI_TLV_FLAG_SGI = 0x00008000, 10705 WMI_TLV_FLAG_SU = 0x00100000, 10706 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 10707 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 10708 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 10709 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 10710 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 10711 10712 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 10713 WMI_TLV_FLAG_BW_MASK = 0x3, 10714 WMI_TLV_FLAG_BW_SHIFT = 9, 10715 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 10716 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 10717 }; 10718 10719 /** 10720 * convert_to_power_info_rate_flags() - convert packet_power_info_params 10721 * to FW understandable format 10722 * @param: pointer to hold packet power info param 10723 * 10724 * @return FW understandable 32 bit rate flags 10725 */ 10726 static uint32_t 10727 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 10728 { 10729 uint32_t rateflags = 0; 10730 10731 if (param->chainmask) 10732 rateflags |= 10733 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 10734 if (param->chan_width) 10735 rateflags |= 10736 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 10737 << WMI_TLV_FLAG_BW_SHIFT); 10738 if (param->su_mu_ofdma) 10739 rateflags |= 10740 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 10741 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 10742 if (param->rate_flags & WMI_HOST_FLAG_STBC) 10743 rateflags |= WMI_TLV_FLAG_STBC; 10744 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 10745 rateflags |= WMI_TLV_FLAG_LDPC; 10746 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 10747 rateflags |= WMI_TLV_FLAG_TXBF; 10748 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 10749 rateflags |= WMI_TLV_FLAG_RTSENA; 10750 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 10751 rateflags |= WMI_TLV_FLAG_CTSENA; 10752 if (param->rate_flags & WMI_HOST_FLAG_SGI) 10753 rateflags |= WMI_TLV_FLAG_SGI; 10754 10755 return rateflags; 10756 } 10757 10758 /** 10759 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 10760 * info to fw 10761 * @wmi_handle: wmi handle 10762 * @param: pointer to hold packet power info param 10763 * 10764 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10765 */ 10766 static QDF_STATUS 10767 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 10768 struct packet_power_info_params *param) 10769 { 10770 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 10771 wmi_buf_t wmibuf; 10772 uint8_t *buf_ptr; 10773 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 10774 10775 wmibuf = wmi_buf_alloc(wmi_handle, len); 10776 if (wmibuf == NULL) 10777 return QDF_STATUS_E_NOMEM; 10778 10779 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 10780 10781 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 10782 WMITLV_SET_HDR(&cmd->tlv_header, 10783 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 10784 WMITLV_GET_STRUCT_TLVLEN( 10785 wmi_pdev_get_tpc_cmd_fixed_param)); 10786 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10787 param->pdev_id); 10788 cmd->rate_flags = convert_to_power_info_rate_flags(param); 10789 cmd->nss = param->nss; 10790 cmd->preamble = param->preamble; 10791 cmd->hw_rate = param->hw_rate; 10792 10793 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 10794 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 10795 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 10796 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 10797 10798 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 10799 WMI_PDEV_GET_TPC_CMDID)) { 10800 WMI_LOGE(FL("Failed to get tpc command\n")); 10801 wmi_buf_free(wmibuf); 10802 return QDF_STATUS_E_FAILURE; 10803 } 10804 10805 return QDF_STATUS_SUCCESS; 10806 } 10807 10808 /** 10809 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 10810 * @wmi_handle: wmi handle 10811 * @param: pointer to hold config ratemask params 10812 * 10813 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10814 */ 10815 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 10816 struct config_ratemask_params *param) 10817 { 10818 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 10819 wmi_buf_t buf; 10820 int32_t len = sizeof(*cmd); 10821 10822 buf = wmi_buf_alloc(wmi_handle, len); 10823 if (!buf) { 10824 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10825 return QDF_STATUS_E_FAILURE; 10826 } 10827 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 10828 WMITLV_SET_HDR(&cmd->tlv_header, 10829 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 10830 WMITLV_GET_STRUCT_TLVLEN( 10831 wmi_vdev_config_ratemask_cmd_fixed_param)); 10832 cmd->vdev_id = param->vdev_id; 10833 cmd->type = param->type; 10834 cmd->mask_lower32 = param->lower32; 10835 cmd->mask_higher32 = param->higher32; 10836 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X, mask_l32 = 0x%X mask_h32 = 0x%X\n", 10837 param->vdev_id, param->type, param->lower32, param->higher32); 10838 10839 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10840 WMI_VDEV_RATEMASK_CMDID)) { 10841 WMI_LOGE("Seting vdev ratemask failed\n"); 10842 wmi_buf_free(buf); 10843 return QDF_STATUS_E_FAILURE; 10844 } 10845 10846 return QDF_STATUS_SUCCESS; 10847 } 10848 10849 /** 10850 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 10851 * @param: param sent from the host side 10852 * @cmd: param to be sent to the fw side 10853 */ 10854 static inline void copy_custom_aggr_bitmap( 10855 struct set_custom_aggr_size_params *param, 10856 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 10857 { 10858 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 10859 param->ac); 10860 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 10861 param->aggr_type); 10862 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10863 param->tx_aggr_size_disable); 10864 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10865 param->rx_aggr_size_disable); 10866 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 10867 param->tx_ac_enable); 10868 } 10869 10870 /** 10871 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 10872 * @wmi_handle: wmi handle 10873 * @param: pointer to hold custom aggr size params 10874 * 10875 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10876 */ 10877 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 10878 wmi_unified_t wmi_handle, 10879 struct set_custom_aggr_size_params *param) 10880 { 10881 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 10882 wmi_buf_t buf; 10883 int32_t len = sizeof(*cmd); 10884 10885 buf = wmi_buf_alloc(wmi_handle, len); 10886 if (!buf) { 10887 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10888 return QDF_STATUS_E_FAILURE; 10889 } 10890 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 10891 wmi_buf_data(buf); 10892 WMITLV_SET_HDR(&cmd->tlv_header, 10893 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 10894 WMITLV_GET_STRUCT_TLVLEN( 10895 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 10896 cmd->vdev_id = param->vdev_id; 10897 cmd->tx_aggr_size = param->tx_aggr_size; 10898 cmd->rx_aggr_size = param->rx_aggr_size; 10899 copy_custom_aggr_bitmap(param, cmd); 10900 10901 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 10902 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 10903 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 10904 "tx_ac_enable=0x%X\n", 10905 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 10906 param->ac, param->aggr_type, param->tx_aggr_size_disable, 10907 param->rx_aggr_size_disable, param->tx_ac_enable); 10908 10909 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10910 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 10911 WMI_LOGE("Seting custom aggregation size failed\n"); 10912 wmi_buf_free(buf); 10913 return QDF_STATUS_E_FAILURE; 10914 } 10915 10916 return QDF_STATUS_SUCCESS; 10917 } 10918 10919 /** 10920 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 10921 * @param wmi_handle : handle to WMI. 10922 * @param param : pointer to tx antenna param 10923 * 10924 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10925 */ 10926 10927 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 10928 struct set_qdepth_thresh_params *param) 10929 { 10930 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 10931 wmi_msduq_qdepth_thresh_update *cmd_update; 10932 wmi_buf_t buf; 10933 int32_t len = 0; 10934 int i; 10935 uint8_t *buf_ptr; 10936 QDF_STATUS ret; 10937 10938 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 10939 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 10940 return QDF_STATUS_E_INVAL; 10941 } 10942 10943 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10944 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 10945 param->num_of_msduq_updates); 10946 buf = wmi_buf_alloc(wmi_handle, len); 10947 10948 if (!buf) { 10949 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10950 return QDF_STATUS_E_NOMEM; 10951 } 10952 10953 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10954 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 10955 buf_ptr; 10956 10957 WMITLV_SET_HDR(&cmd->tlv_header, 10958 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 10959 , WMITLV_GET_STRUCT_TLVLEN( 10960 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 10961 10962 cmd->pdev_id = 10963 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 10964 cmd->vdev_id = param->vdev_id; 10965 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 10966 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 10967 10968 buf_ptr += sizeof( 10969 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 10970 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10971 param->num_of_msduq_updates * 10972 sizeof(wmi_msduq_qdepth_thresh_update)); 10973 buf_ptr += WMI_TLV_HDR_SIZE; 10974 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 10975 10976 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 10977 WMITLV_SET_HDR(&cmd_update->tlv_header, 10978 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 10979 WMITLV_GET_STRUCT_TLVLEN( 10980 wmi_msduq_qdepth_thresh_update)); 10981 cmd_update->tid_num = param->update_params[i].tid_num; 10982 cmd_update->msduq_update_mask = 10983 param->update_params[i].msduq_update_mask; 10984 cmd_update->qdepth_thresh_value = 10985 param->update_params[i].qdepth_thresh_value; 10986 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 10987 "mac_addr_upper4=%X, mac_addr_lower2:%X," 10988 " update mask=0x%X thresh val=0x%X\n", 10989 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 10990 cmd->peer_mac_address.mac_addr31to0, 10991 cmd->peer_mac_address.mac_addr47to32, 10992 cmd_update->msduq_update_mask, 10993 cmd_update->qdepth_thresh_value); 10994 cmd_update++; 10995 } 10996 10997 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10998 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 10999 11000 if (ret != 0) { 11001 WMI_LOGE(" %s :WMI Failed\n", __func__); 11002 wmi_buf_free(buf); 11003 } 11004 11005 return ret; 11006 } 11007 11008 /** 11009 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11010 * @wmi_handle: wmi handle 11011 * @param: pointer to hold vap dscp tid map param 11012 * 11013 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11014 */ 11015 static QDF_STATUS 11016 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11017 struct vap_dscp_tid_map_params *param) 11018 { 11019 wmi_buf_t buf; 11020 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11021 int32_t len = sizeof(*cmd); 11022 11023 buf = wmi_buf_alloc(wmi_handle, len); 11024 if (!buf) { 11025 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11026 return QDF_STATUS_E_FAILURE; 11027 } 11028 11029 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11030 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11031 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 11032 11033 cmd->vdev_id = param->vdev_id; 11034 cmd->enable_override = 0; 11035 11036 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11037 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11038 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11039 WMI_LOGE("Failed to set dscp cmd\n"); 11040 wmi_buf_free(buf); 11041 return QDF_STATUS_E_FAILURE; 11042 } 11043 11044 return QDF_STATUS_SUCCESS; 11045 } 11046 11047 /** 11048 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11049 * @wmi_handle: wmi handle 11050 * @macaddr: vdev mac address 11051 * @param: pointer to hold neigbour rx param 11052 * 11053 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11054 */ 11055 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11056 uint8_t macaddr[IEEE80211_ADDR_LEN], 11057 struct set_neighbour_rx_params *param) 11058 { 11059 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11060 wmi_buf_t buf; 11061 int32_t len = sizeof(*cmd); 11062 11063 buf = wmi_buf_alloc(wmi_handle, len); 11064 if (!buf) { 11065 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11066 return QDF_STATUS_E_FAILURE; 11067 } 11068 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11069 WMITLV_SET_HDR(&cmd->tlv_header, 11070 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11071 WMITLV_GET_STRUCT_TLVLEN( 11072 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11073 cmd->vdev_id = param->vdev_id; 11074 cmd->bssid_idx = param->idx; 11075 cmd->action = param->action; 11076 cmd->type = param->type; 11077 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11078 cmd->flag = 0; 11079 11080 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11081 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11082 WMI_LOGE("Failed to set neighbour rx param\n"); 11083 wmi_buf_free(buf); 11084 return QDF_STATUS_E_FAILURE; 11085 } 11086 11087 return QDF_STATUS_SUCCESS; 11088 } 11089 11090 /** 11091 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11092 * @param wmi_handle : handle to WMI. 11093 * @param macaddr : vdev mac address 11094 * @param param : pointer to tx antenna param 11095 * 11096 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11097 */ 11098 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11099 uint8_t macaddr[IEEE80211_ADDR_LEN], 11100 struct smart_ant_tx_ant_params *param) 11101 { 11102 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11103 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11104 wmi_buf_t buf; 11105 int32_t len = 0; 11106 int i; 11107 uint8_t *buf_ptr; 11108 QDF_STATUS ret; 11109 11110 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11111 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11112 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11113 buf = wmi_buf_alloc(wmi_handle, len); 11114 11115 if (!buf) { 11116 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11117 return QDF_STATUS_E_NOMEM; 11118 } 11119 11120 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11121 qdf_mem_zero(buf_ptr, len); 11122 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11123 11124 WMITLV_SET_HDR(&cmd->tlv_header, 11125 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11126 WMITLV_GET_STRUCT_TLVLEN( 11127 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11128 11129 cmd->vdev_id = param->vdev_id; 11130 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11131 11132 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11133 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11134 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11135 buf_ptr += WMI_TLV_HDR_SIZE; 11136 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11137 11138 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11139 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11140 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11141 WMITLV_GET_STRUCT_TLVLEN( 11142 wmi_peer_smart_ant_set_tx_antenna_series)); 11143 ant_tx_series->antenna_series = param->antenna_array[i]; 11144 ant_tx_series++; 11145 } 11146 11147 ret = wmi_unified_cmd_send(wmi_handle, 11148 buf, 11149 len, 11150 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11151 11152 if (ret != 0) { 11153 WMI_LOGE(" %s :WMI Failed\n", __func__); 11154 wmi_buf_free(buf); 11155 } 11156 11157 return ret; 11158 } 11159 11160 /** 11161 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11162 * @wmi_handle: wmi handle 11163 * @param: pointer to hold ant switch tbl param 11164 * 11165 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11166 */ 11167 static QDF_STATUS 11168 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11169 struct ant_switch_tbl_params *param) 11170 { 11171 uint8_t len; 11172 wmi_buf_t buf; 11173 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11174 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11175 uint8_t *buf_ptr; 11176 11177 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11178 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11179 buf = wmi_buf_alloc(wmi_handle, len); 11180 11181 if (!buf) { 11182 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11183 return QDF_STATUS_E_NOMEM; 11184 } 11185 11186 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11187 qdf_mem_zero(buf_ptr, len); 11188 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11189 11190 WMITLV_SET_HDR(&cmd->tlv_header, 11191 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11192 WMITLV_GET_STRUCT_TLVLEN( 11193 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11194 11195 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11196 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11197 cmd->mac_id = 11198 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11199 11200 /* TLV indicating array of structures to follow */ 11201 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11202 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11203 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11204 buf_ptr += WMI_TLV_HDR_SIZE; 11205 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11206 11207 ctrl_chain->pdev_id = 11208 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11209 ctrl_chain->antCtrlChain = param->antCtrlChain; 11210 11211 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11212 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11213 wmi_buf_free(buf); 11214 return QDF_STATUS_E_FAILURE; 11215 } 11216 11217 return QDF_STATUS_SUCCESS; 11218 } 11219 11220 /** 11221 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11222 * training information function 11223 * @param wmi_handle : handle to WMI. 11224 * @macaddr : vdev mac address 11225 * @param param : pointer to tx antenna param 11226 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11227 */ 11228 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11229 wmi_unified_t wmi_handle, 11230 uint8_t macaddr[IEEE80211_ADDR_LEN], 11231 struct smart_ant_training_info_params *param) 11232 { 11233 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11234 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11235 wmi_buf_t buf; 11236 uint8_t *buf_ptr; 11237 int32_t len = 0; 11238 QDF_STATUS ret; 11239 int loop; 11240 11241 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11242 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11243 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11244 buf = wmi_buf_alloc(wmi_handle, len); 11245 11246 if (!buf) { 11247 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11248 return QDF_STATUS_E_NOMEM; 11249 } 11250 11251 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11252 qdf_mem_zero(buf_ptr, len); 11253 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11254 11255 WMITLV_SET_HDR(&cmd->tlv_header, 11256 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11257 WMITLV_GET_STRUCT_TLVLEN( 11258 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11259 11260 cmd->vdev_id = param->vdev_id; 11261 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11262 cmd->num_pkts = param->numpkts; 11263 11264 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11265 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11266 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11267 WMI_SMART_ANT_MAX_RATE_SERIES); 11268 11269 buf_ptr += WMI_TLV_HDR_SIZE; 11270 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11271 11272 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11273 WMITLV_SET_HDR(&train_param->tlv_header, 11274 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11275 WMITLV_GET_STRUCT_TLVLEN( 11276 wmi_peer_smart_ant_set_train_antenna_param)); 11277 train_param->train_rate_series = param->rate_array[loop]; 11278 train_param->train_antenna_series = param->antenna_array[loop]; 11279 train_param->rc_flags = 0; 11280 WMI_LOGI(FL("Series number:%d\n"), loop); 11281 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11282 train_param->train_rate_series, 11283 train_param->train_antenna_series); 11284 train_param++; 11285 } 11286 11287 ret = wmi_unified_cmd_send(wmi_handle, 11288 buf, 11289 len, 11290 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 11291 11292 if (ret != 0) { 11293 WMI_LOGE(" %s :WMI Failed\n", __func__); 11294 wmi_buf_free(buf); 11295 return QDF_STATUS_E_FAILURE; 11296 } 11297 11298 return ret; 11299 } 11300 11301 /** 11302 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 11303 * configuration function 11304 * @param wmi_handle : handle to WMI. 11305 * @macaddr : vdev mad address 11306 * @param param : pointer to tx antenna param 11307 * 11308 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11309 */ 11310 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 11311 wmi_unified_t wmi_handle, 11312 uint8_t macaddr[IEEE80211_ADDR_LEN], 11313 struct smart_ant_node_config_params *param) 11314 { 11315 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 11316 wmi_buf_t buf; 11317 uint8_t *buf_ptr; 11318 int32_t len = 0, args_tlv_len; 11319 int ret; 11320 int i = 0; 11321 uint32_t *node_config_args; 11322 11323 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 11324 len = sizeof(*cmd) + args_tlv_len; 11325 11326 if (param->args_count == 0) { 11327 WMI_LOGE("%s: Can't send a command with %d arguments\n", 11328 __func__, param->args_count); 11329 return QDF_STATUS_E_FAILURE; 11330 } 11331 11332 buf = wmi_buf_alloc(wmi_handle, len); 11333 if (!buf) { 11334 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11335 return QDF_STATUS_E_NOMEM; 11336 } 11337 11338 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 11339 wmi_buf_data(buf); 11340 buf_ptr = (uint8_t *)cmd; 11341 WMITLV_SET_HDR(&cmd->tlv_header, 11342 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 11343 WMITLV_GET_STRUCT_TLVLEN( 11344 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 11345 cmd->vdev_id = param->vdev_id; 11346 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11347 cmd->cmd_id = param->cmd_id; 11348 cmd->args_count = param->args_count; 11349 buf_ptr += sizeof( 11350 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 11351 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11352 (cmd->args_count * sizeof(uint32_t))); 11353 buf_ptr += WMI_TLV_HDR_SIZE; 11354 node_config_args = (uint32_t *)buf_ptr; 11355 11356 for (i = 0; i < param->args_count; i++) { 11357 node_config_args[i] = param->args_arr[i]; 11358 WMI_LOGI("%d", param->args_arr[i]); 11359 } 11360 11361 ret = wmi_unified_cmd_send(wmi_handle, 11362 buf, 11363 len, 11364 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 11365 11366 if (ret != 0) { 11367 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 11368 __func__, param->cmd_id, macaddr[0], 11369 macaddr[1], macaddr[2], macaddr[3], 11370 macaddr[4], macaddr[5], ret); 11371 wmi_buf_free(buf); 11372 } 11373 11374 return ret; 11375 } 11376 11377 /** 11378 * send_set_atf_cmd_tlv() - send set atf command to fw 11379 * @wmi_handle: wmi handle 11380 * @param: pointer to set atf param 11381 * 11382 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11383 */ 11384 static QDF_STATUS 11385 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 11386 struct set_atf_params *param) 11387 { 11388 wmi_atf_peer_info *peer_info; 11389 wmi_peer_atf_request_fixed_param *cmd; 11390 wmi_buf_t buf; 11391 uint8_t *buf_ptr; 11392 int i; 11393 int32_t len = 0; 11394 QDF_STATUS retval; 11395 11396 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11397 len += param->num_peers * sizeof(wmi_atf_peer_info); 11398 buf = wmi_buf_alloc(wmi_handle, len); 11399 if (!buf) { 11400 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11401 return QDF_STATUS_E_FAILURE; 11402 } 11403 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11404 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 11405 WMITLV_SET_HDR(&cmd->tlv_header, 11406 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 11407 WMITLV_GET_STRUCT_TLVLEN( 11408 wmi_peer_atf_request_fixed_param)); 11409 cmd->num_peers = param->num_peers; 11410 11411 buf_ptr += sizeof(*cmd); 11412 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11413 sizeof(wmi_atf_peer_info) * 11414 cmd->num_peers); 11415 buf_ptr += WMI_TLV_HDR_SIZE; 11416 peer_info = (wmi_atf_peer_info *)buf_ptr; 11417 11418 for (i = 0; i < cmd->num_peers; i++) { 11419 WMITLV_SET_HDR(&peer_info->tlv_header, 11420 WMITLV_TAG_STRUC_wmi_atf_peer_info, 11421 WMITLV_GET_STRUCT_TLVLEN( 11422 wmi_atf_peer_info)); 11423 qdf_mem_copy(&(peer_info->peer_macaddr), 11424 &(param->peer_info[i].peer_macaddr), 11425 sizeof(wmi_mac_addr)); 11426 peer_info->atf_units = param->peer_info[i].percentage_peer; 11427 peer_info->vdev_id = param->peer_info[i].vdev_id; 11428 peer_info->pdev_id = 11429 wmi_handle->ops->convert_pdev_id_host_to_target( 11430 param->peer_info[i].pdev_id); 11431 /* 11432 * TLV definition for peer atf request fixed param combines 11433 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 11434 * stats and atf extension stats as two different 11435 * implementations. 11436 * Need to discuss with FW on this. 11437 * 11438 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 11439 * peer_info->atf_units_reserved = 11440 * param->peer_ext_info[i].atf_index_reserved; 11441 */ 11442 peer_info++; 11443 } 11444 11445 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11446 WMI_PEER_ATF_REQUEST_CMDID); 11447 11448 if (retval != QDF_STATUS_SUCCESS) { 11449 WMI_LOGE("%s : WMI Failed\n", __func__); 11450 wmi_buf_free(buf); 11451 } 11452 11453 return retval; 11454 } 11455 11456 /** 11457 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 11458 * @wmi_handle: wmi handle 11459 * @param: pointer to hold fwtest param 11460 * 11461 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11462 */ 11463 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 11464 struct set_fwtest_params *param) 11465 { 11466 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11467 wmi_buf_t buf; 11468 int32_t len = sizeof(*cmd); 11469 11470 buf = wmi_buf_alloc(wmi_handle, len); 11471 11472 if (!buf) { 11473 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11474 return QDF_STATUS_E_FAILURE; 11475 } 11476 11477 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 11478 WMITLV_SET_HDR(&cmd->tlv_header, 11479 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11480 WMITLV_GET_STRUCT_TLVLEN( 11481 wmi_fwtest_set_param_cmd_fixed_param)); 11482 cmd->param_id = param->arg; 11483 cmd->param_value = param->value; 11484 11485 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 11486 WMI_LOGE("Setting FW test param failed\n"); 11487 wmi_buf_free(buf); 11488 return QDF_STATUS_E_FAILURE; 11489 } 11490 11491 return QDF_STATUS_SUCCESS; 11492 } 11493 11494 /** 11495 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 11496 * @wmi_handle: wmi handle 11497 * @param: pointer to qboost params 11498 * @macaddr: vdev mac address 11499 * 11500 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11501 */ 11502 static QDF_STATUS 11503 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 11504 uint8_t macaddr[IEEE80211_ADDR_LEN], 11505 struct set_qboost_params *param) 11506 { 11507 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 11508 wmi_buf_t buf; 11509 int32_t len; 11510 QDF_STATUS ret; 11511 11512 len = sizeof(*cmd); 11513 11514 buf = wmi_buf_alloc(wmi_handle, len); 11515 if (!buf) { 11516 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11517 return QDF_STATUS_E_FAILURE; 11518 } 11519 11520 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 11521 WMITLV_SET_HDR(&cmd->tlv_header, 11522 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 11523 WMITLV_GET_STRUCT_TLVLEN( 11524 WMI_QBOOST_CFG_CMD_fixed_param)); 11525 cmd->vdev_id = param->vdev_id; 11526 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11527 cmd->qb_enable = param->value; 11528 11529 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11530 WMI_QBOOST_CFG_CMDID); 11531 11532 if (ret != 0) { 11533 WMI_LOGE("Setting qboost cmd failed\n"); 11534 wmi_buf_free(buf); 11535 } 11536 11537 return ret; 11538 } 11539 11540 /** 11541 * send_gpio_config_cmd_tlv() - send gpio config to fw 11542 * @wmi_handle: wmi handle 11543 * @param: pointer to hold gpio config param 11544 * 11545 * Return: 0 for success or error code 11546 */ 11547 static QDF_STATUS 11548 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 11549 struct gpio_config_params *param) 11550 { 11551 wmi_gpio_config_cmd_fixed_param *cmd; 11552 wmi_buf_t buf; 11553 int32_t len; 11554 QDF_STATUS ret; 11555 11556 len = sizeof(*cmd); 11557 11558 /* Sanity Checks */ 11559 if (param->pull_type > WMI_GPIO_PULL_DOWN || 11560 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 11561 return QDF_STATUS_E_FAILURE; 11562 } 11563 11564 buf = wmi_buf_alloc(wmi_handle, len); 11565 if (!buf) { 11566 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11567 return QDF_STATUS_E_FAILURE; 11568 } 11569 11570 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 11571 WMITLV_SET_HDR(&cmd->tlv_header, 11572 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 11573 WMITLV_GET_STRUCT_TLVLEN( 11574 wmi_gpio_config_cmd_fixed_param)); 11575 cmd->gpio_num = param->gpio_num; 11576 cmd->input = param->input; 11577 cmd->pull_type = param->pull_type; 11578 cmd->intr_mode = param->intr_mode; 11579 11580 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11581 WMI_GPIO_CONFIG_CMDID); 11582 11583 if (ret != 0) { 11584 WMI_LOGE("Sending GPIO config cmd failed\n"); 11585 wmi_buf_free(buf); 11586 } 11587 11588 return ret; 11589 } 11590 11591 /** 11592 * send_gpio_output_cmd_tlv() - send gpio output to fw 11593 * @wmi_handle: wmi handle 11594 * @param: pointer to hold gpio output param 11595 * 11596 * Return: 0 for success or error code 11597 */ 11598 static QDF_STATUS 11599 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 11600 struct gpio_output_params *param) 11601 { 11602 wmi_gpio_output_cmd_fixed_param *cmd; 11603 wmi_buf_t buf; 11604 int32_t len; 11605 QDF_STATUS ret; 11606 11607 len = sizeof(*cmd); 11608 11609 buf = wmi_buf_alloc(wmi_handle, len); 11610 if (!buf) { 11611 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11612 return QDF_STATUS_E_FAILURE; 11613 } 11614 11615 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 11616 WMITLV_SET_HDR(&cmd->tlv_header, 11617 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 11618 WMITLV_GET_STRUCT_TLVLEN( 11619 wmi_gpio_output_cmd_fixed_param)); 11620 cmd->gpio_num = param->gpio_num; 11621 cmd->set = param->set; 11622 11623 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11624 WMI_GPIO_OUTPUT_CMDID); 11625 11626 if (ret != 0) { 11627 WMI_LOGE("Sending GPIO output cmd failed\n"); 11628 wmi_buf_free(buf); 11629 } 11630 11631 return ret; 11632 11633 } 11634 11635 /** 11636 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 11637 * 11638 * @param wmi_handle : handle to WMI. 11639 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11640 */ 11641 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 11642 { 11643 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 11644 wmi_buf_t buf; 11645 QDF_STATUS ret; 11646 int32_t len; 11647 11648 len = sizeof(*cmd); 11649 11650 buf = wmi_buf_alloc(wmi_handle, len); 11651 if (!buf) { 11652 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11653 return QDF_STATUS_E_FAILURE; 11654 } 11655 11656 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 11657 WMITLV_SET_HDR(&cmd->tlv_header, 11658 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 11659 WMITLV_GET_STRUCT_TLVLEN( 11660 wmi_pdev_dfs_disable_cmd_fixed_param)); 11661 /* Filling it with WMI_PDEV_ID_SOC for now */ 11662 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11663 WMI_HOST_PDEV_ID_SOC); 11664 11665 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11666 WMI_PDEV_DFS_DISABLE_CMDID); 11667 11668 if (ret != 0) { 11669 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 11670 wmi_buf_free(buf); 11671 } 11672 11673 return ret; 11674 } 11675 11676 /** 11677 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 11678 * 11679 * @param wmi_handle : handle to WMI. 11680 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11681 */ 11682 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 11683 { 11684 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 11685 wmi_buf_t buf; 11686 QDF_STATUS ret; 11687 int32_t len; 11688 11689 len = sizeof(*cmd); 11690 11691 buf = wmi_buf_alloc(wmi_handle, len); 11692 if (!buf) { 11693 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11694 return QDF_STATUS_E_FAILURE; 11695 } 11696 11697 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 11698 WMITLV_SET_HDR(&cmd->tlv_header, 11699 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 11700 WMITLV_GET_STRUCT_TLVLEN( 11701 wmi_pdev_dfs_enable_cmd_fixed_param)); 11702 /* Reserved for future use */ 11703 cmd->reserved0 = 0; 11704 11705 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11706 WMI_PDEV_DFS_ENABLE_CMDID); 11707 11708 if (ret != 0) { 11709 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 11710 wmi_buf_free(buf); 11711 } 11712 11713 return ret; 11714 } 11715 11716 /** 11717 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 11718 * to fw 11719 * @wmi_handle: wmi handle 11720 * @param: pointer to hold periodic chan stats param 11721 * 11722 * Return: 0 for success or error code 11723 */ 11724 static QDF_STATUS 11725 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 11726 struct periodic_chan_stats_params *param) 11727 { 11728 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 11729 wmi_buf_t buf; 11730 QDF_STATUS ret; 11731 int32_t len; 11732 11733 len = sizeof(*cmd); 11734 11735 buf = wmi_buf_alloc(wmi_handle, len); 11736 if (!buf) { 11737 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11738 return QDF_STATUS_E_FAILURE; 11739 } 11740 11741 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 11742 wmi_buf_data(buf); 11743 WMITLV_SET_HDR(&cmd->tlv_header, 11744 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 11745 WMITLV_GET_STRUCT_TLVLEN( 11746 wmi_set_periodic_channel_stats_config_fixed_param)); 11747 cmd->enable = param->enable; 11748 cmd->stats_period = param->stats_period; 11749 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11750 param->pdev_id); 11751 11752 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11753 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 11754 11755 if (ret != 0) { 11756 WMI_LOGE("Sending periodic chan stats config failed"); 11757 wmi_buf_free(buf); 11758 } 11759 11760 return ret; 11761 } 11762 11763 /** 11764 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 11765 * @wmi_handle: wmi handle 11766 * @mac_id: radio context 11767 * 11768 * Return: 0 for success or error code 11769 */ 11770 static QDF_STATUS 11771 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 11772 { 11773 wmi_buf_t buf; 11774 QDF_STATUS ret; 11775 wmi_pdev_get_nfcal_power_fixed_param *cmd; 11776 int32_t len = sizeof(*cmd); 11777 11778 buf = wmi_buf_alloc(wmi_handle, len); 11779 if (buf == NULL) 11780 return QDF_STATUS_E_NOMEM; 11781 11782 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 11783 WMITLV_SET_HDR(&cmd->tlv_header, 11784 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 11785 WMITLV_GET_STRUCT_TLVLEN 11786 (wmi_pdev_get_nfcal_power_fixed_param)); 11787 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 11788 11789 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11790 WMI_PDEV_GET_NFCAL_POWER_CMDID); 11791 if (ret != 0) { 11792 WMI_LOGE("Sending get nfcal power cmd failed\n"); 11793 wmi_buf_free(buf); 11794 } 11795 11796 return ret; 11797 } 11798 11799 /** 11800 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 11801 * @wmi_handle: wmi handle 11802 * @param: pointer to ht ie param 11803 * 11804 * Return: 0 for success or error code 11805 */ 11806 static QDF_STATUS 11807 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11808 struct ht_ie_params *param) 11809 { 11810 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 11811 wmi_buf_t buf; 11812 QDF_STATUS ret; 11813 int32_t len; 11814 uint8_t *buf_ptr; 11815 11816 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11817 roundup(param->ie_len, sizeof(uint32_t)); 11818 11819 buf = wmi_buf_alloc(wmi_handle, len); 11820 if (!buf) { 11821 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11822 return QDF_STATUS_E_FAILURE; 11823 } 11824 11825 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11826 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 11827 WMITLV_SET_HDR(&cmd->tlv_header, 11828 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 11829 WMITLV_GET_STRUCT_TLVLEN( 11830 wmi_pdev_set_ht_ie_cmd_fixed_param)); 11831 cmd->reserved0 = 0; 11832 cmd->ie_len = param->ie_len; 11833 cmd->tx_streams = param->tx_streams; 11834 cmd->rx_streams = param->rx_streams; 11835 11836 buf_ptr += sizeof(*cmd); 11837 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11838 buf_ptr += WMI_TLV_HDR_SIZE; 11839 if (param->ie_len) 11840 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11841 cmd->ie_len); 11842 11843 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11844 WMI_PDEV_SET_HT_CAP_IE_CMDID); 11845 11846 if (ret != 0) { 11847 WMI_LOGE("Sending set ht ie cmd failed\n"); 11848 wmi_buf_free(buf); 11849 } 11850 11851 return ret; 11852 } 11853 11854 /** 11855 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 11856 * @wmi_handle: wmi handle 11857 * @param: pointer to vht ie param 11858 * 11859 * Return: 0 for success or error code 11860 */ 11861 static QDF_STATUS 11862 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11863 struct vht_ie_params *param) 11864 { 11865 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 11866 wmi_buf_t buf; 11867 QDF_STATUS ret; 11868 int32_t len; 11869 uint8_t *buf_ptr; 11870 11871 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11872 roundup(param->ie_len, sizeof(uint32_t)); 11873 11874 buf = wmi_buf_alloc(wmi_handle, len); 11875 if (!buf) { 11876 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11877 return QDF_STATUS_E_FAILURE; 11878 } 11879 11880 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11881 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 11882 WMITLV_SET_HDR(&cmd->tlv_header, 11883 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 11884 WMITLV_GET_STRUCT_TLVLEN( 11885 wmi_pdev_set_vht_ie_cmd_fixed_param)); 11886 cmd->reserved0 = 0; 11887 cmd->ie_len = param->ie_len; 11888 cmd->tx_streams = param->tx_streams; 11889 cmd->rx_streams = param->rx_streams; 11890 11891 buf_ptr += sizeof(*cmd); 11892 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11893 buf_ptr += WMI_TLV_HDR_SIZE; 11894 if (param->ie_len) 11895 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11896 cmd->ie_len); 11897 11898 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11899 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 11900 11901 if (ret != 0) { 11902 WMI_LOGE("Sending set vht ie cmd failed\n"); 11903 wmi_buf_free(buf); 11904 } 11905 11906 return ret; 11907 } 11908 11909 /** 11910 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 11911 * @wmi_handle: wmi handle 11912 * @param: pointer to quiet mode params 11913 * 11914 * Return: 0 for success or error code 11915 */ 11916 static QDF_STATUS 11917 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 11918 struct set_quiet_mode_params *param) 11919 { 11920 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 11921 wmi_buf_t buf; 11922 QDF_STATUS ret; 11923 int32_t len; 11924 11925 len = sizeof(*quiet_cmd); 11926 buf = wmi_buf_alloc(wmi_handle, len); 11927 if (!buf) { 11928 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11929 return QDF_STATUS_E_FAILURE; 11930 } 11931 11932 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11933 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 11934 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 11935 WMITLV_GET_STRUCT_TLVLEN( 11936 wmi_pdev_set_quiet_cmd_fixed_param)); 11937 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11938 quiet_cmd->enabled = param->enabled; 11939 quiet_cmd->period = (param->period)*(param->intval); 11940 quiet_cmd->duration = param->duration; 11941 quiet_cmd->next_start = param->offset; 11942 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11943 WMI_HOST_PDEV_ID_SOC); 11944 11945 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11946 WMI_PDEV_SET_QUIET_MODE_CMDID); 11947 11948 if (ret != 0) { 11949 WMI_LOGE("Sending set quiet cmd failed\n"); 11950 wmi_buf_free(buf); 11951 } 11952 11953 return ret; 11954 } 11955 11956 /** 11957 * send_set_bwf_cmd_tlv() - send set bwf command to fw 11958 * @wmi_handle: wmi handle 11959 * @param: pointer to set bwf param 11960 * 11961 * Return: 0 for success or error code 11962 */ 11963 static QDF_STATUS 11964 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 11965 struct set_bwf_params *param) 11966 { 11967 wmi_bwf_peer_info *peer_info; 11968 wmi_peer_bwf_request_fixed_param *cmd; 11969 wmi_buf_t buf; 11970 QDF_STATUS retval; 11971 int32_t len; 11972 uint8_t *buf_ptr; 11973 int i; 11974 11975 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11976 len += param->num_peers * sizeof(wmi_bwf_peer_info); 11977 buf = wmi_buf_alloc(wmi_handle, len); 11978 if (!buf) { 11979 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11980 return QDF_STATUS_E_FAILURE; 11981 } 11982 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11983 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 11984 WMITLV_SET_HDR(&cmd->tlv_header, 11985 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 11986 WMITLV_GET_STRUCT_TLVLEN( 11987 wmi_peer_bwf_request_fixed_param)); 11988 cmd->num_peers = param->num_peers; 11989 11990 buf_ptr += sizeof(*cmd); 11991 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11992 sizeof(wmi_bwf_peer_info) * 11993 cmd->num_peers); 11994 buf_ptr += WMI_TLV_HDR_SIZE; 11995 peer_info = (wmi_bwf_peer_info *)buf_ptr; 11996 11997 for (i = 0; i < cmd->num_peers; i++) { 11998 WMITLV_SET_HDR(&peer_info->tlv_header, 11999 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12000 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12001 peer_info->bwf_guaranteed_bandwidth = 12002 param->peer_info[i].throughput; 12003 peer_info->bwf_max_airtime = 12004 param->peer_info[i].max_airtime; 12005 peer_info->bwf_peer_priority = 12006 param->peer_info[i].priority; 12007 qdf_mem_copy(&peer_info->peer_macaddr, 12008 ¶m->peer_info[i].peer_macaddr, 12009 sizeof(param->peer_info[i].peer_macaddr)); 12010 peer_info->vdev_id = 12011 param->peer_info[i].vdev_id; 12012 peer_info->pdev_id = 12013 wmi_handle->ops->convert_pdev_id_host_to_target( 12014 param->peer_info[i].pdev_id); 12015 peer_info++; 12016 } 12017 12018 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12019 WMI_PEER_BWF_REQUEST_CMDID); 12020 12021 if (retval != QDF_STATUS_SUCCESS) { 12022 WMI_LOGE("%s : WMI Failed\n", __func__); 12023 wmi_buf_free(buf); 12024 } 12025 12026 return retval; 12027 } 12028 12029 /** 12030 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12031 * @wmi_handle: wmi handle 12032 * @param: pointer to hold mcast update param 12033 * 12034 * Return: 0 for success or error code 12035 */ 12036 static QDF_STATUS 12037 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12038 struct mcast_group_update_params *param) 12039 { 12040 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12041 wmi_buf_t buf; 12042 QDF_STATUS ret; 12043 int32_t len; 12044 int offset = 0; 12045 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12046 12047 len = sizeof(*cmd); 12048 buf = wmi_buf_alloc(wmi_handle, len); 12049 if (!buf) { 12050 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12051 return QDF_STATUS_E_FAILURE; 12052 } 12053 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12054 WMITLV_SET_HDR(&cmd->tlv_header, 12055 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12056 WMITLV_GET_STRUCT_TLVLEN( 12057 wmi_peer_mcast_group_cmd_fixed_param)); 12058 /* confirm the buffer is 4-byte aligned */ 12059 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12060 qdf_mem_zero(cmd, sizeof(*cmd)); 12061 12062 cmd->vdev_id = param->vap_id; 12063 /* construct the message assuming our endianness matches the target */ 12064 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12065 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12066 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12067 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12068 if (param->is_action_delete) 12069 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12070 12071 if (param->is_mcast_addr_len) 12072 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12073 12074 if (param->is_filter_mode_snoop) 12075 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12076 12077 /* unicast address spec only applies for non-wildcard cases */ 12078 if (!param->wildcard && param->ucast_mac_addr) { 12079 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12080 &cmd->ucast_mac_addr); 12081 } 12082 12083 if (param->mcast_ip_addr) { 12084 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12085 sizeof(cmd->mcast_ip_addr)); 12086 offset = sizeof(cmd->mcast_ip_addr) - 12087 param->mcast_ip_addr_bytes; 12088 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12089 param->mcast_ip_addr, 12090 param->mcast_ip_addr_bytes); 12091 } 12092 if (!param->mask) 12093 param->mask = &dummymask[0]; 12094 12095 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12096 param->mask, 12097 param->mcast_ip_addr_bytes); 12098 12099 if (param->srcs && param->nsrcs) { 12100 cmd->num_filter_addr = param->nsrcs; 12101 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12102 sizeof(cmd->filter_addr)); 12103 12104 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12105 param->nsrcs * param->mcast_ip_addr_bytes); 12106 } 12107 12108 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12109 WMI_PEER_MCAST_GROUP_CMDID); 12110 12111 if (ret != QDF_STATUS_SUCCESS) { 12112 WMI_LOGE("%s : WMI Failed\n", __func__); 12113 wmi_buf_free(buf); 12114 } 12115 12116 return ret; 12117 } 12118 12119 /** 12120 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12121 * command to fw 12122 * @wmi_handle: wmi handle 12123 * @param: pointer to hold spectral config parameter 12124 * 12125 * Return: 0 for success or error code 12126 */ 12127 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12128 struct vdev_spectral_configure_params *param) 12129 { 12130 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12131 wmi_buf_t buf; 12132 QDF_STATUS ret; 12133 int32_t len; 12134 12135 len = sizeof(*cmd); 12136 buf = wmi_buf_alloc(wmi_handle, len); 12137 if (!buf) { 12138 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12139 return QDF_STATUS_E_FAILURE; 12140 } 12141 12142 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12143 WMITLV_SET_HDR(&cmd->tlv_header, 12144 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12145 WMITLV_GET_STRUCT_TLVLEN( 12146 wmi_vdev_spectral_configure_cmd_fixed_param)); 12147 12148 cmd->vdev_id = param->vdev_id; 12149 cmd->spectral_scan_count = param->count; 12150 cmd->spectral_scan_period = param->period; 12151 cmd->spectral_scan_priority = param->spectral_pri; 12152 cmd->spectral_scan_fft_size = param->fft_size; 12153 cmd->spectral_scan_gc_ena = param->gc_enable; 12154 cmd->spectral_scan_restart_ena = param->restart_enable; 12155 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12156 cmd->spectral_scan_init_delay = param->init_delay; 12157 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12158 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12159 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12160 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12161 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12162 cmd->spectral_scan_pwr_format = param->pwr_format; 12163 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12164 cmd->spectral_scan_bin_scale = param->bin_scale; 12165 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12166 cmd->spectral_scan_chn_mask = param->chn_mask; 12167 12168 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12169 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12170 12171 if (ret != 0) { 12172 WMI_LOGE("Sending set quiet cmd failed\n"); 12173 wmi_buf_free(buf); 12174 } 12175 12176 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12177 __func__); 12178 12179 WMI_LOGI("vdev_id = %u\n" 12180 "spectral_scan_count = %u\n" 12181 "spectral_scan_period = %u\n" 12182 "spectral_scan_priority = %u\n" 12183 "spectral_scan_fft_size = %u\n" 12184 "spectral_scan_gc_ena = %u\n" 12185 "spectral_scan_restart_ena = %u\n" 12186 "spectral_scan_noise_floor_ref = %u\n" 12187 "spectral_scan_init_delay = %u\n" 12188 "spectral_scan_nb_tone_thr = %u\n" 12189 "spectral_scan_str_bin_thr = %u\n" 12190 "spectral_scan_wb_rpt_mode = %u\n" 12191 "spectral_scan_rssi_rpt_mode = %u\n" 12192 "spectral_scan_rssi_thr = %u\n" 12193 "spectral_scan_pwr_format = %u\n" 12194 "spectral_scan_rpt_mode = %u\n" 12195 "spectral_scan_bin_scale = %u\n" 12196 "spectral_scan_dBm_adj = %u\n" 12197 "spectral_scan_chn_mask = %u\n", 12198 param->vdev_id, 12199 param->count, 12200 param->period, 12201 param->spectral_pri, 12202 param->fft_size, 12203 param->gc_enable, 12204 param->restart_enable, 12205 param->noise_floor_ref, 12206 param->init_delay, 12207 param->nb_tone_thr, 12208 param->str_bin_thr, 12209 param->wb_rpt_mode, 12210 param->rssi_rpt_mode, 12211 param->rssi_thr, 12212 param->pwr_format, 12213 param->rpt_mode, 12214 param->bin_scale, 12215 param->dbm_adj, 12216 param->chn_mask); 12217 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12218 12219 return ret; 12220 } 12221 12222 /** 12223 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12224 * command to fw 12225 * @wmi_handle: wmi handle 12226 * @param: pointer to hold spectral enable parameter 12227 * 12228 * Return: 0 for success or error code 12229 */ 12230 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12231 struct vdev_spectral_enable_params *param) 12232 { 12233 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12234 wmi_buf_t buf; 12235 QDF_STATUS ret; 12236 int32_t len; 12237 12238 len = sizeof(*cmd); 12239 buf = wmi_buf_alloc(wmi_handle, len); 12240 if (!buf) { 12241 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12242 return QDF_STATUS_E_FAILURE; 12243 } 12244 12245 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12246 WMITLV_SET_HDR(&cmd->tlv_header, 12247 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12248 WMITLV_GET_STRUCT_TLVLEN( 12249 wmi_vdev_spectral_enable_cmd_fixed_param)); 12250 12251 cmd->vdev_id = param->vdev_id; 12252 12253 if (param->active_valid) { 12254 cmd->trigger_cmd = param->active ? 1 : 2; 12255 /* 1: Trigger, 2: Clear Trigger */ 12256 } else { 12257 cmd->trigger_cmd = 0; /* 0: Ignore */ 12258 } 12259 12260 if (param->enabled_valid) { 12261 cmd->enable_cmd = param->enabled ? 1 : 2; 12262 /* 1: Enable 2: Disable */ 12263 } else { 12264 cmd->enable_cmd = 0; /* 0: Ignore */ 12265 } 12266 12267 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12268 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12269 12270 if (ret != 0) { 12271 WMI_LOGE("Sending scan enable CMD failed\n"); 12272 wmi_buf_free(buf); 12273 } 12274 12275 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12276 12277 WMI_LOGI("vdev_id = %u\n" 12278 "trigger_cmd = %u\n" 12279 "enable_cmd = %u\n", 12280 cmd->vdev_id, 12281 cmd->trigger_cmd, 12282 cmd->enable_cmd); 12283 12284 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12285 12286 return ret; 12287 } 12288 12289 /** 12290 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12291 * @param wmi_handle : handle to WMI. 12292 * @param param : pointer to hold thermal mitigation param 12293 * 12294 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12295 */ 12296 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12297 wmi_unified_t wmi_handle, 12298 struct thermal_mitigation_params *param) 12299 { 12300 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 12301 wmi_therm_throt_level_config_info *lvl_conf = NULL; 12302 wmi_buf_t buf = NULL; 12303 uint8_t *buf_ptr = NULL; 12304 int error; 12305 int32_t len; 12306 int i; 12307 12308 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 12309 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 12310 12311 buf = wmi_buf_alloc(wmi_handle, len); 12312 if (!buf) { 12313 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12314 return QDF_STATUS_E_NOMEM; 12315 } 12316 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 12317 12318 /* init fixed params */ 12319 WMITLV_SET_HDR(tt_conf, 12320 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 12321 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 12322 12323 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12324 param->pdev_id); 12325 tt_conf->enable = param->enable; 12326 tt_conf->dc = param->dc; 12327 tt_conf->dc_per_event = param->dc_per_event; 12328 tt_conf->therm_throt_levels = THERMAL_LEVELS; 12329 12330 buf_ptr = (uint8_t *) ++tt_conf; 12331 /* init TLV params */ 12332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12333 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 12334 12335 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 12336 for (i = 0; i < THERMAL_LEVELS; i++) { 12337 WMITLV_SET_HDR(&lvl_conf->tlv_header, 12338 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 12339 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 12340 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 12341 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 12342 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 12343 lvl_conf->prio = param->levelconf[i].priority; 12344 lvl_conf++; 12345 } 12346 12347 error = wmi_unified_cmd_send(wmi_handle, buf, len, 12348 WMI_THERM_THROT_SET_CONF_CMDID); 12349 if (QDF_IS_STATUS_ERROR(error)) { 12350 wmi_buf_free(buf); 12351 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 12352 } 12353 12354 return error; 12355 } 12356 12357 /** 12358 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 12359 * @wmi_handle: wmi handle 12360 * @param: pointer to pdev_qvit_params 12361 * 12362 * Return: 0 for success or error code 12363 */ 12364 static QDF_STATUS 12365 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 12366 struct pdev_qvit_params *param) 12367 { 12368 wmi_buf_t buf; 12369 QDF_STATUS ret = QDF_STATUS_E_INVAL; 12370 uint8_t *cmd; 12371 static uint8_t msgref = 1; 12372 uint8_t segnumber = 0, seginfo, numsegments; 12373 uint16_t chunk_len, total_bytes; 12374 uint8_t *bufpos; 12375 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 12376 12377 bufpos = param->utf_payload; 12378 total_bytes = param->len; 12379 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 12380 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 12381 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 12382 12383 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 12384 numsegments++; 12385 12386 while (param->len) { 12387 if (param->len > MAX_WMI_QVIT_LEN) 12388 chunk_len = MAX_WMI_QVIT_LEN; /* MAX message */ 12389 else 12390 chunk_len = param->len; 12391 12392 buf = wmi_buf_alloc(wmi_handle, 12393 (chunk_len + sizeof(seghdrinfo) + 12394 WMI_TLV_HDR_SIZE)); 12395 if (!buf) { 12396 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12397 return QDF_STATUS_E_NOMEM; 12398 } 12399 12400 cmd = (uint8_t *) wmi_buf_data(buf); 12401 12402 seghdrinfo.len = total_bytes; 12403 seghdrinfo.msgref = msgref; 12404 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 12405 seghdrinfo.segmentInfo = seginfo; 12406 12407 segnumber++; 12408 12409 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 12410 (chunk_len + sizeof(seghdrinfo))); 12411 cmd += WMI_TLV_HDR_SIZE; 12412 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 12413 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 12414 12415 ret = wmi_unified_cmd_send(wmi_handle, buf, 12416 (chunk_len + sizeof(seghdrinfo) + 12417 WMI_TLV_HDR_SIZE), 12418 WMI_PDEV_QVIT_CMDID); 12419 12420 if (ret != 0) { 12421 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 12422 wmi_buf_free(buf); 12423 break; 12424 } 12425 12426 param->len -= chunk_len; 12427 bufpos += chunk_len; 12428 } 12429 msgref++; 12430 12431 return ret; 12432 } 12433 12434 /** 12435 * send_wmm_update_cmd_tlv() - send wmm update command to fw 12436 * @wmi_handle: wmi handle 12437 * @param: pointer to wmm update param 12438 * 12439 * Return: 0 for success or error code 12440 */ 12441 static QDF_STATUS 12442 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 12443 struct wmm_update_params *param) 12444 { 12445 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 12446 wmi_wmm_params *wmm_param; 12447 wmi_buf_t buf; 12448 QDF_STATUS ret; 12449 int32_t len; 12450 int ac = 0; 12451 struct wmi_host_wmeParams *wmep; 12452 uint8_t *buf_ptr; 12453 12454 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 12455 buf = wmi_buf_alloc(wmi_handle, len); 12456 if (!buf) { 12457 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12458 return QDF_STATUS_E_FAILURE; 12459 } 12460 12461 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12462 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 12463 WMITLV_SET_HDR(&cmd->tlv_header, 12464 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 12465 WMITLV_GET_STRUCT_TLVLEN 12466 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 12467 12468 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 12469 12470 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 12471 12472 for (ac = 0; ac < WME_NUM_AC; ac++) { 12473 wmep = ¶m->wmep_array[ac]; 12474 wmm_param = (wmi_wmm_params *)buf_ptr; 12475 WMITLV_SET_HDR(&wmm_param->tlv_header, 12476 WMITLV_TAG_STRUC_wmi_wmm_params, 12477 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 12478 wmm_param->aifs = wmep->wmep_aifsn; 12479 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 12480 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 12481 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 12482 wmm_param->acm = wmep->wmep_acm; 12483 wmm_param->no_ack = wmep->wmep_noackPolicy; 12484 buf_ptr += sizeof(wmi_wmm_params); 12485 } 12486 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12487 WMI_PDEV_SET_WMM_PARAMS_CMDID); 12488 12489 if (ret != 0) { 12490 WMI_LOGE("Sending WMM update CMD failed\n"); 12491 wmi_buf_free(buf); 12492 } 12493 12494 return ret; 12495 } 12496 12497 /** 12498 * send_coex_config_cmd_tlv() - send coex config command to fw 12499 * @wmi_handle: wmi handle 12500 * @param: pointer to coex config param 12501 * 12502 * Return: 0 for success or error code 12503 */ 12504 static QDF_STATUS 12505 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 12506 struct coex_config_params *param) 12507 { 12508 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 12509 wmi_buf_t buf; 12510 QDF_STATUS ret; 12511 int32_t len; 12512 12513 len = sizeof(*cmd); 12514 buf = wmi_buf_alloc(wmi_handle, len); 12515 if (!buf) { 12516 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12517 return QDF_STATUS_E_FAILURE; 12518 } 12519 12520 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 12521 WMITLV_SET_HDR(&cmd->tlv_header, 12522 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 12523 WMITLV_GET_STRUCT_TLVLEN( 12524 WMI_COEX_CONFIG_CMD_fixed_param)); 12525 12526 cmd->vdev_id = param->vdev_id; 12527 cmd->config_type = param->config_type; 12528 cmd->config_arg1 = param->config_arg1; 12529 cmd->config_arg2 = param->config_arg2; 12530 cmd->config_arg3 = param->config_arg3; 12531 cmd->config_arg4 = param->config_arg4; 12532 cmd->config_arg5 = param->config_arg5; 12533 cmd->config_arg6 = param->config_arg6; 12534 12535 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12536 WMI_COEX_CONFIG_CMDID); 12537 12538 if (ret != 0) { 12539 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 12540 wmi_buf_free(buf); 12541 } 12542 12543 return ret; 12544 } 12545 12546 12547 #ifdef WLAN_SUPPORT_TWT 12548 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12549 target_resource_config *tgt_res_cfg) 12550 { 12551 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 12552 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 12553 } 12554 #else 12555 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12556 target_resource_config *tgt_res_cfg) 12557 { 12558 resource_cfg->twt_ap_pdev_count = 0; 12559 resource_cfg->twt_ap_sta_count = 0; 12560 } 12561 #endif 12562 12563 static 12564 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 12565 target_resource_config *tgt_res_cfg) 12566 { 12567 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 12568 resource_cfg->num_peers = tgt_res_cfg->num_peers; 12569 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 12570 resource_cfg->num_offload_reorder_buffs = 12571 tgt_res_cfg->num_offload_reorder_buffs; 12572 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 12573 resource_cfg->num_tids = tgt_res_cfg->num_tids; 12574 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 12575 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 12576 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 12577 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 12578 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 12579 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 12580 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 12581 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 12582 resource_cfg->scan_max_pending_req = 12583 tgt_res_cfg->scan_max_pending_req; 12584 resource_cfg->bmiss_offload_max_vdev = 12585 tgt_res_cfg->bmiss_offload_max_vdev; 12586 resource_cfg->roam_offload_max_vdev = 12587 tgt_res_cfg->roam_offload_max_vdev; 12588 resource_cfg->roam_offload_max_ap_profiles = 12589 tgt_res_cfg->roam_offload_max_ap_profiles; 12590 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 12591 resource_cfg->num_mcast_table_elems = 12592 tgt_res_cfg->num_mcast_table_elems; 12593 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 12594 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 12595 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 12596 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 12597 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 12598 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 12599 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 12600 resource_cfg->vow_config = tgt_res_cfg->vow_config; 12601 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 12602 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 12603 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 12604 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 12605 resource_cfg->num_tdls_conn_table_entries = 12606 tgt_res_cfg->num_tdls_conn_table_entries; 12607 resource_cfg->beacon_tx_offload_max_vdev = 12608 tgt_res_cfg->beacon_tx_offload_max_vdev; 12609 resource_cfg->num_multicast_filter_entries = 12610 tgt_res_cfg->num_multicast_filter_entries; 12611 resource_cfg->num_wow_filters = 12612 tgt_res_cfg->num_wow_filters; 12613 resource_cfg->num_keep_alive_pattern = 12614 tgt_res_cfg->num_keep_alive_pattern; 12615 resource_cfg->keep_alive_pattern_size = 12616 tgt_res_cfg->keep_alive_pattern_size; 12617 resource_cfg->max_tdls_concurrent_sleep_sta = 12618 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 12619 resource_cfg->max_tdls_concurrent_buffer_sta = 12620 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 12621 resource_cfg->wmi_send_separate = 12622 tgt_res_cfg->wmi_send_separate; 12623 resource_cfg->num_ocb_vdevs = 12624 tgt_res_cfg->num_ocb_vdevs; 12625 resource_cfg->num_ocb_channels = 12626 tgt_res_cfg->num_ocb_channels; 12627 resource_cfg->num_ocb_schedules = 12628 tgt_res_cfg->num_ocb_schedules; 12629 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 12630 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 12631 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 12632 resource_cfg->max_num_dbs_scan_duty_cycle = 12633 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 12634 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 12635 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 12636 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 12637 12638 if (tgt_res_cfg->atf_config) 12639 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 12640 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 12641 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 12642 resource_cfg->flag1, 1); 12643 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 12644 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 12645 resource_cfg->flag1, 1); 12646 if (tgt_res_cfg->cce_disable) 12647 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 12648 12649 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 12650 } 12651 12652 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 12653 * @wmi_handle: pointer to wmi handle 12654 * @buf_ptr: pointer to current position in init command buffer 12655 * @len: pointer to length. This will be updated with current length of cmd 12656 * @param: point host parameters for init command 12657 * 12658 * Return: Updated pointer of buf_ptr. 12659 */ 12660 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 12661 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 12662 { 12663 uint16_t idx; 12664 12665 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 12666 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 12667 wmi_pdev_band_to_mac *band_to_mac; 12668 12669 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 12670 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 12671 sizeof(wmi_resource_config) + 12672 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 12673 sizeof(wlan_host_memory_chunk))); 12674 12675 WMITLV_SET_HDR(&hw_mode->tlv_header, 12676 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 12677 (WMITLV_GET_STRUCT_TLVLEN 12678 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 12679 12680 hw_mode->hw_mode_index = param->hw_mode_id; 12681 hw_mode->num_band_to_mac = param->num_band_to_mac; 12682 12683 buf_ptr = (uint8_t *) (hw_mode + 1); 12684 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 12685 WMI_TLV_HDR_SIZE); 12686 for (idx = 0; idx < param->num_band_to_mac; idx++) { 12687 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 12688 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 12689 WMITLV_GET_STRUCT_TLVLEN 12690 (wmi_pdev_band_to_mac)); 12691 band_to_mac[idx].pdev_id = 12692 wmi_handle->ops->convert_pdev_id_host_to_target( 12693 param->band_to_mac[idx].pdev_id); 12694 band_to_mac[idx].start_freq = 12695 param->band_to_mac[idx].start_freq; 12696 band_to_mac[idx].end_freq = 12697 param->band_to_mac[idx].end_freq; 12698 } 12699 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12700 (param->num_band_to_mac * 12701 sizeof(wmi_pdev_band_to_mac)) + 12702 WMI_TLV_HDR_SIZE; 12703 12704 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12705 (param->num_band_to_mac * 12706 sizeof(wmi_pdev_band_to_mac))); 12707 } 12708 12709 return buf_ptr; 12710 } 12711 12712 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 12713 wmi_init_cmd_fixed_param *cmd) 12714 { 12715 int num_whitelist; 12716 wmi_abi_version my_vers; 12717 12718 num_whitelist = sizeof(version_whitelist) / 12719 sizeof(wmi_whitelist_version_info); 12720 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 12721 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 12722 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 12723 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 12724 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 12725 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 12726 12727 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 12728 &my_vers, 12729 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 12730 &cmd->host_abi_vers); 12731 12732 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 12733 __func__, 12734 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 12735 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 12736 cmd->host_abi_vers.abi_version_ns_0, 12737 cmd->host_abi_vers.abi_version_ns_1, 12738 cmd->host_abi_vers.abi_version_ns_2, 12739 cmd->host_abi_vers.abi_version_ns_3); 12740 12741 /* Save version sent from host - 12742 * Will be used to check ready event 12743 */ 12744 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 12745 sizeof(wmi_abi_version)); 12746 } 12747 12748 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12749 { 12750 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12751 wmi_service_ready_event_fixed_param *ev; 12752 12753 12754 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12755 12756 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12757 if (!ev) 12758 return QDF_STATUS_E_FAILURE; 12759 12760 /*Save fw version from service ready message */ 12761 /*This will be used while sending INIT message */ 12762 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12763 sizeof(wmi_handle->fw_abi_version)); 12764 12765 return QDF_STATUS_SUCCESS; 12766 } 12767 12768 /** 12769 * wmi_unified_save_fw_version_cmd() - save fw version 12770 * @wmi_handle: pointer to wmi handle 12771 * @res_cfg: resource config 12772 * @num_mem_chunks: no of mem chunck 12773 * @mem_chunk: pointer to mem chunck structure 12774 * 12775 * This function sends IE information to firmware 12776 * 12777 * Return: QDF_STATUS_SUCCESS for success otherwise failure 12778 * 12779 */ 12780 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 12781 void *evt_buf) 12782 { 12783 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12784 wmi_ready_event_fixed_param *ev = NULL; 12785 12786 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12787 ev = param_buf->fixed_param; 12788 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 12789 &wmi_handle->final_abi_vers, 12790 &ev->fw_abi_vers)) { 12791 /* 12792 * Error: Our host version and the given firmware version 12793 * are incompatible. 12794 **/ 12795 WMI_LOGD("%s: Error: Incompatible WMI version." 12796 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 12797 __func__, 12798 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 12799 abi_version_0), 12800 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 12801 abi_version_0), 12802 wmi_handle->final_abi_vers.abi_version_ns_0, 12803 wmi_handle->final_abi_vers.abi_version_ns_1, 12804 wmi_handle->final_abi_vers.abi_version_ns_2, 12805 wmi_handle->final_abi_vers.abi_version_ns_3, 12806 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 12807 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 12808 ev->fw_abi_vers.abi_version_ns_0, 12809 ev->fw_abi_vers.abi_version_ns_1, 12810 ev->fw_abi_vers.abi_version_ns_2, 12811 ev->fw_abi_vers.abi_version_ns_3); 12812 12813 return QDF_STATUS_E_FAILURE; 12814 } 12815 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 12816 sizeof(wmi_abi_version)); 12817 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12818 sizeof(wmi_abi_version)); 12819 12820 return QDF_STATUS_SUCCESS; 12821 } 12822 12823 /** 12824 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 12825 * @wmi_handle: wmi handle 12826 * @custom_addr: base mac address 12827 * 12828 * Return: QDF_STATUS_SUCCESS for success or error code 12829 */ 12830 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 12831 uint8_t *custom_addr) 12832 { 12833 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 12834 wmi_buf_t buf; 12835 int err; 12836 12837 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 12838 if (!buf) { 12839 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 12840 return QDF_STATUS_E_NOMEM; 12841 } 12842 12843 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 12844 qdf_mem_zero(cmd, sizeof(*cmd)); 12845 12846 WMITLV_SET_HDR(&cmd->tlv_header, 12847 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 12848 WMITLV_GET_STRUCT_TLVLEN 12849 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 12850 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 12851 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12852 WMI_HOST_PDEV_ID_SOC); 12853 err = wmi_unified_cmd_send(wmi_handle, buf, 12854 sizeof(*cmd), 12855 WMI_PDEV_SET_BASE_MACADDR_CMDID); 12856 if (err) { 12857 WMI_LOGE("Failed to send set_base_macaddr cmd"); 12858 wmi_buf_free(buf); 12859 return QDF_STATUS_E_FAILURE; 12860 } 12861 12862 return 0; 12863 } 12864 12865 /** 12866 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 12867 * @handle: wmi handle 12868 * @event: Event received from FW 12869 * @len: Length of the event 12870 * 12871 * Enables the low frequency events and disables the high frequency 12872 * events. Bit 17 indicates if the event if low/high frequency. 12873 * 1 - high frequency, 0 - low frequency 12874 * 12875 * Return: 0 on successfully enabling/disabling the events 12876 */ 12877 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 12878 uint8_t *event, 12879 uint32_t len) 12880 { 12881 uint32_t num_of_diag_events_logs; 12882 wmi_diag_event_log_config_fixed_param *cmd; 12883 wmi_buf_t buf; 12884 uint8_t *buf_ptr; 12885 uint32_t *cmd_args, *evt_args; 12886 uint32_t buf_len, i; 12887 12888 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 12889 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 12890 12891 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 12892 12893 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 12894 if (!param_buf) { 12895 WMI_LOGE("Invalid log supported event buffer"); 12896 return QDF_STATUS_E_INVAL; 12897 } 12898 wmi_event = param_buf->fixed_param; 12899 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 12900 12901 if (num_of_diag_events_logs > 12902 param_buf->num_diag_events_logs_list) { 12903 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 12904 num_of_diag_events_logs, 12905 param_buf->num_diag_events_logs_list); 12906 return QDF_STATUS_E_INVAL; 12907 } 12908 12909 evt_args = param_buf->diag_events_logs_list; 12910 if (!evt_args) { 12911 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 12912 __func__, num_of_diag_events_logs); 12913 return QDF_STATUS_E_INVAL; 12914 } 12915 12916 WMI_LOGD("%s: num_of_diag_events_logs=%d", 12917 __func__, num_of_diag_events_logs); 12918 12919 /* Free any previous allocation */ 12920 if (wmi_handle->events_logs_list) 12921 qdf_mem_free(wmi_handle->events_logs_list); 12922 12923 if (num_of_diag_events_logs > 12924 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 12925 WMI_LOGE("%s: excess num of logs:%d", __func__, 12926 num_of_diag_events_logs); 12927 QDF_ASSERT(0); 12928 return QDF_STATUS_E_INVAL; 12929 } 12930 /* Store the event list for run time enable/disable */ 12931 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 12932 sizeof(uint32_t)); 12933 if (!wmi_handle->events_logs_list) { 12934 WMI_LOGE("%s: event log list memory allocation failed", 12935 __func__); 12936 return QDF_STATUS_E_NOMEM; 12937 } 12938 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 12939 12940 /* Prepare the send buffer */ 12941 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12942 (num_of_diag_events_logs * sizeof(uint32_t)); 12943 12944 buf = wmi_buf_alloc(wmi_handle, buf_len); 12945 if (!buf) { 12946 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12947 qdf_mem_free(wmi_handle->events_logs_list); 12948 wmi_handle->events_logs_list = NULL; 12949 return QDF_STATUS_E_NOMEM; 12950 } 12951 12952 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 12953 buf_ptr = (uint8_t *) cmd; 12954 12955 WMITLV_SET_HDR(&cmd->tlv_header, 12956 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 12957 WMITLV_GET_STRUCT_TLVLEN( 12958 wmi_diag_event_log_config_fixed_param)); 12959 12960 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 12961 12962 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 12963 12964 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12965 (num_of_diag_events_logs * sizeof(uint32_t))); 12966 12967 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 12968 12969 /* Populate the events */ 12970 for (i = 0; i < num_of_diag_events_logs; i++) { 12971 /* Low freq (0) - Enable (1) the event 12972 * High freq (1) - Disable (0) the event 12973 */ 12974 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 12975 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 12976 /* Set the event ID */ 12977 WMI_DIAG_ID_SET(cmd_args[i], 12978 WMI_DIAG_ID_GET(evt_args[i])); 12979 /* Set the type */ 12980 WMI_DIAG_TYPE_SET(cmd_args[i], 12981 WMI_DIAG_TYPE_GET(evt_args[i])); 12982 /* Storing the event/log list in WMI */ 12983 wmi_handle->events_logs_list[i] = evt_args[i]; 12984 } 12985 12986 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 12987 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 12988 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 12989 __func__); 12990 wmi_buf_free(buf); 12991 /* Not clearing events_logs_list, though wmi cmd failed. 12992 * Host can still have this list 12993 */ 12994 return QDF_STATUS_E_INVAL; 12995 } 12996 12997 return 0; 12998 } 12999 13000 /** 13001 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13002 * @wmi_handle: wmi handle 13003 * @start_log: Start logging related parameters 13004 * 13005 * Send the command to the FW based on which specific logging of diag 13006 * event/log id can be started/stopped 13007 * 13008 * Return: None 13009 */ 13010 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13011 struct wmi_wifi_start_log *start_log) 13012 { 13013 wmi_diag_event_log_config_fixed_param *cmd; 13014 wmi_buf_t buf; 13015 uint8_t *buf_ptr; 13016 uint32_t len, count, log_level, i; 13017 uint32_t *cmd_args; 13018 uint32_t total_len; 13019 count = 0; 13020 13021 if (!wmi_handle->events_logs_list) { 13022 WMI_LOGE("%s: Not received event/log list from FW, yet", 13023 __func__); 13024 return QDF_STATUS_E_NOMEM; 13025 } 13026 /* total_len stores the number of events where BITS 17 and 18 are set. 13027 * i.e., events of high frequency (17) and for extended debugging (18) 13028 */ 13029 total_len = 0; 13030 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13031 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13032 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13033 total_len++; 13034 } 13035 13036 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13037 (total_len * sizeof(uint32_t)); 13038 13039 buf = wmi_buf_alloc(wmi_handle, len); 13040 if (!buf) { 13041 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13042 return QDF_STATUS_E_NOMEM; 13043 } 13044 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13045 buf_ptr = (uint8_t *) cmd; 13046 13047 WMITLV_SET_HDR(&cmd->tlv_header, 13048 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13049 WMITLV_GET_STRUCT_TLVLEN( 13050 wmi_diag_event_log_config_fixed_param)); 13051 13052 cmd->num_of_diag_events_logs = total_len; 13053 13054 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13055 13056 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13057 (total_len * sizeof(uint32_t))); 13058 13059 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13060 13061 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13062 log_level = 1; 13063 else 13064 log_level = 0; 13065 13066 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13067 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13068 uint32_t val = wmi_handle->events_logs_list[i]; 13069 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13070 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13071 13072 WMI_DIAG_ID_SET(cmd_args[count], 13073 WMI_DIAG_ID_GET(val)); 13074 WMI_DIAG_TYPE_SET(cmd_args[count], 13075 WMI_DIAG_TYPE_GET(val)); 13076 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13077 log_level); 13078 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13079 count++; 13080 } 13081 } 13082 13083 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13084 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13085 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13086 __func__); 13087 wmi_buf_free(buf); 13088 return QDF_STATUS_E_INVAL; 13089 } 13090 13091 return QDF_STATUS_SUCCESS; 13092 } 13093 13094 /** 13095 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13096 * @wmi_handle: WMI handle 13097 * 13098 * This function is used to send the flush command to the FW, 13099 * that will flush the fw logs that are residue in the FW 13100 * 13101 * Return: None 13102 */ 13103 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13104 { 13105 wmi_debug_mesg_flush_fixed_param *cmd; 13106 wmi_buf_t buf; 13107 int len = sizeof(*cmd); 13108 QDF_STATUS ret; 13109 13110 buf = wmi_buf_alloc(wmi_handle, len); 13111 if (!buf) { 13112 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13113 return QDF_STATUS_E_NOMEM; 13114 } 13115 13116 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13117 WMITLV_SET_HDR(&cmd->tlv_header, 13118 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13119 WMITLV_GET_STRUCT_TLVLEN( 13120 wmi_debug_mesg_flush_fixed_param)); 13121 cmd->reserved0 = 0; 13122 13123 ret = wmi_unified_cmd_send(wmi_handle, 13124 buf, 13125 len, 13126 WMI_DEBUG_MESG_FLUSH_CMDID); 13127 if (QDF_IS_STATUS_ERROR(ret)) { 13128 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13129 wmi_buf_free(buf); 13130 return QDF_STATUS_E_INVAL; 13131 } 13132 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13133 13134 return ret; 13135 } 13136 13137 /** 13138 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13139 * @wmi_handle: wmi handle 13140 * @msg: PCL structure containing the PCL and the number of channels 13141 * 13142 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13143 * firmware. The DBS Manager is the consumer of this information in the WLAN 13144 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13145 * to migrate to a new channel without host driver involvement. An example of 13146 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13147 * manage the channel selection without firmware involvement. 13148 * 13149 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13150 * channel list. The weights corresponds to the channels sent in 13151 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13152 * weightage compared to the non PCL channels. 13153 * 13154 * Return: Success if the cmd is sent successfully to the firmware 13155 */ 13156 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13157 struct wmi_pcl_chan_weights *msg) 13158 { 13159 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13160 wmi_buf_t buf; 13161 uint8_t *buf_ptr; 13162 uint32_t *cmd_args, i, len; 13163 uint32_t chan_len; 13164 13165 chan_len = msg->saved_num_chan; 13166 13167 len = sizeof(*cmd) + 13168 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13169 13170 buf = wmi_buf_alloc(wmi_handle, len); 13171 if (!buf) { 13172 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13173 return QDF_STATUS_E_NOMEM; 13174 } 13175 13176 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13177 buf_ptr = (uint8_t *) cmd; 13178 WMITLV_SET_HDR(&cmd->tlv_header, 13179 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13180 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13181 13182 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13183 WMI_HOST_PDEV_ID_SOC); 13184 cmd->num_chan = chan_len; 13185 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13186 13187 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13189 (chan_len * sizeof(uint32_t))); 13190 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13191 for (i = 0; i < chan_len ; i++) { 13192 cmd_args[i] = msg->weighed_valid_list[i]; 13193 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13194 msg->saved_chan_list[i], cmd_args[i]); 13195 } 13196 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13197 WMI_PDEV_SET_PCL_CMDID)) { 13198 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13199 wmi_buf_free(buf); 13200 return QDF_STATUS_E_FAILURE; 13201 } 13202 return QDF_STATUS_SUCCESS; 13203 } 13204 13205 /** 13206 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13207 * @wmi_handle: wmi handle 13208 * @msg: Structure containing the following parameters 13209 * 13210 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13211 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13212 * 13213 * Provides notification to the WLAN firmware that host driver is requesting a 13214 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13215 * configurations that include the Dual Band Simultaneous (DBS) feature. 13216 * 13217 * Return: Success if the cmd is sent successfully to the firmware 13218 */ 13219 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13220 uint32_t hw_mode_index) 13221 { 13222 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13223 wmi_buf_t buf; 13224 uint32_t len; 13225 13226 len = sizeof(*cmd); 13227 13228 buf = wmi_buf_alloc(wmi_handle, len); 13229 if (!buf) { 13230 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13231 return QDF_STATUS_E_NOMEM; 13232 } 13233 13234 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13235 WMITLV_SET_HDR(&cmd->tlv_header, 13236 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13237 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13238 13239 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13240 WMI_HOST_PDEV_ID_SOC); 13241 cmd->hw_mode_index = hw_mode_index; 13242 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13243 13244 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13245 WMI_PDEV_SET_HW_MODE_CMDID)) { 13246 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13247 __func__); 13248 wmi_buf_free(buf); 13249 return QDF_STATUS_E_FAILURE; 13250 } 13251 13252 return QDF_STATUS_SUCCESS; 13253 } 13254 13255 #ifdef WLAN_POLICY_MGR_ENABLE 13256 /** 13257 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13258 * @wmi_handle: wmi handle 13259 * @msg: Dual MAC config parameters 13260 * 13261 * Configures WLAN firmware with the dual MAC features 13262 * 13263 * Return: QDF_STATUS. 0 on success. 13264 */ 13265 static 13266 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13267 struct policy_mgr_dual_mac_config *msg) 13268 { 13269 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13270 wmi_buf_t buf; 13271 uint32_t len; 13272 13273 len = sizeof(*cmd); 13274 13275 buf = wmi_buf_alloc(wmi_handle, len); 13276 if (!buf) { 13277 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13278 return QDF_STATUS_E_FAILURE; 13279 } 13280 13281 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13282 WMITLV_SET_HDR(&cmd->tlv_header, 13283 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13284 WMITLV_GET_STRUCT_TLVLEN( 13285 wmi_pdev_set_mac_config_cmd_fixed_param)); 13286 13287 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13288 WMI_HOST_PDEV_ID_SOC); 13289 cmd->concurrent_scan_config_bits = msg->scan_config; 13290 cmd->fw_mode_config_bits = msg->fw_mode_config; 13291 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 13292 __func__, msg->scan_config, msg->fw_mode_config); 13293 13294 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13295 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13296 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13297 __func__); 13298 wmi_buf_free(buf); 13299 } 13300 return QDF_STATUS_SUCCESS; 13301 } 13302 #endif 13303 13304 #ifdef BIG_ENDIAN_HOST 13305 /** 13306 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13307 * @param data_len - data length 13308 * @param data - pointer to data 13309 * 13310 * Return: QDF_STATUS - success or error status 13311 */ 13312 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13313 struct fips_params *param) 13314 { 13315 unsigned char *key_unaligned, *data_unaligned; 13316 int c; 13317 u_int8_t *key_aligned = NULL; 13318 u_int8_t *data_aligned = NULL; 13319 13320 /* Assigning unaligned space to copy the key */ 13321 key_unaligned = qdf_mem_malloc( 13322 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 13323 data_unaligned = qdf_mem_malloc( 13324 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 13325 13326 /* Checking if kmalloc is successful to allocate space */ 13327 if (key_unaligned == NULL) 13328 return QDF_STATUS_SUCCESS; 13329 /* Checking if space is aligned */ 13330 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 13331 /* align to 4 */ 13332 key_aligned = 13333 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 13334 FIPS_ALIGN); 13335 } else { 13336 key_aligned = (u_int8_t *)key_unaligned; 13337 } 13338 13339 /* memset and copy content from key to key aligned */ 13340 OS_MEMSET(key_aligned, 0, param->key_len); 13341 OS_MEMCPY(key_aligned, param->key, param->key_len); 13342 13343 /* print a hexdump for host debug */ 13344 print_hex_dump(KERN_DEBUG, 13345 "\t Aligned and Copied Key:@@@@ ", 13346 DUMP_PREFIX_NONE, 13347 16, 1, key_aligned, param->key_len, true); 13348 13349 /* Checking if kmalloc is successful to allocate space */ 13350 if (data_unaligned == NULL) 13351 return QDF_STATUS_SUCCESS; 13352 /* Checking of space is aligned */ 13353 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13354 /* align to 4 */ 13355 data_aligned = 13356 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 13357 FIPS_ALIGN); 13358 } else { 13359 data_aligned = (u_int8_t *)data_unaligned; 13360 } 13361 13362 /* memset and copy content from data to data aligned */ 13363 OS_MEMSET(data_aligned, 0, param->data_len); 13364 OS_MEMCPY(data_aligned, param->data, param->data_len); 13365 13366 /* print a hexdump for host debug */ 13367 print_hex_dump(KERN_DEBUG, 13368 "\t Properly Aligned and Copied Data:@@@@ ", 13369 DUMP_PREFIX_NONE, 13370 16, 1, data_aligned, param->data_len, true); 13371 13372 /* converting to little Endian both key_aligned and 13373 * data_aligned*/ 13374 for (c = 0; c < param->key_len/4; c++) { 13375 *((u_int32_t *)key_aligned+c) = 13376 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 13377 } 13378 for (c = 0; c < param->data_len/4; c++) { 13379 *((u_int32_t *)data_aligned+c) = 13380 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 13381 } 13382 13383 /* update endian data to key and data vectors */ 13384 OS_MEMCPY(param->key, key_aligned, param->key_len); 13385 OS_MEMCPY(param->data, data_aligned, param->data_len); 13386 13387 /* clean up allocated spaces */ 13388 qdf_mem_free(key_unaligned); 13389 key_unaligned = NULL; 13390 key_aligned = NULL; 13391 13392 qdf_mem_free(data_unaligned); 13393 data_unaligned = NULL; 13394 data_aligned = NULL; 13395 13396 return QDF_STATUS_SUCCESS; 13397 } 13398 #else 13399 /** 13400 * fips_align_data_be() - DUMMY for LE platform 13401 * 13402 * Return: QDF_STATUS - success 13403 */ 13404 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13405 struct fips_params *param) 13406 { 13407 return QDF_STATUS_SUCCESS; 13408 } 13409 #endif 13410 13411 13412 /** 13413 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 13414 * @wmi_handle: wmi handle 13415 * @param: pointer to hold pdev fips param 13416 * 13417 * Return: 0 for success or error code 13418 */ 13419 static QDF_STATUS 13420 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 13421 struct fips_params *param) 13422 { 13423 wmi_pdev_fips_cmd_fixed_param *cmd; 13424 wmi_buf_t buf; 13425 uint8_t *buf_ptr; 13426 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 13427 QDF_STATUS retval = QDF_STATUS_SUCCESS; 13428 13429 /* Length TLV placeholder for array of bytes */ 13430 len += WMI_TLV_HDR_SIZE; 13431 if (param->data_len) 13432 len += (param->data_len*sizeof(uint8_t)); 13433 13434 /* 13435 * Data length must be multiples of 16 bytes - checked against 0xF - 13436 * and must be less than WMI_SVC_MSG_SIZE - static size of 13437 * wmi_pdev_fips_cmd structure 13438 */ 13439 13440 /* do sanity on the input */ 13441 if (!(((param->data_len & 0xF) == 0) && 13442 ((param->data_len > 0) && 13443 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 13444 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 13445 return QDF_STATUS_E_INVAL; 13446 } 13447 13448 buf = wmi_buf_alloc(wmi_handle, len); 13449 if (!buf) { 13450 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 13451 return QDF_STATUS_E_FAILURE; 13452 } 13453 13454 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13455 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 13456 WMITLV_SET_HDR(&cmd->tlv_header, 13457 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 13458 WMITLV_GET_STRUCT_TLVLEN 13459 (wmi_pdev_fips_cmd_fixed_param)); 13460 13461 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13462 param->pdev_id); 13463 if (param->key != NULL && param->data != NULL) { 13464 cmd->key_len = param->key_len; 13465 cmd->data_len = param->data_len; 13466 cmd->fips_cmd = !!(param->op); 13467 13468 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 13469 return QDF_STATUS_E_FAILURE; 13470 13471 qdf_mem_copy(cmd->key, param->key, param->key_len); 13472 13473 if (param->mode == FIPS_ENGINE_AES_CTR || 13474 param->mode == FIPS_ENGINE_AES_MIC) { 13475 cmd->mode = param->mode; 13476 } else { 13477 cmd->mode = FIPS_ENGINE_AES_CTR; 13478 } 13479 qdf_print(KERN_ERR "Key len = %d, Data len = %d\n", 13480 cmd->key_len, cmd->data_len); 13481 13482 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 13483 cmd->key, cmd->key_len, true); 13484 buf_ptr += sizeof(*cmd); 13485 13486 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 13487 13488 buf_ptr += WMI_TLV_HDR_SIZE; 13489 if (param->data_len) 13490 qdf_mem_copy(buf_ptr, 13491 (uint8_t *) param->data, param->data_len); 13492 13493 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 13494 16, 1, buf_ptr, cmd->data_len, true); 13495 13496 buf_ptr += param->data_len; 13497 13498 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 13499 WMI_PDEV_FIPS_CMDID); 13500 qdf_print("%s return value %d\n", __func__, retval); 13501 } else { 13502 qdf_print("\n%s:%d Key or Data is NULL\n", __func__, __LINE__); 13503 wmi_buf_free(buf); 13504 retval = -QDF_STATUS_E_BADMSG; 13505 } 13506 13507 return retval; 13508 } 13509 13510 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 13511 /** 13512 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 13513 * @wmi_handle: wmi handle 13514 * @vdev_id: vdev id 13515 * @bitmap: Event bitmap 13516 * @enable: enable/disable 13517 * 13518 * Return: CDF status 13519 */ 13520 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 13521 uint32_t vdev_id, 13522 uint32_t *bitmap, 13523 bool enable) 13524 { 13525 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 13526 uint16_t len; 13527 wmi_buf_t buf; 13528 int ret; 13529 13530 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 13531 buf = wmi_buf_alloc(wmi_handle, len); 13532 if (!buf) { 13533 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13534 return QDF_STATUS_E_NOMEM; 13535 } 13536 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 13537 WMITLV_SET_HDR(&cmd->tlv_header, 13538 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 13539 WMITLV_GET_STRUCT_TLVLEN 13540 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 13541 cmd->vdev_id = vdev_id; 13542 cmd->is_add = enable; 13543 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 13544 WMI_WOW_MAX_EVENT_BM_LEN); 13545 13546 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 13547 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 13548 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 13549 13550 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13551 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 13552 if (ret) { 13553 WMI_LOGE("Failed to config wow wakeup event"); 13554 wmi_buf_free(buf); 13555 return QDF_STATUS_E_FAILURE; 13556 } 13557 13558 return QDF_STATUS_SUCCESS; 13559 } 13560 13561 /** 13562 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 13563 * @wmi_handle: wmi handle 13564 * @vdev_id: vdev id 13565 * @ptrn_id: pattern id 13566 * @ptrn: pattern 13567 * @ptrn_len: pattern length 13568 * @ptrn_offset: pattern offset 13569 * @mask: mask 13570 * @mask_len: mask length 13571 * @user: true for user configured pattern and false for default pattern 13572 * @default_patterns: default patterns 13573 * 13574 * Return: CDF status 13575 */ 13576 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 13577 uint8_t vdev_id, uint8_t ptrn_id, 13578 const uint8_t *ptrn, uint8_t ptrn_len, 13579 uint8_t ptrn_offset, const uint8_t *mask, 13580 uint8_t mask_len, bool user, 13581 uint8_t default_patterns) 13582 { 13583 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13584 WOW_BITMAP_PATTERN_T *bitmap_pattern; 13585 wmi_buf_t buf; 13586 uint8_t *buf_ptr; 13587 int32_t len; 13588 int ret; 13589 13590 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13591 WMI_TLV_HDR_SIZE + 13592 1 * sizeof(WOW_BITMAP_PATTERN_T) + 13593 WMI_TLV_HDR_SIZE + 13594 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13595 WMI_TLV_HDR_SIZE + 13596 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13597 WMI_TLV_HDR_SIZE + 13598 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13599 WMI_TLV_HDR_SIZE + 13600 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13601 13602 buf = wmi_buf_alloc(wmi_handle, len); 13603 if (!buf) { 13604 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13605 return QDF_STATUS_E_NOMEM; 13606 } 13607 13608 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13609 buf_ptr = (uint8_t *) cmd; 13610 13611 WMITLV_SET_HDR(&cmd->tlv_header, 13612 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13613 WMITLV_GET_STRUCT_TLVLEN 13614 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13615 cmd->vdev_id = vdev_id; 13616 cmd->pattern_id = ptrn_id; 13617 13618 cmd->pattern_type = WOW_BITMAP_PATTERN; 13619 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13620 13621 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13622 sizeof(WOW_BITMAP_PATTERN_T)); 13623 buf_ptr += WMI_TLV_HDR_SIZE; 13624 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 13625 13626 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 13627 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 13628 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 13629 13630 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 13631 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 13632 13633 bitmap_pattern->pattern_offset = ptrn_offset; 13634 bitmap_pattern->pattern_len = ptrn_len; 13635 13636 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 13637 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 13638 13639 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 13640 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 13641 13642 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 13643 bitmap_pattern->pattern_id = ptrn_id; 13644 13645 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 13646 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 13647 bitmap_pattern->pattern_offset, user); 13648 WMI_LOGI("Pattern : "); 13649 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13650 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 13651 13652 WMI_LOGI("Mask : "); 13653 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13654 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 13655 13656 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 13657 13658 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 13659 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13660 buf_ptr += WMI_TLV_HDR_SIZE; 13661 13662 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 13663 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13664 buf_ptr += WMI_TLV_HDR_SIZE; 13665 13666 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 13667 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13668 buf_ptr += WMI_TLV_HDR_SIZE; 13669 13670 /* Fill TLV for pattern_info_timeout but no data. */ 13671 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 13672 buf_ptr += WMI_TLV_HDR_SIZE; 13673 13674 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 13675 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 13676 buf_ptr += WMI_TLV_HDR_SIZE; 13677 *(uint32_t *) buf_ptr = 0; 13678 13679 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13680 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 13681 if (ret) { 13682 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 13683 wmi_buf_free(buf); 13684 return QDF_STATUS_E_FAILURE; 13685 } 13686 13687 return QDF_STATUS_SUCCESS; 13688 } 13689 13690 /** 13691 * fill_arp_offload_params_tlv() - Fill ARP offload data 13692 * @wmi_handle: wmi handle 13693 * @offload_req: offload request 13694 * @buf_ptr: buffer pointer 13695 * 13696 * To fill ARP offload data to firmware 13697 * when target goes to wow mode. 13698 * 13699 * Return: None 13700 */ 13701 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 13702 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 13703 { 13704 13705 int i; 13706 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 13707 bool enable_or_disable = offload_req->enable; 13708 13709 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13710 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 13711 *buf_ptr += WMI_TLV_HDR_SIZE; 13712 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 13713 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 13714 WMITLV_SET_HDR(&arp_tuple->tlv_header, 13715 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 13716 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 13717 13718 /* Fill data for ARP and NS in the first tupple for LA */ 13719 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 13720 /* Copy the target ip addr and flags */ 13721 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 13722 qdf_mem_copy(&arp_tuple->target_ipaddr, 13723 offload_req->host_ipv4_addr, 13724 WMI_IPV4_ADDR_LEN); 13725 WMI_LOGD("ARPOffload IP4 address: %pI4", 13726 offload_req->host_ipv4_addr); 13727 } 13728 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 13729 } 13730 } 13731 13732 #ifdef WLAN_NS_OFFLOAD 13733 /** 13734 * fill_ns_offload_params_tlv() - Fill NS offload data 13735 * @wmi|_handle: wmi handle 13736 * @offload_req: offload request 13737 * @buf_ptr: buffer pointer 13738 * 13739 * To fill NS offload data to firmware 13740 * when target goes to wow mode. 13741 * 13742 * Return: None 13743 */ 13744 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13745 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13746 { 13747 13748 int i; 13749 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13750 13751 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13752 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13753 *buf_ptr += WMI_TLV_HDR_SIZE; 13754 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 13755 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13756 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13757 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13758 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 13759 13760 /* 13761 * Fill data only for NS offload in the first ARP tuple for LA 13762 */ 13763 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13764 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13765 /* Copy the target/solicitation/remote ip addr */ 13766 if (ns_req->target_ipv6_addr_valid[i]) 13767 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13768 &ns_req->target_ipv6_addr[i], 13769 sizeof(WMI_IPV6_ADDR)); 13770 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13771 &ns_req->self_ipv6_addr[i], 13772 sizeof(WMI_IPV6_ADDR)); 13773 if (ns_req->target_ipv6_addr_ac_type[i]) { 13774 ns_tuple->flags |= 13775 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13776 } 13777 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13778 i, &ns_req->self_ipv6_addr[i], 13779 &ns_req->target_ipv6_addr[i]); 13780 13781 /* target MAC is optional, check if it is valid, 13782 * if this is not valid, the target will use the known 13783 * local MAC address rather than the tuple 13784 */ 13785 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13786 ns_req->self_macaddr.bytes, 13787 &ns_tuple->target_mac); 13788 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13789 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13790 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13791 } 13792 } 13793 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13794 } 13795 } 13796 13797 13798 /** 13799 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 13800 * @wmi: wmi handle 13801 * @offload_req: offload request 13802 * @buf_ptr: buffer pointer 13803 * 13804 * To fill extended NS offload extended data to firmware 13805 * when target goes to wow mode. 13806 * 13807 * Return: None 13808 */ 13809 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13810 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13811 { 13812 int i; 13813 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13814 uint32_t count, num_ns_ext_tuples; 13815 13816 count = ns_req->num_ns_offload_count; 13817 num_ns_ext_tuples = ns_req->num_ns_offload_count - 13818 WMI_MAX_NS_OFFLOADS; 13819 13820 /* Populate extended NS offload tuples */ 13821 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13822 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13823 *buf_ptr += WMI_TLV_HDR_SIZE; 13824 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 13825 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13826 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13827 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13828 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 13829 13830 /* 13831 * Fill data only for NS offload in the first ARP tuple for LA 13832 */ 13833 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13834 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13835 /* Copy the target/solicitation/remote ip addr */ 13836 if (ns_req->target_ipv6_addr_valid[i]) 13837 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13838 &ns_req->target_ipv6_addr[i], 13839 sizeof(WMI_IPV6_ADDR)); 13840 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13841 &ns_req->self_ipv6_addr[i], 13842 sizeof(WMI_IPV6_ADDR)); 13843 if (ns_req->target_ipv6_addr_ac_type[i]) { 13844 ns_tuple->flags |= 13845 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13846 } 13847 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13848 i, &ns_req->self_ipv6_addr[i], 13849 &ns_req->target_ipv6_addr[i]); 13850 13851 /* target MAC is optional, check if it is valid, 13852 * if this is not valid, the target will use the 13853 * known local MAC address rather than the tuple 13854 */ 13855 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13856 ns_req->self_macaddr.bytes, 13857 &ns_tuple->target_mac); 13858 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13859 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13860 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13861 } 13862 } 13863 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13864 } 13865 } 13866 #else 13867 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13868 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13869 { 13870 } 13871 13872 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13873 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13874 { 13875 } 13876 #endif 13877 13878 /** 13879 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 13880 * @wma: wmi handle 13881 * @arp_offload_req: arp offload request 13882 * @ns_offload_req: ns offload request 13883 * @arp_only: flag 13884 * 13885 * To configure ARP NS off load data to firmware 13886 * when target goes to wow mode. 13887 * 13888 * Return: QDF Status 13889 */ 13890 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 13891 struct pmo_arp_offload_params *arp_offload_req, 13892 struct pmo_ns_offload_params *ns_offload_req, 13893 uint8_t vdev_id) 13894 { 13895 int32_t res; 13896 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 13897 uint8_t *buf_ptr; 13898 wmi_buf_t buf; 13899 int32_t len; 13900 uint32_t count = 0, num_ns_ext_tuples = 0; 13901 13902 count = ns_offload_req->num_ns_offload_count; 13903 13904 /* 13905 * TLV place holder size for array of NS tuples 13906 * TLV place holder size for array of ARP tuples 13907 */ 13908 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 13909 WMI_TLV_HDR_SIZE + 13910 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 13911 WMI_TLV_HDR_SIZE + 13912 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 13913 13914 /* 13915 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 13916 * extra length for extended NS offload tuples which follows ARP offload 13917 * tuples. Host needs to fill this structure in following format: 13918 * 2 NS ofload tuples 13919 * 2 ARP offload tuples 13920 * N numbers of extended NS offload tuples if HDD has given more than 13921 * 2 NS offload addresses 13922 */ 13923 if (count > WMI_MAX_NS_OFFLOADS) { 13924 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 13925 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 13926 * sizeof(WMI_NS_OFFLOAD_TUPLE); 13927 } 13928 13929 buf = wmi_buf_alloc(wmi_handle, len); 13930 if (!buf) { 13931 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13932 return QDF_STATUS_E_NOMEM; 13933 } 13934 13935 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13936 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 13937 WMITLV_SET_HDR(&cmd->tlv_header, 13938 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 13939 WMITLV_GET_STRUCT_TLVLEN 13940 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 13941 cmd->flags = 0; 13942 cmd->vdev_id = vdev_id; 13943 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 13944 13945 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 13946 13947 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 13948 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13949 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 13950 if (num_ns_ext_tuples) 13951 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13952 13953 res = wmi_unified_cmd_send(wmi_handle, buf, len, 13954 WMI_SET_ARP_NS_OFFLOAD_CMDID); 13955 if (res) { 13956 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 13957 wmi_buf_free(buf); 13958 return QDF_STATUS_E_FAILURE; 13959 } 13960 13961 return QDF_STATUS_SUCCESS; 13962 } 13963 13964 /** 13965 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 13966 * @wmi_handle: wmi handle 13967 * @vdev_id: vdev id 13968 * @action: true for enable else false 13969 * 13970 * To enable enhance multicast offload to firmware 13971 * when target goes to wow mode. 13972 * 13973 * Return: QDF Status 13974 */ 13975 13976 static 13977 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 13978 wmi_unified_t wmi_handle, 13979 uint8_t vdev_id, bool action) 13980 { 13981 QDF_STATUS status; 13982 wmi_buf_t buf; 13983 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 13984 13985 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13986 if (!buf) { 13987 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 13988 return QDF_STATUS_E_NOMEM; 13989 } 13990 13991 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 13992 wmi_buf_data(buf); 13993 13994 WMITLV_SET_HDR(&cmd->tlv_header, 13995 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 13996 WMITLV_GET_STRUCT_TLVLEN( 13997 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 13998 13999 cmd->vdev_id = vdev_id; 14000 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14001 ENHANCED_MCAST_FILTER_ENABLED); 14002 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14003 __func__, action, vdev_id); 14004 status = wmi_unified_cmd_send(wmi_handle, buf, 14005 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14006 if (status != QDF_STATUS_SUCCESS) { 14007 qdf_nbuf_free(buf); 14008 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14009 __func__); 14010 } 14011 14012 return status; 14013 } 14014 14015 /** 14016 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14017 * @wmi_handle: wmi handle 14018 * @param evt_buf: pointer to event buffer 14019 * @param hdr: Pointer to hold header 14020 * @param bufp: Pointer to hold pointer to rx param buffer 14021 * 14022 * Return: QDF_STATUS_SUCCESS for success or error code 14023 */ 14024 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14025 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14026 { 14027 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14028 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14029 14030 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14031 if (!param_buf) { 14032 WMI_LOGE("gtk param_buf is NULL"); 14033 return QDF_STATUS_E_INVAL; 14034 } 14035 14036 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14037 WMI_LOGE("Invalid length for GTK status"); 14038 return QDF_STATUS_E_INVAL; 14039 } 14040 14041 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14042 param_buf->fixed_param; 14043 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14044 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14045 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14046 qdf_mem_copy(>k_rsp_param->replay_counter, 14047 &fixed_param->replay_counter, 14048 GTK_REPLAY_COUNTER_BYTES); 14049 14050 return QDF_STATUS_SUCCESS; 14051 14052 } 14053 14054 #ifdef FEATURE_WLAN_RA_FILTERING 14055 /** 14056 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14057 * @wmi_handle: wmi handle 14058 * @vdev_id: vdev id 14059 * 14060 * Return: CDF status 14061 */ 14062 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14063 uint8_t vdev_id, uint8_t default_pattern, 14064 uint16_t rate_limit_interval) 14065 { 14066 14067 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14068 wmi_buf_t buf; 14069 uint8_t *buf_ptr; 14070 int32_t len; 14071 int ret; 14072 14073 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14074 WMI_TLV_HDR_SIZE + 14075 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14076 WMI_TLV_HDR_SIZE + 14077 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14078 WMI_TLV_HDR_SIZE + 14079 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14080 WMI_TLV_HDR_SIZE + 14081 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14082 WMI_TLV_HDR_SIZE + 14083 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14084 14085 buf = wmi_buf_alloc(wmi_handle, len); 14086 if (!buf) { 14087 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14088 return QDF_STATUS_E_NOMEM; 14089 } 14090 14091 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14092 buf_ptr = (uint8_t *) cmd; 14093 14094 WMITLV_SET_HDR(&cmd->tlv_header, 14095 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14096 WMITLV_GET_STRUCT_TLVLEN 14097 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14098 cmd->vdev_id = vdev_id; 14099 cmd->pattern_id = default_pattern, 14100 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14101 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14102 14103 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14104 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14105 buf_ptr += WMI_TLV_HDR_SIZE; 14106 14107 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14108 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14109 buf_ptr += WMI_TLV_HDR_SIZE; 14110 14111 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14112 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14113 buf_ptr += WMI_TLV_HDR_SIZE; 14114 14115 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14116 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14117 buf_ptr += WMI_TLV_HDR_SIZE; 14118 14119 /* Fill TLV for pattern_info_timeout but no data. */ 14120 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14121 buf_ptr += WMI_TLV_HDR_SIZE; 14122 14123 /* Fill TLV for ra_ratelimit_interval. */ 14124 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14125 buf_ptr += WMI_TLV_HDR_SIZE; 14126 14127 *((uint32_t *) buf_ptr) = rate_limit_interval; 14128 14129 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14130 rate_limit_interval, vdev_id); 14131 14132 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14133 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14134 if (ret) { 14135 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14136 wmi_buf_free(buf); 14137 return QDF_STATUS_E_FAILURE; 14138 } 14139 14140 return QDF_STATUS_SUCCESS; 14141 14142 } 14143 #endif /* FEATURE_WLAN_RA_FILTERING */ 14144 14145 /** 14146 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14147 * @wmi_handle: wmi handle 14148 * @vdev_id: vdev id 14149 * @multicastAddr: mcast address 14150 * @clearList: clear list flag 14151 * 14152 * Return: QDF_STATUS_SUCCESS for success or error code 14153 */ 14154 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14155 uint8_t vdev_id, 14156 struct qdf_mac_addr multicast_addr, 14157 bool clearList) 14158 { 14159 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14160 wmi_buf_t buf; 14161 int err; 14162 14163 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14164 if (!buf) { 14165 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14166 return QDF_STATUS_E_NOMEM; 14167 } 14168 14169 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14170 qdf_mem_zero(cmd, sizeof(*cmd)); 14171 14172 WMITLV_SET_HDR(&cmd->tlv_header, 14173 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14174 WMITLV_GET_STRUCT_TLVLEN 14175 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14176 cmd->action = 14177 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14178 cmd->vdev_id = vdev_id; 14179 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14180 14181 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14182 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14183 14184 err = wmi_unified_cmd_send(wmi_handle, buf, 14185 sizeof(*cmd), 14186 WMI_SET_MCASTBCAST_FILTER_CMDID); 14187 if (err) { 14188 WMI_LOGE("Failed to send set_param cmd"); 14189 wmi_buf_free(buf); 14190 return QDF_STATUS_E_FAILURE; 14191 } 14192 14193 return QDF_STATUS_SUCCESS; 14194 } 14195 14196 /** 14197 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14198 * command to fw 14199 * @wmi_handle: wmi handle 14200 * @vdev_id: vdev id 14201 * @mcast_filter_params: mcast filter params 14202 * 14203 * Return: QDF_STATUS_SUCCESS for success or error code 14204 */ 14205 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14206 wmi_unified_t wmi_handle, 14207 uint8_t vdev_id, 14208 struct pmo_mcast_filter_params *filter_param) 14209 14210 { 14211 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14212 uint8_t *buf_ptr; 14213 wmi_buf_t buf; 14214 int err; 14215 int i; 14216 uint8_t *mac_addr_src_ptr = NULL; 14217 wmi_mac_addr *mac_addr_dst_ptr; 14218 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14219 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14220 14221 buf = wmi_buf_alloc(wmi_handle, len); 14222 if (!buf) { 14223 WMI_LOGE("Failed to allocate memory"); 14224 return QDF_STATUS_E_NOMEM; 14225 } 14226 14227 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14228 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14229 wmi_buf_data(buf); 14230 qdf_mem_zero(cmd, sizeof(*cmd)); 14231 14232 WMITLV_SET_HDR(&cmd->tlv_header, 14233 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14234 WMITLV_GET_STRUCT_TLVLEN 14235 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14236 cmd->operation = 14237 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14238 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14239 cmd->vdev_id = vdev_id; 14240 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14241 14242 buf_ptr += sizeof(*cmd); 14243 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14244 sizeof(wmi_mac_addr) * 14245 filter_param->multicast_addr_cnt); 14246 14247 if (filter_param->multicast_addr_cnt == 0) 14248 goto send_cmd; 14249 14250 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14251 mac_addr_dst_ptr = (wmi_mac_addr *) 14252 (buf_ptr + WMI_TLV_HDR_SIZE); 14253 14254 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14255 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14256 mac_addr_src_ptr += ATH_MAC_LEN; 14257 mac_addr_dst_ptr++; 14258 } 14259 14260 send_cmd: 14261 err = wmi_unified_cmd_send(wmi_handle, buf, 14262 len, 14263 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14264 if (err) { 14265 WMI_LOGE("Failed to send set_param cmd"); 14266 wmi_buf_free(buf); 14267 return QDF_STATUS_E_FAILURE; 14268 } 14269 14270 return QDF_STATUS_SUCCESS; 14271 } 14272 14273 14274 /** 14275 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14276 * @wmi_handle: wmi handle 14277 * @vdev_id: vdev id 14278 * @params: GTK offload parameters 14279 * 14280 * Return: CDF status 14281 */ 14282 static 14283 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14284 struct pmo_gtk_req *params, 14285 bool enable_offload, 14286 uint32_t gtk_offload_opcode) 14287 { 14288 int len; 14289 wmi_buf_t buf; 14290 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14291 wmi_gtk_offload_fils_tlv_param *ext_param; 14292 QDF_STATUS status = QDF_STATUS_SUCCESS; 14293 uint8_t *buf_ptr; 14294 14295 WMI_LOGD("%s Enter", __func__); 14296 14297 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*ext_param); 14298 14299 /* alloc wmi buffer */ 14300 buf = wmi_buf_alloc(wmi_handle, len); 14301 if (!buf) { 14302 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14303 status = QDF_STATUS_E_NOMEM; 14304 goto out; 14305 } 14306 14307 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14308 buf_ptr = (uint8_t *)cmd; 14309 WMITLV_SET_HDR(&cmd->tlv_header, 14310 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14311 WMITLV_GET_STRUCT_TLVLEN 14312 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14313 14314 cmd->vdev_id = vdev_id; 14315 14316 /* Request target to enable GTK offload */ 14317 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 14318 cmd->flags = gtk_offload_opcode; 14319 14320 /* Copy the keys and replay counter */ 14321 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 14322 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 14323 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 14324 GTK_REPLAY_COUNTER_BYTES); 14325 } else { 14326 cmd->flags = gtk_offload_opcode; 14327 } 14328 14329 buf_ptr += sizeof(*cmd); 14330 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(*ext_param)); 14331 buf_ptr += WMI_TLV_HDR_SIZE; 14332 14333 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 14334 WMITLV_SET_HDR(&ext_param->tlv_header, 14335 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 14336 WMITLV_GET_STRUCT_TLVLEN( 14337 wmi_gtk_offload_fils_tlv_param)); 14338 ext_param->vdev_id = vdev_id; 14339 ext_param->flags = cmd->flags; 14340 ext_param->kek_len = params->kek_len; 14341 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 14342 qdf_mem_copy(ext_param->KCK, params->kck, WMI_GTK_OFFLOAD_KCK_BYTES); 14343 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 14344 GTK_REPLAY_COUNTER_BYTES); 14345 14346 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 14347 /* send the wmi command */ 14348 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14349 WMI_GTK_OFFLOAD_CMDID)) { 14350 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 14351 wmi_buf_free(buf); 14352 status = QDF_STATUS_E_FAILURE; 14353 } 14354 14355 out: 14356 WMI_LOGD("%s Exit", __func__); 14357 return status; 14358 } 14359 14360 /** 14361 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 14362 * @wmi_handle: wmi handle 14363 * @params: GTK offload params 14364 * 14365 * Return: CDF status 14366 */ 14367 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 14368 wmi_unified_t wmi_handle, 14369 uint8_t vdev_id, 14370 uint64_t offload_req_opcode) 14371 { 14372 int len; 14373 wmi_buf_t buf; 14374 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14375 QDF_STATUS status = QDF_STATUS_SUCCESS; 14376 14377 len = sizeof(*cmd); 14378 14379 /* alloc wmi buffer */ 14380 buf = wmi_buf_alloc(wmi_handle, len); 14381 if (!buf) { 14382 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14383 status = QDF_STATUS_E_NOMEM; 14384 goto out; 14385 } 14386 14387 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14388 WMITLV_SET_HDR(&cmd->tlv_header, 14389 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14390 WMITLV_GET_STRUCT_TLVLEN 14391 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14392 14393 /* Request for GTK offload status */ 14394 cmd->flags = offload_req_opcode; 14395 cmd->vdev_id = vdev_id; 14396 14397 /* send the wmi command */ 14398 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14399 WMI_GTK_OFFLOAD_CMDID)) { 14400 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 14401 wmi_buf_free(buf); 14402 status = QDF_STATUS_E_FAILURE; 14403 } 14404 14405 out: 14406 return status; 14407 } 14408 14409 /** 14410 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 14411 * @wmi_handle: wmi handler 14412 * @action_params: pointer to action_params 14413 * 14414 * Return: 0 for success, otherwise appropriate error code 14415 */ 14416 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 14417 struct pmo_action_wakeup_set_params *action_params) 14418 { 14419 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 14420 wmi_buf_t buf; 14421 int i; 14422 int32_t err; 14423 uint32_t len = 0, *cmd_args; 14424 uint8_t *buf_ptr; 14425 14426 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 14427 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 14428 buf = wmi_buf_alloc(wmi_handle, len); 14429 if (!buf) { 14430 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 14431 return QDF_STATUS_E_NOMEM; 14432 } 14433 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 14434 buf_ptr = (uint8_t *)cmd; 14435 WMITLV_SET_HDR(&cmd->tlv_header, 14436 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 14437 WMITLV_GET_STRUCT_TLVLEN( 14438 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 14439 14440 cmd->vdev_id = action_params->vdev_id; 14441 cmd->operation = action_params->operation; 14442 14443 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 14444 cmd->action_category_map[i] = 14445 action_params->action_category_map[i]; 14446 14447 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 14448 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14449 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 14450 buf_ptr += WMI_TLV_HDR_SIZE; 14451 cmd_args = (uint32_t *) buf_ptr; 14452 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 14453 cmd_args[i] = action_params->action_per_category[i]; 14454 14455 err = wmi_unified_cmd_send(wmi_handle, buf, 14456 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 14457 if (err) { 14458 WMI_LOGE("Failed to send ap_ps_egap cmd"); 14459 wmi_buf_free(buf); 14460 return QDF_STATUS_E_FAILURE; 14461 } 14462 14463 return QDF_STATUS_SUCCESS; 14464 } 14465 14466 #ifdef FEATURE_WLAN_LPHB 14467 14468 /** 14469 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 14470 * @wmi_handle: wmi handle 14471 * @lphb_conf_req: configuration info 14472 * 14473 * Return: CDF status 14474 */ 14475 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 14476 wmi_hb_set_enable_cmd_fixed_param *params) 14477 { 14478 QDF_STATUS status; 14479 wmi_buf_t buf = NULL; 14480 uint8_t *buf_ptr; 14481 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 14482 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 14483 14484 14485 buf = wmi_buf_alloc(wmi_handle, len); 14486 if (!buf) { 14487 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14488 return QDF_STATUS_E_NOMEM; 14489 } 14490 14491 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14492 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 14493 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 14494 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 14495 WMITLV_GET_STRUCT_TLVLEN 14496 (wmi_hb_set_enable_cmd_fixed_param)); 14497 14498 /* fill in values */ 14499 hb_enable_fp->vdev_id = params->session; 14500 hb_enable_fp->enable = params->enable; 14501 hb_enable_fp->item = params->item; 14502 hb_enable_fp->session = params->session; 14503 14504 status = wmi_unified_cmd_send(wmi_handle, buf, 14505 len, WMI_HB_SET_ENABLE_CMDID); 14506 if (QDF_IS_STATUS_ERROR(status)) { 14507 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 14508 status); 14509 wmi_buf_free(buf); 14510 } 14511 14512 return status; 14513 } 14514 14515 /** 14516 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 14517 * @wmi_handle: wmi handle 14518 * @lphb_conf_req: lphb config request 14519 * 14520 * Return: CDF status 14521 */ 14522 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 14523 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 14524 { 14525 QDF_STATUS status; 14526 wmi_buf_t buf = NULL; 14527 uint8_t *buf_ptr; 14528 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 14529 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 14530 14531 buf = wmi_buf_alloc(wmi_handle, len); 14532 if (!buf) { 14533 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14534 return QDF_STATUS_E_NOMEM; 14535 } 14536 14537 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14538 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 14539 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 14540 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 14541 WMITLV_GET_STRUCT_TLVLEN 14542 (wmi_hb_set_tcp_params_cmd_fixed_param)); 14543 14544 /* fill in values */ 14545 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14546 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14547 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14548 hb_tcp_params_fp->seq = lphb_conf_req->seq; 14549 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 14550 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 14551 hb_tcp_params_fp->interval = lphb_conf_req->interval; 14552 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 14553 hb_tcp_params_fp->session = lphb_conf_req->session; 14554 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 14555 &lphb_conf_req->gateway_mac, 14556 sizeof(hb_tcp_params_fp->gateway_mac)); 14557 14558 status = wmi_unified_cmd_send(wmi_handle, buf, 14559 len, WMI_HB_SET_TCP_PARAMS_CMDID); 14560 if (QDF_IS_STATUS_ERROR(status)) { 14561 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 14562 status); 14563 wmi_buf_free(buf); 14564 } 14565 14566 return status; 14567 } 14568 14569 /** 14570 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 14571 * @wmi_handle: wmi handle 14572 * @lphb_conf_req: lphb config request 14573 * 14574 * Return: CDF status 14575 */ 14576 static 14577 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14578 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 14579 { 14580 QDF_STATUS status; 14581 wmi_buf_t buf = NULL; 14582 uint8_t *buf_ptr; 14583 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 14584 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 14585 14586 buf = wmi_buf_alloc(wmi_handle, len); 14587 if (!buf) { 14588 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14589 return QDF_STATUS_E_NOMEM; 14590 } 14591 14592 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14593 hb_tcp_filter_fp = 14594 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 14595 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 14596 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 14597 WMITLV_GET_STRUCT_TLVLEN 14598 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 14599 14600 /* fill in values */ 14601 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 14602 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 14603 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 14604 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 14605 memcpy((void *)&hb_tcp_filter_fp->filter, 14606 (void *)&g_hb_tcp_filter_fp->filter, 14607 WMI_WLAN_HB_MAX_FILTER_SIZE); 14608 14609 status = wmi_unified_cmd_send(wmi_handle, buf, 14610 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 14611 if (QDF_IS_STATUS_ERROR(status)) { 14612 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 14613 status); 14614 wmi_buf_free(buf); 14615 } 14616 14617 return status; 14618 } 14619 14620 /** 14621 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 14622 * @wmi_handle: wmi handle 14623 * @lphb_conf_req: lphb config request 14624 * 14625 * Return: CDF status 14626 */ 14627 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 14628 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 14629 { 14630 QDF_STATUS status; 14631 wmi_buf_t buf = NULL; 14632 uint8_t *buf_ptr; 14633 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 14634 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 14635 14636 buf = wmi_buf_alloc(wmi_handle, len); 14637 if (!buf) { 14638 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14639 return QDF_STATUS_E_NOMEM; 14640 } 14641 14642 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14643 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 14644 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 14645 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 14646 WMITLV_GET_STRUCT_TLVLEN 14647 (wmi_hb_set_udp_params_cmd_fixed_param)); 14648 14649 /* fill in values */ 14650 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14651 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14652 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14653 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 14654 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 14655 hb_udp_params_fp->interval = lphb_conf_req->interval; 14656 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 14657 hb_udp_params_fp->session = lphb_conf_req->session; 14658 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 14659 &lphb_conf_req->gateway_mac, 14660 sizeof(lphb_conf_req->gateway_mac)); 14661 14662 status = wmi_unified_cmd_send(wmi_handle, buf, 14663 len, WMI_HB_SET_UDP_PARAMS_CMDID); 14664 if (QDF_IS_STATUS_ERROR(status)) { 14665 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 14666 status); 14667 wmi_buf_free(buf); 14668 } 14669 14670 return status; 14671 } 14672 14673 /** 14674 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 14675 * @wmi_handle: wmi handle 14676 * @lphb_conf_req: lphb config request 14677 * 14678 * Return: CDF status 14679 */ 14680 static 14681 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14682 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 14683 { 14684 QDF_STATUS status; 14685 wmi_buf_t buf = NULL; 14686 uint8_t *buf_ptr; 14687 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 14688 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 14689 14690 buf = wmi_buf_alloc(wmi_handle, len); 14691 if (!buf) { 14692 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14693 return QDF_STATUS_E_NOMEM; 14694 } 14695 14696 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14697 hb_udp_filter_fp = 14698 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 14699 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 14700 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 14701 WMITLV_GET_STRUCT_TLVLEN 14702 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 14703 14704 /* fill in values */ 14705 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 14706 hb_udp_filter_fp->length = lphb_conf_req->length; 14707 hb_udp_filter_fp->offset = lphb_conf_req->offset; 14708 hb_udp_filter_fp->session = lphb_conf_req->session; 14709 memcpy((void *)&hb_udp_filter_fp->filter, 14710 (void *)&lphb_conf_req->filter, 14711 WMI_WLAN_HB_MAX_FILTER_SIZE); 14712 14713 status = wmi_unified_cmd_send(wmi_handle, buf, 14714 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 14715 if (QDF_IS_STATUS_ERROR(status)) { 14716 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 14717 status); 14718 wmi_buf_free(buf); 14719 } 14720 14721 return status; 14722 } 14723 #endif /* FEATURE_WLAN_LPHB */ 14724 14725 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 14726 struct pmo_hw_filter_params *req) 14727 { 14728 QDF_STATUS status; 14729 wmi_hw_data_filter_cmd_fixed_param *cmd; 14730 wmi_buf_t wmi_buf; 14731 14732 if (!req) { 14733 WMI_LOGE("req is null"); 14734 return QDF_STATUS_E_INVAL; 14735 } 14736 14737 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 14738 if (!wmi_buf) { 14739 WMI_LOGE(FL("Out of memory")); 14740 return QDF_STATUS_E_NOMEM; 14741 } 14742 14743 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 14744 WMITLV_SET_HDR(&cmd->tlv_header, 14745 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 14746 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 14747 cmd->vdev_id = req->vdev_id; 14748 cmd->enable = req->enable; 14749 /* Set all modes in case of disable */ 14750 if (!cmd->enable) 14751 cmd->hw_filter_bitmap = ((uint32_t)~0U); 14752 else 14753 cmd->hw_filter_bitmap = req->mode_bitmap; 14754 14755 WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d", 14756 req->enable ? "enable" : "disable", req->mode_bitmap, 14757 req->vdev_id); 14758 14759 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 14760 WMI_HW_DATA_FILTER_CMDID); 14761 if (QDF_IS_STATUS_ERROR(status)) { 14762 WMI_LOGE("Failed to configure hw filter"); 14763 wmi_buf_free(wmi_buf); 14764 } 14765 14766 return status; 14767 } 14768 14769 /** 14770 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 14771 * @wmi_handle: wmi handle 14772 * @vdev_id: vdev id 14773 * @enable: Flag to enable/disable packet filter 14774 * 14775 * Return: QDF_STATUS_SUCCESS for success or error code 14776 */ 14777 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 14778 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 14779 { 14780 int32_t len; 14781 int ret = 0; 14782 wmi_buf_t buf; 14783 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 14784 14785 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 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_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 14794 WMITLV_SET_HDR(&cmd->tlv_header, 14795 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 14796 WMITLV_GET_STRUCT_TLVLEN( 14797 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 14798 14799 cmd->vdev_id = vdev_id; 14800 if (enable) 14801 cmd->enable = PACKET_FILTER_SET_ENABLE; 14802 else 14803 cmd->enable = PACKET_FILTER_SET_DISABLE; 14804 14805 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 14806 __func__, cmd->enable, vdev_id); 14807 14808 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14809 WMI_PACKET_FILTER_ENABLE_CMDID); 14810 if (ret) { 14811 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 14812 wmi_buf_free(buf); 14813 } 14814 14815 return ret; 14816 } 14817 14818 /** 14819 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 14820 * @wmi_handle: wmi handle 14821 * @vdev_id: vdev id 14822 * @rcv_filter_param: Packet filter parameters 14823 * @filter_id: Filter id 14824 * @enable: Flag to add/delete packet filter configuration 14825 * 14826 * Return: QDF_STATUS_SUCCESS for success or error code 14827 */ 14828 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 14829 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 14830 uint8_t filter_id, bool enable) 14831 { 14832 int len, i; 14833 int err = 0; 14834 wmi_buf_t buf; 14835 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 14836 14837 14838 /* allocate the memory */ 14839 len = sizeof(*cmd); 14840 buf = wmi_buf_alloc(wmi_handle, len); 14841 if (!buf) { 14842 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14843 return QDF_STATUS_E_NOMEM; 14844 } 14845 14846 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 14847 WMITLV_SET_HDR(&cmd->tlv_header, 14848 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 14849 WMITLV_GET_STRUCT_TLVLEN 14850 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 14851 14852 cmd->vdev_id = vdev_id; 14853 cmd->filter_id = filter_id; 14854 if (enable) 14855 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 14856 else 14857 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 14858 14859 if (enable) { 14860 cmd->num_params = QDF_MIN( 14861 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 14862 rcv_filter_param->num_params); 14863 cmd->filter_type = rcv_filter_param->filter_type; 14864 cmd->coalesce_time = rcv_filter_param->coalesce_time; 14865 14866 for (i = 0; i < cmd->num_params; i++) { 14867 cmd->paramsData[i].proto_type = 14868 rcv_filter_param->params_data[i].protocol_layer; 14869 cmd->paramsData[i].cmp_type = 14870 rcv_filter_param->params_data[i].compare_flag; 14871 cmd->paramsData[i].data_length = 14872 rcv_filter_param->params_data[i].data_length; 14873 cmd->paramsData[i].data_offset = 14874 rcv_filter_param->params_data[i].data_offset; 14875 memcpy(&cmd->paramsData[i].compareData, 14876 rcv_filter_param->params_data[i].compare_data, 14877 sizeof(cmd->paramsData[i].compareData)); 14878 memcpy(&cmd->paramsData[i].dataMask, 14879 rcv_filter_param->params_data[i].data_mask, 14880 sizeof(cmd->paramsData[i].dataMask)); 14881 } 14882 } 14883 14884 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 14885 cmd->filter_action, cmd->filter_id, cmd->num_params); 14886 /* send the command along with data */ 14887 err = wmi_unified_cmd_send(wmi_handle, buf, len, 14888 WMI_PACKET_FILTER_CONFIG_CMDID); 14889 if (err) { 14890 WMI_LOGE("Failed to send pkt_filter cmd"); 14891 wmi_buf_free(buf); 14892 return QDF_STATUS_E_FAILURE; 14893 } 14894 14895 return QDF_STATUS_SUCCESS; 14896 } 14897 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 14898 14899 /** 14900 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 14901 * @wmi_handle: wmi handle 14902 * @request: SSID hotlist set request 14903 * 14904 * Return: QDF_STATUS enumeration 14905 */ 14906 static QDF_STATUS 14907 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 14908 struct ssid_hotlist_request_params *request) 14909 { 14910 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 14911 wmi_buf_t wmi_buf; 14912 uint32_t len; 14913 uint32_t array_size; 14914 uint8_t *buf_ptr; 14915 14916 /* length of fixed portion */ 14917 len = sizeof(*cmd); 14918 14919 /* length of variable portion */ 14920 array_size = 14921 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 14922 len += WMI_TLV_HDR_SIZE + array_size; 14923 14924 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14925 if (!wmi_buf) { 14926 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14927 return QDF_STATUS_E_NOMEM; 14928 } 14929 14930 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 14931 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 14932 buf_ptr; 14933 WMITLV_SET_HDR 14934 (&cmd->tlv_header, 14935 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 14936 WMITLV_GET_STRUCT_TLVLEN 14937 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 14938 14939 cmd->request_id = request->request_id; 14940 cmd->requestor_id = 0; 14941 cmd->vdev_id = request->session_id; 14942 cmd->table_id = 0; 14943 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 14944 cmd->total_entries = request->ssid_count; 14945 cmd->num_entries_in_page = request->ssid_count; 14946 cmd->first_entry_index = 0; 14947 14948 buf_ptr += sizeof(*cmd); 14949 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 14950 14951 if (request->ssid_count) { 14952 wmi_extscan_hotlist_ssid_entry *entry; 14953 int i; 14954 14955 buf_ptr += WMI_TLV_HDR_SIZE; 14956 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 14957 for (i = 0; i < request->ssid_count; i++) { 14958 WMITLV_SET_HDR 14959 (entry, 14960 WMITLV_TAG_ARRAY_STRUC, 14961 WMITLV_GET_STRUCT_TLVLEN 14962 (wmi_extscan_hotlist_ssid_entry)); 14963 entry->ssid.ssid_len = request->ssids[i].ssid.length; 14964 qdf_mem_copy(entry->ssid.ssid, 14965 request->ssids[i].ssid.mac_ssid, 14966 request->ssids[i].ssid.length); 14967 entry->band = request->ssids[i].band; 14968 entry->min_rssi = request->ssids[i].rssi_low; 14969 entry->max_rssi = request->ssids[i].rssi_high; 14970 entry++; 14971 } 14972 cmd->mode = WMI_EXTSCAN_MODE_START; 14973 } else { 14974 cmd->mode = WMI_EXTSCAN_MODE_STOP; 14975 } 14976 14977 if (wmi_unified_cmd_send 14978 (wmi_handle, wmi_buf, len, 14979 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 14980 WMI_LOGE("%s: failed to send command", __func__); 14981 wmi_buf_free(wmi_buf); 14982 return QDF_STATUS_E_FAILURE; 14983 } 14984 14985 return QDF_STATUS_SUCCESS; 14986 } 14987 14988 /** 14989 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 14990 * @wmi_handle: wmi handle 14991 * @vdev_id: vdev id 14992 * 14993 * This function sends roam synch complete event to fw. 14994 * 14995 * Return: CDF STATUS 14996 */ 14997 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 14998 uint8_t vdev_id) 14999 { 15000 wmi_roam_synch_complete_fixed_param *cmd; 15001 wmi_buf_t wmi_buf; 15002 uint8_t *buf_ptr; 15003 uint16_t len; 15004 len = sizeof(wmi_roam_synch_complete_fixed_param); 15005 15006 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15007 if (!wmi_buf) { 15008 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15009 return QDF_STATUS_E_NOMEM; 15010 } 15011 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15012 buf_ptr = (uint8_t *) cmd; 15013 WMITLV_SET_HDR(&cmd->tlv_header, 15014 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15015 WMITLV_GET_STRUCT_TLVLEN 15016 (wmi_roam_synch_complete_fixed_param)); 15017 cmd->vdev_id = vdev_id; 15018 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15019 WMI_ROAM_SYNCH_COMPLETE)) { 15020 WMI_LOGP("%s: failed to send roam synch confirmation", 15021 __func__); 15022 wmi_buf_free(wmi_buf); 15023 return QDF_STATUS_E_FAILURE; 15024 } 15025 15026 return QDF_STATUS_SUCCESS; 15027 } 15028 15029 /** 15030 * send_fw_test_cmd_tlv() - send fw test command to fw. 15031 * @wmi_handle: wmi handle 15032 * @wmi_fwtest: fw test command 15033 * 15034 * This function sends fw test command to fw. 15035 * 15036 * Return: CDF STATUS 15037 */ 15038 static 15039 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15040 struct set_fwtest_params *wmi_fwtest) 15041 { 15042 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15043 wmi_buf_t wmi_buf; 15044 uint16_t len; 15045 15046 len = sizeof(*cmd); 15047 15048 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15049 if (!wmi_buf) { 15050 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15051 return QDF_STATUS_E_NOMEM; 15052 } 15053 15054 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15055 WMITLV_SET_HDR(&cmd->tlv_header, 15056 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15057 WMITLV_GET_STRUCT_TLVLEN( 15058 wmi_fwtest_set_param_cmd_fixed_param)); 15059 cmd->param_id = wmi_fwtest->arg; 15060 cmd->param_value = wmi_fwtest->value; 15061 15062 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15063 WMI_FWTEST_CMDID)) { 15064 WMI_LOGP("%s: failed to send fw test command", __func__); 15065 qdf_nbuf_free(wmi_buf); 15066 return QDF_STATUS_E_FAILURE; 15067 } 15068 15069 return QDF_STATUS_SUCCESS; 15070 } 15071 15072 /** 15073 * send_unit_test_cmd_tlv() - send unit test command to fw. 15074 * @wmi_handle: wmi handle 15075 * @wmi_utest: unit test command 15076 * 15077 * This function send unit test command to fw. 15078 * 15079 * Return: CDF STATUS 15080 */ 15081 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15082 struct wmi_unit_test_cmd *wmi_utest) 15083 { 15084 wmi_unit_test_cmd_fixed_param *cmd; 15085 wmi_buf_t wmi_buf; 15086 uint8_t *buf_ptr; 15087 int i; 15088 uint16_t len, args_tlv_len; 15089 uint32_t *unit_test_cmd_args; 15090 15091 args_tlv_len = 15092 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15093 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15094 15095 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15096 if (!wmi_buf) { 15097 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15098 return QDF_STATUS_E_NOMEM; 15099 } 15100 15101 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15102 buf_ptr = (uint8_t *) cmd; 15103 WMITLV_SET_HDR(&cmd->tlv_header, 15104 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15105 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15106 cmd->vdev_id = wmi_utest->vdev_id; 15107 cmd->module_id = wmi_utest->module_id; 15108 cmd->num_args = wmi_utest->num_args; 15109 cmd->diag_token = wmi_utest->diag_token; 15110 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15111 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15112 (wmi_utest->num_args * sizeof(uint32_t))); 15113 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15114 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15115 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15116 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15117 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15118 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15119 unit_test_cmd_args[i] = wmi_utest->args[i]; 15120 WMI_LOGI("%d,", wmi_utest->args[i]); 15121 } 15122 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15123 WMI_UNIT_TEST_CMDID)) { 15124 WMI_LOGP("%s: failed to send unit test command", __func__); 15125 wmi_buf_free(wmi_buf); 15126 return QDF_STATUS_E_FAILURE; 15127 } 15128 15129 return QDF_STATUS_SUCCESS; 15130 } 15131 15132 /** 15133 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15134 * @wmi_handle: wma handle 15135 * @roaminvoke: roam invoke command 15136 * 15137 * Send roam invoke command to fw for fastreassoc. 15138 * 15139 * Return: CDF STATUS 15140 */ 15141 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15142 struct wmi_roam_invoke_cmd *roaminvoke, 15143 uint32_t ch_hz) 15144 { 15145 wmi_roam_invoke_cmd_fixed_param *cmd; 15146 wmi_buf_t wmi_buf; 15147 u_int8_t *buf_ptr; 15148 u_int16_t len, args_tlv_len; 15149 uint32_t *channel_list; 15150 wmi_mac_addr *bssid_list; 15151 wmi_tlv_buf_len_param *buf_len_tlv; 15152 15153 /* Host sends only one channel and one bssid */ 15154 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15155 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15156 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15157 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15158 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15159 if (!wmi_buf) { 15160 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15161 return QDF_STATUS_E_NOMEM; 15162 } 15163 15164 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15165 buf_ptr = (u_int8_t *) cmd; 15166 WMITLV_SET_HDR(&cmd->tlv_header, 15167 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15168 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15169 cmd->vdev_id = roaminvoke->vdev_id; 15170 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15171 if (roaminvoke->is_same_bssid) 15172 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15173 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15174 15175 if (roaminvoke->frame_len) { 15176 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15177 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15178 cmd->num_buf = 1; 15179 } else { 15180 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15181 cmd->num_buf = 0; 15182 } 15183 15184 cmd->roam_ap_sel_mode = 0; 15185 cmd->roam_delay = 0; 15186 cmd->num_chan = 1; 15187 cmd->num_bssid = 1; 15188 15189 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15191 (sizeof(u_int32_t))); 15192 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15193 *channel_list = ch_hz; 15194 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15195 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15196 (sizeof(wmi_mac_addr))); 15197 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15198 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15199 15200 /* move to next tlv i.e. bcn_prb_buf_list */ 15201 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15202 15203 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15204 sizeof(wmi_tlv_buf_len_param)); 15205 15206 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15207 buf_len_tlv->buf_len = roaminvoke->frame_len; 15208 15209 /* move to next tlv i.e. bcn_prb_frm */ 15210 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15211 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15212 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15213 15214 /* copy frame after the header */ 15215 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15216 roaminvoke->frame_buf, 15217 roaminvoke->frame_len); 15218 15219 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15220 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 15221 buf_ptr + WMI_TLV_HDR_SIZE, 15222 roaminvoke->frame_len); 15223 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15224 cmd->flags, cmd->roam_scan_mode, 15225 cmd->roam_ap_sel_mode, cmd->roam_delay, 15226 cmd->num_chan, cmd->num_bssid); 15227 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15228 15229 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15230 WMI_ROAM_INVOKE_CMDID)) { 15231 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15232 wmi_buf_free(wmi_buf); 15233 return QDF_STATUS_E_FAILURE; 15234 } 15235 15236 return QDF_STATUS_SUCCESS; 15237 } 15238 15239 /** 15240 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15241 * @wmi_handle: wmi handle 15242 * @command: command 15243 * @vdev_id: vdev id 15244 * 15245 * This function set roam offload command to fw. 15246 * 15247 * Return: CDF status 15248 */ 15249 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15250 uint32_t command, uint32_t vdev_id) 15251 { 15252 QDF_STATUS status; 15253 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15254 wmi_buf_t buf = NULL; 15255 int len; 15256 uint8_t *buf_ptr; 15257 15258 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15259 buf = wmi_buf_alloc(wmi_handle, len); 15260 if (!buf) { 15261 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15262 return QDF_STATUS_E_NOMEM; 15263 } 15264 15265 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15266 15267 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15268 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15269 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15270 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15271 cmd_fp->vdev_id = vdev_id; 15272 cmd_fp->command_arg = command; 15273 15274 status = wmi_unified_cmd_send(wmi_handle, buf, 15275 len, WMI_ROAM_SCAN_CMD); 15276 if (QDF_IS_STATUS_ERROR(status)) { 15277 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15278 status); 15279 goto error; 15280 } 15281 15282 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15283 return QDF_STATUS_SUCCESS; 15284 15285 error: 15286 wmi_buf_free(buf); 15287 15288 return status; 15289 } 15290 15291 /** 15292 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15293 * @wmi_handle: wmi handle 15294 * @ap_profile_p: ap profile 15295 * @vdev_id: vdev id 15296 * 15297 * Send WMI_ROAM_AP_PROFILE to firmware 15298 * 15299 * Return: CDF status 15300 */ 15301 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15302 struct ap_profile_params *ap_profile) 15303 { 15304 wmi_buf_t buf = NULL; 15305 QDF_STATUS status; 15306 int len; 15307 uint8_t *buf_ptr; 15308 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 15309 wmi_roam_cnd_scoring_param *score_param; 15310 wmi_ap_profile *profile; 15311 15312 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 15313 len += sizeof(*score_param); 15314 buf = wmi_buf_alloc(wmi_handle, len); 15315 if (!buf) { 15316 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15317 return QDF_STATUS_E_NOMEM; 15318 } 15319 15320 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15321 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 15322 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 15323 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 15324 WMITLV_GET_STRUCT_TLVLEN 15325 (wmi_roam_ap_profile_fixed_param)); 15326 /* fill in threshold values */ 15327 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 15328 roam_ap_profile_fp->id = 0; 15329 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 15330 15331 profile = (wmi_ap_profile *)buf_ptr; 15332 WMITLV_SET_HDR(&profile->tlv_header, 15333 WMITLV_TAG_STRUC_wmi_ap_profile, 15334 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 15335 profile->flags = ap_profile->profile.flags; 15336 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 15337 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 15338 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 15339 profile->ssid.ssid_len); 15340 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 15341 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 15342 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 15343 profile->rsn_mcastmgmtcipherset = 15344 ap_profile->profile.rsn_mcastmgmtcipherset; 15345 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 15346 15347 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", 15348 profile->flags, profile->rssi_threshold, 15349 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 15350 profile->rsn_authmode, profile->rsn_ucastcipherset, 15351 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 15352 profile->rssi_abs_thresh); 15353 15354 buf_ptr += sizeof(wmi_ap_profile); 15355 15356 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 15357 WMITLV_SET_HDR(&score_param->tlv_header, 15358 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 15359 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 15360 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 15361 score_param->rssi_weightage_pcnt = 15362 ap_profile->param.rssi_weightage; 15363 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 15364 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 15365 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 15366 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 15367 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 15368 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 15369 score_param->esp_qbss_weightage_pcnt = 15370 ap_profile->param.esp_qbss_weightage; 15371 score_param->beamforming_weightage_pcnt = 15372 ap_profile->param.beamforming_weightage; 15373 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 15374 score_param->oce_wan_weightage_pcnt = 15375 ap_profile->param.oce_wan_weightage; 15376 15377 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", 15378 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 15379 score_param->ht_weightage_pcnt, 15380 score_param->vht_weightage_pcnt, 15381 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 15382 score_param->band_weightage_pcnt, 15383 score_param->nss_weightage_pcnt, 15384 score_param->esp_qbss_weightage_pcnt, 15385 score_param->beamforming_weightage_pcnt, 15386 score_param->pcl_weightage_pcnt, 15387 score_param->oce_wan_weightage_pcnt); 15388 15389 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 15390 score_param->band_scoring.score_pcnt = 15391 ap_profile->param.band_index_score; 15392 score_param->nss_scoring.score_pcnt = 15393 ap_profile->param.nss_index_score; 15394 15395 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 15396 score_param->bw_scoring.score_pcnt, 15397 score_param->band_scoring.score_pcnt, 15398 score_param->nss_scoring.score_pcnt); 15399 15400 score_param->rssi_scoring.best_rssi_threshold = 15401 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 15402 score_param->rssi_scoring.good_rssi_threshold = 15403 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 15404 score_param->rssi_scoring.bad_rssi_threshold = 15405 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 15406 score_param->rssi_scoring.good_rssi_pcnt = 15407 ap_profile->param.rssi_scoring.good_rssi_pcnt; 15408 score_param->rssi_scoring.bad_rssi_pcnt = 15409 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 15410 score_param->rssi_scoring.good_bucket_size = 15411 ap_profile->param.rssi_scoring.good_bucket_size; 15412 score_param->rssi_scoring.bad_bucket_size = 15413 ap_profile->param.rssi_scoring.bad_bucket_size; 15414 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 15415 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 15416 15417 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 15418 score_param->rssi_scoring.best_rssi_threshold, 15419 score_param->rssi_scoring.good_rssi_threshold, 15420 score_param->rssi_scoring.bad_rssi_threshold, 15421 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 15422 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 15423 score_param->rssi_scoring.good_rssi_pcnt, 15424 score_param->rssi_scoring.bad_rssi_pcnt, 15425 score_param->rssi_scoring.good_bucket_size, 15426 score_param->rssi_scoring.bad_bucket_size); 15427 15428 score_param->esp_qbss_scoring.num_slot = 15429 ap_profile->param.esp_qbss_scoring.num_slot; 15430 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 15431 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 15432 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 15433 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 15434 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 15435 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 15436 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 15437 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 15438 15439 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15440 score_param->esp_qbss_scoring.num_slot, 15441 score_param->esp_qbss_scoring.score_pcnt3_to_0, 15442 score_param->esp_qbss_scoring.score_pcnt7_to_4, 15443 score_param->esp_qbss_scoring.score_pcnt11_to_8, 15444 score_param->esp_qbss_scoring.score_pcnt15_to_12); 15445 15446 score_param->oce_wan_scoring.num_slot = 15447 ap_profile->param.oce_wan_scoring.num_slot; 15448 score_param->oce_wan_scoring.score_pcnt3_to_0 = 15449 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 15450 score_param->oce_wan_scoring.score_pcnt7_to_4 = 15451 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 15452 score_param->oce_wan_scoring.score_pcnt11_to_8 = 15453 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 15454 score_param->oce_wan_scoring.score_pcnt15_to_12 = 15455 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 15456 15457 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15458 score_param->oce_wan_scoring.num_slot, 15459 score_param->oce_wan_scoring.score_pcnt3_to_0, 15460 score_param->oce_wan_scoring.score_pcnt7_to_4, 15461 score_param->oce_wan_scoring.score_pcnt11_to_8, 15462 score_param->oce_wan_scoring.score_pcnt15_to_12); 15463 15464 status = wmi_unified_cmd_send(wmi_handle, buf, 15465 len, WMI_ROAM_AP_PROFILE); 15466 if (QDF_IS_STATUS_ERROR(status)) { 15467 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 15468 status); 15469 wmi_buf_free(buf); 15470 } 15471 15472 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 15473 15474 return status; 15475 } 15476 15477 /** 15478 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 15479 * @wmi_handle: wmi handle 15480 * @scan_period: scan period 15481 * @scan_age: scan age 15482 * @vdev_id: vdev id 15483 * 15484 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 15485 * 15486 * Return: CDF status 15487 */ 15488 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 15489 uint32_t scan_period, 15490 uint32_t scan_age, 15491 uint32_t vdev_id) 15492 { 15493 QDF_STATUS status; 15494 wmi_buf_t buf = NULL; 15495 int len; 15496 uint8_t *buf_ptr; 15497 wmi_roam_scan_period_fixed_param *scan_period_fp; 15498 15499 /* Send scan period values */ 15500 len = sizeof(wmi_roam_scan_period_fixed_param); 15501 buf = wmi_buf_alloc(wmi_handle, len); 15502 if (!buf) { 15503 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15504 return QDF_STATUS_E_NOMEM; 15505 } 15506 15507 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15508 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 15509 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 15510 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 15511 WMITLV_GET_STRUCT_TLVLEN 15512 (wmi_roam_scan_period_fixed_param)); 15513 /* fill in scan period values */ 15514 scan_period_fp->vdev_id = vdev_id; 15515 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 15516 scan_period_fp->roam_scan_age = scan_age; 15517 15518 status = wmi_unified_cmd_send(wmi_handle, buf, 15519 len, WMI_ROAM_SCAN_PERIOD); 15520 if (QDF_IS_STATUS_ERROR(status)) { 15521 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 15522 status); 15523 goto error; 15524 } 15525 15526 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 15527 __func__, scan_period, scan_age); 15528 return QDF_STATUS_SUCCESS; 15529 error: 15530 wmi_buf_free(buf); 15531 15532 return status; 15533 } 15534 15535 /** 15536 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 15537 * @wmi_handle: wmi handle 15538 * @chan_count: channel count 15539 * @chan_list: channel list 15540 * @list_type: list type 15541 * @vdev_id: vdev id 15542 * 15543 * Set roam offload channel list. 15544 * 15545 * Return: CDF status 15546 */ 15547 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 15548 uint8_t chan_count, 15549 uint32_t *chan_list, 15550 uint8_t list_type, uint32_t vdev_id) 15551 { 15552 wmi_buf_t buf = NULL; 15553 QDF_STATUS status; 15554 int len, list_tlv_len; 15555 int i; 15556 uint8_t *buf_ptr; 15557 wmi_roam_chan_list_fixed_param *chan_list_fp; 15558 uint32_t *roam_chan_list_array; 15559 15560 if (chan_count == 0) { 15561 WMI_LOGD("%s : invalid number of channels %d", __func__, 15562 chan_count); 15563 return QDF_STATUS_E_EMPTY; 15564 } 15565 /* Channel list is a table of 2 TLV's */ 15566 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 15567 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 15568 buf = wmi_buf_alloc(wmi_handle, len); 15569 if (!buf) { 15570 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15571 return QDF_STATUS_E_NOMEM; 15572 } 15573 15574 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15575 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 15576 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 15577 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 15578 WMITLV_GET_STRUCT_TLVLEN 15579 (wmi_roam_chan_list_fixed_param)); 15580 chan_list_fp->vdev_id = vdev_id; 15581 chan_list_fp->num_chan = chan_count; 15582 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 15583 /* external app is controlling channel list */ 15584 chan_list_fp->chan_list_type = 15585 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 15586 } else { 15587 /* umac supplied occupied channel list in LFR */ 15588 chan_list_fp->chan_list_type = 15589 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 15590 } 15591 15592 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 15593 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15594 (chan_list_fp->num_chan * sizeof(uint32_t))); 15595 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15596 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 15597 for (i = 0; ((i < chan_list_fp->num_chan) && 15598 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 15599 roam_chan_list_array[i] = chan_list[i]; 15600 WMI_LOGD("%d,", roam_chan_list_array[i]); 15601 } 15602 15603 status = wmi_unified_cmd_send(wmi_handle, buf, 15604 len, WMI_ROAM_CHAN_LIST); 15605 if (QDF_IS_STATUS_ERROR(status)) { 15606 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 15607 status); 15608 goto error; 15609 } 15610 15611 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 15612 return QDF_STATUS_SUCCESS; 15613 error: 15614 wmi_buf_free(buf); 15615 15616 return status; 15617 } 15618 15619 /** 15620 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 15621 * @wmi_handle: wmi handle 15622 * @req_buf: per roam config buffer 15623 * 15624 * Return: QDF status 15625 */ 15626 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 15627 struct wmi_per_roam_config_req *req_buf) 15628 { 15629 wmi_buf_t buf = NULL; 15630 QDF_STATUS status; 15631 int len; 15632 uint8_t *buf_ptr; 15633 wmi_roam_per_config_fixed_param *wmi_per_config; 15634 15635 len = sizeof(wmi_roam_per_config_fixed_param); 15636 buf = wmi_buf_alloc(wmi_handle, len); 15637 if (!buf) { 15638 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15639 return QDF_STATUS_E_NOMEM; 15640 } 15641 15642 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15643 wmi_per_config = 15644 (wmi_roam_per_config_fixed_param *) buf_ptr; 15645 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 15646 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 15647 WMITLV_GET_STRUCT_TLVLEN 15648 (wmi_roam_per_config_fixed_param)); 15649 15650 /* fill in per roam config values */ 15651 wmi_per_config->vdev_id = req_buf->vdev_id; 15652 15653 wmi_per_config->enable = req_buf->per_config.enable; 15654 wmi_per_config->high_rate_thresh = 15655 (req_buf->per_config.tx_high_rate_thresh << 16) | 15656 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 15657 wmi_per_config->low_rate_thresh = 15658 (req_buf->per_config.tx_low_rate_thresh << 16) | 15659 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 15660 wmi_per_config->pkt_err_rate_thresh_pct = 15661 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 15662 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 15663 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 15664 wmi_per_config->pkt_err_rate_mon_time = 15665 (req_buf->per_config.tx_per_mon_time << 16) | 15666 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 15667 wmi_per_config->min_candidate_rssi = 15668 req_buf->per_config.min_candidate_rssi; 15669 15670 /* Send per roam config parameters */ 15671 status = wmi_unified_cmd_send(wmi_handle, buf, 15672 len, WMI_ROAM_PER_CONFIG_CMDID); 15673 if (QDF_IS_STATUS_ERROR(status)) { 15674 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 15675 status); 15676 wmi_buf_free(buf); 15677 return status; 15678 } 15679 15680 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 15681 req_buf->per_config.enable, req_buf->vdev_id); 15682 return QDF_STATUS_SUCCESS; 15683 } 15684 15685 /** 15686 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 15687 * @wmi_handle: wmi handle 15688 * @rssi_change_thresh: RSSI Change threshold 15689 * @bcn_rssi_weight: beacon RSSI weight 15690 * @vdev_id: vdev id 15691 * 15692 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 15693 * 15694 * Return: CDF status 15695 */ 15696 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 15697 uint32_t vdev_id, 15698 int32_t rssi_change_thresh, 15699 uint32_t bcn_rssi_weight, 15700 uint32_t hirssi_delay_btw_scans) 15701 { 15702 wmi_buf_t buf = NULL; 15703 QDF_STATUS status; 15704 int len; 15705 uint8_t *buf_ptr; 15706 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 15707 15708 /* Send rssi change parameters */ 15709 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 15710 buf = wmi_buf_alloc(wmi_handle, len); 15711 if (!buf) { 15712 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15713 return QDF_STATUS_E_NOMEM; 15714 } 15715 15716 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15717 rssi_change_fp = 15718 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 15719 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 15720 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 15721 WMITLV_GET_STRUCT_TLVLEN 15722 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 15723 /* fill in rssi change threshold (hysteresis) values */ 15724 rssi_change_fp->vdev_id = vdev_id; 15725 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 15726 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 15727 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 15728 15729 status = wmi_unified_cmd_send(wmi_handle, buf, 15730 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 15731 if (QDF_IS_STATUS_ERROR(status)) { 15732 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 15733 status); 15734 goto error; 15735 } 15736 15737 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 15738 rssi_change_thresh, bcn_rssi_weight); 15739 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 15740 return QDF_STATUS_SUCCESS; 15741 error: 15742 wmi_buf_free(buf); 15743 15744 return status; 15745 } 15746 15747 /** 15748 * send_power_dbg_cmd_tlv() - send power debug commands 15749 * @wmi_handle: wmi handle 15750 * @param: wmi power debug parameter 15751 * 15752 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 15753 * 15754 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15755 */ 15756 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 15757 struct wmi_power_dbg_params *param) 15758 { 15759 wmi_buf_t buf = NULL; 15760 QDF_STATUS status; 15761 int len, args_tlv_len; 15762 uint8_t *buf_ptr; 15763 uint8_t i; 15764 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 15765 uint32_t *cmd_args; 15766 15767 /* Prepare and send power debug cmd parameters */ 15768 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 15769 len = sizeof(*cmd) + args_tlv_len; 15770 buf = wmi_buf_alloc(wmi_handle, len); 15771 if (!buf) { 15772 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15773 return QDF_STATUS_E_NOMEM; 15774 } 15775 15776 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15777 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 15778 WMITLV_SET_HDR(&cmd->tlv_header, 15779 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 15780 WMITLV_GET_STRUCT_TLVLEN 15781 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 15782 15783 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15784 param->pdev_id); 15785 cmd->module_id = param->module_id; 15786 cmd->num_args = param->num_args; 15787 buf_ptr += sizeof(*cmd); 15788 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15789 (param->num_args * sizeof(uint32_t))); 15790 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15791 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 15792 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 15793 cmd_args[i] = param->args[i]; 15794 WMI_LOGI("%d,", param->args[i]); 15795 } 15796 15797 status = wmi_unified_cmd_send(wmi_handle, buf, 15798 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 15799 if (QDF_IS_STATUS_ERROR(status)) { 15800 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 15801 status); 15802 goto error; 15803 } 15804 15805 return QDF_STATUS_SUCCESS; 15806 error: 15807 wmi_buf_free(buf); 15808 15809 return status; 15810 } 15811 15812 /** 15813 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 15814 * @wmi_handle: wmi handle 15815 * @param: wmi multiple vdev restart req param 15816 * 15817 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 15818 * 15819 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15820 */ 15821 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 15822 wmi_unified_t wmi_handle, 15823 struct multiple_vdev_restart_params *param) 15824 { 15825 wmi_buf_t buf; 15826 QDF_STATUS qdf_status; 15827 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 15828 int i; 15829 uint8_t *buf_ptr; 15830 uint32_t *vdev_ids; 15831 wmi_channel *chan_info; 15832 struct channel_param *tchan_info; 15833 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 15834 15835 len += sizeof(wmi_channel); 15836 if (param->num_vdevs) 15837 len += sizeof(uint32_t) * param->num_vdevs; 15838 15839 buf = wmi_buf_alloc(wmi_handle, len); 15840 if (!buf) { 15841 WMI_LOGE("Failed to allocate memory\n"); 15842 qdf_status = QDF_STATUS_E_NOMEM; 15843 goto end; 15844 } 15845 15846 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15847 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 15848 buf_ptr; 15849 15850 WMITLV_SET_HDR(&cmd->tlv_header, 15851 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 15852 WMITLV_GET_STRUCT_TLVLEN 15853 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 15854 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15855 param->pdev_id); 15856 cmd->requestor_id = param->requestor_id; 15857 cmd->disable_hw_ack = param->disable_hw_ack; 15858 cmd->cac_duration_ms = param->cac_duration_ms; 15859 cmd->num_vdevs = param->num_vdevs; 15860 15861 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 15862 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 15863 " cmd->num_vdevs: %d ", 15864 __func__, cmd->pdev_id, cmd->requestor_id, 15865 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 15866 buf_ptr += sizeof(*cmd); 15867 15868 WMITLV_SET_HDR(buf_ptr, 15869 WMITLV_TAG_ARRAY_UINT32, 15870 sizeof(uint32_t) * param->num_vdevs); 15871 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15872 for (i = 0; i < param->num_vdevs; i++) { 15873 vdev_ids[i] = param->vdev_ids[i]; 15874 } 15875 15876 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 15877 15878 WMITLV_SET_HDR(buf_ptr, 15879 WMITLV_TAG_STRUC_wmi_channel, 15880 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 15881 chan_info = (wmi_channel *)buf_ptr; 15882 tchan_info = &(param->ch_param); 15883 chan_info->mhz = tchan_info->mhz; 15884 chan_info->band_center_freq1 = tchan_info->cfreq1; 15885 chan_info->band_center_freq2 = tchan_info->cfreq2; 15886 if (tchan_info->is_chan_passive) 15887 WMI_SET_CHANNEL_FLAG(chan_info, 15888 WMI_CHAN_FLAG_PASSIVE); 15889 if (tchan_info->dfs_set) 15890 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 15891 15892 if (tchan_info->allow_vht) 15893 WMI_SET_CHANNEL_FLAG(chan_info, 15894 WMI_CHAN_FLAG_ALLOW_VHT); 15895 else if (tchan_info->allow_ht) 15896 WMI_SET_CHANNEL_FLAG(chan_info, 15897 WMI_CHAN_FLAG_ALLOW_HT); 15898 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 15899 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 15900 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 15901 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 15902 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 15903 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 15904 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 15905 15906 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 15907 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 15908 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 15909 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 15910 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 15911 "tchan_info->reg_class_id: %d ," 15912 "tchan_info->maxregpower : %d ", __func__, 15913 tchan_info->is_chan_passive, tchan_info->dfs_set, 15914 tchan_info->allow_vht, tchan_info->allow_ht, 15915 tchan_info->antennamax, tchan_info->phy_mode, 15916 tchan_info->minpower, tchan_info->maxpower, 15917 tchan_info->maxregpower, tchan_info->reg_class_id, 15918 tchan_info->maxregpower); 15919 15920 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 15921 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 15922 15923 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15924 WMI_LOGE("%s: Failed to send\n", __func__); 15925 wmi_buf_free(buf); 15926 } 15927 15928 end: 15929 return qdf_status; 15930 } 15931 15932 /** 15933 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 15934 * @wmi_handle: wmi handle 15935 * @pdev_id: pdev id 15936 * 15937 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 15938 * 15939 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15940 */ 15941 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 15942 uint32_t pdev_id) 15943 { 15944 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 15945 wmi_buf_t buf; 15946 uint16_t len; 15947 QDF_STATUS ret; 15948 15949 len = sizeof(*cmd); 15950 buf = wmi_buf_alloc(wmi_handle, len); 15951 15952 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 15953 15954 if (!buf) { 15955 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15956 return QDF_STATUS_E_NOMEM; 15957 } 15958 15959 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 15960 wmi_buf_data(buf); 15961 15962 WMITLV_SET_HDR(&cmd->tlv_header, 15963 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 15964 WMITLV_GET_STRUCT_TLVLEN( 15965 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 15966 15967 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 15968 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15969 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 15970 if (QDF_IS_STATUS_ERROR(ret)) { 15971 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 15972 __func__, ret, pdev_id); 15973 wmi_buf_free(buf); 15974 return QDF_STATUS_E_FAILURE; 15975 } 15976 15977 return QDF_STATUS_SUCCESS; 15978 } 15979 15980 /** 15981 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 15982 * @wmi_handle: wmi handle 15983 * @pdev_id: pdev id 15984 * 15985 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 15986 * 15987 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15988 */ 15989 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 15990 uint32_t pdev_id) 15991 { 15992 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 15993 wmi_buf_t buf; 15994 uint16_t len; 15995 QDF_STATUS ret; 15996 15997 len = sizeof(*cmd); 15998 buf = wmi_buf_alloc(wmi_handle, len); 15999 16000 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16001 16002 if (!buf) { 16003 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16004 return QDF_STATUS_E_NOMEM; 16005 } 16006 16007 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16008 wmi_buf_data(buf); 16009 16010 WMITLV_SET_HDR(&cmd->tlv_header, 16011 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16012 WMITLV_GET_STRUCT_TLVLEN( 16013 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16014 16015 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16016 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16017 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16018 if (QDF_IS_STATUS_ERROR(ret)) { 16019 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16020 __func__, ret, pdev_id); 16021 wmi_buf_free(buf); 16022 return QDF_STATUS_E_FAILURE; 16023 } 16024 16025 return QDF_STATUS_SUCCESS; 16026 } 16027 16028 /** 16029 * init_cmd_send_tlv() - send initialization cmd to fw 16030 * @wmi_handle: wmi handle 16031 * @param param: pointer to wmi init param 16032 * 16033 * Return: QDF_STATUS_SUCCESS for success or error code 16034 */ 16035 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16036 struct wmi_init_cmd_param *param) 16037 { 16038 wmi_buf_t buf; 16039 wmi_init_cmd_fixed_param *cmd; 16040 uint8_t *buf_ptr; 16041 wmi_resource_config *resource_cfg; 16042 wlan_host_memory_chunk *host_mem_chunks; 16043 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16044 uint16_t idx; 16045 int len; 16046 QDF_STATUS ret; 16047 16048 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16049 WMI_TLV_HDR_SIZE; 16050 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16051 16052 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16053 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16054 WMI_TLV_HDR_SIZE + 16055 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16056 16057 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16058 if (!buf) { 16059 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16060 return QDF_STATUS_E_FAILURE; 16061 } 16062 16063 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16064 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16065 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16066 16067 host_mem_chunks = (wlan_host_memory_chunk *) 16068 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16069 + WMI_TLV_HDR_SIZE); 16070 16071 WMITLV_SET_HDR(&cmd->tlv_header, 16072 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16073 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16074 16075 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16076 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16077 WMITLV_TAG_STRUC_wmi_resource_config, 16078 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16079 16080 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16081 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16082 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16083 WMITLV_GET_STRUCT_TLVLEN 16084 (wlan_host_memory_chunk)); 16085 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16086 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16087 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16088 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16089 "chunk %d len %d requested ,ptr 0x%x ", 16090 idx, host_mem_chunks[idx].size, 16091 host_mem_chunks[idx].ptr); 16092 } 16093 cmd->num_host_mem_chunks = param->num_mem_chunks; 16094 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16095 16096 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 16097 WMITLV_TAG_ARRAY_STRUC, 16098 (sizeof(wlan_host_memory_chunk) * 16099 param->num_mem_chunks)); 16100 16101 /* Fill hw mode id config */ 16102 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 16103 16104 /* Fill fw_abi_vers */ 16105 copy_fw_abi_version_tlv(wmi_handle, cmd); 16106 16107 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 16108 if (QDF_IS_STATUS_ERROR(ret)) { 16109 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 16110 ret); 16111 wmi_buf_free(buf); 16112 } 16113 16114 return ret; 16115 16116 } 16117 16118 /** 16119 * send_addba_send_cmd_tlv() - send addba send command to fw 16120 * @wmi_handle: wmi handle 16121 * @param: pointer to delba send params 16122 * @macaddr: peer mac address 16123 * 16124 * Send WMI_ADDBA_SEND_CMDID command to firmware 16125 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16126 */ 16127 static QDF_STATUS 16128 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 16129 uint8_t macaddr[IEEE80211_ADDR_LEN], 16130 struct addba_send_params *param) 16131 { 16132 wmi_addba_send_cmd_fixed_param *cmd; 16133 wmi_buf_t buf; 16134 uint16_t len; 16135 QDF_STATUS ret; 16136 16137 len = sizeof(*cmd); 16138 16139 buf = wmi_buf_alloc(wmi_handle, len); 16140 if (!buf) { 16141 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16142 return QDF_STATUS_E_NOMEM; 16143 } 16144 16145 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 16146 16147 WMITLV_SET_HDR(&cmd->tlv_header, 16148 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 16149 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 16150 16151 cmd->vdev_id = param->vdev_id; 16152 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16153 cmd->tid = param->tidno; 16154 cmd->buffersize = param->buffersize; 16155 16156 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 16157 if (QDF_IS_STATUS_ERROR(ret)) { 16158 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16159 wmi_buf_free(buf); 16160 return QDF_STATUS_E_FAILURE; 16161 } 16162 16163 return QDF_STATUS_SUCCESS; 16164 } 16165 16166 /** 16167 * send_delba_send_cmd_tlv() - send delba send command to fw 16168 * @wmi_handle: wmi handle 16169 * @param: pointer to delba send params 16170 * @macaddr: peer mac address 16171 * 16172 * Send WMI_DELBA_SEND_CMDID command to firmware 16173 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16174 */ 16175 static QDF_STATUS 16176 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 16177 uint8_t macaddr[IEEE80211_ADDR_LEN], 16178 struct delba_send_params *param) 16179 { 16180 wmi_delba_send_cmd_fixed_param *cmd; 16181 wmi_buf_t buf; 16182 uint16_t len; 16183 QDF_STATUS ret; 16184 16185 len = sizeof(*cmd); 16186 16187 buf = wmi_buf_alloc(wmi_handle, len); 16188 if (!buf) { 16189 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16190 return QDF_STATUS_E_NOMEM; 16191 } 16192 16193 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 16194 16195 WMITLV_SET_HDR(&cmd->tlv_header, 16196 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 16197 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 16198 16199 cmd->vdev_id = param->vdev_id; 16200 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16201 cmd->tid = param->tidno; 16202 cmd->initiator = param->initiator; 16203 cmd->reasoncode = param->reasoncode; 16204 16205 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 16206 if (QDF_IS_STATUS_ERROR(ret)) { 16207 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16208 wmi_buf_free(buf); 16209 return QDF_STATUS_E_FAILURE; 16210 } 16211 16212 return QDF_STATUS_SUCCESS; 16213 } 16214 16215 /** 16216 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 16217 * to fw 16218 * @wmi_handle: wmi handle 16219 * @param: pointer to addba clearresp params 16220 * @macaddr: peer mac address 16221 * Return: 0 for success or error code 16222 */ 16223 static QDF_STATUS 16224 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 16225 uint8_t macaddr[IEEE80211_ADDR_LEN], 16226 struct addba_clearresponse_params *param) 16227 { 16228 wmi_addba_clear_resp_cmd_fixed_param *cmd; 16229 wmi_buf_t buf; 16230 uint16_t len; 16231 QDF_STATUS ret; 16232 16233 len = sizeof(*cmd); 16234 16235 buf = wmi_buf_alloc(wmi_handle, len); 16236 if (!buf) { 16237 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 16238 return QDF_STATUS_E_FAILURE; 16239 } 16240 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 16241 16242 WMITLV_SET_HDR(&cmd->tlv_header, 16243 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 16244 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 16245 16246 cmd->vdev_id = param->vdev_id; 16247 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16248 16249 ret = wmi_unified_cmd_send(wmi_handle, 16250 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 16251 if (QDF_IS_STATUS_ERROR(ret)) { 16252 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16253 wmi_buf_free(buf); 16254 return QDF_STATUS_E_FAILURE; 16255 } 16256 16257 return QDF_STATUS_SUCCESS; 16258 } 16259 16260 /** 16261 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 16262 * @wmi_handle: wmi handle 16263 * @bcn_ctrl_param: pointer to bcn_offload_control param 16264 * 16265 * Return: QDF_STATUS_SUCCESS for success or error code 16266 */ 16267 static 16268 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 16269 struct bcn_offload_control *bcn_ctrl_param) 16270 { 16271 wmi_buf_t buf; 16272 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 16273 QDF_STATUS ret; 16274 uint32_t len; 16275 16276 len = sizeof(*cmd); 16277 16278 buf = wmi_buf_alloc(wmi_handle, len); 16279 if (!buf) { 16280 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16281 return QDF_STATUS_E_FAILURE; 16282 } 16283 16284 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 16285 WMITLV_SET_HDR(&cmd->tlv_header, 16286 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 16287 WMITLV_GET_STRUCT_TLVLEN 16288 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 16289 cmd->vdev_id = bcn_ctrl_param->vdev_id; 16290 switch (bcn_ctrl_param->bcn_ctrl_op) { 16291 case BCN_OFFLD_CTRL_TX_DISABLE: 16292 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 16293 break; 16294 case BCN_OFFLD_CTRL_TX_ENABLE: 16295 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 16296 break; 16297 case BCN_OFFLD_CTRL_SWBA_DISABLE: 16298 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 16299 break; 16300 case BCN_OFFLD_CTRL_SWBA_ENABLE: 16301 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 16302 break; 16303 default: 16304 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 16305 bcn_ctrl_param->bcn_ctrl_op); 16306 wmi_buf_free(buf); 16307 return QDF_STATUS_E_FAILURE; 16308 break; 16309 } 16310 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16311 WMI_BCN_OFFLOAD_CTRL_CMDID); 16312 16313 if (QDF_IS_STATUS_ERROR(ret)) { 16314 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 16315 ret); 16316 wmi_buf_free(buf); 16317 } 16318 16319 return ret; 16320 } 16321 16322 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 16323 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 16324 struct nan_datapath_initiator_req *ndp_req) 16325 { 16326 uint16_t len; 16327 wmi_buf_t buf; 16328 uint8_t *tlv_ptr; 16329 QDF_STATUS status; 16330 wmi_channel *ch_tlv; 16331 wmi_ndp_initiator_req_fixed_param *cmd; 16332 uint32_t passphrase_len, service_name_len; 16333 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 16334 wmi_ndp_transport_ip_param *tcp_ip_param; 16335 16336 /* 16337 * WMI command expects 4 byte alligned len: 16338 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16339 */ 16340 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 16341 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 16342 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 16343 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 16344 service_name_len = 16345 qdf_roundup(ndp_req->service_name.service_name_len, 4); 16346 /* allocated memory for fixed params as well as variable size data */ 16347 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 16348 + ndp_cfg_len + ndp_app_info_len + pmk_len 16349 + passphrase_len + service_name_len; 16350 16351 if (ndp_req->is_ipv6_addr_present) 16352 len += sizeof(*tcp_ip_param); 16353 16354 buf = wmi_buf_alloc(wmi_handle, len); 16355 if (!buf) { 16356 WMI_LOGE("wmi_buf_alloc failed"); 16357 return QDF_STATUS_E_NOMEM; 16358 } 16359 16360 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 16361 WMITLV_SET_HDR(&cmd->tlv_header, 16362 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 16363 WMITLV_GET_STRUCT_TLVLEN( 16364 wmi_ndp_initiator_req_fixed_param)); 16365 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 16366 cmd->transaction_id = ndp_req->transaction_id; 16367 cmd->service_instance_id = ndp_req->service_instance_id; 16368 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 16369 &cmd->peer_discovery_mac_addr); 16370 16371 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 16372 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 16373 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 16374 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 16375 cmd->nan_csid = ndp_req->ncs_sk_type; 16376 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 16377 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 16378 16379 ch_tlv = (wmi_channel *)&cmd[1]; 16380 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 16381 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16382 ch_tlv->mhz = ndp_req->channel; 16383 tlv_ptr = (uint8_t *)&ch_tlv[1]; 16384 16385 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16386 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16387 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16388 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16389 16390 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16391 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16392 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 16393 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16394 16395 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16396 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 16397 cmd->nan_pmk_len); 16398 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16399 16400 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16401 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 16402 cmd->nan_passphrase_len); 16403 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16404 16405 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16406 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16407 ndp_req->service_name.service_name, 16408 cmd->nan_servicename_len); 16409 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16410 16411 if (ndp_req->is_ipv6_addr_present) { 16412 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16413 WMITLV_SET_HDR(tcp_ip_param, 16414 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16415 WMITLV_GET_STRUCT_TLVLEN( 16416 wmi_ndp_transport_ip_param)); 16417 tcp_ip_param->ipv6_addr_present = true; 16418 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16419 ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16420 } 16421 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16422 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr); 16423 16424 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 16425 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 16426 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 16427 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16428 cmd->peer_discovery_mac_addr.mac_addr31to0, 16429 cmd->peer_discovery_mac_addr.mac_addr47to32); 16430 16431 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 16432 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16433 ndp_req->ndp_config.ndp_cfg, 16434 ndp_req->ndp_config.ndp_cfg_len); 16435 16436 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 16437 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16438 ndp_req->ndp_info.ndp_app_info, 16439 ndp_req->ndp_info.ndp_app_info_len); 16440 16441 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16442 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16443 ndp_req->pmk.pmk, cmd->nan_pmk_len); 16444 16445 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16446 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16447 ndp_req->passphrase.passphrase, 16448 cmd->nan_passphrase_len); 16449 16450 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16451 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16452 ndp_req->service_name.service_name, 16453 cmd->nan_servicename_len); 16454 16455 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 16456 WMI_NDP_INITIATOR_REQ_CMDID); 16457 16458 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16459 WMI_NDP_INITIATOR_REQ_CMDID); 16460 if (QDF_IS_STATUS_ERROR(status)) { 16461 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 16462 wmi_buf_free(buf); 16463 } 16464 16465 return status; 16466 } 16467 16468 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 16469 struct nan_datapath_responder_req *req) 16470 { 16471 uint16_t len; 16472 wmi_buf_t buf; 16473 uint8_t *tlv_ptr; 16474 QDF_STATUS status; 16475 wmi_ndp_responder_req_fixed_param *cmd; 16476 wmi_ndp_transport_ip_param *tcp_ip_param; 16477 uint32_t passphrase_len, service_name_len; 16478 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 16479 16480 vdev_id = wlan_vdev_get_id(req->vdev); 16481 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 16482 vdev_id, req->transaction_id, 16483 req->ndp_rsp, 16484 req->ndp_instance_id, 16485 req->ndp_info.ndp_app_info_len); 16486 16487 /* 16488 * WMI command expects 4 byte alligned len: 16489 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16490 */ 16491 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 16492 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 16493 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 16494 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 16495 service_name_len = 16496 qdf_roundup(req->service_name.service_name_len, 4); 16497 16498 /* allocated memory for fixed params as well as variable size data */ 16499 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 16500 + pmk_len + passphrase_len + service_name_len; 16501 16502 if (req->is_ipv6_addr_present || req->is_port_present || 16503 req->is_protocol_present) 16504 len += sizeof(*tcp_ip_param); 16505 16506 buf = wmi_buf_alloc(wmi_handle, len); 16507 if (!buf) { 16508 WMI_LOGE("wmi_buf_alloc failed"); 16509 return QDF_STATUS_E_NOMEM; 16510 } 16511 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 16512 WMITLV_SET_HDR(&cmd->tlv_header, 16513 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 16514 WMITLV_GET_STRUCT_TLVLEN( 16515 wmi_ndp_responder_req_fixed_param)); 16516 cmd->vdev_id = vdev_id; 16517 cmd->transaction_id = req->transaction_id; 16518 cmd->ndp_instance_id = req->ndp_instance_id; 16519 cmd->rsp_code = req->ndp_rsp; 16520 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 16521 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 16522 cmd->nan_pmk_len = req->pmk.pmk_len; 16523 cmd->nan_csid = req->ncs_sk_type; 16524 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 16525 cmd->nan_servicename_len = req->service_name.service_name_len; 16526 16527 tlv_ptr = (uint8_t *)&cmd[1]; 16528 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16529 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16530 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16531 16532 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16533 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16534 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16535 req->ndp_info.ndp_app_info, 16536 req->ndp_info.ndp_app_info_len); 16537 16538 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16539 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16540 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 16541 cmd->nan_pmk_len); 16542 16543 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16544 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16545 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16546 req->passphrase.passphrase, 16547 cmd->nan_passphrase_len); 16548 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16549 16550 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16551 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16552 req->service_name.service_name, 16553 cmd->nan_servicename_len); 16554 16555 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16556 16557 if (req->is_ipv6_addr_present || req->is_port_present || 16558 req->is_protocol_present) { 16559 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16560 WMITLV_SET_HDR(tcp_ip_param, 16561 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16562 WMITLV_GET_STRUCT_TLVLEN( 16563 wmi_ndp_transport_ip_param)); 16564 tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present; 16565 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16566 req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16567 16568 tcp_ip_param->trans_port_present = req->is_port_present; 16569 tcp_ip_param->transport_port = req->port; 16570 16571 tcp_ip_param->trans_proto_present = req->is_protocol_present; 16572 tcp_ip_param->transport_protocol = req->protocol; 16573 } 16574 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16575 req->is_ipv6_addr_present, req->ipv6_addr); 16576 WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port); 16577 WMI_LOGD(FL("protocol: %d present: %d"), 16578 req->is_protocol_present, req->protocol); 16579 16580 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 16581 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 16582 16583 WMI_LOGD("ndp_config len: %d", 16584 req->ndp_config.ndp_cfg_len); 16585 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16586 req->ndp_config.ndp_cfg, 16587 req->ndp_config.ndp_cfg_len); 16588 16589 WMI_LOGD("ndp_app_info len: %d", 16590 req->ndp_info.ndp_app_info_len); 16591 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16592 req->ndp_info.ndp_app_info, 16593 req->ndp_info.ndp_app_info_len); 16594 16595 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16596 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16597 req->pmk.pmk, cmd->nan_pmk_len); 16598 16599 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16600 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16601 req->passphrase.passphrase, 16602 cmd->nan_passphrase_len); 16603 16604 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16605 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16606 req->service_name.service_name, 16607 cmd->nan_servicename_len); 16608 16609 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 16610 WMI_NDP_RESPONDER_REQ_CMDID); 16611 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16612 WMI_NDP_RESPONDER_REQ_CMDID); 16613 if (QDF_IS_STATUS_ERROR(status)) { 16614 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 16615 wmi_buf_free(buf); 16616 } 16617 return status; 16618 } 16619 16620 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 16621 struct nan_datapath_end_req *req) 16622 { 16623 uint16_t len; 16624 wmi_buf_t buf; 16625 QDF_STATUS status; 16626 uint32_t ndp_end_req_len, i; 16627 wmi_ndp_end_req *ndp_end_req_lst; 16628 wmi_ndp_end_req_fixed_param *cmd; 16629 16630 /* len of tlv following fixed param */ 16631 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 16632 /* above comes out to 4 byte alligned already, no need of padding */ 16633 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 16634 buf = wmi_buf_alloc(wmi_handle, len); 16635 if (!buf) { 16636 WMI_LOGE("Malloc failed"); 16637 return QDF_STATUS_E_NOMEM; 16638 } 16639 16640 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 16641 WMITLV_SET_HDR(&cmd->tlv_header, 16642 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 16643 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 16644 16645 cmd->transaction_id = req->transaction_id; 16646 16647 /* set tlv pointer to end of fixed param */ 16648 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 16649 ndp_end_req_len); 16650 16651 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 16652 WMI_TLV_HDR_SIZE); 16653 for (i = 0; i < req->num_ndp_instances; i++) { 16654 WMITLV_SET_HDR(&ndp_end_req_lst[i], 16655 WMITLV_TAG_ARRAY_FIXED_STRUC, 16656 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 16657 16658 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 16659 } 16660 16661 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 16662 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16663 WMI_NDP_END_REQ_CMDID); 16664 if (QDF_IS_STATUS_ERROR(status)) { 16665 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 16666 wmi_buf_free(buf); 16667 } 16668 16669 return status; 16670 } 16671 16672 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 16673 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 16674 { 16675 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 16676 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 16677 16678 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 16679 fixed_params = event->fixed_param; 16680 16681 rsp->vdev = 16682 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16683 fixed_params->vdev_id, 16684 WLAN_NAN_ID); 16685 if (!rsp->vdev) { 16686 WMI_LOGE("vdev is null"); 16687 return QDF_STATUS_E_INVAL; 16688 } 16689 16690 rsp->transaction_id = fixed_params->transaction_id; 16691 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16692 rsp->status = fixed_params->rsp_status; 16693 rsp->reason = fixed_params->reason_code; 16694 16695 return QDF_STATUS_SUCCESS; 16696 } 16697 16698 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 16699 uint8_t *data, struct nan_datapath_indication_event *rsp) 16700 { 16701 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 16702 wmi_ndp_indication_event_fixed_param *fixed_params; 16703 size_t total_array_len; 16704 16705 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 16706 fixed_params = 16707 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 16708 16709 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16710 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16711 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16712 return QDF_STATUS_E_INVAL; 16713 } 16714 16715 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16716 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16717 fixed_params->ndp_app_info_len, 16718 event->num_ndp_app_info); 16719 return QDF_STATUS_E_INVAL; 16720 } 16721 16722 if (fixed_params->ndp_cfg_len > 16723 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16724 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16725 __func__, fixed_params->ndp_cfg_len); 16726 return QDF_STATUS_E_INVAL; 16727 } 16728 16729 total_array_len = fixed_params->ndp_cfg_len + 16730 sizeof(*fixed_params); 16731 16732 if (fixed_params->ndp_app_info_len > 16733 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16734 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16735 __func__, fixed_params->ndp_app_info_len); 16736 return QDF_STATUS_E_INVAL; 16737 } 16738 total_array_len += fixed_params->ndp_app_info_len; 16739 16740 if (fixed_params->nan_scid_len > 16741 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16742 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16743 __func__, fixed_params->nan_scid_len); 16744 return QDF_STATUS_E_INVAL; 16745 } 16746 16747 rsp->vdev = 16748 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16749 fixed_params->vdev_id, 16750 WLAN_NAN_ID); 16751 if (!rsp->vdev) { 16752 WMI_LOGE("vdev is null"); 16753 return QDF_STATUS_E_INVAL; 16754 } 16755 rsp->service_instance_id = fixed_params->service_instance_id; 16756 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16757 rsp->role = fixed_params->self_ndp_role; 16758 rsp->policy = fixed_params->accept_policy; 16759 16760 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16761 rsp->peer_mac_addr.bytes); 16762 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 16763 rsp->peer_discovery_mac_addr.bytes); 16764 16765 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 16766 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 16767 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 16768 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 16769 fixed_params->service_instance_id, 16770 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 16771 fixed_params->accept_policy, 16772 fixed_params->nan_csid, fixed_params->nan_scid_len, 16773 rsp->peer_mac_addr.bytes, 16774 rsp->peer_discovery_mac_addr.bytes); 16775 16776 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16777 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16778 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16779 16780 WMI_LOGD("ndp_app_info - %d bytes", 16781 fixed_params->ndp_app_info_len); 16782 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16783 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16784 16785 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 16786 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16787 rsp->ncs_sk_type = fixed_params->nan_csid; 16788 rsp->scid.scid_len = fixed_params->nan_scid_len; 16789 16790 if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN) 16791 rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN; 16792 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 16793 rsp->ndp_config.ndp_cfg_len); 16794 16795 if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN) 16796 rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN; 16797 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16798 rsp->ndp_info.ndp_app_info_len); 16799 16800 if (rsp->scid.scid_len > NDP_SCID_BUF_LEN) 16801 rsp->scid.scid_len = NDP_SCID_BUF_LEN; 16802 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 16803 16804 if (event->ndp_transport_ip_param && 16805 event->num_ndp_transport_ip_param) { 16806 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16807 rsp->is_ipv6_addr_present = true; 16808 qdf_mem_copy(rsp->ipv6_addr, 16809 event->ndp_transport_ip_param->ipv6_intf_addr, 16810 WMI_NDP_IPV6_INTF_ADDR_LEN); 16811 } 16812 } 16813 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16814 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16815 16816 WMI_LOGD("scid hex dump:"); 16817 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16818 rsp->scid.scid, rsp->scid.scid_len); 16819 16820 return QDF_STATUS_SUCCESS; 16821 } 16822 16823 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 16824 uint8_t *data, struct nan_datapath_confirm_event *rsp) 16825 { 16826 uint8_t i; 16827 WMI_HOST_WLAN_PHY_MODE ch_mode; 16828 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 16829 wmi_ndp_confirm_event_fixed_param *fixed_params; 16830 size_t total_array_len; 16831 16832 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 16833 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 16834 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", 16835 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 16836 fixed_params->ndp_instance_id, fixed_params->rsp_code, 16837 fixed_params->reason_code, 16838 fixed_params->num_active_ndps_on_peer); 16839 WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels); 16840 16841 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16842 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16843 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16844 return QDF_STATUS_E_INVAL; 16845 } 16846 16847 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16848 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16849 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16850 16851 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16852 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16853 fixed_params->ndp_app_info_len, 16854 event->num_ndp_app_info); 16855 return QDF_STATUS_E_INVAL; 16856 } 16857 16858 WMI_LOGD("ndp_app_info - %d bytes", 16859 fixed_params->ndp_app_info_len); 16860 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16861 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16862 16863 if (fixed_params->ndp_cfg_len > 16864 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16865 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16866 __func__, fixed_params->ndp_cfg_len); 16867 return QDF_STATUS_E_INVAL; 16868 } 16869 16870 total_array_len = fixed_params->ndp_cfg_len + 16871 sizeof(*fixed_params); 16872 16873 if (fixed_params->ndp_app_info_len > 16874 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16875 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16876 __func__, fixed_params->ndp_app_info_len); 16877 return QDF_STATUS_E_INVAL; 16878 } 16879 16880 rsp->vdev = 16881 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16882 fixed_params->vdev_id, 16883 WLAN_NAN_ID); 16884 if (!rsp->vdev) { 16885 WMI_LOGE("vdev is null"); 16886 return QDF_STATUS_E_INVAL; 16887 } 16888 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16889 rsp->rsp_code = fixed_params->rsp_code; 16890 rsp->reason_code = fixed_params->reason_code; 16891 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 16892 rsp->num_channels = fixed_params->num_ndp_channels; 16893 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16894 rsp->peer_ndi_mac_addr.bytes); 16895 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16896 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16897 rsp->ndp_info.ndp_app_info_len); 16898 16899 if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 16900 WMI_LOGE(FL("too many channels")); 16901 rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS; 16902 } 16903 16904 for (i = 0; i < rsp->num_channels; i++) { 16905 rsp->ch[i].channel = event->ndp_channel_list[i].mhz; 16906 rsp->ch[i].nss = event->nss_list[i]; 16907 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]); 16908 rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 16909 ch_mode); 16910 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 16911 rsp->ch[i].channel, 16912 rsp->ch[i].ch_width, 16913 rsp->ch[i].nss); 16914 } 16915 16916 if (event->ndp_transport_ip_param && 16917 event->num_ndp_transport_ip_param) { 16918 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16919 rsp->is_ipv6_addr_present = true; 16920 qdf_mem_copy(rsp->ipv6_addr, 16921 event->ndp_transport_ip_param->ipv6_intf_addr, 16922 WMI_NDP_IPV6_INTF_ADDR_LEN); 16923 } 16924 16925 if (event->ndp_transport_ip_param->trans_port_present) { 16926 rsp->is_port_present = true; 16927 rsp->port = 16928 event->ndp_transport_ip_param->transport_port; 16929 } 16930 16931 if (event->ndp_transport_ip_param->trans_proto_present) { 16932 rsp->is_protocol_present = true; 16933 rsp->protocol = 16934 event->ndp_transport_ip_param->transport_protocol; 16935 } 16936 } 16937 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16938 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16939 WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present); 16940 WMI_LOGD(FL("protocol: %d present: %d"), 16941 rsp->protocol, rsp->is_protocol_present); 16942 16943 return QDF_STATUS_SUCCESS; 16944 } 16945 16946 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 16947 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 16948 { 16949 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 16950 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 16951 16952 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 16953 fixed_params = event->fixed_param; 16954 16955 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", 16956 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 16957 rsp->peer_mac_addr.bytes, rsp->transaction_id, 16958 rsp->status, rsp->reason, rsp->create_peer); 16959 16960 rsp->vdev = 16961 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16962 fixed_params->vdev_id, 16963 WLAN_NAN_ID); 16964 if (!rsp->vdev) { 16965 WMI_LOGE("vdev is null"); 16966 return QDF_STATUS_E_INVAL; 16967 } 16968 rsp->transaction_id = fixed_params->transaction_id; 16969 rsp->reason = fixed_params->reason_code; 16970 rsp->status = fixed_params->rsp_status; 16971 rsp->create_peer = fixed_params->create_peer; 16972 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16973 rsp->peer_mac_addr.bytes); 16974 16975 return QDF_STATUS_SUCCESS; 16976 } 16977 16978 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 16979 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 16980 { 16981 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 16982 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 16983 16984 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 16985 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 16986 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 16987 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 16988 fixed_params->rsp_status, fixed_params->reason_code); 16989 16990 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 16991 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 16992 if (!rsp->vdev) { 16993 WMI_LOGE("vdev is null"); 16994 return QDF_STATUS_E_INVAL; 16995 } 16996 rsp->transaction_id = fixed_params->transaction_id; 16997 rsp->reason = fixed_params->reason_code; 16998 rsp->status = fixed_params->rsp_status; 16999 17000 return QDF_STATUS_SUCCESS; 17001 } 17002 17003 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17004 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17005 { 17006 uint32_t i, buf_size; 17007 wmi_ndp_end_indication *ind; 17008 struct qdf_mac_addr peer_addr; 17009 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17010 17011 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17012 ind = event->ndp_end_indication_list; 17013 17014 if (event->num_ndp_end_indication_list == 0) { 17015 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17016 return QDF_STATUS_E_INVAL; 17017 } 17018 17019 WMI_LOGD("number of ndp instances = %d", 17020 event->num_ndp_end_indication_list); 17021 17022 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17023 sizeof((*rsp)->ndp_map[0]))) { 17024 WMI_LOGE("num_ndp_end_ind_list %d too large", 17025 event->num_ndp_end_indication_list); 17026 return QDF_STATUS_E_INVAL; 17027 } 17028 17029 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17030 sizeof((*rsp)->ndp_map[0]); 17031 *rsp = qdf_mem_malloc(buf_size); 17032 if (!(*rsp)) { 17033 WMI_LOGE("Failed to allocate memory"); 17034 return QDF_STATUS_E_NOMEM; 17035 } 17036 17037 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17038 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17039 if (!(*rsp)->vdev) { 17040 WMI_LOGE("vdev is null"); 17041 qdf_mem_free(*rsp); 17042 *rsp = NULL; 17043 return QDF_STATUS_E_INVAL; 17044 } 17045 17046 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17047 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17048 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17049 peer_addr.bytes); 17050 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17051 i, ind[i].type, ind[i].reason_code, 17052 ind[i].ndp_instance_id, 17053 ind[i].num_active_ndps_on_peer); 17054 /* Add each instance entry to the list */ 17055 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17056 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17057 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17058 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17059 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17060 ind[i].num_active_ndps_on_peer; 17061 (*rsp)->ndp_map[i].type = ind[i].type; 17062 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17063 } 17064 17065 return QDF_STATUS_SUCCESS; 17066 } 17067 17068 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 17069 uint8_t *data, struct nan_datapath_sch_update_event *ind) 17070 { 17071 uint8_t i; 17072 WMI_HOST_WLAN_PHY_MODE ch_mode; 17073 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 17074 wmi_ndl_schedule_update_fixed_param *fixed_params; 17075 17076 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 17077 fixed_params = event->fixed_param; 17078 17079 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 17080 fixed_params->flags, fixed_params->num_channels, 17081 fixed_params->num_ndp_instances); 17082 17083 ind->vdev = 17084 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17085 fixed_params->vdev_id, 17086 WLAN_NAN_ID); 17087 if (!ind->vdev) { 17088 WMI_LOGE("vdev is null"); 17089 return QDF_STATUS_E_INVAL; 17090 } 17091 17092 ind->flags = fixed_params->flags; 17093 ind->num_channels = fixed_params->num_channels; 17094 ind->num_ndp_instances = fixed_params->num_ndp_instances; 17095 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 17096 ind->peer_addr.bytes); 17097 17098 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 17099 WMI_LOGE(FL("uint32 overflow")); 17100 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 17101 return QDF_STATUS_E_INVAL; 17102 } 17103 17104 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 17105 sizeof(uint32_t) * ind->num_ndp_instances); 17106 17107 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 17108 WMI_LOGE(FL("too many channels")); 17109 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 17110 } 17111 for (i = 0; i < ind->num_channels; i++) { 17112 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 17113 ind->ch[i].nss = event->nss_list[i]; 17114 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 17115 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 17116 ch_mode); 17117 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 17118 ind->ch[i].channel, 17119 ind->ch[i].ch_width, 17120 ind->ch[i].nss); 17121 } 17122 17123 for (i = 0; i < fixed_params->num_ndp_instances; i++) 17124 WMI_LOGD(FL("instance_id[%d]: %d"), 17125 i, event->ndp_instance_list[i]); 17126 17127 return QDF_STATUS_SUCCESS; 17128 } 17129 17130 #endif 17131 17132 #ifdef QCA_SUPPORT_CP_STATS 17133 /** 17134 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17135 * @wmi_handle: wma handle 17136 * @evt_buf: event buffer 17137 * @out_buff: buffer to populated after stats extraction 17138 * 17139 * Return: status of operation 17140 */ 17141 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17142 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17143 { 17144 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17145 wmi_congestion_stats *congestion_stats; 17146 17147 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17148 congestion_stats = param_buf->congestion_stats; 17149 if (!congestion_stats) { 17150 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17151 return QDF_STATUS_E_INVAL; 17152 } 17153 17154 out_buff->vdev_id = congestion_stats->vdev_id; 17155 out_buff->congestion = congestion_stats->congestion; 17156 17157 WMI_LOGD("%s: cca stats event processed", __func__); 17158 return QDF_STATUS_SUCCESS; 17159 } 17160 #endif /* QCA_SUPPORT_CP_STATS */ 17161 17162 /** 17163 * save_service_bitmap_tlv() - save service bitmap 17164 * @wmi_handle: wmi handle 17165 * @param evt_buf: pointer to event buffer 17166 * @param bitmap_buf: bitmap buffer, for converged legacy support 17167 * 17168 * Return: QDF_STATUS 17169 */ 17170 static 17171 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17172 void *bitmap_buf) 17173 { 17174 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17175 struct wmi_soc *soc = wmi_handle->soc; 17176 17177 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17178 17179 /* If it is already allocated, use that buffer. This can happen 17180 * during target stop/start scenarios where host allocation is skipped. 17181 */ 17182 if (!soc->wmi_service_bitmap) { 17183 soc->wmi_service_bitmap = 17184 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17185 if (!soc->wmi_service_bitmap) { 17186 WMI_LOGE("Failed memory allocation for service bitmap"); 17187 return QDF_STATUS_E_NOMEM; 17188 } 17189 } 17190 17191 qdf_mem_copy(soc->wmi_service_bitmap, 17192 param_buf->wmi_service_bitmap, 17193 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17194 17195 if (bitmap_buf) 17196 qdf_mem_copy(bitmap_buf, 17197 param_buf->wmi_service_bitmap, 17198 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17199 17200 return QDF_STATUS_SUCCESS; 17201 } 17202 17203 /** 17204 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17205 * @wmi_handle: wmi handle 17206 * @param evt_buf: pointer to event buffer 17207 * @param bitmap_buf: bitmap buffer, for converged legacy support 17208 * 17209 * Return: QDF_STATUS 17210 */ 17211 static 17212 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17213 void *bitmap_buf) 17214 { 17215 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17216 wmi_service_available_event_fixed_param *ev; 17217 struct wmi_soc *soc = wmi_handle->soc; 17218 17219 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17220 17221 ev = param_buf->fixed_param; 17222 17223 /* If it is already allocated, use that buffer. This can happen 17224 * during target stop/start scenarios where host allocation is skipped. 17225 */ 17226 if (!soc->wmi_ext_service_bitmap) { 17227 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17228 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17229 if (!soc->wmi_ext_service_bitmap) { 17230 WMI_LOGE("Failed memory allocation for service bitmap"); 17231 return QDF_STATUS_E_NOMEM; 17232 } 17233 } 17234 17235 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17236 ev->wmi_service_segment_bitmap, 17237 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17238 17239 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17240 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17241 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17242 17243 if (bitmap_buf) 17244 qdf_mem_copy(bitmap_buf, 17245 soc->wmi_ext_service_bitmap, 17246 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17247 17248 return QDF_STATUS_SUCCESS; 17249 } 17250 /** 17251 * is_service_enabled_tlv() - Check if service enabled 17252 * @param wmi_handle: wmi handle 17253 * @param service_id: service identifier 17254 * 17255 * Return: 1 enabled, 0 disabled 17256 */ 17257 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17258 uint32_t service_id) 17259 { 17260 struct wmi_soc *soc = wmi_handle->soc; 17261 17262 if (!soc->wmi_service_bitmap) { 17263 WMI_LOGE("WMI service bit map is not saved yet\n"); 17264 return false; 17265 } 17266 17267 /* if wmi_service_enabled was received with extended bitmap, 17268 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17269 */ 17270 if (soc->wmi_ext_service_bitmap) 17271 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17272 soc->wmi_ext_service_bitmap, 17273 service_id); 17274 17275 if (service_id >= WMI_MAX_SERVICE) { 17276 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 17277 service_id); 17278 return false; 17279 } 17280 17281 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17282 service_id); 17283 } 17284 17285 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17286 struct wlan_psoc_target_capability_info *cap) 17287 { 17288 /* except LDPC all flags are common betwen legacy and here 17289 * also IBFEER is not defined for TLV 17290 */ 17291 cap->ht_cap_info |= ev_target_cap & ( 17292 WMI_HT_CAP_ENABLED 17293 | WMI_HT_CAP_HT20_SGI 17294 | WMI_HT_CAP_DYNAMIC_SMPS 17295 | WMI_HT_CAP_TX_STBC 17296 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17297 | WMI_HT_CAP_RX_STBC 17298 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17299 | WMI_HT_CAP_LDPC 17300 | WMI_HT_CAP_L_SIG_TXOP_PROT 17301 | WMI_HT_CAP_MPDU_DENSITY 17302 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17303 | WMI_HT_CAP_HT40_SGI); 17304 if (ev_target_cap & WMI_HT_CAP_LDPC) 17305 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17306 WMI_HOST_HT_CAP_TX_LDPC; 17307 } 17308 /** 17309 * extract_service_ready_tlv() - extract service ready event 17310 * @wmi_handle: wmi handle 17311 * @param evt_buf: pointer to received event buffer 17312 * @param cap: pointer to hold target capability information extracted from even 17313 * 17314 * Return: QDF_STATUS_SUCCESS for success or error code 17315 */ 17316 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17317 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17318 { 17319 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17320 wmi_service_ready_event_fixed_param *ev; 17321 17322 17323 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17324 17325 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17326 if (!ev) { 17327 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17328 return QDF_STATUS_E_FAILURE; 17329 } 17330 17331 cap->phy_capability = ev->phy_capability; 17332 cap->max_frag_entry = ev->max_frag_entry; 17333 cap->num_rf_chains = ev->num_rf_chains; 17334 copy_ht_cap_info(ev->ht_cap_info, cap); 17335 cap->vht_cap_info = ev->vht_cap_info; 17336 cap->vht_supp_mcs = ev->vht_supp_mcs; 17337 cap->hw_min_tx_power = ev->hw_min_tx_power; 17338 cap->hw_max_tx_power = ev->hw_max_tx_power; 17339 cap->sys_cap_info = ev->sys_cap_info; 17340 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17341 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17342 cap->max_num_scan_channels = ev->max_num_scan_channels; 17343 cap->max_supported_macs = ev->max_supported_macs; 17344 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17345 cap->txrx_chainmask = ev->txrx_chainmask; 17346 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17347 cap->num_msdu_desc = ev->num_msdu_desc; 17348 cap->fw_version = ev->fw_build_vers; 17349 /* fw_version_1 is not available in TLV. */ 17350 cap->fw_version_1 = 0; 17351 17352 return QDF_STATUS_SUCCESS; 17353 } 17354 17355 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 17356 * to host internal WMI_HOST_REGDMN_MODE values. 17357 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 17358 * host currently. Add this in the future if required. 17359 * 11AX (Phase II) : 11ax related values are not currently 17360 * advertised separately by FW. As part of phase II regulatory bring-up, 17361 * finalize the advertisement mechanism. 17362 * @target_wireless_mode: target wireless mode received in message 17363 * 17364 * Return: returns the host internal wireless mode. 17365 */ 17366 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 17367 { 17368 17369 uint32_t wireless_modes = 0; 17370 17371 if (target_wireless_mode & REGDMN_MODE_11A) 17372 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 17373 17374 if (target_wireless_mode & REGDMN_MODE_TURBO) 17375 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 17376 17377 if (target_wireless_mode & REGDMN_MODE_11B) 17378 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 17379 17380 if (target_wireless_mode & REGDMN_MODE_PUREG) 17381 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 17382 17383 if (target_wireless_mode & REGDMN_MODE_11G) 17384 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 17385 17386 if (target_wireless_mode & REGDMN_MODE_108G) 17387 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 17388 17389 if (target_wireless_mode & REGDMN_MODE_108A) 17390 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 17391 17392 if (target_wireless_mode & REGDMN_MODE_XR) 17393 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 17394 17395 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 17396 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 17397 17398 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 17399 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 17400 17401 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 17402 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 17403 17404 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 17405 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 17406 17407 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 17408 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 17409 17410 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 17411 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 17412 17413 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 17414 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 17415 17416 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 17417 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 17418 17419 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 17420 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 17421 17422 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 17423 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 17424 17425 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 17426 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 17427 17428 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 17429 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 17430 17431 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 17432 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 17433 17434 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 17435 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 17436 17437 return wireless_modes; 17438 } 17439 17440 /** 17441 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 17442 * @wmi_handle: wmi handle 17443 * @param evt_buf: Pointer to event buffer 17444 * @param cap: pointer to hold HAL reg capabilities 17445 * 17446 * Return: QDF_STATUS_SUCCESS for success or error code 17447 */ 17448 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 17449 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 17450 { 17451 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17452 17453 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17454 17455 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 17456 sizeof(uint32_t)), 17457 sizeof(struct wlan_psoc_hal_reg_capability)); 17458 17459 cap->wireless_modes = convert_wireless_modes_tlv( 17460 param_buf->hal_reg_capabilities->wireless_modes); 17461 17462 return QDF_STATUS_SUCCESS; 17463 } 17464 17465 /** 17466 * extract_host_mem_req_tlv() - Extract host memory request event 17467 * @wmi_handle: wmi handle 17468 * @param evt_buf: pointer to event buffer 17469 * @param num_entries: pointer to hold number of entries requested 17470 * 17471 * Return: Number of entries requested 17472 */ 17473 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 17474 void *evt_buf, uint8_t *num_entries) 17475 { 17476 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17477 wmi_service_ready_event_fixed_param *ev; 17478 17479 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17480 17481 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17482 if (!ev) { 17483 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17484 return NULL; 17485 } 17486 17487 *num_entries = ev->num_mem_reqs; 17488 17489 return (host_mem_req *)param_buf->mem_reqs; 17490 } 17491 17492 /** 17493 * save_fw_version_in_service_ready_tlv() - Save fw version in service 17494 * ready function 17495 * @wmi_handle: wmi handle 17496 * @param evt_buf: pointer to event buffer 17497 * 17498 * Return: QDF_STATUS_SUCCESS for success or error code 17499 */ 17500 static QDF_STATUS 17501 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 17502 { 17503 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17504 wmi_service_ready_event_fixed_param *ev; 17505 17506 17507 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17508 17509 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17510 if (!ev) { 17511 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 17512 return QDF_STATUS_E_FAILURE; 17513 } 17514 17515 /*Save fw version from service ready message */ 17516 /*This will be used while sending INIT message */ 17517 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 17518 sizeof(wmi_handle->fw_abi_version)); 17519 17520 return QDF_STATUS_SUCCESS; 17521 } 17522 17523 /** 17524 * ready_extract_init_status_tlv() - Extract init status from ready event 17525 * @wmi_handle: wmi handle 17526 * @param evt_buf: Pointer to event buffer 17527 * 17528 * Return: ready status 17529 */ 17530 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 17531 void *evt_buf) 17532 { 17533 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17534 wmi_ready_event_fixed_param *ev = NULL; 17535 17536 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17537 ev = param_buf->fixed_param; 17538 17539 qdf_print("%s:%d\n", __func__, ev->status); 17540 17541 return ev->status; 17542 } 17543 17544 /** 17545 * ready_extract_mac_addr_tlv() - extract mac address from ready event 17546 * @wmi_handle: wmi handle 17547 * @param evt_buf: pointer to event buffer 17548 * @param macaddr: Pointer to hold MAC address 17549 * 17550 * Return: QDF_STATUS_SUCCESS for success or error code 17551 */ 17552 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 17553 void *evt_buf, uint8_t *macaddr) 17554 { 17555 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17556 wmi_ready_event_fixed_param *ev = NULL; 17557 17558 17559 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17560 ev = param_buf->fixed_param; 17561 17562 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 17563 17564 return QDF_STATUS_SUCCESS; 17565 } 17566 17567 /** 17568 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 17569 * @wmi_handle: wmi handle 17570 * @param evt_buf: pointer to event buffer 17571 * @param macaddr: Pointer to hold number of MAC addresses 17572 * 17573 * Return: Pointer to addr list 17574 */ 17575 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 17576 void *evt_buf, uint8_t *num_mac) 17577 { 17578 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17579 wmi_ready_event_fixed_param *ev = NULL; 17580 17581 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17582 ev = param_buf->fixed_param; 17583 17584 *num_mac = ev->num_extra_mac_addr; 17585 17586 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 17587 } 17588 17589 /** 17590 * extract_ready_params_tlv() - Extract data from ready event apart from 17591 * status, macaddr and version. 17592 * @wmi_handle: Pointer to WMI handle. 17593 * @evt_buf: Pointer to Ready event buffer. 17594 * @ev_param: Pointer to host defined struct to copy the data from event. 17595 * 17596 * Return: QDF_STATUS_SUCCESS on success. 17597 */ 17598 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 17599 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 17600 { 17601 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17602 wmi_ready_event_fixed_param *ev = NULL; 17603 17604 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17605 ev = param_buf->fixed_param; 17606 17607 ev_param->status = ev->status; 17608 ev_param->num_dscp_table = ev->num_dscp_table; 17609 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 17610 ev_param->num_total_peer = ev->num_total_peers; 17611 ev_param->num_extra_peer = ev->num_extra_peers; 17612 /* Agile_cap in ready event is not supported in TLV target */ 17613 ev_param->agile_capability = false; 17614 17615 return QDF_STATUS_SUCCESS; 17616 } 17617 17618 /** 17619 * extract_dbglog_data_len_tlv() - extract debuglog data length 17620 * @wmi_handle: wmi handle 17621 * @param evt_buf: pointer to event buffer 17622 * 17623 * Return: length 17624 */ 17625 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 17626 void *evt_buf, uint32_t *len) 17627 { 17628 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 17629 17630 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 17631 17632 *len = param_buf->num_bufp; 17633 17634 return param_buf->bufp; 17635 } 17636 17637 /** 17638 * extract_vdev_start_resp_tlv() - extract vdev start response 17639 * @wmi_handle: wmi handle 17640 * @param evt_buf: pointer to event buffer 17641 * @param vdev_rsp: Pointer to hold vdev response 17642 * 17643 * Return: QDF_STATUS_SUCCESS for success or error code 17644 */ 17645 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 17646 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 17647 { 17648 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 17649 wmi_vdev_start_response_event_fixed_param *ev; 17650 17651 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 17652 if (!param_buf) { 17653 qdf_print("Invalid start response event buffer\n"); 17654 return QDF_STATUS_E_INVAL; 17655 } 17656 17657 ev = param_buf->fixed_param; 17658 if (!ev) { 17659 qdf_print("Invalid start response event buffer\n"); 17660 return QDF_STATUS_E_INVAL; 17661 } 17662 17663 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 17664 17665 vdev_rsp->vdev_id = ev->vdev_id; 17666 vdev_rsp->requestor_id = ev->requestor_id; 17667 switch (ev->resp_type) { 17668 case WMI_VDEV_START_RESP_EVENT: 17669 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 17670 break; 17671 case WMI_VDEV_RESTART_RESP_EVENT: 17672 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 17673 break; 17674 default: 17675 qdf_print("Invalid start response event buffer\n"); 17676 break; 17677 }; 17678 vdev_rsp->status = ev->status; 17679 vdev_rsp->chain_mask = ev->chain_mask; 17680 vdev_rsp->smps_mode = ev->smps_mode; 17681 vdev_rsp->mac_id = ev->mac_id; 17682 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 17683 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 17684 17685 return QDF_STATUS_SUCCESS; 17686 } 17687 17688 /** 17689 * extract_vdev_delete_resp_tlv() - extract vdev delete response 17690 * @wmi_handle: wmi handle 17691 * @param evt_buf: pointer to event buffer 17692 * @param delete_rsp: Pointer to hold vdev delete response 17693 * 17694 * Return: QDF_STATUS_SUCCESS for success or error code 17695 */ 17696 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 17697 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 17698 { 17699 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 17700 wmi_vdev_delete_resp_event_fixed_param *ev; 17701 17702 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 17703 if (!param_buf) { 17704 WMI_LOGE("Invalid vdev delete response event buffer\n"); 17705 return QDF_STATUS_E_INVAL; 17706 } 17707 17708 ev = param_buf->fixed_param; 17709 if (!ev) { 17710 WMI_LOGE("Invalid vdev delete response event\n"); 17711 return QDF_STATUS_E_INVAL; 17712 } 17713 17714 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 17715 delete_rsp->vdev_id = ev->vdev_id; 17716 17717 return QDF_STATUS_SUCCESS; 17718 } 17719 17720 17721 /** 17722 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 17723 * @wmi_handle: wmi handle 17724 * @param evt_buf: pointer to event buffer 17725 * @param num_vdevs: Pointer to hold num vdev 17726 * 17727 * Return: QDF_STATUS_SUCCESS for success or error code 17728 */ 17729 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17730 void *evt_buf, uint32_t *num_vdevs) 17731 { 17732 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17733 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17734 uint32_t vdev_map; 17735 17736 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 17737 if (!param_buf) { 17738 qdf_print("Invalid tbtt update ext event buffer\n"); 17739 return QDF_STATUS_E_INVAL; 17740 } 17741 tbtt_offset_event = param_buf->fixed_param; 17742 vdev_map = tbtt_offset_event->vdev_map; 17743 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 17744 17745 return QDF_STATUS_SUCCESS; 17746 } 17747 17748 /** 17749 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 17750 * @wmi_handle: wmi handle 17751 * @param evt_buf: pointer to event buffer 17752 * @param num_vdevs: Pointer to hold num vdev 17753 * 17754 * Return: QDF_STATUS_SUCCESS for success or error code 17755 */ 17756 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17757 void *evt_buf, uint32_t *num_vdevs) 17758 { 17759 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17760 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 17761 17762 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17763 if (!param_buf) { 17764 qdf_print("Invalid tbtt update ext event buffer\n"); 17765 return QDF_STATUS_E_INVAL; 17766 } 17767 tbtt_offset_ext_event = param_buf->fixed_param; 17768 17769 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 17770 17771 return QDF_STATUS_SUCCESS; 17772 } 17773 17774 /** 17775 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 17776 * @wmi_handle: wmi handle 17777 * @param evt_buf: pointer to event buffer 17778 * @param idx: Index referring to a vdev 17779 * @param tbtt_param: Pointer to tbttoffset event param 17780 * 17781 * Return: QDF_STATUS_SUCCESS for success or error code 17782 */ 17783 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 17784 void *evt_buf, uint8_t idx, 17785 struct tbttoffset_params *tbtt_param) 17786 { 17787 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17788 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17789 uint32_t vdev_map; 17790 17791 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 17792 if (!param_buf) { 17793 qdf_print("Invalid tbtt update event buffer\n"); 17794 return QDF_STATUS_E_INVAL; 17795 } 17796 17797 tbtt_offset_event = param_buf->fixed_param; 17798 vdev_map = tbtt_offset_event->vdev_map; 17799 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 17800 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 17801 return QDF_STATUS_E_INVAL; 17802 tbtt_param->tbttoffset = 17803 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 17804 17805 return QDF_STATUS_SUCCESS; 17806 } 17807 17808 /** 17809 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 17810 * @wmi_handle: wmi handle 17811 * @param evt_buf: pointer to event buffer 17812 * @param idx: Index referring to a vdev 17813 * @param tbtt_param: Pointer to tbttoffset event param 17814 * 17815 * Return: QDF_STATUS_SUCCESS for success or error code 17816 */ 17817 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 17818 void *evt_buf, uint8_t idx, 17819 struct tbttoffset_params *tbtt_param) 17820 { 17821 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17822 wmi_tbtt_offset_info *tbtt_offset_info; 17823 17824 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17825 if (!param_buf) { 17826 qdf_print("Invalid tbtt update event buffer\n"); 17827 return QDF_STATUS_E_INVAL; 17828 } 17829 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 17830 17831 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 17832 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 17833 17834 return QDF_STATUS_SUCCESS; 17835 } 17836 17837 /** 17838 * extract_mgmt_rx_params_tlv() - extract management rx params from event 17839 * @wmi_handle: wmi handle 17840 * @param evt_buf: pointer to event buffer 17841 * @param hdr: Pointer to hold header 17842 * @param bufp: Pointer to hold pointer to rx param buffer 17843 * 17844 * Return: QDF_STATUS_SUCCESS for success or error code 17845 */ 17846 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 17847 void *evt_buf, struct mgmt_rx_event_params *hdr, 17848 uint8_t **bufp) 17849 { 17850 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 17851 wmi_mgmt_rx_hdr *ev_hdr = NULL; 17852 int i; 17853 17854 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 17855 if (!param_tlvs) { 17856 WMI_LOGE("Get NULL point message from FW"); 17857 return QDF_STATUS_E_INVAL; 17858 } 17859 17860 ev_hdr = param_tlvs->hdr; 17861 if (!hdr) { 17862 WMI_LOGE("Rx event is NULL"); 17863 return QDF_STATUS_E_INVAL; 17864 } 17865 17866 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17867 ev_hdr->pdev_id); 17868 17869 hdr->channel = ev_hdr->channel; 17870 hdr->snr = ev_hdr->snr; 17871 hdr->rate = ev_hdr->rate; 17872 hdr->phy_mode = ev_hdr->phy_mode; 17873 hdr->buf_len = ev_hdr->buf_len; 17874 hdr->status = ev_hdr->status; 17875 hdr->flags = ev_hdr->flags; 17876 hdr->rssi = ev_hdr->rssi; 17877 hdr->tsf_delta = ev_hdr->tsf_delta; 17878 for (i = 0; i < ATH_MAX_ANTENNA; i++) 17879 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 17880 17881 *bufp = param_tlvs->bufp; 17882 17883 return QDF_STATUS_SUCCESS; 17884 } 17885 17886 /** 17887 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 17888 * @wmi_handle: wmi handle 17889 * @param evt_buf: pointer to event buffer 17890 * @param vdev_id: Pointer to hold vdev identifier 17891 * 17892 * Return: QDF_STATUS_SUCCESS for success or error code 17893 */ 17894 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 17895 void *evt_buf, uint32_t *vdev_id) 17896 { 17897 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 17898 wmi_vdev_stopped_event_fixed_param *resp_event; 17899 17900 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 17901 if (!param_buf) { 17902 WMI_LOGE("Invalid event buffer"); 17903 return QDF_STATUS_E_INVAL; 17904 } 17905 resp_event = param_buf->fixed_param; 17906 *vdev_id = resp_event->vdev_id; 17907 17908 return QDF_STATUS_SUCCESS; 17909 } 17910 17911 /** 17912 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 17913 * @wmi_handle: wmi handle 17914 * @param evt_buf: pointer to event buffer 17915 * @param param: Pointer to hold roam param 17916 * 17917 * Return: QDF_STATUS_SUCCESS for success or error code 17918 */ 17919 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 17920 void *evt_buf, wmi_host_roam_event *param) 17921 { 17922 WMI_ROAM_EVENTID_param_tlvs *param_buf; 17923 wmi_roam_event_fixed_param *evt; 17924 17925 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 17926 if (!param_buf) { 17927 WMI_LOGE("Invalid roam event buffer"); 17928 return QDF_STATUS_E_INVAL; 17929 } 17930 17931 evt = param_buf->fixed_param; 17932 qdf_mem_zero(param, sizeof(*param)); 17933 17934 param->vdev_id = evt->vdev_id; 17935 param->reason = evt->reason; 17936 param->rssi = evt->rssi; 17937 17938 return QDF_STATUS_SUCCESS; 17939 } 17940 17941 /** 17942 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 17943 * @wmi_handle: wmi handle 17944 * @param evt_buf: pointer to event buffer 17945 * @param param: Pointer to hold vdev scan param 17946 * 17947 * Return: QDF_STATUS_SUCCESS for success or error code 17948 */ 17949 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 17950 void *evt_buf, struct scan_event *param) 17951 { 17952 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 17953 wmi_scan_event_fixed_param *evt = NULL; 17954 17955 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 17956 evt = param_buf->fixed_param; 17957 17958 qdf_mem_zero(param, sizeof(*param)); 17959 17960 switch (evt->event) { 17961 case WMI_SCAN_EVENT_STARTED: 17962 param->type = SCAN_EVENT_TYPE_STARTED; 17963 break; 17964 case WMI_SCAN_EVENT_COMPLETED: 17965 param->type = SCAN_EVENT_TYPE_COMPLETED; 17966 break; 17967 case WMI_SCAN_EVENT_BSS_CHANNEL: 17968 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 17969 break; 17970 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 17971 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 17972 break; 17973 case WMI_SCAN_EVENT_DEQUEUED: 17974 param->type = SCAN_EVENT_TYPE_DEQUEUED; 17975 break; 17976 case WMI_SCAN_EVENT_PREEMPTED: 17977 param->type = SCAN_EVENT_TYPE_PREEMPTED; 17978 break; 17979 case WMI_SCAN_EVENT_START_FAILED: 17980 param->type = SCAN_EVENT_TYPE_START_FAILED; 17981 break; 17982 case WMI_SCAN_EVENT_RESTARTED: 17983 param->type = SCAN_EVENT_TYPE_RESTARTED; 17984 break; 17985 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 17986 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 17987 break; 17988 case WMI_SCAN_EVENT_MAX: 17989 default: 17990 param->type = SCAN_EVENT_TYPE_MAX; 17991 break; 17992 }; 17993 17994 switch (evt->reason) { 17995 case WMI_SCAN_REASON_NONE: 17996 param->reason = SCAN_REASON_NONE; 17997 break; 17998 case WMI_SCAN_REASON_COMPLETED: 17999 param->reason = SCAN_REASON_COMPLETED; 18000 break; 18001 case WMI_SCAN_REASON_CANCELLED: 18002 param->reason = SCAN_REASON_CANCELLED; 18003 break; 18004 case WMI_SCAN_REASON_PREEMPTED: 18005 param->reason = SCAN_REASON_PREEMPTED; 18006 break; 18007 case WMI_SCAN_REASON_TIMEDOUT: 18008 param->reason = SCAN_REASON_TIMEDOUT; 18009 break; 18010 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18011 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18012 break; 18013 case WMI_SCAN_REASON_SUSPENDED: 18014 param->reason = SCAN_REASON_SUSPENDED; 18015 break; 18016 case WMI_SCAN_REASON_MAX: 18017 param->reason = SCAN_REASON_MAX; 18018 break; 18019 default: 18020 param->reason = SCAN_REASON_MAX; 18021 break; 18022 }; 18023 18024 param->chan_freq = evt->channel_freq; 18025 param->requester = evt->requestor; 18026 param->scan_id = evt->scan_id; 18027 param->vdev_id = evt->vdev_id; 18028 param->timestamp = evt->tsf_timestamp; 18029 18030 return QDF_STATUS_SUCCESS; 18031 } 18032 18033 #ifdef CONVERGED_TDLS_ENABLE 18034 /** 18035 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18036 * @wmi_handle: wmi handle 18037 * @param evt_buf: pointer to event buffer 18038 * @param param: Pointer to hold vdev tdls param 18039 * 18040 * Return: QDF_STATUS_SUCCESS for success or error code 18041 */ 18042 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18043 void *evt_buf, struct tdls_event_info *param) 18044 { 18045 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18046 wmi_tdls_peer_event_fixed_param *evt; 18047 18048 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18049 if (!param_buf) { 18050 WMI_LOGE("%s: NULL param_buf", __func__); 18051 return QDF_STATUS_E_NULL_VALUE; 18052 } 18053 18054 evt = param_buf->fixed_param; 18055 18056 qdf_mem_zero(param, sizeof(*param)); 18057 18058 param->vdev_id = evt->vdev_id; 18059 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18060 param->peermac.bytes); 18061 switch (evt->peer_status) { 18062 case WMI_TDLS_SHOULD_DISCOVER: 18063 param->message_type = TDLS_SHOULD_DISCOVER; 18064 break; 18065 case WMI_TDLS_SHOULD_TEARDOWN: 18066 param->message_type = TDLS_SHOULD_TEARDOWN; 18067 break; 18068 case WMI_TDLS_PEER_DISCONNECTED: 18069 param->message_type = TDLS_PEER_DISCONNECTED; 18070 break; 18071 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18072 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18073 break; 18074 default: 18075 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18076 __func__, evt->peer_status); 18077 return QDF_STATUS_E_INVAL; 18078 }; 18079 18080 switch (evt->peer_reason) { 18081 case WMI_TDLS_TEARDOWN_REASON_TX: 18082 param->peer_reason = TDLS_TEARDOWN_TX; 18083 break; 18084 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18085 param->peer_reason = TDLS_TEARDOWN_RSSI; 18086 break; 18087 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18088 param->peer_reason = TDLS_TEARDOWN_SCAN; 18089 break; 18090 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18091 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18092 break; 18093 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18094 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18095 break; 18096 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18097 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18098 break; 18099 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18100 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18101 break; 18102 case WMI_TDLS_ENTER_BUF_STA: 18103 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18104 break; 18105 case WMI_TDLS_EXIT_BUF_STA: 18106 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18107 break; 18108 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18109 param->peer_reason = TDLS_ENTER_BT_BUSY; 18110 break; 18111 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18112 param->peer_reason = TDLS_EXIT_BT_BUSY; 18113 break; 18114 case WMI_TDLS_SCAN_STARTED_EVENT: 18115 param->peer_reason = TDLS_SCAN_STARTED; 18116 break; 18117 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18118 param->peer_reason = TDLS_SCAN_COMPLETED; 18119 break; 18120 18121 default: 18122 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18123 __func__, evt->peer_reason, evt->peer_status); 18124 return QDF_STATUS_E_INVAL; 18125 }; 18126 18127 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18128 __func__, param->peermac.bytes, param->message_type, 18129 param->peer_reason, param->vdev_id); 18130 18131 return QDF_STATUS_SUCCESS; 18132 } 18133 #endif 18134 18135 /** 18136 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18137 * @wmi_handle: wmi handle 18138 * @param evt_buf: pointer to event buffer 18139 * @param param: Pointer to hold MGMT TX completion params 18140 * 18141 * Return: QDF_STATUS_SUCCESS for success or error code 18142 */ 18143 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18144 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18145 { 18146 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18147 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18148 18149 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18150 evt_buf; 18151 if (!param_buf) { 18152 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18153 return QDF_STATUS_E_INVAL; 18154 } 18155 cmpl_params = param_buf->fixed_param; 18156 18157 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18158 cmpl_params->pdev_id); 18159 param->desc_id = cmpl_params->desc_id; 18160 param->status = cmpl_params->status; 18161 param->ppdu_id = cmpl_params->ppdu_id; 18162 18163 return QDF_STATUS_SUCCESS; 18164 } 18165 18166 /** 18167 * extract_offchan_data_tx_compl_param_tlv() - 18168 * extract Offchan data tx completion event params 18169 * @wmi_handle: wmi handle 18170 * @param evt_buf: pointer to event buffer 18171 * @param param: Pointer to hold offchan data TX completion params 18172 * 18173 * Return: QDF_STATUS_SUCCESS for success or error code 18174 */ 18175 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18176 wmi_unified_t wmi_handle, void *evt_buf, 18177 struct wmi_host_offchan_data_tx_compl_event *param) 18178 { 18179 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18180 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18181 18182 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18183 evt_buf; 18184 if (!param_buf) { 18185 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18186 return QDF_STATUS_E_INVAL; 18187 } 18188 cmpl_params = param_buf->fixed_param; 18189 18190 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18191 cmpl_params->pdev_id); 18192 param->desc_id = cmpl_params->desc_id; 18193 param->status = cmpl_params->status; 18194 18195 return QDF_STATUS_SUCCESS; 18196 } 18197 18198 /** 18199 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18200 * status tlv 18201 * @wmi_handle: wmi handle 18202 * @param evt_buf: pointer to event buffer 18203 * @param param: Pointer to hold csa switch count status event param 18204 * 18205 * Return: QDF_STATUS_SUCCESS for success or error code 18206 */ 18207 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18208 wmi_unified_t wmi_handle, 18209 void *evt_buf, 18210 struct pdev_csa_switch_count_status *param) 18211 { 18212 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18213 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18214 18215 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18216 evt_buf; 18217 if (!param_buf) { 18218 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18219 return QDF_STATUS_E_INVAL; 18220 } 18221 18222 csa_status = param_buf->fixed_param; 18223 18224 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18225 csa_status->pdev_id); 18226 param->current_switch_count = csa_status->current_switch_count; 18227 param->num_vdevs = csa_status->num_vdevs; 18228 param->vdev_ids = param_buf->vdev_ids; 18229 18230 return QDF_STATUS_SUCCESS; 18231 } 18232 18233 /** 18234 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18235 * param from event 18236 * @wmi_handle: wmi handle 18237 * @param evt_buf: pointer to event buffer 18238 * @param param: Pointer to hold tpc configuration 18239 * 18240 * Return: 0 for success or error code 18241 */ 18242 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18243 void *evt_buf, 18244 wmi_host_pdev_tpc_config_event *param) 18245 { 18246 wmi_pdev_tpc_config_event_fixed_param *event = 18247 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18248 18249 if (!event) { 18250 WMI_LOGE("Invalid event buffer"); 18251 return QDF_STATUS_E_INVAL; 18252 } 18253 18254 param->pdev_id = event->pdev_id; 18255 param->regDomain = event->regDomain; 18256 param->chanFreq = event->chanFreq; 18257 param->phyMode = event->phyMode; 18258 param->twiceAntennaReduction = event->twiceAntennaReduction; 18259 param->twiceMaxRDPower = event->twiceMaxRDPower; 18260 param->powerLimit = event->powerLimit; 18261 param->rateMax = event->rateMax; 18262 param->numTxChain = event->numTxChain; 18263 param->ctl = event->ctl; 18264 param->flags = event->flags; 18265 18266 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18267 sizeof(param->maxRegAllowedPower)); 18268 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18269 event->maxRegAllowedPowerAGCDD, 18270 sizeof(param->maxRegAllowedPowerAGCDD)); 18271 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18272 event->maxRegAllowedPowerAGSTBC, 18273 sizeof(param->maxRegAllowedPowerAGSTBC)); 18274 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18275 event->maxRegAllowedPowerAGTXBF, 18276 sizeof(param->maxRegAllowedPowerAGTXBF)); 18277 WMI_LOGD("%s:extract success", __func__); 18278 18279 return QDF_STATUS_SUCCESS; 18280 } 18281 18282 /** 18283 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18284 * @wmi_handle: wmi handle 18285 * @param evt_buf: pointer to event buffer 18286 * @param num_vdevs: Pointer to hold num vdevs 18287 * 18288 * Return: QDF_STATUS_SUCCESS for success or error code 18289 */ 18290 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18291 void *evt_buf, uint32_t *num_vdevs) 18292 { 18293 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18294 wmi_host_swba_event_fixed_param *swba_event; 18295 uint32_t vdev_map; 18296 18297 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18298 if (!param_buf) { 18299 WMI_LOGE("Invalid swba event buffer"); 18300 return QDF_STATUS_E_INVAL; 18301 } 18302 18303 swba_event = param_buf->fixed_param; 18304 *num_vdevs = swba_event->num_vdevs; 18305 if (!(*num_vdevs)) { 18306 vdev_map = swba_event->vdev_map; 18307 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18308 } 18309 18310 return QDF_STATUS_SUCCESS; 18311 } 18312 18313 /** 18314 * extract_swba_tim_info_tlv() - extract swba tim info from event 18315 * @wmi_handle: wmi handle 18316 * @param evt_buf: pointer to event buffer 18317 * @param idx: Index to bcn info 18318 * @param tim_info: Pointer to hold tim info 18319 * 18320 * Return: QDF_STATUS_SUCCESS for success or error code 18321 */ 18322 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18323 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18324 { 18325 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18326 wmi_tim_info *tim_info_ev; 18327 18328 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18329 if (!param_buf) { 18330 WMI_LOGE("Invalid swba event buffer"); 18331 return QDF_STATUS_E_INVAL; 18332 } 18333 18334 tim_info_ev = ¶m_buf->tim_info[idx]; 18335 18336 tim_info->tim_len = tim_info_ev->tim_len; 18337 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18338 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18339 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18340 tim_info->tim_changed = tim_info_ev->tim_changed; 18341 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18342 tim_info->vdev_id = tim_info_ev->vdev_id; 18343 18344 return QDF_STATUS_SUCCESS; 18345 } 18346 18347 /** 18348 * extract_swba_noa_info_tlv() - extract swba NoA information from event 18349 * @wmi_handle: wmi handle 18350 * @param evt_buf: pointer to event buffer 18351 * @param idx: Index to bcn info 18352 * @param p2p_desc: Pointer to hold p2p NoA info 18353 * 18354 * Return: QDF_STATUS_SUCCESS for success or error code 18355 */ 18356 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 18357 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 18358 { 18359 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18360 wmi_p2p_noa_info *p2p_noa_info; 18361 uint8_t i = 0; 18362 18363 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18364 if (!param_buf) { 18365 WMI_LOGE("Invalid swba event buffer"); 18366 return QDF_STATUS_E_INVAL; 18367 } 18368 18369 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 18370 18371 p2p_desc->modified = false; 18372 p2p_desc->num_descriptors = 0; 18373 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 18374 p2p_desc->modified = true; 18375 p2p_desc->index = 18376 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 18377 p2p_desc->oppPS = 18378 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 18379 p2p_desc->ctwindow = 18380 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 18381 p2p_desc->num_descriptors = 18382 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 18383 (p2p_noa_info); 18384 for (i = 0; i < p2p_desc->num_descriptors; i++) { 18385 p2p_desc->noa_descriptors[i].type_count = 18386 (uint8_t) p2p_noa_info->noa_descriptors[i]. 18387 type_count; 18388 p2p_desc->noa_descriptors[i].duration = 18389 p2p_noa_info->noa_descriptors[i].duration; 18390 p2p_desc->noa_descriptors[i].interval = 18391 p2p_noa_info->noa_descriptors[i].interval; 18392 p2p_desc->noa_descriptors[i].start_time = 18393 p2p_noa_info->noa_descriptors[i].start_time; 18394 } 18395 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 18396 } 18397 18398 return QDF_STATUS_SUCCESS; 18399 } 18400 18401 #ifdef CONVERGED_P2P_ENABLE 18402 /** 18403 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 18404 * @wmi_handle: wmi handle 18405 * @param evt_buf: pointer to event buffer 18406 * @param param: Pointer to hold p2p noa info 18407 * 18408 * Return: QDF_STATUS_SUCCESS for success or error code 18409 */ 18410 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 18411 wmi_unified_t wmi_handle, void *evt_buf, 18412 struct p2p_noa_info *param) 18413 { 18414 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 18415 wmi_p2p_noa_event_fixed_param *fixed_param; 18416 uint8_t i; 18417 wmi_p2p_noa_info *wmi_noa_info; 18418 uint8_t *buf_ptr; 18419 uint32_t descriptors; 18420 18421 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 18422 if (!param_tlvs) { 18423 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 18424 return QDF_STATUS_E_INVAL; 18425 } 18426 18427 if (!param) { 18428 WMI_LOGE("noa information param is null"); 18429 return QDF_STATUS_E_INVAL; 18430 } 18431 18432 fixed_param = param_tlvs->fixed_param; 18433 buf_ptr = (uint8_t *) fixed_param; 18434 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 18435 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 18436 18437 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 18438 WMI_LOGE("%s: noa attr is not modified", __func__); 18439 return QDF_STATUS_E_INVAL; 18440 } 18441 18442 param->vdev_id = fixed_param->vdev_id; 18443 param->index = 18444 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 18445 param->opps_ps = 18446 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 18447 param->ct_window = 18448 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 18449 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 18450 param->num_desc = (uint8_t) descriptors; 18451 18452 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 18453 param->index, param->opps_ps, param->ct_window, 18454 param->num_desc); 18455 for (i = 0; i < param->num_desc; i++) { 18456 param->noa_desc[i].type_count = 18457 (uint8_t) wmi_noa_info->noa_descriptors[i]. 18458 type_count; 18459 param->noa_desc[i].duration = 18460 wmi_noa_info->noa_descriptors[i].duration; 18461 param->noa_desc[i].interval = 18462 wmi_noa_info->noa_descriptors[i].interval; 18463 param->noa_desc[i].start_time = 18464 wmi_noa_info->noa_descriptors[i].start_time; 18465 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 18466 __func__, i, param->noa_desc[i].type_count, 18467 param->noa_desc[i].duration, 18468 param->noa_desc[i].interval, 18469 param->noa_desc[i].start_time); 18470 } 18471 18472 return QDF_STATUS_SUCCESS; 18473 } 18474 18475 /** 18476 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 18477 * information from event 18478 * @wmi_handle: wmi handle 18479 * @param evt_buf: pointer to event buffer 18480 * @param param: Pointer to hold p2p lo stop event information 18481 * 18482 * Return: QDF_STATUS_SUCCESS for success or error code 18483 */ 18484 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 18485 wmi_unified_t wmi_handle, void *evt_buf, 18486 struct p2p_lo_event *param) 18487 { 18488 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 18489 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 18490 18491 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 18492 evt_buf; 18493 if (!param_tlvs) { 18494 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 18495 return QDF_STATUS_E_INVAL; 18496 } 18497 18498 if (!param) { 18499 WMI_LOGE("lo stop event param is null"); 18500 return QDF_STATUS_E_INVAL; 18501 } 18502 18503 lo_param = param_tlvs->fixed_param; 18504 param->vdev_id = lo_param->vdev_id; 18505 param->reason_code = lo_param->reason; 18506 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 18507 param->vdev_id, param->reason_code); 18508 18509 return QDF_STATUS_SUCCESS; 18510 } 18511 #endif /* End of CONVERGED_P2P_ENABLE */ 18512 18513 /** 18514 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 18515 * @wmi_handle: wmi handle 18516 * @param evt_buf: pointer to event buffer 18517 * @param ev: Pointer to hold peer param 18518 * 18519 * Return: QDF_STATUS_SUCCESS for success or error code 18520 */ 18521 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 18522 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 18523 { 18524 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 18525 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 18526 18527 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 18528 kickout_event = param_buf->fixed_param; 18529 18530 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 18531 ev->peer_macaddr); 18532 18533 ev->reason = kickout_event->reason; 18534 ev->rssi = kickout_event->rssi; 18535 18536 return QDF_STATUS_SUCCESS; 18537 } 18538 18539 /** 18540 * extract_all_stats_counts_tlv() - extract all stats count from event 18541 * @wmi_handle: wmi handle 18542 * @param evt_buf: pointer to event buffer 18543 * @param stats_param: Pointer to hold stats count 18544 * 18545 * Return: QDF_STATUS_SUCCESS for success or error code 18546 */ 18547 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 18548 void *evt_buf, wmi_host_stats_event *stats_param) 18549 { 18550 wmi_stats_event_fixed_param *ev; 18551 wmi_per_chain_rssi_stats *rssi_event; 18552 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18553 18554 qdf_mem_zero(stats_param, sizeof(*stats_param)); 18555 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18556 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18557 rssi_event = param_buf->chain_stats; 18558 if (!ev) { 18559 WMI_LOGE("%s: event fixed param NULL\n", __func__); 18560 return QDF_STATUS_E_FAILURE; 18561 } 18562 18563 switch (ev->stats_id) { 18564 case WMI_REQUEST_PEER_STAT: 18565 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 18566 break; 18567 18568 case WMI_REQUEST_AP_STAT: 18569 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 18570 break; 18571 18572 case WMI_REQUEST_PDEV_STAT: 18573 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 18574 break; 18575 18576 case WMI_REQUEST_VDEV_STAT: 18577 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 18578 break; 18579 18580 case WMI_REQUEST_BCNFLT_STAT: 18581 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 18582 break; 18583 18584 case WMI_REQUEST_VDEV_RATE_STAT: 18585 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 18586 break; 18587 18588 case WMI_REQUEST_BCN_STAT: 18589 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 18590 break; 18591 18592 default: 18593 stats_param->stats_id = 0; 18594 break; 18595 18596 } 18597 18598 stats_param->num_pdev_stats = ev->num_pdev_stats; 18599 stats_param->num_pdev_ext_stats = 0; 18600 stats_param->num_vdev_stats = ev->num_vdev_stats; 18601 stats_param->num_peer_stats = ev->num_peer_stats; 18602 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 18603 stats_param->num_chan_stats = ev->num_chan_stats; 18604 stats_param->num_bcn_stats = ev->num_bcn_stats; 18605 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18606 ev->pdev_id); 18607 18608 /* if chain_stats is not populated */ 18609 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 18610 return QDF_STATUS_SUCCESS; 18611 18612 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 18613 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 18614 return QDF_STATUS_SUCCESS; 18615 18616 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 18617 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 18618 return QDF_STATUS_SUCCESS; 18619 18620 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 18621 18622 return QDF_STATUS_SUCCESS; 18623 } 18624 18625 /** 18626 * extract_pdev_tx_stats() - extract pdev tx stats from event 18627 */ 18628 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 18629 { 18630 /* Tx Stats */ 18631 tx->comp_queued = tx_stats->comp_queued; 18632 tx->comp_delivered = tx_stats->comp_delivered; 18633 tx->msdu_enqued = tx_stats->msdu_enqued; 18634 tx->mpdu_enqued = tx_stats->mpdu_enqued; 18635 tx->wmm_drop = tx_stats->wmm_drop; 18636 tx->local_enqued = tx_stats->local_enqued; 18637 tx->local_freed = tx_stats->local_freed; 18638 tx->hw_queued = tx_stats->hw_queued; 18639 tx->hw_reaped = tx_stats->hw_reaped; 18640 tx->underrun = tx_stats->underrun; 18641 tx->tx_abort = tx_stats->tx_abort; 18642 tx->mpdus_requed = tx_stats->mpdus_requed; 18643 tx->data_rc = tx_stats->data_rc; 18644 tx->self_triggers = tx_stats->self_triggers; 18645 tx->sw_retry_failure = tx_stats->sw_retry_failure; 18646 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 18647 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 18648 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 18649 tx->pdev_resets = tx_stats->pdev_resets; 18650 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 18651 tx->phy_underrun = tx_stats->phy_underrun; 18652 tx->txop_ovf = tx_stats->txop_ovf; 18653 18654 return; 18655 } 18656 18657 18658 /** 18659 * extract_pdev_rx_stats() - extract pdev rx stats from event 18660 */ 18661 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 18662 { 18663 /* Rx Stats */ 18664 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 18665 rx->status_rcvd = rx_stats->status_rcvd; 18666 rx->r0_frags = rx_stats->r0_frags; 18667 rx->r1_frags = rx_stats->r1_frags; 18668 rx->r2_frags = rx_stats->r2_frags; 18669 /* Only TLV */ 18670 rx->r3_frags = 0; 18671 rx->htt_msdus = rx_stats->htt_msdus; 18672 rx->htt_mpdus = rx_stats->htt_mpdus; 18673 rx->loc_msdus = rx_stats->loc_msdus; 18674 rx->loc_mpdus = rx_stats->loc_mpdus; 18675 rx->oversize_amsdu = rx_stats->oversize_amsdu; 18676 rx->phy_errs = rx_stats->phy_errs; 18677 rx->phy_err_drop = rx_stats->phy_err_drop; 18678 rx->mpdu_errs = rx_stats->mpdu_errs; 18679 18680 return; 18681 } 18682 18683 /** 18684 * extract_pdev_stats_tlv() - extract pdev stats from event 18685 * @wmi_handle: wmi handle 18686 * @param evt_buf: pointer to event buffer 18687 * @param index: Index into pdev stats 18688 * @param pdev_stats: Pointer to hold pdev stats 18689 * 18690 * Return: QDF_STATUS_SUCCESS for success or error code 18691 */ 18692 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 18693 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 18694 { 18695 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18696 wmi_stats_event_fixed_param *ev_param; 18697 uint8_t *data; 18698 18699 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18700 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18701 18702 data = param_buf->data; 18703 18704 if (index < ev_param->num_pdev_stats) { 18705 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 18706 (index * sizeof(wmi_pdev_stats))); 18707 18708 pdev_stats->chan_nf = ev->chan_nf; 18709 pdev_stats->tx_frame_count = ev->tx_frame_count; 18710 pdev_stats->rx_frame_count = ev->rx_frame_count; 18711 pdev_stats->rx_clear_count = ev->rx_clear_count; 18712 pdev_stats->cycle_count = ev->cycle_count; 18713 pdev_stats->phy_err_count = ev->phy_err_count; 18714 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 18715 18716 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 18717 &(ev->pdev_stats.tx)); 18718 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 18719 &(ev->pdev_stats.rx)); 18720 } 18721 18722 return QDF_STATUS_SUCCESS; 18723 } 18724 18725 /** 18726 * extract_unit_test_tlv() - extract unit test data 18727 * @wmi_handle: wmi handle 18728 * @param evt_buf: pointer to event buffer 18729 * @param unit_test: pointer to hold unit test data 18730 * @param maxspace: Amount of space in evt_buf 18731 * 18732 * Return: QDF_STATUS_SUCCESS for success or error code 18733 */ 18734 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 18735 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 18736 { 18737 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 18738 wmi_unit_test_event_fixed_param *ev_param; 18739 uint32_t num_bufp; 18740 uint32_t copy_size; 18741 uint8_t *bufp; 18742 18743 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 18744 ev_param = param_buf->fixed_param; 18745 bufp = param_buf->bufp; 18746 num_bufp = param_buf->num_bufp; 18747 unit_test->vdev_id = ev_param->vdev_id; 18748 unit_test->module_id = ev_param->module_id; 18749 unit_test->diag_token = ev_param->diag_token; 18750 unit_test->flag = ev_param->flag; 18751 unit_test->payload_len = ev_param->payload_len; 18752 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 18753 ev_param->vdev_id, 18754 ev_param->module_id, 18755 ev_param->diag_token, 18756 ev_param->flag); 18757 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 18758 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 18759 bufp, num_bufp); 18760 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 18761 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 18762 unit_test->buffer_len = copy_size; 18763 18764 return QDF_STATUS_SUCCESS; 18765 } 18766 18767 /** 18768 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 18769 * @wmi_handle: wmi handle 18770 * @param evt_buf: pointer to event buffer 18771 * @param index: Index into extended pdev stats 18772 * @param pdev_ext_stats: Pointer to hold extended pdev stats 18773 * 18774 * Return: QDF_STATUS_SUCCESS for success or error code 18775 */ 18776 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 18777 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 18778 { 18779 return QDF_STATUS_SUCCESS; 18780 } 18781 18782 /** 18783 * extract_vdev_stats_tlv() - extract vdev stats from event 18784 * @wmi_handle: wmi handle 18785 * @param evt_buf: pointer to event buffer 18786 * @param index: Index into vdev stats 18787 * @param vdev_stats: Pointer to hold vdev stats 18788 * 18789 * Return: QDF_STATUS_SUCCESS for success or error code 18790 */ 18791 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 18792 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 18793 { 18794 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18795 wmi_stats_event_fixed_param *ev_param; 18796 uint8_t *data; 18797 18798 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18799 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18800 data = (uint8_t *) param_buf->data; 18801 18802 if (index < ev_param->num_vdev_stats) { 18803 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 18804 ((ev_param->num_pdev_stats) * 18805 sizeof(wmi_pdev_stats)) + 18806 (index * sizeof(wmi_vdev_stats))); 18807 18808 vdev_stats->vdev_id = ev->vdev_id; 18809 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 18810 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 18811 18812 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 18813 sizeof(ev->tx_frm_cnt)); 18814 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 18815 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 18816 ev->multiple_retry_cnt, 18817 sizeof(ev->multiple_retry_cnt)); 18818 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 18819 sizeof(ev->fail_cnt)); 18820 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 18821 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 18822 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 18823 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 18824 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 18825 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 18826 sizeof(ev->tx_rate_history)); 18827 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 18828 sizeof(ev->bcn_rssi_history)); 18829 18830 } 18831 18832 return QDF_STATUS_SUCCESS; 18833 } 18834 18835 /** 18836 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 18837 * buffer 18838 * @wmi_handle: wmi handle 18839 * @evt_buf: pointer to event buffer 18840 * @index: Index into vdev stats 18841 * @rssi_stats: Pointer to hold rssi stats 18842 * 18843 * Return: QDF_STATUS_SUCCESS for success or error code 18844 */ 18845 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 18846 void *evt_buf, uint32_t index, 18847 struct wmi_host_per_chain_rssi_stats *rssi_stats) 18848 { 18849 uint8_t *data; 18850 wmi_rssi_stats *fw_rssi_stats; 18851 wmi_per_chain_rssi_stats *rssi_event; 18852 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18853 18854 if (!evt_buf) { 18855 WMI_LOGE("evt_buf is null"); 18856 return QDF_STATUS_E_NULL_VALUE; 18857 } 18858 18859 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18860 rssi_event = param_buf->chain_stats; 18861 18862 if (index >= rssi_event->num_per_chain_rssi_stats) { 18863 WMI_LOGE("invalid index"); 18864 return QDF_STATUS_E_INVAL; 18865 } 18866 18867 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 18868 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 18869 18870 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 18871 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 18872 fw_rssi_stats->rssi_avg_beacon, 18873 sizeof(fw_rssi_stats->rssi_avg_beacon)); 18874 qdf_mem_copy(rssi_stats->rssi_avg_data, 18875 fw_rssi_stats->rssi_avg_data, 18876 sizeof(fw_rssi_stats->rssi_avg_data)); 18877 qdf_mem_copy(&rssi_stats->peer_macaddr, 18878 &fw_rssi_stats->peer_macaddr, 18879 sizeof(fw_rssi_stats->peer_macaddr)); 18880 18881 return QDF_STATUS_SUCCESS; 18882 } 18883 18884 18885 18886 /** 18887 * extract_bcn_stats_tlv() - extract bcn stats from event 18888 * @wmi_handle: wmi handle 18889 * @param evt_buf: pointer to event buffer 18890 * @param index: Index into vdev stats 18891 * @param bcn_stats: Pointer to hold bcn stats 18892 * 18893 * Return: QDF_STATUS_SUCCESS for success or error code 18894 */ 18895 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 18896 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 18897 { 18898 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18899 wmi_stats_event_fixed_param *ev_param; 18900 uint8_t *data; 18901 18902 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18903 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18904 data = (uint8_t *) param_buf->data; 18905 18906 if (index < ev_param->num_bcn_stats) { 18907 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 18908 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18909 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18910 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 18911 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 18912 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 18913 (index * sizeof(wmi_bcn_stats))); 18914 18915 bcn_stats->vdev_id = ev->vdev_id; 18916 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 18917 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 18918 } 18919 18920 return QDF_STATUS_SUCCESS; 18921 } 18922 18923 /** 18924 * extract_peer_stats_tlv() - extract peer stats from event 18925 * @wmi_handle: wmi handle 18926 * @param evt_buf: pointer to event buffer 18927 * @param index: Index into peer stats 18928 * @param peer_stats: Pointer to hold peer stats 18929 * 18930 * Return: QDF_STATUS_SUCCESS for success or error code 18931 */ 18932 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 18933 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 18934 { 18935 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18936 wmi_stats_event_fixed_param *ev_param; 18937 uint8_t *data; 18938 18939 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18940 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18941 data = (uint8_t *) param_buf->data; 18942 18943 if (index < ev_param->num_peer_stats) { 18944 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 18945 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18946 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18947 (index * sizeof(wmi_peer_stats))); 18948 18949 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 18950 18951 OS_MEMCPY(&(peer_stats->peer_macaddr), 18952 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 18953 18954 peer_stats->peer_rssi = ev->peer_rssi; 18955 peer_stats->peer_tx_rate = ev->peer_tx_rate; 18956 peer_stats->peer_rx_rate = ev->peer_rx_rate; 18957 } 18958 18959 return QDF_STATUS_SUCCESS; 18960 } 18961 18962 /** 18963 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 18964 * @wmi_handle: wmi handle 18965 * @param evt_buf: pointer to event buffer 18966 * @param index: Index into bcn fault stats 18967 * @param bcnflt_stats: Pointer to hold bcn fault stats 18968 * 18969 * Return: QDF_STATUS_SUCCESS for success or error code 18970 */ 18971 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 18972 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 18973 { 18974 return QDF_STATUS_SUCCESS; 18975 } 18976 18977 /** 18978 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 18979 * @wmi_handle: wmi handle 18980 * @param evt_buf: pointer to event buffer 18981 * @param index: Index into extended peer stats 18982 * @param peer_extd_stats: Pointer to hold extended peer stats 18983 * 18984 * Return: QDF_STATUS_SUCCESS for success or error code 18985 */ 18986 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 18987 void *evt_buf, uint32_t index, 18988 wmi_host_peer_extd_stats *peer_extd_stats) 18989 { 18990 return QDF_STATUS_SUCCESS; 18991 } 18992 18993 /** 18994 * extract_chan_stats_tlv() - extract chan stats from event 18995 * @wmi_handle: wmi handle 18996 * @param evt_buf: pointer to event buffer 18997 * @param index: Index into chan stats 18998 * @param vdev_extd_stats: Pointer to hold chan stats 18999 * 19000 * Return: QDF_STATUS_SUCCESS for success or error code 19001 */ 19002 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19003 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19004 { 19005 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19006 wmi_stats_event_fixed_param *ev_param; 19007 uint8_t *data; 19008 19009 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19010 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19011 data = (uint8_t *) param_buf->data; 19012 19013 if (index < ev_param->num_chan_stats) { 19014 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19015 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19016 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19017 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19018 (index * sizeof(wmi_chan_stats))); 19019 19020 19021 /* Non-TLV doesn't have num_chan_stats */ 19022 chan_stats->chan_mhz = ev->chan_mhz; 19023 chan_stats->sampling_period_us = ev->sampling_period_us; 19024 chan_stats->rx_clear_count = ev->rx_clear_count; 19025 chan_stats->tx_duration_us = ev->tx_duration_us; 19026 chan_stats->rx_duration_us = ev->rx_duration_us; 19027 } 19028 19029 return QDF_STATUS_SUCCESS; 19030 } 19031 19032 /** 19033 * extract_profile_ctx_tlv() - extract profile context from event 19034 * @wmi_handle: wmi handle 19035 * @param evt_buf: pointer to event buffer 19036 * @idx: profile stats index to extract 19037 * @param profile_ctx: Pointer to hold profile context 19038 * 19039 * Return: QDF_STATUS_SUCCESS for success or error code 19040 */ 19041 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19042 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19043 { 19044 return QDF_STATUS_SUCCESS; 19045 } 19046 19047 /** 19048 * extract_profile_data_tlv() - extract profile data from event 19049 * @wmi_handle: wmi handle 19050 * @param evt_buf: pointer to event buffer 19051 * @param profile_data: Pointer to hold profile data 19052 * 19053 * Return: QDF_STATUS_SUCCESS for success or error code 19054 */ 19055 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19056 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19057 { 19058 19059 return QDF_STATUS_SUCCESS; 19060 } 19061 19062 /** 19063 * extract_chan_info_event_tlv() - extract chan information from event 19064 * @wmi_handle: wmi handle 19065 * @param evt_buf: pointer to event buffer 19066 * @param chan_info: Pointer to hold chan information 19067 * 19068 * Return: QDF_STATUS_SUCCESS for success or error code 19069 */ 19070 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19071 void *evt_buf, wmi_host_chan_info_event *chan_info) 19072 { 19073 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19074 wmi_chan_info_event_fixed_param *ev; 19075 19076 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19077 19078 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19079 if (!ev) { 19080 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19081 return QDF_STATUS_E_FAILURE; 19082 } 19083 19084 chan_info->err_code = ev->err_code; 19085 chan_info->freq = ev->freq; 19086 chan_info->cmd_flags = ev->cmd_flags; 19087 chan_info->noise_floor = ev->noise_floor; 19088 chan_info->rx_clear_count = ev->rx_clear_count; 19089 chan_info->cycle_count = ev->cycle_count; 19090 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19091 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19092 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19093 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19094 ev->vdev_id, WLAN_SCAN_ID); 19095 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19096 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19097 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19098 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19099 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19100 chan_info->rx_frame_count = ev->rx_frame_count; 19101 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19102 chan_info->vdev_id = ev->vdev_id; 19103 19104 return QDF_STATUS_SUCCESS; 19105 } 19106 19107 /** 19108 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19109 * @wmi_handle: WMI handle 19110 * @param evt_buf: Pointer to event buffer 19111 * @param param: Pointer to hold data 19112 * 19113 * Return : QDF_STATUS_SUCCESS for success or error code 19114 */ 19115 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19116 uint8_t *evt_buf, 19117 struct wmi_host_pdev_utf_event *event) 19118 { 19119 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19120 struct wmi_host_utf_seg_header_info *seg_hdr; 19121 19122 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19123 event->data = param_buf->data; 19124 event->datalen = param_buf->num_data; 19125 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19126 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19127 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19128 seg_hdr->pdev_id); 19129 19130 return QDF_STATUS_SUCCESS; 19131 } 19132 19133 /** 19134 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19135 * @wmi_handle: wmi handle 19136 * @param evt_buf: pointer to event buffer 19137 * @param param: Pointer to hold evt buf 19138 * 19139 * Return: QDF_STATUS_SUCCESS for success or error code 19140 */ 19141 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19142 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19143 { 19144 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19145 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19146 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19147 uint8_t i = 0, j = 0; 19148 19149 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19150 if (!param_buf) 19151 return QDF_STATUS_E_INVAL; 19152 19153 hw_caps = param_buf->soc_hw_mode_caps; 19154 if (!hw_caps) 19155 return QDF_STATUS_E_INVAL; 19156 19157 if (!hw_caps->num_chainmask_tables) 19158 return QDF_STATUS_E_INVAL; 19159 19160 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19161 19162 if (chainmask_caps == NULL) 19163 return QDF_STATUS_E_INVAL; 19164 19165 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19166 19167 qdf_print("Dumping chain mask combo data for table : %d\n", i); 19168 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19169 19170 chainmask_table[i].cap_list[j].chainmask = 19171 chainmask_caps->chainmask; 19172 19173 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19174 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19175 19176 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19177 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19178 19179 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19180 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19181 19182 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19183 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19184 19185 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19186 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19187 19188 chainmask_table[i].cap_list[j].chain_mask_2G = 19189 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19190 19191 chainmask_table[i].cap_list[j].chain_mask_5G = 19192 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19193 19194 chainmask_table[i].cap_list[j].chain_mask_tx = 19195 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19196 19197 chainmask_table[i].cap_list[j].chain_mask_rx = 19198 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19199 19200 chainmask_table[i].cap_list[j].supports_aDFS = 19201 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19202 19203 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x\n", 19204 chainmask_caps->supported_flags, 19205 chainmask_caps->chainmask 19206 ); 19207 chainmask_caps++; 19208 } 19209 } 19210 19211 return QDF_STATUS_SUCCESS; 19212 } 19213 19214 /** 19215 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19216 * from event 19217 * @wmi_handle: wmi handle 19218 * @param evt_buf: pointer to event buffer 19219 * @param param: Pointer to hold evt buf 19220 * 19221 * Return: QDF_STATUS_SUCCESS for success or error code 19222 */ 19223 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19224 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19225 { 19226 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19227 wmi_service_ready_ext_event_fixed_param *ev; 19228 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19229 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19230 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19231 uint8_t i = 0; 19232 19233 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19234 if (!param_buf) 19235 return QDF_STATUS_E_INVAL; 19236 19237 ev = param_buf->fixed_param; 19238 if (!ev) 19239 return QDF_STATUS_E_INVAL; 19240 19241 /* Move this to host based bitmap */ 19242 param->default_conc_scan_config_bits = 19243 ev->default_conc_scan_config_bits; 19244 param->default_fw_config_bits = ev->default_fw_config_bits; 19245 param->he_cap_info = ev->he_cap_info; 19246 param->mpdu_density = ev->mpdu_density; 19247 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19248 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19249 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19250 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19251 19252 hw_caps = param_buf->soc_hw_mode_caps; 19253 if (hw_caps) 19254 param->num_hw_modes = hw_caps->num_hw_modes; 19255 else 19256 param->num_hw_modes = 0; 19257 19258 reg_caps = param_buf->soc_hal_reg_caps; 19259 if (reg_caps) 19260 param->num_phy = reg_caps->num_phy; 19261 else 19262 param->num_phy = 0; 19263 19264 if (hw_caps) { 19265 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19266 qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables); 19267 } else 19268 param->num_chainmask_tables = 0; 19269 19270 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19271 19272 if (chain_mask_combo == NULL) 19273 return QDF_STATUS_SUCCESS; 19274 19275 qdf_print("Dumping chain mask combo data\n"); 19276 19277 for (i = 0; i < param->num_chainmask_tables; i++) { 19278 19279 qdf_print("table_id : %d Num valid chainmasks: %d\n", 19280 chain_mask_combo->chainmask_table_id, 19281 chain_mask_combo->num_valid_chainmask 19282 ); 19283 19284 param->chainmask_table[i].table_id = 19285 chain_mask_combo->chainmask_table_id; 19286 param->chainmask_table[i].num_valid_chainmasks = 19287 chain_mask_combo->num_valid_chainmask; 19288 chain_mask_combo++; 19289 } 19290 qdf_print("chain mask combo end\n"); 19291 19292 return QDF_STATUS_SUCCESS; 19293 } 19294 19295 /** 19296 * extract_sar_cap_service_ready_ext_tlv() - 19297 * extract SAR cap from service ready event 19298 * @wmi_handle: wmi handle 19299 * @event: pointer to event buffer 19300 * @ext_param: extended target info 19301 * 19302 * Return: QDF_STATUS_SUCCESS for success or error code 19303 */ 19304 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 19305 wmi_unified_t wmi_handle, 19306 uint8_t *event, 19307 struct wlan_psoc_host_service_ext_param *ext_param) 19308 { 19309 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19310 WMI_SAR_CAPABILITIES *sar_caps; 19311 19312 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19313 19314 sar_caps = param_buf->sar_caps; 19315 if (!sar_caps) 19316 return QDF_STATUS_E_INVAL; 19317 19318 ext_param->sar_version = sar_caps->active_version; 19319 19320 return QDF_STATUS_SUCCESS; 19321 } 19322 19323 /** 19324 * extract_hw_mode_cap_service_ready_ext_tlv() - 19325 * extract HW mode cap from service ready event 19326 * @wmi_handle: wmi handle 19327 * @param evt_buf: pointer to event buffer 19328 * @param param: Pointer to hold evt buf 19329 * @param hw_mode_idx: hw mode idx should be less than num_mode 19330 * 19331 * Return: QDF_STATUS_SUCCESS for success or error code 19332 */ 19333 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19334 wmi_unified_t wmi_handle, 19335 uint8_t *event, uint8_t hw_mode_idx, 19336 struct wlan_psoc_host_hw_mode_caps *param) 19337 { 19338 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19339 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19340 19341 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19342 if (!param_buf) 19343 return QDF_STATUS_E_INVAL; 19344 19345 hw_caps = param_buf->soc_hw_mode_caps; 19346 if (!hw_caps) 19347 return QDF_STATUS_E_INVAL; 19348 19349 if (hw_mode_idx >= hw_caps->num_hw_modes) 19350 return QDF_STATUS_E_INVAL; 19351 19352 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19353 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19354 19355 param->hw_mode_config_type = 19356 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19357 19358 return QDF_STATUS_SUCCESS; 19359 } 19360 19361 /** 19362 * extract_mac_phy_cap_service_ready_ext_tlv() - 19363 * extract MAC phy cap from service ready event 19364 * @wmi_handle: wmi handle 19365 * @param evt_buf: pointer to event buffer 19366 * @param param: Pointer to hold evt buf 19367 * @param hw_mode_idx: hw mode idx should be less than num_mode 19368 * @param phy_id: phy id within hw_mode 19369 * 19370 * Return: QDF_STATUS_SUCCESS for success or error code 19371 */ 19372 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19373 wmi_unified_t wmi_handle, 19374 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19375 struct wlan_psoc_host_mac_phy_caps *param) 19376 { 19377 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19378 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19379 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19380 uint32_t phy_map; 19381 uint8_t hw_idx, phy_idx = 0; 19382 19383 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19384 if (!param_buf) 19385 return QDF_STATUS_E_INVAL; 19386 19387 hw_caps = param_buf->soc_hw_mode_caps; 19388 if (!hw_caps) 19389 return QDF_STATUS_E_INVAL; 19390 19391 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19392 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19393 break; 19394 19395 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19396 while (phy_map) { 19397 phy_map >>= 1; 19398 phy_idx++; 19399 } 19400 } 19401 19402 if (hw_idx == hw_caps->num_hw_modes) 19403 return QDF_STATUS_E_INVAL; 19404 19405 phy_idx += phy_id; 19406 if (phy_idx >= param_buf->num_mac_phy_caps) 19407 return QDF_STATUS_E_INVAL; 19408 19409 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19410 19411 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19412 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19413 mac_phy_caps->pdev_id); 19414 param->phy_id = mac_phy_caps->phy_id; 19415 param->supports_11b = 19416 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19417 param->supports_11g = 19418 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19419 param->supports_11a = 19420 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19421 param->supports_11n = 19422 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19423 param->supports_11ac = 19424 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19425 param->supports_11ax = 19426 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19427 19428 param->supported_bands = mac_phy_caps->supported_bands; 19429 param->ampdu_density = mac_phy_caps->ampdu_density; 19430 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19431 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19432 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19433 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19434 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 19435 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19436 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19437 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19438 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19439 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19440 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19441 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19442 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 19443 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 19444 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 19445 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 19446 qdf_mem_copy(¶m->he_cap_phy_info_2G, 19447 &mac_phy_caps->he_cap_phy_info_2G, 19448 sizeof(param->he_cap_phy_info_2G)); 19449 qdf_mem_copy(¶m->he_cap_phy_info_5G, 19450 &mac_phy_caps->he_cap_phy_info_5G, 19451 sizeof(param->he_cap_phy_info_5G)); 19452 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 19453 sizeof(param->he_ppet2G)); 19454 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 19455 sizeof(param->he_ppet5G)); 19456 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 19457 19458 return QDF_STATUS_SUCCESS; 19459 } 19460 19461 /** 19462 * extract_reg_cap_service_ready_ext_tlv() - 19463 * extract REG cap from service ready event 19464 * @wmi_handle: wmi handle 19465 * @param evt_buf: pointer to event buffer 19466 * @param param: Pointer to hold evt buf 19467 * @param phy_idx: phy idx should be less than num_mode 19468 * 19469 * Return: QDF_STATUS_SUCCESS for success or error code 19470 */ 19471 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 19472 wmi_unified_t wmi_handle, 19473 uint8_t *event, uint8_t phy_idx, 19474 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 19475 { 19476 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19477 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19478 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 19479 19480 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19481 if (!param_buf) 19482 return QDF_STATUS_E_INVAL; 19483 19484 reg_caps = param_buf->soc_hal_reg_caps; 19485 if (!reg_caps) 19486 return QDF_STATUS_E_INVAL; 19487 19488 if (phy_idx >= reg_caps->num_phy) 19489 return QDF_STATUS_E_INVAL; 19490 19491 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 19492 19493 param->phy_id = ext_reg_cap->phy_id; 19494 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 19495 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 19496 param->regcap1 = ext_reg_cap->regcap1; 19497 param->regcap2 = ext_reg_cap->regcap2; 19498 param->wireless_modes = convert_wireless_modes_tlv( 19499 ext_reg_cap->wireless_modes); 19500 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 19501 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 19502 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 19503 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 19504 19505 return QDF_STATUS_SUCCESS; 19506 } 19507 19508 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 19509 wmi_unified_t wmi_handle, 19510 uint8_t *event, uint8_t idx, 19511 struct wlan_psoc_host_dbr_ring_caps *param) 19512 { 19513 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19514 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 19515 19516 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19517 if (!param_buf) 19518 return QDF_STATUS_E_INVAL; 19519 19520 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 19521 19522 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19523 dbr_ring_caps->pdev_id); 19524 param->mod_id = dbr_ring_caps->mod_id; 19525 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 19526 param->min_buf_size = dbr_ring_caps->min_buf_size; 19527 param->min_buf_align = dbr_ring_caps->min_buf_align; 19528 19529 return QDF_STATUS_SUCCESS; 19530 } 19531 19532 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 19533 uint8_t *event, struct direct_buf_rx_rsp *param) 19534 { 19535 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19536 wmi_dma_buf_release_fixed_param *ev; 19537 19538 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19539 if (!param_buf) 19540 return QDF_STATUS_E_INVAL; 19541 19542 ev = param_buf->fixed_param; 19543 if (!ev) 19544 return QDF_STATUS_E_INVAL; 19545 19546 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19547 ev->pdev_id); 19548 param->mod_id = ev->mod_id; 19549 param->num_buf_release_entry = ev->num_buf_release_entry; 19550 param->num_meta_data_entry = ev->num_meta_data_entry; 19551 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 19552 param->pdev_id, param->mod_id, param->num_buf_release_entry); 19553 19554 return QDF_STATUS_SUCCESS; 19555 } 19556 19557 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 19558 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 19559 { 19560 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19561 wmi_dma_buf_release_entry *entry; 19562 19563 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19564 if (!param_buf) 19565 return QDF_STATUS_E_INVAL; 19566 19567 entry = ¶m_buf->entries[idx]; 19568 19569 if (!entry) { 19570 WMI_LOGE("%s: Entry is NULL\n", __func__); 19571 return QDF_STATUS_E_FAILURE; 19572 } 19573 19574 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 19575 19576 param->paddr_lo = entry->paddr_lo; 19577 param->paddr_hi = entry->paddr_hi; 19578 19579 return QDF_STATUS_SUCCESS; 19580 } 19581 19582 static QDF_STATUS extract_dbr_buf_metadata_tlv( 19583 wmi_unified_t wmi_handle, uint8_t *event, 19584 uint8_t idx, struct direct_buf_rx_metadata *param) 19585 { 19586 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19587 wmi_dma_buf_release_spectral_meta_data *entry; 19588 19589 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19590 if (!param_buf) 19591 return QDF_STATUS_E_INVAL; 19592 19593 entry = ¶m_buf->meta_data[idx]; 19594 19595 if (!entry) { 19596 WMI_LOGE("%s: Entry is NULL\n", __func__); 19597 return QDF_STATUS_E_FAILURE; 19598 } 19599 19600 qdf_mem_copy(param->noisefloor, entry->noise_floor, 19601 sizeof(entry->noise_floor)); 19602 return QDF_STATUS_SUCCESS; 19603 } 19604 19605 /** 19606 * extract_dcs_interference_type_tlv() - extract dcs interference type 19607 * from event 19608 * @wmi_handle: wmi handle 19609 * @param evt_buf: pointer to event buffer 19610 * @param param: Pointer to hold dcs interference param 19611 * 19612 * Return: 0 for success or error code 19613 */ 19614 static QDF_STATUS extract_dcs_interference_type_tlv( 19615 wmi_unified_t wmi_handle, 19616 void *evt_buf, struct wmi_host_dcs_interference_param *param) 19617 { 19618 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19619 19620 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19621 if (!param_buf) 19622 return QDF_STATUS_E_INVAL; 19623 19624 param->interference_type = param_buf->fixed_param->interference_type; 19625 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19626 param_buf->fixed_param->pdev_id); 19627 19628 return QDF_STATUS_SUCCESS; 19629 } 19630 19631 /* 19632 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 19633 * @wmi_handle: wmi handle 19634 * @param evt_buf: pointer to event buffer 19635 * @param cw_int: Pointer to hold cw interference 19636 * 19637 * Return: 0 for success or error code 19638 */ 19639 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 19640 void *evt_buf, 19641 wmi_host_ath_dcs_cw_int *cw_int) 19642 { 19643 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19644 wlan_dcs_cw_int *ev; 19645 19646 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19647 if (!param_buf) 19648 return QDF_STATUS_E_INVAL; 19649 19650 ev = param_buf->cw_int; 19651 19652 cw_int->channel = ev->channel; 19653 19654 return QDF_STATUS_SUCCESS; 19655 } 19656 19657 /** 19658 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 19659 * @wmi_handle: wmi handle 19660 * @param evt_buf: pointer to event buffer 19661 * @param wlan_stat: Pointer to hold wlan stats 19662 * 19663 * Return: 0 for success or error code 19664 */ 19665 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 19666 void *evt_buf, 19667 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 19668 { 19669 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19670 wlan_dcs_im_tgt_stats_t *ev; 19671 19672 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19673 if (!param_buf) 19674 return QDF_STATUS_E_INVAL; 19675 19676 ev = param_buf->wlan_stat; 19677 wlan_stat->reg_tsf32 = ev->reg_tsf32; 19678 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 19679 wlan_stat->tx_waste_time = ev->tx_waste_time; 19680 wlan_stat->rx_time = ev->rx_time; 19681 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 19682 wlan_stat->mib_stats.listen_time = ev->listen_time; 19683 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 19684 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 19685 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 19686 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 19687 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 19688 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 19689 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 19690 wlan_stat->chan_nf = ev->chan_nf; 19691 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19692 19693 return QDF_STATUS_SUCCESS; 19694 } 19695 19696 /** 19697 * extract_thermal_stats_tlv() - extract thermal stats from event 19698 * @wmi_handle: wmi handle 19699 * @param evt_buf: Pointer to event buffer 19700 * @param temp: Pointer to hold extracted temperature 19701 * @param level: Pointer to hold extracted level 19702 * 19703 * Return: 0 for success or error code 19704 */ 19705 static QDF_STATUS 19706 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 19707 void *evt_buf, uint32_t *temp, 19708 uint32_t *level, uint32_t *pdev_id) 19709 { 19710 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19711 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 19712 19713 param_buf = 19714 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19715 if (!param_buf) 19716 return QDF_STATUS_E_INVAL; 19717 19718 tt_stats_event = param_buf->fixed_param; 19719 19720 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19721 tt_stats_event->pdev_id); 19722 *temp = tt_stats_event->temp; 19723 *level = tt_stats_event->level; 19724 19725 return QDF_STATUS_SUCCESS; 19726 } 19727 19728 /** 19729 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 19730 * @wmi_handle: wmi handle 19731 * @param evt_buf: pointer to event buffer 19732 * @param idx: Index to level stats 19733 * @param levelcount: Pointer to hold levelcount 19734 * @param dccount: Pointer to hold dccount 19735 * 19736 * Return: 0 for success or error code 19737 */ 19738 static QDF_STATUS 19739 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 19740 void *evt_buf, uint8_t idx, uint32_t *levelcount, 19741 uint32_t *dccount) 19742 { 19743 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19744 wmi_therm_throt_level_stats_info *tt_level_info; 19745 19746 param_buf = 19747 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19748 if (!param_buf) 19749 return QDF_STATUS_E_INVAL; 19750 19751 tt_level_info = param_buf->therm_throt_level_stats_info; 19752 19753 if (idx < THERMAL_LEVELS) { 19754 *levelcount = tt_level_info[idx].level_count; 19755 *dccount = tt_level_info[idx].dc_count; 19756 return QDF_STATUS_SUCCESS; 19757 } 19758 19759 return QDF_STATUS_E_FAILURE; 19760 } 19761 #ifdef BIG_ENDIAN_HOST 19762 /** 19763 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 19764 * @param data_len - data length 19765 * @param data - pointer to data 19766 * 19767 * Return: QDF_STATUS - success or error status 19768 */ 19769 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19770 { 19771 uint8_t *data_aligned = NULL; 19772 int c; 19773 unsigned char *data_unaligned; 19774 19775 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 19776 FIPS_ALIGN)); 19777 /* Assigning unaligned space to copy the data */ 19778 /* Checking if kmalloc does successful allocation */ 19779 if (data_unaligned == NULL) 19780 return QDF_STATUS_E_FAILURE; 19781 19782 /* Checking if space is alligned */ 19783 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 19784 /* align the data space */ 19785 data_aligned = 19786 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 19787 } else { 19788 data_aligned = (u_int8_t *)data_unaligned; 19789 } 19790 19791 /* memset and copy content from data to data aligned */ 19792 OS_MEMSET(data_aligned, 0, data_len); 19793 OS_MEMCPY(data_aligned, data, data_len); 19794 /* Endianness to LE */ 19795 for (c = 0; c < data_len/4; c++) { 19796 *((u_int32_t *)data_aligned + c) = 19797 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 19798 } 19799 19800 /* Copy content to event->data */ 19801 OS_MEMCPY(data, data_aligned, data_len); 19802 19803 /* clean up allocated space */ 19804 qdf_mem_free(data_unaligned); 19805 data_aligned = NULL; 19806 data_unaligned = NULL; 19807 19808 /*************************************************************/ 19809 19810 return QDF_STATUS_SUCCESS; 19811 } 19812 #else 19813 /** 19814 * fips_conv_data_be() - DUMMY for LE platform 19815 * 19816 * Return: QDF_STATUS - success 19817 */ 19818 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19819 { 19820 return QDF_STATUS_SUCCESS; 19821 } 19822 #endif 19823 19824 /** 19825 * extract_fips_event_data_tlv() - extract fips event data 19826 * @wmi_handle: wmi handle 19827 * @param evt_buf: pointer to event buffer 19828 * @param param: pointer FIPS event params 19829 * 19830 * Return: 0 for success or error code 19831 */ 19832 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 19833 void *evt_buf, struct wmi_host_fips_event_param *param) 19834 { 19835 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 19836 wmi_pdev_fips_event_fixed_param *event; 19837 19838 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 19839 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 19840 19841 if (fips_conv_data_be(event->data_len, param_buf->data) != 19842 QDF_STATUS_SUCCESS) 19843 return QDF_STATUS_E_FAILURE; 19844 19845 param->data = (uint32_t *)param_buf->data; 19846 param->data_len = event->data_len; 19847 param->error_status = event->error_status; 19848 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19849 event->pdev_id); 19850 19851 return QDF_STATUS_SUCCESS; 19852 } 19853 19854 /* 19855 * extract_peer_delete_response_event_tlv() - extract peer delete response event 19856 * @wmi_handle: wmi handle 19857 * @param evt_buf: pointer to event buffer 19858 * @param vdev_id: Pointer to hold vdev_id 19859 * @param mac_addr: Pointer to hold peer mac address 19860 * 19861 * Return: QDF_STATUS_SUCCESS for success or error code 19862 */ 19863 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 19864 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 19865 { 19866 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 19867 wmi_peer_delete_resp_event_fixed_param *ev; 19868 19869 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 19870 19871 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 19872 if (!ev) { 19873 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 19874 return QDF_STATUS_E_FAILURE; 19875 } 19876 19877 param->vdev_id = ev->vdev_id; 19878 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 19879 ¶m->mac_address.bytes[0]); 19880 19881 return QDF_STATUS_SUCCESS; 19882 } 19883 19884 static bool is_management_record_tlv(uint32_t cmd_id) 19885 { 19886 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 19887 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 19888 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 19889 return true; 19890 } 19891 19892 return false; 19893 } 19894 19895 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19896 { 19897 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 19898 19899 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 19900 19901 switch (set_cmd->param_id) { 19902 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 19903 case WMI_VDEV_PARAM_DTIM_POLICY: 19904 return HTC_TX_PACKET_TAG_AUTO_PM; 19905 default: 19906 break; 19907 } 19908 19909 return 0; 19910 } 19911 19912 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19913 { 19914 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 19915 19916 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 19917 19918 switch (ps_cmd->param) { 19919 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 19920 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 19921 case WMI_STA_PS_ENABLE_QPOWER: 19922 return HTC_TX_PACKET_TAG_AUTO_PM; 19923 default: 19924 break; 19925 } 19926 19927 return 0; 19928 } 19929 19930 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 19931 uint32_t cmd_id) 19932 { 19933 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 19934 return 0; 19935 19936 switch (cmd_id) { 19937 case WMI_VDEV_SET_PARAM_CMDID: 19938 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 19939 case WMI_STA_POWERSAVE_PARAM_CMDID: 19940 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 19941 default: 19942 break; 19943 } 19944 19945 return 0; 19946 } 19947 19948 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 19949 { 19950 uint16_t tag = 0; 19951 19952 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 19953 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 19954 __func__); 19955 return tag; 19956 } 19957 19958 if (wmi_handle->tag_crash_inject) 19959 tag = HTC_TX_PACKET_TAG_AUTO_PM; 19960 19961 wmi_handle->tag_crash_inject = false; 19962 return tag; 19963 } 19964 19965 /** 19966 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 19967 * @wmi_handle: WMI handle 19968 * @buf: WMI buffer 19969 * @cmd_id: WMI command Id 19970 * 19971 * Return htc_tx_tag 19972 */ 19973 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 19974 wmi_buf_t buf, 19975 uint32_t cmd_id) 19976 { 19977 uint16_t htc_tx_tag = 0; 19978 19979 switch (cmd_id) { 19980 case WMI_WOW_ENABLE_CMDID: 19981 case WMI_PDEV_SUSPEND_CMDID: 19982 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 19983 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 19984 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 19985 case WMI_PDEV_RESUME_CMDID: 19986 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 19987 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 19988 #ifdef FEATURE_WLAN_D0WOW 19989 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 19990 #endif 19991 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 19992 break; 19993 case WMI_FORCE_FW_HANG_CMDID: 19994 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 19995 break; 19996 case WMI_VDEV_SET_PARAM_CMDID: 19997 case WMI_STA_POWERSAVE_PARAM_CMDID: 19998 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 19999 default: 20000 break; 20001 } 20002 20003 return htc_tx_tag; 20004 } 20005 20006 /** 20007 * extract_channel_hopping_event_tlv() - extract channel hopping param 20008 * from event 20009 * @wmi_handle: wmi handle 20010 * @param evt_buf: pointer to event buffer 20011 * @param ch_hopping: Pointer to hold channel hopping param 20012 * 20013 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20014 */ 20015 static QDF_STATUS extract_channel_hopping_event_tlv( 20016 wmi_unified_t wmi_handle, void *evt_buf, 20017 wmi_host_pdev_channel_hopping_event *ch_hopping) 20018 { 20019 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20020 wmi_pdev_channel_hopping_event_fixed_param *event; 20021 20022 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20023 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20024 param_buf->fixed_param; 20025 20026 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20027 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20028 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20029 event->pdev_id); 20030 20031 return QDF_STATUS_SUCCESS; 20032 } 20033 20034 /** 20035 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20036 * @wmi_handle: wmi handle 20037 * @param evt_buf: pointer to event buffer 20038 * @param param: Pointer to hold tpc param 20039 * 20040 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20041 */ 20042 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20043 void *evt_buf, 20044 wmi_host_pdev_tpc_event *param) 20045 { 20046 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20047 wmi_pdev_tpc_event_fixed_param *event; 20048 20049 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20050 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20051 20052 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20053 event->pdev_id); 20054 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20055 20056 return QDF_STATUS_SUCCESS; 20057 } 20058 20059 /** 20060 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20061 * power param from event 20062 * @wmi_handle: wmi handle 20063 * @param evt_buf: pointer to event buffer 20064 * @param param: Pointer to hold nf cal power param 20065 * 20066 * Return: 0 for success or error code 20067 */ 20068 static QDF_STATUS 20069 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20070 void *evt_buf, 20071 wmi_host_pdev_nfcal_power_all_channels_event *param) 20072 { 20073 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20074 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20075 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20076 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20077 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20078 uint32_t i; 20079 20080 param_buf = 20081 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20082 event = param_buf->fixed_param; 20083 ch_nfdbr = param_buf->nfdbr; 20084 ch_nfdbm = param_buf->nfdbm; 20085 ch_freqnum = param_buf->freqnum; 20086 20087 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20088 event->pdev_id, param_buf->num_nfdbr, 20089 param_buf->num_nfdbm, param_buf->num_freqnum); 20090 20091 if (param_buf->num_nfdbr > 20092 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20093 WMI_LOGE("invalid number of nfdBr"); 20094 return QDF_STATUS_E_FAILURE; 20095 } 20096 20097 if (param_buf->num_nfdbm > 20098 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20099 WMI_LOGE("invalid number of nfdBm"); 20100 return QDF_STATUS_E_FAILURE; 20101 } 20102 20103 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20104 WMI_LOGE("invalid number of freqNum"); 20105 return QDF_STATUS_E_FAILURE; 20106 } 20107 20108 for (i = 0; i < param_buf->num_nfdbr; i++) { 20109 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20110 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20111 ch_nfdbr++; 20112 ch_nfdbm++; 20113 } 20114 20115 for (i = 0; i < param_buf->num_freqnum; i++) { 20116 param->freqnum[i] = ch_freqnum->freqNum; 20117 ch_freqnum++; 20118 } 20119 20120 param->pdev_id = wmi_handle->ops-> 20121 convert_pdev_id_target_to_host(event->pdev_id); 20122 20123 return QDF_STATUS_SUCCESS; 20124 } 20125 20126 20127 #ifdef BIG_ENDIAN_HOST 20128 /** 20129 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20130 * @param data_len - data length 20131 * @param data - pointer to data 20132 * 20133 * Return: QDF_STATUS - success or error status 20134 */ 20135 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20136 { 20137 uint8_t *datap = (uint8_t *)ev; 20138 int i; 20139 /* Skip swapping the first word */ 20140 datap += sizeof(uint32_t); 20141 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20142 i++, datap += sizeof(uint32_t)) { 20143 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20144 } 20145 20146 return QDF_STATUS_SUCCESS; 20147 } 20148 #else 20149 /** 20150 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20151 * @param data_len - data length 20152 * @param data - pointer to data 20153 * 20154 * Return: QDF_STATUS - success or error status 20155 */ 20156 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20157 { 20158 return QDF_STATUS_SUCCESS; 20159 } 20160 #endif 20161 20162 /** 20163 * extract_wds_addr_event_tlv() - extract wds address from event 20164 * @wmi_handle: wmi handle 20165 * @param evt_buf: pointer to event buffer 20166 * @param wds_ev: Pointer to hold wds address 20167 * 20168 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20169 */ 20170 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20171 void *evt_buf, 20172 uint16_t len, wds_addr_event_t *wds_ev) 20173 { 20174 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20175 wmi_wds_addr_event_fixed_param *ev; 20176 int i; 20177 20178 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20179 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20180 20181 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20182 return QDF_STATUS_E_FAILURE; 20183 20184 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20185 sizeof(wds_ev->event_type)); 20186 for (i = 0; i < 4; i++) { 20187 wds_ev->peer_mac[i] = 20188 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20189 wds_ev->dest_mac[i] = 20190 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20191 } 20192 for (i = 0; i < 2; i++) { 20193 wds_ev->peer_mac[4+i] = 20194 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20195 wds_ev->dest_mac[4+i] = 20196 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20197 } 20198 return QDF_STATUS_SUCCESS; 20199 } 20200 20201 /** 20202 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20203 * from event 20204 * @wmi_handle: wmi handle 20205 * @param evt_buf: pointer to event buffer 20206 * @param ev: Pointer to hold peer param and ps state 20207 * 20208 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20209 */ 20210 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20211 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20212 { 20213 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20214 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20215 20216 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20217 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20218 param_buf->fixed_param; 20219 20220 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20221 ev->peer_ps_state = event->peer_ps_state; 20222 20223 return QDF_STATUS_SUCCESS; 20224 } 20225 20226 /** 20227 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20228 * @wmi_handle: wmi handle 20229 * @param evt_buf: pointer to event buffer 20230 * @param inst_rssi_resp: Pointer to hold inst rssi response 20231 * 20232 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20233 */ 20234 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20235 wmi_unified_t wmi_handle, void *evt_buf, 20236 wmi_host_inst_stats_resp *inst_rssi_resp) 20237 { 20238 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20239 wmi_inst_rssi_stats_resp_fixed_param *event; 20240 20241 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20242 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20243 20244 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20245 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20246 inst_rssi_resp->iRSSI = event->iRSSI; 20247 20248 return QDF_STATUS_SUCCESS; 20249 } 20250 20251 static struct cur_reg_rule 20252 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20253 wmi_regulatory_rule_struct *wmi_reg_rule) 20254 { 20255 struct cur_reg_rule *reg_rule_ptr; 20256 uint32_t count; 20257 20258 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20259 20260 if (NULL == reg_rule_ptr) { 20261 WMI_LOGE("memory allocation failure"); 20262 return NULL; 20263 } 20264 20265 for (count = 0; count < num_reg_rules; count++) { 20266 reg_rule_ptr[count].start_freq = 20267 WMI_REG_RULE_START_FREQ_GET( 20268 wmi_reg_rule[count].freq_info); 20269 reg_rule_ptr[count].end_freq = 20270 WMI_REG_RULE_END_FREQ_GET( 20271 wmi_reg_rule[count].freq_info); 20272 reg_rule_ptr[count].max_bw = 20273 WMI_REG_RULE_MAX_BW_GET( 20274 wmi_reg_rule[count].bw_pwr_info); 20275 reg_rule_ptr[count].reg_power = 20276 WMI_REG_RULE_REG_POWER_GET( 20277 wmi_reg_rule[count].bw_pwr_info); 20278 reg_rule_ptr[count].ant_gain = 20279 WMI_REG_RULE_ANTENNA_GAIN_GET( 20280 wmi_reg_rule[count].bw_pwr_info); 20281 reg_rule_ptr[count].flags = 20282 WMI_REG_RULE_FLAGS_GET( 20283 wmi_reg_rule[count].flag_info); 20284 } 20285 20286 return reg_rule_ptr; 20287 } 20288 20289 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20290 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20291 struct cur_regulatory_info *reg_info, uint32_t len) 20292 { 20293 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20294 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20295 wmi_regulatory_rule_struct *wmi_reg_rule; 20296 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20297 20298 WMI_LOGD("processing regulatory channel list"); 20299 20300 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20301 if (!param_buf) { 20302 WMI_LOGE("invalid channel list event buf"); 20303 return QDF_STATUS_E_FAILURE; 20304 } 20305 20306 chan_list_event_hdr = param_buf->fixed_param; 20307 20308 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20309 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20310 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20311 REG_ALPHA2_LEN); 20312 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20313 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20314 reg_info->offload_enabled = true; 20315 reg_info->num_phy = chan_list_event_hdr->num_phy; 20316 reg_info->phy_id = chan_list_event_hdr->phy_id; 20317 reg_info->ctry_code = chan_list_event_hdr->country_id; 20318 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20319 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20320 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20321 else if (chan_list_event_hdr->status_code == 20322 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20323 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20324 else if (chan_list_event_hdr->status_code == 20325 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20326 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20327 else if (chan_list_event_hdr->status_code == 20328 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20329 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20330 else if (chan_list_event_hdr->status_code == 20331 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20332 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20333 else if (chan_list_event_hdr->status_code == 20334 WMI_REG_SET_CC_STATUS_FAIL) 20335 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20336 20337 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20338 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20339 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20340 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20341 20342 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20343 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20344 20345 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20346 __func__, reg_info->alpha2, reg_info->dfs_region, 20347 reg_info->min_bw_2g, reg_info->max_bw_2g, 20348 reg_info->min_bw_5g, reg_info->max_bw_5g); 20349 20350 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20351 num_2g_reg_rules, num_5g_reg_rules); 20352 wmi_reg_rule = 20353 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20354 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20355 + WMI_TLV_HDR_SIZE); 20356 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20357 wmi_reg_rule); 20358 wmi_reg_rule += num_2g_reg_rules; 20359 20360 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20361 wmi_reg_rule); 20362 20363 WMI_LOGD("processed regulatory channel list"); 20364 20365 return QDF_STATUS_SUCCESS; 20366 } 20367 20368 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20369 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20370 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20371 { 20372 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20373 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20374 20375 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20376 if (!param_buf) { 20377 WMI_LOGE("invalid 11d country event buf"); 20378 return QDF_STATUS_E_FAILURE; 20379 } 20380 20381 reg_11d_country_event = param_buf->fixed_param; 20382 20383 qdf_mem_copy(reg_11d_country->alpha2, 20384 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20385 20386 WMI_LOGD("processed 11d country event, new cc %s", 20387 reg_11d_country->alpha2); 20388 20389 return QDF_STATUS_SUCCESS; 20390 } 20391 20392 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20393 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20394 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20395 { 20396 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20397 wmi_avoid_freq_range_desc *afr_desc; 20398 uint32_t num_freq_ranges, freq_range_idx; 20399 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20400 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20401 20402 if (!param_buf) { 20403 WMI_LOGE("Invalid channel avoid event buffer"); 20404 return QDF_STATUS_E_INVAL; 20405 } 20406 20407 afr_fixed_param = param_buf->fixed_param; 20408 if (!afr_fixed_param) { 20409 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20410 return QDF_STATUS_E_INVAL; 20411 } 20412 20413 if (!ch_avoid_ind) { 20414 WMI_LOGE("Invalid channel avoid indication buffer"); 20415 return QDF_STATUS_E_INVAL; 20416 } 20417 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20418 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20419 afr_fixed_param->num_freq_ranges; 20420 20421 WMI_LOGD("Channel avoid event received with %d ranges", 20422 num_freq_ranges); 20423 20424 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20425 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20426 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20427 freq_range_idx++) { 20428 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20429 afr_desc->start_freq; 20430 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20431 afr_desc->end_freq; 20432 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20433 freq_range_idx, afr_desc->tlv_header, 20434 afr_desc->start_freq, afr_desc->end_freq); 20435 afr_desc++; 20436 } 20437 20438 return QDF_STATUS_SUCCESS; 20439 } 20440 #ifdef DFS_COMPONENT_ENABLE 20441 /** 20442 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20443 * @wmi_handle: wma handle 20444 * @evt_buf: event buffer 20445 * @vdev_id: vdev id 20446 * @len: length of buffer 20447 * 20448 * Return: 0 for success or error code 20449 */ 20450 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20451 uint8_t *evt_buf, 20452 uint32_t *vdev_id, 20453 uint32_t len) 20454 { 20455 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20456 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20457 20458 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20459 if (!param_tlvs) { 20460 WMI_LOGE("invalid cac complete event buf"); 20461 return QDF_STATUS_E_FAILURE; 20462 } 20463 20464 cac_event = param_tlvs->fixed_param; 20465 *vdev_id = cac_event->vdev_id; 20466 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20467 20468 return QDF_STATUS_SUCCESS; 20469 } 20470 20471 /** 20472 * extract_dfs_radar_detection_event_tlv() - extract radar found event 20473 * @wmi_handle: wma handle 20474 * @evt_buf: event buffer 20475 * @radar_found: radar found event info 20476 * @len: length of buffer 20477 * 20478 * Return: 0 for success or error code 20479 */ 20480 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 20481 wmi_unified_t wmi_handle, 20482 uint8_t *evt_buf, 20483 struct radar_found_info *radar_found, 20484 uint32_t len) 20485 { 20486 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 20487 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 20488 20489 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 20490 if (!param_tlv) { 20491 WMI_LOGE("invalid radar detection event buf"); 20492 return QDF_STATUS_E_FAILURE; 20493 } 20494 20495 radar_event = param_tlv->fixed_param; 20496 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 20497 radar_event->pdev_id); 20498 radar_found->detection_mode = radar_event->detection_mode; 20499 radar_found->chan_freq = radar_event->chan_freq; 20500 radar_found->chan_width = radar_event->chan_width; 20501 radar_found->detector_id = radar_event->detector_id; 20502 radar_found->segment_id = radar_event->segment_id; 20503 radar_found->timestamp = radar_event->timestamp; 20504 radar_found->is_chirp = radar_event->is_chirp; 20505 radar_found->freq_offset = radar_event->freq_offset; 20506 radar_found->sidx = radar_event->sidx; 20507 20508 WMI_LOGI("processed radar found event pdev %d," 20509 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 20510 "chan_width (RSSI) %d,detector_id (false_radar) %d," 20511 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 20512 "is_chirp %d,detection mode %d\n", 20513 radar_event->pdev_id, radar_found->pdev_id, 20514 radar_event->timestamp, radar_event->chan_freq, 20515 radar_event->chan_width, radar_event->detector_id, 20516 radar_event->freq_offset, radar_event->segment_id, 20517 radar_event->sidx, radar_event->is_chirp, 20518 radar_event->detection_mode); 20519 20520 return QDF_STATUS_SUCCESS; 20521 } 20522 20523 #ifdef QCA_MCL_DFS_SUPPORT 20524 /** 20525 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 20526 * @wmi_handle: wma handle 20527 * @evt_buf: event buffer 20528 * @wlan_radar_event: Pointer to struct radar_event_info 20529 * @len: length of buffer 20530 * 20531 * Return: QDF_STATUS 20532 */ 20533 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20534 wmi_unified_t wmi_handle, 20535 uint8_t *evt_buf, 20536 struct radar_event_info *wlan_radar_event, 20537 uint32_t len) 20538 { 20539 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 20540 wmi_dfs_radar_event_fixed_param *radar_event; 20541 20542 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 20543 if (!param_tlv) { 20544 WMI_LOGE("invalid wlan radar event buf"); 20545 return QDF_STATUS_E_FAILURE; 20546 } 20547 20548 radar_event = param_tlv->fixed_param; 20549 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 20550 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 20551 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 20552 wlan_radar_event->rssi = radar_event->rssi; 20553 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 20554 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 20555 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 20556 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 20557 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 20558 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 20559 if (radar_event->pulse_flags & 20560 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 20561 wlan_radar_event->is_psidx_diff_valid = true; 20562 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 20563 } else { 20564 wlan_radar_event->is_psidx_diff_valid = false; 20565 } 20566 20567 wlan_radar_event->pdev_id = radar_event->pdev_id; 20568 20569 return QDF_STATUS_SUCCESS; 20570 } 20571 #else 20572 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20573 wmi_unified_t wmi_handle, 20574 uint8_t *evt_buf, 20575 struct radar_event_info *wlan_radar_event, 20576 uint32_t len) 20577 { 20578 return QDF_STATUS_SUCCESS; 20579 } 20580 #endif 20581 #endif 20582 20583 /** 20584 * send_get_rcpi_cmd_tlv() - send request for rcpi value 20585 * @wmi_handle: wmi handle 20586 * @get_rcpi_param: rcpi params 20587 * 20588 * Return: QDF status 20589 */ 20590 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 20591 struct rcpi_req *get_rcpi_param) 20592 { 20593 wmi_buf_t buf; 20594 wmi_request_rcpi_cmd_fixed_param *cmd; 20595 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 20596 20597 buf = wmi_buf_alloc(wmi_handle, len); 20598 if (!buf) { 20599 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 20600 return QDF_STATUS_E_NOMEM; 20601 } 20602 20603 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 20604 WMITLV_SET_HDR(&cmd->tlv_header, 20605 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 20606 WMITLV_GET_STRUCT_TLVLEN 20607 (wmi_request_rcpi_cmd_fixed_param)); 20608 20609 cmd->vdev_id = get_rcpi_param->vdev_id; 20610 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 20611 &cmd->peer_macaddr); 20612 20613 switch (get_rcpi_param->measurement_type) { 20614 20615 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20616 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20617 break; 20618 20619 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 20620 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 20621 break; 20622 20623 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20624 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20625 break; 20626 20627 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 20628 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 20629 break; 20630 20631 default: 20632 /* 20633 * invalid rcpi measurement type, fall back to 20634 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 20635 */ 20636 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20637 break; 20638 } 20639 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 20640 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20641 WMI_REQUEST_RCPI_CMDID)) { 20642 20643 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 20644 __func__); 20645 wmi_buf_free(buf); 20646 return QDF_STATUS_E_FAILURE; 20647 } 20648 20649 return QDF_STATUS_SUCCESS; 20650 } 20651 20652 /** 20653 * extract_rcpi_response_event_tlv() - Extract RCPI event params 20654 * @wmi_handle: wmi handle 20655 * @evt_buf: pointer to event buffer 20656 * @res: pointer to hold rcpi response from firmware 20657 * 20658 * Return: QDF_STATUS_SUCCESS for successful event parse 20659 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 20660 */ 20661 static QDF_STATUS 20662 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 20663 void *evt_buf, struct rcpi_res *res) 20664 { 20665 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 20666 wmi_update_rcpi_event_fixed_param *event; 20667 20668 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 20669 if (!param_buf) { 20670 WMI_LOGE(FL("Invalid rcpi event")); 20671 return QDF_STATUS_E_INVAL; 20672 } 20673 20674 event = param_buf->fixed_param; 20675 res->vdev_id = event->vdev_id; 20676 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 20677 20678 switch (event->measurement_type) { 20679 20680 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20681 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20682 break; 20683 20684 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 20685 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 20686 break; 20687 20688 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20689 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20690 break; 20691 20692 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 20693 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 20694 break; 20695 20696 default: 20697 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 20698 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 20699 return QDF_STATUS_E_FAILURE; 20700 } 20701 20702 if (event->status) 20703 return QDF_STATUS_E_FAILURE; 20704 else 20705 return QDF_STATUS_SUCCESS; 20706 } 20707 20708 /** 20709 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 20710 * host to target defines. For legacy there is not conversion 20711 * required. Just return pdev_id as it is. 20712 * @param pdev_id: host pdev_id to be converted. 20713 * Return: target pdev_id after conversion. 20714 */ 20715 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 20716 uint32_t pdev_id) 20717 { 20718 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 20719 return WMI_PDEV_ID_SOC; 20720 20721 /*No conversion required*/ 20722 return pdev_id; 20723 } 20724 20725 /** 20726 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 20727 * target to host defines. For legacy there is not conversion 20728 * required. Just return pdev_id as it is. 20729 * @param pdev_id: target pdev_id to be converted. 20730 * Return: host pdev_id after conversion. 20731 */ 20732 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 20733 uint32_t pdev_id) 20734 { 20735 /*No conversion required*/ 20736 return pdev_id; 20737 } 20738 20739 /** 20740 * send_set_country_cmd_tlv() - WMI scan channel list function 20741 * @param wmi_handle : handle to WMI. 20742 * @param param : pointer to hold scan channel list parameter 20743 * 20744 * Return: 0 on success and -ve on failure. 20745 */ 20746 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 20747 struct set_country *params) 20748 { 20749 wmi_buf_t buf; 20750 QDF_STATUS qdf_status; 20751 wmi_set_current_country_cmd_fixed_param *cmd; 20752 uint16_t len = sizeof(*cmd); 20753 20754 buf = wmi_buf_alloc(wmi_handle, len); 20755 if (!buf) { 20756 WMI_LOGE("Failed to allocate memory"); 20757 qdf_status = QDF_STATUS_E_NOMEM; 20758 goto end; 20759 } 20760 20761 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 20762 WMITLV_SET_HDR(&cmd->tlv_header, 20763 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 20764 WMITLV_GET_STRUCT_TLVLEN 20765 (wmi_set_current_country_cmd_fixed_param)); 20766 20767 WMI_LOGD("setting cuurnet country to %s", params->country); 20768 20769 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 20770 20771 cmd->pdev_id = params->pdev_id; 20772 20773 qdf_status = wmi_unified_cmd_send(wmi_handle, 20774 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 20775 20776 if (QDF_IS_STATUS_ERROR(qdf_status)) { 20777 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 20778 wmi_buf_free(buf); 20779 } 20780 20781 end: 20782 return qdf_status; 20783 } 20784 20785 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 20786 WMI_SET_BITS(alpha, 0, 8, val0); \ 20787 WMI_SET_BITS(alpha, 8, 8, val1); \ 20788 WMI_SET_BITS(alpha, 16, 8, val2); \ 20789 } while (0) 20790 20791 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 20792 uint8_t pdev_id, struct cc_regdmn_s *rd) 20793 { 20794 wmi_set_init_country_cmd_fixed_param *cmd; 20795 uint16_t len; 20796 wmi_buf_t buf; 20797 int ret; 20798 20799 len = sizeof(wmi_set_init_country_cmd_fixed_param); 20800 buf = wmi_buf_alloc(wmi_handle, len); 20801 if (!buf) { 20802 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 20803 return QDF_STATUS_E_NOMEM; 20804 } 20805 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 20806 WMITLV_SET_HDR(&cmd->tlv_header, 20807 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 20808 WMITLV_GET_STRUCT_TLVLEN 20809 (wmi_set_init_country_cmd_fixed_param)); 20810 20811 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 20812 20813 if (rd->flags == CC_IS_SET) { 20814 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 20815 cmd->country_code.country_id = rd->cc.country_code; 20816 } else if (rd->flags == ALPHA_IS_SET) { 20817 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 20818 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 20819 rd->cc.alpha[0], 20820 rd->cc.alpha[1], 20821 rd->cc.alpha[2]); 20822 } else if (rd->flags == REGDMN_IS_SET) { 20823 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 20824 cmd->country_code.domain_code = rd->cc.regdmn_id; 20825 } 20826 20827 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20828 WMI_SET_INIT_COUNTRY_CMDID); 20829 if (ret) { 20830 WMI_LOGE("Failed to config wow wakeup event"); 20831 wmi_buf_free(buf); 20832 return QDF_STATUS_E_FAILURE; 20833 } 20834 20835 return QDF_STATUS_SUCCESS; 20836 } 20837 20838 /** 20839 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 20840 * configuration params 20841 * @wmi_handle: wmi handler 20842 * @limit_off_chan_param: pointer to wmi_off_chan_param 20843 * 20844 * Return: 0 for success and non zero for failure 20845 */ 20846 static 20847 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 20848 struct wmi_limit_off_chan_param *limit_off_chan_param) 20849 { 20850 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 20851 wmi_buf_t buf; 20852 uint32_t len = sizeof(*cmd); 20853 int err; 20854 20855 buf = wmi_buf_alloc(wmi_handle, len); 20856 if (!buf) { 20857 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 20858 __func__); 20859 return QDF_STATUS_E_NOMEM; 20860 } 20861 20862 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 20863 20864 WMITLV_SET_HDR(&cmd->tlv_header, 20865 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 20866 WMITLV_GET_STRUCT_TLVLEN( 20867 wmi_vdev_limit_offchan_cmd_fixed_param)); 20868 20869 cmd->vdev_id = limit_off_chan_param->vdev_id; 20870 20871 cmd->flags &= 0; 20872 if (limit_off_chan_param->status) 20873 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 20874 if (limit_off_chan_param->skip_dfs_chans) 20875 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 20876 20877 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 20878 cmd->rest_time = limit_off_chan_param->rest_time; 20879 20880 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 20881 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 20882 cmd->rest_time); 20883 20884 err = wmi_unified_cmd_send(wmi_handle, buf, 20885 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 20886 if (QDF_IS_STATUS_ERROR(err)) { 20887 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 20888 wmi_buf_free(buf); 20889 return QDF_STATUS_E_FAILURE; 20890 } 20891 20892 return QDF_STATUS_SUCCESS; 20893 } 20894 20895 /** 20896 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 20897 * @wmi_handle: wmi handler 20898 * @req_buf: set arp stats request buffer 20899 * 20900 * Return: 0 for success and non zero for failure 20901 */ 20902 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20903 struct set_arp_stats *req_buf) 20904 { 20905 wmi_buf_t buf = NULL; 20906 QDF_STATUS status; 20907 int len; 20908 uint8_t *buf_ptr; 20909 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 20910 20911 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20912 if (req_buf->pkt_type_bitmap) { 20913 len += WMI_TLV_HDR_SIZE; 20914 len += sizeof(wmi_vdev_set_connectivity_check_stats); 20915 } 20916 buf = wmi_buf_alloc(wmi_handle, len); 20917 if (!buf) { 20918 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 20919 return QDF_STATUS_E_NOMEM; 20920 } 20921 20922 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20923 wmi_set_arp = 20924 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 20925 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 20926 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 20927 WMITLV_GET_STRUCT_TLVLEN 20928 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 20929 20930 /* fill in per roam config values */ 20931 wmi_set_arp->vdev_id = req_buf->vdev_id; 20932 20933 wmi_set_arp->set_clr = req_buf->flag; 20934 wmi_set_arp->pkt_type = req_buf->pkt_type; 20935 wmi_set_arp->ipv4 = req_buf->ip_addr; 20936 20937 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 20938 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 20939 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 20940 20941 /* 20942 * pkt_type_bitmap should be non-zero to ensure 20943 * presence of additional stats. 20944 */ 20945 if (req_buf->pkt_type_bitmap) { 20946 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 20947 20948 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20949 WMITLV_SET_HDR(buf_ptr, 20950 WMITLV_TAG_ARRAY_STRUC, 20951 sizeof(wmi_vdev_set_connectivity_check_stats)); 20952 buf_ptr += WMI_TLV_HDR_SIZE; 20953 wmi_set_connect_stats = 20954 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 20955 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 20956 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 20957 WMITLV_GET_STRUCT_TLVLEN( 20958 wmi_vdev_set_connectivity_check_stats)); 20959 wmi_set_connect_stats->pkt_type_bitmap = 20960 req_buf->pkt_type_bitmap; 20961 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 20962 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 20963 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 20964 20965 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 20966 wmi_set_connect_stats->pkt_type_bitmap, 20967 wmi_set_connect_stats->tcp_src_port, 20968 wmi_set_connect_stats->tcp_dst_port, 20969 wmi_set_connect_stats->icmp_ipv4); 20970 } 20971 20972 /* Send per roam config parameters */ 20973 status = wmi_unified_cmd_send(wmi_handle, buf, 20974 len, WMI_VDEV_SET_ARP_STAT_CMDID); 20975 if (QDF_IS_STATUS_ERROR(status)) { 20976 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 20977 status); 20978 goto error; 20979 } 20980 20981 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 20982 req_buf->flag, req_buf->vdev_id); 20983 return QDF_STATUS_SUCCESS; 20984 error: 20985 wmi_buf_free(buf); 20986 20987 return status; 20988 } 20989 20990 /** 20991 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 20992 * @wmi_handle: wmi handler 20993 * @req_buf: get arp stats request buffer 20994 * 20995 * Return: 0 for success and non zero for failure 20996 */ 20997 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20998 struct get_arp_stats *req_buf) 20999 { 21000 wmi_buf_t buf = NULL; 21001 QDF_STATUS status; 21002 int len; 21003 uint8_t *buf_ptr; 21004 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21005 21006 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21007 buf = wmi_buf_alloc(wmi_handle, len); 21008 if (!buf) { 21009 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21010 return QDF_STATUS_E_NOMEM; 21011 } 21012 21013 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21014 get_arp_stats = 21015 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21016 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21017 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21018 WMITLV_GET_STRUCT_TLVLEN 21019 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21020 21021 /* fill in arp stats req cmd values */ 21022 get_arp_stats->vdev_id = req_buf->vdev_id; 21023 21024 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21025 /* Send per roam config parameters */ 21026 status = wmi_unified_cmd_send(wmi_handle, buf, 21027 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21028 if (QDF_IS_STATUS_ERROR(status)) { 21029 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21030 status); 21031 goto error; 21032 } 21033 21034 return QDF_STATUS_SUCCESS; 21035 error: 21036 wmi_buf_free(buf); 21037 21038 return status; 21039 } 21040 21041 /** 21042 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21043 * @wmi_handle: wmi handler 21044 * @pmk_info: pointer to PMK cache entry 21045 * @vdev_id: vdev id 21046 * 21047 * Return: 0 for success and non zero for failure 21048 */ 21049 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21050 struct wmi_unified_pmk_cache *pmk_info) 21051 { 21052 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21053 wmi_buf_t buf; 21054 QDF_STATUS status; 21055 uint8_t *buf_ptr; 21056 wmi_pmk_cache *pmksa; 21057 uint32_t len = sizeof(*cmd); 21058 21059 if (pmk_info->pmk_len) 21060 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21061 21062 buf = wmi_buf_alloc(wmi_handle, len); 21063 if (!buf) { 21064 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21065 __func__); 21066 return QDF_STATUS_E_NOMEM; 21067 } 21068 21069 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21070 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21071 21072 WMITLV_SET_HDR(&cmd->tlv_header, 21073 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21074 WMITLV_GET_STRUCT_TLVLEN( 21075 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21076 21077 cmd->vdev_id = pmk_info->session_id; 21078 21079 /* If pmk_info->pmk_len is 0, this is a flush request */ 21080 if (!pmk_info->pmk_len) { 21081 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21082 cmd->num_cache = 0; 21083 goto send_cmd; 21084 } 21085 21086 cmd->num_cache = 1; 21087 buf_ptr += sizeof(*cmd); 21088 21089 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21090 sizeof(*pmksa)); 21091 buf_ptr += WMI_TLV_HDR_SIZE; 21092 21093 pmksa = (wmi_pmk_cache *)buf_ptr; 21094 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21095 WMITLV_GET_STRUCT_TLVLEN 21096 (wmi_pmk_cache)); 21097 pmksa->pmk_len = pmk_info->pmk_len; 21098 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21099 pmksa->pmkid_len = pmk_info->pmkid_len; 21100 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21101 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21102 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21103 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21104 pmksa->ssid.ssid_len); 21105 pmksa->cache_id = pmk_info->cache_id; 21106 pmksa->cat_flag = pmk_info->cat_flag; 21107 pmksa->action_flag = pmk_info->action_flag; 21108 21109 send_cmd: 21110 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21111 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21112 if (status != QDF_STATUS_SUCCESS) { 21113 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21114 __func__, status); 21115 wmi_buf_free(buf); 21116 } 21117 21118 return status; 21119 } 21120 21121 /** 21122 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21123 * @wmi_handle: wmi handle 21124 * @param: reserved param 21125 * 21126 * Return: 0 for success or error code 21127 */ 21128 static QDF_STATUS 21129 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21130 uint32_t param) 21131 { 21132 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21133 wmi_buf_t buf; 21134 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21135 21136 buf = wmi_buf_alloc(wmi_handle, len); 21137 if (!buf) { 21138 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21139 return QDF_STATUS_E_FAILURE; 21140 } 21141 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21142 WMITLV_SET_HDR(&cmd->tlv_header, 21143 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21144 WMITLV_GET_STRUCT_TLVLEN 21145 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21146 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21147 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21148 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21149 wmi_buf_free(buf); 21150 return QDF_STATUS_E_FAILURE; 21151 } 21152 21153 return QDF_STATUS_SUCCESS; 21154 } 21155 21156 /** 21157 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21158 * @wmi_handle: wmi handle 21159 * @param evt_buf: pointer to event buffer 21160 * @param param: Pointer to hold peer caldata version data 21161 * 21162 * Return: 0 for success or error code 21163 */ 21164 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21165 wmi_unified_t wmi_handle, 21166 void *evt_buf, 21167 wmi_host_pdev_check_cal_version_event *param) 21168 { 21169 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21170 wmi_pdev_check_cal_version_event_fixed_param *event; 21171 21172 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21173 if (!param_tlvs) { 21174 WMI_LOGE("invalid cal version event buf"); 21175 return QDF_STATUS_E_FAILURE; 21176 } 21177 event = param_tlvs->fixed_param; 21178 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21179 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21180 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21181 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21182 21183 param->software_cal_version = event->software_cal_version; 21184 param->board_cal_version = event->board_cal_version; 21185 param->cal_ok = event->cal_status; 21186 21187 return QDF_STATUS_SUCCESS; 21188 } 21189 21190 /* 21191 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21192 * @wmi_handle: wmi handle 21193 * @params: pointer to wmi_btm_config 21194 * 21195 * Return: QDF_STATUS 21196 */ 21197 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21198 struct wmi_btm_config *params) 21199 { 21200 21201 wmi_btm_config_fixed_param *cmd; 21202 wmi_buf_t buf; 21203 uint32_t len; 21204 21205 len = sizeof(*cmd); 21206 buf = wmi_buf_alloc(wmi_handle, len); 21207 if (!buf) { 21208 qdf_print("%s:wmi_buf_alloc failed\n", __func__); 21209 return QDF_STATUS_E_NOMEM; 21210 } 21211 21212 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21213 WMITLV_SET_HDR(&cmd->tlv_header, 21214 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21215 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21216 cmd->vdev_id = params->vdev_id; 21217 cmd->flags = params->btm_offload_config; 21218 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21219 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21220 cmd->stick_time_seconds = params->btm_sticky_time; 21221 21222 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21223 WMI_ROAM_BTM_CONFIG_CMDID)) { 21224 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21225 __func__); 21226 wmi_buf_free(buf); 21227 return QDF_STATUS_E_FAILURE; 21228 } 21229 21230 return QDF_STATUS_SUCCESS; 21231 } 21232 21233 /** 21234 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21235 * configurations to firmware. 21236 * @wmi_handle: wmi handle 21237 * @obss_cfg_param: obss detection configurations 21238 * 21239 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21240 * 21241 * Return: QDF_STATUS 21242 */ 21243 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21244 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21245 { 21246 wmi_buf_t buf; 21247 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21248 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21249 21250 buf = wmi_buf_alloc(wmi_handle, len); 21251 if (!buf) { 21252 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21253 return QDF_STATUS_E_NOMEM; 21254 } 21255 21256 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21257 WMITLV_SET_HDR(&cmd->tlv_header, 21258 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21259 WMITLV_GET_STRUCT_TLVLEN 21260 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21261 21262 cmd->vdev_id = obss_cfg_param->vdev_id; 21263 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21264 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21265 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21266 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21267 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21268 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21269 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21270 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21271 21272 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21273 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21274 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21275 wmi_buf_free(buf); 21276 return QDF_STATUS_E_FAILURE; 21277 } 21278 21279 return QDF_STATUS_SUCCESS; 21280 } 21281 21282 /** 21283 * extract_obss_detection_info_tlv() - Extract obss detection info 21284 * received from firmware. 21285 * @evt_buf: pointer to event buffer 21286 * @obss_detection: Pointer to hold obss detection info 21287 * 21288 * Return: QDF_STATUS 21289 */ 21290 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21291 struct wmi_obss_detect_info 21292 *obss_detection) 21293 { 21294 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21295 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21296 21297 if (!obss_detection) { 21298 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21299 return QDF_STATUS_E_INVAL; 21300 } 21301 21302 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21303 if (!param_buf) { 21304 WMI_LOGE("%s: Invalid evt_buf", __func__); 21305 return QDF_STATUS_E_INVAL; 21306 } 21307 21308 fix_param = param_buf->fixed_param; 21309 obss_detection->vdev_id = fix_param->vdev_id; 21310 obss_detection->matched_detection_masks = 21311 fix_param->matched_detection_masks; 21312 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21313 &obss_detection->matched_bssid_addr[0]); 21314 switch (fix_param->reason) { 21315 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21316 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21317 break; 21318 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21319 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21320 break; 21321 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21322 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21323 break; 21324 default: 21325 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21326 return QDF_STATUS_E_INVAL; 21327 } 21328 21329 return QDF_STATUS_SUCCESS; 21330 } 21331 21332 /** 21333 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 21334 * @wmi_handle: wmi handler 21335 * @params: pointer to 11k offload params 21336 * 21337 * Return: 0 for success and non zero for failure 21338 */ 21339 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 21340 struct wmi_11k_offload_params *params) 21341 { 21342 wmi_11k_offload_report_fixed_param *cmd; 21343 wmi_buf_t buf; 21344 QDF_STATUS status; 21345 uint8_t *buf_ptr; 21346 wmi_neighbor_report_11k_offload_tlv_param 21347 *neighbor_report_offload_params; 21348 wmi_neighbor_report_offload *neighbor_report_offload; 21349 21350 uint32_t len = sizeof(*cmd); 21351 21352 if (params->offload_11k_bitmask & 21353 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 21354 len += WMI_TLV_HDR_SIZE + 21355 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 21356 21357 buf = wmi_buf_alloc(wmi_handle, len); 21358 if (!buf) { 21359 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 21360 __func__); 21361 return QDF_STATUS_E_NOMEM; 21362 } 21363 21364 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21365 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 21366 21367 WMITLV_SET_HDR(&cmd->tlv_header, 21368 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 21369 WMITLV_GET_STRUCT_TLVLEN( 21370 wmi_11k_offload_report_fixed_param)); 21371 21372 cmd->vdev_id = params->vdev_id; 21373 cmd->offload_11k = params->offload_11k_bitmask; 21374 21375 if (params->offload_11k_bitmask & 21376 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 21377 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 21378 21379 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21380 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 21381 buf_ptr += WMI_TLV_HDR_SIZE; 21382 21383 neighbor_report_offload_params = 21384 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 21385 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 21386 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 21387 WMITLV_GET_STRUCT_TLVLEN( 21388 wmi_neighbor_report_11k_offload_tlv_param)); 21389 21390 neighbor_report_offload = &neighbor_report_offload_params-> 21391 neighbor_rep_ofld_params; 21392 21393 neighbor_report_offload->time_offset = 21394 params->neighbor_report_params.time_offset; 21395 neighbor_report_offload->low_rssi_offset = 21396 params->neighbor_report_params.low_rssi_offset; 21397 neighbor_report_offload->bmiss_count_trigger = 21398 params->neighbor_report_params.bmiss_count_trigger; 21399 neighbor_report_offload->per_threshold_offset = 21400 params->neighbor_report_params.per_threshold_offset; 21401 neighbor_report_offload->neighbor_report_cache_timeout = 21402 params->neighbor_report_params. 21403 neighbor_report_cache_timeout; 21404 neighbor_report_offload->max_neighbor_report_req_cap = 21405 params->neighbor_report_params. 21406 max_neighbor_report_req_cap; 21407 neighbor_report_offload->ssid.ssid_len = 21408 params->neighbor_report_params.ssid.length; 21409 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 21410 ¶ms->neighbor_report_params.ssid.mac_ssid, 21411 neighbor_report_offload->ssid.ssid_len); 21412 } 21413 21414 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21415 WMI_11K_OFFLOAD_REPORT_CMDID); 21416 if (status != QDF_STATUS_SUCCESS) { 21417 WMI_LOGE("%s: failed to send 11k offload command %d", 21418 __func__, status); 21419 wmi_buf_free(buf); 21420 } 21421 21422 return status; 21423 } 21424 21425 /** 21426 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 21427 * command 21428 * @wmi_handle: wmi handler 21429 * @params: pointer to neighbor report invoke params 21430 * 21431 * Return: 0 for success and non zero for failure 21432 */ 21433 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 21434 struct wmi_invoke_neighbor_report_params *params) 21435 { 21436 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 21437 wmi_buf_t buf; 21438 QDF_STATUS status; 21439 uint8_t *buf_ptr; 21440 uint32_t len = sizeof(*cmd); 21441 21442 buf = wmi_buf_alloc(wmi_handle, len); 21443 if (!buf) { 21444 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 21445 __func__); 21446 return QDF_STATUS_E_NOMEM; 21447 } 21448 21449 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21450 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 21451 21452 WMITLV_SET_HDR(&cmd->tlv_header, 21453 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 21454 WMITLV_GET_STRUCT_TLVLEN( 21455 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 21456 21457 cmd->vdev_id = params->vdev_id; 21458 cmd->flags = params->send_resp_to_host; 21459 21460 cmd->ssid.ssid_len = params->ssid.length; 21461 qdf_mem_copy(cmd->ssid.ssid, 21462 ¶ms->ssid.mac_ssid, 21463 cmd->ssid.ssid_len); 21464 21465 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21466 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 21467 if (status != QDF_STATUS_SUCCESS) { 21468 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 21469 __func__, status); 21470 wmi_buf_free(buf); 21471 } 21472 21473 return status; 21474 } 21475 21476 #ifdef WLAN_SUPPORT_GREEN_AP 21477 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 21478 uint8_t *evt_buf, 21479 struct wlan_green_ap_egap_status_info *egap_status_info_params) 21480 { 21481 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 21482 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 21483 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 21484 21485 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 21486 if (!param_buf) { 21487 WMI_LOGE("Invalid EGAP Info status event buffer"); 21488 return QDF_STATUS_E_INVAL; 21489 } 21490 21491 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 21492 param_buf->fixed_param; 21493 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 21494 param_buf->chainmask_list; 21495 21496 egap_status_info_params->status = egap_info_event->status; 21497 egap_status_info_params->mac_id = chainmask_event->mac_id; 21498 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 21499 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 21500 21501 return QDF_STATUS_SUCCESS; 21502 } 21503 #endif 21504 21505 /* 21506 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 21507 * updating bss color change within firmware when AP announces bss color change. 21508 * @wmi_handle: wmi handle 21509 * @vdev_id: vdev ID 21510 * @enable: enable bss color change within firmware 21511 * 21512 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 21513 * 21514 * Return: QDF_STATUS 21515 */ 21516 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 21517 uint32_t vdev_id, 21518 bool enable) 21519 { 21520 wmi_buf_t buf; 21521 wmi_bss_color_change_enable_fixed_param *cmd; 21522 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 21523 21524 buf = wmi_buf_alloc(wmi_handle, len); 21525 if (!buf) { 21526 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21527 return QDF_STATUS_E_NOMEM; 21528 } 21529 21530 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 21531 WMITLV_SET_HDR(&cmd->tlv_header, 21532 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 21533 WMITLV_GET_STRUCT_TLVLEN 21534 (wmi_bss_color_change_enable_fixed_param)); 21535 cmd->vdev_id = vdev_id; 21536 cmd->enable = enable; 21537 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21538 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 21539 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 21540 wmi_buf_free(buf); 21541 return QDF_STATUS_E_FAILURE; 21542 } 21543 21544 return QDF_STATUS_SUCCESS; 21545 } 21546 21547 /** 21548 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 21549 * configurations to firmware. 21550 * @wmi_handle: wmi handle 21551 * @cfg_param: obss detection configurations 21552 * 21553 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 21554 * 21555 * Return: QDF_STATUS 21556 */ 21557 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 21558 wmi_unified_t wmi_handle, 21559 struct wmi_obss_color_collision_cfg_param *cfg_param) 21560 { 21561 wmi_buf_t buf; 21562 wmi_obss_color_collision_det_config_fixed_param *cmd; 21563 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 21564 21565 buf = wmi_buf_alloc(wmi_handle, len); 21566 if (!buf) { 21567 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21568 return QDF_STATUS_E_NOMEM; 21569 } 21570 21571 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 21572 buf); 21573 WMITLV_SET_HDR(&cmd->tlv_header, 21574 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 21575 WMITLV_GET_STRUCT_TLVLEN 21576 (wmi_obss_color_collision_det_config_fixed_param)); 21577 cmd->vdev_id = cfg_param->vdev_id; 21578 cmd->flags = cfg_param->flags; 21579 cmd->current_bss_color = cfg_param->current_bss_color; 21580 cmd->detection_period_ms = cfg_param->detection_period_ms; 21581 cmd->scan_period_ms = cfg_param->scan_period_ms; 21582 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 21583 21584 switch (cfg_param->evt_type) { 21585 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 21586 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 21587 break; 21588 case OBSS_COLOR_COLLISION_DETECTION: 21589 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 21590 break; 21591 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21592 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21593 break; 21594 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 21595 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 21596 break; 21597 default: 21598 WMI_LOGE("%s: invalid event type: %d", 21599 __func__, cfg_param->evt_type); 21600 wmi_buf_free(buf); 21601 return QDF_STATUS_E_FAILURE; 21602 } 21603 21604 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21605 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 21606 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 21607 __func__, cfg_param->vdev_id); 21608 wmi_buf_free(buf); 21609 return QDF_STATUS_E_FAILURE; 21610 } 21611 21612 return QDF_STATUS_SUCCESS; 21613 } 21614 21615 /** 21616 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 21617 * received from firmware. 21618 * @evt_buf: pointer to event buffer 21619 * @info: Pointer to hold bss collision info 21620 * 21621 * Return: QDF_STATUS 21622 */ 21623 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 21624 struct wmi_obss_color_collision_info *info) 21625 { 21626 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 21627 wmi_obss_color_collision_evt_fixed_param *fix_param; 21628 21629 if (!info) { 21630 WMI_LOGE("%s: Invalid obss color buffer", __func__); 21631 return QDF_STATUS_E_INVAL; 21632 } 21633 21634 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 21635 evt_buf; 21636 if (!param_buf) { 21637 WMI_LOGE("%s: Invalid evt_buf", __func__); 21638 return QDF_STATUS_E_INVAL; 21639 } 21640 21641 fix_param = param_buf->fixed_param; 21642 info->vdev_id = fix_param->vdev_id; 21643 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 21644 info->obss_color_bitmap_bit32to63 = 21645 fix_param->bss_color_bitmap_bit32to63; 21646 21647 switch (fix_param->evt_type) { 21648 case WMI_BSS_COLOR_COLLISION_DISABLE: 21649 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 21650 break; 21651 case WMI_BSS_COLOR_COLLISION_DETECTION: 21652 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 21653 break; 21654 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21655 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21656 break; 21657 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 21658 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 21659 break; 21660 default: 21661 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 21662 __func__, fix_param->evt_type, fix_param->vdev_id); 21663 return QDF_STATUS_E_FAILURE; 21664 } 21665 21666 return QDF_STATUS_SUCCESS; 21667 } 21668 21669 /* 21670 * extract_comb_phyerr_tlv() - extract comb phy error from event 21671 * @wmi_handle: wmi handle 21672 * @evt_buf: pointer to event buffer 21673 * @datalen: data length of event buffer 21674 * @buf_offset: Pointer to hold value of current event buffer offset 21675 * post extraction 21676 * @phyerr: Pointer to hold phyerr 21677 * 21678 * Return: QDF_STATUS 21679 */ 21680 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 21681 void *evt_buf, 21682 uint16_t datalen, 21683 uint16_t *buf_offset, 21684 wmi_host_phyerr_t *phyerr) 21685 { 21686 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 21687 wmi_comb_phyerr_rx_hdr *pe_hdr; 21688 21689 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 21690 if (!param_tlvs) { 21691 WMI_LOGD("%s: Received null data from FW", __func__); 21692 return QDF_STATUS_E_FAILURE; 21693 } 21694 21695 pe_hdr = param_tlvs->hdr; 21696 if (!pe_hdr) { 21697 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 21698 return QDF_STATUS_E_FAILURE; 21699 } 21700 21701 /* Ensure it's at least the size of the header */ 21702 if (datalen < sizeof(*pe_hdr)) { 21703 WMI_LOGD("%s: Expected minimum size %zu, received %d", 21704 __func__, sizeof(*pe_hdr), datalen); 21705 return QDF_STATUS_E_FAILURE; 21706 } 21707 21708 phyerr->pdev_id = wmi_handle->ops-> 21709 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 21710 phyerr->tsf64 = pe_hdr->tsf_l32; 21711 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 21712 phyerr->bufp = param_tlvs->bufp; 21713 phyerr->buf_len = pe_hdr->buf_len; 21714 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 21715 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 21716 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 21717 21718 return QDF_STATUS_SUCCESS; 21719 } 21720 21721 /** 21722 * extract_single_phyerr_tlv() - extract single phy error from event 21723 * @wmi_handle: wmi handle 21724 * @evt_buf: pointer to event buffer 21725 * @datalen: data length of event buffer 21726 * @buf_offset: Pointer to hold value of current event buffer offset 21727 * post extraction 21728 * @phyerr: Pointer to hold phyerr 21729 * 21730 * Return: QDF_STATUS 21731 */ 21732 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 21733 void *evt_buf, 21734 uint16_t datalen, 21735 uint16_t *buf_offset, 21736 wmi_host_phyerr_t *phyerr) 21737 { 21738 wmi_single_phyerr_rx_event *ev; 21739 uint16_t n = *buf_offset; 21740 uint8_t *data = (uint8_t *)evt_buf; 21741 21742 if (n < datalen) { 21743 if ((datalen - n) < sizeof(ev->hdr)) { 21744 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 21745 __func__, datalen, n, sizeof(ev->hdr)); 21746 return QDF_STATUS_E_FAILURE; 21747 } 21748 21749 /* 21750 * Obtain a pointer to the beginning of the current event. 21751 * data[0] is the beginning of the WMI payload. 21752 */ 21753 ev = (wmi_single_phyerr_rx_event *)&data[n]; 21754 21755 /* 21756 * Sanity check the buffer length of the event against 21757 * what we currently have. 21758 * 21759 * Since buf_len is 32 bits, we check if it overflows 21760 * a large 32 bit value. It's not 0x7fffffff because 21761 * we increase n by (buf_len + sizeof(hdr)), which would 21762 * in itself cause n to overflow. 21763 * 21764 * If "int" is 64 bits then this becomes a moot point. 21765 */ 21766 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 21767 WMI_LOGD("%s: buf_len is garbage 0x%x", 21768 __func__, ev->hdr.buf_len); 21769 return QDF_STATUS_E_FAILURE; 21770 } 21771 21772 if ((n + ev->hdr.buf_len) > datalen) { 21773 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 21774 __func__, n, ev->hdr.buf_len, datalen); 21775 return QDF_STATUS_E_FAILURE; 21776 } 21777 21778 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 21779 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 21780 phyerr->bufp = &ev->bufp[0]; 21781 phyerr->buf_len = ev->hdr.buf_len; 21782 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 21783 21784 /* 21785 * Advance the buffer pointer to the next PHY error. 21786 * buflen is the length of this payload, so we need to 21787 * advance past the current header _AND_ the payload. 21788 */ 21789 n += sizeof(*ev) + ev->hdr.buf_len; 21790 } 21791 *buf_offset = n; 21792 21793 return QDF_STATUS_SUCCESS; 21794 } 21795 21796 struct wmi_ops tlv_ops = { 21797 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21798 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21799 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21800 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21801 .send_hidden_ssid_vdev_restart_cmd = 21802 send_hidden_ssid_vdev_restart_cmd_tlv, 21803 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21804 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21805 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21806 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21807 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21808 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21809 .send_peer_rx_reorder_queue_setup_cmd = 21810 send_peer_rx_reorder_queue_setup_cmd_tlv, 21811 .send_peer_rx_reorder_queue_remove_cmd = 21812 send_peer_rx_reorder_queue_remove_cmd_tlv, 21813 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 21814 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 21815 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 21816 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21817 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21818 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 21819 .send_suspend_cmd = send_suspend_cmd_tlv, 21820 .send_resume_cmd = send_resume_cmd_tlv, 21821 #ifdef FEATURE_WLAN_D0WOW 21822 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 21823 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 21824 #endif 21825 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21826 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21827 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21828 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21829 #ifdef FEATURE_FW_LOG_PARSING 21830 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21831 #endif 21832 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21833 .send_stats_request_cmd = send_stats_request_cmd_tlv, 21834 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21835 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21836 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21837 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 21838 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21839 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21840 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21841 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21842 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21843 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21844 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21845 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21846 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21847 .send_set_sta_uapsd_auto_trig_cmd = 21848 send_set_sta_uapsd_auto_trig_cmd_tlv, 21849 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21850 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 21851 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 21852 #ifdef CONVERGED_P2P_ENABLE 21853 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 21854 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 21855 #endif 21856 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21857 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21858 #ifdef WLAN_FEATURE_DSRC 21859 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 21860 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 21861 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 21862 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 21863 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 21864 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 21865 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 21866 .send_ocb_start_timing_advert_cmd = 21867 send_ocb_start_timing_advert_cmd_tlv, 21868 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 21869 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 21870 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 21871 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 21872 #endif 21873 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 21874 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 21875 .send_set_mcc_channel_time_latency_cmd = 21876 send_set_mcc_channel_time_latency_cmd_tlv, 21877 .send_set_mcc_channel_time_quota_cmd = 21878 send_set_mcc_channel_time_quota_cmd_tlv, 21879 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21880 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21881 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21882 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 21883 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 21884 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 21885 .send_probe_rsp_tmpl_send_cmd = 21886 send_probe_rsp_tmpl_send_cmd_tlv, 21887 .send_p2p_go_set_beacon_ie_cmd = 21888 send_p2p_go_set_beacon_ie_cmd_tlv, 21889 .send_setup_install_key_cmd = 21890 send_setup_install_key_cmd_tlv, 21891 .send_set_gateway_params_cmd = 21892 send_set_gateway_params_cmd_tlv, 21893 .send_set_rssi_monitoring_cmd = 21894 send_set_rssi_monitoring_cmd_tlv, 21895 .send_scan_probe_setoui_cmd = 21896 send_scan_probe_setoui_cmd_tlv, 21897 .send_roam_scan_offload_rssi_thresh_cmd = 21898 send_roam_scan_offload_rssi_thresh_cmd_tlv, 21899 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 21900 .send_roam_scan_filter_cmd = 21901 send_roam_scan_filter_cmd_tlv, 21902 #ifdef IPA_OFFLOAD 21903 .send_ipa_offload_control_cmd = 21904 send_ipa_offload_control_cmd_tlv, 21905 #endif 21906 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 21907 .send_plm_start_cmd = send_plm_start_cmd_tlv, 21908 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21909 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21910 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21911 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 21912 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21913 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21914 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21915 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21916 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21917 .send_congestion_cmd = send_congestion_cmd_tlv, 21918 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21919 .send_snr_cmd = send_snr_cmd_tlv, 21920 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21921 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 21922 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 21923 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 21924 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 21925 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 21926 .send_multiple_add_clear_mcbc_filter_cmd = 21927 send_multiple_add_clear_mcbc_filter_cmd_tlv, 21928 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 21929 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 21930 .send_process_gtk_offload_getinfo_cmd = 21931 send_process_gtk_offload_getinfo_cmd_tlv, 21932 .send_enable_enhance_multicast_offload_cmd = 21933 send_enable_enhance_multicast_offload_tlv, 21934 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 21935 #ifdef FEATURE_WLAN_RA_FILTERING 21936 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 21937 #endif 21938 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 21939 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 21940 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 21941 .send_lphb_config_tcp_pkt_filter_cmd = 21942 send_lphb_config_tcp_pkt_filter_cmd_tlv, 21943 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 21944 .send_lphb_config_udp_pkt_filter_cmd = 21945 send_lphb_config_udp_pkt_filter_cmd_tlv, 21946 .send_enable_disable_packet_filter_cmd = 21947 send_enable_disable_packet_filter_cmd_tlv, 21948 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 21949 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 21950 #ifdef CONFIG_MCL 21951 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 21952 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 21953 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 21954 .send_roam_scan_offload_mode_cmd = 21955 send_roam_scan_offload_mode_cmd_tlv, 21956 #ifndef REMOVE_PKT_LOG 21957 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21958 #endif 21959 .send_roam_scan_offload_ap_profile_cmd = 21960 send_roam_scan_offload_ap_profile_cmd_tlv, 21961 #endif 21962 #ifdef WLAN_SUPPORT_GREEN_AP 21963 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21964 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21965 .extract_green_ap_egap_status_info = 21966 extract_green_ap_egap_status_info_tlv, 21967 #endif 21968 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 21969 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21970 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 21971 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 21972 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21973 #ifdef WLAN_FEATURE_CIF_CFR 21974 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21975 #endif 21976 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 21977 .send_dfs_phyerr_filter_offload_en_cmd = 21978 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21979 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 21980 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 21981 .send_del_ts_cmd = send_del_ts_cmd_tlv, 21982 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 21983 .send_add_ts_cmd = send_add_ts_cmd_tlv, 21984 .send_process_add_periodic_tx_ptrn_cmd = 21985 send_process_add_periodic_tx_ptrn_cmd_tlv, 21986 .send_process_del_periodic_tx_ptrn_cmd = 21987 send_process_del_periodic_tx_ptrn_cmd_tlv, 21988 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21989 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 21990 .send_set_app_type2_params_in_fw_cmd = 21991 send_set_app_type2_params_in_fw_cmd_tlv, 21992 .send_set_auto_shutdown_timer_cmd = 21993 send_set_auto_shutdown_timer_cmd_tlv, 21994 .send_nan_req_cmd = send_nan_req_cmd_tlv, 21995 .send_process_dhcpserver_offload_cmd = 21996 send_process_dhcpserver_offload_cmd_tlv, 21997 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 21998 .send_process_ch_avoid_update_cmd = 21999 send_process_ch_avoid_update_cmd_tlv, 22000 .send_pdev_set_regdomain_cmd = 22001 send_pdev_set_regdomain_cmd_tlv, 22002 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22003 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22004 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22005 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22006 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22007 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22008 .check_and_update_fw_version = 22009 check_and_update_fw_version_cmd_tlv, 22010 .send_set_base_macaddr_indicate_cmd = 22011 send_set_base_macaddr_indicate_cmd_tlv, 22012 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22013 .send_enable_specific_fw_logs_cmd = 22014 send_enable_specific_fw_logs_cmd_tlv, 22015 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22016 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22017 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22018 #ifdef WLAN_POLICY_MGR_ENABLE 22019 .send_pdev_set_dual_mac_config_cmd = 22020 send_pdev_set_dual_mac_config_cmd_tlv, 22021 #endif 22022 .send_app_type1_params_in_fw_cmd = 22023 send_app_type1_params_in_fw_cmd_tlv, 22024 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22025 .send_process_roam_synch_complete_cmd = 22026 send_process_roam_synch_complete_cmd_tlv, 22027 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22028 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22029 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22030 .send_roam_scan_offload_scan_period_cmd = 22031 send_roam_scan_offload_scan_period_cmd_tlv, 22032 .send_roam_scan_offload_chan_list_cmd = 22033 send_roam_scan_offload_chan_list_cmd_tlv, 22034 .send_roam_scan_offload_rssi_change_cmd = 22035 send_roam_scan_offload_rssi_change_cmd_tlv, 22036 #ifdef FEATURE_WLAN_APF 22037 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 22038 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 22039 .send_apf_write_work_memory_cmd = 22040 wmi_send_apf_write_work_memory_cmd_tlv, 22041 .send_apf_read_work_memory_cmd = 22042 wmi_send_apf_read_work_memory_cmd_tlv, 22043 .extract_apf_read_memory_resp_event = 22044 wmi_extract_apf_read_memory_resp_event_tlv, 22045 #endif /* FEATURE_WLAN_APF */ 22046 .send_adapt_dwelltime_params_cmd = 22047 send_adapt_dwelltime_params_cmd_tlv, 22048 .send_dbs_scan_sel_params_cmd = 22049 send_dbs_scan_sel_params_cmd_tlv, 22050 .init_cmd_send = init_cmd_send_tlv, 22051 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22052 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22053 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22054 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22055 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22056 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22057 .send_vdev_set_custom_aggr_size_cmd = 22058 send_vdev_set_custom_aggr_size_cmd_tlv, 22059 .send_vdev_set_qdepth_thresh_cmd = 22060 send_vdev_set_qdepth_thresh_cmd_tlv, 22061 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22062 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22063 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22064 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22065 .send_smart_ant_set_training_info_cmd = 22066 send_smart_ant_set_training_info_cmd_tlv, 22067 .send_smart_ant_set_node_config_cmd = 22068 send_smart_ant_set_node_config_cmd_tlv, 22069 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22070 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22071 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22072 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22073 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22074 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22075 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22076 .send_periodic_chan_stats_config_cmd = 22077 send_periodic_chan_stats_config_cmd_tlv, 22078 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22079 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22080 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22081 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22082 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22083 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22084 .send_vdev_spectral_configure_cmd = 22085 send_vdev_spectral_configure_cmd_tlv, 22086 .send_vdev_spectral_enable_cmd = 22087 send_vdev_spectral_enable_cmd_tlv, 22088 .send_thermal_mitigation_param_cmd = 22089 send_thermal_mitigation_param_cmd_tlv, 22090 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22091 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22092 .send_process_update_edca_param_cmd = 22093 send_process_update_edca_param_cmd_tlv, 22094 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22095 .send_set_country_cmd = send_set_country_cmd_tlv, 22096 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22097 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22098 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22099 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22100 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22101 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22102 .extract_host_mem_req = extract_host_mem_req_tlv, 22103 .save_service_bitmap = save_service_bitmap_tlv, 22104 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22105 .is_service_enabled = is_service_enabled_tlv, 22106 .save_fw_version = save_fw_version_in_service_ready_tlv, 22107 .ready_extract_init_status = ready_extract_init_status_tlv, 22108 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22109 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22110 .extract_ready_event_params = extract_ready_event_params_tlv, 22111 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22112 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22113 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22114 .extract_tbttoffset_update_params = 22115 extract_tbttoffset_update_params_tlv, 22116 .extract_ext_tbttoffset_update_params = 22117 extract_ext_tbttoffset_update_params_tlv, 22118 .extract_tbttoffset_num_vdevs = 22119 extract_tbttoffset_num_vdevs_tlv, 22120 .extract_ext_tbttoffset_num_vdevs = 22121 extract_ext_tbttoffset_num_vdevs_tlv, 22122 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22123 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22124 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22125 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22126 #ifdef CONVERGED_TDLS_ENABLE 22127 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22128 #endif 22129 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22130 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22131 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22132 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22133 #ifdef CONVERGED_P2P_ENABLE 22134 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22135 .extract_p2p_lo_stop_ev_param = 22136 extract_p2p_lo_stop_ev_param_tlv, 22137 #endif 22138 .extract_offchan_data_tx_compl_param = 22139 extract_offchan_data_tx_compl_param_tlv, 22140 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22141 .extract_all_stats_count = extract_all_stats_counts_tlv, 22142 .extract_pdev_stats = extract_pdev_stats_tlv, 22143 .extract_unit_test = extract_unit_test_tlv, 22144 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22145 .extract_vdev_stats = extract_vdev_stats_tlv, 22146 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22147 .extract_peer_stats = extract_peer_stats_tlv, 22148 .extract_bcn_stats = extract_bcn_stats_tlv, 22149 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22150 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22151 .extract_chan_stats = extract_chan_stats_tlv, 22152 .extract_profile_ctx = extract_profile_ctx_tlv, 22153 .extract_profile_data = extract_profile_data_tlv, 22154 .extract_chan_info_event = extract_chan_info_event_tlv, 22155 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22156 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22157 #ifdef WLAN_FEATURE_DISA 22158 .send_encrypt_decrypt_send_cmd = 22159 send_encrypt_decrypt_send_cmd_tlv, 22160 .extract_encrypt_decrypt_resp_event = 22161 extract_encrypt_decrypt_resp_event_tlv, 22162 #endif 22163 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22164 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22165 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22166 .extract_sar2_result_event = extract_sar2_result_event_tlv, 22167 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22168 .send_multiple_vdev_restart_req_cmd = 22169 send_multiple_vdev_restart_req_cmd_tlv, 22170 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22171 .extract_hw_mode_cap_service_ready_ext = 22172 extract_hw_mode_cap_service_ready_ext_tlv, 22173 .extract_mac_phy_cap_service_ready_ext = 22174 extract_mac_phy_cap_service_ready_ext_tlv, 22175 .extract_reg_cap_service_ready_ext = 22176 extract_reg_cap_service_ready_ext_tlv, 22177 .extract_dbr_ring_cap_service_ready_ext = 22178 extract_dbr_ring_cap_service_ready_ext_tlv, 22179 .extract_sar_cap_service_ready_ext = 22180 extract_sar_cap_service_ready_ext_tlv, 22181 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22182 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22183 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22184 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22185 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22186 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22187 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22188 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22189 .extract_fips_event_data = extract_fips_event_data_tlv, 22190 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22191 .extract_peer_delete_response_event = 22192 extract_peer_delete_response_event_tlv, 22193 .is_management_record = is_management_record_tlv, 22194 .extract_pdev_csa_switch_count_status = 22195 extract_pdev_csa_switch_count_status_tlv, 22196 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22197 .extract_pdev_tpc_config_ev_param = 22198 extract_pdev_tpc_config_ev_param_tlv, 22199 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22200 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22201 .extract_peer_sta_ps_statechange_ev = 22202 extract_peer_sta_ps_statechange_ev_tlv, 22203 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22204 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22205 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22206 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22207 .extract_reg_chan_list_update_event = 22208 extract_reg_chan_list_update_event_tlv, 22209 .extract_chainmask_tables = 22210 extract_chainmask_tables_tlv, 22211 .extract_thermal_stats = extract_thermal_stats_tlv, 22212 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22213 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22214 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22215 #ifdef DFS_COMPONENT_ENABLE 22216 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22217 .extract_dfs_radar_detection_event = 22218 extract_dfs_radar_detection_event_tlv, 22219 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22220 #endif 22221 .convert_pdev_id_host_to_target = 22222 convert_host_pdev_id_to_target_pdev_id_legacy, 22223 .convert_pdev_id_target_to_host = 22224 convert_target_pdev_id_to_host_pdev_id_legacy, 22225 22226 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22227 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22228 .extract_reg_11d_new_country_event = 22229 extract_reg_11d_new_country_event_tlv, 22230 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22231 .send_limit_off_chan_cmd = 22232 send_limit_off_chan_cmd_tlv, 22233 .extract_reg_ch_avoid_event = 22234 extract_reg_ch_avoid_event_tlv, 22235 .send_pdev_caldata_version_check_cmd = 22236 send_pdev_caldata_version_check_cmd_tlv, 22237 .extract_pdev_caldata_version_check_ev_param = 22238 extract_pdev_caldata_version_check_ev_param_tlv, 22239 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22240 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22241 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22242 #if defined(WLAN_FEATURE_FILS_SK) 22243 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22244 #endif 22245 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22246 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22247 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22248 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22249 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22250 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22251 .extract_ndp_ind = extract_ndp_ind_tlv, 22252 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22253 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22254 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22255 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22256 .extract_ndp_sch_update = extract_ndp_sch_update_tlv, 22257 #endif 22258 .send_btm_config = send_btm_config_cmd_tlv, 22259 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22260 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22261 #ifdef WLAN_SUPPORT_FILS 22262 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22263 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22264 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22265 #endif /* WLAN_SUPPORT_FILS */ 22266 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22267 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22268 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22269 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22270 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22271 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22272 .send_bss_color_change_enable_cmd = 22273 send_bss_color_change_enable_cmd_tlv, 22274 .send_obss_color_collision_cfg_cmd = 22275 send_obss_color_collision_cfg_cmd_tlv, 22276 .extract_obss_color_collision_info = 22277 extract_obss_color_collision_info_tlv, 22278 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22279 .extract_single_phyerr = extract_single_phyerr_tlv, 22280 #ifdef QCA_SUPPORT_CP_STATS 22281 .extract_cca_stats = extract_cca_stats_tlv, 22282 #endif 22283 }; 22284 22285 /** 22286 * populate_tlv_event_id() - populates wmi event ids 22287 * 22288 * @param event_ids: Pointer to hold event ids 22289 * Return: None 22290 */ 22291 static void populate_tlv_events_id(uint32_t *event_ids) 22292 { 22293 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22294 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22295 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22296 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22297 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22298 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22299 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22300 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22301 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22302 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22303 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22304 event_ids[wmi_service_ready_ext_event_id] = 22305 WMI_SERVICE_READY_EXT_EVENTID; 22306 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22307 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22308 event_ids[wmi_vdev_install_key_complete_event_id] = 22309 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22310 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22311 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22312 22313 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22314 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22315 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22316 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22317 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22318 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22319 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22320 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22321 event_ids[wmi_peer_delete_response_event_id] = 22322 WMI_PEER_DELETE_RESP_EVENTID; 22323 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22324 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22325 event_ids[wmi_tbttoffset_update_event_id] = 22326 WMI_TBTTOFFSET_UPDATE_EVENTID; 22327 event_ids[wmi_ext_tbttoffset_update_event_id] = 22328 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22329 event_ids[wmi_offload_bcn_tx_status_event_id] = 22330 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22331 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22332 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22333 event_ids[wmi_mgmt_tx_completion_event_id] = 22334 WMI_MGMT_TX_COMPLETION_EVENTID; 22335 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22336 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22337 event_ids[wmi_tx_delba_complete_event_id] = 22338 WMI_TX_DELBA_COMPLETE_EVENTID; 22339 event_ids[wmi_tx_addba_complete_event_id] = 22340 WMI_TX_ADDBA_COMPLETE_EVENTID; 22341 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22342 22343 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22344 22345 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22346 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22347 22348 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22349 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22350 22351 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22352 22353 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22354 event_ids[wmi_p2p_lo_stop_event_id] = 22355 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22356 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22357 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22358 event_ids[wmi_d0_wow_disable_ack_event_id] = 22359 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22360 event_ids[wmi_wow_initial_wakeup_event_id] = 22361 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22362 22363 event_ids[wmi_rtt_meas_report_event_id] = 22364 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22365 event_ids[wmi_tsf_meas_report_event_id] = 22366 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22367 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22368 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22369 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22370 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22371 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22372 event_ids[wmi_diag_event_id_log_supported_event_id] = 22373 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22374 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22375 event_ids[wmi_nlo_scan_complete_event_id] = 22376 WMI_NLO_SCAN_COMPLETE_EVENTID; 22377 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22378 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22379 22380 event_ids[wmi_gtk_offload_status_event_id] = 22381 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22382 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22383 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22384 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22385 22386 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22387 22388 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22389 22390 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22391 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22392 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22393 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22394 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22395 event_ids[wmi_wlan_profile_data_event_id] = 22396 WMI_WLAN_PROFILE_DATA_EVENTID; 22397 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22398 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22399 event_ids[wmi_vdev_get_keepalive_event_id] = 22400 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22401 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22402 22403 event_ids[wmi_diag_container_event_id] = 22404 WMI_DIAG_DATA_CONTAINER_EVENTID; 22405 22406 event_ids[wmi_host_auto_shutdown_event_id] = 22407 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22408 22409 event_ids[wmi_update_whal_mib_stats_event_id] = 22410 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22411 22412 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22413 event_ids[wmi_update_vdev_rate_stats_event_id] = 22414 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22415 22416 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22417 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22418 22419 /** Set OCB Sched Response, deprecated */ 22420 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22421 22422 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22423 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22424 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22425 22426 /* GPIO Event */ 22427 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22428 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22429 22430 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22431 event_ids[wmi_rfkill_state_change_event_id] = 22432 WMI_RFKILL_STATE_CHANGE_EVENTID; 22433 22434 /* TDLS Event */ 22435 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22436 22437 event_ids[wmi_batch_scan_enabled_event_id] = 22438 WMI_BATCH_SCAN_ENABLED_EVENTID; 22439 event_ids[wmi_batch_scan_result_event_id] = 22440 WMI_BATCH_SCAN_RESULT_EVENTID; 22441 /* OEM Event */ 22442 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22443 event_ids[wmi_oem_meas_report_event_id] = 22444 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22445 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22446 22447 /* NAN Event */ 22448 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22449 22450 /* LPI Event */ 22451 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22452 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22453 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22454 22455 /* ExtScan events */ 22456 event_ids[wmi_extscan_start_stop_event_id] = 22457 WMI_EXTSCAN_START_STOP_EVENTID; 22458 event_ids[wmi_extscan_operation_event_id] = 22459 WMI_EXTSCAN_OPERATION_EVENTID; 22460 event_ids[wmi_extscan_table_usage_event_id] = 22461 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22462 event_ids[wmi_extscan_cached_results_event_id] = 22463 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22464 event_ids[wmi_extscan_wlan_change_results_event_id] = 22465 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22466 event_ids[wmi_extscan_hotlist_match_event_id] = 22467 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22468 event_ids[wmi_extscan_capabilities_event_id] = 22469 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22470 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22471 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22472 22473 /* mDNS offload events */ 22474 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22475 22476 /* SAP Authentication offload events */ 22477 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22478 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22479 22480 /** Out-of-context-of-bss (OCB) events */ 22481 event_ids[wmi_ocb_set_config_resp_event_id] = 22482 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22483 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22484 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22485 event_ids[wmi_dcc_get_stats_resp_event_id] = 22486 WMI_DCC_GET_STATS_RESP_EVENTID; 22487 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22488 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22489 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22490 /* System-On-Chip events */ 22491 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22492 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22493 event_ids[wmi_soc_hw_mode_transition_event_id] = 22494 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22495 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22496 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22497 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22498 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22499 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22500 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22501 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22502 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22503 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22504 WMI_PEER_STA_PS_STATECHG_EVENTID; 22505 event_ids[wmi_pdev_channel_hopping_event_id] = 22506 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22507 event_ids[wmi_offchan_data_tx_completion_event] = 22508 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22509 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22510 event_ids[wmi_dfs_radar_detection_event_id] = 22511 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22512 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22513 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22514 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22515 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22516 event_ids[wmi_service_available_event_id] = 22517 WMI_SERVICE_AVAILABLE_EVENTID; 22518 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22519 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22520 /* NDP events */ 22521 event_ids[wmi_ndp_initiator_rsp_event_id] = 22522 WMI_NDP_INITIATOR_RSP_EVENTID; 22523 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22524 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22525 event_ids[wmi_ndp_responder_rsp_event_id] = 22526 WMI_NDP_RESPONDER_RSP_EVENTID; 22527 event_ids[wmi_ndp_end_indication_event_id] = 22528 WMI_NDP_END_INDICATION_EVENTID; 22529 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22530 event_ids[wmi_ndl_schedule_update_event_id] = 22531 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22532 22533 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22534 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22535 event_ids[wmi_pdev_chip_power_stats_event_id] = 22536 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22537 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22538 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22539 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22540 event_ids[wmi_apf_capability_info_event_id] = 22541 WMI_BPF_CAPABILIY_INFO_EVENTID; 22542 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22543 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22544 event_ids[wmi_report_rx_aggr_failure_event_id] = 22545 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22546 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22547 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22548 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22549 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22550 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22551 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22552 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22553 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22554 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22555 event_ids[wmi_coex_bt_activity_event_id] = 22556 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22557 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22558 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22559 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22560 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22561 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22562 event_ids[wmi_dma_buf_release_event_id] = 22563 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22564 event_ids[wmi_sap_obss_detection_report_event_id] = 22565 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22566 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22567 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22568 event_ids[wmi_obss_color_collision_report_event_id] = 22569 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22570 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22571 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22572 event_ids[wmi_twt_enable_complete_event_id] = 22573 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22574 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22575 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22576 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22577 } 22578 22579 /** 22580 * populate_tlv_service() - populates wmi services 22581 * 22582 * @param wmi_service: Pointer to hold wmi_service 22583 * Return: None 22584 */ 22585 static void populate_tlv_service(uint32_t *wmi_service) 22586 { 22587 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22588 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22589 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22590 wmi_service[wmi_service_roam_scan_offload] = 22591 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22592 wmi_service[wmi_service_bcn_miss_offload] = 22593 WMI_SERVICE_BCN_MISS_OFFLOAD; 22594 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22595 wmi_service[wmi_service_sta_advanced_pwrsave] = 22596 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22597 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22598 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22599 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22600 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22601 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22602 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22603 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22604 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22605 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22606 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22607 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22608 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22609 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22610 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22611 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22612 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22613 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22614 wmi_service[wmi_service_packet_power_save] = 22615 WMI_SERVICE_PACKET_POWER_SAVE; 22616 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22617 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22618 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22619 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22620 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22621 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22622 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22623 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22624 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22625 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22626 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22627 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22628 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22629 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22630 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22631 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22632 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22633 wmi_service[wmi_service_mcc_bcn_interval_change] = 22634 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22635 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22636 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22637 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22638 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22639 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22640 wmi_service[wmi_service_lte_ant_share_support] = 22641 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22642 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22643 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22644 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22645 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22646 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22647 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22648 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22649 wmi_service[wmi_service_bcn_txrate_override] = 22650 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22651 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22652 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22653 wmi_service[wmi_service_estimate_linkspeed] = 22654 WMI_SERVICE_ESTIMATE_LINKSPEED; 22655 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22656 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22657 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22658 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22659 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22660 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22661 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22662 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22663 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22664 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22665 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22666 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22667 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22668 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22669 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22670 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22671 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22672 wmi_service[wmi_service_sap_auth_offload] = 22673 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22674 wmi_service[wmi_service_dual_band_simultaneous_support] = 22675 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22676 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22677 wmi_service[wmi_service_ap_arpns_offload] = 22678 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22679 wmi_service[wmi_service_per_band_chainmask_support] = 22680 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22681 wmi_service[wmi_service_packet_filter_offload] = 22682 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22683 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22684 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22685 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22686 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22687 wmi_service[wmi_service_multiple_vdev_restart] = 22688 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22689 22690 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22691 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22692 wmi_service[wmi_service_smart_antenna_sw_support] = 22693 WMI_SERVICE_UNAVAILABLE; 22694 wmi_service[wmi_service_smart_antenna_hw_support] = 22695 WMI_SERVICE_UNAVAILABLE; 22696 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22697 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22698 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22699 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22700 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22701 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22702 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22703 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22704 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22705 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22706 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22707 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22708 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22709 wmi_service[wmi_service_periodic_chan_stat_support] = 22710 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22711 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22712 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22713 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22714 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22715 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22716 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22717 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22718 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22719 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22720 wmi_service[wmi_service_unified_wow_capability] = 22721 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22722 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22723 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22724 wmi_service[wmi_service_sync_delete_cmds] = 22725 WMI_SERVICE_SYNC_DELETE_CMDS; 22726 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22727 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22728 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22729 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22730 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22731 wmi_service[wmi_service_deprecated_replace] = 22732 WMI_SERVICE_DEPRECATED_REPLACE; 22733 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22734 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22735 wmi_service[wmi_service_enhanced_mcast_filter] = 22736 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22737 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22738 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22739 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22740 wmi_service[wmi_service_p2p_listen_offload_support] = 22741 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22742 wmi_service[wmi_service_mark_first_wakeup_packet] = 22743 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22744 wmi_service[wmi_service_multiple_mcast_filter_set] = 22745 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22746 wmi_service[wmi_service_host_managed_rx_reorder] = 22747 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22748 wmi_service[wmi_service_flash_rdwr_support] = 22749 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22750 wmi_service[wmi_service_wlan_stats_report] = 22751 WMI_SERVICE_WLAN_STATS_REPORT; 22752 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22753 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22754 wmi_service[wmi_service_dfs_phyerr_offload] = 22755 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22756 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22757 wmi_service[wmi_service_fw_mem_dump_support] = 22758 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22759 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22760 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22761 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22762 wmi_service[wmi_service_hw_data_filtering] = 22763 WMI_SERVICE_HW_DATA_FILTERING; 22764 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22765 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22766 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22767 wmi_service[wmi_service_extended_nss_support] = 22768 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22769 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22770 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22771 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22772 wmi_service[wmi_service_offchan_data_tid_support] = 22773 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22774 wmi_service[wmi_service_support_dma] = 22775 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22776 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22777 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22778 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22779 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22780 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22781 wmi_service[wmi_service_11k_neighbour_report_support] = 22782 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22783 wmi_service[wmi_service_ap_obss_detection_offload] = 22784 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22785 wmi_service[wmi_service_bss_color_offload] = 22786 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22787 wmi_service[wmi_service_gmac_offload_support] = 22788 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22789 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22790 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22791 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22792 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22793 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22794 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22795 wmi_service[wmi_service_listen_interval_offload_support] = 22796 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22797 22798 } 22799 22800 #ifndef CONFIG_MCL 22801 22802 /** 22803 * populate_pdev_param_tlv() - populates pdev params 22804 * 22805 * @param pdev_param: Pointer to hold pdev params 22806 * Return: None 22807 */ 22808 static void populate_pdev_param_tlv(uint32_t *pdev_param) 22809 { 22810 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 22811 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 22812 pdev_param[wmi_pdev_param_txpower_limit2g] = 22813 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 22814 pdev_param[wmi_pdev_param_txpower_limit5g] = 22815 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 22816 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 22817 pdev_param[wmi_pdev_param_beacon_gen_mode] = 22818 WMI_PDEV_PARAM_BEACON_GEN_MODE; 22819 pdev_param[wmi_pdev_param_beacon_tx_mode] = 22820 WMI_PDEV_PARAM_BEACON_TX_MODE; 22821 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 22822 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 22823 pdev_param[wmi_pdev_param_protection_mode] = 22824 WMI_PDEV_PARAM_PROTECTION_MODE; 22825 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 22826 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 22827 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 22828 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 22829 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 22830 pdev_param[wmi_pdev_param_sta_kickout_th] = 22831 WMI_PDEV_PARAM_STA_KICKOUT_TH; 22832 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 22833 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 22834 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 22835 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 22836 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 22837 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 22838 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 22839 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 22840 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 22841 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 22842 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 22843 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 22844 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 22845 pdev_param[wmi_pdev_param_ltr_sleep_override] = 22846 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 22847 pdev_param[wmi_pdev_param_ltr_rx_override] = 22848 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 22849 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 22850 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 22851 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 22852 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 22853 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 22854 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 22855 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 22856 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 22857 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 22858 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 22859 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 22860 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 22861 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 22862 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 22863 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 22864 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 22865 pdev_param[wmi_pdev_param_peer_stats_update_period] = 22866 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 22867 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 22868 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 22869 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 22870 pdev_param[wmi_pdev_param_arp_ac_override] = 22871 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 22872 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 22873 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 22874 pdev_param[wmi_pdev_param_ani_poll_period] = 22875 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 22876 pdev_param[wmi_pdev_param_ani_listen_period] = 22877 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 22878 pdev_param[wmi_pdev_param_ani_ofdm_level] = 22879 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 22880 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 22881 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 22882 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 22883 pdev_param[wmi_pdev_param_idle_ps_config] = 22884 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 22885 pdev_param[wmi_pdev_param_power_gating_sleep] = 22886 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 22887 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 22888 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 22889 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 22890 pdev_param[wmi_pdev_param_hw_rfkill_config] = 22891 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 22892 pdev_param[wmi_pdev_param_low_power_rf_enable] = 22893 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 22894 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 22895 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 22896 pdev_param[wmi_pdev_param_power_collapse_enable] = 22897 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 22898 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 22899 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 22900 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 22901 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 22902 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 22903 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 22904 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 22905 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 22906 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 22907 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 22908 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 22909 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 22910 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 22911 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 22912 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 22913 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 22914 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 22915 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 22916 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 22917 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 22918 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 22919 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 22920 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 22921 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 22922 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 22923 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 22924 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 22925 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 22926 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 22927 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 22928 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 22929 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 22930 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 22931 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 22932 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 22933 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 22934 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 22935 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 22936 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 22937 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 22938 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 22939 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 22940 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 22941 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 22942 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 22943 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 22944 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 22945 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 22946 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 22947 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 22948 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 22949 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 22950 pdev_param[wmi_pdev_param_proxy_sta_mode] = 22951 WMI_PDEV_PARAM_PROXY_STA_MODE; 22952 pdev_param[wmi_pdev_param_mu_group_policy] = 22953 WMI_PDEV_PARAM_MU_GROUP_POLICY; 22954 pdev_param[wmi_pdev_param_noise_detection] = 22955 WMI_PDEV_PARAM_NOISE_DETECTION; 22956 pdev_param[wmi_pdev_param_noise_threshold] = 22957 WMI_PDEV_PARAM_NOISE_THRESHOLD; 22958 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 22959 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 22960 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 22961 pdev_param[wmi_pdev_param_atf_strict_sch] = 22962 WMI_PDEV_PARAM_ATF_STRICT_SCH; 22963 pdev_param[wmi_pdev_param_atf_sched_duration] = 22964 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 22965 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 22966 pdev_param[wmi_pdev_param_sensitivity_level] = 22967 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 22968 pdev_param[wmi_pdev_param_signed_txpower_2g] = 22969 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 22970 pdev_param[wmi_pdev_param_signed_txpower_5g] = 22971 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 22972 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 22973 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 22974 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 22975 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 22976 pdev_param[wmi_pdev_param_cca_threshold] = 22977 WMI_PDEV_PARAM_CCA_THRESHOLD; 22978 pdev_param[wmi_pdev_param_rts_fixed_rate] = 22979 WMI_PDEV_PARAM_RTS_FIXED_RATE; 22980 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 22981 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 22982 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 22983 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 22984 pdev_param[wmi_pdev_param_arp_srcaddr] = 22985 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 22986 pdev_param[wmi_pdev_param_arp_dstaddr] = 22987 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 22988 pdev_param[wmi_pdev_param_txpower_decr_db] = 22989 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 22990 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 22991 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 22992 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 22993 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 22994 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 22995 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 22996 pdev_param[wmi_pdev_param_cust_txpower_scale] = 22997 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 22998 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 22999 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23000 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23001 WMI_UNAVAILABLE_PARAM; 23002 pdev_param[wmi_pdev_param_igmpmld_override] = 23003 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23004 pdev_param[wmi_pdev_param_igmpmld_tid] = 23005 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23006 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23007 pdev_param[wmi_pdev_param_block_interbss] = 23008 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23009 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23010 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23011 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23012 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23013 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23014 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23015 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23016 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23017 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23018 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23019 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23020 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23021 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23022 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23023 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23024 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23025 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23026 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23027 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23028 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23029 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23030 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23031 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23032 pdev_param[wmi_pdev_param_fast_channel_reset] = 23033 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23034 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23035 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23036 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23037 } 23038 23039 /** 23040 * populate_vdev_param_tlv() - populates vdev params 23041 * 23042 * @param vdev_param: Pointer to hold vdev params 23043 * Return: None 23044 */ 23045 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23046 { 23047 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23048 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23049 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23050 vdev_param[wmi_vdev_param_beacon_interval] = 23051 WMI_VDEV_PARAM_BEACON_INTERVAL; 23052 vdev_param[wmi_vdev_param_listen_interval] = 23053 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23054 vdev_param[wmi_vdev_param_multicast_rate] = 23055 WMI_VDEV_PARAM_MULTICAST_RATE; 23056 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23057 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23058 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23059 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23060 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23061 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23062 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23063 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23064 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23065 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23066 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23067 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23068 vdev_param[wmi_vdev_param_bmiss_count_max] = 23069 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23070 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23071 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23072 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23073 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23074 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23075 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23076 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23077 vdev_param[wmi_vdev_param_disable_htprotection] = 23078 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23079 vdev_param[wmi_vdev_param_sta_quickkickout] = 23080 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23081 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23082 vdev_param[wmi_vdev_param_protection_mode] = 23083 WMI_VDEV_PARAM_PROTECTION_MODE; 23084 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23085 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23086 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23087 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23088 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23089 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23090 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23091 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23092 vdev_param[wmi_vdev_param_bcast_data_rate] = 23093 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23094 vdev_param[wmi_vdev_param_mcast_data_rate] = 23095 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23096 vdev_param[wmi_vdev_param_mcast_indicate] = 23097 WMI_VDEV_PARAM_MCAST_INDICATE; 23098 vdev_param[wmi_vdev_param_dhcp_indicate] = 23099 WMI_VDEV_PARAM_DHCP_INDICATE; 23100 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23101 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23102 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23103 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23104 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23105 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23106 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23107 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23108 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23109 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23110 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23111 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23112 vdev_param[wmi_vdev_param_packet_powersave] = 23113 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23114 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23115 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23116 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23117 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23118 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23119 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23120 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23121 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23122 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23123 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23124 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23125 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23126 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23127 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23128 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23129 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23130 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23131 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23132 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23133 vdev_param[wmi_vdev_param_roam_fw_offload] = 23134 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23135 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23136 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23137 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23138 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23139 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23140 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23141 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23142 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23143 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23144 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23145 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23146 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23147 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23148 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23149 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23150 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23151 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23152 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23153 vdev_param[wmi_vdev_param_inactivity_cnt] = 23154 WMI_VDEV_PARAM_INACTIVITY_CNT; 23155 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23156 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23157 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23158 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23159 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23160 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23161 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23162 vdev_param[wmi_vdev_param_rx_leak_window] = 23163 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23164 vdev_param[wmi_vdev_param_stats_avg_factor] = 23165 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23166 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23167 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23168 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23169 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23170 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23171 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23172 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23173 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23174 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23175 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23176 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23177 WMI_VDEV_PARAM_HE_RANGE_EXT; 23178 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23179 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23180 vdev_param[wmi_vdev_param_set_he_sounding_mode] 23181 = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 23182 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23183 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23184 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23185 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23186 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23187 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23188 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23189 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23190 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23191 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23192 vdev_param[wmi_vdev_param_rc_num_retries] = 23193 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23194 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23195 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23196 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23197 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23198 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23199 vdev_param[wmi_vdev_param_vht80_ratemask] = 23200 WMI_VDEV_PARAM_VHT80_RATEMASK; 23201 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23202 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23203 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23204 vdev_param[wmi_vdev_param_set_he_ltf] = 23205 WMI_VDEV_PARAM_HE_LTF; 23206 vdev_param[wmi_vdev_param_disable_cabq] = 23207 WMI_VDEV_PARAM_DISABLE_CABQ; 23208 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23209 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23210 vdev_param[wmi_vdev_param_set_ba_mode] = 23211 WMI_VDEV_PARAM_BA_MODE; 23212 vdev_param[wmi_vdev_param_capabilities] = 23213 WMI_VDEV_PARAM_CAPABILITIES; 23214 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 23215 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 23216 } 23217 #endif 23218 23219 /** 23220 * populate_target_defines_tlv() - Populate target defines and params 23221 * @wmi_handle: pointer to wmi handle 23222 * 23223 * Return: None 23224 */ 23225 #ifndef CONFIG_MCL 23226 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23227 { 23228 populate_pdev_param_tlv(wmi_handle->pdev_param); 23229 populate_vdev_param_tlv(wmi_handle->vdev_param); 23230 } 23231 #else 23232 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23233 { } 23234 #endif 23235 23236 /** 23237 * wmi_ocb_ut_attach() - Attach OCB test framework 23238 * @wmi_handle: wmi handle 23239 * 23240 * Return: None 23241 */ 23242 #ifdef WLAN_OCB_UT 23243 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23244 #else 23245 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23246 { 23247 return; 23248 } 23249 #endif 23250 23251 /** 23252 * wmi_tlv_attach() - Attach TLV APIs 23253 * 23254 * Return: None 23255 */ 23256 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23257 { 23258 wmi_handle->ops = &tlv_ops; 23259 wmi_ocb_ut_attach(wmi_handle); 23260 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23261 #ifdef WMI_INTERFACE_EVENT_LOGGING 23262 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23263 wmi_handle->log_info.buf_offset_command = 8; 23264 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23265 wmi_handle->log_info.buf_offset_event = 4; 23266 #endif 23267 populate_tlv_events_id(wmi_handle->wmi_events); 23268 populate_tlv_service(wmi_handle->services); 23269 populate_target_defines_tlv(wmi_handle); 23270 wmi_twt_attach_tlv(wmi_handle); 23271 wmi_extscan_attach_tlv(wmi_handle); 23272 } 23273 qdf_export_symbol(wmi_tlv_attach); 23274 23275 /** 23276 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23277 * 23278 * Return: None 23279 */ 23280 void wmi_tlv_init(void) 23281 { 23282 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23283 } 23284