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 WLAN_FEATURE_ACTION_OUI 31 #include "wmi_unified_action_oui_tlv.h" 32 #endif 33 #ifdef CONVERGED_P2P_ENABLE 34 #include "wlan_p2p_public_struct.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 45 #include "nan_public_structs.h" 46 #endif 47 #include "wmi_unified_twt_api.h" 48 49 #ifdef WLAN_POLICY_MGR_ENABLE 50 #include "wlan_policy_mgr_public_struct.h" 51 #endif 52 53 /* HTC service ids for WMI for multi-radio */ 54 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 55 WMI_CONTROL_SVC_WMAC1, 56 WMI_CONTROL_SVC_WMAC2}; 57 58 /** 59 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 60 * host to target defines. 61 * @param pdev_id: host pdev_id to be converted. 62 * Return: target pdev_id after conversion. 63 */ 64 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 65 { 66 switch (pdev_id) { 67 case WMI_HOST_PDEV_ID_SOC: 68 return WMI_PDEV_ID_SOC; 69 case WMI_HOST_PDEV_ID_0: 70 return WMI_PDEV_ID_1ST; 71 case WMI_HOST_PDEV_ID_1: 72 return WMI_PDEV_ID_2ND; 73 case WMI_HOST_PDEV_ID_2: 74 return WMI_PDEV_ID_3RD; 75 } 76 77 QDF_ASSERT(0); 78 79 return WMI_PDEV_ID_SOC; 80 } 81 82 /** 83 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 84 * target to host defines. 85 * @param pdev_id: target pdev_id to be converted. 86 * Return: host pdev_id after conversion. 87 */ 88 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 89 { 90 switch (pdev_id) { 91 case WMI_PDEV_ID_SOC: 92 return WMI_HOST_PDEV_ID_SOC; 93 case WMI_PDEV_ID_1ST: 94 return WMI_HOST_PDEV_ID_0; 95 case WMI_PDEV_ID_2ND: 96 return WMI_HOST_PDEV_ID_1; 97 case WMI_PDEV_ID_3RD: 98 return WMI_HOST_PDEV_ID_2; 99 } 100 101 QDF_ASSERT(0); 102 103 return WMI_HOST_PDEV_ID_SOC; 104 } 105 106 /** 107 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 108 * 109 * Return None. 110 */ 111 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 112 { 113 wmi_handle->ops->convert_pdev_id_host_to_target = 114 convert_host_pdev_id_to_target_pdev_id; 115 wmi_handle->ops->convert_pdev_id_target_to_host = 116 convert_target_pdev_id_to_host_pdev_id; 117 } 118 119 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 120 * buffer. 121 * @wmi_handle: pointer to wmi_handle 122 * @cmd: pointer target vdev create command buffer 123 * @param: pointer host params for vdev create 124 * 125 * Return: None 126 */ 127 #ifdef CONFIG_MCL 128 static inline void copy_vdev_create_pdev_id( 129 struct wmi_unified *wmi_handle, 130 wmi_vdev_create_cmd_fixed_param * cmd, 131 struct vdev_create_params *param) 132 { 133 cmd->pdev_id = WMI_PDEV_ID_SOC; 134 } 135 #else 136 static inline void copy_vdev_create_pdev_id( 137 struct wmi_unified *wmi_handle, 138 wmi_vdev_create_cmd_fixed_param * cmd, 139 struct vdev_create_params *param) 140 { 141 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 142 param->pdev_id); 143 } 144 #endif 145 146 /** 147 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 148 * @wmi_handle: wmi handle 149 * @param: pointer to hold vdev create parameter 150 * @macaddr: vdev mac address 151 * 152 * Return: QDF_STATUS_SUCCESS for success or error code 153 */ 154 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 155 uint8_t macaddr[IEEE80211_ADDR_LEN], 156 struct vdev_create_params *param) 157 { 158 wmi_vdev_create_cmd_fixed_param *cmd; 159 wmi_buf_t buf; 160 int32_t len = sizeof(*cmd); 161 QDF_STATUS ret; 162 int num_bands = 2; 163 uint8_t *buf_ptr; 164 wmi_vdev_txrx_streams *txrx_streams; 165 166 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 167 buf = wmi_buf_alloc(wmi_handle, len); 168 if (!buf) { 169 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 170 return QDF_STATUS_E_NOMEM; 171 } 172 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 173 WMITLV_SET_HDR(&cmd->tlv_header, 174 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 175 WMITLV_GET_STRUCT_TLVLEN 176 (wmi_vdev_create_cmd_fixed_param)); 177 cmd->vdev_id = param->if_id; 178 cmd->vdev_type = param->type; 179 cmd->vdev_subtype = param->subtype; 180 cmd->num_cfg_txrx_streams = num_bands; 181 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 182 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 183 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 184 __func__, param->if_id, cmd->pdev_id, 185 macaddr[0], macaddr[1], macaddr[2], 186 macaddr[3], macaddr[4], macaddr[5]); 187 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 189 (num_bands * sizeof(wmi_vdev_txrx_streams))); 190 buf_ptr += WMI_TLV_HDR_SIZE; 191 192 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 193 param->type, param->subtype, 194 param->nss_2g, param->nss_5g); 195 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 196 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 197 txrx_streams->supported_tx_streams = param->nss_2g; 198 txrx_streams->supported_rx_streams = param->nss_2g; 199 WMITLV_SET_HDR(&txrx_streams->tlv_header, 200 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 201 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 202 203 txrx_streams++; 204 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 205 txrx_streams->supported_tx_streams = param->nss_5g; 206 txrx_streams->supported_rx_streams = param->nss_5g; 207 WMITLV_SET_HDR(&txrx_streams->tlv_header, 208 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 209 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 210 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 211 if (QDF_IS_STATUS_ERROR(ret)) { 212 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 213 wmi_buf_free(buf); 214 } 215 216 return ret; 217 } 218 219 /** 220 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 221 * @wmi_handle: wmi handle 222 * @if_id: vdev id 223 * 224 * Return: QDF_STATUS_SUCCESS for success or error code 225 */ 226 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 227 uint8_t if_id) 228 { 229 wmi_vdev_delete_cmd_fixed_param *cmd; 230 wmi_buf_t buf; 231 QDF_STATUS ret; 232 233 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 234 if (!buf) { 235 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 236 return QDF_STATUS_E_NOMEM; 237 } 238 239 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 240 WMITLV_SET_HDR(&cmd->tlv_header, 241 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 242 WMITLV_GET_STRUCT_TLVLEN 243 (wmi_vdev_delete_cmd_fixed_param)); 244 cmd->vdev_id = if_id; 245 ret = wmi_unified_cmd_send(wmi_handle, buf, 246 sizeof(wmi_vdev_delete_cmd_fixed_param), 247 WMI_VDEV_DELETE_CMDID); 248 if (QDF_IS_STATUS_ERROR(ret)) { 249 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 250 wmi_buf_free(buf); 251 } 252 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 253 254 return ret; 255 } 256 257 /** 258 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 259 * @wmi: wmi handle 260 * @vdev_id: vdev id 261 * 262 * Return: QDF_STATUS_SUCCESS for success or erro code 263 */ 264 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 265 uint8_t vdev_id) 266 { 267 wmi_vdev_stop_cmd_fixed_param *cmd; 268 wmi_buf_t buf; 269 int32_t len = sizeof(*cmd); 270 271 buf = wmi_buf_alloc(wmi, len); 272 if (!buf) { 273 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 274 return QDF_STATUS_E_NOMEM; 275 } 276 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 277 WMITLV_SET_HDR(&cmd->tlv_header, 278 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 279 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 280 cmd->vdev_id = vdev_id; 281 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 282 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 283 wmi_buf_free(buf); 284 return QDF_STATUS_E_FAILURE; 285 } 286 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 287 288 return 0; 289 } 290 291 /** 292 * send_vdev_down_cmd_tlv() - send vdev down command to fw 293 * @wmi: wmi handle 294 * @vdev_id: vdev id 295 * 296 * Return: QDF_STATUS_SUCCESS for success or error code 297 */ 298 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 299 { 300 wmi_vdev_down_cmd_fixed_param *cmd; 301 wmi_buf_t buf; 302 int32_t len = sizeof(*cmd); 303 304 buf = wmi_buf_alloc(wmi, len); 305 if (!buf) { 306 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 307 return QDF_STATUS_E_NOMEM; 308 } 309 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 310 WMITLV_SET_HDR(&cmd->tlv_header, 311 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 312 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 313 cmd->vdev_id = vdev_id; 314 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 315 WMI_LOGP("%s: Failed to send vdev down", __func__); 316 wmi_buf_free(buf); 317 return QDF_STATUS_E_FAILURE; 318 } 319 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 320 321 return 0; 322 } 323 324 #ifdef CONFIG_MCL 325 static inline void copy_channel_info( 326 wmi_vdev_start_request_cmd_fixed_param * cmd, 327 wmi_channel *chan, 328 struct vdev_start_params *req) 329 { 330 chan->mhz = req->chan_freq; 331 332 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 333 334 chan->band_center_freq1 = req->band_center_freq1; 335 chan->band_center_freq2 = req->band_center_freq2; 336 337 if (req->is_half_rate) 338 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 339 else if (req->is_quarter_rate) 340 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 341 342 if (req->is_dfs && req->flag_dfs) { 343 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 344 cmd->disable_hw_ack = req->dis_hw_ack; 345 } 346 347 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 348 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 349 350 } 351 #else 352 static inline void copy_channel_info( 353 wmi_vdev_start_request_cmd_fixed_param * cmd, 354 wmi_channel *chan, 355 struct vdev_start_params *req) 356 { 357 chan->mhz = req->channel.mhz; 358 359 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 360 361 chan->band_center_freq1 = req->channel.cfreq1; 362 chan->band_center_freq2 = req->channel.cfreq2; 363 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 364 365 if (req->channel.half_rate) 366 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 367 else if (req->channel.quarter_rate) 368 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 369 370 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 371 372 if (req->channel.dfs_set) { 373 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 374 cmd->disable_hw_ack = req->disable_hw_ack; 375 } 376 377 if (req->channel.dfs_set_cfreq2) 378 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 379 380 /* According to firmware both reg power and max tx power 381 * on set channel power is used and set it to max reg 382 * power from regulatory. 383 */ 384 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 385 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 386 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 387 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 388 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 389 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 390 391 } 392 #endif 393 /** 394 * send_vdev_start_cmd_tlv() - send vdev start request to fw 395 * @wmi_handle: wmi handle 396 * @req: vdev start params 397 * 398 * Return: QDF status 399 */ 400 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 401 struct vdev_start_params *req) 402 { 403 wmi_vdev_start_request_cmd_fixed_param *cmd; 404 wmi_buf_t buf; 405 wmi_channel *chan; 406 int32_t len, ret; 407 uint8_t *buf_ptr; 408 409 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 410 buf = wmi_buf_alloc(wmi_handle, len); 411 if (!buf) { 412 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 413 return QDF_STATUS_E_NOMEM; 414 } 415 buf_ptr = (uint8_t *) wmi_buf_data(buf); 416 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 417 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 418 WMITLV_SET_HDR(&cmd->tlv_header, 419 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 420 WMITLV_GET_STRUCT_TLVLEN 421 (wmi_vdev_start_request_cmd_fixed_param)); 422 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 423 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 424 cmd->vdev_id = req->vdev_id; 425 426 /* Fill channel info */ 427 copy_channel_info(cmd, chan, req); 428 429 cmd->beacon_interval = req->beacon_intval; 430 cmd->dtim_period = req->dtim_period; 431 432 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 433 if (req->bcn_tx_rate_code) 434 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 435 436 if (!req->is_restart) { 437 cmd->beacon_interval = req->beacon_intval; 438 cmd->dtim_period = req->dtim_period; 439 440 /* Copy the SSID */ 441 if (req->ssid.length) { 442 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 443 cmd->ssid.ssid_len = req->ssid.length; 444 else 445 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 446 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 447 cmd->ssid.ssid_len); 448 } 449 450 if (req->hidden_ssid) 451 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 452 453 if (req->pmf_enabled) 454 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 455 } 456 457 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 458 cmd->num_noa_descriptors = req->num_noa_descriptors; 459 cmd->preferred_rx_streams = req->preferred_rx_streams; 460 cmd->preferred_tx_streams = req->preferred_tx_streams; 461 cmd->cac_duration_ms = req->cac_duration_ms; 462 cmd->regdomain = req->regdomain; 463 cmd->he_ops = req->he_ops; 464 465 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 466 sizeof(wmi_channel)); 467 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 468 cmd->num_noa_descriptors * 469 sizeof(wmi_p2p_noa_descriptor)); 470 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 471 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 472 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 473 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 474 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 475 chan->mhz, req->chan_mode, chan->info, 476 req->is_dfs, req->beacon_intval, cmd->dtim_period, 477 chan->band_center_freq1, chan->band_center_freq2, 478 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 479 req->preferred_tx_streams, req->preferred_rx_streams, 480 req->ldpc_rx_enabled, req->cac_duration_ms, 481 req->regdomain, req->he_ops, 482 req->dis_hw_ack); 483 484 if (req->is_restart) 485 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 486 WMI_VDEV_RESTART_REQUEST_CMDID); 487 else 488 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 489 WMI_VDEV_START_REQUEST_CMDID); 490 if (ret) { 491 WMI_LOGP("%s: Failed to send vdev start command", __func__); 492 wmi_buf_free(buf); 493 return QDF_STATUS_E_FAILURE; 494 } 495 496 return QDF_STATUS_SUCCESS; 497 } 498 499 /** 500 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 501 * @wmi_handle: wmi handle 502 * @restart_params: vdev restart params 503 * 504 * Return: QDF_STATUS_SUCCESS for success or error code 505 */ 506 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 507 struct hidden_ssid_vdev_restart_params *restart_params) 508 { 509 wmi_vdev_start_request_cmd_fixed_param *cmd; 510 wmi_buf_t buf; 511 wmi_channel *chan; 512 int32_t len; 513 uint8_t *buf_ptr; 514 QDF_STATUS ret = 0; 515 516 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 517 buf = wmi_buf_alloc(wmi_handle, len); 518 if (!buf) { 519 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 520 return QDF_STATUS_E_NOMEM; 521 } 522 buf_ptr = (uint8_t *) wmi_buf_data(buf); 523 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 524 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 525 526 WMITLV_SET_HDR(&cmd->tlv_header, 527 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 528 WMITLV_GET_STRUCT_TLVLEN 529 (wmi_vdev_start_request_cmd_fixed_param)); 530 531 WMITLV_SET_HDR(&chan->tlv_header, 532 WMITLV_TAG_STRUC_wmi_channel, 533 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 534 535 cmd->vdev_id = restart_params->session_id; 536 cmd->ssid.ssid_len = restart_params->ssid_len; 537 qdf_mem_copy(cmd->ssid.ssid, 538 restart_params->ssid, 539 cmd->ssid.ssid_len); 540 cmd->flags = restart_params->flags; 541 cmd->requestor_id = restart_params->requestor_id; 542 cmd->disable_hw_ack = restart_params->disable_hw_ack; 543 544 chan->mhz = restart_params->mhz; 545 chan->band_center_freq1 = 546 restart_params->band_center_freq1; 547 chan->band_center_freq2 = 548 restart_params->band_center_freq2; 549 chan->info = restart_params->info; 550 chan->reg_info_1 = restart_params->reg_info_1; 551 chan->reg_info_2 = restart_params->reg_info_2; 552 553 cmd->num_noa_descriptors = 0; 554 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 555 sizeof(wmi_channel)); 556 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 557 cmd->num_noa_descriptors * 558 sizeof(wmi_p2p_noa_descriptor)); 559 560 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 561 WMI_VDEV_RESTART_REQUEST_CMDID); 562 if (QDF_IS_STATUS_ERROR(ret)) { 563 wmi_buf_free(buf); 564 return QDF_STATUS_E_FAILURE; 565 } 566 return QDF_STATUS_SUCCESS; 567 } 568 569 570 /** 571 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 572 * @wmi: wmi handle 573 * @peer_addr: peer mac address 574 * @param: pointer to hold peer flush tid parameter 575 * 576 * Return: 0 for success or error code 577 */ 578 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 579 uint8_t peer_addr[IEEE80211_ADDR_LEN], 580 struct peer_flush_params *param) 581 { 582 wmi_peer_flush_tids_cmd_fixed_param *cmd; 583 wmi_buf_t buf; 584 int32_t len = sizeof(*cmd); 585 586 buf = wmi_buf_alloc(wmi, len); 587 if (!buf) { 588 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 589 return QDF_STATUS_E_NOMEM; 590 } 591 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 592 WMITLV_SET_HDR(&cmd->tlv_header, 593 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 594 WMITLV_GET_STRUCT_TLVLEN 595 (wmi_peer_flush_tids_cmd_fixed_param)); 596 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 597 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 598 cmd->vdev_id = param->vdev_id; 599 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 600 peer_addr, param->vdev_id, 601 param->peer_tid_bitmap); 602 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 603 WMI_LOGP("%s: Failed to send flush tid command", __func__); 604 wmi_buf_free(buf); 605 return QDF_STATUS_E_FAILURE; 606 } 607 608 return 0; 609 } 610 611 /** 612 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 613 * @wmi: wmi handle 614 * @peer_addr: peer mac addr 615 * @vdev_id: vdev id 616 * 617 * Return: QDF_STATUS_SUCCESS for success or error code 618 */ 619 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 620 uint8_t peer_addr[IEEE80211_ADDR_LEN], 621 uint8_t vdev_id) 622 { 623 wmi_peer_delete_cmd_fixed_param *cmd; 624 wmi_buf_t buf; 625 int32_t len = sizeof(*cmd); 626 buf = wmi_buf_alloc(wmi, len); 627 if (!buf) { 628 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 629 return QDF_STATUS_E_NOMEM; 630 } 631 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 632 WMITLV_SET_HDR(&cmd->tlv_header, 633 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 634 WMITLV_GET_STRUCT_TLVLEN 635 (wmi_peer_delete_cmd_fixed_param)); 636 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 637 cmd->vdev_id = vdev_id; 638 639 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 640 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 641 WMI_LOGP("%s: Failed to send peer delete command", __func__); 642 wmi_buf_free(buf); 643 return QDF_STATUS_E_FAILURE; 644 } 645 646 return 0; 647 } 648 649 /** 650 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 651 * to target id. 652 * @targ_paramid: Target parameter id to hold the result. 653 * @peer_param_id: host param id. 654 * 655 * Return: QDF_STATUS_SUCCESS for success 656 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 657 */ 658 #ifdef CONFIG_MCL 659 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 660 uint32_t *targ_paramid, 661 uint32_t peer_param_id) 662 { 663 *targ_paramid = peer_param_id; 664 return QDF_STATUS_SUCCESS; 665 } 666 667 /** 668 * crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd 669 * 670 * On MCL side, we are suspecting this cmd to trigger drop of ARP 671 * response frames from REO by the FW. This function causes a crash if this 672 * command is sent out by the host, so we can track this issue. Ideally no one 673 * should be calling this API from the MCL side 674 * 675 * Return: None 676 */ 677 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 678 { 679 QDF_BUG(0); 680 } 681 #else 682 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 683 uint32_t *targ_paramid, 684 uint32_t peer_param_id) 685 { 686 switch (peer_param_id) { 687 case WMI_HOST_PEER_MIMO_PS_STATE: 688 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 689 break; 690 case WMI_HOST_PEER_AMPDU: 691 *targ_paramid = WMI_PEER_AMPDU; 692 break; 693 case WMI_HOST_PEER_AUTHORIZE: 694 *targ_paramid = WMI_PEER_AUTHORIZE; 695 break; 696 case WMI_HOST_PEER_CHWIDTH: 697 *targ_paramid = WMI_PEER_CHWIDTH; 698 break; 699 case WMI_HOST_PEER_NSS: 700 *targ_paramid = WMI_PEER_NSS; 701 break; 702 case WMI_HOST_PEER_USE_4ADDR: 703 *targ_paramid = WMI_PEER_USE_4ADDR; 704 break; 705 case WMI_HOST_PEER_MEMBERSHIP: 706 *targ_paramid = WMI_PEER_MEMBERSHIP; 707 break; 708 case WMI_HOST_PEER_USERPOS: 709 *targ_paramid = WMI_PEER_USERPOS; 710 break; 711 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 712 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 713 break; 714 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 715 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 716 break; 717 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 718 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 719 break; 720 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 721 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 722 break; 723 case WMI_HOST_PEER_PHYMODE: 724 *targ_paramid = WMI_PEER_PHYMODE; 725 break; 726 case WMI_HOST_PEER_USE_FIXED_PWR: 727 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 728 break; 729 case WMI_HOST_PEER_PARAM_FIXED_RATE: 730 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 731 break; 732 case WMI_HOST_PEER_SET_MU_WHITELIST: 733 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 734 break; 735 case WMI_HOST_PEER_SET_MAC_TX_RATE: 736 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 737 break; 738 case WMI_HOST_PEER_SET_MIN_TX_RATE: 739 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 740 break; 741 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 742 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 743 break; 744 case WMI_HOST_PEER_NSS_VHT160: 745 *targ_paramid = WMI_PEER_NSS_VHT160; 746 break; 747 case WMI_HOST_PEER_NSS_VHT80_80: 748 *targ_paramid = WMI_PEER_NSS_VHT80_80; 749 break; 750 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 751 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 752 break; 753 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 754 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 755 break; 756 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 757 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 758 break; 759 case WMI_HOST_PEER_PARAM_MU_ENABLE: 760 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 761 break; 762 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 763 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 764 break; 765 default: 766 return QDF_STATUS_E_NOSUPPORT; 767 } 768 769 return QDF_STATUS_SUCCESS; 770 } 771 772 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 773 { 774 /* No-OP */ 775 } 776 777 #endif 778 /** 779 * send_peer_param_cmd_tlv() - set peer parameter in fw 780 * @wmi: wmi handle 781 * @peer_addr: peer mac address 782 * @param : pointer to hold peer set parameter 783 * 784 * Return: QDF_STATUS_SUCCESS for success or error code 785 */ 786 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 787 uint8_t peer_addr[IEEE80211_ADDR_LEN], 788 struct peer_set_params *param) 789 { 790 wmi_peer_set_param_cmd_fixed_param *cmd; 791 wmi_buf_t buf; 792 int32_t err; 793 uint32_t param_id; 794 795 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 796 param->param_id) != QDF_STATUS_SUCCESS) 797 return QDF_STATUS_E_NOSUPPORT; 798 799 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 800 if (!buf) { 801 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 802 return QDF_STATUS_E_NOMEM; 803 } 804 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 805 WMITLV_SET_HDR(&cmd->tlv_header, 806 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 807 WMITLV_GET_STRUCT_TLVLEN 808 (wmi_peer_set_param_cmd_fixed_param)); 809 cmd->vdev_id = param->vdev_id; 810 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 811 cmd->param_id = param_id; 812 cmd->param_value = param->param_value; 813 err = wmi_unified_cmd_send(wmi, buf, 814 sizeof(wmi_peer_set_param_cmd_fixed_param), 815 WMI_PEER_SET_PARAM_CMDID); 816 if (err) { 817 WMI_LOGE("Failed to send set_param cmd"); 818 wmi_buf_free(buf); 819 return QDF_STATUS_E_FAILURE; 820 } 821 822 return 0; 823 } 824 825 /** 826 * send_vdev_up_cmd_tlv() - send vdev up command in fw 827 * @wmi: wmi handle 828 * @bssid: bssid 829 * @vdev_up_params: pointer to hold vdev up parameter 830 * 831 * Return: QDF_STATUS_SUCCESS for success or error code 832 */ 833 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 834 uint8_t bssid[IEEE80211_ADDR_LEN], 835 struct vdev_up_params *params) 836 { 837 wmi_vdev_up_cmd_fixed_param *cmd; 838 wmi_buf_t buf; 839 int32_t len = sizeof(*cmd); 840 841 WMI_LOGD("%s: VDEV_UP", __func__); 842 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 843 params->vdev_id, params->assoc_id, bssid); 844 buf = wmi_buf_alloc(wmi, len); 845 if (!buf) { 846 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 847 return QDF_STATUS_E_NOMEM; 848 } 849 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 850 WMITLV_SET_HDR(&cmd->tlv_header, 851 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 852 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 853 cmd->vdev_id = params->vdev_id; 854 cmd->vdev_assoc_id = params->assoc_id; 855 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 856 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 857 WMI_LOGP("%s: Failed to send vdev up command", __func__); 858 wmi_buf_free(buf); 859 return QDF_STATUS_E_FAILURE; 860 } 861 862 return 0; 863 } 864 865 /** 866 * send_peer_create_cmd_tlv() - send peer create command to fw 867 * @wmi: wmi handle 868 * @peer_addr: peer mac address 869 * @peer_type: peer type 870 * @vdev_id: vdev id 871 * 872 * Return: QDF_STATUS_SUCCESS for success or error code 873 */ 874 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 875 struct peer_create_params *param) 876 { 877 wmi_peer_create_cmd_fixed_param *cmd; 878 wmi_buf_t buf; 879 int32_t len = sizeof(*cmd); 880 881 buf = wmi_buf_alloc(wmi, len); 882 if (!buf) { 883 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 884 return QDF_STATUS_E_NOMEM; 885 } 886 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 887 WMITLV_SET_HDR(&cmd->tlv_header, 888 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 889 WMITLV_GET_STRUCT_TLVLEN 890 (wmi_peer_create_cmd_fixed_param)); 891 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 892 cmd->peer_type = param->peer_type; 893 cmd->vdev_id = param->vdev_id; 894 895 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 896 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 897 wmi_buf_free(buf); 898 return QDF_STATUS_E_FAILURE; 899 } 900 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 901 param->vdev_id); 902 903 return 0; 904 } 905 906 /** 907 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 908 * command to fw 909 * @wmi: wmi handle 910 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 911 * 912 * Return: 0 for success or error code 913 */ 914 static 915 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 916 struct rx_reorder_queue_setup_params *param) 917 { 918 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 919 wmi_buf_t buf; 920 int32_t len = sizeof(*cmd); 921 922 buf = wmi_buf_alloc(wmi, len); 923 if (!buf) { 924 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 925 return QDF_STATUS_E_NOMEM; 926 } 927 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 928 WMITLV_SET_HDR(&cmd->tlv_header, 929 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 930 WMITLV_GET_STRUCT_TLVLEN 931 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 932 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 933 cmd->vdev_id = param->vdev_id; 934 cmd->tid = param->tid; 935 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 936 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 937 cmd->queue_no = param->queue_no; 938 cmd->ba_window_size_valid = param->ba_window_size_valid; 939 cmd->ba_window_size = param->ba_window_size; 940 941 942 if (wmi_unified_cmd_send(wmi, buf, len, 943 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 944 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 945 __func__); 946 qdf_nbuf_free(buf); 947 return QDF_STATUS_E_FAILURE; 948 } 949 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 950 param->peer_macaddr, param->vdev_id, param->tid); 951 952 return QDF_STATUS_SUCCESS; 953 } 954 955 /** 956 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 957 * command to fw 958 * @wmi: wmi handle 959 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 960 * 961 * Return: 0 for success or error code 962 */ 963 static 964 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 965 struct rx_reorder_queue_remove_params *param) 966 { 967 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 968 wmi_buf_t buf; 969 int32_t len = sizeof(*cmd); 970 971 crash_on_send_peer_rx_reorder_queue_remove_cmd(); 972 973 buf = wmi_buf_alloc(wmi, len); 974 if (!buf) { 975 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 976 return QDF_STATUS_E_NOMEM; 977 } 978 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 979 wmi_buf_data(buf); 980 WMITLV_SET_HDR(&cmd->tlv_header, 981 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 982 WMITLV_GET_STRUCT_TLVLEN 983 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 984 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 985 cmd->vdev_id = param->vdev_id; 986 cmd->tid_mask = param->peer_tid_bitmap; 987 988 if (wmi_unified_cmd_send(wmi, buf, len, 989 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 990 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 991 __func__); 992 qdf_nbuf_free(buf); 993 return QDF_STATUS_E_FAILURE; 994 } 995 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 996 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 997 998 return QDF_STATUS_SUCCESS; 999 } 1000 1001 /** 1002 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 1003 * @wmi_handle: wmi handle 1004 * @param: pointer holding peer details 1005 * 1006 * Return: 0 for success or error code 1007 */ 1008 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1009 struct peer_add_wds_entry_params *param) 1010 { 1011 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 1012 wmi_buf_t buf; 1013 int len = sizeof(*cmd); 1014 1015 buf = wmi_buf_alloc(wmi_handle, len); 1016 if (!buf) { 1017 qdf_print("%s: wmi_buf_alloc failed", __func__); 1018 return QDF_STATUS_E_FAILURE; 1019 } 1020 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 1021 WMITLV_SET_HDR(&cmd->tlv_header, 1022 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 1023 WMITLV_GET_STRUCT_TLVLEN 1024 (wmi_peer_add_wds_entry_cmd_fixed_param)); 1025 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 1026 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1027 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1028 cmd->vdev_id = param->vdev_id; 1029 1030 return wmi_unified_cmd_send(wmi_handle, buf, len, 1031 WMI_PEER_ADD_WDS_ENTRY_CMDID); 1032 } 1033 1034 /** 1035 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 1036 * @wmi_handle: wmi handle 1037 * @param: pointer holding peer details 1038 * 1039 * Return: 0 for success or error code 1040 */ 1041 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1042 struct peer_del_wds_entry_params *param) 1043 { 1044 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 1045 wmi_buf_t buf; 1046 int len = sizeof(*cmd); 1047 1048 buf = wmi_buf_alloc(wmi_handle, len); 1049 if (!buf) { 1050 qdf_print("%s: wmi_buf_alloc failed", __func__); 1051 return QDF_STATUS_E_NOMEM; 1052 } 1053 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1054 WMITLV_SET_HDR(&cmd->tlv_header, 1055 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 1056 WMITLV_GET_STRUCT_TLVLEN 1057 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 1058 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 1059 cmd->vdev_id = param->vdev_id; 1060 return wmi_unified_cmd_send(wmi_handle, buf, len, 1061 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 1062 } 1063 1064 /** 1065 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 1066 * @wmi_handle: wmi handle 1067 * @param: pointer holding peer details 1068 * 1069 * Return: 0 for success or error code 1070 */ 1071 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1072 struct peer_update_wds_entry_params *param) 1073 { 1074 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 1075 wmi_buf_t buf; 1076 int len = sizeof(*cmd); 1077 1078 buf = wmi_buf_alloc(wmi_handle, len); 1079 if (!buf) { 1080 qdf_print("%s: wmi_buf_alloc failed", __func__); 1081 return QDF_STATUS_E_NOMEM; 1082 } 1083 1084 /* wmi_buf_alloc returns zeroed command buffer */ 1085 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1086 WMITLV_SET_HDR(&cmd->tlv_header, 1087 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 1088 WMITLV_GET_STRUCT_TLVLEN 1089 (wmi_peer_update_wds_entry_cmd_fixed_param)); 1090 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1091 cmd->vdev_id = param->vdev_id; 1092 if (param->wds_macaddr) 1093 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1094 &cmd->wds_macaddr); 1095 if (param->peer_macaddr) 1096 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1097 &cmd->peer_macaddr); 1098 return wmi_unified_cmd_send(wmi_handle, buf, len, 1099 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1100 } 1101 1102 /** 1103 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1104 * @wmi_handle: wmi handle 1105 * @param: pointer to get tpc config params 1106 * 1107 * Return: 0 for success or error code 1108 */ 1109 static QDF_STATUS 1110 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1111 uint32_t param) 1112 { 1113 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1114 wmi_buf_t buf; 1115 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1116 1117 buf = wmi_buf_alloc(wmi_handle, len); 1118 if (!buf) { 1119 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1120 return QDF_STATUS_E_NOMEM; 1121 } 1122 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1123 WMITLV_SET_HDR(&cmd->tlv_header, 1124 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1125 WMITLV_GET_STRUCT_TLVLEN 1126 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1127 1128 cmd->param = param; 1129 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1130 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1131 WMI_LOGE("Send pdev get tpc config cmd failed"); 1132 wmi_buf_free(buf); 1133 return QDF_STATUS_E_FAILURE; 1134 1135 } 1136 WMI_LOGD("%s:send success", __func__); 1137 1138 return QDF_STATUS_SUCCESS; 1139 } 1140 1141 #ifdef WLAN_SUPPORT_GREEN_AP 1142 /** 1143 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1144 * @wmi_handle: wmi handle 1145 * @value: value 1146 * @pdev_id: pdev id to have radio context 1147 * 1148 * Return: QDF_STATUS_SUCCESS for success or error code 1149 */ 1150 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1151 uint32_t value, uint8_t pdev_id) 1152 { 1153 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1154 wmi_buf_t buf; 1155 int32_t len = sizeof(*cmd); 1156 1157 WMI_LOGD("Set Green AP PS val %d", value); 1158 1159 buf = wmi_buf_alloc(wmi_handle, len); 1160 if (!buf) { 1161 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1162 return QDF_STATUS_E_NOMEM; 1163 } 1164 1165 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1166 WMITLV_SET_HDR(&cmd->tlv_header, 1167 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1168 WMITLV_GET_STRUCT_TLVLEN 1169 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1170 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1171 cmd->enable = value; 1172 1173 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1174 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1175 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1176 wmi_buf_free(buf); 1177 return QDF_STATUS_E_FAILURE; 1178 } 1179 1180 return 0; 1181 } 1182 #endif 1183 1184 /** 1185 * send_pdev_utf_cmd_tlv() - send utf command to fw 1186 * @wmi_handle: wmi handle 1187 * @param: pointer to pdev_utf_params 1188 * @mac_id: mac id to have radio context 1189 * 1190 * Return: QDF_STATUS_SUCCESS for success or error code 1191 */ 1192 static QDF_STATUS 1193 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1194 struct pdev_utf_params *param, 1195 uint8_t mac_id) 1196 { 1197 wmi_buf_t buf; 1198 uint8_t *cmd; 1199 /* if param->len is 0 no data is sent, return error */ 1200 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1201 static uint8_t msgref = 1; 1202 uint8_t segNumber = 0, segInfo, numSegments; 1203 uint16_t chunk_len, total_bytes; 1204 uint8_t *bufpos; 1205 struct seg_hdr_info segHdrInfo; 1206 1207 bufpos = param->utf_payload; 1208 total_bytes = param->len; 1209 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1210 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1211 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1212 1213 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1214 numSegments++; 1215 1216 while (param->len) { 1217 if (param->len > MAX_WMI_UTF_LEN) 1218 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1219 else 1220 chunk_len = param->len; 1221 1222 buf = wmi_buf_alloc(wmi_handle, 1223 (chunk_len + sizeof(segHdrInfo) + 1224 WMI_TLV_HDR_SIZE)); 1225 if (!buf) { 1226 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1227 return QDF_STATUS_E_NOMEM; 1228 } 1229 1230 cmd = (uint8_t *) wmi_buf_data(buf); 1231 1232 segHdrInfo.len = total_bytes; 1233 segHdrInfo.msgref = msgref; 1234 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1235 segHdrInfo.segmentInfo = segInfo; 1236 segHdrInfo.pad = 0; 1237 1238 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1239 " segHdrInfo.segmentInfo = %d", 1240 __func__, segHdrInfo.len, segHdrInfo.msgref, 1241 segHdrInfo.segmentInfo); 1242 1243 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1244 "chunk len %d", __func__, total_bytes, segNumber, 1245 numSegments, chunk_len); 1246 1247 segNumber++; 1248 1249 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1250 (chunk_len + sizeof(segHdrInfo))); 1251 cmd += WMI_TLV_HDR_SIZE; 1252 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1253 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1254 1255 ret = wmi_unified_cmd_send(wmi_handle, buf, 1256 (chunk_len + sizeof(segHdrInfo) + 1257 WMI_TLV_HDR_SIZE), 1258 WMI_PDEV_UTF_CMDID); 1259 1260 if (QDF_IS_STATUS_ERROR(ret)) { 1261 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1262 wmi_buf_free(buf); 1263 break; 1264 } 1265 1266 param->len -= chunk_len; 1267 bufpos += chunk_len; 1268 } 1269 1270 msgref++; 1271 1272 return ret; 1273 } 1274 #ifdef CONFIG_MCL 1275 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1276 uint32_t host_param) 1277 { 1278 return host_param; 1279 } 1280 #else 1281 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1282 uint32_t host_param) 1283 { 1284 if (host_param < wmi_pdev_param_max) 1285 return wmi_handle->pdev_param[host_param]; 1286 1287 return WMI_UNAVAILABLE_PARAM; 1288 } 1289 #endif 1290 /** 1291 * send_pdev_param_cmd_tlv() - set pdev parameters 1292 * @wmi_handle: wmi handle 1293 * @param: pointer to pdev parameter 1294 * @mac_id: radio context 1295 * 1296 * Return: 0 on success, errno on failure 1297 */ 1298 static QDF_STATUS 1299 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1300 struct pdev_params *param, 1301 uint8_t mac_id) 1302 { 1303 QDF_STATUS ret; 1304 wmi_pdev_set_param_cmd_fixed_param *cmd; 1305 wmi_buf_t buf; 1306 uint16_t len = sizeof(*cmd); 1307 uint32_t pdev_param; 1308 1309 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1310 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1311 WMI_LOGW("%s: Unavailable param %d\n", 1312 __func__, param->param_id); 1313 return QDF_STATUS_E_INVAL; 1314 } 1315 1316 buf = wmi_buf_alloc(wmi_handle, len); 1317 if (!buf) { 1318 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1319 return QDF_STATUS_E_NOMEM; 1320 } 1321 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1322 WMITLV_SET_HDR(&cmd->tlv_header, 1323 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1324 WMITLV_GET_STRUCT_TLVLEN 1325 (wmi_pdev_set_param_cmd_fixed_param)); 1326 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1327 cmd->param_id = pdev_param; 1328 cmd->param_value = param->param_value; 1329 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1330 param->param_value); 1331 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1332 WMI_PDEV_SET_PARAM_CMDID); 1333 if (QDF_IS_STATUS_ERROR(ret)) { 1334 WMI_LOGE("Failed to send set param command ret = %d", ret); 1335 wmi_buf_free(buf); 1336 } 1337 return ret; 1338 } 1339 1340 /** 1341 * send_suspend_cmd_tlv() - WMI suspend function 1342 * @param wmi_handle : handle to WMI. 1343 * @param param : pointer to hold suspend parameter 1344 * @mac_id: radio context 1345 * 1346 * Return 0 on success and -ve on failure. 1347 */ 1348 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1349 struct suspend_params *param, 1350 uint8_t mac_id) 1351 { 1352 wmi_pdev_suspend_cmd_fixed_param *cmd; 1353 wmi_buf_t wmibuf; 1354 uint32_t len = sizeof(*cmd); 1355 int32_t ret; 1356 1357 /* 1358 * send the command to Target to ignore the 1359 * PCIE reset so as to ensure that Host and target 1360 * states are in sync 1361 */ 1362 wmibuf = wmi_buf_alloc(wmi_handle, len); 1363 if (wmibuf == NULL) 1364 return QDF_STATUS_E_NOMEM; 1365 1366 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1367 WMITLV_SET_HDR(&cmd->tlv_header, 1368 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1369 WMITLV_GET_STRUCT_TLVLEN 1370 (wmi_pdev_suspend_cmd_fixed_param)); 1371 if (param->disable_target_intr) 1372 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1373 else 1374 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1375 1376 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1377 1378 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1379 WMI_PDEV_SUSPEND_CMDID); 1380 if (ret) { 1381 wmi_buf_free(wmibuf); 1382 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1383 } 1384 1385 return ret; 1386 } 1387 1388 /** 1389 * send_resume_cmd_tlv() - WMI resume function 1390 * @param wmi_handle : handle to WMI. 1391 * @mac_id: radio context 1392 * 1393 * Return: 0 on success and -ve on failure. 1394 */ 1395 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1396 uint8_t mac_id) 1397 { 1398 wmi_buf_t wmibuf; 1399 wmi_pdev_resume_cmd_fixed_param *cmd; 1400 QDF_STATUS ret; 1401 1402 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1403 if (wmibuf == NULL) 1404 return QDF_STATUS_E_NOMEM; 1405 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1406 WMITLV_SET_HDR(&cmd->tlv_header, 1407 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1408 WMITLV_GET_STRUCT_TLVLEN 1409 (wmi_pdev_resume_cmd_fixed_param)); 1410 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1411 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1412 WMI_PDEV_RESUME_CMDID); 1413 if (QDF_IS_STATUS_ERROR(ret)) { 1414 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1415 wmi_buf_free(wmibuf); 1416 } 1417 1418 return ret; 1419 } 1420 1421 #ifdef FEATURE_WLAN_D0WOW 1422 /** 1423 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1424 * @param wmi_handle: handle to WMI. 1425 * @mac_id: radio context 1426 * 1427 * Return: 0 on success and error code on failure. 1428 */ 1429 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1430 uint8_t mac_id) 1431 { 1432 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1433 wmi_buf_t buf; 1434 int32_t len; 1435 QDF_STATUS status; 1436 1437 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1438 1439 buf = wmi_buf_alloc(wmi_handle, len); 1440 if (!buf) { 1441 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1442 return QDF_STATUS_E_NOMEM; 1443 } 1444 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1445 WMITLV_SET_HDR(&cmd->tlv_header, 1446 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1447 WMITLV_GET_STRUCT_TLVLEN 1448 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1449 1450 cmd->enable = true; 1451 1452 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1453 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1454 if (QDF_IS_STATUS_ERROR(status)) 1455 wmi_buf_free(buf); 1456 1457 return status; 1458 } 1459 1460 /** 1461 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1462 * @param wmi_handle: handle to WMI. 1463 * @mac_id: radio context 1464 * 1465 * Return: 0 on success and error code on failure. 1466 */ 1467 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1468 uint8_t mac_id) 1469 { 1470 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1471 wmi_buf_t buf; 1472 int32_t len; 1473 QDF_STATUS status; 1474 1475 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1476 1477 buf = wmi_buf_alloc(wmi_handle, len); 1478 if (!buf) { 1479 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1480 return QDF_STATUS_E_NOMEM; 1481 } 1482 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1483 WMITLV_SET_HDR(&cmd->tlv_header, 1484 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1485 WMITLV_GET_STRUCT_TLVLEN 1486 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1487 1488 cmd->enable = false; 1489 1490 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1491 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1492 if (QDF_IS_STATUS_ERROR(status)) 1493 wmi_buf_free(buf); 1494 1495 return status; 1496 } 1497 #endif 1498 1499 /** 1500 * send_wow_enable_cmd_tlv() - WMI wow enable function 1501 * @param wmi_handle : handle to WMI. 1502 * @param param : pointer to hold wow enable parameter 1503 * @mac_id: radio context 1504 * 1505 * Return: 0 on success and -ve on failure. 1506 */ 1507 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1508 struct wow_cmd_params *param, 1509 uint8_t mac_id) 1510 { 1511 wmi_wow_enable_cmd_fixed_param *cmd; 1512 wmi_buf_t buf; 1513 int32_t len; 1514 int32_t ret; 1515 1516 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1517 1518 buf = wmi_buf_alloc(wmi_handle, len); 1519 if (!buf) { 1520 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1521 return QDF_STATUS_E_NOMEM; 1522 } 1523 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1524 WMITLV_SET_HDR(&cmd->tlv_header, 1525 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1526 WMITLV_GET_STRUCT_TLVLEN 1527 (wmi_wow_enable_cmd_fixed_param)); 1528 cmd->enable = param->enable; 1529 if (param->can_suspend_link) 1530 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1531 else 1532 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1533 cmd->flags = param->flags; 1534 1535 WMI_LOGI("suspend type: %s", 1536 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1537 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1538 1539 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1540 WMI_WOW_ENABLE_CMDID); 1541 if (ret) 1542 wmi_buf_free(buf); 1543 1544 return ret; 1545 } 1546 1547 /** 1548 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1549 * @wmi_handle: wmi handle 1550 * @peer_addr: peer mac address 1551 * @param: pointer to ap_ps parameter structure 1552 * 1553 * Return: QDF_STATUS_SUCCESS for success or error code 1554 */ 1555 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1556 uint8_t *peer_addr, 1557 struct ap_ps_params *param) 1558 { 1559 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1560 wmi_buf_t buf; 1561 int32_t err; 1562 1563 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1564 if (!buf) { 1565 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1566 return QDF_STATUS_E_NOMEM; 1567 } 1568 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1569 WMITLV_SET_HDR(&cmd->tlv_header, 1570 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1571 WMITLV_GET_STRUCT_TLVLEN 1572 (wmi_ap_ps_peer_cmd_fixed_param)); 1573 cmd->vdev_id = param->vdev_id; 1574 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1575 cmd->param = param->param; 1576 cmd->value = param->value; 1577 err = wmi_unified_cmd_send(wmi_handle, buf, 1578 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1579 if (err) { 1580 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1581 wmi_buf_free(buf); 1582 return QDF_STATUS_E_FAILURE; 1583 } 1584 1585 return 0; 1586 } 1587 1588 /** 1589 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1590 * @wmi_handle: wmi handle 1591 * @peer_addr: peer mac address 1592 * @param: pointer to sta_ps parameter structure 1593 * 1594 * Return: QDF_STATUS_SUCCESS for success or error code 1595 */ 1596 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1597 struct sta_ps_params *param) 1598 { 1599 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1600 wmi_buf_t buf; 1601 int32_t len = sizeof(*cmd); 1602 1603 buf = wmi_buf_alloc(wmi_handle, len); 1604 if (!buf) { 1605 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1606 return QDF_STATUS_E_NOMEM; 1607 } 1608 1609 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1610 WMITLV_SET_HDR(&cmd->tlv_header, 1611 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1612 WMITLV_GET_STRUCT_TLVLEN 1613 (wmi_sta_powersave_param_cmd_fixed_param)); 1614 cmd->vdev_id = param->vdev_id; 1615 cmd->param = param->param; 1616 cmd->value = param->value; 1617 1618 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1619 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1620 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1621 param->vdev_id, param->param, param->value); 1622 wmi_buf_free(buf); 1623 return QDF_STATUS_E_FAILURE; 1624 } 1625 1626 return 0; 1627 } 1628 1629 /** 1630 * send_crash_inject_cmd_tlv() - inject fw crash 1631 * @wmi_handle: wmi handle 1632 * @param: ponirt to crash inject parameter structure 1633 * 1634 * Return: QDF_STATUS_SUCCESS for success or return error 1635 */ 1636 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1637 struct crash_inject *param) 1638 { 1639 int32_t ret = 0; 1640 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1641 uint16_t len = sizeof(*cmd); 1642 wmi_buf_t buf; 1643 1644 buf = wmi_buf_alloc(wmi_handle, len); 1645 if (!buf) { 1646 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1647 return QDF_STATUS_E_NOMEM; 1648 } 1649 1650 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1651 WMITLV_SET_HDR(&cmd->tlv_header, 1652 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1653 WMITLV_GET_STRUCT_TLVLEN 1654 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1655 cmd->type = param->type; 1656 cmd->delay_time_ms = param->delay_time_ms; 1657 1658 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1659 WMI_FORCE_FW_HANG_CMDID); 1660 if (ret) { 1661 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1662 __func__, ret); 1663 wmi_buf_free(buf); 1664 } 1665 1666 return ret; 1667 } 1668 1669 #ifdef FEATURE_FW_LOG_PARSING 1670 /** 1671 * send_dbglog_cmd_tlv() - set debug log level 1672 * @param wmi_handle : handle to WMI. 1673 * @param param : pointer to hold dbglog level parameter 1674 * 1675 * Return: 0 on success and -ve on failure. 1676 */ 1677 static QDF_STATUS 1678 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1679 struct dbglog_params *dbglog_param) 1680 { 1681 wmi_buf_t buf; 1682 wmi_debug_log_config_cmd_fixed_param *configmsg; 1683 QDF_STATUS status; 1684 int32_t i; 1685 int32_t len; 1686 int8_t *buf_ptr; 1687 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1688 1689 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1690 1691 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1692 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1693 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1694 buf = wmi_buf_alloc(wmi_handle, len); 1695 if (buf == NULL) 1696 return QDF_STATUS_E_NOMEM; 1697 1698 configmsg = 1699 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1700 buf_ptr = (int8_t *) configmsg; 1701 WMITLV_SET_HDR(&configmsg->tlv_header, 1702 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1703 WMITLV_GET_STRUCT_TLVLEN 1704 (wmi_debug_log_config_cmd_fixed_param)); 1705 configmsg->dbg_log_param = dbglog_param->param; 1706 configmsg->value = dbglog_param->val; 1707 /* Filling in the data part of second tlv -- should 1708 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1709 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1710 sizeof 1711 (wmi_debug_log_config_cmd_fixed_param) 1712 + WMI_TLV_HDR_SIZE); 1713 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1714 WMITLV_TAG_ARRAY_UINT32, 1715 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1716 if (dbglog_param->module_id_bitmap) { 1717 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1718 module_id_bitmap_array[i] = 1719 dbglog_param->module_id_bitmap[i]; 1720 } 1721 } 1722 1723 status = wmi_unified_cmd_send(wmi_handle, buf, 1724 len, WMI_DBGLOG_CFG_CMDID); 1725 1726 if (status != QDF_STATUS_SUCCESS) 1727 wmi_buf_free(buf); 1728 1729 return status; 1730 } 1731 #endif 1732 1733 #ifdef CONFIG_MCL 1734 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1735 uint32_t host_param) 1736 { 1737 return host_param; 1738 } 1739 #else 1740 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1741 uint32_t host_param) 1742 { 1743 if (host_param < wmi_vdev_param_max) 1744 return wmi_handle->vdev_param[host_param]; 1745 1746 return WMI_UNAVAILABLE_PARAM; 1747 } 1748 #endif 1749 /** 1750 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1751 * @param wmi_handle : handle to WMI. 1752 * @param macaddr : MAC address 1753 * @param param : pointer to hold vdev set parameter 1754 * 1755 * Return: 0 on success and -ve on failure. 1756 */ 1757 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1758 struct vdev_set_params *param) 1759 { 1760 QDF_STATUS ret; 1761 wmi_vdev_set_param_cmd_fixed_param *cmd; 1762 wmi_buf_t buf; 1763 uint16_t len = sizeof(*cmd); 1764 uint32_t vdev_param; 1765 1766 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1767 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1768 WMI_LOGW("%s:Vdev param %d not available", __func__, 1769 param->param_id); 1770 return QDF_STATUS_E_INVAL; 1771 1772 } 1773 1774 buf = wmi_buf_alloc(wmi_handle, len); 1775 if (!buf) { 1776 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1777 return QDF_STATUS_E_NOMEM; 1778 } 1779 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1780 WMITLV_SET_HDR(&cmd->tlv_header, 1781 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1782 WMITLV_GET_STRUCT_TLVLEN 1783 (wmi_vdev_set_param_cmd_fixed_param)); 1784 cmd->vdev_id = param->if_id; 1785 cmd->param_id = vdev_param; 1786 cmd->param_value = param->param_value; 1787 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1788 cmd->vdev_id, cmd->param_id, cmd->param_value); 1789 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1790 WMI_VDEV_SET_PARAM_CMDID); 1791 if (QDF_IS_STATUS_ERROR(ret)) { 1792 WMI_LOGE("Failed to send set param command ret = %d", ret); 1793 wmi_buf_free(buf); 1794 } 1795 1796 return ret; 1797 } 1798 1799 /** 1800 * send_stats_request_cmd_tlv() - WMI request stats function 1801 * @param wmi_handle : handle to WMI. 1802 * @param macaddr : MAC address 1803 * @param param : pointer to hold stats request parameter 1804 * 1805 * Return: 0 on success and -ve on failure. 1806 */ 1807 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1808 uint8_t macaddr[IEEE80211_ADDR_LEN], 1809 struct stats_request_params *param) 1810 { 1811 int32_t ret; 1812 wmi_request_stats_cmd_fixed_param *cmd; 1813 wmi_buf_t buf; 1814 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1815 1816 buf = wmi_buf_alloc(wmi_handle, len); 1817 if (!buf) { 1818 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1819 return -QDF_STATUS_E_NOMEM; 1820 } 1821 1822 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1823 WMITLV_SET_HDR(&cmd->tlv_header, 1824 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1825 WMITLV_GET_STRUCT_TLVLEN 1826 (wmi_request_stats_cmd_fixed_param)); 1827 cmd->stats_id = param->stats_id; 1828 cmd->vdev_id = param->vdev_id; 1829 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1830 param->pdev_id); 1831 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1832 1833 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1834 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1835 1836 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1837 WMI_REQUEST_STATS_CMDID); 1838 1839 if (ret) { 1840 WMI_LOGE("Failed to send status request to fw =%d", ret); 1841 wmi_buf_free(buf); 1842 } 1843 1844 return ret; 1845 } 1846 1847 #ifdef CONFIG_WIN 1848 /** 1849 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1850 * @param wmi_handle : handle to WMI. 1851 * @param PKTLOG_EVENT : packet log event 1852 * @mac_id: mac id to have radio context 1853 * 1854 * Return: 0 on success and -ve on failure. 1855 */ 1856 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1857 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1858 { 1859 int32_t ret; 1860 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1861 wmi_buf_t buf; 1862 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1863 1864 buf = wmi_buf_alloc(wmi_handle, len); 1865 if (!buf) { 1866 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1867 return -QDF_STATUS_E_NOMEM; 1868 } 1869 1870 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1871 WMITLV_SET_HDR(&cmd->tlv_header, 1872 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1873 WMITLV_GET_STRUCT_TLVLEN 1874 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1875 cmd->evlist = PKTLOG_EVENT; 1876 cmd->pdev_id = mac_id; 1877 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1878 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1879 if (ret) { 1880 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1881 wmi_buf_free(buf); 1882 } 1883 1884 return ret; 1885 } 1886 1887 /** 1888 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1889 * @param wmi_handle : handle to WMI. 1890 * @mac_id: mac id to have radio context 1891 * 1892 * Return: 0 on success and -ve on failure. 1893 */ 1894 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1895 uint8_t mac_id) 1896 { 1897 int32_t ret; 1898 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1899 wmi_buf_t buf; 1900 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1901 1902 buf = wmi_buf_alloc(wmi_handle, len); 1903 if (!buf) { 1904 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1905 return -QDF_STATUS_E_NOMEM; 1906 } 1907 1908 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1909 WMITLV_SET_HDR(&cmd->tlv_header, 1910 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1911 WMITLV_GET_STRUCT_TLVLEN 1912 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1913 cmd->pdev_id = mac_id; 1914 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1915 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1916 if (ret) { 1917 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1918 wmi_buf_free(buf); 1919 } 1920 1921 return ret; 1922 } 1923 #else 1924 /** 1925 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1926 * packet-log 1927 * @param wmi_handle : handle to WMI. 1928 * @param macaddr : MAC address 1929 * @param param : pointer to hold stats request parameter 1930 * 1931 * Return: 0 on success and -ve on failure. 1932 */ 1933 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1934 uint8_t macaddr[IEEE80211_ADDR_LEN], 1935 struct packet_enable_params *param) 1936 { 1937 return 0; 1938 } 1939 /** 1940 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1941 * packet-log 1942 * @param wmi_handle : handle to WMI. 1943 * @mac_id: mac id to have radio context 1944 * 1945 * Return: 0 on success and -ve on failure. 1946 */ 1947 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1948 uint8_t mac_id) 1949 { 1950 return 0; 1951 } 1952 #endif 1953 1954 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 1955 /** 1956 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 1957 * sync time between bwtween host and firmware 1958 * @param wmi_handle : handle to WMI. 1959 * 1960 * Return: None 1961 */ 1962 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 1963 { 1964 wmi_buf_t buf; 1965 QDF_STATUS status = QDF_STATUS_SUCCESS; 1966 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 1967 int32_t len; 1968 qdf_time_t time_ms; 1969 1970 len = sizeof(*time_stamp); 1971 buf = wmi_buf_alloc(wmi_handle, len); 1972 1973 if (!buf) { 1974 WMI_LOGP(FL("wmi_buf_alloc failed")); 1975 return; 1976 } 1977 time_stamp = 1978 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 1979 (wmi_buf_data(buf)); 1980 WMITLV_SET_HDR(&time_stamp->tlv_header, 1981 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 1982 WMITLV_GET_STRUCT_TLVLEN( 1983 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 1984 1985 time_ms = qdf_get_time_of_the_day_ms(); 1986 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 1987 time_stamp->time_stamp_low = time_ms & 1988 WMI_FW_TIME_STAMP_LOW_MASK; 1989 /* 1990 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 1991 * wont exceed 27 bit 1992 */ 1993 time_stamp->time_stamp_high = 0; 1994 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 1995 time_stamp->mode, time_stamp->time_stamp_low, 1996 time_stamp->time_stamp_high); 1997 1998 status = wmi_unified_cmd_send(wmi_handle, buf, 1999 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2000 if (status) { 2001 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2002 wmi_buf_free(buf); 2003 } 2004 2005 } 2006 2007 #ifdef WLAN_SUPPORT_FILS 2008 /** 2009 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 2010 * @wmi_handle: wmi handle 2011 * @evt_buf: pointer to event buffer 2012 * @vdev_id: pointer to hold vdev id 2013 * 2014 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 2015 */ 2016 static QDF_STATUS 2017 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 2018 void *evt_buf, uint32_t *vdev_id) 2019 { 2020 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 2021 wmi_host_swfda_event_fixed_param *swfda_event; 2022 2023 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 2024 if (!param_buf) { 2025 WMI_LOGE("Invalid swfda event buffer"); 2026 return QDF_STATUS_E_INVAL; 2027 } 2028 swfda_event = param_buf->fixed_param; 2029 *vdev_id = swfda_event->vdev_id; 2030 2031 return QDF_STATUS_SUCCESS; 2032 } 2033 2034 /** 2035 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 2036 * @wmi_handle: wmi handle 2037 * @param: pointer to hold FILS discovery enable param 2038 * 2039 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 2040 */ 2041 static QDF_STATUS 2042 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 2043 struct config_fils_params *param) 2044 { 2045 wmi_enable_fils_cmd_fixed_param *cmd; 2046 wmi_buf_t buf; 2047 QDF_STATUS status; 2048 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 2049 2050 buf = wmi_buf_alloc(wmi_handle, len); 2051 if (!buf) { 2052 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2053 return QDF_STATUS_E_NOMEM; 2054 } 2055 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 2056 WMITLV_SET_HDR(&cmd->tlv_header, 2057 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 2058 WMITLV_GET_STRUCT_TLVLEN( 2059 wmi_enable_fils_cmd_fixed_param)); 2060 cmd->vdev_id = param->vdev_id; 2061 cmd->fd_period = param->fd_period; 2062 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 2063 param->fd_period, param->vdev_id); 2064 2065 status = wmi_unified_cmd_send(wmi_handle, buf, len, 2066 WMI_ENABLE_FILS_CMDID); 2067 if (status != QDF_STATUS_SUCCESS) { 2068 wmi_buf_free(buf); 2069 return QDF_STATUS_E_FAILURE; 2070 } 2071 2072 return QDF_STATUS_SUCCESS; 2073 } 2074 2075 /** 2076 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 2077 * @wmi_handle: wmi handle 2078 * @param: pointer to hold FD send cmd parameter 2079 * 2080 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 2081 */ 2082 static QDF_STATUS 2083 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 2084 struct fd_params *param) 2085 { 2086 QDF_STATUS ret; 2087 wmi_fd_send_from_host_cmd_fixed_param *cmd; 2088 wmi_buf_t wmi_buf; 2089 qdf_dma_addr_t dma_addr; 2090 2091 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2092 if (!wmi_buf) { 2093 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2094 return QDF_STATUS_E_NOMEM; 2095 } 2096 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2097 WMITLV_SET_HDR(&cmd->tlv_header, 2098 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2099 WMITLV_GET_STRUCT_TLVLEN( 2100 wmi_fd_send_from_host_cmd_fixed_param)); 2101 cmd->vdev_id = param->vdev_id; 2102 cmd->data_len = qdf_nbuf_len(param->wbuf); 2103 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2104 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2105 cmd->frame_ctrl = param->frame_ctrl; 2106 2107 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2108 WMI_PDEV_SEND_FD_CMDID); 2109 if (ret != QDF_STATUS_SUCCESS) { 2110 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2111 __func__, ret); 2112 wmi_buf_free(wmi_buf); 2113 } 2114 2115 return ret; 2116 } 2117 #endif /* WLAN_SUPPORT_FILS */ 2118 2119 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2120 struct beacon_params *param) 2121 { 2122 QDF_STATUS ret; 2123 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2124 wmi_buf_t wmi_buf; 2125 qdf_dma_addr_t dma_addr; 2126 uint32_t dtim_flag = 0; 2127 2128 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2129 if (!wmi_buf) { 2130 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2131 return QDF_STATUS_E_NOMEM; 2132 } 2133 if (param->is_dtim_count_zero) { 2134 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2135 if (param->is_bitctl_reqd) { 2136 /* deliver CAB traffic in next DTIM beacon */ 2137 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2138 } 2139 } 2140 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2141 WMITLV_SET_HDR(&cmd->tlv_header, 2142 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2143 WMITLV_GET_STRUCT_TLVLEN 2144 (wmi_bcn_send_from_host_cmd_fixed_param)); 2145 cmd->vdev_id = param->vdev_id; 2146 cmd->data_len = qdf_nbuf_len(param->wbuf); 2147 cmd->frame_ctrl = param->frame_ctrl; 2148 cmd->dtim_flag = dtim_flag; 2149 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2150 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2151 #if defined(HTT_PADDR64) 2152 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2153 #endif 2154 cmd->bcn_antenna = param->bcn_txant; 2155 2156 ret = wmi_unified_cmd_send(wmi_handle, 2157 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2158 if (ret != QDF_STATUS_SUCCESS) { 2159 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2160 wmi_buf_free(wmi_buf); 2161 } 2162 2163 return ret; 2164 } 2165 2166 /** 2167 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2168 * @param wmi_handle : handle to WMI. 2169 * @param param : pointer to hold beacon send cmd parameter 2170 * 2171 * Return: 0 on success and -ve on failure. 2172 */ 2173 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2174 struct beacon_tmpl_params *param) 2175 { 2176 int32_t ret; 2177 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2178 wmi_bcn_prb_info *bcn_prb_info; 2179 wmi_buf_t wmi_buf; 2180 uint8_t *buf_ptr; 2181 uint32_t wmi_buf_len; 2182 2183 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2184 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2185 param->tmpl_len_aligned; 2186 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2187 if (!wmi_buf) { 2188 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2189 return QDF_STATUS_E_NOMEM; 2190 } 2191 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2192 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2193 WMITLV_SET_HDR(&cmd->tlv_header, 2194 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2195 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2196 cmd->vdev_id = param->vdev_id; 2197 cmd->tim_ie_offset = param->tim_ie_offset; 2198 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2199 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2200 cmd->buf_len = param->tmpl_len; 2201 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2202 2203 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2204 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2205 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2206 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2207 bcn_prb_info->caps = 0; 2208 bcn_prb_info->erp = 0; 2209 buf_ptr += sizeof(wmi_bcn_prb_info); 2210 2211 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2212 buf_ptr += WMI_TLV_HDR_SIZE; 2213 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2214 2215 ret = wmi_unified_cmd_send(wmi_handle, 2216 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2217 if (ret) { 2218 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2219 wmi_buf_free(wmi_buf); 2220 } 2221 2222 return 0; 2223 } 2224 2225 #ifdef CONFIG_MCL 2226 static inline void copy_peer_flags_tlv( 2227 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2228 struct peer_assoc_params *param) 2229 { 2230 cmd->peer_flags = param->peer_flags; 2231 } 2232 #else 2233 static inline void copy_peer_flags_tlv( 2234 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2235 struct peer_assoc_params *param) 2236 { 2237 /* 2238 * The target only needs a subset of the flags maintained in the host. 2239 * Just populate those flags and send it down 2240 */ 2241 cmd->peer_flags = 0; 2242 2243 /* 2244 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2245 */ 2246 if (param->is_wme_set) { 2247 2248 if (param->qos_flag) 2249 cmd->peer_flags |= WMI_PEER_QOS; 2250 if (param->apsd_flag) 2251 cmd->peer_flags |= WMI_PEER_APSD; 2252 if (param->ht_flag) 2253 cmd->peer_flags |= WMI_PEER_HT; 2254 if (param->bw_40) 2255 cmd->peer_flags |= WMI_PEER_40MHZ; 2256 if (param->bw_80) 2257 cmd->peer_flags |= WMI_PEER_80MHZ; 2258 if (param->bw_160) 2259 cmd->peer_flags |= WMI_PEER_160MHZ; 2260 2261 /* Typically if STBC is enabled for VHT it should be enabled 2262 * for HT as well 2263 **/ 2264 if (param->stbc_flag) 2265 cmd->peer_flags |= WMI_PEER_STBC; 2266 2267 /* Typically if LDPC is enabled for VHT it should be enabled 2268 * for HT as well 2269 **/ 2270 if (param->ldpc_flag) 2271 cmd->peer_flags |= WMI_PEER_LDPC; 2272 2273 if (param->static_mimops_flag) 2274 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2275 if (param->dynamic_mimops_flag) 2276 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2277 if (param->spatial_mux_flag) 2278 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2279 if (param->vht_flag) 2280 cmd->peer_flags |= WMI_PEER_VHT; 2281 if (param->he_flag) 2282 cmd->peer_flags |= WMI_PEER_HE; 2283 } 2284 2285 if (param->is_pmf_enabled) 2286 cmd->peer_flags |= WMI_PEER_PMF; 2287 /* 2288 * Suppress authorization for all AUTH modes that need 4-way handshake 2289 * (during re-association). 2290 * Authorization will be done for these modes on key installation. 2291 */ 2292 if (param->auth_flag) 2293 cmd->peer_flags |= WMI_PEER_AUTH; 2294 if (param->need_ptk_4_way) 2295 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2296 else 2297 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2298 if (param->need_gtk_2_way) 2299 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2300 /* safe mode bypass the 4-way handshake */ 2301 if (param->safe_mode_enabled) 2302 cmd->peer_flags &= 2303 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2304 /* Disable AMSDU for station transmit, if user configures it */ 2305 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2306 * it 2307 * if (param->amsdu_disable) Add after FW support 2308 **/ 2309 2310 /* Target asserts if node is marked HT and all MCS is set to 0. 2311 * Mark the node as non-HT if all the mcs rates are disabled through 2312 * iwpriv 2313 **/ 2314 if (param->peer_ht_rates.num_rates == 0) 2315 cmd->peer_flags &= ~WMI_PEER_HT; 2316 2317 if (param->twt_requester) 2318 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2319 2320 if (param->twt_responder) 2321 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2322 } 2323 #endif 2324 2325 #ifdef CONFIG_MCL 2326 static inline void copy_peer_mac_addr_tlv( 2327 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2328 struct peer_assoc_params *param) 2329 { 2330 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2331 sizeof(param->peer_macaddr)); 2332 } 2333 #else 2334 static inline void copy_peer_mac_addr_tlv( 2335 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2336 struct peer_assoc_params *param) 2337 { 2338 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2339 } 2340 #endif 2341 2342 /** 2343 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2344 * @param wmi_handle : handle to WMI. 2345 * @param param : pointer to peer assoc parameter 2346 * 2347 * Return: 0 on success and -ve on failure. 2348 */ 2349 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2350 struct peer_assoc_params *param) 2351 { 2352 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2353 wmi_vht_rate_set *mcs; 2354 wmi_he_rate_set *he_mcs; 2355 wmi_buf_t buf; 2356 int32_t len; 2357 uint8_t *buf_ptr; 2358 QDF_STATUS ret; 2359 uint32_t peer_legacy_rates_align; 2360 uint32_t peer_ht_rates_align; 2361 int32_t i; 2362 2363 2364 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2365 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2366 2367 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2368 (peer_legacy_rates_align * sizeof(uint8_t)) + 2369 WMI_TLV_HDR_SIZE + 2370 (peer_ht_rates_align * sizeof(uint8_t)) + 2371 sizeof(wmi_vht_rate_set) + 2372 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2373 + WMI_TLV_HDR_SIZE); 2374 2375 buf = wmi_buf_alloc(wmi_handle, len); 2376 if (!buf) { 2377 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2378 return QDF_STATUS_E_NOMEM; 2379 } 2380 2381 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2382 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2383 WMITLV_SET_HDR(&cmd->tlv_header, 2384 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2385 WMITLV_GET_STRUCT_TLVLEN 2386 (wmi_peer_assoc_complete_cmd_fixed_param)); 2387 2388 cmd->vdev_id = param->vdev_id; 2389 2390 cmd->peer_new_assoc = param->peer_new_assoc; 2391 cmd->peer_associd = param->peer_associd; 2392 2393 copy_peer_flags_tlv(cmd, param); 2394 copy_peer_mac_addr_tlv(cmd, param); 2395 2396 cmd->peer_rate_caps = param->peer_rate_caps; 2397 cmd->peer_caps = param->peer_caps; 2398 cmd->peer_listen_intval = param->peer_listen_intval; 2399 cmd->peer_ht_caps = param->peer_ht_caps; 2400 cmd->peer_max_mpdu = param->peer_max_mpdu; 2401 cmd->peer_mpdu_density = param->peer_mpdu_density; 2402 cmd->peer_vht_caps = param->peer_vht_caps; 2403 cmd->peer_phymode = param->peer_phymode; 2404 2405 /* Update 11ax capabilities */ 2406 cmd->peer_he_cap_info = param->peer_he_cap_macinfo; 2407 cmd->peer_he_ops = param->peer_he_ops; 2408 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2409 sizeof(param->peer_he_cap_phyinfo)); 2410 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2411 sizeof(param->peer_ppet)); 2412 2413 /* Update peer legacy rate information */ 2414 buf_ptr += sizeof(*cmd); 2415 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2416 peer_legacy_rates_align); 2417 buf_ptr += WMI_TLV_HDR_SIZE; 2418 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2419 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2420 param->peer_legacy_rates.num_rates); 2421 2422 /* Update peer HT rate information */ 2423 buf_ptr += peer_legacy_rates_align; 2424 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2425 peer_ht_rates_align); 2426 buf_ptr += WMI_TLV_HDR_SIZE; 2427 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2428 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2429 param->peer_ht_rates.num_rates); 2430 2431 /* VHT Rates */ 2432 buf_ptr += peer_ht_rates_align; 2433 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2434 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2435 2436 cmd->peer_nss = param->peer_nss; 2437 2438 /* Update bandwidth-NSS mapping */ 2439 cmd->peer_bw_rxnss_override = 0; 2440 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2441 2442 mcs = (wmi_vht_rate_set *) buf_ptr; 2443 if (param->vht_capable) { 2444 mcs->rx_max_rate = param->rx_max_rate; 2445 mcs->rx_mcs_set = param->rx_mcs_set; 2446 mcs->tx_max_rate = param->tx_max_rate; 2447 mcs->tx_mcs_set = param->tx_mcs_set; 2448 } 2449 2450 /* HE Rates */ 2451 cmd->peer_he_mcs = param->peer_he_mcs_count; 2452 buf_ptr += sizeof(wmi_vht_rate_set); 2453 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2454 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2455 buf_ptr += WMI_TLV_HDR_SIZE; 2456 2457 /* Loop through the HE rate set */ 2458 for (i = 0; i < param->peer_he_mcs_count; i++) { 2459 he_mcs = (wmi_he_rate_set *) buf_ptr; 2460 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2461 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2462 2463 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2464 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2465 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2466 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2467 buf_ptr += sizeof(wmi_he_rate_set); 2468 } 2469 2470 2471 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2472 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2473 "nss %d phymode %d peer_mpdu_density %d " 2474 "cmd->peer_vht_caps %x " 2475 "HE cap_info %x ops %x " 2476 "HE phy %x %x %x " 2477 "peer_bw_rxnss_override %x", __func__, 2478 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2479 cmd->peer_rate_caps, cmd->peer_caps, 2480 cmd->peer_listen_intval, cmd->peer_ht_caps, 2481 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2482 cmd->peer_mpdu_density, 2483 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2484 cmd->peer_he_ops, cmd->peer_he_cap_phy[0], 2485 cmd->peer_he_cap_phy[1], cmd->peer_he_cap_phy[2], 2486 cmd->peer_bw_rxnss_override); 2487 2488 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2489 WMI_PEER_ASSOC_CMDID); 2490 if (QDF_IS_STATUS_ERROR(ret)) { 2491 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2492 __func__, ret); 2493 wmi_buf_free(buf); 2494 } 2495 2496 return ret; 2497 } 2498 2499 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2500 */ 2501 static inline void copy_scan_event_cntrl_flags( 2502 wmi_start_scan_cmd_fixed_param * cmd, 2503 struct scan_req_params *param) 2504 { 2505 2506 /* Scan events subscription */ 2507 if (param->scan_ev_started) 2508 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2509 if (param->scan_ev_completed) 2510 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2511 if (param->scan_ev_bss_chan) 2512 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2513 if (param->scan_ev_foreign_chan) 2514 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2515 if (param->scan_ev_dequeued) 2516 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2517 if (param->scan_ev_preempted) 2518 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2519 if (param->scan_ev_start_failed) 2520 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2521 if (param->scan_ev_restarted) 2522 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2523 if (param->scan_ev_foreign_chn_exit) 2524 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2525 if (param->scan_ev_suspended) 2526 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2527 if (param->scan_ev_resumed) 2528 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2529 2530 /** Set scan control flags */ 2531 cmd->scan_ctrl_flags = 0; 2532 if (param->scan_f_passive) 2533 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2534 if (param->scan_f_strict_passive_pch) 2535 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2536 if (param->scan_f_promisc_mode) 2537 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2538 if (param->scan_f_capture_phy_err) 2539 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2540 if (param->scan_f_half_rate) 2541 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2542 if (param->scan_f_quarter_rate) 2543 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2544 if (param->scan_f_cck_rates) 2545 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2546 if (param->scan_f_ofdm_rates) 2547 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2548 if (param->scan_f_chan_stat_evnt) 2549 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2550 if (param->scan_f_filter_prb_req) 2551 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2552 if (param->scan_f_bcast_probe) 2553 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2554 if (param->scan_f_offchan_mgmt_tx) 2555 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2556 if (param->scan_f_offchan_data_tx) 2557 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2558 if (param->scan_f_force_active_dfs_chn) 2559 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2560 if (param->scan_f_add_tpc_ie_in_probe) 2561 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2562 if (param->scan_f_add_ds_ie_in_probe) 2563 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2564 if (param->scan_f_add_spoofed_mac_in_probe) 2565 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2566 if (param->scan_f_add_rand_seq_in_probe) 2567 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2568 if (param->scan_f_en_ie_whitelist_in_probe) 2569 cmd->scan_ctrl_flags |= 2570 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2571 2572 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2573 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2574 param->adaptive_dwell_time_mode); 2575 } 2576 2577 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2578 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2579 struct scan_req_params *params) 2580 { 2581 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2582 } 2583 2584 /** 2585 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2586 * @mac: random mac addr 2587 * @mask: random mac mask 2588 * @mac_addr: wmi random mac 2589 * @mac_mask: wmi random mac mask 2590 * 2591 * Return None. 2592 */ 2593 static inline 2594 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2595 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2596 { 2597 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2598 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2599 } 2600 2601 /* 2602 * wmi_fill_vendor_oui() - fill vendor OUIs 2603 * @buf_ptr: pointer to wmi tlv buffer 2604 * @num_vendor_oui: number of vendor OUIs to be filled 2605 * @param_voui: pointer to OUI buffer 2606 * 2607 * This function populates the wmi tlv buffer when vendor specific OUIs are 2608 * present. 2609 * 2610 * Return: None 2611 */ 2612 static inline 2613 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2614 uint32_t *pvoui) 2615 { 2616 wmi_vendor_oui *voui = NULL; 2617 uint32_t i; 2618 2619 voui = (wmi_vendor_oui *)buf_ptr; 2620 2621 for (i = 0; i < num_vendor_oui; i++) { 2622 WMITLV_SET_HDR(&voui[i].tlv_header, 2623 WMITLV_TAG_STRUC_wmi_vendor_oui, 2624 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2625 voui[i].oui_type_subtype = pvoui[i]; 2626 } 2627 } 2628 2629 /* 2630 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2631 * @ie_bitmap: output pointer to ie bit map in cmd 2632 * @num_vendor_oui: output pointer to num vendor OUIs 2633 * @ie_whitelist: input parameter 2634 * 2635 * This function populates the IE whitelist attrs of scan, pno and 2636 * scan oui commands for ie_whitelist parameter. 2637 * 2638 * Return: None 2639 */ 2640 static inline 2641 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2642 uint32_t *num_vendor_oui, 2643 struct probe_req_whitelist_attr *ie_whitelist) 2644 { 2645 uint32_t i = 0; 2646 2647 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2648 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2649 2650 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2651 } 2652 2653 /** 2654 * send_scan_start_cmd_tlv() - WMI scan start function 2655 * @param wmi_handle : handle to WMI. 2656 * @param param : pointer to hold scan start cmd parameter 2657 * 2658 * Return: 0 on success and -ve on failure. 2659 */ 2660 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2661 struct scan_req_params *params) 2662 { 2663 int32_t ret = 0; 2664 int32_t i; 2665 wmi_buf_t wmi_buf; 2666 wmi_start_scan_cmd_fixed_param *cmd; 2667 uint8_t *buf_ptr; 2668 uint32_t *tmp_ptr; 2669 wmi_ssid *ssid = NULL; 2670 wmi_mac_addr *bssid; 2671 int len = sizeof(*cmd); 2672 uint8_t extraie_len_with_pad = 0; 2673 uint8_t phymode_roundup = 0; 2674 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2675 2676 /* Length TLV placeholder for array of uint32_t */ 2677 len += WMI_TLV_HDR_SIZE; 2678 /* calculate the length of buffer required */ 2679 if (params->chan_list.num_chan) 2680 len += params->chan_list.num_chan * sizeof(uint32_t); 2681 2682 /* Length TLV placeholder for array of wmi_ssid structures */ 2683 len += WMI_TLV_HDR_SIZE; 2684 if (params->num_ssids) 2685 len += params->num_ssids * sizeof(wmi_ssid); 2686 2687 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2688 len += WMI_TLV_HDR_SIZE; 2689 if (params->num_bssid) 2690 len += sizeof(wmi_mac_addr) * params->num_bssid; 2691 2692 /* Length TLV placeholder for array of bytes */ 2693 len += WMI_TLV_HDR_SIZE; 2694 if (params->extraie.len) 2695 extraie_len_with_pad = 2696 roundup(params->extraie.len, sizeof(uint32_t)); 2697 len += extraie_len_with_pad; 2698 2699 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2700 if (ie_whitelist->num_vendor_oui) 2701 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2702 2703 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2704 if (params->scan_f_wide_band) 2705 phymode_roundup = 2706 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2707 sizeof(uint32_t)); 2708 len += phymode_roundup; 2709 2710 /* Allocate the memory */ 2711 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2712 if (!wmi_buf) { 2713 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2714 __func__); 2715 return QDF_STATUS_E_FAILURE; 2716 } 2717 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2718 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2719 WMITLV_SET_HDR(&cmd->tlv_header, 2720 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2721 WMITLV_GET_STRUCT_TLVLEN 2722 (wmi_start_scan_cmd_fixed_param)); 2723 2724 cmd->scan_id = params->scan_id; 2725 cmd->scan_req_id = params->scan_req_id; 2726 cmd->vdev_id = params->vdev_id; 2727 cmd->scan_priority = params->scan_priority; 2728 2729 copy_scan_event_cntrl_flags(cmd, params); 2730 2731 cmd->dwell_time_active = params->dwell_time_active; 2732 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2733 cmd->dwell_time_passive = params->dwell_time_passive; 2734 cmd->min_rest_time = params->min_rest_time; 2735 cmd->max_rest_time = params->max_rest_time; 2736 cmd->repeat_probe_time = params->repeat_probe_time; 2737 cmd->probe_spacing_time = params->probe_spacing_time; 2738 cmd->idle_time = params->idle_time; 2739 cmd->max_scan_time = params->max_scan_time; 2740 cmd->probe_delay = params->probe_delay; 2741 cmd->burst_duration = params->burst_duration; 2742 cmd->num_chan = params->chan_list.num_chan; 2743 cmd->num_bssid = params->num_bssid; 2744 cmd->num_ssids = params->num_ssids; 2745 cmd->ie_len = params->extraie.len; 2746 cmd->n_probes = params->n_probes; 2747 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2748 2749 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2750 2751 if (params->scan_random.randomize) 2752 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2753 params->scan_random.mac_mask, 2754 &cmd->mac_addr, 2755 &cmd->mac_mask); 2756 2757 if (ie_whitelist->white_list) 2758 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2759 &cmd->num_vendor_oui, 2760 ie_whitelist); 2761 2762 buf_ptr += sizeof(*cmd); 2763 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2764 for (i = 0; i < params->chan_list.num_chan; ++i) 2765 tmp_ptr[i] = params->chan_list.chan[i].freq; 2766 2767 WMITLV_SET_HDR(buf_ptr, 2768 WMITLV_TAG_ARRAY_UINT32, 2769 (params->chan_list.num_chan * sizeof(uint32_t))); 2770 buf_ptr += WMI_TLV_HDR_SIZE + 2771 (params->chan_list.num_chan * sizeof(uint32_t)); 2772 2773 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2774 WMI_LOGE("Invalid value for numSsid"); 2775 goto error; 2776 } 2777 2778 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2779 (params->num_ssids * sizeof(wmi_ssid))); 2780 2781 if (params->num_ssids) { 2782 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2783 for (i = 0; i < params->num_ssids; ++i) { 2784 ssid->ssid_len = params->ssid[i].length; 2785 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2786 params->ssid[i].length); 2787 ssid++; 2788 } 2789 } 2790 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2791 2792 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2793 (params->num_bssid * sizeof(wmi_mac_addr))); 2794 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2795 2796 if (params->num_bssid) { 2797 for (i = 0; i < params->num_bssid; ++i) { 2798 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2799 ¶ms->bssid_list[i].bytes[0], bssid); 2800 bssid++; 2801 } 2802 } 2803 2804 buf_ptr += WMI_TLV_HDR_SIZE + 2805 (params->num_bssid * sizeof(wmi_mac_addr)); 2806 2807 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2808 if (params->extraie.len) 2809 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2810 params); 2811 2812 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2813 2814 /* probe req ie whitelisting */ 2815 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2816 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2817 2818 buf_ptr += WMI_TLV_HDR_SIZE; 2819 2820 if (cmd->num_vendor_oui) { 2821 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2822 ie_whitelist->voui); 2823 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2824 } 2825 2826 /* Add phy mode TLV if it's a wide band scan */ 2827 if (params->scan_f_wide_band) { 2828 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2829 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2830 for (i = 0; i < params->chan_list.num_chan; ++i) 2831 buf_ptr[i] = 2832 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2833 buf_ptr += phymode_roundup; 2834 } else { 2835 /* Add ZERO legth phy mode TLV */ 2836 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2837 } 2838 2839 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2840 len, WMI_START_SCAN_CMDID); 2841 if (ret) { 2842 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2843 wmi_buf_free(wmi_buf); 2844 } 2845 return ret; 2846 error: 2847 wmi_buf_free(wmi_buf); 2848 return QDF_STATUS_E_FAILURE; 2849 } 2850 2851 /** 2852 * send_scan_stop_cmd_tlv() - WMI scan start function 2853 * @param wmi_handle : handle to WMI. 2854 * @param param : pointer to hold scan cancel cmd parameter 2855 * 2856 * Return: 0 on success and -ve on failure. 2857 */ 2858 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2859 struct scan_cancel_param *param) 2860 { 2861 wmi_stop_scan_cmd_fixed_param *cmd; 2862 int ret; 2863 int len = sizeof(*cmd); 2864 wmi_buf_t wmi_buf; 2865 2866 /* Allocate the memory */ 2867 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2868 if (!wmi_buf) { 2869 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2870 __func__); 2871 ret = QDF_STATUS_E_NOMEM; 2872 goto error; 2873 } 2874 2875 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2876 WMITLV_SET_HDR(&cmd->tlv_header, 2877 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2878 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2879 cmd->vdev_id = param->vdev_id; 2880 cmd->requestor = param->requester; 2881 cmd->scan_id = param->scan_id; 2882 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2883 param->pdev_id); 2884 /* stop the scan with the corresponding scan_id */ 2885 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2886 /* Cancelling all scans */ 2887 cmd->req_type = WMI_SCAN_STOP_ALL; 2888 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2889 /* Cancelling VAP scans */ 2890 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2891 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2892 /* Cancelling specific scan */ 2893 cmd->req_type = WMI_SCAN_STOP_ONE; 2894 } else { 2895 WMI_LOGE("%s: Invalid Command : ", __func__); 2896 wmi_buf_free(wmi_buf); 2897 return QDF_STATUS_E_INVAL; 2898 } 2899 2900 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2901 len, WMI_STOP_SCAN_CMDID); 2902 if (ret) { 2903 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2904 wmi_buf_free(wmi_buf); 2905 } 2906 2907 error: 2908 return ret; 2909 } 2910 2911 #ifdef CONFIG_MCL 2912 /** 2913 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2914 * @param wmi_handle : handle to WMI. 2915 * @param param : pointer to hold scan channel list parameter 2916 * 2917 * Return: 0 on success and -ve on failure. 2918 */ 2919 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2920 struct scan_chan_list_params *chan_list) 2921 { 2922 wmi_buf_t buf; 2923 QDF_STATUS qdf_status; 2924 wmi_scan_chan_list_cmd_fixed_param *cmd; 2925 int i; 2926 uint8_t *buf_ptr; 2927 wmi_channel_param *chan_info, *tchan_info; 2928 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 2929 2930 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 2931 buf = wmi_buf_alloc(wmi_handle, len); 2932 if (!buf) { 2933 WMI_LOGE("Failed to allocate memory"); 2934 qdf_status = QDF_STATUS_E_NOMEM; 2935 goto end; 2936 } 2937 2938 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2939 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 2940 WMITLV_SET_HDR(&cmd->tlv_header, 2941 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 2942 WMITLV_GET_STRUCT_TLVLEN 2943 (wmi_scan_chan_list_cmd_fixed_param)); 2944 2945 WMI_LOGD("no of channels = %d, len = %d", chan_list->num_scan_chans, len); 2946 2947 cmd->num_scan_chans = chan_list->num_scan_chans; 2948 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 2949 WMITLV_TAG_ARRAY_STRUC, 2950 sizeof(wmi_channel) * chan_list->num_scan_chans); 2951 chan_info = (wmi_channel_param *) 2952 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 2953 tchan_info = chan_list->chan_info; 2954 2955 for (i = 0; i < chan_list->num_scan_chans; ++i) { 2956 WMITLV_SET_HDR(&chan_info->tlv_header, 2957 WMITLV_TAG_STRUC_wmi_channel, 2958 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 2959 chan_info->mhz = tchan_info->mhz; 2960 chan_info->band_center_freq1 = 2961 tchan_info->band_center_freq1; 2962 chan_info->band_center_freq2 = 2963 tchan_info->band_center_freq2; 2964 chan_info->info = tchan_info->info; 2965 chan_info->reg_info_1 = tchan_info->reg_info_1; 2966 chan_info->reg_info_2 = tchan_info->reg_info_2; 2967 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 2968 2969 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 2970 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 2971 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 2972 tchan_info++; 2973 chan_info++; 2974 } 2975 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2976 chan_list->pdev_id); 2977 2978 qdf_status = wmi_unified_cmd_send(wmi_handle, 2979 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 2980 2981 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2982 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 2983 wmi_buf_free(buf); 2984 } 2985 2986 end: 2987 return qdf_status; 2988 } 2989 #else 2990 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2991 struct scan_chan_list_params *chan_list) 2992 { 2993 wmi_buf_t buf; 2994 QDF_STATUS qdf_status; 2995 wmi_scan_chan_list_cmd_fixed_param *cmd; 2996 int i; 2997 uint8_t *buf_ptr; 2998 wmi_channel *chan_info; 2999 struct channel_param *tchan_info; 3000 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3001 3002 len += sizeof(wmi_channel) * chan_list->nallchans; 3003 buf = wmi_buf_alloc(wmi_handle, len); 3004 if (!buf) { 3005 WMI_LOGE("Failed to allocate memory"); 3006 qdf_status = QDF_STATUS_E_NOMEM; 3007 goto end; 3008 } 3009 3010 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3011 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 3012 WMITLV_SET_HDR(&cmd->tlv_header, 3013 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3014 WMITLV_GET_STRUCT_TLVLEN 3015 (wmi_scan_chan_list_cmd_fixed_param)); 3016 3017 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 3018 3019 if (chan_list->append) 3020 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3021 3022 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3023 chan_list->pdev_id); 3024 cmd->num_scan_chans = chan_list->nallchans; 3025 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3026 WMITLV_TAG_ARRAY_STRUC, 3027 sizeof(wmi_channel) * chan_list->nallchans); 3028 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 3029 tchan_info = &(chan_list->ch_param[0]); 3030 3031 for (i = 0; i < chan_list->nallchans; ++i) { 3032 WMITLV_SET_HDR(&chan_info->tlv_header, 3033 WMITLV_TAG_STRUC_wmi_channel, 3034 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3035 chan_info->mhz = tchan_info->mhz; 3036 chan_info->band_center_freq1 = 3037 tchan_info->cfreq1; 3038 chan_info->band_center_freq2 = 3039 tchan_info->cfreq2; 3040 3041 if (tchan_info->is_chan_passive) 3042 WMI_SET_CHANNEL_FLAG(chan_info, 3043 WMI_CHAN_FLAG_PASSIVE); 3044 3045 if (tchan_info->allow_vht) 3046 WMI_SET_CHANNEL_FLAG(chan_info, 3047 WMI_CHAN_FLAG_ALLOW_VHT); 3048 else if (tchan_info->allow_ht) 3049 WMI_SET_CHANNEL_FLAG(chan_info, 3050 WMI_CHAN_FLAG_ALLOW_HT); 3051 WMI_SET_CHANNEL_MODE(chan_info, 3052 tchan_info->phy_mode); 3053 3054 if (tchan_info->half_rate) 3055 WMI_SET_CHANNEL_FLAG(chan_info, 3056 WMI_CHAN_FLAG_HALF_RATE); 3057 3058 if (tchan_info->quarter_rate) 3059 WMI_SET_CHANNEL_FLAG(chan_info, 3060 WMI_CHAN_FLAG_QUARTER_RATE); 3061 3062 /* also fill in power information */ 3063 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3064 tchan_info->minpower); 3065 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3066 tchan_info->maxpower); 3067 WMI_SET_CHANNEL_REG_POWER(chan_info, 3068 tchan_info->maxregpower); 3069 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3070 tchan_info->antennamax); 3071 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3072 tchan_info->reg_class_id); 3073 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3074 tchan_info->maxregpower); 3075 3076 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 3077 3078 tchan_info++; 3079 chan_info++; 3080 } 3081 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3082 chan_list->pdev_id); 3083 3084 qdf_status = wmi_unified_cmd_send( 3085 wmi_handle, 3086 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3087 3088 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3089 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3090 wmi_buf_free(buf); 3091 } 3092 3093 end: 3094 return qdf_status; 3095 } 3096 #endif 3097 3098 /** 3099 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3100 * 3101 * @bufp: Pointer to buffer 3102 * @param: Pointer to tx param 3103 * 3104 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3105 */ 3106 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3107 struct tx_send_params param) 3108 { 3109 wmi_tx_send_params *tx_param; 3110 QDF_STATUS status = QDF_STATUS_SUCCESS; 3111 3112 if (!bufp) { 3113 status = QDF_STATUS_E_FAILURE; 3114 return status; 3115 } 3116 tx_param = (wmi_tx_send_params *)bufp; 3117 WMITLV_SET_HDR(&tx_param->tlv_header, 3118 WMITLV_TAG_STRUC_wmi_tx_send_params, 3119 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3120 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3121 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3122 param.mcs_mask); 3123 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3124 param.nss_mask); 3125 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3126 param.retry_limit); 3127 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3128 param.chain_mask); 3129 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3130 param.bw_mask); 3131 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3132 param.preamble_type); 3133 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3134 param.frame_type); 3135 3136 return status; 3137 } 3138 3139 #ifdef CONFIG_HL_SUPPORT 3140 /** 3141 * send_mgmt_cmd_tlv() - WMI scan start function 3142 * @wmi_handle : handle to WMI. 3143 * @param : pointer to hold mgmt cmd parameter 3144 * 3145 * Return: 0 on success and -ve on failure. 3146 */ 3147 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3148 struct wmi_mgmt_params *param) 3149 { 3150 wmi_buf_t buf; 3151 uint8_t *bufp; 3152 int32_t cmd_len; 3153 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3154 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3155 mgmt_tx_dl_frm_len; 3156 3157 if (param->frm_len > mgmt_tx_dl_frm_len) { 3158 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 3159 __func__, param->frm_len, mgmt_tx_dl_frm_len); 3160 return QDF_STATUS_E_INVAL; 3161 } 3162 3163 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3164 WMI_TLV_HDR_SIZE + 3165 roundup(bufp_len, sizeof(uint32_t)); 3166 3167 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3168 if (!buf) { 3169 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3170 return QDF_STATUS_E_NOMEM; 3171 } 3172 3173 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3174 bufp = (uint8_t *) cmd; 3175 WMITLV_SET_HDR(&cmd->tlv_header, 3176 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3177 WMITLV_GET_STRUCT_TLVLEN 3178 (wmi_mgmt_tx_send_cmd_fixed_param)); 3179 3180 cmd->vdev_id = param->vdev_id; 3181 3182 cmd->desc_id = param->desc_id; 3183 cmd->chanfreq = param->chanfreq; 3184 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3185 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3186 sizeof(uint32_t))); 3187 bufp += WMI_TLV_HDR_SIZE; 3188 qdf_mem_copy(bufp, param->pdata, bufp_len); 3189 3190 cmd->frame_len = param->frm_len; 3191 cmd->buf_len = bufp_len; 3192 cmd->tx_params_valid = param->tx_params_valid; 3193 3194 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3195 bufp, cmd->vdev_id, cmd->chanfreq); 3196 3197 bufp += roundup(bufp_len, sizeof(uint32_t)); 3198 if (param->tx_params_valid) { 3199 if (populate_tx_send_params(bufp, param->tx_param) != 3200 QDF_STATUS_SUCCESS) { 3201 WMI_LOGE("%s: Populate TX send params failed", 3202 __func__); 3203 goto free_buf; 3204 } 3205 cmd_len += sizeof(wmi_tx_send_params); 3206 } 3207 3208 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3209 WMI_MGMT_TX_SEND_CMDID)) { 3210 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3211 goto free_buf; 3212 } 3213 return QDF_STATUS_SUCCESS; 3214 3215 free_buf: 3216 wmi_buf_free(buf); 3217 return QDF_STATUS_E_FAILURE; 3218 } 3219 #else 3220 /** 3221 * send_mgmt_cmd_tlv() - WMI scan start function 3222 * @wmi_handle : handle to WMI. 3223 * @param : pointer to hold mgmt cmd parameter 3224 * 3225 * Return: 0 on success and -ve on failure. 3226 */ 3227 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3228 struct wmi_mgmt_params *param) 3229 { 3230 wmi_buf_t buf; 3231 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3232 int32_t cmd_len; 3233 uint64_t dma_addr; 3234 void *qdf_ctx = param->qdf_ctx; 3235 uint8_t *bufp; 3236 QDF_STATUS status = QDF_STATUS_SUCCESS; 3237 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3238 mgmt_tx_dl_frm_len; 3239 3240 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3241 WMI_TLV_HDR_SIZE + 3242 roundup(bufp_len, sizeof(uint32_t)); 3243 3244 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3245 if (!buf) { 3246 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3247 return QDF_STATUS_E_NOMEM; 3248 } 3249 3250 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3251 bufp = (uint8_t *) cmd; 3252 WMITLV_SET_HDR(&cmd->tlv_header, 3253 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3254 WMITLV_GET_STRUCT_TLVLEN 3255 (wmi_mgmt_tx_send_cmd_fixed_param)); 3256 3257 cmd->vdev_id = param->vdev_id; 3258 3259 cmd->desc_id = param->desc_id; 3260 cmd->chanfreq = param->chanfreq; 3261 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3262 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3263 sizeof(uint32_t))); 3264 bufp += WMI_TLV_HDR_SIZE; 3265 qdf_mem_copy(bufp, param->pdata, bufp_len); 3266 3267 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3268 QDF_DMA_TO_DEVICE); 3269 if (status != QDF_STATUS_SUCCESS) { 3270 WMI_LOGE("%s: wmi buf map failed", __func__); 3271 goto free_buf; 3272 } 3273 3274 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3275 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3276 #if defined(HTT_PADDR64) 3277 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3278 #endif 3279 cmd->frame_len = param->frm_len; 3280 cmd->buf_len = bufp_len; 3281 cmd->tx_params_valid = param->tx_params_valid; 3282 3283 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3284 bufp, cmd->vdev_id, cmd->chanfreq); 3285 3286 bufp += roundup(bufp_len, sizeof(uint32_t)); 3287 if (param->tx_params_valid) { 3288 status = populate_tx_send_params(bufp, param->tx_param); 3289 if (status != QDF_STATUS_SUCCESS) { 3290 WMI_LOGE("%s: Populate TX send params failed", 3291 __func__); 3292 goto unmap_tx_frame; 3293 } 3294 cmd_len += sizeof(wmi_tx_send_params); 3295 } 3296 3297 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3298 WMI_MGMT_TX_SEND_CMDID)) { 3299 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3300 goto unmap_tx_frame; 3301 } 3302 return QDF_STATUS_SUCCESS; 3303 3304 unmap_tx_frame: 3305 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3306 QDF_DMA_TO_DEVICE); 3307 free_buf: 3308 wmi_buf_free(buf); 3309 return QDF_STATUS_E_FAILURE; 3310 } 3311 #endif /* CONFIG_HL_SUPPORT */ 3312 3313 /** 3314 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3315 * @wmi_handle : handle to WMI. 3316 * @param : pointer to offchan data tx cmd parameter 3317 * 3318 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3319 */ 3320 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3321 struct wmi_offchan_data_tx_params *param) 3322 { 3323 wmi_buf_t buf; 3324 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3325 int32_t cmd_len; 3326 uint64_t dma_addr; 3327 void *qdf_ctx = param->qdf_ctx; 3328 uint8_t *bufp; 3329 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3330 param->frm_len : mgmt_tx_dl_frm_len; 3331 QDF_STATUS status = QDF_STATUS_SUCCESS; 3332 3333 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3334 WMI_TLV_HDR_SIZE + 3335 roundup(bufp_len, sizeof(uint32_t)); 3336 3337 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3338 if (!buf) { 3339 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3340 return QDF_STATUS_E_NOMEM; 3341 } 3342 3343 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3344 bufp = (uint8_t *) cmd; 3345 WMITLV_SET_HDR(&cmd->tlv_header, 3346 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3347 WMITLV_GET_STRUCT_TLVLEN 3348 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3349 3350 cmd->vdev_id = param->vdev_id; 3351 3352 cmd->desc_id = param->desc_id; 3353 cmd->chanfreq = param->chanfreq; 3354 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3355 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3356 sizeof(uint32_t))); 3357 bufp += WMI_TLV_HDR_SIZE; 3358 qdf_mem_copy(bufp, param->pdata, bufp_len); 3359 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3360 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3361 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3362 #if defined(HTT_PADDR64) 3363 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3364 #endif 3365 cmd->frame_len = param->frm_len; 3366 cmd->buf_len = bufp_len; 3367 cmd->tx_params_valid = param->tx_params_valid; 3368 3369 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3370 bufp, cmd->vdev_id, cmd->chanfreq); 3371 3372 bufp += roundup(bufp_len, sizeof(uint32_t)); 3373 if (param->tx_params_valid) { 3374 status = populate_tx_send_params(bufp, param->tx_param); 3375 if (status != QDF_STATUS_SUCCESS) { 3376 WMI_LOGE("%s: Populate TX send params failed", 3377 __func__); 3378 goto err1; 3379 } 3380 cmd_len += sizeof(wmi_tx_send_params); 3381 } 3382 3383 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3384 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3385 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3386 goto err1; 3387 } 3388 3389 return QDF_STATUS_SUCCESS; 3390 3391 err1: 3392 wmi_buf_free(buf); 3393 return QDF_STATUS_E_FAILURE; 3394 } 3395 3396 /** 3397 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3398 * @wmi_handle: wmi handle 3399 * @param_value: parameter value 3400 * 3401 * Return: QDF_STATUS_SUCCESS for success or error code 3402 */ 3403 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3404 uint32_t param_value) 3405 { 3406 QDF_STATUS ret; 3407 wmi_modem_power_state_cmd_param *cmd; 3408 wmi_buf_t buf; 3409 uint16_t len = sizeof(*cmd); 3410 3411 buf = wmi_buf_alloc(wmi_handle, len); 3412 if (!buf) { 3413 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3414 return QDF_STATUS_E_NOMEM; 3415 } 3416 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3417 WMITLV_SET_HDR(&cmd->tlv_header, 3418 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3419 WMITLV_GET_STRUCT_TLVLEN 3420 (wmi_modem_power_state_cmd_param)); 3421 cmd->modem_power_state = param_value; 3422 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3423 param_value); 3424 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3425 WMI_MODEM_POWER_STATE_CMDID); 3426 if (QDF_IS_STATUS_ERROR(ret)) { 3427 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3428 wmi_buf_free(buf); 3429 } 3430 3431 return ret; 3432 } 3433 3434 /** 3435 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3436 * @wmi_handle: wmi handle 3437 * @vdev_id: vdev id 3438 * @val: value 3439 * 3440 * Return: QDF_STATUS_SUCCESS for success or error code. 3441 */ 3442 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3443 uint32_t vdev_id, uint8_t val) 3444 { 3445 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3446 wmi_buf_t buf; 3447 int32_t len = sizeof(*cmd); 3448 3449 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3450 3451 buf = wmi_buf_alloc(wmi_handle, len); 3452 if (!buf) { 3453 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3454 return QDF_STATUS_E_NOMEM; 3455 } 3456 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3457 WMITLV_SET_HDR(&cmd->tlv_header, 3458 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3459 WMITLV_GET_STRUCT_TLVLEN 3460 (wmi_sta_powersave_mode_cmd_fixed_param)); 3461 cmd->vdev_id = vdev_id; 3462 if (val) 3463 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3464 else 3465 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3466 3467 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3468 WMI_STA_POWERSAVE_MODE_CMDID)) { 3469 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3470 vdev_id, val); 3471 wmi_buf_free(buf); 3472 return QDF_STATUS_E_FAILURE; 3473 } 3474 return 0; 3475 } 3476 3477 /** 3478 * send_set_mimops_cmd_tlv() - set MIMO powersave 3479 * @wmi_handle: wmi handle 3480 * @vdev_id: vdev id 3481 * @value: value 3482 * 3483 * Return: QDF_STATUS_SUCCESS for success or error code. 3484 */ 3485 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3486 uint8_t vdev_id, int value) 3487 { 3488 QDF_STATUS ret; 3489 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3490 wmi_buf_t buf; 3491 uint16_t len = sizeof(*cmd); 3492 3493 buf = wmi_buf_alloc(wmi_handle, len); 3494 if (!buf) { 3495 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3496 return QDF_STATUS_E_NOMEM; 3497 } 3498 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3499 WMITLV_SET_HDR(&cmd->tlv_header, 3500 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3501 WMITLV_GET_STRUCT_TLVLEN 3502 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3503 3504 cmd->vdev_id = vdev_id; 3505 3506 /* WMI_SMPS_FORCED_MODE values do not directly map 3507 * to SM power save values defined in the specification. 3508 * Make sure to send the right mapping. 3509 */ 3510 switch (value) { 3511 case 0: 3512 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3513 break; 3514 case 1: 3515 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3516 break; 3517 case 2: 3518 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3519 break; 3520 case 3: 3521 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3522 break; 3523 default: 3524 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3525 wmi_buf_free(buf); 3526 return QDF_STATUS_E_FAILURE; 3527 } 3528 3529 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3530 3531 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3532 WMI_STA_SMPS_FORCE_MODE_CMDID); 3533 if (QDF_IS_STATUS_ERROR(ret)) { 3534 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3535 wmi_buf_free(buf); 3536 } 3537 3538 return ret; 3539 } 3540 3541 /** 3542 * send_set_smps_params_cmd_tlv() - set smps params 3543 * @wmi_handle: wmi handle 3544 * @vdev_id: vdev id 3545 * @value: value 3546 * 3547 * Return: QDF_STATUS_SUCCESS for success or error code. 3548 */ 3549 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3550 int value) 3551 { 3552 QDF_STATUS ret; 3553 wmi_sta_smps_param_cmd_fixed_param *cmd; 3554 wmi_buf_t buf; 3555 uint16_t len = sizeof(*cmd); 3556 3557 buf = wmi_buf_alloc(wmi_handle, len); 3558 if (!buf) { 3559 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3560 return QDF_STATUS_E_NOMEM; 3561 } 3562 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3563 WMITLV_SET_HDR(&cmd->tlv_header, 3564 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3565 WMITLV_GET_STRUCT_TLVLEN 3566 (wmi_sta_smps_param_cmd_fixed_param)); 3567 3568 cmd->vdev_id = vdev_id; 3569 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3570 cmd->param = 3571 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3572 3573 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3574 cmd->param); 3575 3576 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3577 WMI_STA_SMPS_PARAM_CMDID); 3578 if (QDF_IS_STATUS_ERROR(ret)) { 3579 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3580 wmi_buf_free(buf); 3581 } 3582 3583 return ret; 3584 } 3585 3586 /** 3587 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3588 * @wmi_handle: wmi handle 3589 * @noa: p2p power save parameters 3590 * 3591 * Return: CDF status 3592 */ 3593 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3594 struct p2p_ps_params *noa) 3595 { 3596 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3597 wmi_p2p_noa_descriptor *noa_discriptor; 3598 wmi_buf_t buf; 3599 uint8_t *buf_ptr; 3600 uint16_t len; 3601 QDF_STATUS status; 3602 uint32_t duration; 3603 3604 WMI_LOGD("%s: Enter", __func__); 3605 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3606 buf = wmi_buf_alloc(wmi_handle, len); 3607 if (!buf) { 3608 WMI_LOGE("Failed to allocate memory"); 3609 status = QDF_STATUS_E_FAILURE; 3610 goto end; 3611 } 3612 3613 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3614 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3615 WMITLV_SET_HDR(&cmd->tlv_header, 3616 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3617 WMITLV_GET_STRUCT_TLVLEN 3618 (wmi_p2p_set_noa_cmd_fixed_param)); 3619 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3620 cmd->vdev_id = noa->session_id; 3621 cmd->enable = (duration) ? true : false; 3622 cmd->num_noa = 1; 3623 3624 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3625 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3626 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3627 sizeof 3628 (wmi_p2p_set_noa_cmd_fixed_param) 3629 + WMI_TLV_HDR_SIZE); 3630 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3631 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3632 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3633 noa_discriptor->type_count = noa->count; 3634 noa_discriptor->duration = duration; 3635 noa_discriptor->interval = noa->interval; 3636 noa_discriptor->start_time = 0; 3637 3638 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3639 cmd->vdev_id, noa->count, noa_discriptor->duration, 3640 noa->interval); 3641 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3642 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3643 if (QDF_IS_STATUS_ERROR(status)) { 3644 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3645 wmi_buf_free(buf); 3646 } 3647 3648 end: 3649 WMI_LOGD("%s: Exit", __func__); 3650 return status; 3651 } 3652 3653 3654 /** 3655 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3656 * @wmi_handle: wmi handle 3657 * @noa: p2p opp power save parameters 3658 * 3659 * Return: CDF status 3660 */ 3661 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3662 struct p2p_ps_params *oppps) 3663 { 3664 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3665 wmi_buf_t buf; 3666 QDF_STATUS status; 3667 3668 WMI_LOGD("%s: Enter", __func__); 3669 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3670 if (!buf) { 3671 WMI_LOGE("Failed to allocate memory"); 3672 status = QDF_STATUS_E_FAILURE; 3673 goto end; 3674 } 3675 3676 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3677 WMITLV_SET_HDR(&cmd->tlv_header, 3678 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3679 WMITLV_GET_STRUCT_TLVLEN 3680 (wmi_p2p_set_oppps_cmd_fixed_param)); 3681 cmd->vdev_id = oppps->session_id; 3682 if (oppps->ctwindow) 3683 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3684 3685 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3686 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3687 cmd->vdev_id, oppps->ctwindow); 3688 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3689 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3690 if (QDF_IS_STATUS_ERROR(status)) { 3691 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3692 wmi_buf_free(buf); 3693 } 3694 3695 end: 3696 WMI_LOGD("%s: Exit", __func__); 3697 return status; 3698 } 3699 3700 #ifdef CONVERGED_P2P_ENABLE 3701 /** 3702 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3703 * @wmi_handle: wmi handle 3704 * @param: p2p listen offload start parameters 3705 * 3706 * Return: QDF status 3707 */ 3708 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3709 struct p2p_lo_start *param) 3710 { 3711 wmi_buf_t buf; 3712 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3713 int32_t len = sizeof(*cmd); 3714 uint8_t *buf_ptr; 3715 QDF_STATUS status; 3716 int device_types_len_aligned; 3717 int probe_resp_len_aligned; 3718 3719 if (!param) { 3720 WMI_LOGE("lo start param is null"); 3721 return QDF_STATUS_E_INVAL; 3722 } 3723 3724 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3725 3726 device_types_len_aligned = 3727 qdf_roundup(param->dev_types_len, 3728 sizeof(uint32_t)); 3729 probe_resp_len_aligned = 3730 qdf_roundup(param->probe_resp_len, 3731 sizeof(uint32_t)); 3732 3733 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3734 probe_resp_len_aligned; 3735 3736 buf = wmi_buf_alloc(wmi_handle, len); 3737 if (!buf) { 3738 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3739 __func__); 3740 return QDF_STATUS_E_NOMEM; 3741 } 3742 3743 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3744 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3745 3746 WMITLV_SET_HDR(&cmd->tlv_header, 3747 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3748 WMITLV_GET_STRUCT_TLVLEN( 3749 wmi_p2p_lo_start_cmd_fixed_param)); 3750 3751 cmd->vdev_id = param->vdev_id; 3752 cmd->ctl_flags = param->ctl_flags; 3753 cmd->channel = param->freq; 3754 cmd->period = param->period; 3755 cmd->interval = param->interval; 3756 cmd->count = param->count; 3757 cmd->device_types_len = param->dev_types_len; 3758 cmd->prob_resp_len = param->probe_resp_len; 3759 3760 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3761 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3762 device_types_len_aligned); 3763 buf_ptr += WMI_TLV_HDR_SIZE; 3764 qdf_mem_copy(buf_ptr, param->device_types, 3765 param->dev_types_len); 3766 3767 buf_ptr += device_types_len_aligned; 3768 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3769 probe_resp_len_aligned); 3770 buf_ptr += WMI_TLV_HDR_SIZE; 3771 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3772 param->probe_resp_len); 3773 3774 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3775 cmd->channel, cmd->period, cmd->interval, cmd->count); 3776 3777 status = wmi_unified_cmd_send(wmi_handle, 3778 buf, len, 3779 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3780 if (status != QDF_STATUS_SUCCESS) { 3781 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3782 __func__, status); 3783 wmi_buf_free(buf); 3784 return status; 3785 } 3786 3787 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3788 3789 return QDF_STATUS_SUCCESS; 3790 } 3791 3792 /** 3793 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3794 * @wmi_handle: wmi handle 3795 * @param: p2p listen offload stop parameters 3796 * 3797 * Return: QDF status 3798 */ 3799 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3800 uint8_t vdev_id) 3801 { 3802 wmi_buf_t buf; 3803 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3804 int32_t len; 3805 QDF_STATUS status; 3806 3807 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3808 3809 len = sizeof(*cmd); 3810 buf = wmi_buf_alloc(wmi_handle, len); 3811 if (!buf) { 3812 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3813 __func__); 3814 return QDF_STATUS_E_NOMEM; 3815 } 3816 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3817 3818 WMITLV_SET_HDR(&cmd->tlv_header, 3819 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3820 WMITLV_GET_STRUCT_TLVLEN( 3821 wmi_p2p_lo_stop_cmd_fixed_param)); 3822 3823 cmd->vdev_id = vdev_id; 3824 3825 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3826 3827 status = wmi_unified_cmd_send(wmi_handle, 3828 buf, len, 3829 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3830 if (status != QDF_STATUS_SUCCESS) { 3831 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3832 __func__, status); 3833 wmi_buf_free(buf); 3834 return status; 3835 } 3836 3837 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3838 3839 return QDF_STATUS_SUCCESS; 3840 } 3841 #endif /* End of CONVERGED_P2P_ENABLE */ 3842 3843 /** 3844 * send_get_temperature_cmd_tlv() - get pdev temperature req 3845 * @wmi_handle: wmi handle 3846 * 3847 * Return: QDF_STATUS_SUCCESS for success or error code. 3848 */ 3849 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3850 { 3851 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3852 wmi_buf_t wmi_buf; 3853 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3854 uint8_t *buf_ptr; 3855 3856 if (!wmi_handle) { 3857 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3858 return QDF_STATUS_E_INVAL; 3859 } 3860 3861 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3862 if (!wmi_buf) { 3863 WMI_LOGE(FL("wmi_buf_alloc failed")); 3864 return QDF_STATUS_E_NOMEM; 3865 } 3866 3867 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3868 3869 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3870 WMITLV_SET_HDR(&cmd->tlv_header, 3871 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3872 WMITLV_GET_STRUCT_TLVLEN 3873 (wmi_pdev_get_temperature_cmd_fixed_param)); 3874 3875 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3876 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3877 WMI_LOGE(FL("failed to send get temperature command")); 3878 wmi_buf_free(wmi_buf); 3879 return QDF_STATUS_E_FAILURE; 3880 } 3881 3882 return QDF_STATUS_SUCCESS; 3883 } 3884 3885 /** 3886 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3887 * @wmi_handle: wmi handle 3888 * @vdevid: vdev id 3889 * @peer_addr: peer mac address 3890 * @auto_triggerparam: auto trigger parameters 3891 * @num_ac: number of access category 3892 * 3893 * This function sets the trigger 3894 * uapsd params such as service interval, delay interval 3895 * and suspend interval which will be used by the firmware 3896 * to send trigger frames periodically when there is no 3897 * traffic on the transmit side. 3898 * 3899 * Return: QDF_STATUS_SUCCESS for success or error code. 3900 */ 3901 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3902 struct sta_uapsd_trig_params *param) 3903 { 3904 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3905 QDF_STATUS ret; 3906 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3907 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3908 uint32_t i; 3909 wmi_buf_t buf; 3910 uint8_t *buf_ptr; 3911 struct sta_uapsd_params *uapsd_param; 3912 wmi_sta_uapsd_auto_trig_param *trig_param; 3913 3914 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3915 if (!buf) { 3916 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3917 return QDF_STATUS_E_NOMEM; 3918 } 3919 3920 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3921 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3922 WMITLV_SET_HDR(&cmd->tlv_header, 3923 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3924 WMITLV_GET_STRUCT_TLVLEN 3925 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3926 cmd->vdev_id = param->vdevid; 3927 cmd->num_ac = param->num_ac; 3928 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3929 3930 /* TLV indicating array of structures to follow */ 3931 buf_ptr += sizeof(*cmd); 3932 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3933 3934 buf_ptr += WMI_TLV_HDR_SIZE; 3935 3936 /* 3937 * Update tag and length for uapsd auto trigger params (this will take 3938 * care of updating tag and length if it is not pre-filled by caller). 3939 */ 3940 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3941 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3942 for (i = 0; i < param->num_ac; i++) { 3943 WMITLV_SET_HDR((buf_ptr + 3944 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3945 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3946 WMITLV_GET_STRUCT_TLVLEN 3947 (wmi_sta_uapsd_auto_trig_param)); 3948 trig_param->wmm_ac = uapsd_param->wmm_ac; 3949 trig_param->user_priority = uapsd_param->user_priority; 3950 trig_param->service_interval = uapsd_param->service_interval; 3951 trig_param->suspend_interval = uapsd_param->suspend_interval; 3952 trig_param->delay_interval = uapsd_param->delay_interval; 3953 trig_param++; 3954 uapsd_param++; 3955 } 3956 3957 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3958 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3959 if (QDF_IS_STATUS_ERROR(ret)) { 3960 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3961 wmi_buf_free(buf); 3962 } 3963 3964 return ret; 3965 } 3966 3967 #ifdef WLAN_FEATURE_DSRC 3968 /** 3969 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 3970 * @wmi_handle: pointer to the wmi handle 3971 * @utc: pointer to the UTC time struct 3972 * 3973 * Return: 0 on succes 3974 */ 3975 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 3976 struct ocb_utc_param *utc) 3977 { 3978 QDF_STATUS ret; 3979 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 3980 uint8_t *buf_ptr; 3981 uint32_t len, i; 3982 wmi_buf_t buf; 3983 3984 len = sizeof(*cmd); 3985 buf = wmi_buf_alloc(wmi_handle, len); 3986 if (!buf) { 3987 WMI_LOGE(FL("wmi_buf_alloc failed")); 3988 return QDF_STATUS_E_NOMEM; 3989 } 3990 3991 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3992 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 3993 WMITLV_SET_HDR(&cmd->tlv_header, 3994 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 3995 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 3996 cmd->vdev_id = utc->vdev_id; 3997 3998 for (i = 0; i < SIZE_UTC_TIME; i++) 3999 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 4000 4001 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 4002 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 4003 4004 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4005 WMI_OCB_SET_UTC_TIME_CMDID); 4006 if (QDF_IS_STATUS_ERROR(ret)) { 4007 WMI_LOGE(FL("Failed to set OCB UTC time")); 4008 wmi_buf_free(buf); 4009 } 4010 4011 return ret; 4012 } 4013 4014 /** 4015 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 4016 * frames on a channel 4017 * @wmi_handle: pointer to the wmi handle 4018 * @timing_advert: pointer to the timing advertisement struct 4019 * 4020 * Return: 0 on succes 4021 */ 4022 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 4023 struct ocb_timing_advert_param *timing_advert) 4024 { 4025 QDF_STATUS ret; 4026 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 4027 uint8_t *buf_ptr; 4028 uint32_t len, len_template; 4029 wmi_buf_t buf; 4030 4031 len = sizeof(*cmd) + 4032 WMI_TLV_HDR_SIZE; 4033 4034 len_template = timing_advert->template_length; 4035 /* Add padding to the template if needed */ 4036 if (len_template % 4 != 0) 4037 len_template += 4 - (len_template % 4); 4038 len += len_template; 4039 4040 buf = wmi_buf_alloc(wmi_handle, len); 4041 if (!buf) { 4042 WMI_LOGE(FL("wmi_buf_alloc failed")); 4043 return QDF_STATUS_E_NOMEM; 4044 } 4045 4046 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4047 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 4048 WMITLV_SET_HDR(&cmd->tlv_header, 4049 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 4050 WMITLV_GET_STRUCT_TLVLEN( 4051 wmi_ocb_start_timing_advert_cmd_fixed_param)); 4052 cmd->vdev_id = timing_advert->vdev_id; 4053 cmd->repeat_rate = timing_advert->repeat_rate; 4054 cmd->channel_freq = timing_advert->chan_freq; 4055 cmd->timestamp_offset = timing_advert->timestamp_offset; 4056 cmd->time_value_offset = timing_advert->time_value_offset; 4057 cmd->timing_advert_template_length = timing_advert->template_length; 4058 buf_ptr += sizeof(*cmd); 4059 4060 /* Add the timing advert template */ 4061 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4062 len_template); 4063 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 4064 (uint8_t *)timing_advert->template_value, 4065 timing_advert->template_length); 4066 4067 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4068 WMI_OCB_START_TIMING_ADVERT_CMDID); 4069 if (QDF_IS_STATUS_ERROR(ret)) { 4070 WMI_LOGE(FL("Failed to start OCB timing advert")); 4071 wmi_buf_free(buf); 4072 } 4073 4074 return ret; 4075 } 4076 4077 /** 4078 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 4079 * on a channel 4080 * @wmi_handle: pointer to the wmi handle 4081 * @timing_advert: pointer to the timing advertisement struct 4082 * 4083 * Return: 0 on succes 4084 */ 4085 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 4086 struct ocb_timing_advert_param *timing_advert) 4087 { 4088 QDF_STATUS ret; 4089 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 4090 uint8_t *buf_ptr; 4091 uint32_t len; 4092 wmi_buf_t buf; 4093 4094 len = sizeof(*cmd); 4095 buf = wmi_buf_alloc(wmi_handle, len); 4096 if (!buf) { 4097 WMI_LOGE(FL("wmi_buf_alloc failed")); 4098 return QDF_STATUS_E_NOMEM; 4099 } 4100 4101 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4102 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 4103 WMITLV_SET_HDR(&cmd->tlv_header, 4104 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 4105 WMITLV_GET_STRUCT_TLVLEN( 4106 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 4107 cmd->vdev_id = timing_advert->vdev_id; 4108 cmd->channel_freq = timing_advert->chan_freq; 4109 4110 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4111 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 4112 if (QDF_IS_STATUS_ERROR(ret)) { 4113 WMI_LOGE(FL("Failed to stop OCB timing advert")); 4114 wmi_buf_free(buf); 4115 } 4116 4117 return ret; 4118 } 4119 4120 /** 4121 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 4122 * @wmi_handle: pointer to the wmi handle 4123 * @request: pointer to the request 4124 * 4125 * Return: 0 on succes 4126 */ 4127 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 4128 uint8_t vdev_id) 4129 { 4130 QDF_STATUS ret; 4131 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 4132 uint8_t *buf_ptr; 4133 wmi_buf_t buf; 4134 int32_t len; 4135 4136 len = sizeof(*cmd); 4137 buf = wmi_buf_alloc(wmi_handle, len); 4138 if (!buf) { 4139 WMI_LOGE(FL("wmi_buf_alloc failed")); 4140 return QDF_STATUS_E_NOMEM; 4141 } 4142 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4143 4144 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 4145 qdf_mem_zero(cmd, len); 4146 WMITLV_SET_HDR(&cmd->tlv_header, 4147 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 4148 WMITLV_GET_STRUCT_TLVLEN( 4149 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 4150 cmd->vdev_id = vdev_id; 4151 4152 /* Send the WMI command */ 4153 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4154 WMI_OCB_GET_TSF_TIMER_CMDID); 4155 /* If there is an error, set the completion event */ 4156 if (QDF_IS_STATUS_ERROR(ret)) { 4157 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4158 wmi_buf_free(buf); 4159 } 4160 4161 return ret; 4162 } 4163 4164 /** 4165 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 4166 * @wmi_handle: pointer to the wmi handle 4167 * @get_stats_param: pointer to the dcc stats 4168 * 4169 * Return: 0 on succes 4170 */ 4171 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 4172 struct ocb_dcc_get_stats_param *get_stats_param) 4173 { 4174 QDF_STATUS ret; 4175 wmi_dcc_get_stats_cmd_fixed_param *cmd; 4176 wmi_dcc_channel_stats_request *channel_stats_array; 4177 wmi_buf_t buf; 4178 uint8_t *buf_ptr; 4179 uint32_t len; 4180 uint32_t i; 4181 4182 /* Validate the input */ 4183 if (get_stats_param->request_array_len != 4184 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4185 WMI_LOGE(FL("Invalid parameter")); 4186 return QDF_STATUS_E_INVAL; 4187 } 4188 4189 /* Allocate memory for the WMI command */ 4190 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4191 get_stats_param->request_array_len; 4192 4193 buf = wmi_buf_alloc(wmi_handle, len); 4194 if (!buf) { 4195 WMI_LOGE(FL("wmi_buf_alloc failed")); 4196 return QDF_STATUS_E_NOMEM; 4197 } 4198 4199 buf_ptr = wmi_buf_data(buf); 4200 qdf_mem_zero(buf_ptr, len); 4201 4202 /* Populate the WMI command */ 4203 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4204 buf_ptr += sizeof(*cmd); 4205 4206 WMITLV_SET_HDR(&cmd->tlv_header, 4207 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4208 WMITLV_GET_STRUCT_TLVLEN( 4209 wmi_dcc_get_stats_cmd_fixed_param)); 4210 cmd->vdev_id = get_stats_param->vdev_id; 4211 cmd->num_channels = get_stats_param->channel_count; 4212 4213 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4214 get_stats_param->request_array_len); 4215 buf_ptr += WMI_TLV_HDR_SIZE; 4216 4217 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4218 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4219 get_stats_param->request_array_len); 4220 for (i = 0; i < cmd->num_channels; i++) 4221 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4222 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4223 WMITLV_GET_STRUCT_TLVLEN( 4224 wmi_dcc_channel_stats_request)); 4225 4226 /* Send the WMI command */ 4227 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4228 WMI_DCC_GET_STATS_CMDID); 4229 4230 if (QDF_IS_STATUS_ERROR(ret)) { 4231 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4232 wmi_buf_free(buf); 4233 } 4234 4235 return ret; 4236 } 4237 4238 /** 4239 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4240 * @wmi_handle: pointer to the wmi handle 4241 * @vdev_id: vdev id 4242 * @dcc_stats_bitmap: dcc status bitmap 4243 * 4244 * Return: 0 on succes 4245 */ 4246 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4247 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4248 { 4249 QDF_STATUS ret; 4250 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4251 wmi_buf_t buf; 4252 uint8_t *buf_ptr; 4253 uint32_t len; 4254 4255 /* Allocate memory for the WMI command */ 4256 len = sizeof(*cmd); 4257 4258 buf = wmi_buf_alloc(wmi_handle, len); 4259 if (!buf) { 4260 WMI_LOGE(FL("wmi_buf_alloc failed")); 4261 return QDF_STATUS_E_NOMEM; 4262 } 4263 4264 buf_ptr = wmi_buf_data(buf); 4265 qdf_mem_zero(buf_ptr, len); 4266 4267 /* Populate the WMI command */ 4268 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4269 4270 WMITLV_SET_HDR(&cmd->tlv_header, 4271 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4272 WMITLV_GET_STRUCT_TLVLEN( 4273 wmi_dcc_clear_stats_cmd_fixed_param)); 4274 cmd->vdev_id = vdev_id; 4275 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4276 4277 /* Send the WMI command */ 4278 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4279 WMI_DCC_CLEAR_STATS_CMDID); 4280 if (QDF_IS_STATUS_ERROR(ret)) { 4281 WMI_LOGE(FL("Failed to send the WMI command")); 4282 wmi_buf_free(buf); 4283 } 4284 4285 return ret; 4286 } 4287 4288 /** 4289 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4290 * @wmi_handle: pointer to the wmi handle 4291 * @update_ndl_param: pointer to the request parameters 4292 * 4293 * Return: 0 on success 4294 */ 4295 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4296 struct ocb_dcc_update_ndl_param *update_ndl_param) 4297 { 4298 QDF_STATUS qdf_status; 4299 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4300 wmi_dcc_ndl_chan *ndl_chan_array; 4301 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4302 uint32_t active_state_count; 4303 wmi_buf_t buf; 4304 uint8_t *buf_ptr; 4305 uint32_t len; 4306 uint32_t i; 4307 4308 /* validate the input */ 4309 if (update_ndl_param->dcc_ndl_chan_list_len != 4310 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4311 WMI_LOGE(FL("Invalid parameter")); 4312 return QDF_STATUS_E_INVAL; 4313 } 4314 active_state_count = 0; 4315 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4316 for (i = 0; i < update_ndl_param->channel_count; i++) 4317 active_state_count += 4318 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4319 if (update_ndl_param->dcc_ndl_active_state_list_len != 4320 active_state_count * sizeof(*ndl_active_state_array)) { 4321 WMI_LOGE(FL("Invalid parameter")); 4322 return QDF_STATUS_E_INVAL; 4323 } 4324 4325 /* Allocate memory for the WMI command */ 4326 len = sizeof(*cmd) + 4327 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4328 WMI_TLV_HDR_SIZE + 4329 update_ndl_param->dcc_ndl_active_state_list_len; 4330 4331 buf = wmi_buf_alloc(wmi_handle, len); 4332 if (!buf) { 4333 WMI_LOGE(FL("wmi_buf_alloc failed")); 4334 return QDF_STATUS_E_NOMEM; 4335 } 4336 4337 buf_ptr = wmi_buf_data(buf); 4338 qdf_mem_zero(buf_ptr, len); 4339 4340 /* Populate the WMI command */ 4341 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4342 buf_ptr += sizeof(*cmd); 4343 4344 WMITLV_SET_HDR(&cmd->tlv_header, 4345 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4346 WMITLV_GET_STRUCT_TLVLEN( 4347 wmi_dcc_update_ndl_cmd_fixed_param)); 4348 cmd->vdev_id = update_ndl_param->vdev_id; 4349 cmd->num_channel = update_ndl_param->channel_count; 4350 4351 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4352 update_ndl_param->dcc_ndl_chan_list_len); 4353 buf_ptr += WMI_TLV_HDR_SIZE; 4354 4355 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4356 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4357 update_ndl_param->dcc_ndl_chan_list_len); 4358 for (i = 0; i < cmd->num_channel; i++) 4359 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4360 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4361 WMITLV_GET_STRUCT_TLVLEN( 4362 wmi_dcc_ndl_chan)); 4363 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4364 4365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4366 update_ndl_param->dcc_ndl_active_state_list_len); 4367 buf_ptr += WMI_TLV_HDR_SIZE; 4368 4369 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4370 qdf_mem_copy(ndl_active_state_array, 4371 update_ndl_param->dcc_ndl_active_state_list, 4372 update_ndl_param->dcc_ndl_active_state_list_len); 4373 for (i = 0; i < active_state_count; i++) { 4374 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4375 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4376 WMITLV_GET_STRUCT_TLVLEN( 4377 wmi_dcc_ndl_active_state_config)); 4378 } 4379 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4380 4381 /* Send the WMI command */ 4382 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4383 WMI_DCC_UPDATE_NDL_CMDID); 4384 /* If there is an error, set the completion event */ 4385 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4386 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4387 wmi_buf_free(buf); 4388 } 4389 4390 return qdf_status; 4391 } 4392 4393 /** 4394 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4395 * @wmi_handle: pointer to the wmi handle 4396 * @config: the OCB configuration 4397 * 4398 * Return: 0 on success 4399 */ 4400 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4401 struct ocb_config *config) 4402 { 4403 QDF_STATUS ret; 4404 wmi_ocb_set_config_cmd_fixed_param *cmd; 4405 wmi_channel *chan; 4406 wmi_ocb_channel *ocb_chan; 4407 wmi_qos_parameter *qos_param; 4408 wmi_dcc_ndl_chan *ndl_chan; 4409 wmi_dcc_ndl_active_state_config *ndl_active_config; 4410 wmi_ocb_schedule_element *sched_elem; 4411 uint8_t *buf_ptr; 4412 wmi_buf_t buf; 4413 int32_t len; 4414 int32_t i, j, active_state_count; 4415 4416 /* 4417 * Validate the dcc_ndl_chan_list_len and count the number of active 4418 * states. Validate dcc_ndl_active_state_list_len. 4419 */ 4420 active_state_count = 0; 4421 if (config->dcc_ndl_chan_list_len) { 4422 if (!config->dcc_ndl_chan_list || 4423 config->dcc_ndl_chan_list_len != 4424 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4425 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4426 config->dcc_ndl_chan_list_len); 4427 return QDF_STATUS_E_INVAL; 4428 } 4429 4430 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4431 i < config->channel_count; ++i, ++ndl_chan) 4432 active_state_count += 4433 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4434 4435 if (active_state_count) { 4436 if (!config->dcc_ndl_active_state_list || 4437 config->dcc_ndl_active_state_list_len != 4438 active_state_count * 4439 sizeof(wmi_dcc_ndl_active_state_config)) { 4440 WMI_LOGE(FL("NDL active state is invalid.")); 4441 return QDF_STATUS_E_INVAL; 4442 } 4443 } 4444 } 4445 4446 len = sizeof(*cmd) + 4447 WMI_TLV_HDR_SIZE + config->channel_count * 4448 sizeof(wmi_channel) + 4449 WMI_TLV_HDR_SIZE + config->channel_count * 4450 sizeof(wmi_ocb_channel) + 4451 WMI_TLV_HDR_SIZE + config->channel_count * 4452 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4453 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4454 WMI_TLV_HDR_SIZE + active_state_count * 4455 sizeof(wmi_dcc_ndl_active_state_config) + 4456 WMI_TLV_HDR_SIZE + config->schedule_size * 4457 sizeof(wmi_ocb_schedule_element); 4458 buf = wmi_buf_alloc(wmi_handle, len); 4459 if (!buf) { 4460 WMI_LOGE(FL("wmi_buf_alloc failed")); 4461 return QDF_STATUS_E_NOMEM; 4462 } 4463 4464 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4465 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4466 WMITLV_SET_HDR(&cmd->tlv_header, 4467 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4468 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4469 cmd->vdev_id = config->vdev_id; 4470 cmd->channel_count = config->channel_count; 4471 cmd->schedule_size = config->schedule_size; 4472 cmd->flags = config->flags; 4473 buf_ptr += sizeof(*cmd); 4474 4475 /* Add the wmi_channel info */ 4476 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4477 config->channel_count*sizeof(wmi_channel)); 4478 buf_ptr += WMI_TLV_HDR_SIZE; 4479 for (i = 0; i < config->channel_count; i++) { 4480 chan = (wmi_channel *)buf_ptr; 4481 WMITLV_SET_HDR(&chan->tlv_header, 4482 WMITLV_TAG_STRUC_wmi_channel, 4483 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4484 chan->mhz = config->channels[i].chan_freq; 4485 chan->band_center_freq1 = config->channels[i].chan_freq; 4486 chan->band_center_freq2 = 0; 4487 chan->info = 0; 4488 4489 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4490 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4491 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4492 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4493 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4494 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4495 config->channels[i].antenna_max); 4496 4497 if (config->channels[i].bandwidth < 10) 4498 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4499 else if (config->channels[i].bandwidth < 20) 4500 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4501 buf_ptr += sizeof(*chan); 4502 } 4503 4504 /* Add the wmi_ocb_channel info */ 4505 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4506 config->channel_count*sizeof(wmi_ocb_channel)); 4507 buf_ptr += WMI_TLV_HDR_SIZE; 4508 for (i = 0; i < config->channel_count; i++) { 4509 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4510 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4511 WMITLV_TAG_STRUC_wmi_ocb_channel, 4512 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4513 ocb_chan->bandwidth = config->channels[i].bandwidth; 4514 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4515 config->channels[i].mac_address.bytes, 4516 &ocb_chan->mac_address); 4517 buf_ptr += sizeof(*ocb_chan); 4518 } 4519 4520 /* Add the wmi_qos_parameter info */ 4521 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4522 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4523 buf_ptr += WMI_TLV_HDR_SIZE; 4524 /* WMI_MAX_NUM_AC parameters for each channel */ 4525 for (i = 0; i < config->channel_count; i++) { 4526 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4527 qos_param = (wmi_qos_parameter *)buf_ptr; 4528 WMITLV_SET_HDR(&qos_param->tlv_header, 4529 WMITLV_TAG_STRUC_wmi_qos_parameter, 4530 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4531 qos_param->aifsn = 4532 config->channels[i].qos_params[j].aifsn; 4533 qos_param->cwmin = 4534 config->channels[i].qos_params[j].cwmin; 4535 qos_param->cwmax = 4536 config->channels[i].qos_params[j].cwmax; 4537 buf_ptr += sizeof(*qos_param); 4538 } 4539 } 4540 4541 /* Add the wmi_dcc_ndl_chan (per channel) */ 4542 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4543 config->dcc_ndl_chan_list_len); 4544 buf_ptr += WMI_TLV_HDR_SIZE; 4545 if (config->dcc_ndl_chan_list_len) { 4546 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4547 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4548 config->dcc_ndl_chan_list_len); 4549 for (i = 0; i < config->channel_count; i++) 4550 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4551 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4552 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4553 buf_ptr += config->dcc_ndl_chan_list_len; 4554 } 4555 4556 /* Add the wmi_dcc_ndl_active_state_config */ 4557 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4558 sizeof(wmi_dcc_ndl_active_state_config)); 4559 buf_ptr += WMI_TLV_HDR_SIZE; 4560 if (active_state_count) { 4561 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4562 qdf_mem_copy(ndl_active_config, 4563 config->dcc_ndl_active_state_list, 4564 active_state_count * sizeof(*ndl_active_config)); 4565 for (i = 0; i < active_state_count; ++i) 4566 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4567 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4568 WMITLV_GET_STRUCT_TLVLEN( 4569 wmi_dcc_ndl_active_state_config)); 4570 buf_ptr += active_state_count * 4571 sizeof(*ndl_active_config); 4572 } 4573 4574 /* Add the wmi_ocb_schedule_element info */ 4575 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4576 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4577 buf_ptr += WMI_TLV_HDR_SIZE; 4578 for (i = 0; i < config->schedule_size; i++) { 4579 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4580 WMITLV_SET_HDR(&sched_elem->tlv_header, 4581 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4582 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4583 sched_elem->channel_freq = config->schedule[i].chan_freq; 4584 sched_elem->total_duration = config->schedule[i].total_duration; 4585 sched_elem->guard_interval = config->schedule[i].guard_interval; 4586 buf_ptr += sizeof(*sched_elem); 4587 } 4588 4589 4590 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4591 WMI_OCB_SET_CONFIG_CMDID); 4592 if (QDF_IS_STATUS_ERROR(ret)) { 4593 WMI_LOGE("Failed to set OCB config"); 4594 wmi_buf_free(buf); 4595 } 4596 4597 return ret; 4598 } 4599 4600 /** 4601 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4602 * @wmi_handle: wmi handle 4603 * @evt_buf: wmi event buffer 4604 * @status: status buffer 4605 * 4606 * Return: QDF_STATUS_SUCCESS on success 4607 */ 4608 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4609 void *evt_buf, 4610 uint32_t *status) 4611 { 4612 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4613 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4614 4615 param_tlvs = evt_buf; 4616 fix_param = param_tlvs->fixed_param; 4617 4618 *status = fix_param->status; 4619 return QDF_STATUS_SUCCESS; 4620 } 4621 4622 /** 4623 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4624 * @wmi_handle: wmi handle 4625 * @evt_buf: wmi event buffer 4626 * @resp: response buffer 4627 * 4628 * Return: QDF_STATUS_SUCCESS on success 4629 */ 4630 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4631 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4632 { 4633 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4634 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4635 4636 param_tlvs = evt_buf; 4637 fix_param = param_tlvs->fixed_param; 4638 resp->vdev_id = fix_param->vdev_id; 4639 resp->timer_high = fix_param->tsf_timer_high; 4640 resp->timer_low = fix_param->tsf_timer_low; 4641 4642 return QDF_STATUS_SUCCESS; 4643 } 4644 4645 /** 4646 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4647 * @wmi_handle: wmi handle 4648 * @evt_buf: wmi event buffer 4649 * @resp: response buffer 4650 * 4651 * Return: QDF_STATUS_SUCCESS on success 4652 */ 4653 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4654 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4655 { 4656 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4657 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4658 4659 param_tlvs = evt_buf; 4660 fix_param = param_tlvs->fixed_param; 4661 resp->vdev_id = fix_param->vdev_id; 4662 resp->status = fix_param->status; 4663 return QDF_STATUS_SUCCESS; 4664 } 4665 4666 /** 4667 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4668 * @wmi_handle: wmi handle 4669 * @evt_buf: wmi event buffer 4670 * @resp: response buffer 4671 * 4672 * Since length of stats is variable, buffer for DCC stats will be allocated 4673 * in this function. The caller must free the buffer. 4674 * 4675 * Return: QDF_STATUS_SUCCESS on success 4676 */ 4677 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4678 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4679 { 4680 struct ocb_dcc_get_stats_response *response; 4681 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4682 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4683 4684 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4685 fix_param = param_tlvs->fixed_param; 4686 4687 /* Allocate and populate the response */ 4688 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4689 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4690 WMI_LOGE("%s: too many channels:%d", __func__, 4691 fix_param->num_channels); 4692 QDF_ASSERT(0); 4693 *resp = NULL; 4694 return QDF_STATUS_E_INVAL; 4695 } 4696 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4697 sizeof(wmi_dcc_ndl_stats_per_channel)); 4698 *resp = response; 4699 if (!response) 4700 return QDF_STATUS_E_NOMEM; 4701 4702 response->vdev_id = fix_param->vdev_id; 4703 response->num_channels = fix_param->num_channels; 4704 response->channel_stats_array_len = 4705 fix_param->num_channels * 4706 sizeof(wmi_dcc_ndl_stats_per_channel); 4707 response->channel_stats_array = ((uint8_t *)response) + 4708 sizeof(*response); 4709 qdf_mem_copy(response->channel_stats_array, 4710 param_tlvs->stats_per_channel_list, 4711 response->channel_stats_array_len); 4712 4713 return QDF_STATUS_SUCCESS; 4714 } 4715 #endif 4716 4717 /** 4718 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4719 * @wmi_handle: wmi handle 4720 * @mcc_adaptive_scheduler: enable/disable 4721 * 4722 * This function enable/disable mcc adaptive scheduler in fw. 4723 * 4724 * Return: QDF_STATUS_SUCCESS for success or error code 4725 */ 4726 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4727 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4728 uint32_t pdev_id) 4729 { 4730 QDF_STATUS ret; 4731 wmi_buf_t buf = 0; 4732 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4733 uint16_t len = 4734 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4735 4736 buf = wmi_buf_alloc(wmi_handle, len); 4737 if (!buf) { 4738 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4739 return QDF_STATUS_E_NOMEM; 4740 } 4741 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4742 wmi_buf_data(buf); 4743 4744 WMITLV_SET_HDR(&cmd->tlv_header, 4745 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4746 WMITLV_GET_STRUCT_TLVLEN 4747 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4748 cmd->enable = mcc_adaptive_scheduler; 4749 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4750 4751 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4752 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4753 if (QDF_IS_STATUS_ERROR(ret)) { 4754 WMI_LOGP("%s: Failed to send enable/disable MCC" 4755 " adaptive scheduler command", __func__); 4756 wmi_buf_free(buf); 4757 } 4758 4759 return ret; 4760 } 4761 4762 /** 4763 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4764 * @wmi: wmi handle 4765 * @mcc_channel: mcc channel 4766 * @mcc_channel_time_latency: MCC channel time latency. 4767 * 4768 * Currently used to set time latency for an MCC vdev/adapter using operating 4769 * channel of it and channel number. The info is provided run time using 4770 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4771 * 4772 * Return: CDF status 4773 */ 4774 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4775 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4776 { 4777 QDF_STATUS ret; 4778 wmi_buf_t buf = 0; 4779 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4780 uint16_t len = 0; 4781 uint8_t *buf_ptr = NULL; 4782 wmi_resmgr_chan_latency chan_latency; 4783 /* Note: we only support MCC time latency for a single channel */ 4784 uint32_t num_channels = 1; 4785 uint32_t chan1_freq = mcc_channel_freq; 4786 uint32_t latency_chan1 = mcc_channel_time_latency; 4787 4788 4789 /* If 0ms latency is provided, then FW will set to a default. 4790 * Otherwise, latency must be at least 30ms. 4791 */ 4792 if ((latency_chan1 > 0) && 4793 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4794 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4795 "Minimum is 30ms (or 0 to use default value by " 4796 "firmware)", __func__, latency_chan1); 4797 return QDF_STATUS_E_INVAL; 4798 } 4799 4800 /* Set WMI CMD for channel time latency here */ 4801 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4802 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4803 num_channels * sizeof(wmi_resmgr_chan_latency); 4804 buf = wmi_buf_alloc(wmi_handle, len); 4805 if (!buf) { 4806 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4807 return QDF_STATUS_E_NOMEM; 4808 } 4809 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4810 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4811 wmi_buf_data(buf); 4812 WMITLV_SET_HDR(&cmdTL->tlv_header, 4813 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4814 WMITLV_GET_STRUCT_TLVLEN 4815 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4816 cmdTL->num_chans = num_channels; 4817 /* Update channel time latency information for home channel(s) */ 4818 buf_ptr += sizeof(*cmdTL); 4819 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4820 num_channels * sizeof(wmi_resmgr_chan_latency)); 4821 buf_ptr += WMI_TLV_HDR_SIZE; 4822 chan_latency.chan_mhz = chan1_freq; 4823 chan_latency.latency = latency_chan1; 4824 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4825 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4826 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4827 if (QDF_IS_STATUS_ERROR(ret)) { 4828 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4829 __func__); 4830 wmi_buf_free(buf); 4831 QDF_ASSERT(0); 4832 } 4833 4834 return ret; 4835 } 4836 4837 /** 4838 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4839 * @wmi: wmi handle 4840 * @adapter_1_chan_number: adapter 1 channel number 4841 * @adapter_1_quota: adapter 1 quota 4842 * @adapter_2_chan_number: adapter 2 channel number 4843 * 4844 * Return: CDF status 4845 */ 4846 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4847 uint32_t adapter_1_chan_freq, 4848 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4849 { 4850 QDF_STATUS ret; 4851 wmi_buf_t buf = 0; 4852 uint16_t len = 0; 4853 uint8_t *buf_ptr = NULL; 4854 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4855 wmi_resmgr_chan_time_quota chan_quota; 4856 uint32_t quota_chan1 = adapter_1_quota; 4857 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4858 uint32_t quota_chan2 = 100 - quota_chan1; 4859 /* Note: setting time quota for MCC requires info for 2 channels */ 4860 uint32_t num_channels = 2; 4861 uint32_t chan1_freq = adapter_1_chan_freq; 4862 uint32_t chan2_freq = adapter_2_chan_freq; 4863 4864 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4865 "freq2:%dMHz, Quota2:%dms", __func__, 4866 chan1_freq, quota_chan1, chan2_freq, 4867 quota_chan2); 4868 4869 /* 4870 * Perform sanity check on time quota values provided. 4871 */ 4872 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4873 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4874 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4875 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4876 return QDF_STATUS_E_INVAL; 4877 } 4878 /* Set WMI CMD for channel time quota here */ 4879 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4880 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4881 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4882 buf = wmi_buf_alloc(wmi_handle, len); 4883 if (!buf) { 4884 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4885 QDF_ASSERT(0); 4886 return QDF_STATUS_E_NOMEM; 4887 } 4888 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4889 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4890 wmi_buf_data(buf); 4891 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4892 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4893 WMITLV_GET_STRUCT_TLVLEN 4894 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4895 cmdTQ->num_chans = num_channels; 4896 4897 /* Update channel time quota information for home channel(s) */ 4898 buf_ptr += sizeof(*cmdTQ); 4899 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4900 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4901 buf_ptr += WMI_TLV_HDR_SIZE; 4902 chan_quota.chan_mhz = chan1_freq; 4903 chan_quota.channel_time_quota = quota_chan1; 4904 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4905 /* Construct channel and quota record for the 2nd MCC mode. */ 4906 buf_ptr += sizeof(chan_quota); 4907 chan_quota.chan_mhz = chan2_freq; 4908 chan_quota.channel_time_quota = quota_chan2; 4909 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 4910 4911 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4912 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 4913 if (QDF_IS_STATUS_ERROR(ret)) { 4914 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 4915 wmi_buf_free(buf); 4916 QDF_ASSERT(0); 4917 } 4918 4919 return ret; 4920 } 4921 4922 /** 4923 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4924 * @wmi_handle: Pointer to wmi handle 4925 * @thermal_info: Thermal command information 4926 * 4927 * This function sends the thermal management command 4928 * to the firmware 4929 * 4930 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4931 */ 4932 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4933 struct thermal_cmd_params *thermal_info) 4934 { 4935 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4936 wmi_buf_t buf = NULL; 4937 QDF_STATUS status; 4938 uint32_t len = 0; 4939 4940 len = sizeof(*cmd); 4941 4942 buf = wmi_buf_alloc(wmi_handle, len); 4943 if (!buf) { 4944 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4945 return QDF_STATUS_E_FAILURE; 4946 } 4947 4948 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4949 4950 WMITLV_SET_HDR(&cmd->tlv_header, 4951 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4952 WMITLV_GET_STRUCT_TLVLEN 4953 (wmi_thermal_mgmt_cmd_fixed_param)); 4954 4955 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4956 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4957 cmd->enable = thermal_info->thermal_enable; 4958 4959 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4960 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4961 4962 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4963 WMI_THERMAL_MGMT_CMDID); 4964 if (QDF_IS_STATUS_ERROR(status)) { 4965 wmi_buf_free(buf); 4966 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4967 } 4968 4969 return status; 4970 } 4971 4972 4973 /** 4974 * send_lro_config_cmd_tlv() - process the LRO config command 4975 * @wmi_handle: Pointer to WMI handle 4976 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4977 * 4978 * This function sends down the LRO configuration parameters to 4979 * the firmware to enable LRO, sets the TCP flags and sets the 4980 * seed values for the toeplitz hash generation 4981 * 4982 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4983 */ 4984 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4985 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4986 { 4987 wmi_lro_info_cmd_fixed_param *cmd; 4988 wmi_buf_t buf; 4989 QDF_STATUS status; 4990 4991 4992 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4993 if (!buf) { 4994 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 4995 return QDF_STATUS_E_FAILURE; 4996 } 4997 4998 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4999 5000 WMITLV_SET_HDR(&cmd->tlv_header, 5001 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5002 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5003 5004 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5005 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5006 wmi_lro_cmd->tcp_flag); 5007 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5008 wmi_lro_cmd->tcp_flag_mask); 5009 cmd->toeplitz_hash_ipv4_0_3 = 5010 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5011 cmd->toeplitz_hash_ipv4_4_7 = 5012 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5013 cmd->toeplitz_hash_ipv4_8_11 = 5014 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5015 cmd->toeplitz_hash_ipv4_12_15 = 5016 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5017 cmd->toeplitz_hash_ipv4_16 = 5018 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5019 5020 cmd->toeplitz_hash_ipv6_0_3 = 5021 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5022 cmd->toeplitz_hash_ipv6_4_7 = 5023 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5024 cmd->toeplitz_hash_ipv6_8_11 = 5025 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5026 cmd->toeplitz_hash_ipv6_12_15 = 5027 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5028 cmd->toeplitz_hash_ipv6_16_19 = 5029 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5030 cmd->toeplitz_hash_ipv6_20_23 = 5031 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5032 cmd->toeplitz_hash_ipv6_24_27 = 5033 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5034 cmd->toeplitz_hash_ipv6_28_31 = 5035 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5036 cmd->toeplitz_hash_ipv6_32_35 = 5037 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5038 cmd->toeplitz_hash_ipv6_36_39 = 5039 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5040 cmd->toeplitz_hash_ipv6_40 = 5041 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5042 5043 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 5044 cmd->lro_enable, cmd->tcp_flag_u32); 5045 5046 status = wmi_unified_cmd_send(wmi_handle, buf, 5047 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5048 if (QDF_IS_STATUS_ERROR(status)) { 5049 wmi_buf_free(buf); 5050 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 5051 } 5052 5053 return status; 5054 } 5055 5056 /** 5057 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5058 * @wmi_handle: Pointer to wmi handle 5059 * @rate_report_params: Pointer to peer rate report parameters 5060 * 5061 * 5062 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5063 */ 5064 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5065 struct wmi_peer_rate_report_params *rate_report_params) 5066 { 5067 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5068 wmi_buf_t buf = NULL; 5069 QDF_STATUS status = 0; 5070 uint32_t len = 0; 5071 uint32_t i, j; 5072 5073 len = sizeof(*cmd); 5074 5075 buf = wmi_buf_alloc(wmi_handle, len); 5076 if (!buf) { 5077 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 5078 return QDF_STATUS_E_FAILURE; 5079 } 5080 5081 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5082 wmi_buf_data(buf); 5083 5084 WMITLV_SET_HDR( 5085 &cmd->tlv_header, 5086 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5087 WMITLV_GET_STRUCT_TLVLEN( 5088 wmi_peer_set_rate_report_condition_fixed_param)); 5089 5090 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5091 cmd->report_backoff_time = rate_report_params->backoff_time; 5092 cmd->report_timer_period = rate_report_params->timer_period; 5093 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5094 cmd->cond_per_phy[i].val_cond_flags = 5095 rate_report_params->report_per_phy[i].cond_flags; 5096 cmd->cond_per_phy[i].rate_delta.min_delta = 5097 rate_report_params->report_per_phy[i].delta.delta_min; 5098 cmd->cond_per_phy[i].rate_delta.percentage = 5099 rate_report_params->report_per_phy[i].delta.percent; 5100 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5101 cmd->cond_per_phy[i].rate_threshold[j] = 5102 rate_report_params->report_per_phy[i]. 5103 report_rate_threshold[j]; 5104 } 5105 } 5106 5107 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 5108 cmd->enable_rate_report, 5109 cmd->report_backoff_time, cmd->report_timer_period); 5110 5111 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5112 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5113 if (QDF_IS_STATUS_ERROR(status)) { 5114 wmi_buf_free(buf); 5115 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 5116 __func__); 5117 } 5118 return status; 5119 } 5120 5121 /** 5122 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 5123 * @wmi_handle: wmi handle 5124 * @param: bcn ll cmd parameter 5125 * 5126 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5127 */ 5128 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 5129 wmi_bcn_send_from_host_cmd_fixed_param *param) 5130 { 5131 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 5132 wmi_buf_t wmi_buf; 5133 QDF_STATUS ret; 5134 5135 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5136 if (!wmi_buf) { 5137 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5138 return QDF_STATUS_E_FAILURE; 5139 } 5140 5141 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 5142 WMITLV_SET_HDR(&cmd->tlv_header, 5143 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 5144 WMITLV_GET_STRUCT_TLVLEN 5145 (wmi_bcn_send_from_host_cmd_fixed_param)); 5146 cmd->vdev_id = param->vdev_id; 5147 cmd->data_len = param->data_len; 5148 cmd->frame_ctrl = param->frame_ctrl; 5149 cmd->frag_ptr = param->frag_ptr; 5150 cmd->dtim_flag = param->dtim_flag; 5151 5152 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 5153 WMI_PDEV_SEND_BCN_CMDID); 5154 5155 if (QDF_IS_STATUS_ERROR(ret)) { 5156 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 5157 wmi_buf_free(wmi_buf); 5158 } 5159 5160 return ret; 5161 } 5162 5163 /** 5164 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 5165 * @wmi_handle: wmi handle 5166 * @vdev_id: vdev id 5167 * @max_retries: max retries 5168 * @retry_interval: retry interval 5169 * This function sets sta query related parameters in fw. 5170 * 5171 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5172 */ 5173 5174 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 5175 uint8_t vdev_id, uint32_t max_retries, 5176 uint32_t retry_interval) 5177 { 5178 wmi_buf_t buf; 5179 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 5180 int len; 5181 5182 len = sizeof(*cmd); 5183 buf = wmi_buf_alloc(wmi_handle, len); 5184 if (!buf) { 5185 WMI_LOGE(FL("wmi_buf_alloc failed")); 5186 return QDF_STATUS_E_FAILURE; 5187 } 5188 5189 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5190 WMITLV_SET_HDR(&cmd->tlv_header, 5191 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5192 WMITLV_GET_STRUCT_TLVLEN 5193 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5194 5195 5196 cmd->vdev_id = vdev_id; 5197 cmd->sa_query_max_retry_count = max_retries; 5198 cmd->sa_query_retry_interval = retry_interval; 5199 5200 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5201 vdev_id, retry_interval, max_retries); 5202 5203 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5204 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5205 WMI_LOGE(FL("Failed to offload STA SA Query")); 5206 wmi_buf_free(buf); 5207 return QDF_STATUS_E_FAILURE; 5208 } 5209 5210 WMI_LOGD(FL("Exit :")); 5211 return 0; 5212 } 5213 5214 /** 5215 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5216 * @wmi_handle: wmi handle 5217 * @params: sta keep alive parameter 5218 * 5219 * This function sets keep alive related parameters in fw. 5220 * 5221 * Return: CDF status 5222 */ 5223 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5224 struct sta_params *params) 5225 { 5226 wmi_buf_t buf; 5227 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5228 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5229 uint8_t *buf_ptr; 5230 int len; 5231 QDF_STATUS ret; 5232 5233 WMI_LOGD("%s: Enter", __func__); 5234 5235 len = sizeof(*cmd) + sizeof(*arp_rsp); 5236 buf = wmi_buf_alloc(wmi_handle, len); 5237 if (!buf) { 5238 WMI_LOGE("wmi_buf_alloc failed"); 5239 return QDF_STATUS_E_FAILURE; 5240 } 5241 5242 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5243 buf_ptr = (uint8_t *) cmd; 5244 WMITLV_SET_HDR(&cmd->tlv_header, 5245 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5246 WMITLV_GET_STRUCT_TLVLEN 5247 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5248 cmd->interval = params->timeperiod; 5249 cmd->enable = (params->timeperiod) ? 1 : 0; 5250 cmd->vdev_id = params->vdev_id; 5251 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5252 params->timeperiod, params->method); 5253 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5254 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5255 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5256 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5257 5258 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5259 (params->method == 5260 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5261 if ((NULL == params->hostv4addr) || 5262 (NULL == params->destv4addr) || 5263 (NULL == params->destmac)) { 5264 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5265 "destv4addr:%pK destmac:%pK ", __func__, 5266 params->hostv4addr, params->destv4addr, params->destmac); 5267 wmi_buf_free(buf); 5268 return QDF_STATUS_E_FAILURE; 5269 } 5270 cmd->method = params->method; 5271 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5272 WMI_IPV4_ADDR_LEN); 5273 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5274 WMI_IPV4_ADDR_LEN); 5275 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5276 } else { 5277 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5278 } 5279 5280 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5281 WMI_STA_KEEPALIVE_CMDID); 5282 if (QDF_IS_STATUS_ERROR(ret)) { 5283 WMI_LOGE("Failed to set KeepAlive"); 5284 wmi_buf_free(buf); 5285 } 5286 5287 WMI_LOGD("%s: Exit", __func__); 5288 return ret; 5289 } 5290 5291 /** 5292 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5293 * @wmi_handle: wmi handle 5294 * @if_id: vdev id 5295 * @gtx_info: GTX config params 5296 * 5297 * This function set GTX related params in firmware. 5298 * 5299 * Return: QDF_STATUS_SUCCESS for success or error code 5300 */ 5301 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5302 struct wmi_gtx_config *gtx_info) 5303 { 5304 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5305 wmi_buf_t buf; 5306 QDF_STATUS ret; 5307 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5308 5309 buf = wmi_buf_alloc(wmi_handle, len); 5310 if (!buf) { 5311 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5312 return QDF_STATUS_E_NOMEM; 5313 } 5314 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5315 WMITLV_SET_HDR(&cmd->tlv_header, 5316 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5317 WMITLV_GET_STRUCT_TLVLEN 5318 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5319 cmd->vdev_id = if_id; 5320 5321 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5322 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5323 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5324 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5325 cmd->gtxPERMargin = gtx_info->gtx_margin; 5326 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5327 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5328 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5329 5330 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5331 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5332 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5333 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5334 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5335 5336 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5337 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5338 if (QDF_IS_STATUS_ERROR(ret)) { 5339 WMI_LOGE("Failed to set GTX PARAMS"); 5340 wmi_buf_free(buf); 5341 } 5342 return ret; 5343 } 5344 5345 /** 5346 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5347 * @wmi_handle: wmi handle 5348 * @vdev_id: vdev id. 5349 * @wmm_vparams: edca parameters 5350 * 5351 * This function updates EDCA parameters to the target 5352 * 5353 * Return: CDF Status 5354 */ 5355 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5356 uint8_t vdev_id, bool mu_edca_param, 5357 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5358 { 5359 uint8_t *buf_ptr; 5360 wmi_buf_t buf; 5361 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5362 wmi_wmm_vparams *wmm_param; 5363 struct wmi_host_wme_vparams *twmm_param; 5364 int len = sizeof(*cmd); 5365 int ac; 5366 5367 buf = wmi_buf_alloc(wmi_handle, len); 5368 5369 if (!buf) { 5370 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5371 return QDF_STATUS_E_NOMEM; 5372 } 5373 5374 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5375 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5376 WMITLV_SET_HDR(&cmd->tlv_header, 5377 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5378 WMITLV_GET_STRUCT_TLVLEN 5379 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5380 cmd->vdev_id = vdev_id; 5381 cmd->wmm_param_type = mu_edca_param; 5382 5383 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5384 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5385 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5386 WMITLV_SET_HDR(&wmm_param->tlv_header, 5387 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5388 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5389 wmm_param->cwmin = twmm_param->cwmin; 5390 wmm_param->cwmax = twmm_param->cwmax; 5391 wmm_param->aifs = twmm_param->aifs; 5392 if (mu_edca_param) 5393 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5394 else 5395 wmm_param->txoplimit = twmm_param->txoplimit; 5396 wmm_param->acm = twmm_param->acm; 5397 wmm_param->no_ack = twmm_param->noackpolicy; 5398 } 5399 5400 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5401 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5402 goto fail; 5403 5404 return QDF_STATUS_SUCCESS; 5405 5406 fail: 5407 wmi_buf_free(buf); 5408 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5409 return QDF_STATUS_E_FAILURE; 5410 } 5411 5412 /** 5413 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5414 * @wmi_handle: wmi handle 5415 * @vdev_id: vdev id 5416 * @probe_rsp_info: probe response info 5417 * 5418 * Return: QDF_STATUS_SUCCESS for success or error code 5419 */ 5420 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5421 uint8_t vdev_id, 5422 struct wmi_probe_resp_params *probe_rsp_info) 5423 { 5424 wmi_prb_tmpl_cmd_fixed_param *cmd; 5425 wmi_bcn_prb_info *bcn_prb_info; 5426 wmi_buf_t wmi_buf; 5427 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5428 uint8_t *buf_ptr; 5429 QDF_STATUS ret; 5430 5431 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5432 5433 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5434 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5435 5436 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5437 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5438 tmpl_len_aligned; 5439 5440 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5441 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5442 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5443 return QDF_STATUS_E_INVAL; 5444 } 5445 5446 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5447 if (!wmi_buf) { 5448 WMI_LOGE(FL("wmi_buf_alloc failed")); 5449 return QDF_STATUS_E_NOMEM; 5450 } 5451 5452 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5453 5454 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5455 WMITLV_SET_HDR(&cmd->tlv_header, 5456 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5457 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5458 cmd->vdev_id = vdev_id; 5459 cmd->buf_len = tmpl_len; 5460 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5461 5462 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5463 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5464 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5465 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5466 bcn_prb_info->caps = 0; 5467 bcn_prb_info->erp = 0; 5468 buf_ptr += sizeof(wmi_bcn_prb_info); 5469 5470 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5471 buf_ptr += WMI_TLV_HDR_SIZE; 5472 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5473 5474 ret = wmi_unified_cmd_send(wmi_handle, 5475 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5476 if (QDF_IS_STATUS_ERROR(ret)) { 5477 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5478 wmi_buf_free(wmi_buf); 5479 } 5480 5481 return ret; 5482 } 5483 5484 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5485 #define WPI_IV_LEN 16 5486 5487 /** 5488 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5489 * 5490 * @dest_tx: destination address of tsc key counter 5491 * @src_tx: source address of tsc key counter 5492 * @dest_rx: destination address of rsc key counter 5493 * @src_rx: source address of rsc key counter 5494 * 5495 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5496 * 5497 * Return: None 5498 * 5499 */ 5500 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5501 uint8_t *dest_rx, uint8_t *src_rx) 5502 { 5503 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5504 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5505 } 5506 #else 5507 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5508 uint8_t *dest_rx, uint8_t *src_rx) 5509 { 5510 return; 5511 } 5512 #endif 5513 5514 /** 5515 * send_setup_install_key_cmd_tlv() - set key parameters 5516 * @wmi_handle: wmi handle 5517 * @key_params: key parameters 5518 * 5519 * This function fills structure from information 5520 * passed in key_params. 5521 * 5522 * Return: QDF_STATUS_SUCCESS - success 5523 * QDF_STATUS_E_FAILURE - failure 5524 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5525 */ 5526 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5527 struct set_key_params *key_params) 5528 { 5529 wmi_vdev_install_key_cmd_fixed_param *cmd; 5530 wmi_buf_t buf; 5531 uint8_t *buf_ptr; 5532 uint32_t len; 5533 uint8_t *key_data; 5534 QDF_STATUS status; 5535 5536 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5537 WMI_TLV_HDR_SIZE; 5538 5539 buf = wmi_buf_alloc(wmi_handle, len); 5540 if (!buf) { 5541 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5542 return QDF_STATUS_E_NOMEM; 5543 } 5544 5545 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5546 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5547 WMITLV_SET_HDR(&cmd->tlv_header, 5548 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5549 WMITLV_GET_STRUCT_TLVLEN 5550 (wmi_vdev_install_key_cmd_fixed_param)); 5551 cmd->vdev_id = key_params->vdev_id; 5552 cmd->key_ix = key_params->key_idx; 5553 5554 5555 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5556 cmd->key_flags |= key_params->key_flags; 5557 cmd->key_cipher = key_params->key_cipher; 5558 if ((key_params->key_txmic_len) && 5559 (key_params->key_rxmic_len)) { 5560 cmd->key_txmic_len = key_params->key_txmic_len; 5561 cmd->key_rxmic_len = key_params->key_rxmic_len; 5562 } 5563 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5564 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5565 key_params->tx_iv, 5566 cmd->wpi_key_rsc_counter, 5567 key_params->rx_iv); 5568 #endif 5569 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5570 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5571 roundup(key_params->key_len, sizeof(uint32_t))); 5572 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5573 qdf_mem_copy((void *)key_data, 5574 (const void *)key_params->key_data, key_params->key_len); 5575 if (key_params->key_rsc_counter) 5576 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5577 sizeof(wmi_key_seq_counter)); 5578 cmd->key_len = key_params->key_len; 5579 5580 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5581 WMI_VDEV_INSTALL_KEY_CMDID); 5582 if (QDF_IS_STATUS_ERROR(status)) 5583 wmi_buf_free(buf); 5584 5585 return status; 5586 } 5587 5588 /** 5589 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5590 * @wmi_handle: wmi handle 5591 * @params: sar limit params 5592 * 5593 * Return: QDF_STATUS_SUCCESS for success or error code 5594 */ 5595 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5596 struct sar_limit_cmd_params *sar_limit_params) 5597 { 5598 wmi_buf_t buf; 5599 QDF_STATUS qdf_status; 5600 wmi_sar_limits_cmd_fixed_param *cmd; 5601 int i; 5602 uint8_t *buf_ptr; 5603 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5604 struct sar_limit_cmd_row *sar_rows_list; 5605 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5606 5607 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5608 buf = wmi_buf_alloc(wmi_handle, len); 5609 if (!buf) { 5610 WMI_LOGE("Failed to allocate memory"); 5611 qdf_status = QDF_STATUS_E_NOMEM; 5612 goto end; 5613 } 5614 5615 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5616 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5617 WMITLV_SET_HDR(&cmd->tlv_header, 5618 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5619 WMITLV_GET_STRUCT_TLVLEN 5620 (wmi_sar_limits_cmd_fixed_param)); 5621 cmd->sar_enable = sar_limit_params->sar_enable; 5622 cmd->commit_limits = sar_limit_params->commit_limits; 5623 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5624 5625 WMI_LOGD("no of sar rows = %d, len = %d", 5626 sar_limit_params->num_limit_rows, len); 5627 buf_ptr += sizeof(*cmd); 5628 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5629 sizeof(wmi_sar_limit_cmd_row) * 5630 sar_limit_params->num_limit_rows); 5631 if (cmd->num_limit_rows == 0) 5632 goto send_sar_limits; 5633 5634 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5635 (buf_ptr + WMI_TLV_HDR_SIZE); 5636 sar_rows_list = sar_limit_params->sar_limit_row_list; 5637 5638 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5639 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5640 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5641 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5642 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5643 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5644 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5645 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5646 wmi_sar_rows_list->validity_bitmap = 5647 sar_rows_list->validity_bitmap; 5648 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5649 i, wmi_sar_rows_list->band_id, 5650 wmi_sar_rows_list->chain_id, 5651 wmi_sar_rows_list->mod_id, 5652 wmi_sar_rows_list->limit_value, 5653 wmi_sar_rows_list->validity_bitmap); 5654 sar_rows_list++; 5655 wmi_sar_rows_list++; 5656 } 5657 send_sar_limits: 5658 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5659 WMI_SAR_LIMITS_CMDID); 5660 5661 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5662 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5663 wmi_buf_free(buf); 5664 } 5665 5666 end: 5667 return qdf_status; 5668 } 5669 5670 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5671 { 5672 wmi_sar_get_limits_cmd_fixed_param *cmd; 5673 wmi_buf_t wmi_buf; 5674 uint32_t len; 5675 QDF_STATUS status; 5676 5677 WMI_LOGD(FL("Enter")); 5678 5679 len = sizeof(*cmd); 5680 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5681 if (!wmi_buf) { 5682 WMI_LOGP(FL("failed to allocate memory for msg")); 5683 return QDF_STATUS_E_NOMEM; 5684 } 5685 5686 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5687 5688 WMITLV_SET_HDR(&cmd->tlv_header, 5689 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5690 WMITLV_GET_STRUCT_TLVLEN 5691 (wmi_sar_get_limits_cmd_fixed_param)); 5692 5693 cmd->reserved = 0; 5694 5695 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5696 WMI_SAR_GET_LIMITS_CMDID); 5697 if (QDF_IS_STATUS_ERROR(status)) { 5698 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5699 wmi_buf_free(wmi_buf); 5700 } 5701 5702 WMI_LOGD(FL("Exit")); 5703 5704 return status; 5705 } 5706 5707 /** 5708 * wmi_sar2_result_string() - return string conversion of sar2 result 5709 * @result: sar2 result value 5710 * 5711 * This utility function helps log string conversion of sar2 result. 5712 * 5713 * Return: string conversion of sar 2 result, if match found; 5714 * "Unknown response" otherwise. 5715 */ 5716 static const char *wmi_sar2_result_string(uint32_t result) 5717 { 5718 switch (result) { 5719 CASE_RETURN_STRING(WMI_SAR2_SUCCESS); 5720 CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX); 5721 CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX); 5722 CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR); 5723 CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE); 5724 default: 5725 return "Unknown response"; 5726 } 5727 } 5728 5729 /** 5730 * extract_sar2_result_event_tlv() - process sar response event from FW. 5731 * @handle: wma handle 5732 * @event: event buffer 5733 * @len: buffer length 5734 * 5735 * Return: 0 for success or error code 5736 */ 5737 static QDF_STATUS extract_sar2_result_event_tlv(void *handle, 5738 uint8_t *event, 5739 uint32_t len) 5740 { 5741 wmi_sar2_result_event_fixed_param *sar2_fixed_param; 5742 5743 WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf = 5744 (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event; 5745 5746 if (!param_buf) { 5747 WMI_LOGI("Invalid sar2 result event buffer"); 5748 return QDF_STATUS_E_INVAL; 5749 } 5750 5751 sar2_fixed_param = param_buf->fixed_param; 5752 if (!sar2_fixed_param) { 5753 WMI_LOGI("Invalid sar2 result event fixed param buffer"); 5754 return QDF_STATUS_E_INVAL; 5755 } 5756 5757 WMI_LOGI("SAR2 result: %s", 5758 wmi_sar2_result_string(sar2_fixed_param->result)); 5759 5760 return QDF_STATUS_SUCCESS; 5761 } 5762 5763 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5764 uint8_t *evt_buf, 5765 struct sar_limit_event *event) 5766 { 5767 wmi_sar_get_limits_event_fixed_param *fixed_param; 5768 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5769 wmi_sar_get_limit_event_row *row_in; 5770 struct sar_limit_event_row *row_out; 5771 uint32_t row; 5772 5773 if (!evt_buf) { 5774 WMI_LOGE(FL("input event is NULL")); 5775 return QDF_STATUS_E_INVAL; 5776 } 5777 if (!event) { 5778 WMI_LOGE(FL("output event is NULL")); 5779 return QDF_STATUS_E_INVAL; 5780 } 5781 5782 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5783 5784 fixed_param = param_buf->fixed_param; 5785 if (!fixed_param) { 5786 WMI_LOGE(FL("Invalid fixed param")); 5787 return QDF_STATUS_E_INVAL; 5788 } 5789 5790 event->sar_enable = fixed_param->sar_enable; 5791 event->num_limit_rows = fixed_param->num_limit_rows; 5792 5793 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5794 QDF_ASSERT(0); 5795 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5796 event->num_limit_rows, 5797 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5798 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5799 } 5800 5801 row_in = param_buf->sar_get_limits; 5802 row_out = &event->sar_limit_row[0]; 5803 for (row = 0; row < event->num_limit_rows; row++) { 5804 row_out->band_id = row_in->band_id; 5805 row_out->chain_id = row_in->chain_id; 5806 row_out->mod_id = row_in->mod_id; 5807 row_out->limit_value = row_in->limit_value; 5808 row_out++; 5809 row_in++; 5810 } 5811 5812 return QDF_STATUS_SUCCESS; 5813 } 5814 5815 #ifdef WLAN_FEATURE_DISA 5816 /** 5817 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5818 * @wmi_handle: wmi handle 5819 * @params: encrypt/decrypt params 5820 * 5821 * Return: QDF_STATUS_SUCCESS for success or error code 5822 */ 5823 static 5824 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5825 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5826 { 5827 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5828 wmi_buf_t wmi_buf; 5829 uint8_t *buf_ptr; 5830 QDF_STATUS ret; 5831 uint32_t len; 5832 5833 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5834 5835 len = sizeof(*cmd) + 5836 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5837 WMI_TLV_HDR_SIZE; 5838 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5839 if (!wmi_buf) { 5840 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5841 __func__); 5842 return QDF_STATUS_E_NOMEM; 5843 } 5844 5845 buf_ptr = wmi_buf_data(wmi_buf); 5846 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5847 5848 WMITLV_SET_HDR(&cmd->tlv_header, 5849 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5850 WMITLV_GET_STRUCT_TLVLEN( 5851 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5852 5853 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5854 cmd->key_flag = encrypt_decrypt_params->key_flag; 5855 cmd->key_idx = encrypt_decrypt_params->key_idx; 5856 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5857 cmd->key_len = encrypt_decrypt_params->key_len; 5858 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5859 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5860 5861 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5862 encrypt_decrypt_params->key_len); 5863 5864 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5865 MAX_MAC_HEADER_LEN); 5866 5867 cmd->data_len = encrypt_decrypt_params->data_len; 5868 5869 if (cmd->data_len) { 5870 buf_ptr += sizeof(*cmd); 5871 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5872 roundup(encrypt_decrypt_params->data_len, 5873 sizeof(uint32_t))); 5874 buf_ptr += WMI_TLV_HDR_SIZE; 5875 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5876 encrypt_decrypt_params->data_len); 5877 } 5878 5879 /* This conversion is to facilitate data to FW in little endian */ 5880 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5881 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5882 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5883 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 5884 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 5885 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 5886 5887 ret = wmi_unified_cmd_send(wmi_handle, 5888 wmi_buf, len, 5889 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 5890 if (QDF_IS_STATUS_ERROR(ret)) { 5891 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 5892 wmi_buf_free(wmi_buf); 5893 } 5894 5895 return ret; 5896 } 5897 5898 /** 5899 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 5900 * params from event 5901 * @wmi_handle: wmi handle 5902 * @evt_buf: pointer to event buffer 5903 * @resp: Pointer to hold resp parameters 5904 * 5905 * Return: QDF_STATUS_SUCCESS for success or error code 5906 */ 5907 static 5908 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 5909 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 5910 { 5911 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 5912 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 5913 5914 param_buf = evt_buf; 5915 if (!param_buf) { 5916 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 5917 return QDF_STATUS_E_INVAL; 5918 } 5919 5920 data_event = param_buf->fixed_param; 5921 5922 resp->vdev_id = data_event->vdev_id; 5923 resp->status = data_event->status; 5924 5925 if ((data_event->data_length > param_buf->num_enc80211_frame) || 5926 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE - 5927 sizeof(*data_event))) { 5928 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 5929 data_event->data_length, 5930 param_buf->num_enc80211_frame); 5931 return QDF_STATUS_E_INVAL; 5932 } 5933 5934 resp->data_len = data_event->data_length; 5935 5936 if (resp->data_len) 5937 resp->data = (uint8_t *)param_buf->enc80211_frame; 5938 5939 return QDF_STATUS_SUCCESS; 5940 } 5941 #endif 5942 5943 /** 5944 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5945 * @wmi_handle: wmi handle 5946 * @vdev_id: vdev id 5947 * @p2p_ie: p2p IE 5948 * 5949 * Return: QDF_STATUS_SUCCESS for success or error code 5950 */ 5951 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5952 uint32_t vdev_id, uint8_t *p2p_ie) 5953 { 5954 QDF_STATUS ret; 5955 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5956 wmi_buf_t wmi_buf; 5957 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5958 uint8_t *buf_ptr; 5959 5960 ie_len = (uint32_t) (p2p_ie[1] + 2); 5961 5962 /* More than one P2P IE may be included in a single frame. 5963 If multiple P2P IEs are present, the complete P2P attribute 5964 data consists of the concatenation of the P2P Attribute 5965 fields of the P2P IEs. The P2P Attributes field of each 5966 P2P IE may be any length up to the maximum (251 octets). 5967 In this case host sends one P2P IE to firmware so the length 5968 should not exceed more than 251 bytes 5969 */ 5970 if (ie_len > 251) { 5971 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 5972 return QDF_STATUS_E_INVAL; 5973 } 5974 5975 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5976 5977 wmi_buf_len = 5978 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5979 WMI_TLV_HDR_SIZE; 5980 5981 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5982 if (!wmi_buf) { 5983 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 5984 return QDF_STATUS_E_NOMEM; 5985 } 5986 5987 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5988 5989 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5990 WMITLV_SET_HDR(&cmd->tlv_header, 5991 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5992 WMITLV_GET_STRUCT_TLVLEN 5993 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5994 cmd->vdev_id = vdev_id; 5995 cmd->ie_buf_len = ie_len; 5996 5997 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5999 buf_ptr += WMI_TLV_HDR_SIZE; 6000 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6001 6002 WMI_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 6003 6004 ret = wmi_unified_cmd_send(wmi_handle, 6005 wmi_buf, wmi_buf_len, 6006 WMI_P2P_GO_SET_BEACON_IE); 6007 if (QDF_IS_STATUS_ERROR(ret)) { 6008 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 6009 wmi_buf_free(wmi_buf); 6010 } 6011 6012 WMI_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 6013 return ret; 6014 } 6015 6016 /** 6017 * send_set_gateway_params_cmd_tlv() - set gateway parameters 6018 * @wmi_handle: wmi handle 6019 * @req: gateway parameter update request structure 6020 * 6021 * This function reads the incoming @req and fill in the destination 6022 * WMI structure and sends down the gateway configs down to the firmware 6023 * 6024 * Return: QDF_STATUS 6025 */ 6026 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 6027 struct gateway_update_req_param *req) 6028 { 6029 wmi_roam_subnet_change_config_fixed_param *cmd; 6030 wmi_buf_t buf; 6031 QDF_STATUS ret; 6032 int len = sizeof(*cmd); 6033 6034 buf = wmi_buf_alloc(wmi_handle, len); 6035 if (!buf) { 6036 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6037 return QDF_STATUS_E_NOMEM; 6038 } 6039 6040 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 6041 WMITLV_SET_HDR(&cmd->tlv_header, 6042 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 6043 WMITLV_GET_STRUCT_TLVLEN( 6044 wmi_roam_subnet_change_config_fixed_param)); 6045 6046 cmd->vdev_id = req->session_id; 6047 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 6048 QDF_IPV4_ADDR_SIZE); 6049 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 6050 QDF_IPV6_ADDR_SIZE); 6051 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 6052 &cmd->inet_gw_mac_addr); 6053 cmd->max_retries = req->max_retries; 6054 cmd->timeout = req->timeout; 6055 cmd->num_skip_subnet_change_detection_bssid_list = 0; 6056 cmd->flag = 0; 6057 if (req->ipv4_addr_type) 6058 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 6059 6060 if (req->ipv6_addr_type) 6061 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 6062 6063 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6064 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 6065 if (QDF_IS_STATUS_ERROR(ret)) { 6066 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 6067 ret); 6068 wmi_buf_free(buf); 6069 } 6070 6071 return ret; 6072 } 6073 6074 /** 6075 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 6076 * @wmi_handle: wmi handle 6077 * @req: rssi monitoring request structure 6078 * 6079 * This function reads the incoming @req and fill in the destination 6080 * WMI structure and send down the rssi monitoring configs down to the firmware 6081 * 6082 * Return: 0 on success; error number otherwise 6083 */ 6084 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 6085 struct rssi_monitor_param *req) 6086 { 6087 wmi_rssi_breach_monitor_config_fixed_param *cmd; 6088 wmi_buf_t buf; 6089 QDF_STATUS ret; 6090 uint32_t len = sizeof(*cmd); 6091 6092 buf = wmi_buf_alloc(wmi_handle, len); 6093 if (!buf) { 6094 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6095 return QDF_STATUS_E_NOMEM; 6096 } 6097 6098 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 6099 WMITLV_SET_HDR(&cmd->tlv_header, 6100 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 6101 WMITLV_GET_STRUCT_TLVLEN( 6102 wmi_rssi_breach_monitor_config_fixed_param)); 6103 6104 cmd->vdev_id = req->session_id; 6105 cmd->request_id = req->request_id; 6106 cmd->lo_rssi_reenable_hysteresis = 0; 6107 cmd->hi_rssi_reenable_histeresis = 0; 6108 cmd->min_report_interval = 0; 6109 cmd->max_num_report = 1; 6110 if (req->control) { 6111 /* enable one threshold for each min/max */ 6112 cmd->enabled_bitmap = 0x09; 6113 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 6114 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 6115 } else { 6116 cmd->enabled_bitmap = 0; 6117 cmd->low_rssi_breach_threshold[0] = 0; 6118 cmd->hi_rssi_breach_threshold[0] = 0; 6119 } 6120 6121 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6122 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 6123 if (QDF_IS_STATUS_ERROR(ret)) { 6124 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 6125 wmi_buf_free(buf); 6126 } 6127 6128 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 6129 6130 return ret; 6131 } 6132 6133 /** 6134 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6135 * @wmi_handle: wmi handle 6136 * @psetoui: OUI parameters 6137 * 6138 * set scan probe OUI parameters in firmware 6139 * 6140 * Return: CDF status 6141 */ 6142 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6143 struct scan_mac_oui *psetoui) 6144 { 6145 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6146 wmi_buf_t wmi_buf; 6147 uint32_t len; 6148 uint8_t *buf_ptr; 6149 uint32_t *oui_buf; 6150 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 6151 6152 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6153 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 6154 6155 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6156 if (!wmi_buf) { 6157 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 6158 return QDF_STATUS_E_NOMEM; 6159 } 6160 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6161 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6162 WMITLV_SET_HDR(&cmd->tlv_header, 6163 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6164 WMITLV_GET_STRUCT_TLVLEN 6165 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6166 6167 oui_buf = &cmd->prob_req_oui; 6168 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6169 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6170 | psetoui->oui[2]; 6171 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 6172 cmd->prob_req_oui); 6173 6174 cmd->vdev_id = psetoui->vdev_id; 6175 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6176 if (psetoui->enb_probe_req_sno_randomization) 6177 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6178 6179 if (ie_whitelist->white_list) { 6180 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 6181 &cmd->num_vendor_oui, 6182 ie_whitelist); 6183 cmd->flags |= 6184 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6185 } 6186 6187 buf_ptr += sizeof(*cmd); 6188 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6189 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6190 buf_ptr += WMI_TLV_HDR_SIZE; 6191 6192 if (cmd->num_vendor_oui != 0) { 6193 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6194 ie_whitelist->voui); 6195 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6196 } 6197 6198 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6199 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6200 WMI_LOGE("%s: failed to send command", __func__); 6201 wmi_buf_free(wmi_buf); 6202 return QDF_STATUS_E_FAILURE; 6203 } 6204 return QDF_STATUS_SUCCESS; 6205 } 6206 6207 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6208 /** 6209 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6210 * @wmi_handle: wmi handle 6211 * @roam_req: Roam scan offload params 6212 * @buf_ptr: command buffer to send 6213 * @fils_tlv_len: fils tlv length 6214 * 6215 * Return: Updated buffer pointer 6216 */ 6217 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6218 struct roam_offload_scan_params *roam_req, 6219 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6220 { 6221 wmi_roam_fils_offload_tlv_param *fils_tlv; 6222 wmi_erp_info *erp_info; 6223 struct roam_fils_params *roam_fils_params; 6224 6225 if (!roam_req->add_fils_tlv) 6226 return buf_ptr; 6227 6228 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6229 sizeof(*fils_tlv)); 6230 buf_ptr += WMI_TLV_HDR_SIZE; 6231 6232 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6233 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6234 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6235 WMITLV_GET_STRUCT_TLVLEN 6236 (wmi_roam_fils_offload_tlv_param)); 6237 6238 roam_fils_params = &roam_req->roam_fils_params; 6239 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6240 6241 erp_info->username_length = roam_fils_params->username_length; 6242 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6243 erp_info->username_length); 6244 6245 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6246 6247 erp_info->rRk_length = roam_fils_params->rrk_length; 6248 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6249 erp_info->rRk_length); 6250 6251 erp_info->rIk_length = roam_fils_params->rik_length; 6252 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6253 erp_info->rIk_length); 6254 6255 erp_info->realm_len = roam_fils_params->realm_len; 6256 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6257 erp_info->realm_len); 6258 6259 buf_ptr += sizeof(*fils_tlv); 6260 return buf_ptr; 6261 } 6262 #else 6263 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6264 struct roam_offload_scan_params *roam_req, 6265 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6266 { 6267 return buf_ptr; 6268 } 6269 #endif 6270 /** 6271 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6272 * @wmi_handle: wmi handle 6273 * @scan_cmd_fp: start scan command ptr 6274 * @roam_req: roam request param 6275 * 6276 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6277 * of WMI_ROAM_SCAN_MODE. 6278 * 6279 * Return: QDF status 6280 */ 6281 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6282 wmi_start_scan_cmd_fixed_param * 6283 scan_cmd_fp, 6284 struct roam_offload_scan_params *roam_req) 6285 { 6286 wmi_buf_t buf = NULL; 6287 QDF_STATUS status; 6288 int len; 6289 uint8_t *buf_ptr; 6290 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6291 6292 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6293 int auth_mode = roam_req->auth_mode; 6294 wmi_roam_offload_tlv_param *roam_offload_params; 6295 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6296 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6297 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6298 wmi_tlv_buf_len_param *assoc_ies; 6299 uint32_t fils_tlv_len = 0; 6300 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6301 /* Need to create a buf with roam_scan command at 6302 * front and piggyback with scan command */ 6303 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6304 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6305 (2 * WMI_TLV_HDR_SIZE) + 6306 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6307 sizeof(wmi_start_scan_cmd_fixed_param); 6308 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6309 WMI_LOGD("auth_mode = %d", auth_mode); 6310 if (roam_req->is_roam_req_valid && 6311 roam_req->roam_offload_enabled) { 6312 len += sizeof(wmi_roam_offload_tlv_param); 6313 len += WMI_TLV_HDR_SIZE; 6314 if ((auth_mode != WMI_AUTH_NONE) && 6315 ((auth_mode != WMI_AUTH_OPEN) || 6316 (auth_mode == WMI_AUTH_OPEN && 6317 roam_req->mdid.mdie_present && 6318 roam_req->is_11r_assoc) || 6319 roam_req->is_ese_assoc)) { 6320 len += WMI_TLV_HDR_SIZE; 6321 if (roam_req->is_ese_assoc) 6322 len += 6323 sizeof(wmi_roam_ese_offload_tlv_param); 6324 else if (auth_mode == WMI_AUTH_FT_RSNA || 6325 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6326 (auth_mode == WMI_AUTH_OPEN && 6327 roam_req->mdid.mdie_present && 6328 roam_req->is_11r_assoc)) 6329 len += 6330 sizeof(wmi_roam_11r_offload_tlv_param); 6331 else 6332 len += 6333 sizeof(wmi_roam_11i_offload_tlv_param); 6334 } else { 6335 len += WMI_TLV_HDR_SIZE; 6336 } 6337 6338 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6339 + roundup(roam_req->assoc_ie_length, 6340 sizeof(uint32_t))); 6341 6342 if (roam_req->add_fils_tlv) { 6343 fils_tlv_len = sizeof( 6344 wmi_roam_fils_offload_tlv_param); 6345 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6346 } 6347 } else { 6348 if (roam_req->is_roam_req_valid) 6349 WMI_LOGD("%s : roam offload = %d", 6350 __func__, roam_req->roam_offload_enabled); 6351 else 6352 WMI_LOGD("%s : roam_req is NULL", __func__); 6353 len += (4 * WMI_TLV_HDR_SIZE); 6354 } 6355 if (roam_req->is_roam_req_valid && 6356 roam_req->roam_offload_enabled) { 6357 roam_req->mode = roam_req->mode | 6358 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6359 } 6360 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6361 6362 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6363 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6364 len = sizeof(wmi_roam_scan_mode_fixed_param); 6365 6366 buf = wmi_buf_alloc(wmi_handle, len); 6367 if (!buf) { 6368 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6369 return QDF_STATUS_E_NOMEM; 6370 } 6371 6372 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6373 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6374 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6375 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6376 WMITLV_GET_STRUCT_TLVLEN 6377 (wmi_roam_scan_mode_fixed_param)); 6378 6379 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6380 roam_req->roam_trigger_reason_bitmask; 6381 roam_scan_mode_fp->min_delay_btw_scans = 6382 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6383 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6384 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6385 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6386 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6387 roam_scan_mode_fp->flags |= 6388 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6389 goto send_roam_scan_mode_cmd; 6390 } 6391 6392 /* Fill in scan parameters suitable for roaming scan */ 6393 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6394 6395 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6396 sizeof(wmi_start_scan_cmd_fixed_param)); 6397 /* Ensure there is no additional IEs */ 6398 scan_cmd_fp->ie_len = 0; 6399 WMITLV_SET_HDR(buf_ptr, 6400 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6401 WMITLV_GET_STRUCT_TLVLEN 6402 (wmi_start_scan_cmd_fixed_param)); 6403 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6404 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6405 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6406 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6407 sizeof(wmi_roam_offload_tlv_param)); 6408 buf_ptr += WMI_TLV_HDR_SIZE; 6409 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6410 WMITLV_SET_HDR(buf_ptr, 6411 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6412 WMITLV_GET_STRUCT_TLVLEN 6413 (wmi_roam_offload_tlv_param)); 6414 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6415 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6416 roam_offload_params->select_5g_margin = 6417 roam_req->select_5ghz_margin; 6418 roam_offload_params->handoff_delay_for_rx = 6419 roam_req->roam_offload_params.ho_delay_for_rx; 6420 roam_offload_params->reassoc_failure_timeout = 6421 roam_req->reassoc_failure_timeout; 6422 6423 /* Fill the capabilities */ 6424 roam_offload_params->capability = 6425 roam_req->roam_offload_params.capability; 6426 roam_offload_params->ht_caps_info = 6427 roam_req->roam_offload_params.ht_caps_info; 6428 roam_offload_params->ampdu_param = 6429 roam_req->roam_offload_params.ampdu_param; 6430 roam_offload_params->ht_ext_cap = 6431 roam_req->roam_offload_params.ht_ext_cap; 6432 roam_offload_params->ht_txbf = 6433 roam_req->roam_offload_params.ht_txbf; 6434 roam_offload_params->asel_cap = 6435 roam_req->roam_offload_params.asel_cap; 6436 roam_offload_params->qos_caps = 6437 roam_req->roam_offload_params.qos_caps; 6438 roam_offload_params->qos_enabled = 6439 roam_req->roam_offload_params.qos_enabled; 6440 roam_offload_params->wmm_caps = 6441 roam_req->roam_offload_params.wmm_caps; 6442 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6443 (uint8_t *)roam_req->roam_offload_params.mcsset, 6444 ROAM_OFFLOAD_NUM_MCS_SET); 6445 6446 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6447 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6448 * they are filled in the same order.Depending on the 6449 * authentication type, the other mode TLV's are nullified 6450 * and only headers are filled.*/ 6451 if ((auth_mode != WMI_AUTH_NONE) && 6452 ((auth_mode != WMI_AUTH_OPEN) || 6453 (auth_mode == WMI_AUTH_OPEN 6454 && roam_req->mdid.mdie_present && 6455 roam_req->is_11r_assoc) || 6456 roam_req->is_ese_assoc)) { 6457 if (roam_req->is_ese_assoc) { 6458 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6459 WMITLV_GET_STRUCT_TLVLEN(0)); 6460 buf_ptr += WMI_TLV_HDR_SIZE; 6461 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6462 WMITLV_GET_STRUCT_TLVLEN(0)); 6463 buf_ptr += WMI_TLV_HDR_SIZE; 6464 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6465 sizeof(wmi_roam_ese_offload_tlv_param)); 6466 buf_ptr += WMI_TLV_HDR_SIZE; 6467 roam_offload_ese = 6468 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6469 qdf_mem_copy(roam_offload_ese->krk, 6470 roam_req->krk, 6471 sizeof(roam_req->krk)); 6472 qdf_mem_copy(roam_offload_ese->btk, 6473 roam_req->btk, 6474 sizeof(roam_req->btk)); 6475 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6476 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6477 WMITLV_GET_STRUCT_TLVLEN 6478 (wmi_roam_ese_offload_tlv_param)); 6479 buf_ptr += 6480 sizeof(wmi_roam_ese_offload_tlv_param); 6481 } else if (auth_mode == WMI_AUTH_FT_RSNA 6482 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6483 || (auth_mode == WMI_AUTH_OPEN 6484 && roam_req->mdid.mdie_present && 6485 roam_req->is_11r_assoc)) { 6486 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6487 0); 6488 buf_ptr += WMI_TLV_HDR_SIZE; 6489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6490 sizeof(wmi_roam_11r_offload_tlv_param)); 6491 buf_ptr += WMI_TLV_HDR_SIZE; 6492 roam_offload_11r = 6493 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6494 roam_offload_11r->r0kh_id_len = 6495 roam_req->rokh_id_length; 6496 qdf_mem_copy(roam_offload_11r->r0kh_id, 6497 roam_req->rokh_id, 6498 roam_offload_11r->r0kh_id_len); 6499 qdf_mem_copy(roam_offload_11r->psk_msk, 6500 roam_req->psk_pmk, 6501 sizeof(roam_req->psk_pmk)); 6502 roam_offload_11r->psk_msk_len = 6503 roam_req->pmk_len; 6504 roam_offload_11r->mdie_present = 6505 roam_req->mdid.mdie_present; 6506 roam_offload_11r->mdid = 6507 roam_req->mdid.mobility_domain; 6508 if (auth_mode == WMI_AUTH_OPEN) { 6509 /* If FT-Open ensure pmk length 6510 and r0khid len are zero */ 6511 roam_offload_11r->r0kh_id_len = 0; 6512 roam_offload_11r->psk_msk_len = 0; 6513 } 6514 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6515 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6516 WMITLV_GET_STRUCT_TLVLEN 6517 (wmi_roam_11r_offload_tlv_param)); 6518 buf_ptr += 6519 sizeof(wmi_roam_11r_offload_tlv_param); 6520 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6521 WMITLV_GET_STRUCT_TLVLEN(0)); 6522 buf_ptr += WMI_TLV_HDR_SIZE; 6523 WMI_LOGD("psk_msk_len = %d", 6524 roam_offload_11r->psk_msk_len); 6525 if (roam_offload_11r->psk_msk_len) 6526 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6527 QDF_TRACE_LEVEL_DEBUG, 6528 roam_offload_11r->psk_msk, 6529 roam_offload_11r->psk_msk_len); 6530 } else { 6531 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6532 sizeof(wmi_roam_11i_offload_tlv_param)); 6533 buf_ptr += WMI_TLV_HDR_SIZE; 6534 roam_offload_11i = 6535 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6536 6537 if (roam_req->roam_key_mgmt_offload_enabled && 6538 roam_req->fw_okc) { 6539 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6540 (roam_offload_11i->flags); 6541 WMI_LOGI("LFR3:OKC enabled"); 6542 } else { 6543 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6544 (roam_offload_11i->flags); 6545 WMI_LOGI("LFR3:OKC disabled"); 6546 } 6547 if (roam_req->roam_key_mgmt_offload_enabled && 6548 roam_req->fw_pmksa_cache) { 6549 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6550 (roam_offload_11i->flags); 6551 WMI_LOGI("LFR3:PMKSA caching enabled"); 6552 } else { 6553 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6554 (roam_offload_11i->flags); 6555 WMI_LOGI("LFR3:PMKSA caching disabled"); 6556 } 6557 6558 qdf_mem_copy(roam_offload_11i->pmk, 6559 roam_req->psk_pmk, 6560 sizeof(roam_req->psk_pmk)); 6561 roam_offload_11i->pmk_len = roam_req->pmk_len; 6562 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6563 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6564 WMITLV_GET_STRUCT_TLVLEN 6565 (wmi_roam_11i_offload_tlv_param)); 6566 buf_ptr += 6567 sizeof(wmi_roam_11i_offload_tlv_param); 6568 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6569 0); 6570 buf_ptr += WMI_TLV_HDR_SIZE; 6571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6572 0); 6573 buf_ptr += WMI_TLV_HDR_SIZE; 6574 WMI_LOGD("pmk_len = %d", 6575 roam_offload_11i->pmk_len); 6576 if (roam_offload_11i->pmk_len) 6577 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6578 QDF_TRACE_LEVEL_DEBUG, 6579 roam_offload_11i->pmk, 6580 roam_offload_11i->pmk_len); 6581 } 6582 } else { 6583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6584 WMITLV_GET_STRUCT_TLVLEN(0)); 6585 buf_ptr += WMI_TLV_HDR_SIZE; 6586 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6587 WMITLV_GET_STRUCT_TLVLEN(0)); 6588 buf_ptr += WMI_TLV_HDR_SIZE; 6589 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6590 WMITLV_GET_STRUCT_TLVLEN(0)); 6591 buf_ptr += WMI_TLV_HDR_SIZE; 6592 } 6593 6594 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6595 sizeof(*assoc_ies)); 6596 buf_ptr += WMI_TLV_HDR_SIZE; 6597 6598 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6599 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6600 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6601 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6602 assoc_ies->buf_len = roam_req->assoc_ie_length; 6603 6604 buf_ptr += sizeof(*assoc_ies); 6605 6606 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6607 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6608 buf_ptr += WMI_TLV_HDR_SIZE; 6609 6610 if (assoc_ies->buf_len != 0) { 6611 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6612 assoc_ies->buf_len); 6613 } 6614 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6615 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6616 buf_ptr, fils_tlv_len); 6617 } else { 6618 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6619 WMITLV_GET_STRUCT_TLVLEN(0)); 6620 buf_ptr += WMI_TLV_HDR_SIZE; 6621 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6622 WMITLV_GET_STRUCT_TLVLEN(0)); 6623 buf_ptr += WMI_TLV_HDR_SIZE; 6624 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6625 WMITLV_GET_STRUCT_TLVLEN(0)); 6626 buf_ptr += WMI_TLV_HDR_SIZE; 6627 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6628 WMITLV_GET_STRUCT_TLVLEN(0)); 6629 buf_ptr += WMI_TLV_HDR_SIZE; 6630 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6631 WMITLV_GET_STRUCT_TLVLEN(0)); 6632 buf_ptr += WMI_TLV_HDR_SIZE; 6633 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6634 WMITLV_GET_STRUCT_TLVLEN(0)); 6635 } 6636 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6637 6638 send_roam_scan_mode_cmd: 6639 status = wmi_unified_cmd_send(wmi_handle, buf, 6640 len, WMI_ROAM_SCAN_MODE); 6641 if (QDF_IS_STATUS_ERROR(status)) { 6642 WMI_LOGE( 6643 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6644 status); 6645 wmi_buf_free(buf); 6646 } 6647 6648 return status; 6649 } 6650 6651 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6652 struct wmi_mawc_roam_params *params) 6653 { 6654 wmi_buf_t buf = NULL; 6655 QDF_STATUS status; 6656 int len; 6657 uint8_t *buf_ptr; 6658 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6659 6660 len = sizeof(*wmi_roam_mawc_params); 6661 buf = wmi_buf_alloc(wmi_handle, len); 6662 if (!buf) { 6663 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6664 return QDF_STATUS_E_NOMEM; 6665 } 6666 6667 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6668 wmi_roam_mawc_params = 6669 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6670 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6671 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6672 WMITLV_GET_STRUCT_TLVLEN 6673 (wmi_roam_configure_mawc_cmd_fixed_param)); 6674 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6675 if (params->enable) 6676 wmi_roam_mawc_params->enable = 1; 6677 else 6678 wmi_roam_mawc_params->enable = 0; 6679 wmi_roam_mawc_params->traffic_load_threshold = 6680 params->traffic_load_threshold; 6681 wmi_roam_mawc_params->best_ap_rssi_threshold = 6682 params->best_ap_rssi_threshold; 6683 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6684 params->rssi_stationary_high_adjust; 6685 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6686 params->rssi_stationary_low_adjust; 6687 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6688 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6689 wmi_roam_mawc_params->traffic_load_threshold, 6690 wmi_roam_mawc_params->best_ap_rssi_threshold, 6691 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6692 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6693 6694 status = wmi_unified_cmd_send(wmi_handle, buf, 6695 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6696 if (QDF_IS_STATUS_ERROR(status)) { 6697 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6698 status); 6699 wmi_buf_free(buf); 6700 return status; 6701 } 6702 6703 return QDF_STATUS_SUCCESS; 6704 } 6705 6706 /** 6707 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6708 * rssi threashold 6709 * @wmi_handle: wmi handle 6710 * @roam_req: Roaming request buffer 6711 * 6712 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6713 * 6714 * Return: QDF status 6715 */ 6716 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6717 struct roam_offload_scan_rssi_params *roam_req) 6718 { 6719 wmi_buf_t buf = NULL; 6720 QDF_STATUS status; 6721 int len; 6722 uint8_t *buf_ptr; 6723 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6724 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6725 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6726 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6727 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6728 6729 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6730 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6731 len += sizeof(wmi_roam_scan_extended_threshold_param); 6732 len += WMI_TLV_HDR_SIZE; 6733 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6734 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6735 len += sizeof(wmi_roam_dense_thres_param); 6736 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6737 len += sizeof(wmi_roam_bg_scan_roaming_param); 6738 buf = wmi_buf_alloc(wmi_handle, len); 6739 if (!buf) { 6740 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6741 return QDF_STATUS_E_NOMEM; 6742 } 6743 6744 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6745 rssi_threshold_fp = 6746 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6747 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6748 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6749 WMITLV_GET_STRUCT_TLVLEN 6750 (wmi_roam_scan_rssi_threshold_fixed_param)); 6751 /* fill in threshold values */ 6752 rssi_threshold_fp->vdev_id = roam_req->session_id; 6753 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6754 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6755 rssi_threshold_fp->hirssi_scan_max_count = 6756 roam_req->hi_rssi_scan_max_count; 6757 rssi_threshold_fp->hirssi_scan_delta = 6758 roam_req->hi_rssi_scan_rssi_delta; 6759 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6760 rssi_threshold_fp->rssi_thresh_offset_5g = 6761 roam_req->rssi_thresh_offset_5g; 6762 6763 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6764 WMITLV_SET_HDR(buf_ptr, 6765 WMITLV_TAG_ARRAY_STRUC, 6766 sizeof(wmi_roam_scan_extended_threshold_param)); 6767 buf_ptr += WMI_TLV_HDR_SIZE; 6768 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6769 6770 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6771 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6772 ext_thresholds->boost_threshold_5g = 6773 roam_req->boost_threshold_5g; 6774 6775 ext_thresholds->boost_algorithm_5g = 6776 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6777 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6778 ext_thresholds->penalty_algorithm_5g = 6779 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6780 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6781 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6782 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6783 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6784 6785 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6786 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6787 WMITLV_GET_STRUCT_TLVLEN 6788 (wmi_roam_scan_extended_threshold_param)); 6789 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6790 WMITLV_SET_HDR(buf_ptr, 6791 WMITLV_TAG_ARRAY_STRUC, 6792 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6793 buf_ptr += WMI_TLV_HDR_SIZE; 6794 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6795 early_stop_thresholds->roam_earlystop_thres_min = 6796 roam_req->roam_earlystop_thres_min; 6797 early_stop_thresholds->roam_earlystop_thres_max = 6798 roam_req->roam_earlystop_thres_max; 6799 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6800 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6801 WMITLV_GET_STRUCT_TLVLEN 6802 (wmi_roam_earlystop_rssi_thres_param)); 6803 6804 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6805 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6806 sizeof(wmi_roam_dense_thres_param)); 6807 buf_ptr += WMI_TLV_HDR_SIZE; 6808 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6809 dense_thresholds->roam_dense_rssi_thres_offset = 6810 roam_req->dense_rssi_thresh_offset; 6811 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6812 dense_thresholds->roam_dense_traffic_thres = 6813 roam_req->traffic_threshold; 6814 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6815 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6816 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6817 WMITLV_GET_STRUCT_TLVLEN 6818 (wmi_roam_dense_thres_param)); 6819 6820 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6821 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6822 sizeof(wmi_roam_bg_scan_roaming_param)); 6823 buf_ptr += WMI_TLV_HDR_SIZE; 6824 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6825 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6826 roam_req->bg_scan_bad_rssi_thresh; 6827 bg_scan_params->roam_bg_scan_client_bitmap = 6828 roam_req->bg_scan_client_bitmap; 6829 bg_scan_params->bad_rssi_thresh_offset_2g = 6830 roam_req->roam_bad_rssi_thresh_offset_2g; 6831 bg_scan_params->flags = roam_req->flags; 6832 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6833 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6834 WMITLV_GET_STRUCT_TLVLEN 6835 (wmi_roam_bg_scan_roaming_param)); 6836 6837 status = wmi_unified_cmd_send(wmi_handle, buf, 6838 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6839 if (QDF_IS_STATUS_ERROR(status)) { 6840 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6841 status); 6842 wmi_buf_free(buf); 6843 } 6844 6845 return status; 6846 } 6847 6848 /** 6849 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6850 * configuration params 6851 * @wma_handle: wma handler 6852 * @dwelltime_params: pointer to dwelltime_params 6853 * 6854 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6855 */ 6856 static 6857 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6858 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6859 { 6860 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6861 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6862 wmi_buf_t buf; 6863 uint8_t *buf_ptr; 6864 int32_t err; 6865 int len; 6866 6867 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6868 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6869 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6870 buf = wmi_buf_alloc(wmi_handle, len); 6871 if (!buf) { 6872 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6873 __func__); 6874 return QDF_STATUS_E_NOMEM; 6875 } 6876 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6877 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 6878 WMITLV_SET_HDR(&dwell_param->tlv_header, 6879 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 6880 WMITLV_GET_STRUCT_TLVLEN 6881 (wmi_scan_adaptive_dwell_config_fixed_param)); 6882 6883 dwell_param->enable = dwelltime_params->is_enabled; 6884 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6885 WMITLV_SET_HDR(buf_ptr, 6886 WMITLV_TAG_ARRAY_STRUC, 6887 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 6888 buf_ptr += WMI_TLV_HDR_SIZE; 6889 6890 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 6891 WMITLV_SET_HDR(&cmd->tlv_header, 6892 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 6893 WMITLV_GET_STRUCT_TLVLEN( 6894 wmi_scan_adaptive_dwell_parameters_tlv)); 6895 6896 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 6897 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 6898 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 6899 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 6900 err = wmi_unified_cmd_send(wmi_handle, buf, 6901 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 6902 if (err) { 6903 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 6904 wmi_buf_free(buf); 6905 return QDF_STATUS_E_FAILURE; 6906 } 6907 6908 return QDF_STATUS_SUCCESS; 6909 } 6910 6911 /** 6912 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 6913 * configuration params 6914 * @wmi_handle: wmi handler 6915 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 6916 * 6917 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6918 */ 6919 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 6920 struct wmi_dbs_scan_sel_params *dbs_scan_params) 6921 { 6922 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 6923 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 6924 wmi_buf_t buf; 6925 uint8_t *buf_ptr; 6926 QDF_STATUS err; 6927 uint32_t i; 6928 int len; 6929 6930 len = sizeof(*dbs_scan_param); 6931 len += WMI_TLV_HDR_SIZE; 6932 len += dbs_scan_params->num_clients * sizeof(*cmd); 6933 6934 buf = wmi_buf_alloc(wmi_handle, len); 6935 if (!buf) { 6936 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 6937 return QDF_STATUS_E_NOMEM; 6938 } 6939 6940 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6941 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 6942 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 6943 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 6944 WMITLV_GET_STRUCT_TLVLEN 6945 (wmi_scan_dbs_duty_cycle_fixed_param)); 6946 6947 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 6948 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 6949 buf_ptr += sizeof(*dbs_scan_param); 6950 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6951 (sizeof(*cmd) * dbs_scan_params->num_clients)); 6952 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 6953 6954 for (i = 0; i < dbs_scan_params->num_clients; i++) { 6955 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 6956 WMITLV_SET_HDR(&cmd->tlv_header, 6957 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 6958 WMITLV_GET_STRUCT_TLVLEN( 6959 wmi_scan_dbs_duty_cycle_tlv_param)); 6960 cmd->module_id = dbs_scan_params->module_id[i]; 6961 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 6962 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 6963 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 6964 } 6965 6966 err = wmi_unified_cmd_send(wmi_handle, buf, 6967 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 6968 if (QDF_IS_STATUS_ERROR(err)) { 6969 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 6970 wmi_buf_free(buf); 6971 return QDF_STATUS_E_FAILURE; 6972 } 6973 6974 return QDF_STATUS_SUCCESS; 6975 } 6976 6977 /** 6978 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 6979 * @wmi_handle: wmi handle 6980 * @roam_req: Request which contains the filters 6981 * 6982 * There are filters such as whitelist, blacklist and preferred 6983 * list that need to be applied to the scan results to form the 6984 * probable candidates for roaming. 6985 * 6986 * Return: Return success upon successfully passing the 6987 * parameters to the firmware, otherwise failure. 6988 */ 6989 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 6990 struct roam_scan_filter_params *roam_req) 6991 { 6992 wmi_buf_t buf = NULL; 6993 QDF_STATUS status; 6994 uint32_t i; 6995 uint32_t len, blist_len = 0; 6996 uint8_t *buf_ptr; 6997 wmi_roam_filter_fixed_param *roam_filter; 6998 uint8_t *bssid_src_ptr = NULL; 6999 wmi_mac_addr *bssid_dst_ptr = NULL; 7000 wmi_ssid *ssid_ptr = NULL; 7001 uint32_t *bssid_preferred_factor_ptr = NULL; 7002 wmi_roam_lca_disallow_config_tlv_param *blist_param; 7003 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 7004 7005 len = sizeof(wmi_roam_filter_fixed_param); 7006 7007 len += WMI_TLV_HDR_SIZE; 7008 if (roam_req->num_bssid_black_list) 7009 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 7010 len += WMI_TLV_HDR_SIZE; 7011 if (roam_req->num_ssid_white_list) 7012 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 7013 len += 2 * WMI_TLV_HDR_SIZE; 7014 if (roam_req->num_bssid_preferred_list) { 7015 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 7016 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 7017 } 7018 len += WMI_TLV_HDR_SIZE; 7019 if (roam_req->lca_disallow_config_present) { 7020 len += sizeof(*blist_param); 7021 blist_len = sizeof(*blist_param); 7022 } 7023 7024 len += WMI_TLV_HDR_SIZE; 7025 if (roam_req->num_rssi_rejection_ap) 7026 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 7027 7028 buf = wmi_buf_alloc(wmi_handle, len); 7029 if (!buf) { 7030 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7031 return QDF_STATUS_E_NOMEM; 7032 } 7033 7034 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 7035 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 7036 WMITLV_SET_HDR(&roam_filter->tlv_header, 7037 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 7038 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 7039 /* fill in fixed values */ 7040 roam_filter->vdev_id = roam_req->session_id; 7041 roam_filter->flags = 0; 7042 roam_filter->op_bitmap = roam_req->op_bitmap; 7043 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 7044 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 7045 roam_filter->num_bssid_preferred_list = 7046 roam_req->num_bssid_preferred_list; 7047 roam_filter->num_rssi_rejection_ap = 7048 roam_req->num_rssi_rejection_ap; 7049 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 7050 7051 WMITLV_SET_HDR((buf_ptr), 7052 WMITLV_TAG_ARRAY_FIXED_STRUC, 7053 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 7054 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 7055 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7056 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 7057 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 7058 bssid_src_ptr += ATH_MAC_LEN; 7059 bssid_dst_ptr++; 7060 } 7061 buf_ptr += WMI_TLV_HDR_SIZE + 7062 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 7063 WMITLV_SET_HDR((buf_ptr), 7064 WMITLV_TAG_ARRAY_FIXED_STRUC, 7065 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 7066 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 7067 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 7068 qdf_mem_copy(&ssid_ptr->ssid, 7069 &roam_req->ssid_allowed_list[i].mac_ssid, 7070 roam_req->ssid_allowed_list[i].length); 7071 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 7072 ssid_ptr++; 7073 } 7074 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 7075 sizeof(wmi_ssid)); 7076 WMITLV_SET_HDR((buf_ptr), 7077 WMITLV_TAG_ARRAY_FIXED_STRUC, 7078 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 7079 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 7080 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7081 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7082 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 7083 (wmi_mac_addr *)bssid_dst_ptr); 7084 bssid_src_ptr += ATH_MAC_LEN; 7085 bssid_dst_ptr++; 7086 } 7087 buf_ptr += WMI_TLV_HDR_SIZE + 7088 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 7089 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7090 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 7091 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 7092 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7093 *bssid_preferred_factor_ptr = 7094 roam_req->bssid_favored_factor[i]; 7095 bssid_preferred_factor_ptr++; 7096 } 7097 buf_ptr += WMI_TLV_HDR_SIZE + 7098 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 7099 7100 WMITLV_SET_HDR(buf_ptr, 7101 WMITLV_TAG_ARRAY_STRUC, blist_len); 7102 buf_ptr += WMI_TLV_HDR_SIZE; 7103 if (roam_req->lca_disallow_config_present) { 7104 blist_param = 7105 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 7106 WMITLV_SET_HDR(&blist_param->tlv_header, 7107 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 7108 WMITLV_GET_STRUCT_TLVLEN( 7109 wmi_roam_lca_disallow_config_tlv_param)); 7110 7111 blist_param->disallow_duration = roam_req->disallow_duration; 7112 blist_param->rssi_channel_penalization = 7113 roam_req->rssi_channel_penalization; 7114 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 7115 blist_param->disallow_lca_enable_source_bitmap = 7116 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 7117 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 7118 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 7119 } 7120 7121 WMITLV_SET_HDR(buf_ptr, 7122 WMITLV_TAG_ARRAY_STRUC, 7123 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 7124 buf_ptr += WMI_TLV_HDR_SIZE; 7125 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 7126 rssi_rej = 7127 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 7128 WMITLV_SET_HDR(&rssi_rej->tlv_header, 7129 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7130 WMITLV_GET_STRUCT_TLVLEN( 7131 wmi_roam_rssi_rejection_oce_config_param)); 7132 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7133 roam_req->rssi_rejection_ap[i].bssid.bytes, 7134 &rssi_rej->bssid); 7135 rssi_rej->remaining_disallow_duration = 7136 roam_req->rssi_rejection_ap[i].remaining_duration; 7137 rssi_rej->requested_rssi = 7138 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 7139 buf_ptr += 7140 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7141 } 7142 7143 status = wmi_unified_cmd_send(wmi_handle, buf, 7144 len, WMI_ROAM_FILTER_CMDID); 7145 if (QDF_IS_STATUS_ERROR(status)) { 7146 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7147 status); 7148 wmi_buf_free(buf); 7149 } 7150 7151 return status; 7152 } 7153 7154 #if defined(WLAN_FEATURE_FILS_SK) 7155 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7156 struct hlp_params *params) 7157 { 7158 uint32_t len; 7159 uint8_t *buf_ptr; 7160 wmi_buf_t buf = NULL; 7161 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7162 7163 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7164 len += WMI_TLV_HDR_SIZE; 7165 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7166 7167 buf = wmi_buf_alloc(wmi_handle, len); 7168 if (!buf) { 7169 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7170 return QDF_STATUS_E_NOMEM; 7171 } 7172 7173 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7174 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7175 WMITLV_SET_HDR(&hlp_params->tlv_header, 7176 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7177 WMITLV_GET_STRUCT_TLVLEN( 7178 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7179 7180 hlp_params->vdev_id = params->vdev_id; 7181 hlp_params->size = params->hlp_ie_len; 7182 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7183 7184 buf_ptr += sizeof(*hlp_params); 7185 7186 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7187 round_up(params->hlp_ie_len, 7188 sizeof(uint32_t))); 7189 buf_ptr += WMI_TLV_HDR_SIZE; 7190 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7191 7192 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7193 hlp_params->vdev_id, hlp_params->size); 7194 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7195 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7196 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7197 wmi_buf_free(buf); 7198 return QDF_STATUS_E_FAILURE; 7199 } 7200 7201 return QDF_STATUS_SUCCESS; 7202 } 7203 #endif 7204 7205 #ifdef IPA_OFFLOAD 7206 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7207 * @wmi_handle: wmi handle 7208 * @ipa_offload: ipa offload control parameter 7209 * 7210 * Returns: 0 on success, error number otherwise 7211 */ 7212 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7213 struct ipa_uc_offload_control_params *ipa_offload) 7214 { 7215 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7216 wmi_buf_t wmi_buf; 7217 uint32_t len; 7218 u_int8_t *buf_ptr; 7219 7220 len = sizeof(*cmd); 7221 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7222 if (!wmi_buf) { 7223 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7224 return QDF_STATUS_E_NOMEM; 7225 } 7226 7227 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7228 ipa_offload->offload_type, ipa_offload->enable); 7229 7230 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7231 7232 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7233 WMITLV_SET_HDR(&cmd->tlv_header, 7234 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7235 WMITLV_GET_STRUCT_TLVLEN( 7236 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7237 7238 cmd->offload_type = ipa_offload->offload_type; 7239 cmd->vdev_id = ipa_offload->vdev_id; 7240 cmd->enable = ipa_offload->enable; 7241 7242 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7243 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7244 WMI_LOGE("%s: failed to command", __func__); 7245 wmi_buf_free(wmi_buf); 7246 return QDF_STATUS_E_FAILURE; 7247 } 7248 7249 return QDF_STATUS_SUCCESS; 7250 } 7251 #endif 7252 7253 /** 7254 * send_plm_stop_cmd_tlv() - plm stop request 7255 * @wmi_handle: wmi handle 7256 * @plm: plm request parameters 7257 * 7258 * This function request FW to stop PLM. 7259 * 7260 * Return: CDF status 7261 */ 7262 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7263 const struct plm_req_params *plm) 7264 { 7265 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7266 int32_t len; 7267 wmi_buf_t buf; 7268 uint8_t *buf_ptr; 7269 int ret; 7270 7271 len = sizeof(*cmd); 7272 buf = wmi_buf_alloc(wmi_handle, len); 7273 if (!buf) { 7274 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7275 return QDF_STATUS_E_NOMEM; 7276 } 7277 7278 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7279 7280 buf_ptr = (uint8_t *) cmd; 7281 7282 WMITLV_SET_HDR(&cmd->tlv_header, 7283 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7284 WMITLV_GET_STRUCT_TLVLEN 7285 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7286 7287 cmd->vdev_id = plm->session_id; 7288 7289 cmd->meas_token = plm->meas_token; 7290 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7291 7292 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7293 WMI_VDEV_PLMREQ_STOP_CMDID); 7294 if (ret) { 7295 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7296 wmi_buf_free(buf); 7297 return QDF_STATUS_E_FAILURE; 7298 } 7299 7300 return QDF_STATUS_SUCCESS; 7301 } 7302 7303 /** 7304 * send_plm_start_cmd_tlv() - plm start request 7305 * @wmi_handle: wmi handle 7306 * @plm: plm request parameters 7307 * 7308 * This function request FW to start PLM. 7309 * 7310 * Return: CDF status 7311 */ 7312 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7313 const struct plm_req_params *plm, 7314 uint32_t *gchannel_list) 7315 { 7316 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7317 uint32_t *channel_list; 7318 int32_t len; 7319 wmi_buf_t buf; 7320 uint8_t *buf_ptr; 7321 uint8_t count; 7322 int ret; 7323 7324 /* TLV place holder for channel_list */ 7325 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7326 len += sizeof(uint32_t) * plm->plm_num_ch; 7327 7328 buf = wmi_buf_alloc(wmi_handle, len); 7329 if (!buf) { 7330 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7331 return QDF_STATUS_E_NOMEM; 7332 } 7333 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 7334 7335 buf_ptr = (uint8_t *) cmd; 7336 7337 WMITLV_SET_HDR(&cmd->tlv_header, 7338 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 7339 WMITLV_GET_STRUCT_TLVLEN 7340 (wmi_vdev_plmreq_start_cmd_fixed_param)); 7341 7342 cmd->vdev_id = plm->session_id; 7343 7344 cmd->meas_token = plm->meas_token; 7345 cmd->dialog_token = plm->diag_token; 7346 cmd->number_bursts = plm->num_bursts; 7347 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 7348 cmd->off_duration = plm->meas_duration; 7349 cmd->burst_cycle = plm->burst_len; 7350 cmd->tx_power = plm->desired_tx_pwr; 7351 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 7352 cmd->num_chans = plm->plm_num_ch; 7353 7354 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 7355 7356 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 7357 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 7358 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 7359 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 7360 WMI_LOGD("off_duration: %d", cmd->off_duration); 7361 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 7362 WMI_LOGD("tx_power: %d", cmd->tx_power); 7363 WMI_LOGD("Number of channels : %d", cmd->num_chans); 7364 7365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7366 (cmd->num_chans * sizeof(uint32_t))); 7367 7368 buf_ptr += WMI_TLV_HDR_SIZE; 7369 if (cmd->num_chans) { 7370 channel_list = (uint32_t *) buf_ptr; 7371 for (count = 0; count < cmd->num_chans; count++) { 7372 channel_list[count] = plm->plm_ch_list[count]; 7373 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 7374 channel_list[count] = 7375 gchannel_list[count]; 7376 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 7377 } 7378 buf_ptr += cmd->num_chans * sizeof(uint32_t); 7379 } 7380 7381 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7382 WMI_VDEV_PLMREQ_START_CMDID); 7383 if (ret) { 7384 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 7385 wmi_buf_free(buf); 7386 return QDF_STATUS_E_FAILURE; 7387 } 7388 7389 return QDF_STATUS_SUCCESS; 7390 } 7391 7392 /** 7393 * send_pno_stop_cmd_tlv() - PNO stop request 7394 * @wmi_handle: wmi handle 7395 * @vdev_id: vdev id 7396 * 7397 * This function request FW to stop ongoing PNO operation. 7398 * 7399 * Return: CDF status 7400 */ 7401 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7402 { 7403 wmi_nlo_config_cmd_fixed_param *cmd; 7404 int32_t len = sizeof(*cmd); 7405 wmi_buf_t buf; 7406 uint8_t *buf_ptr; 7407 int ret; 7408 7409 /* 7410 * TLV place holder for array of structures nlo_configured_parameters 7411 * TLV place holder for array of uint32_t channel_list 7412 * TLV place holder for chnl prediction cfg 7413 */ 7414 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7415 buf = wmi_buf_alloc(wmi_handle, len); 7416 if (!buf) { 7417 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7418 return QDF_STATUS_E_NOMEM; 7419 } 7420 7421 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7422 buf_ptr = (uint8_t *) cmd; 7423 7424 WMITLV_SET_HDR(&cmd->tlv_header, 7425 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7426 WMITLV_GET_STRUCT_TLVLEN 7427 (wmi_nlo_config_cmd_fixed_param)); 7428 7429 cmd->vdev_id = vdev_id; 7430 cmd->flags = WMI_NLO_CONFIG_STOP; 7431 buf_ptr += sizeof(*cmd); 7432 7433 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7434 buf_ptr += WMI_TLV_HDR_SIZE; 7435 7436 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7437 buf_ptr += WMI_TLV_HDR_SIZE; 7438 7439 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7440 buf_ptr += WMI_TLV_HDR_SIZE; 7441 7442 7443 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7444 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7445 if (ret) { 7446 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7447 wmi_buf_free(buf); 7448 return QDF_STATUS_E_FAILURE; 7449 } 7450 7451 return QDF_STATUS_SUCCESS; 7452 } 7453 7454 /** 7455 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 7456 * @buf_ptr: Buffer passed by upper layers 7457 * @pno: Buffer to be sent to the firmware 7458 * 7459 * Copy the PNO Channel prediction configuration parameters 7460 * passed by the upper layers to a WMI format TLV and send it 7461 * down to the firmware. 7462 * 7463 * Return: None 7464 */ 7465 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 7466 struct pno_scan_req_params *pno) 7467 { 7468 nlo_channel_prediction_cfg *channel_prediction_cfg = 7469 (nlo_channel_prediction_cfg *) buf_ptr; 7470 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 7471 WMITLV_TAG_ARRAY_BYTE, 7472 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 7473 #ifdef FEATURE_WLAN_SCAN_PNO 7474 channel_prediction_cfg->enable = pno->pno_channel_prediction; 7475 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 7476 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 7477 channel_prediction_cfg->full_scan_period_ms = 7478 pno->channel_prediction_full_scan; 7479 #endif 7480 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7481 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 7482 channel_prediction_cfg->enable, 7483 channel_prediction_cfg->top_k_num, 7484 channel_prediction_cfg->stationary_threshold, 7485 channel_prediction_cfg->full_scan_period_ms); 7486 } 7487 7488 /** 7489 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 7490 * @wmi_handle: wmi handle 7491 * @params: configuration parameters 7492 * 7493 * Return: QDF_STATUS 7494 */ 7495 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 7496 struct nlo_mawc_params *params) 7497 { 7498 wmi_buf_t buf = NULL; 7499 QDF_STATUS status; 7500 int len; 7501 uint8_t *buf_ptr; 7502 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 7503 7504 len = sizeof(*wmi_nlo_mawc_params); 7505 buf = wmi_buf_alloc(wmi_handle, len); 7506 if (!buf) { 7507 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7508 return QDF_STATUS_E_NOMEM; 7509 } 7510 7511 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7512 wmi_nlo_mawc_params = 7513 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 7514 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 7515 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 7516 WMITLV_GET_STRUCT_TLVLEN 7517 (wmi_nlo_configure_mawc_cmd_fixed_param)); 7518 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 7519 if (params->enable) 7520 wmi_nlo_mawc_params->enable = 1; 7521 else 7522 wmi_nlo_mawc_params->enable = 0; 7523 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 7524 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 7525 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 7526 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 7527 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 7528 wmi_nlo_mawc_params->exp_backoff_ratio, 7529 wmi_nlo_mawc_params->init_scan_interval, 7530 wmi_nlo_mawc_params->max_scan_interval); 7531 7532 status = wmi_unified_cmd_send(wmi_handle, buf, 7533 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 7534 if (QDF_IS_STATUS_ERROR(status)) { 7535 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 7536 status); 7537 wmi_buf_free(buf); 7538 return QDF_STATUS_E_FAILURE; 7539 } 7540 7541 return QDF_STATUS_SUCCESS; 7542 } 7543 7544 /** 7545 * send_pno_start_cmd_tlv() - PNO start request 7546 * @wmi_handle: wmi handle 7547 * @pno: PNO request 7548 * 7549 * This function request FW to start PNO request. 7550 * Request: CDF status 7551 */ 7552 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 7553 struct pno_scan_req_params *pno) 7554 { 7555 wmi_nlo_config_cmd_fixed_param *cmd; 7556 nlo_configured_parameters *nlo_list; 7557 uint32_t *channel_list; 7558 int32_t len; 7559 wmi_buf_t buf; 7560 uint8_t *buf_ptr; 7561 uint8_t i; 7562 int ret; 7563 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 7564 connected_nlo_rssi_params *nlo_relative_rssi; 7565 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 7566 7567 /* 7568 * TLV place holder for array nlo_configured_parameters(nlo_list) 7569 * TLV place holder for array of uint32_t channel_list 7570 * TLV place holder for chnnl prediction cfg 7571 * TLV place holder for array of wmi_vendor_oui 7572 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 7573 */ 7574 len = sizeof(*cmd) + 7575 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 7576 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7577 7578 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 7579 WMI_NLO_MAX_CHAN); 7580 len += sizeof(nlo_configured_parameters) * 7581 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7582 len += sizeof(nlo_channel_prediction_cfg); 7583 len += sizeof(enlo_candidate_score_params); 7584 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 7585 len += sizeof(connected_nlo_rssi_params); 7586 len += sizeof(connected_nlo_bss_band_rssi_pref); 7587 7588 buf = wmi_buf_alloc(wmi_handle, len); 7589 if (!buf) { 7590 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7591 return QDF_STATUS_E_NOMEM; 7592 } 7593 7594 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7595 7596 buf_ptr = (uint8_t *) cmd; 7597 WMITLV_SET_HDR(&cmd->tlv_header, 7598 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7599 WMITLV_GET_STRUCT_TLVLEN 7600 (wmi_nlo_config_cmd_fixed_param)); 7601 cmd->vdev_id = pno->vdev_id; 7602 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 7603 7604 #ifdef FEATURE_WLAN_SCAN_PNO 7605 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 7606 pno->adaptive_dwell_mode); 7607 #endif 7608 /* Current FW does not support min-max range for dwell time */ 7609 cmd->active_dwell_time = pno->active_dwell_time; 7610 cmd->passive_dwell_time = pno->passive_dwell_time; 7611 7612 if (pno->do_passive_scan) 7613 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 7614 /* Copy scan interval */ 7615 cmd->fast_scan_period = pno->fast_scan_period; 7616 cmd->slow_scan_period = pno->slow_scan_period; 7617 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 7618 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 7619 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 7620 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 7621 cmd->fast_scan_period, cmd->slow_scan_period); 7622 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 7623 7624 /* mac randomization attributes */ 7625 if (pno->scan_random.randomize) { 7626 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 7627 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 7628 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 7629 pno->scan_random.mac_mask, 7630 &cmd->mac_addr, 7631 &cmd->mac_mask); 7632 } 7633 7634 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7635 7636 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7637 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 7638 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7639 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7640 buf_ptr += WMI_TLV_HDR_SIZE; 7641 7642 nlo_list = (nlo_configured_parameters *) buf_ptr; 7643 for (i = 0; i < cmd->no_of_ssids; i++) { 7644 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7645 WMITLV_TAG_ARRAY_BYTE, 7646 WMITLV_GET_STRUCT_TLVLEN 7647 (nlo_configured_parameters)); 7648 /* Copy ssid and it's length */ 7649 nlo_list[i].ssid.valid = true; 7650 nlo_list[i].ssid.ssid.ssid_len = 7651 pno->networks_list[i].ssid.length; 7652 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7653 pno->networks_list[i].ssid.ssid, 7654 nlo_list[i].ssid.ssid.ssid_len); 7655 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7656 nlo_list[i].ssid.ssid.ssid_len, 7657 (char *)nlo_list[i].ssid.ssid.ssid, 7658 nlo_list[i].ssid.ssid.ssid_len); 7659 7660 /* Copy rssi threshold */ 7661 if (pno->networks_list[i].rssi_thresh && 7662 pno->networks_list[i].rssi_thresh > 7663 WMI_RSSI_THOLD_DEFAULT) { 7664 nlo_list[i].rssi_cond.valid = true; 7665 nlo_list[i].rssi_cond.rssi = 7666 pno->networks_list[i].rssi_thresh; 7667 WMI_LOGD("RSSI threshold : %d dBm", 7668 nlo_list[i].rssi_cond.rssi); 7669 } 7670 nlo_list[i].bcast_nw_type.valid = true; 7671 nlo_list[i].bcast_nw_type.bcast_nw_type = 7672 pno->networks_list[i].bc_new_type; 7673 WMI_LOGD("Broadcast NW type (%u)", 7674 nlo_list[i].bcast_nw_type.bcast_nw_type); 7675 } 7676 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7677 7678 /* Copy channel info */ 7679 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 7680 WMI_NLO_MAX_CHAN); 7681 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 7682 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7683 (cmd->num_of_channels * sizeof(uint32_t))); 7684 buf_ptr += WMI_TLV_HDR_SIZE; 7685 7686 channel_list = (uint32_t *) buf_ptr; 7687 for (i = 0; i < cmd->num_of_channels; i++) { 7688 channel_list[i] = pno->networks_list[0].channels[i]; 7689 7690 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 7691 channel_list[i] = 7692 wlan_chan_to_freq(pno-> 7693 networks_list[0].channels[i]); 7694 7695 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 7696 } 7697 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 7698 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7699 sizeof(nlo_channel_prediction_cfg)); 7700 buf_ptr += WMI_TLV_HDR_SIZE; 7701 wmi_set_pno_channel_prediction(buf_ptr, pno); 7702 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7703 /** TODO: Discrete firmware doesn't have command/option to configure 7704 * App IE which comes from wpa_supplicant as of part PNO start request. 7705 */ 7706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 7707 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7708 buf_ptr += sizeof(enlo_candidate_score_params); 7709 7710 if (ie_whitelist->white_list) { 7711 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 7712 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 7713 &cmd->num_vendor_oui, 7714 ie_whitelist); 7715 } 7716 7717 /* ie white list */ 7718 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7719 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 7720 buf_ptr += WMI_TLV_HDR_SIZE; 7721 if (cmd->num_vendor_oui != 0) { 7722 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 7723 ie_whitelist->voui); 7724 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 7725 } 7726 7727 if (pno->relative_rssi_set) 7728 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 7729 7730 /* 7731 * Firmware calculation using connected PNO params: 7732 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 7733 * deduction of rssi_pref for chosen band_pref and 7734 * addition of rssi_pref for remaining bands (other than chosen band). 7735 */ 7736 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 7737 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 7738 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 7739 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 7740 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 7741 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 7742 buf_ptr += sizeof(*nlo_relative_rssi); 7743 7744 /* 7745 * As of now Kernel and Host supports one band and rssi preference. 7746 * Firmware supports array of band and rssi preferences 7747 */ 7748 cmd->num_cnlo_band_pref = 1; 7749 WMITLV_SET_HDR(buf_ptr, 7750 WMITLV_TAG_ARRAY_STRUC, 7751 cmd->num_cnlo_band_pref * 7752 sizeof(connected_nlo_bss_band_rssi_pref)); 7753 buf_ptr += WMI_TLV_HDR_SIZE; 7754 7755 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 7756 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 7757 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 7758 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 7759 WMITLV_GET_STRUCT_TLVLEN( 7760 connected_nlo_bss_band_rssi_pref)); 7761 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 7762 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 7763 WMI_LOGI("band_pref %d, rssi_pref %d", 7764 nlo_band_rssi[i].band, 7765 nlo_band_rssi[i].rssi_pref); 7766 } 7767 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 7768 7769 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7770 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7771 if (ret) { 7772 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7773 wmi_buf_free(buf); 7774 return QDF_STATUS_E_FAILURE; 7775 } 7776 7777 return QDF_STATUS_SUCCESS; 7778 } 7779 7780 /* send_set_ric_req_cmd_tlv() - set ric request element 7781 * @wmi_handle: wmi handle 7782 * @msg: message 7783 * @is_add_ts: is addts required 7784 * 7785 * This function sets ric request element for 11r roaming. 7786 * 7787 * Return: CDF status 7788 */ 7789 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 7790 void *msg, uint8_t is_add_ts) 7791 { 7792 wmi_ric_request_fixed_param *cmd; 7793 wmi_ric_tspec *tspec_param; 7794 wmi_buf_t buf; 7795 uint8_t *buf_ptr; 7796 struct mac_tspec_ie *ptspecIE = NULL; 7797 int32_t len = sizeof(wmi_ric_request_fixed_param) + 7798 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 7799 7800 buf = wmi_buf_alloc(wmi_handle, len); 7801 if (!buf) { 7802 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 7803 return QDF_STATUS_E_NOMEM; 7804 } 7805 7806 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7807 7808 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 7809 WMITLV_SET_HDR(&cmd->tlv_header, 7810 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 7811 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 7812 if (is_add_ts) 7813 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 7814 else 7815 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 7816 cmd->num_ric_request = 1; 7817 cmd->is_add_ric = is_add_ts; 7818 7819 buf_ptr += sizeof(wmi_ric_request_fixed_param); 7820 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 7821 7822 buf_ptr += WMI_TLV_HDR_SIZE; 7823 tspec_param = (wmi_ric_tspec *) buf_ptr; 7824 WMITLV_SET_HDR(&tspec_param->tlv_header, 7825 WMITLV_TAG_STRUC_wmi_ric_tspec, 7826 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 7827 7828 if (is_add_ts) 7829 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 7830 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7831 else 7832 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 7833 #endif 7834 if (ptspecIE) { 7835 /* Fill the tsinfo in the format expected by firmware */ 7836 #ifndef ANI_LITTLE_BIT_ENDIAN 7837 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 7838 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7839 #else 7840 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 7841 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7842 #endif /* ANI_LITTLE_BIT_ENDIAN */ 7843 7844 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 7845 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 7846 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 7847 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 7848 tspec_param->inactivity_interval = ptspecIE->inactInterval; 7849 tspec_param->suspension_interval = ptspecIE->suspendInterval; 7850 tspec_param->svc_start_time = ptspecIE->svcStartTime; 7851 tspec_param->min_data_rate = ptspecIE->minDataRate; 7852 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 7853 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 7854 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 7855 tspec_param->delay_bound = ptspecIE->delayBound; 7856 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 7857 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 7858 tspec_param->medium_time = 0; 7859 } 7860 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 7861 7862 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7863 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 7864 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 7865 __func__); 7866 if (is_add_ts) 7867 ((struct add_ts_param *) msg)->status = 7868 QDF_STATUS_E_FAILURE; 7869 wmi_buf_free(buf); 7870 return QDF_STATUS_E_FAILURE; 7871 } 7872 7873 return QDF_STATUS_SUCCESS; 7874 } 7875 7876 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 7877 /** 7878 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 7879 * @wmi_handle: wmi handle 7880 * @clear_req: ll stats clear request command params 7881 * 7882 * Return: QDF_STATUS_SUCCESS for success or error code 7883 */ 7884 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 7885 const struct ll_stats_clear_params *clear_req, 7886 uint8_t addr[IEEE80211_ADDR_LEN]) 7887 { 7888 wmi_clear_link_stats_cmd_fixed_param *cmd; 7889 int32_t len; 7890 wmi_buf_t buf; 7891 uint8_t *buf_ptr; 7892 int ret; 7893 7894 len = sizeof(*cmd); 7895 buf = wmi_buf_alloc(wmi_handle, len); 7896 7897 if (!buf) { 7898 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7899 return QDF_STATUS_E_NOMEM; 7900 } 7901 7902 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7903 qdf_mem_zero(buf_ptr, len); 7904 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 7905 7906 WMITLV_SET_HDR(&cmd->tlv_header, 7907 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 7908 WMITLV_GET_STRUCT_TLVLEN 7909 (wmi_clear_link_stats_cmd_fixed_param)); 7910 7911 cmd->stop_stats_collection_req = clear_req->stop_req; 7912 cmd->vdev_id = clear_req->sta_id; 7913 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 7914 7915 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 7916 &cmd->peer_macaddr); 7917 7918 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 7919 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 7920 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 7921 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 7922 /* WMI_LOGD("Peer MAC Addr : %pM", 7923 cmd->peer_macaddr); */ 7924 7925 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7926 WMI_CLEAR_LINK_STATS_CMDID); 7927 if (ret) { 7928 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 7929 wmi_buf_free(buf); 7930 return QDF_STATUS_E_FAILURE; 7931 } 7932 7933 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 7934 return QDF_STATUS_SUCCESS; 7935 } 7936 7937 /** 7938 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 7939 * @wmi_handle: wmi handle 7940 * @setReq: ll stats set request command params 7941 * 7942 * Return: QDF_STATUS_SUCCESS for success or error code 7943 */ 7944 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7945 const struct ll_stats_set_params *set_req) 7946 { 7947 wmi_start_link_stats_cmd_fixed_param *cmd; 7948 int32_t len; 7949 wmi_buf_t buf; 7950 uint8_t *buf_ptr; 7951 int ret; 7952 7953 len = sizeof(*cmd); 7954 buf = wmi_buf_alloc(wmi_handle, len); 7955 7956 if (!buf) { 7957 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7958 return QDF_STATUS_E_NOMEM; 7959 } 7960 7961 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7962 qdf_mem_zero(buf_ptr, len); 7963 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7964 7965 WMITLV_SET_HDR(&cmd->tlv_header, 7966 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7967 WMITLV_GET_STRUCT_TLVLEN 7968 (wmi_start_link_stats_cmd_fixed_param)); 7969 7970 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7971 cmd->aggressive_statistics_gathering = 7972 set_req->aggressive_statistics_gathering; 7973 7974 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 7975 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 7976 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 7977 7978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7979 WMI_START_LINK_STATS_CMDID); 7980 if (ret) { 7981 WMI_LOGE("%s: Failed to send set link stats request", __func__); 7982 wmi_buf_free(buf); 7983 return QDF_STATUS_E_FAILURE; 7984 } 7985 7986 return QDF_STATUS_SUCCESS; 7987 } 7988 7989 /** 7990 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7991 * @wmi_handle:wmi handle 7992 * @get_req:ll stats get request command params 7993 * @addr: mac address 7994 * 7995 * Return: QDF_STATUS_SUCCESS for success or error code 7996 */ 7997 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7998 const struct ll_stats_get_params *get_req, 7999 uint8_t addr[IEEE80211_ADDR_LEN]) 8000 { 8001 wmi_request_link_stats_cmd_fixed_param *cmd; 8002 int32_t len; 8003 wmi_buf_t buf; 8004 uint8_t *buf_ptr; 8005 int ret; 8006 8007 len = sizeof(*cmd); 8008 buf = wmi_buf_alloc(wmi_handle, len); 8009 8010 if (!buf) { 8011 WMI_LOGE("%s: buf allocation failed", __func__); 8012 return QDF_STATUS_E_NOMEM; 8013 } 8014 8015 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8016 qdf_mem_zero(buf_ptr, len); 8017 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 8018 8019 WMITLV_SET_HDR(&cmd->tlv_header, 8020 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 8021 WMITLV_GET_STRUCT_TLVLEN 8022 (wmi_request_link_stats_cmd_fixed_param)); 8023 8024 cmd->request_id = get_req->req_id; 8025 cmd->stats_type = get_req->param_id_mask; 8026 cmd->vdev_id = get_req->sta_id; 8027 8028 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8029 &cmd->peer_macaddr); 8030 8031 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 8032 WMI_LOGD("Request ID : %u", cmd->request_id); 8033 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 8034 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 8035 WMI_LOGD("Peer MAC Addr : %pM", addr); 8036 8037 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8038 WMI_REQUEST_LINK_STATS_CMDID); 8039 if (ret) { 8040 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8041 wmi_buf_free(buf); 8042 return QDF_STATUS_E_FAILURE; 8043 } 8044 8045 return QDF_STATUS_SUCCESS; 8046 } 8047 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 8048 8049 /** 8050 * send_congestion_cmd_tlv() - send request to fw to get CCA 8051 * @wmi_handle: wmi handle 8052 * @vdev_id: vdev id 8053 * 8054 * Return: CDF status 8055 */ 8056 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8057 uint8_t vdev_id) 8058 { 8059 wmi_buf_t buf; 8060 wmi_request_stats_cmd_fixed_param *cmd; 8061 uint8_t len; 8062 uint8_t *buf_ptr; 8063 8064 len = sizeof(*cmd); 8065 buf = wmi_buf_alloc(wmi_handle, len); 8066 if (!buf) { 8067 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8068 return QDF_STATUS_E_FAILURE; 8069 } 8070 8071 buf_ptr = wmi_buf_data(buf); 8072 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8073 WMITLV_SET_HDR(&cmd->tlv_header, 8074 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8075 WMITLV_GET_STRUCT_TLVLEN 8076 (wmi_request_stats_cmd_fixed_param)); 8077 8078 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8079 cmd->vdev_id = vdev_id; 8080 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8081 cmd->vdev_id, cmd->stats_id); 8082 8083 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8084 WMI_REQUEST_STATS_CMDID)) { 8085 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8086 __func__); 8087 wmi_buf_free(buf); 8088 return QDF_STATUS_E_FAILURE; 8089 } 8090 8091 return QDF_STATUS_SUCCESS; 8092 } 8093 8094 /** 8095 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8096 * @wmi_handle: wmi handle 8097 * @rssi_req: get RSSI request 8098 * 8099 * Return: CDF status 8100 */ 8101 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8102 { 8103 wmi_buf_t buf; 8104 wmi_request_stats_cmd_fixed_param *cmd; 8105 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8106 8107 buf = wmi_buf_alloc(wmi_handle, len); 8108 if (!buf) { 8109 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8110 return QDF_STATUS_E_FAILURE; 8111 } 8112 8113 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8114 WMITLV_SET_HDR(&cmd->tlv_header, 8115 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8116 WMITLV_GET_STRUCT_TLVLEN 8117 (wmi_request_stats_cmd_fixed_param)); 8118 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8119 if (wmi_unified_cmd_send 8120 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8121 WMI_LOGE("Failed to send host stats request to fw"); 8122 wmi_buf_free(buf); 8123 return QDF_STATUS_E_FAILURE; 8124 } 8125 8126 return QDF_STATUS_SUCCESS; 8127 } 8128 8129 /** 8130 * send_snr_cmd_tlv() - get RSSI from fw 8131 * @wmi_handle: wmi handle 8132 * @vdev_id: vdev id 8133 * 8134 * Return: CDF status 8135 */ 8136 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8137 { 8138 wmi_buf_t buf; 8139 wmi_request_stats_cmd_fixed_param *cmd; 8140 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8141 8142 buf = wmi_buf_alloc(wmi_handle, len); 8143 if (!buf) { 8144 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8145 return QDF_STATUS_E_FAILURE; 8146 } 8147 8148 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8149 cmd->vdev_id = vdev_id; 8150 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_STAT; 8156 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8157 WMI_REQUEST_STATS_CMDID)) { 8158 WMI_LOGE("Failed to send host stats request to fw"); 8159 wmi_buf_free(buf); 8160 return QDF_STATUS_E_FAILURE; 8161 } 8162 8163 return QDF_STATUS_SUCCESS; 8164 } 8165 8166 /** 8167 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8168 * @wmi_handle: wmi handle 8169 * @link_status: get link params 8170 * 8171 * Return: CDF status 8172 */ 8173 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8174 struct link_status_params *link_status) 8175 { 8176 wmi_buf_t buf; 8177 wmi_request_stats_cmd_fixed_param *cmd; 8178 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8179 8180 buf = wmi_buf_alloc(wmi_handle, len); 8181 if (!buf) { 8182 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8183 return QDF_STATUS_E_FAILURE; 8184 } 8185 8186 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8187 WMITLV_SET_HDR(&cmd->tlv_header, 8188 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8189 WMITLV_GET_STRUCT_TLVLEN 8190 (wmi_request_stats_cmd_fixed_param)); 8191 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8192 cmd->vdev_id = link_status->session_id; 8193 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8194 WMI_REQUEST_STATS_CMDID)) { 8195 WMI_LOGE("Failed to send WMI link status request to fw"); 8196 wmi_buf_free(buf); 8197 return QDF_STATUS_E_FAILURE; 8198 } 8199 8200 return QDF_STATUS_SUCCESS; 8201 } 8202 8203 /** 8204 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8205 * @wmi_handle: wmi handle 8206 * @ta_dhcp_ind: DHCP indication parameter 8207 * 8208 * Return: CDF Status 8209 */ 8210 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8211 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8212 { 8213 QDF_STATUS status; 8214 wmi_buf_t buf = NULL; 8215 uint8_t *buf_ptr; 8216 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8217 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8218 8219 8220 buf = wmi_buf_alloc(wmi_handle, len); 8221 if (!buf) { 8222 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8223 return QDF_STATUS_E_NOMEM; 8224 } 8225 8226 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8227 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8228 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8229 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8230 WMITLV_GET_STRUCT_TLVLEN 8231 (wmi_peer_set_param_cmd_fixed_param)); 8232 8233 /* fill in values */ 8234 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8235 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8236 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8237 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8238 &ta_dhcp_ind->peer_macaddr, 8239 sizeof(ta_dhcp_ind->peer_macaddr)); 8240 8241 status = wmi_unified_cmd_send(wmi_handle, buf, 8242 len, WMI_PEER_SET_PARAM_CMDID); 8243 if (QDF_IS_STATUS_ERROR(status)) { 8244 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8245 " returned Error %d", __func__, status); 8246 wmi_buf_free(buf); 8247 } 8248 8249 return status; 8250 } 8251 8252 /** 8253 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8254 * @wmi_handle: wmi handle 8255 * @pLinkSpeed: link speed info 8256 * 8257 * Return: CDF status 8258 */ 8259 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8260 wmi_mac_addr peer_macaddr) 8261 { 8262 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8263 wmi_buf_t wmi_buf; 8264 uint32_t len; 8265 uint8_t *buf_ptr; 8266 8267 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8268 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8269 if (!wmi_buf) { 8270 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8271 return QDF_STATUS_E_NOMEM; 8272 } 8273 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8274 8275 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8276 WMITLV_SET_HDR(&cmd->tlv_header, 8277 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8278 WMITLV_GET_STRUCT_TLVLEN 8279 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8280 8281 /* Copy the peer macaddress to the wma buffer */ 8282 qdf_mem_copy(&cmd->peer_macaddr, 8283 &peer_macaddr, 8284 sizeof(peer_macaddr)); 8285 8286 8287 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8288 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8289 WMI_LOGE("%s: failed to send link speed command", __func__); 8290 wmi_buf_free(wmi_buf); 8291 return QDF_STATUS_E_FAILURE; 8292 } 8293 return QDF_STATUS_SUCCESS; 8294 } 8295 8296 #ifdef WLAN_SUPPORT_GREEN_AP 8297 /** 8298 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8299 * @wmi_handle: wmi handler 8300 * @egap_params: pointer to egap_params 8301 * 8302 * Return: 0 for success, otherwise appropriate error code 8303 */ 8304 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8305 struct wlan_green_ap_egap_params *egap_params) 8306 { 8307 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8308 wmi_buf_t buf; 8309 int32_t err; 8310 8311 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8312 if (!buf) { 8313 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8314 return QDF_STATUS_E_NOMEM; 8315 } 8316 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8317 WMITLV_SET_HDR(&cmd->tlv_header, 8318 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8319 WMITLV_GET_STRUCT_TLVLEN( 8320 wmi_ap_ps_egap_param_cmd_fixed_param)); 8321 8322 cmd->enable = egap_params->host_enable_egap; 8323 cmd->inactivity_time = egap_params->egap_inactivity_time; 8324 cmd->wait_time = egap_params->egap_wait_time; 8325 cmd->flags = egap_params->egap_feature_flags; 8326 err = wmi_unified_cmd_send(wmi_handle, buf, 8327 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 8328 if (err) { 8329 WMI_LOGE("Failed to send ap_ps_egap cmd"); 8330 wmi_buf_free(buf); 8331 return QDF_STATUS_E_FAILURE; 8332 } 8333 8334 return QDF_STATUS_SUCCESS; 8335 } 8336 #endif 8337 8338 /** 8339 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 8340 * @wmi_handl: wmi handle 8341 * @cmd: Profiling command index 8342 * @value1: parameter1 value 8343 * @value2: parameter2 value 8344 * 8345 * Return: QDF_STATUS_SUCCESS for success else error code 8346 */ 8347 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 8348 uint32_t cmd, uint32_t value1, uint32_t value2) 8349 { 8350 wmi_buf_t buf; 8351 int32_t len = 0; 8352 int ret; 8353 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8354 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8355 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8356 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 8357 8358 switch (cmd) { 8359 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 8360 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8361 buf = wmi_buf_alloc(wmi_handle, len); 8362 if (!buf) { 8363 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8364 return QDF_STATUS_E_NOMEM; 8365 } 8366 prof_trig_cmd = 8367 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8368 wmi_buf_data(buf); 8369 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8370 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8371 WMITLV_GET_STRUCT_TLVLEN 8372 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8373 prof_trig_cmd->enable = value1; 8374 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8375 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8376 if (ret) { 8377 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 8378 value1); 8379 wmi_buf_free(buf); 8380 return ret; 8381 } 8382 break; 8383 8384 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 8385 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 8386 buf = wmi_buf_alloc(wmi_handle, len); 8387 if (!buf) { 8388 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8389 return QDF_STATUS_E_NOMEM; 8390 } 8391 profile_getdata_cmd = 8392 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 8393 wmi_buf_data(buf); 8394 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 8395 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 8396 WMITLV_GET_STRUCT_TLVLEN 8397 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 8398 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8399 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 8400 if (ret) { 8401 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 8402 value1, value2); 8403 wmi_buf_free(buf); 8404 return ret; 8405 } 8406 break; 8407 8408 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 8409 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8410 buf = wmi_buf_alloc(wmi_handle, len); 8411 if (!buf) { 8412 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8413 return QDF_STATUS_E_NOMEM; 8414 } 8415 hist_intvl_cmd = 8416 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8417 wmi_buf_data(buf); 8418 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8419 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8420 WMITLV_GET_STRUCT_TLVLEN 8421 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8422 hist_intvl_cmd->profile_id = value1; 8423 hist_intvl_cmd->value = value2; 8424 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8425 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8426 if (ret) { 8427 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 8428 value1, value2); 8429 wmi_buf_free(buf); 8430 return ret; 8431 } 8432 break; 8433 8434 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 8435 len = 8436 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8437 buf = wmi_buf_alloc(wmi_handle, len); 8438 if (!buf) { 8439 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8440 return QDF_STATUS_E_NOMEM; 8441 } 8442 profile_enable_cmd = 8443 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8444 wmi_buf_data(buf); 8445 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8446 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8447 WMITLV_GET_STRUCT_TLVLEN 8448 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8449 profile_enable_cmd->profile_id = value1; 8450 profile_enable_cmd->enable = value2; 8451 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8452 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8453 if (ret) { 8454 WMI_LOGE("enable cmd Failed for id %d value %d", 8455 value1, value2); 8456 wmi_buf_free(buf); 8457 return ret; 8458 } 8459 break; 8460 8461 default: 8462 WMI_LOGD("%s: invalid profiling command", __func__); 8463 break; 8464 } 8465 8466 return 0; 8467 } 8468 8469 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 8470 struct wlm_latency_level_param *params) 8471 { 8472 wmi_wlm_config_cmd_fixed_param *cmd; 8473 wmi_buf_t buf; 8474 uint32_t len = sizeof(*cmd); 8475 static uint32_t ll[4] = {100, 60, 40, 20}; 8476 8477 buf = wmi_buf_alloc(wmi_handle, len); 8478 if (!buf) { 8479 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8480 return QDF_STATUS_E_NOMEM; 8481 } 8482 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 8483 WMITLV_SET_HDR(&cmd->tlv_header, 8484 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 8485 WMITLV_GET_STRUCT_TLVLEN 8486 (wmi_wlm_config_cmd_fixed_param)); 8487 cmd->vdev_id = params->vdev_id; 8488 cmd->latency_level = params->wlm_latency_level; 8489 cmd->ul_latency = ll[params->wlm_latency_level]; 8490 cmd->dl_latency = ll[params->wlm_latency_level]; 8491 cmd->flags = params->wlm_latency_flags; 8492 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8493 WMI_WLM_CONFIG_CMDID)) { 8494 WMI_LOGE("%s: Failed to send setting latency config command", 8495 __func__); 8496 wmi_buf_free(buf); 8497 return QDF_STATUS_E_FAILURE; 8498 } 8499 8500 return 0; 8501 } 8502 /** 8503 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 8504 * @wmi_handle: wmi handle 8505 * @vdev_id: vdev id 8506 * 8507 * Return: QDF_STATUS_SUCCESS for success or error code 8508 */ 8509 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8510 { 8511 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 8512 wmi_buf_t buf; 8513 int32_t len = sizeof(*cmd); 8514 8515 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8516 buf = wmi_buf_alloc(wmi_handle, len); 8517 if (!buf) { 8518 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8519 return QDF_STATUS_E_NOMEM; 8520 } 8521 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 8522 wmi_buf_data(buf); 8523 WMITLV_SET_HDR(&cmd->tlv_header, 8524 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 8525 WMITLV_GET_STRUCT_TLVLEN 8526 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 8527 cmd->vdev_id = vdev_id; 8528 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 8529 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8530 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 8531 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 8532 __func__); 8533 wmi_buf_free(buf); 8534 return QDF_STATUS_E_FAILURE; 8535 } 8536 8537 return 0; 8538 } 8539 8540 /** 8541 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 8542 * @wmi_handle: wmi handle 8543 * @vdev_id: vdev id 8544 * 8545 * Return: QDF_STATUS_SUCCESS for success or error code 8546 */ 8547 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 8548 uint8_t vdev_id) 8549 { 8550 wmi_csa_offload_enable_cmd_fixed_param *cmd; 8551 wmi_buf_t buf; 8552 int32_t len = sizeof(*cmd); 8553 8554 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8555 buf = wmi_buf_alloc(wmi_handle, len); 8556 if (!buf) { 8557 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8558 return QDF_STATUS_E_NOMEM; 8559 } 8560 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 8561 WMITLV_SET_HDR(&cmd->tlv_header, 8562 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 8563 WMITLV_GET_STRUCT_TLVLEN 8564 (wmi_csa_offload_enable_cmd_fixed_param)); 8565 cmd->vdev_id = vdev_id; 8566 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 8567 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8568 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 8569 WMI_LOGP("%s: Failed to send CSA offload enable command", 8570 __func__); 8571 wmi_buf_free(buf); 8572 return QDF_STATUS_E_FAILURE; 8573 } 8574 8575 return 0; 8576 } 8577 8578 #ifdef WLAN_FEATURE_CIF_CFR 8579 /** 8580 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 8581 * @wmi_handle: wmi handle 8582 * @data_len: len of dma cfg req 8583 * @data: dma cfg req 8584 * 8585 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8586 */ 8587 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8588 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 8589 { 8590 wmi_buf_t buf; 8591 uint8_t *cmd; 8592 QDF_STATUS ret; 8593 8594 WMITLV_SET_HDR(cfg, 8595 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 8596 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 8597 8598 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 8599 if (!buf) { 8600 WMI_LOGE(FL("wmi_buf_alloc failed")); 8601 return QDF_STATUS_E_FAILURE; 8602 } 8603 8604 cmd = (uint8_t *) wmi_buf_data(buf); 8605 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 8606 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 8607 sizeof(*cfg)); 8608 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 8609 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 8610 if (QDF_IS_STATUS_ERROR(ret)) { 8611 WMI_LOGE(FL(":wmi cmd send failed")); 8612 wmi_buf_free(buf); 8613 } 8614 8615 return ret; 8616 } 8617 #endif 8618 8619 /** 8620 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 8621 * @wmi_handle: wmi handle 8622 * @data_len: len of dma cfg req 8623 * @data: dma cfg req 8624 * 8625 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8626 */ 8627 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8628 struct direct_buf_rx_cfg_req *cfg) 8629 { 8630 wmi_buf_t buf; 8631 wmi_dma_ring_cfg_req_fixed_param *cmd; 8632 QDF_STATUS ret; 8633 int32_t len = sizeof(*cmd); 8634 8635 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8636 if (!buf) { 8637 WMI_LOGE(FL("wmi_buf_alloc failed")); 8638 return QDF_STATUS_E_FAILURE; 8639 } 8640 8641 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 8642 8643 WMITLV_SET_HDR(&cmd->tlv_header, 8644 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 8645 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 8646 8647 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8648 cfg->pdev_id); 8649 cmd->mod_id = cfg->mod_id; 8650 cmd->base_paddr_lo = cfg->base_paddr_lo; 8651 cmd->base_paddr_hi = cfg->base_paddr_hi; 8652 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 8653 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 8654 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 8655 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 8656 cmd->num_elems = cfg->num_elems; 8657 cmd->buf_size = cfg->buf_size; 8658 cmd->num_resp_per_event = cfg->num_resp_per_event; 8659 cmd->event_timeout_ms = cfg->event_timeout_ms; 8660 8661 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 8662 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 8663 "head idx paddr hi %x tail idx paddr lo %x" 8664 "tail idx addr hi %x num elems %d buf size %d num resp %d" 8665 "event timeout %d\n", __func__, cmd->pdev_id, 8666 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 8667 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 8668 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 8669 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 8670 cmd->event_timeout_ms); 8671 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8672 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 8673 if (QDF_IS_STATUS_ERROR(ret)) { 8674 WMI_LOGE(FL(":wmi cmd send failed")); 8675 wmi_buf_free(buf); 8676 } 8677 8678 return ret; 8679 } 8680 8681 /** 8682 * send_start_11d_scan_cmd_tlv() - start 11d scan request 8683 * @wmi_handle: wmi handle 8684 * @start_11d_scan: 11d scan start request parameters 8685 * 8686 * This function request FW to start 11d scan. 8687 * 8688 * Return: QDF status 8689 */ 8690 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8691 struct reg_start_11d_scan_req *start_11d_scan) 8692 { 8693 wmi_11d_scan_start_cmd_fixed_param *cmd; 8694 int32_t len; 8695 wmi_buf_t buf; 8696 int ret; 8697 8698 len = sizeof(*cmd); 8699 buf = wmi_buf_alloc(wmi_handle, len); 8700 if (!buf) { 8701 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8702 return QDF_STATUS_E_NOMEM; 8703 } 8704 8705 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 8706 8707 WMITLV_SET_HDR(&cmd->tlv_header, 8708 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 8709 WMITLV_GET_STRUCT_TLVLEN 8710 (wmi_11d_scan_start_cmd_fixed_param)); 8711 8712 cmd->vdev_id = start_11d_scan->vdev_id; 8713 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 8714 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 8715 8716 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 8717 8718 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8719 WMI_11D_SCAN_START_CMDID); 8720 if (ret) { 8721 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 8722 wmi_buf_free(buf); 8723 return QDF_STATUS_E_FAILURE; 8724 } 8725 8726 return QDF_STATUS_SUCCESS; 8727 } 8728 8729 /** 8730 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 8731 * @wmi_handle: wmi handle 8732 * @start_11d_scan: 11d scan stop request parameters 8733 * 8734 * This function request FW to stop 11d scan. 8735 * 8736 * Return: QDF status 8737 */ 8738 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8739 struct reg_stop_11d_scan_req *stop_11d_scan) 8740 { 8741 wmi_11d_scan_stop_cmd_fixed_param *cmd; 8742 int32_t len; 8743 wmi_buf_t buf; 8744 int ret; 8745 8746 len = sizeof(*cmd); 8747 buf = wmi_buf_alloc(wmi_handle, len); 8748 if (!buf) { 8749 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8750 return QDF_STATUS_E_NOMEM; 8751 } 8752 8753 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 8754 8755 WMITLV_SET_HDR(&cmd->tlv_header, 8756 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 8757 WMITLV_GET_STRUCT_TLVLEN 8758 (wmi_11d_scan_stop_cmd_fixed_param)); 8759 8760 cmd->vdev_id = stop_11d_scan->vdev_id; 8761 8762 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 8763 8764 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8765 WMI_11D_SCAN_STOP_CMDID); 8766 if (ret) { 8767 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 8768 wmi_buf_free(buf); 8769 return QDF_STATUS_E_FAILURE; 8770 } 8771 8772 return QDF_STATUS_SUCCESS; 8773 } 8774 8775 /** 8776 * send_start_oem_data_cmd_tlv() - start OEM data request to target 8777 * @wmi_handle: wmi handle 8778 * @startOemDataReq: start request params 8779 * 8780 * Return: CDF status 8781 */ 8782 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 8783 uint32_t data_len, 8784 uint8_t *data) 8785 { 8786 wmi_buf_t buf; 8787 uint8_t *cmd; 8788 QDF_STATUS ret; 8789 8790 buf = wmi_buf_alloc(wmi_handle, 8791 (data_len + WMI_TLV_HDR_SIZE)); 8792 if (!buf) { 8793 WMI_LOGE(FL("wmi_buf_alloc failed")); 8794 return QDF_STATUS_E_FAILURE; 8795 } 8796 8797 cmd = (uint8_t *) wmi_buf_data(buf); 8798 8799 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 8800 cmd += WMI_TLV_HDR_SIZE; 8801 qdf_mem_copy(cmd, data, 8802 data_len); 8803 8804 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 8805 data_len); 8806 8807 ret = wmi_unified_cmd_send(wmi_handle, buf, 8808 (data_len + 8809 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 8810 8811 if (QDF_IS_STATUS_ERROR(ret)) { 8812 WMI_LOGE(FL(":wmi cmd send failed")); 8813 wmi_buf_free(buf); 8814 } 8815 8816 return ret; 8817 } 8818 8819 /** 8820 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 8821 * @wmi_handle: wmi handle 8822 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 8823 * 8824 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 8825 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 8826 * to firmware based on phyerr filtering 8827 * offload status. 8828 * 8829 * Return: 1 success, 0 failure 8830 */ 8831 static QDF_STATUS 8832 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8833 bool dfs_phyerr_filter_offload) 8834 { 8835 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 8836 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 8837 wmi_buf_t buf; 8838 uint16_t len; 8839 QDF_STATUS ret; 8840 8841 8842 if (false == dfs_phyerr_filter_offload) { 8843 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 8844 __func__); 8845 len = sizeof(*disable_phyerr_offload_cmd); 8846 buf = wmi_buf_alloc(wmi_handle, len); 8847 if (!buf) { 8848 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8849 return 0; 8850 } 8851 disable_phyerr_offload_cmd = 8852 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 8853 wmi_buf_data(buf); 8854 8855 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 8856 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 8857 WMITLV_GET_STRUCT_TLVLEN 8858 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 8859 8860 /* 8861 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 8862 * to the firmware to disable the phyerror 8863 * filtering offload. 8864 */ 8865 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8866 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 8867 if (QDF_IS_STATUS_ERROR(ret)) { 8868 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID 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_DIS_CMDID Send Success", 8874 __func__); 8875 } else { 8876 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 8877 __func__); 8878 8879 len = sizeof(*enable_phyerr_offload_cmd); 8880 buf = wmi_buf_alloc(wmi_handle, len); 8881 if (!buf) { 8882 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 8883 return QDF_STATUS_E_FAILURE; 8884 } 8885 8886 enable_phyerr_offload_cmd = 8887 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 8888 wmi_buf_data(buf); 8889 8890 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 8891 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 8892 WMITLV_GET_STRUCT_TLVLEN 8893 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 8894 8895 /* 8896 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 8897 * to the firmware to enable the phyerror 8898 * filtering offload. 8899 */ 8900 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8901 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 8902 8903 if (QDF_IS_STATUS_ERROR(ret)) { 8904 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 8905 __func__, ret); 8906 wmi_buf_free(buf); 8907 return QDF_STATUS_E_FAILURE; 8908 } 8909 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 8910 __func__); 8911 } 8912 8913 return QDF_STATUS_SUCCESS; 8914 } 8915 8916 /** 8917 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 8918 * will wake up host after specified time is elapsed 8919 * @wmi_handle: wmi handle 8920 * @vdev_id: vdev id 8921 * @cookie: value to identify reason why host set up wake call. 8922 * @time: time in ms 8923 * 8924 * Return: QDF status 8925 */ 8926 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 8927 uint8_t vdev_id, uint32_t cookie, uint32_t time) 8928 { 8929 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 8930 wmi_buf_t buf; 8931 uint8_t *buf_ptr; 8932 int32_t len; 8933 int ret; 8934 8935 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 8936 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 8937 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 8938 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 8939 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 8940 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 8941 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 8942 8943 buf = wmi_buf_alloc(wmi_handle, len); 8944 if (!buf) { 8945 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8946 return QDF_STATUS_E_NOMEM; 8947 } 8948 8949 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 8950 buf_ptr = (uint8_t *) cmd; 8951 8952 WMITLV_SET_HDR(&cmd->tlv_header, 8953 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 8954 WMITLV_GET_STRUCT_TLVLEN 8955 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 8956 cmd->vdev_id = vdev_id; 8957 cmd->pattern_id = cookie, 8958 cmd->pattern_type = WOW_TIMER_PATTERN; 8959 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 8960 8961 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 8962 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8963 buf_ptr += WMI_TLV_HDR_SIZE; 8964 8965 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 8966 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8967 buf_ptr += WMI_TLV_HDR_SIZE; 8968 8969 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 8970 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8971 buf_ptr += WMI_TLV_HDR_SIZE; 8972 8973 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 8974 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8975 buf_ptr += WMI_TLV_HDR_SIZE; 8976 8977 /* Fill TLV for pattern_info_timeout, and time value */ 8978 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8979 buf_ptr += WMI_TLV_HDR_SIZE; 8980 *((uint32_t *) buf_ptr) = time; 8981 buf_ptr += sizeof(uint32_t); 8982 8983 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 8984 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8985 buf_ptr += WMI_TLV_HDR_SIZE; 8986 *((uint32_t *) buf_ptr) = 0; 8987 8988 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 8989 __func__, time, vdev_id); 8990 8991 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8992 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 8993 if (ret) { 8994 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 8995 __func__); 8996 wmi_buf_free(buf); 8997 return QDF_STATUS_E_FAILURE; 8998 } 8999 9000 return QDF_STATUS_SUCCESS; 9001 } 9002 9003 #if !defined(REMOVE_PKT_LOG) 9004 /** 9005 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 9006 * @wmi_handle: wmi handle 9007 * @pktlog_event: pktlog event 9008 * @cmd_id: pktlog cmd id 9009 * 9010 * Return: CDF status 9011 */ 9012 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 9013 WMI_PKTLOG_EVENT pktlog_event, 9014 WMI_CMD_ID cmd_id, uint8_t user_triggered) 9015 { 9016 WMI_PKTLOG_EVENT PKTLOG_EVENT; 9017 WMI_CMD_ID CMD_ID; 9018 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 9019 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 9020 int len = 0; 9021 wmi_buf_t buf; 9022 9023 PKTLOG_EVENT = pktlog_event; 9024 CMD_ID = cmd_id; 9025 9026 switch (CMD_ID) { 9027 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 9028 len = sizeof(*cmd); 9029 buf = wmi_buf_alloc(wmi_handle, len); 9030 if (!buf) { 9031 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9032 return QDF_STATUS_E_NOMEM; 9033 } 9034 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 9035 wmi_buf_data(buf); 9036 WMITLV_SET_HDR(&cmd->tlv_header, 9037 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9038 WMITLV_GET_STRUCT_TLVLEN 9039 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9040 cmd->evlist = PKTLOG_EVENT; 9041 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9042 : WMI_PKTLOG_ENABLE_AUTO; 9043 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9044 WMI_HOST_PDEV_ID_SOC); 9045 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9046 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9047 WMI_LOGE("failed to send pktlog enable cmdid"); 9048 goto wmi_send_failed; 9049 } 9050 break; 9051 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9052 len = sizeof(*disable_cmd); 9053 buf = wmi_buf_alloc(wmi_handle, len); 9054 if (!buf) { 9055 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9056 return QDF_STATUS_E_NOMEM; 9057 } 9058 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9059 wmi_buf_data(buf); 9060 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9061 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9062 WMITLV_GET_STRUCT_TLVLEN 9063 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9064 disable_cmd->pdev_id = 9065 wmi_handle->ops->convert_pdev_id_host_to_target( 9066 WMI_HOST_PDEV_ID_SOC); 9067 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9068 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9069 WMI_LOGE("failed to send pktlog disable cmdid"); 9070 goto wmi_send_failed; 9071 } 9072 break; 9073 default: 9074 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9075 break; 9076 } 9077 9078 return QDF_STATUS_SUCCESS; 9079 9080 wmi_send_failed: 9081 wmi_buf_free(buf); 9082 return QDF_STATUS_E_FAILURE; 9083 } 9084 #endif /* REMOVE_PKT_LOG */ 9085 9086 /** 9087 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9088 * @wmi_handle: wmi handle 9089 * @ptrn_id: pattern id 9090 * @vdev_id: vdev id 9091 * 9092 * Return: CDF status 9093 */ 9094 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9095 uint8_t ptrn_id, uint8_t vdev_id) 9096 { 9097 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9098 wmi_buf_t buf; 9099 int32_t len; 9100 int ret; 9101 9102 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9103 9104 9105 buf = wmi_buf_alloc(wmi_handle, len); 9106 if (!buf) { 9107 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9108 return QDF_STATUS_E_NOMEM; 9109 } 9110 9111 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9112 9113 WMITLV_SET_HDR(&cmd->tlv_header, 9114 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9115 WMITLV_GET_STRUCT_TLVLEN( 9116 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9117 cmd->vdev_id = vdev_id; 9118 cmd->pattern_id = ptrn_id; 9119 cmd->pattern_type = WOW_BITMAP_PATTERN; 9120 9121 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9122 cmd->pattern_id, vdev_id); 9123 9124 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9125 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9126 if (ret) { 9127 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9128 wmi_buf_free(buf); 9129 return QDF_STATUS_E_FAILURE; 9130 } 9131 9132 return QDF_STATUS_SUCCESS; 9133 } 9134 9135 /** 9136 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9137 * @wmi_handle: wmi handle 9138 * 9139 * Sends host wakeup indication to FW. On receiving this indication, 9140 * FW will come out of WOW. 9141 * 9142 * Return: CDF status 9143 */ 9144 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9145 { 9146 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9147 wmi_buf_t buf; 9148 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9149 int32_t len; 9150 int ret; 9151 9152 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9153 9154 buf = wmi_buf_alloc(wmi_handle, len); 9155 if (!buf) { 9156 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9157 return QDF_STATUS_E_NOMEM; 9158 } 9159 9160 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9161 wmi_buf_data(buf); 9162 WMITLV_SET_HDR(&cmd->tlv_header, 9163 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9164 WMITLV_GET_STRUCT_TLVLEN 9165 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9166 9167 9168 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9169 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9170 if (ret) { 9171 WMI_LOGE("Failed to send host wakeup indication to fw"); 9172 wmi_buf_free(buf); 9173 return QDF_STATUS_E_FAILURE; 9174 } 9175 9176 return qdf_status; 9177 } 9178 9179 /** 9180 * send_del_ts_cmd_tlv() - send DELTS request to fw 9181 * @wmi_handle: wmi handle 9182 * @msg: delts params 9183 * 9184 * Return: CDF status 9185 */ 9186 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9187 uint8_t ac) 9188 { 9189 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9190 wmi_buf_t buf; 9191 int32_t len = sizeof(*cmd); 9192 9193 buf = wmi_buf_alloc(wmi_handle, len); 9194 if (!buf) { 9195 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9196 return QDF_STATUS_E_NOMEM; 9197 } 9198 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9199 WMITLV_SET_HDR(&cmd->tlv_header, 9200 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9201 WMITLV_GET_STRUCT_TLVLEN 9202 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9203 cmd->vdev_id = vdev_id; 9204 cmd->ac = ac; 9205 9206 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9207 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9208 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9209 WMI_VDEV_WMM_DELTS_CMDID)) { 9210 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9211 wmi_buf_free(buf); 9212 return QDF_STATUS_E_FAILURE; 9213 } 9214 9215 return QDF_STATUS_SUCCESS; 9216 } 9217 9218 /** 9219 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9220 * @wmi_handle: handle to wmi 9221 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9222 * 9223 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9224 * ADD_TS requestes to firmware in loop for all the ACs with 9225 * active flow. 9226 * 9227 * Return: CDF status 9228 */ 9229 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9230 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9231 { 9232 int i = 0; 9233 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9234 wmi_buf_t buf; 9235 int32_t len = sizeof(*cmd); 9236 9237 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9238 /* if flow in this AC is active */ 9239 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9240 /* 9241 * as per implementation of wma_add_ts_req() we 9242 * are not waiting any response from firmware so 9243 * apart from sending ADDTS to firmware just send 9244 * success to upper layers 9245 */ 9246 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9247 9248 buf = wmi_buf_alloc(wmi_handle, len); 9249 if (!buf) { 9250 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9251 return QDF_STATUS_E_NOMEM; 9252 } 9253 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9254 wmi_buf_data(buf); 9255 WMITLV_SET_HDR(&cmd->tlv_header, 9256 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9257 WMITLV_GET_STRUCT_TLVLEN 9258 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9259 cmd->vdev_id = aggr_qos_rsp_msg->vdev_id; 9260 cmd->ac = 9261 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9262 traffic.userPrio); 9263 cmd->medium_time_us = 9264 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9265 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9266 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9267 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9268 cmd->medium_time_us, cmd->downgrade_type); 9269 if (wmi_unified_cmd_send 9270 (wmi_handle, buf, len, 9271 WMI_VDEV_WMM_ADDTS_CMDID)) { 9272 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9273 __func__); 9274 aggr_qos_rsp_msg->status[i] = 9275 QDF_STATUS_E_FAILURE; 9276 wmi_buf_free(buf); 9277 return QDF_STATUS_E_FAILURE; 9278 } 9279 } 9280 } 9281 9282 return QDF_STATUS_SUCCESS; 9283 } 9284 9285 /** 9286 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9287 * @wmi_handle: wmi handle 9288 * @msg: ADDTS params 9289 * 9290 * Return: CDF status 9291 */ 9292 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9293 struct add_ts_param *msg) 9294 { 9295 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9296 wmi_buf_t buf; 9297 int32_t len = sizeof(*cmd); 9298 9299 msg->status = QDF_STATUS_SUCCESS; 9300 9301 buf = wmi_buf_alloc(wmi_handle, len); 9302 if (!buf) { 9303 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9304 return QDF_STATUS_E_NOMEM; 9305 } 9306 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9307 WMITLV_SET_HDR(&cmd->tlv_header, 9308 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9309 WMITLV_GET_STRUCT_TLVLEN 9310 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9311 cmd->vdev_id = msg->sme_session_id; 9312 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9313 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9314 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9315 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9316 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9317 cmd->downgrade_type, __func__, __LINE__); 9318 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9319 WMI_VDEV_WMM_ADDTS_CMDID)) { 9320 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9321 msg->status = QDF_STATUS_E_FAILURE; 9322 wmi_buf_free(buf); 9323 return QDF_STATUS_E_FAILURE; 9324 } 9325 9326 return QDF_STATUS_SUCCESS; 9327 } 9328 9329 /** 9330 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 9331 * @wmi_handle: wmi handle 9332 * @pAddPeriodicTxPtrnParams: tx ptrn params 9333 * 9334 * Retrun: CDF status 9335 */ 9336 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9337 struct periodic_tx_pattern * 9338 pAddPeriodicTxPtrnParams, 9339 uint8_t vdev_id) 9340 { 9341 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9342 wmi_buf_t wmi_buf; 9343 uint32_t len; 9344 uint8_t *buf_ptr; 9345 uint32_t ptrn_len, ptrn_len_aligned; 9346 int j; 9347 9348 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 9349 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 9350 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 9351 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 9352 9353 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9354 if (!wmi_buf) { 9355 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9356 return QDF_STATUS_E_NOMEM; 9357 } 9358 9359 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 9360 9361 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 9362 WMITLV_SET_HDR(&cmd->tlv_header, 9363 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9364 WMITLV_GET_STRUCT_TLVLEN 9365 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9366 9367 /* Pass the pattern id to delete for the corresponding vdev id */ 9368 cmd->vdev_id = vdev_id; 9369 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 9370 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 9371 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 9372 9373 /* Pattern info */ 9374 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9375 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 9376 buf_ptr += WMI_TLV_HDR_SIZE; 9377 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 9378 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 9379 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 9380 9381 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 9382 __func__, cmd->pattern_id, cmd->vdev_id); 9383 9384 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9385 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9386 WMI_LOGE("%s: failed to add pattern set state command", 9387 __func__); 9388 wmi_buf_free(wmi_buf); 9389 return QDF_STATUS_E_FAILURE; 9390 } 9391 return QDF_STATUS_SUCCESS; 9392 } 9393 9394 /** 9395 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 9396 * @wmi_handle: wmi handle 9397 * @vdev_id: vdev id 9398 * @pattern_id: pattern id 9399 * 9400 * Retrun: CDF status 9401 */ 9402 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9403 uint8_t vdev_id, 9404 uint8_t pattern_id) 9405 { 9406 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9407 wmi_buf_t wmi_buf; 9408 uint32_t len = 9409 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9410 9411 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9412 if (!wmi_buf) { 9413 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9414 return QDF_STATUS_E_NOMEM; 9415 } 9416 9417 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 9418 wmi_buf_data(wmi_buf); 9419 WMITLV_SET_HDR(&cmd->tlv_header, 9420 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9421 WMITLV_GET_STRUCT_TLVLEN 9422 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9423 9424 /* Pass the pattern id to delete for the corresponding vdev id */ 9425 cmd->vdev_id = vdev_id; 9426 cmd->pattern_id = pattern_id; 9427 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 9428 __func__, cmd->pattern_id, cmd->vdev_id); 9429 9430 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9431 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9432 WMI_LOGE("%s: failed to send del pattern command", __func__); 9433 wmi_buf_free(wmi_buf); 9434 return QDF_STATUS_E_FAILURE; 9435 } 9436 return QDF_STATUS_SUCCESS; 9437 } 9438 9439 /** 9440 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 9441 * @wmi_handle: wmi handle 9442 * @preq: stats ext params 9443 * 9444 * Return: CDF status 9445 */ 9446 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 9447 struct stats_ext_params *preq) 9448 { 9449 QDF_STATUS ret; 9450 wmi_req_stats_ext_cmd_fixed_param *cmd; 9451 wmi_buf_t buf; 9452 size_t len; 9453 uint8_t *buf_ptr; 9454 9455 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 9456 9457 buf = wmi_buf_alloc(wmi_handle, len); 9458 if (!buf) { 9459 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9460 return QDF_STATUS_E_NOMEM; 9461 } 9462 9463 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9464 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 9465 9466 WMITLV_SET_HDR(&cmd->tlv_header, 9467 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 9468 WMITLV_GET_STRUCT_TLVLEN 9469 (wmi_req_stats_ext_cmd_fixed_param)); 9470 cmd->vdev_id = preq->vdev_id; 9471 cmd->data_len = preq->request_data_len; 9472 9473 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 9474 __func__, preq->request_data_len, preq->vdev_id); 9475 9476 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 9477 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 9478 9479 buf_ptr += WMI_TLV_HDR_SIZE; 9480 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 9481 9482 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9483 WMI_REQUEST_STATS_EXT_CMDID); 9484 if (QDF_IS_STATUS_ERROR(ret)) { 9485 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 9486 ret); 9487 wmi_buf_free(buf); 9488 } 9489 9490 return ret; 9491 } 9492 9493 /** 9494 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 9495 * @wmi_handle: wmi handle 9496 * @params: ext wow params 9497 * 9498 * Return:0 for success or error code 9499 */ 9500 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 9501 struct ext_wow_params *params) 9502 { 9503 wmi_extwow_enable_cmd_fixed_param *cmd; 9504 wmi_buf_t buf; 9505 int32_t len; 9506 int ret; 9507 9508 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 9509 buf = wmi_buf_alloc(wmi_handle, len); 9510 if (!buf) { 9511 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9512 return QDF_STATUS_E_NOMEM; 9513 } 9514 9515 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 9516 9517 WMITLV_SET_HDR(&cmd->tlv_header, 9518 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 9519 WMITLV_GET_STRUCT_TLVLEN 9520 (wmi_extwow_enable_cmd_fixed_param)); 9521 9522 cmd->vdev_id = params->vdev_id; 9523 cmd->type = params->type; 9524 cmd->wakeup_pin_num = params->wakeup_pin_num; 9525 9526 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 9527 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 9528 9529 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9530 WMI_EXTWOW_ENABLE_CMDID); 9531 if (ret) { 9532 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 9533 wmi_buf_free(buf); 9534 return QDF_STATUS_E_FAILURE; 9535 } 9536 9537 return QDF_STATUS_SUCCESS; 9538 9539 } 9540 9541 /** 9542 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 9543 * @wmi_handle: wmi handle 9544 * @app_type1_params: app type1 params 9545 * 9546 * Return: CDF status 9547 */ 9548 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9549 struct app_type1_params *app_type1_params) 9550 { 9551 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 9552 wmi_buf_t buf; 9553 int32_t len; 9554 int ret; 9555 9556 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 9557 buf = wmi_buf_alloc(wmi_handle, len); 9558 if (!buf) { 9559 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9560 return QDF_STATUS_E_NOMEM; 9561 } 9562 9563 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 9564 wmi_buf_data(buf); 9565 9566 WMITLV_SET_HDR(&cmd->tlv_header, 9567 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 9568 WMITLV_GET_STRUCT_TLVLEN 9569 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 9570 9571 cmd->vdev_id = app_type1_params->vdev_id; 9572 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 9573 &cmd->wakee_mac); 9574 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 9575 cmd->ident_len = app_type1_params->id_length; 9576 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 9577 cmd->passwd_len = app_type1_params->pass_length; 9578 9579 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 9580 "identification_id %.8s id_length %u " 9581 "password %.16s pass_length %u", 9582 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 9583 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 9584 9585 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9586 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 9587 if (ret) { 9588 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 9589 wmi_buf_free(buf); 9590 return QDF_STATUS_E_FAILURE; 9591 } 9592 9593 return QDF_STATUS_SUCCESS; 9594 } 9595 9596 /** 9597 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 9598 * @wmi_handle: wmi handle 9599 * @appType2Params: app type2 params 9600 * 9601 * Return: CDF status 9602 */ 9603 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9604 struct app_type2_params *appType2Params) 9605 { 9606 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 9607 wmi_buf_t buf; 9608 int32_t len; 9609 int ret; 9610 9611 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 9612 buf = wmi_buf_alloc(wmi_handle, len); 9613 if (!buf) { 9614 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9615 return QDF_STATUS_E_NOMEM; 9616 } 9617 9618 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 9619 wmi_buf_data(buf); 9620 9621 WMITLV_SET_HDR(&cmd->tlv_header, 9622 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 9623 WMITLV_GET_STRUCT_TLVLEN 9624 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 9625 9626 cmd->vdev_id = appType2Params->vdev_id; 9627 9628 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 9629 cmd->rc4_key_len = appType2Params->rc4_key_len; 9630 9631 cmd->ip_id = appType2Params->ip_id; 9632 cmd->ip_device_ip = appType2Params->ip_device_ip; 9633 cmd->ip_server_ip = appType2Params->ip_server_ip; 9634 9635 cmd->tcp_src_port = appType2Params->tcp_src_port; 9636 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 9637 cmd->tcp_seq = appType2Params->tcp_seq; 9638 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 9639 9640 cmd->keepalive_init = appType2Params->keepalive_init; 9641 cmd->keepalive_min = appType2Params->keepalive_min; 9642 cmd->keepalive_max = appType2Params->keepalive_max; 9643 cmd->keepalive_inc = appType2Params->keepalive_inc; 9644 9645 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 9646 &cmd->gateway_mac); 9647 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 9648 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 9649 9650 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 9651 "rc4_key %.16s rc4_key_len %u " 9652 "ip_id %x ip_device_ip %x ip_server_ip %x " 9653 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 9654 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 9655 "keepalive_max %u keepalive_inc %u " 9656 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 9657 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 9658 cmd->rc4_key, cmd->rc4_key_len, 9659 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 9660 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 9661 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 9662 cmd->keepalive_max, cmd->keepalive_inc, 9663 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 9664 9665 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9666 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 9667 if (ret) { 9668 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 9669 wmi_buf_free(buf); 9670 return QDF_STATUS_E_FAILURE; 9671 } 9672 9673 return QDF_STATUS_SUCCESS; 9674 9675 } 9676 9677 /** 9678 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 9679 * @wmi_handle: wmi handle 9680 * @timer_val: auto shutdown timer value 9681 * 9682 * Return: CDF status 9683 */ 9684 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 9685 uint32_t timer_val) 9686 { 9687 QDF_STATUS status; 9688 wmi_buf_t buf = NULL; 9689 uint8_t *buf_ptr; 9690 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 9691 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 9692 9693 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 9694 __func__, timer_val); 9695 9696 buf = wmi_buf_alloc(wmi_handle, len); 9697 if (!buf) { 9698 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9699 return QDF_STATUS_E_NOMEM; 9700 } 9701 9702 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9703 wmi_auto_sh_cmd = 9704 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 9705 wmi_auto_sh_cmd->timer_value = timer_val; 9706 9707 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 9708 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 9709 WMITLV_GET_STRUCT_TLVLEN 9710 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 9711 9712 status = wmi_unified_cmd_send(wmi_handle, buf, 9713 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 9714 if (QDF_IS_STATUS_ERROR(status)) { 9715 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 9716 __func__, status); 9717 wmi_buf_free(buf); 9718 } 9719 9720 return status; 9721 } 9722 9723 /** 9724 * send_nan_req_cmd_tlv() - to send nan request to target 9725 * @wmi_handle: wmi handle 9726 * @nan_req: request data which will be non-null 9727 * 9728 * Return: CDF status 9729 */ 9730 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 9731 struct nan_req_params *nan_req) 9732 { 9733 QDF_STATUS ret; 9734 wmi_nan_cmd_param *cmd; 9735 wmi_buf_t buf; 9736 uint16_t len = sizeof(*cmd); 9737 uint16_t nan_data_len, nan_data_len_aligned; 9738 uint8_t *buf_ptr; 9739 9740 /* 9741 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 9742 * +------------+----------+-----------------------+--------------+ 9743 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 9744 * +------------+----------+-----------------------+--------------+ 9745 */ 9746 if (!nan_req) { 9747 WMI_LOGE("%s:nan req is not valid", __func__); 9748 return QDF_STATUS_E_FAILURE; 9749 } 9750 nan_data_len = nan_req->request_data_len; 9751 nan_data_len_aligned = roundup(nan_req->request_data_len, 9752 sizeof(uint32_t)); 9753 if (nan_data_len_aligned < nan_req->request_data_len) { 9754 WMI_LOGE("%s: integer overflow while rounding up data_len", 9755 __func__); 9756 return QDF_STATUS_E_FAILURE; 9757 } 9758 9759 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 9760 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 9761 __func__); 9762 return QDF_STATUS_E_FAILURE; 9763 } 9764 9765 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 9766 buf = wmi_buf_alloc(wmi_handle, len); 9767 if (!buf) { 9768 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9769 return QDF_STATUS_E_NOMEM; 9770 } 9771 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9772 cmd = (wmi_nan_cmd_param *) buf_ptr; 9773 WMITLV_SET_HDR(&cmd->tlv_header, 9774 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 9775 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 9776 cmd->data_len = nan_req->request_data_len; 9777 WMI_LOGD("%s: The data len value is %u", 9778 __func__, nan_req->request_data_len); 9779 buf_ptr += sizeof(wmi_nan_cmd_param); 9780 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 9781 buf_ptr += WMI_TLV_HDR_SIZE; 9782 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 9783 9784 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9785 WMI_NAN_CMDID); 9786 if (QDF_IS_STATUS_ERROR(ret)) { 9787 WMI_LOGE("%s Failed to send set param command ret = %d", 9788 __func__, ret); 9789 wmi_buf_free(buf); 9790 } 9791 9792 return ret; 9793 } 9794 9795 /** 9796 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 9797 * @wmi_handle: wmi handle 9798 * @params: DHCP server offload info 9799 * 9800 * Return: QDF_STATUS_SUCCESS for success or error code 9801 */ 9802 static QDF_STATUS 9803 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 9804 struct dhcp_offload_info_params *params) 9805 { 9806 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 9807 wmi_buf_t buf; 9808 QDF_STATUS status; 9809 9810 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 9811 if (!buf) { 9812 WMI_LOGE("Failed to allocate buffer to send " 9813 "set_dhcp_server_offload cmd"); 9814 return QDF_STATUS_E_NOMEM; 9815 } 9816 9817 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 9818 9819 WMITLV_SET_HDR(&cmd->tlv_header, 9820 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 9821 WMITLV_GET_STRUCT_TLVLEN 9822 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 9823 cmd->vdev_id = params->vdev_id; 9824 cmd->enable = params->dhcp_offload_enabled; 9825 cmd->num_client = params->dhcp_client_num; 9826 cmd->srv_ipv4 = params->dhcp_srv_addr; 9827 cmd->start_lsb = 0; 9828 status = wmi_unified_cmd_send(wmi_handle, buf, 9829 sizeof(*cmd), 9830 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 9831 if (QDF_IS_STATUS_ERROR(status)) { 9832 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 9833 wmi_buf_free(buf); 9834 return QDF_STATUS_E_FAILURE; 9835 } 9836 WMI_LOGD("Set dhcp server offload to vdevId %d", 9837 params->vdev_id); 9838 9839 return status; 9840 } 9841 9842 /** 9843 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 9844 * @wmi_handle: wmi handle 9845 * @flashing: flashing request 9846 * 9847 * Return: CDF status 9848 */ 9849 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 9850 struct flashing_req_params *flashing) 9851 { 9852 wmi_set_led_flashing_cmd_fixed_param *cmd; 9853 QDF_STATUS status; 9854 wmi_buf_t buf; 9855 uint8_t *buf_ptr; 9856 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 9857 9858 buf = wmi_buf_alloc(wmi_handle, len); 9859 if (!buf) { 9860 WMI_LOGP(FL("wmi_buf_alloc failed")); 9861 return QDF_STATUS_E_NOMEM; 9862 } 9863 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9864 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 9865 WMITLV_SET_HDR(&cmd->tlv_header, 9866 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 9867 WMITLV_GET_STRUCT_TLVLEN 9868 (wmi_set_led_flashing_cmd_fixed_param)); 9869 cmd->pattern_id = flashing->pattern_id; 9870 cmd->led_x0 = flashing->led_x0; 9871 cmd->led_x1 = flashing->led_x1; 9872 9873 status = wmi_unified_cmd_send(wmi_handle, buf, len, 9874 WMI_PDEV_SET_LED_FLASHING_CMDID); 9875 if (QDF_IS_STATUS_ERROR(status)) { 9876 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 9877 " returned Error %d", __func__, status); 9878 wmi_buf_free(buf); 9879 } 9880 9881 return status; 9882 } 9883 9884 /** 9885 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 9886 * @wmi_handle: wmi handle 9887 * @ch_avoid_update_req: channel avoid update params 9888 * 9889 * Return: CDF status 9890 */ 9891 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 9892 { 9893 QDF_STATUS status; 9894 wmi_buf_t buf = NULL; 9895 uint8_t *buf_ptr; 9896 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 9897 int len = sizeof(wmi_chan_avoid_update_cmd_param); 9898 9899 9900 buf = wmi_buf_alloc(wmi_handle, len); 9901 if (!buf) { 9902 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9903 return QDF_STATUS_E_NOMEM; 9904 } 9905 9906 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9907 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 9908 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 9909 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 9910 WMITLV_GET_STRUCT_TLVLEN 9911 (wmi_chan_avoid_update_cmd_param)); 9912 9913 status = wmi_unified_cmd_send(wmi_handle, buf, 9914 len, WMI_CHAN_AVOID_UPDATE_CMDID); 9915 if (QDF_IS_STATUS_ERROR(status)) { 9916 WMI_LOGE("wmi_unified_cmd_send" 9917 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 9918 " returned Error %d", status); 9919 wmi_buf_free(buf); 9920 } 9921 9922 return status; 9923 } 9924 9925 /** 9926 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 9927 * @wmi_handle: wmi handle 9928 * @param: pointer to pdev regdomain params 9929 * 9930 * Return: 0 for success or error code 9931 */ 9932 static QDF_STATUS 9933 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 9934 struct pdev_set_regdomain_params *param) 9935 { 9936 wmi_buf_t buf; 9937 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9938 int32_t len = sizeof(*cmd); 9939 9940 9941 buf = wmi_buf_alloc(wmi_handle, len); 9942 if (!buf) { 9943 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9944 return QDF_STATUS_E_NOMEM; 9945 } 9946 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9947 WMITLV_SET_HDR(&cmd->tlv_header, 9948 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 9949 WMITLV_GET_STRUCT_TLVLEN 9950 (wmi_pdev_set_regdomain_cmd_fixed_param)); 9951 9952 cmd->reg_domain = param->currentRDinuse; 9953 cmd->reg_domain_2G = param->currentRD2G; 9954 cmd->reg_domain_5G = param->currentRD5G; 9955 cmd->conformance_test_limit_2G = param->ctl_2G; 9956 cmd->conformance_test_limit_5G = param->ctl_5G; 9957 cmd->dfs_domain = param->dfsDomain; 9958 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9959 param->pdev_id); 9960 9961 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9962 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 9963 WMI_LOGE("%s: Failed to send pdev set regdomain command", 9964 __func__); 9965 wmi_buf_free(buf); 9966 return QDF_STATUS_E_FAILURE; 9967 } 9968 9969 return QDF_STATUS_SUCCESS; 9970 } 9971 9972 /** 9973 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 9974 * @wmi_handle: wmi handle 9975 * @reg_dmn: reg domain 9976 * @regdmn2G: 2G reg domain 9977 * @regdmn5G: 5G reg domain 9978 * @ctl2G: 2G test limit 9979 * @ctl5G: 5G test limit 9980 * 9981 * Return: none 9982 */ 9983 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 9984 uint32_t reg_dmn, uint16_t regdmn2G, 9985 uint16_t regdmn5G, uint8_t ctl2G, 9986 uint8_t ctl5G) 9987 { 9988 wmi_buf_t buf; 9989 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 9990 int32_t len = sizeof(*cmd); 9991 9992 9993 buf = wmi_buf_alloc(wmi_handle, len); 9994 if (!buf) { 9995 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9996 return QDF_STATUS_E_NOMEM; 9997 } 9998 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 9999 WMITLV_SET_HDR(&cmd->tlv_header, 10000 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10001 WMITLV_GET_STRUCT_TLVLEN 10002 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10003 cmd->reg_domain = reg_dmn; 10004 cmd->reg_domain_2G = regdmn2G; 10005 cmd->reg_domain_5G = regdmn5G; 10006 cmd->conformance_test_limit_2G = ctl2G; 10007 cmd->conformance_test_limit_5G = ctl5G; 10008 10009 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10010 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10011 WMI_LOGP("%s: Failed to send pdev set regdomain command", 10012 __func__); 10013 wmi_buf_free(buf); 10014 return QDF_STATUS_E_FAILURE; 10015 } 10016 10017 return QDF_STATUS_SUCCESS; 10018 } 10019 10020 10021 /** 10022 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 10023 * @wmi_handle: wmi handle 10024 * @chan_switch_params: Pointer to tdls channel switch parameter structure 10025 * 10026 * This function sets tdls off channel mode 10027 * 10028 * Return: 0 on success; Negative errno otherwise 10029 */ 10030 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 10031 struct tdls_channel_switch_params *chan_switch_params) 10032 { 10033 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 10034 wmi_buf_t wmi_buf; 10035 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10036 10037 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10038 if (!wmi_buf) { 10039 WMI_LOGE(FL("wmi_buf_alloc failed")); 10040 return QDF_STATUS_E_FAILURE; 10041 } 10042 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10043 wmi_buf_data(wmi_buf); 10044 WMITLV_SET_HDR(&cmd->tlv_header, 10045 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10046 WMITLV_GET_STRUCT_TLVLEN( 10047 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10048 10049 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10050 &cmd->peer_macaddr); 10051 cmd->vdev_id = chan_switch_params->vdev_id; 10052 cmd->offchan_mode = chan_switch_params->tdls_sw_mode; 10053 cmd->is_peer_responder = chan_switch_params->is_responder; 10054 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10055 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10056 cmd->offchan_oper_class = chan_switch_params->oper_class; 10057 10058 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10059 cmd->peer_macaddr.mac_addr31to0, 10060 cmd->peer_macaddr.mac_addr47to32); 10061 10062 WMI_LOGD(FL( 10063 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10064 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10065 ), 10066 cmd->vdev_id, 10067 cmd->offchan_mode, 10068 cmd->offchan_num, 10069 cmd->offchan_bw_bitmap, 10070 cmd->is_peer_responder, 10071 cmd->offchan_oper_class); 10072 10073 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10074 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10075 WMI_LOGP(FL("failed to send tdls off chan command")); 10076 wmi_buf_free(wmi_buf); 10077 return QDF_STATUS_E_FAILURE; 10078 } 10079 10080 10081 return QDF_STATUS_SUCCESS; 10082 } 10083 10084 /** 10085 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10086 * @wmi_handle: wmi handle 10087 * @pwmaTdlsparams: TDLS params 10088 * 10089 * Return: 0 for success or error code 10090 */ 10091 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10092 void *tdls_param, uint8_t tdls_state) 10093 { 10094 wmi_tdls_set_state_cmd_fixed_param *cmd; 10095 wmi_buf_t wmi_buf; 10096 10097 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10098 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10099 10100 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10101 if (!wmi_buf) { 10102 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10103 return QDF_STATUS_E_FAILURE; 10104 } 10105 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10106 WMITLV_SET_HDR(&cmd->tlv_header, 10107 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10108 WMITLV_GET_STRUCT_TLVLEN 10109 (wmi_tdls_set_state_cmd_fixed_param)); 10110 cmd->vdev_id = wmi_tdls->vdev_id; 10111 cmd->state = tdls_state; 10112 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10113 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10114 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10115 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10116 cmd->rssi_delta = wmi_tdls->rssi_delta; 10117 cmd->tdls_options = wmi_tdls->tdls_options; 10118 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10119 cmd->tdls_peer_traffic_response_timeout_ms = 10120 wmi_tdls->peer_traffic_response_timeout; 10121 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10122 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10123 cmd->tdls_puapsd_rx_frame_threshold = 10124 wmi_tdls->puapsd_rx_frame_threshold; 10125 cmd->teardown_notification_ms = 10126 wmi_tdls->teardown_notification_ms; 10127 cmd->tdls_peer_kickout_threshold = 10128 wmi_tdls->tdls_peer_kickout_threshold; 10129 10130 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10131 "notification_interval_ms: %d, " 10132 "tx_discovery_threshold: %d, " 10133 "tx_teardown_threshold: %d, " 10134 "rssi_teardown_threshold: %d, " 10135 "rssi_delta: %d, " 10136 "tdls_options: 0x%x, " 10137 "tdls_peer_traffic_ind_window: %d, " 10138 "tdls_peer_traffic_response_timeout: %d, " 10139 "tdls_puapsd_mask: 0x%x, " 10140 "tdls_puapsd_inactivity_time: %d, " 10141 "tdls_puapsd_rx_frame_threshold: %d, " 10142 "teardown_notification_ms: %d, " 10143 "tdls_peer_kickout_threshold: %d", 10144 __func__, tdls_state, cmd->state, 10145 cmd->notification_interval_ms, 10146 cmd->tx_discovery_threshold, 10147 cmd->tx_teardown_threshold, 10148 cmd->rssi_teardown_threshold, 10149 cmd->rssi_delta, 10150 cmd->tdls_options, 10151 cmd->tdls_peer_traffic_ind_window, 10152 cmd->tdls_peer_traffic_response_timeout_ms, 10153 cmd->tdls_puapsd_mask, 10154 cmd->tdls_puapsd_inactivity_time_ms, 10155 cmd->tdls_puapsd_rx_frame_threshold, 10156 cmd->teardown_notification_ms, 10157 cmd->tdls_peer_kickout_threshold); 10158 10159 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10160 WMI_TDLS_SET_STATE_CMDID)) { 10161 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10162 wmi_buf_free(wmi_buf); 10163 return QDF_STATUS_E_FAILURE; 10164 } 10165 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10166 10167 return QDF_STATUS_SUCCESS; 10168 } 10169 10170 /** 10171 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10172 * @wmi_handle: wmi handle 10173 * @peerStateParams: TDLS peer state params 10174 * 10175 * Return: QDF_STATUS_SUCCESS for success or error code 10176 */ 10177 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10178 struct tdls_peer_state_params *peerStateParams, 10179 uint32_t *ch_mhz) 10180 { 10181 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10182 wmi_tdls_peer_capabilities *peer_cap; 10183 wmi_channel *chan_info; 10184 wmi_buf_t wmi_buf; 10185 uint8_t *buf_ptr; 10186 uint32_t i; 10187 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10188 sizeof(wmi_tdls_peer_capabilities); 10189 10190 10191 len += WMI_TLV_HDR_SIZE + 10192 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10193 10194 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10195 if (!wmi_buf) { 10196 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10197 return QDF_STATUS_E_FAILURE; 10198 } 10199 10200 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10201 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10202 WMITLV_SET_HDR(&cmd->tlv_header, 10203 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10204 WMITLV_GET_STRUCT_TLVLEN 10205 (wmi_tdls_peer_update_cmd_fixed_param)); 10206 10207 cmd->vdev_id = peerStateParams->vdevId; 10208 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10209 &cmd->peer_macaddr); 10210 10211 10212 cmd->peer_state = peerStateParams->peerState; 10213 10214 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10215 "peer_macaddr.mac_addr31to0: 0x%x, " 10216 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10217 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10218 cmd->peer_macaddr.mac_addr31to0, 10219 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10220 10221 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10222 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10223 WMITLV_SET_HDR(&peer_cap->tlv_header, 10224 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10225 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10226 10227 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10228 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10229 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10230 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10231 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10232 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10233 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10234 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10235 10236 /* Ack and More Data Ack are sent as 0, so no need to set 10237 * but fill SP 10238 */ 10239 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10240 peerStateParams->peerCap.peerMaxSp); 10241 10242 peer_cap->buff_sta_support = 10243 peerStateParams->peerCap.peerBuffStaSupport; 10244 peer_cap->off_chan_support = 10245 peerStateParams->peerCap.peerOffChanSupport; 10246 peer_cap->peer_curr_operclass = 10247 peerStateParams->peerCap.peerCurrOperClass; 10248 /* self curr operclass is not being used and so pass op class for 10249 * preferred off chan in it. 10250 */ 10251 peer_cap->self_curr_operclass = 10252 peerStateParams->peerCap.opClassForPrefOffChan; 10253 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10254 peer_cap->peer_operclass_len = 10255 peerStateParams->peerCap.peerOperClassLen; 10256 10257 WMI_LOGD("%s: peer_operclass_len: %d", 10258 __func__, peer_cap->peer_operclass_len); 10259 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10260 peer_cap->peer_operclass[i] = 10261 peerStateParams->peerCap.peerOperClass[i]; 10262 WMI_LOGD("%s: peer_operclass[%d]: %d", 10263 __func__, i, peer_cap->peer_operclass[i]); 10264 } 10265 10266 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10267 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10268 peer_cap->pref_offchan_bw = 10269 peerStateParams->peerCap.prefOffChanBandwidth; 10270 10271 WMI_LOGD 10272 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10273 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10274 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10275 " %d, pref_offchan_bw: %d", 10276 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10277 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10278 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10279 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10280 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10281 10282 /* next fill variable size array of peer chan info */ 10283 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10284 WMITLV_SET_HDR(buf_ptr, 10285 WMITLV_TAG_ARRAY_STRUC, 10286 sizeof(wmi_channel) * 10287 peerStateParams->peerCap.peerChanLen); 10288 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10289 10290 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10291 WMITLV_SET_HDR(&chan_info->tlv_header, 10292 WMITLV_TAG_STRUC_wmi_channel, 10293 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10294 chan_info->mhz = ch_mhz[i]; 10295 chan_info->band_center_freq1 = chan_info->mhz; 10296 chan_info->band_center_freq2 = 0; 10297 10298 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10299 10300 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10301 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10302 WMI_LOGI("chan[%d] DFS[%d]\n", 10303 peerStateParams->peerCap.peerChan[i].chanId, 10304 peerStateParams->peerCap.peerChan[i].dfsSet); 10305 } 10306 10307 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10308 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10309 else 10310 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10311 10312 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10313 peerStateParams->peerCap. 10314 peerChan[i].pwr); 10315 10316 WMI_SET_CHANNEL_REG_POWER(chan_info, 10317 peerStateParams->peerCap.peerChan[i]. 10318 pwr); 10319 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10320 peerStateParams->peerCap.peerChan[i].pwr); 10321 10322 chan_info++; 10323 } 10324 10325 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10326 WMI_TDLS_PEER_UPDATE_CMDID)) { 10327 WMI_LOGE("%s: failed to send tdls peer update state command", 10328 __func__); 10329 wmi_buf_free(wmi_buf); 10330 return QDF_STATUS_E_FAILURE; 10331 } 10332 10333 10334 return QDF_STATUS_SUCCESS; 10335 } 10336 10337 /* 10338 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 10339 * @wmi_handle: Pointer to WMi handle 10340 * @ie_data: Pointer for ie data 10341 * 10342 * This function sends IE information to firmware 10343 * 10344 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10345 * 10346 */ 10347 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 10348 struct vdev_ie_info_param *ie_info) 10349 { 10350 wmi_vdev_set_ie_cmd_fixed_param *cmd; 10351 wmi_buf_t buf; 10352 uint8_t *buf_ptr; 10353 uint32_t len, ie_len_aligned; 10354 QDF_STATUS ret; 10355 10356 10357 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 10358 /* Allocate memory for the WMI command */ 10359 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 10360 10361 buf = wmi_buf_alloc(wmi_handle, len); 10362 if (!buf) { 10363 WMI_LOGE(FL("wmi_buf_alloc failed")); 10364 return QDF_STATUS_E_NOMEM; 10365 } 10366 10367 buf_ptr = wmi_buf_data(buf); 10368 qdf_mem_zero(buf_ptr, len); 10369 10370 /* Populate the WMI command */ 10371 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 10372 10373 WMITLV_SET_HDR(&cmd->tlv_header, 10374 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 10375 WMITLV_GET_STRUCT_TLVLEN( 10376 wmi_vdev_set_ie_cmd_fixed_param)); 10377 cmd->vdev_id = ie_info->vdev_id; 10378 cmd->ie_id = ie_info->ie_id; 10379 cmd->ie_len = ie_info->length; 10380 cmd->band = ie_info->band; 10381 10382 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 10383 ie_info->length, ie_info->vdev_id); 10384 10385 buf_ptr += sizeof(*cmd); 10386 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 10387 buf_ptr += WMI_TLV_HDR_SIZE; 10388 10389 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 10390 10391 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10392 WMI_VDEV_SET_IE_CMDID); 10393 if (QDF_IS_STATUS_ERROR(ret)) { 10394 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 10395 wmi_buf_free(buf); 10396 } 10397 10398 return ret; 10399 } 10400 10401 /** 10402 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 10403 * 10404 * @param wmi_handle : handle to WMI. 10405 * @param param : pointer to antenna param 10406 * 10407 * This function sends smart antenna enable command to FW 10408 * 10409 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10410 */ 10411 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 10412 struct smart_ant_enable_params *param) 10413 { 10414 /* Send WMI COMMAND to Enable */ 10415 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 10416 wmi_pdev_smart_ant_gpio_handle *gpio_param; 10417 wmi_buf_t buf; 10418 uint8_t *buf_ptr; 10419 int len = 0; 10420 QDF_STATUS ret; 10421 int loop = 0; 10422 10423 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10424 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 10425 buf = wmi_buf_alloc(wmi_handle, len); 10426 10427 if (!buf) { 10428 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10429 return QDF_STATUS_E_NOMEM; 10430 } 10431 10432 buf_ptr = wmi_buf_data(buf); 10433 qdf_mem_zero(buf_ptr, len); 10434 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 10435 10436 WMITLV_SET_HDR(&cmd->tlv_header, 10437 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 10438 WMITLV_GET_STRUCT_TLVLEN( 10439 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 10440 10441 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10442 param->pdev_id); 10443 cmd->enable = param->enable; 10444 cmd->mode = param->mode; 10445 cmd->rx_antenna = param->rx_antenna; 10446 cmd->tx_default_antenna = param->rx_antenna; 10447 10448 /* TLV indicating array of structures to follow */ 10449 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 10450 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10451 WMI_HAL_MAX_SANTENNA * 10452 sizeof(wmi_pdev_smart_ant_gpio_handle)); 10453 10454 buf_ptr += WMI_TLV_HDR_SIZE; 10455 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 10456 10457 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 10458 WMITLV_SET_HDR(&gpio_param->tlv_header, 10459 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 10460 WMITLV_GET_STRUCT_TLVLEN( 10461 wmi_pdev_smart_ant_gpio_handle)); 10462 if (param->mode == SMART_ANT_MODE_SERIAL) { 10463 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 10464 gpio_param->gpio_pin = param->gpio_pin[loop]; 10465 gpio_param->gpio_func = param->gpio_func[loop]; 10466 } else { 10467 gpio_param->gpio_pin = 0; 10468 gpio_param->gpio_func = 0; 10469 } 10470 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 10471 gpio_param->gpio_pin = param->gpio_pin[loop]; 10472 gpio_param->gpio_func = param->gpio_func[loop]; 10473 } 10474 /* Setting it to 0 for now */ 10475 gpio_param->pdev_id = 10476 wmi_handle->ops->convert_pdev_id_host_to_target( 10477 param->pdev_id); 10478 gpio_param++; 10479 } 10480 10481 ret = wmi_unified_cmd_send(wmi_handle, 10482 buf, 10483 len, 10484 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 10485 10486 if (ret != 0) { 10487 WMI_LOGE(" %s :WMI Failed\n", __func__); 10488 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 10489 cmd->enable, 10490 cmd->mode, 10491 cmd->rx_antenna, 10492 param->gpio_pin[0], param->gpio_pin[1], 10493 param->gpio_pin[2], param->gpio_pin[3], 10494 param->gpio_func[0], param->gpio_func[1], 10495 param->gpio_func[2], param->gpio_func[3], 10496 ret); 10497 wmi_buf_free(buf); 10498 } 10499 10500 return ret; 10501 } 10502 10503 /** 10504 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 10505 * 10506 * @param wmi_handle : handle to WMI. 10507 * @param param : pointer to rx antenna param 10508 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10509 */ 10510 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 10511 struct smart_ant_rx_ant_params *param) 10512 { 10513 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 10514 wmi_buf_t buf; 10515 uint8_t *buf_ptr; 10516 uint32_t len; 10517 QDF_STATUS ret; 10518 10519 len = sizeof(*cmd); 10520 buf = wmi_buf_alloc(wmi_handle, len); 10521 WMI_LOGD("%s:\n", __func__); 10522 if (!buf) { 10523 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10524 return QDF_STATUS_E_NOMEM; 10525 } 10526 10527 buf_ptr = wmi_buf_data(buf); 10528 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 10529 WMITLV_SET_HDR(&cmd->tlv_header, 10530 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 10531 WMITLV_GET_STRUCT_TLVLEN( 10532 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 10533 cmd->rx_antenna = param->antenna; 10534 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10535 param->pdev_id); 10536 10537 ret = wmi_unified_cmd_send(wmi_handle, 10538 buf, 10539 len, 10540 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 10541 10542 if (ret != 0) { 10543 WMI_LOGE(" %s :WMI Failed\n", __func__); 10544 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 10545 __func__, 10546 cmd->rx_antenna, 10547 ret); 10548 wmi_buf_free(buf); 10549 } 10550 10551 return ret; 10552 } 10553 10554 /** 10555 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 10556 * @wmi_handle: wmi handle 10557 * @param: pointer to hold ctl table param 10558 * 10559 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10560 */ 10561 static QDF_STATUS 10562 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 10563 struct ctl_table_params *param) 10564 { 10565 uint16_t len, ctl_tlv_len; 10566 uint8_t *buf_ptr; 10567 wmi_buf_t buf; 10568 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 10569 uint32_t *ctl_array; 10570 10571 if (!param->ctl_array) 10572 return QDF_STATUS_E_FAILURE; 10573 10574 ctl_tlv_len = WMI_TLV_HDR_SIZE + 10575 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 10576 len = sizeof(*cmd) + ctl_tlv_len; 10577 10578 buf = wmi_buf_alloc(wmi_handle, len); 10579 if (!buf) { 10580 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10581 return QDF_STATUS_E_FAILURE; 10582 } 10583 10584 buf_ptr = wmi_buf_data(buf); 10585 qdf_mem_zero(buf_ptr, len); 10586 10587 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 10588 10589 WMITLV_SET_HDR(&cmd->tlv_header, 10590 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 10591 WMITLV_GET_STRUCT_TLVLEN( 10592 wmi_pdev_set_ctl_table_cmd_fixed_param)); 10593 cmd->ctl_len = param->ctl_cmd_len; 10594 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10595 param->pdev_id); 10596 10597 buf_ptr += sizeof(*cmd); 10598 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10599 (cmd->ctl_len)); 10600 buf_ptr += WMI_TLV_HDR_SIZE; 10601 ctl_array = (uint32_t *)buf_ptr; 10602 10603 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 10604 sizeof(param->ctl_band)); 10605 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 10606 param->ctl_cmd_len - 10607 sizeof(param->ctl_band)); 10608 10609 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10610 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 10611 WMI_LOGE("%s:Failed to send command\n", __func__); 10612 wmi_buf_free(buf); 10613 return QDF_STATUS_E_FAILURE; 10614 } 10615 10616 return QDF_STATUS_SUCCESS; 10617 } 10618 10619 /** 10620 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 10621 * @wmi_handle: wmi handle 10622 * @param: pointer to hold mimogain table param 10623 * 10624 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10625 */ 10626 static QDF_STATUS 10627 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 10628 struct mimogain_table_params *param) 10629 { 10630 uint16_t len, table_tlv_len; 10631 wmi_buf_t buf; 10632 uint8_t *buf_ptr; 10633 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 10634 uint32_t *gain_table; 10635 10636 if (!param->array_gain) 10637 return QDF_STATUS_E_FAILURE; 10638 10639 /* len must be multiple of a single array gain table */ 10640 if (param->tbl_len % 10641 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 10642 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 10643 WMI_LOGE("Array gain table len not correct\n"); 10644 return QDF_STATUS_E_FAILURE; 10645 } 10646 10647 table_tlv_len = WMI_TLV_HDR_SIZE + 10648 roundup(param->tbl_len, sizeof(uint32_t)); 10649 len = sizeof(*cmd) + table_tlv_len; 10650 10651 buf = wmi_buf_alloc(wmi_handle, len); 10652 if (!buf) { 10653 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10654 return QDF_STATUS_E_FAILURE; 10655 } 10656 10657 buf_ptr = wmi_buf_data(buf); 10658 qdf_mem_zero(buf_ptr, len); 10659 10660 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 10661 10662 WMITLV_SET_HDR(&cmd->tlv_header, 10663 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 10664 WMITLV_GET_STRUCT_TLVLEN( 10665 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 10666 10667 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10668 param->pdev_id); 10669 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 10670 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 10671 param->multichain_gain_bypass); 10672 10673 buf_ptr += sizeof(*cmd); 10674 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10675 (param->tbl_len)); 10676 buf_ptr += WMI_TLV_HDR_SIZE; 10677 gain_table = (uint32_t *)buf_ptr; 10678 10679 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 10680 param->array_gain, 10681 param->tbl_len); 10682 10683 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10684 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 10685 return QDF_STATUS_E_FAILURE; 10686 } 10687 10688 return QDF_STATUS_SUCCESS; 10689 } 10690 10691 /** 10692 * enum packet_power_tlv_flags: target defined 10693 * packet power rate flags for TLV 10694 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 10695 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 10696 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 10697 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 10698 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 10699 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 10700 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 10701 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 10702 * @WMI_TLV_FLAG_STBC: STBC is set 10703 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 10704 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 10705 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 10706 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 10707 * @WMI_TLV_FLAG_RTSENA: RTS enabled 10708 * @WMI_TLV_FLAG_CTSENA: CTS enabled 10709 * @WMI_TLV_FLAG_LDPC: LDPC is set 10710 * @WMI_TLV_FLAG_SGI: Short gaurd interval 10711 * @WMI_TLV_FLAG_SU: SU Data 10712 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 10713 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 10714 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 10715 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 10716 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 10717 * 10718 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 10719 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 10720 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 10721 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 10722 */ 10723 enum packet_power_tlv_flags { 10724 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 10725 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 10726 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 10727 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 10728 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 10729 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 10730 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 10731 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 10732 WMI_TLV_FLAG_STBC = 0x00000100, 10733 WMI_TLV_FLAG_40MHZ = 0x00000200, 10734 WMI_TLV_FLAG_80MHZ = 0x00000300, 10735 WMI_TLV_FLAG_160MHZ = 0x00000400, 10736 WMI_TLV_FLAG_TXBF = 0x00000800, 10737 WMI_TLV_FLAG_RTSENA = 0x00001000, 10738 WMI_TLV_FLAG_CTSENA = 0x00002000, 10739 WMI_TLV_FLAG_LDPC = 0x00004000, 10740 WMI_TLV_FLAG_SGI = 0x00008000, 10741 WMI_TLV_FLAG_SU = 0x00100000, 10742 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 10743 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 10744 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 10745 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 10746 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 10747 10748 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 10749 WMI_TLV_FLAG_BW_MASK = 0x3, 10750 WMI_TLV_FLAG_BW_SHIFT = 9, 10751 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 10752 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 10753 }; 10754 10755 /** 10756 * convert_to_power_info_rate_flags() - convert packet_power_info_params 10757 * to FW understandable format 10758 * @param: pointer to hold packet power info param 10759 * 10760 * @return FW understandable 32 bit rate flags 10761 */ 10762 static uint32_t 10763 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 10764 { 10765 uint32_t rateflags = 0; 10766 10767 if (param->chainmask) 10768 rateflags |= 10769 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 10770 if (param->chan_width) 10771 rateflags |= 10772 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 10773 << WMI_TLV_FLAG_BW_SHIFT); 10774 if (param->su_mu_ofdma) 10775 rateflags |= 10776 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 10777 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 10778 if (param->rate_flags & WMI_HOST_FLAG_STBC) 10779 rateflags |= WMI_TLV_FLAG_STBC; 10780 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 10781 rateflags |= WMI_TLV_FLAG_LDPC; 10782 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 10783 rateflags |= WMI_TLV_FLAG_TXBF; 10784 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 10785 rateflags |= WMI_TLV_FLAG_RTSENA; 10786 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 10787 rateflags |= WMI_TLV_FLAG_CTSENA; 10788 if (param->rate_flags & WMI_HOST_FLAG_SGI) 10789 rateflags |= WMI_TLV_FLAG_SGI; 10790 10791 return rateflags; 10792 } 10793 10794 /** 10795 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 10796 * info to fw 10797 * @wmi_handle: wmi handle 10798 * @param: pointer to hold packet power info param 10799 * 10800 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10801 */ 10802 static QDF_STATUS 10803 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 10804 struct packet_power_info_params *param) 10805 { 10806 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 10807 wmi_buf_t wmibuf; 10808 uint8_t *buf_ptr; 10809 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 10810 10811 wmibuf = wmi_buf_alloc(wmi_handle, len); 10812 if (wmibuf == NULL) 10813 return QDF_STATUS_E_NOMEM; 10814 10815 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 10816 10817 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 10818 WMITLV_SET_HDR(&cmd->tlv_header, 10819 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 10820 WMITLV_GET_STRUCT_TLVLEN( 10821 wmi_pdev_get_tpc_cmd_fixed_param)); 10822 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10823 param->pdev_id); 10824 cmd->rate_flags = convert_to_power_info_rate_flags(param); 10825 cmd->nss = param->nss; 10826 cmd->preamble = param->preamble; 10827 cmd->hw_rate = param->hw_rate; 10828 10829 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 10830 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 10831 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 10832 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 10833 10834 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 10835 WMI_PDEV_GET_TPC_CMDID)) { 10836 WMI_LOGE(FL("Failed to get tpc command\n")); 10837 wmi_buf_free(wmibuf); 10838 return QDF_STATUS_E_FAILURE; 10839 } 10840 10841 return QDF_STATUS_SUCCESS; 10842 } 10843 10844 /** 10845 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 10846 * @wmi_handle: wmi handle 10847 * @param: pointer to hold config ratemask params 10848 * 10849 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10850 */ 10851 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 10852 struct config_ratemask_params *param) 10853 { 10854 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 10855 wmi_buf_t buf; 10856 int32_t len = sizeof(*cmd); 10857 10858 buf = wmi_buf_alloc(wmi_handle, len); 10859 if (!buf) { 10860 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10861 return QDF_STATUS_E_FAILURE; 10862 } 10863 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 10864 WMITLV_SET_HDR(&cmd->tlv_header, 10865 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 10866 WMITLV_GET_STRUCT_TLVLEN( 10867 wmi_vdev_config_ratemask_cmd_fixed_param)); 10868 cmd->vdev_id = param->vdev_id; 10869 cmd->type = param->type; 10870 cmd->mask_lower32 = param->lower32; 10871 cmd->mask_higher32 = param->higher32; 10872 cmd->mask_lower32_2 = param->lower32_2; 10873 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X" 10874 "mask_l32 = 0x%X mask_h32 = 0x%X mask_l32_2 = 0x%X\n", 10875 param->vdev_id, param->type, param->lower32, 10876 param->higher32, param->lower32_2); 10877 10878 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10879 WMI_VDEV_RATEMASK_CMDID)) { 10880 WMI_LOGE("Seting vdev ratemask failed\n"); 10881 wmi_buf_free(buf); 10882 return QDF_STATUS_E_FAILURE; 10883 } 10884 10885 return QDF_STATUS_SUCCESS; 10886 } 10887 10888 /** 10889 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 10890 * @param: param sent from the host side 10891 * @cmd: param to be sent to the fw side 10892 */ 10893 static inline void copy_custom_aggr_bitmap( 10894 struct set_custom_aggr_size_params *param, 10895 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 10896 { 10897 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 10898 param->ac); 10899 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 10900 param->aggr_type); 10901 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10902 param->tx_aggr_size_disable); 10903 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 10904 param->rx_aggr_size_disable); 10905 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 10906 param->tx_ac_enable); 10907 } 10908 10909 /** 10910 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 10911 * @wmi_handle: wmi handle 10912 * @param: pointer to hold custom aggr size params 10913 * 10914 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10915 */ 10916 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 10917 wmi_unified_t wmi_handle, 10918 struct set_custom_aggr_size_params *param) 10919 { 10920 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 10921 wmi_buf_t buf; 10922 int32_t len = sizeof(*cmd); 10923 10924 buf = wmi_buf_alloc(wmi_handle, len); 10925 if (!buf) { 10926 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10927 return QDF_STATUS_E_FAILURE; 10928 } 10929 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 10930 wmi_buf_data(buf); 10931 WMITLV_SET_HDR(&cmd->tlv_header, 10932 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 10933 WMITLV_GET_STRUCT_TLVLEN( 10934 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 10935 cmd->vdev_id = param->vdev_id; 10936 cmd->tx_aggr_size = param->tx_aggr_size; 10937 cmd->rx_aggr_size = param->rx_aggr_size; 10938 copy_custom_aggr_bitmap(param, cmd); 10939 10940 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 10941 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 10942 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 10943 "tx_ac_enable=0x%X\n", 10944 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 10945 param->ac, param->aggr_type, param->tx_aggr_size_disable, 10946 param->rx_aggr_size_disable, param->tx_ac_enable); 10947 10948 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10949 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 10950 WMI_LOGE("Seting custom aggregation size failed\n"); 10951 wmi_buf_free(buf); 10952 return QDF_STATUS_E_FAILURE; 10953 } 10954 10955 return QDF_STATUS_SUCCESS; 10956 } 10957 10958 /** 10959 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 10960 * @param wmi_handle : handle to WMI. 10961 * @param param : pointer to tx antenna param 10962 * 10963 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10964 */ 10965 10966 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 10967 struct set_qdepth_thresh_params *param) 10968 { 10969 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 10970 wmi_msduq_qdepth_thresh_update *cmd_update; 10971 wmi_buf_t buf; 10972 int32_t len = 0; 10973 int i; 10974 uint8_t *buf_ptr; 10975 QDF_STATUS ret; 10976 10977 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 10978 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 10979 return QDF_STATUS_E_INVAL; 10980 } 10981 10982 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10983 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 10984 param->num_of_msduq_updates); 10985 buf = wmi_buf_alloc(wmi_handle, len); 10986 10987 if (!buf) { 10988 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10989 return QDF_STATUS_E_NOMEM; 10990 } 10991 10992 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10993 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 10994 buf_ptr; 10995 10996 WMITLV_SET_HDR(&cmd->tlv_header, 10997 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 10998 , WMITLV_GET_STRUCT_TLVLEN( 10999 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 11000 11001 cmd->pdev_id = 11002 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11003 cmd->vdev_id = param->vdev_id; 11004 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 11005 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 11006 11007 buf_ptr += sizeof( 11008 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 11009 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11010 param->num_of_msduq_updates * 11011 sizeof(wmi_msduq_qdepth_thresh_update)); 11012 buf_ptr += WMI_TLV_HDR_SIZE; 11013 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 11014 11015 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 11016 WMITLV_SET_HDR(&cmd_update->tlv_header, 11017 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 11018 WMITLV_GET_STRUCT_TLVLEN( 11019 wmi_msduq_qdepth_thresh_update)); 11020 cmd_update->tid_num = param->update_params[i].tid_num; 11021 cmd_update->msduq_update_mask = 11022 param->update_params[i].msduq_update_mask; 11023 cmd_update->qdepth_thresh_value = 11024 param->update_params[i].qdepth_thresh_value; 11025 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 11026 "mac_addr_upper4=%X, mac_addr_lower2:%X," 11027 " update mask=0x%X thresh val=0x%X\n", 11028 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 11029 cmd->peer_mac_address.mac_addr31to0, 11030 cmd->peer_mac_address.mac_addr47to32, 11031 cmd_update->msduq_update_mask, 11032 cmd_update->qdepth_thresh_value); 11033 cmd_update++; 11034 } 11035 11036 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11037 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 11038 11039 if (ret != 0) { 11040 WMI_LOGE(" %s :WMI Failed\n", __func__); 11041 wmi_buf_free(buf); 11042 } 11043 11044 return ret; 11045 } 11046 11047 /** 11048 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11049 * @wmi_handle: wmi handle 11050 * @param: pointer to hold vap dscp tid map param 11051 * 11052 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11053 */ 11054 static QDF_STATUS 11055 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11056 struct vap_dscp_tid_map_params *param) 11057 { 11058 wmi_buf_t buf; 11059 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11060 int32_t len = sizeof(*cmd); 11061 11062 buf = wmi_buf_alloc(wmi_handle, len); 11063 if (!buf) { 11064 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11065 return QDF_STATUS_E_FAILURE; 11066 } 11067 11068 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11069 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11070 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 11071 11072 cmd->vdev_id = param->vdev_id; 11073 cmd->enable_override = 0; 11074 11075 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11076 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11077 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11078 WMI_LOGE("Failed to set dscp cmd\n"); 11079 wmi_buf_free(buf); 11080 return QDF_STATUS_E_FAILURE; 11081 } 11082 11083 return QDF_STATUS_SUCCESS; 11084 } 11085 11086 /** 11087 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11088 * @wmi_handle: wmi handle 11089 * @macaddr: vdev mac address 11090 * @param: pointer to hold neigbour rx param 11091 * 11092 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11093 */ 11094 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11095 uint8_t macaddr[IEEE80211_ADDR_LEN], 11096 struct set_neighbour_rx_params *param) 11097 { 11098 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11099 wmi_buf_t buf; 11100 int32_t len = sizeof(*cmd); 11101 11102 buf = wmi_buf_alloc(wmi_handle, len); 11103 if (!buf) { 11104 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11105 return QDF_STATUS_E_FAILURE; 11106 } 11107 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11108 WMITLV_SET_HDR(&cmd->tlv_header, 11109 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11110 WMITLV_GET_STRUCT_TLVLEN( 11111 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11112 cmd->vdev_id = param->vdev_id; 11113 cmd->bssid_idx = param->idx; 11114 cmd->action = param->action; 11115 cmd->type = param->type; 11116 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11117 cmd->flag = 0; 11118 11119 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11120 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11121 WMI_LOGE("Failed to set neighbour rx param\n"); 11122 wmi_buf_free(buf); 11123 return QDF_STATUS_E_FAILURE; 11124 } 11125 11126 return QDF_STATUS_SUCCESS; 11127 } 11128 11129 /** 11130 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11131 * @param wmi_handle : handle to WMI. 11132 * @param macaddr : vdev mac address 11133 * @param param : pointer to tx antenna param 11134 * 11135 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11136 */ 11137 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11138 uint8_t macaddr[IEEE80211_ADDR_LEN], 11139 struct smart_ant_tx_ant_params *param) 11140 { 11141 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11142 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11143 wmi_buf_t buf; 11144 int32_t len = 0; 11145 int i; 11146 uint8_t *buf_ptr; 11147 QDF_STATUS ret; 11148 11149 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11150 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11151 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11152 buf = wmi_buf_alloc(wmi_handle, len); 11153 11154 if (!buf) { 11155 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11156 return QDF_STATUS_E_NOMEM; 11157 } 11158 11159 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11160 qdf_mem_zero(buf_ptr, len); 11161 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11162 11163 WMITLV_SET_HDR(&cmd->tlv_header, 11164 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11165 WMITLV_GET_STRUCT_TLVLEN( 11166 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11167 11168 cmd->vdev_id = param->vdev_id; 11169 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11170 11171 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11172 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11173 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11174 buf_ptr += WMI_TLV_HDR_SIZE; 11175 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11176 11177 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11178 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11179 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11180 WMITLV_GET_STRUCT_TLVLEN( 11181 wmi_peer_smart_ant_set_tx_antenna_series)); 11182 ant_tx_series->antenna_series = param->antenna_array[i]; 11183 ant_tx_series++; 11184 } 11185 11186 ret = wmi_unified_cmd_send(wmi_handle, 11187 buf, 11188 len, 11189 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11190 11191 if (ret != 0) { 11192 WMI_LOGE(" %s :WMI Failed\n", __func__); 11193 wmi_buf_free(buf); 11194 } 11195 11196 return ret; 11197 } 11198 11199 /** 11200 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11201 * @wmi_handle: wmi handle 11202 * @param: pointer to hold ant switch tbl param 11203 * 11204 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11205 */ 11206 static QDF_STATUS 11207 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11208 struct ant_switch_tbl_params *param) 11209 { 11210 uint8_t len; 11211 wmi_buf_t buf; 11212 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11213 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11214 uint8_t *buf_ptr; 11215 11216 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11217 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11218 buf = wmi_buf_alloc(wmi_handle, len); 11219 11220 if (!buf) { 11221 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11222 return QDF_STATUS_E_NOMEM; 11223 } 11224 11225 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11226 qdf_mem_zero(buf_ptr, len); 11227 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11228 11229 WMITLV_SET_HDR(&cmd->tlv_header, 11230 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11231 WMITLV_GET_STRUCT_TLVLEN( 11232 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11233 11234 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11235 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11236 cmd->mac_id = 11237 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11238 11239 /* TLV indicating array of structures to follow */ 11240 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11241 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11242 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11243 buf_ptr += WMI_TLV_HDR_SIZE; 11244 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11245 11246 ctrl_chain->pdev_id = 11247 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11248 ctrl_chain->antCtrlChain = param->antCtrlChain; 11249 11250 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11251 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11252 wmi_buf_free(buf); 11253 return QDF_STATUS_E_FAILURE; 11254 } 11255 11256 return QDF_STATUS_SUCCESS; 11257 } 11258 11259 /** 11260 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11261 * training information function 11262 * @param wmi_handle : handle to WMI. 11263 * @macaddr : vdev mac address 11264 * @param param : pointer to tx antenna param 11265 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11266 */ 11267 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11268 wmi_unified_t wmi_handle, 11269 uint8_t macaddr[IEEE80211_ADDR_LEN], 11270 struct smart_ant_training_info_params *param) 11271 { 11272 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11273 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11274 wmi_buf_t buf; 11275 uint8_t *buf_ptr; 11276 int32_t len = 0; 11277 QDF_STATUS ret; 11278 int loop; 11279 11280 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11281 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11282 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11283 buf = wmi_buf_alloc(wmi_handle, len); 11284 11285 if (!buf) { 11286 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11287 return QDF_STATUS_E_NOMEM; 11288 } 11289 11290 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11291 qdf_mem_zero(buf_ptr, len); 11292 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11293 11294 WMITLV_SET_HDR(&cmd->tlv_header, 11295 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11296 WMITLV_GET_STRUCT_TLVLEN( 11297 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11298 11299 cmd->vdev_id = param->vdev_id; 11300 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11301 cmd->num_pkts = param->numpkts; 11302 11303 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11304 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11305 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11306 WMI_SMART_ANT_MAX_RATE_SERIES); 11307 11308 buf_ptr += WMI_TLV_HDR_SIZE; 11309 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11310 11311 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11312 WMITLV_SET_HDR(&train_param->tlv_header, 11313 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11314 WMITLV_GET_STRUCT_TLVLEN( 11315 wmi_peer_smart_ant_set_train_antenna_param)); 11316 train_param->train_rate_series = param->rate_array[loop]; 11317 train_param->train_antenna_series = param->antenna_array[loop]; 11318 train_param->rc_flags = 0; 11319 WMI_LOGI(FL("Series number:%d\n"), loop); 11320 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11321 train_param->train_rate_series, 11322 train_param->train_antenna_series); 11323 train_param++; 11324 } 11325 11326 ret = wmi_unified_cmd_send(wmi_handle, 11327 buf, 11328 len, 11329 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 11330 11331 if (ret != 0) { 11332 WMI_LOGE(" %s :WMI Failed\n", __func__); 11333 wmi_buf_free(buf); 11334 return QDF_STATUS_E_FAILURE; 11335 } 11336 11337 return ret; 11338 } 11339 11340 /** 11341 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 11342 * configuration function 11343 * @param wmi_handle : handle to WMI. 11344 * @macaddr : vdev mad address 11345 * @param param : pointer to tx antenna param 11346 * 11347 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11348 */ 11349 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 11350 wmi_unified_t wmi_handle, 11351 uint8_t macaddr[IEEE80211_ADDR_LEN], 11352 struct smart_ant_node_config_params *param) 11353 { 11354 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 11355 wmi_buf_t buf; 11356 uint8_t *buf_ptr; 11357 int32_t len = 0, args_tlv_len; 11358 int ret; 11359 int i = 0; 11360 uint32_t *node_config_args; 11361 11362 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 11363 len = sizeof(*cmd) + args_tlv_len; 11364 11365 if (param->args_count == 0) { 11366 WMI_LOGE("%s: Can't send a command with %d arguments\n", 11367 __func__, param->args_count); 11368 return QDF_STATUS_E_FAILURE; 11369 } 11370 11371 buf = wmi_buf_alloc(wmi_handle, len); 11372 if (!buf) { 11373 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11374 return QDF_STATUS_E_NOMEM; 11375 } 11376 11377 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 11378 wmi_buf_data(buf); 11379 buf_ptr = (uint8_t *)cmd; 11380 WMITLV_SET_HDR(&cmd->tlv_header, 11381 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 11382 WMITLV_GET_STRUCT_TLVLEN( 11383 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 11384 cmd->vdev_id = param->vdev_id; 11385 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11386 cmd->cmd_id = param->cmd_id; 11387 cmd->args_count = param->args_count; 11388 buf_ptr += sizeof( 11389 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 11390 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11391 (cmd->args_count * sizeof(uint32_t))); 11392 buf_ptr += WMI_TLV_HDR_SIZE; 11393 node_config_args = (uint32_t *)buf_ptr; 11394 11395 for (i = 0; i < param->args_count; i++) { 11396 node_config_args[i] = param->args_arr[i]; 11397 WMI_LOGI("%d", param->args_arr[i]); 11398 } 11399 11400 ret = wmi_unified_cmd_send(wmi_handle, 11401 buf, 11402 len, 11403 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 11404 11405 if (ret != 0) { 11406 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 11407 __func__, param->cmd_id, macaddr[0], 11408 macaddr[1], macaddr[2], macaddr[3], 11409 macaddr[4], macaddr[5], ret); 11410 wmi_buf_free(buf); 11411 } 11412 11413 return ret; 11414 } 11415 11416 #ifdef WLAN_ATF_ENABLE 11417 /** 11418 * send_set_atf_cmd_tlv() - send set atf command to fw 11419 * @wmi_handle: wmi handle 11420 * @param: pointer to set atf param 11421 * 11422 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11423 */ 11424 static QDF_STATUS 11425 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 11426 struct set_atf_params *param) 11427 { 11428 wmi_atf_peer_info *peer_info; 11429 wmi_peer_atf_request_fixed_param *cmd; 11430 wmi_buf_t buf; 11431 uint8_t *buf_ptr; 11432 int i; 11433 int32_t len = 0; 11434 QDF_STATUS retval; 11435 11436 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11437 len += param->num_peers * sizeof(wmi_atf_peer_info); 11438 buf = wmi_buf_alloc(wmi_handle, len); 11439 if (!buf) { 11440 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11441 return QDF_STATUS_E_FAILURE; 11442 } 11443 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11444 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 11445 WMITLV_SET_HDR(&cmd->tlv_header, 11446 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 11447 WMITLV_GET_STRUCT_TLVLEN( 11448 wmi_peer_atf_request_fixed_param)); 11449 cmd->num_peers = param->num_peers; 11450 11451 buf_ptr += sizeof(*cmd); 11452 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11453 sizeof(wmi_atf_peer_info) * 11454 cmd->num_peers); 11455 buf_ptr += WMI_TLV_HDR_SIZE; 11456 peer_info = (wmi_atf_peer_info *)buf_ptr; 11457 11458 for (i = 0; i < cmd->num_peers; i++) { 11459 WMITLV_SET_HDR(&peer_info->tlv_header, 11460 WMITLV_TAG_STRUC_wmi_atf_peer_info, 11461 WMITLV_GET_STRUCT_TLVLEN( 11462 wmi_atf_peer_info)); 11463 qdf_mem_copy(&(peer_info->peer_macaddr), 11464 &(param->peer_info[i].peer_macaddr), 11465 sizeof(wmi_mac_addr)); 11466 peer_info->atf_units = param->peer_info[i].percentage_peer; 11467 peer_info->vdev_id = param->peer_info[i].vdev_id; 11468 peer_info->pdev_id = 11469 wmi_handle->ops->convert_pdev_id_host_to_target( 11470 param->peer_info[i].pdev_id); 11471 /* 11472 * TLV definition for peer atf request fixed param combines 11473 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 11474 * stats and atf extension stats as two different 11475 * implementations. 11476 * Need to discuss with FW on this. 11477 * 11478 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 11479 * peer_info->atf_units_reserved = 11480 * param->peer_ext_info[i].atf_index_reserved; 11481 */ 11482 peer_info++; 11483 } 11484 11485 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11486 WMI_PEER_ATF_REQUEST_CMDID); 11487 11488 if (retval != QDF_STATUS_SUCCESS) { 11489 WMI_LOGE("%s : WMI Failed\n", __func__); 11490 wmi_buf_free(buf); 11491 } 11492 11493 return retval; 11494 } 11495 #endif 11496 11497 /** 11498 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 11499 * @wmi_handle: wmi handle 11500 * @param: pointer to hold fwtest param 11501 * 11502 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11503 */ 11504 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 11505 struct set_fwtest_params *param) 11506 { 11507 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11508 wmi_buf_t buf; 11509 int32_t len = sizeof(*cmd); 11510 11511 buf = wmi_buf_alloc(wmi_handle, len); 11512 11513 if (!buf) { 11514 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11515 return QDF_STATUS_E_FAILURE; 11516 } 11517 11518 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 11519 WMITLV_SET_HDR(&cmd->tlv_header, 11520 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11521 WMITLV_GET_STRUCT_TLVLEN( 11522 wmi_fwtest_set_param_cmd_fixed_param)); 11523 cmd->param_id = param->arg; 11524 cmd->param_value = param->value; 11525 11526 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 11527 WMI_LOGE("Setting FW test param failed\n"); 11528 wmi_buf_free(buf); 11529 return QDF_STATUS_E_FAILURE; 11530 } 11531 11532 return QDF_STATUS_SUCCESS; 11533 } 11534 11535 /** 11536 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 11537 * @wmi_handle: wmi handle 11538 * @param: pointer to qboost params 11539 * @macaddr: vdev mac address 11540 * 11541 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11542 */ 11543 static QDF_STATUS 11544 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 11545 uint8_t macaddr[IEEE80211_ADDR_LEN], 11546 struct set_qboost_params *param) 11547 { 11548 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 11549 wmi_buf_t buf; 11550 int32_t len; 11551 QDF_STATUS ret; 11552 11553 len = sizeof(*cmd); 11554 11555 buf = wmi_buf_alloc(wmi_handle, len); 11556 if (!buf) { 11557 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11558 return QDF_STATUS_E_FAILURE; 11559 } 11560 11561 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 11562 WMITLV_SET_HDR(&cmd->tlv_header, 11563 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 11564 WMITLV_GET_STRUCT_TLVLEN( 11565 WMI_QBOOST_CFG_CMD_fixed_param)); 11566 cmd->vdev_id = param->vdev_id; 11567 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11568 cmd->qb_enable = param->value; 11569 11570 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11571 WMI_QBOOST_CFG_CMDID); 11572 11573 if (ret != 0) { 11574 WMI_LOGE("Setting qboost cmd failed\n"); 11575 wmi_buf_free(buf); 11576 } 11577 11578 return ret; 11579 } 11580 11581 /** 11582 * send_gpio_config_cmd_tlv() - send gpio config to fw 11583 * @wmi_handle: wmi handle 11584 * @param: pointer to hold gpio config param 11585 * 11586 * Return: 0 for success or error code 11587 */ 11588 static QDF_STATUS 11589 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 11590 struct gpio_config_params *param) 11591 { 11592 wmi_gpio_config_cmd_fixed_param *cmd; 11593 wmi_buf_t buf; 11594 int32_t len; 11595 QDF_STATUS ret; 11596 11597 len = sizeof(*cmd); 11598 11599 /* Sanity Checks */ 11600 if (param->pull_type > WMI_GPIO_PULL_DOWN || 11601 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 11602 return QDF_STATUS_E_FAILURE; 11603 } 11604 11605 buf = wmi_buf_alloc(wmi_handle, len); 11606 if (!buf) { 11607 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11608 return QDF_STATUS_E_FAILURE; 11609 } 11610 11611 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 11612 WMITLV_SET_HDR(&cmd->tlv_header, 11613 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 11614 WMITLV_GET_STRUCT_TLVLEN( 11615 wmi_gpio_config_cmd_fixed_param)); 11616 cmd->gpio_num = param->gpio_num; 11617 cmd->input = param->input; 11618 cmd->pull_type = param->pull_type; 11619 cmd->intr_mode = param->intr_mode; 11620 11621 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11622 WMI_GPIO_CONFIG_CMDID); 11623 11624 if (ret != 0) { 11625 WMI_LOGE("Sending GPIO config cmd failed\n"); 11626 wmi_buf_free(buf); 11627 } 11628 11629 return ret; 11630 } 11631 11632 /** 11633 * send_gpio_output_cmd_tlv() - send gpio output to fw 11634 * @wmi_handle: wmi handle 11635 * @param: pointer to hold gpio output param 11636 * 11637 * Return: 0 for success or error code 11638 */ 11639 static QDF_STATUS 11640 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 11641 struct gpio_output_params *param) 11642 { 11643 wmi_gpio_output_cmd_fixed_param *cmd; 11644 wmi_buf_t buf; 11645 int32_t len; 11646 QDF_STATUS ret; 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_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 11657 WMITLV_SET_HDR(&cmd->tlv_header, 11658 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 11659 WMITLV_GET_STRUCT_TLVLEN( 11660 wmi_gpio_output_cmd_fixed_param)); 11661 cmd->gpio_num = param->gpio_num; 11662 cmd->set = param->set; 11663 11664 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11665 WMI_GPIO_OUTPUT_CMDID); 11666 11667 if (ret != 0) { 11668 WMI_LOGE("Sending GPIO output cmd failed\n"); 11669 wmi_buf_free(buf); 11670 } 11671 11672 return ret; 11673 11674 } 11675 11676 /** 11677 * send_phyerr_disable_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_disable_cmd_tlv(wmi_unified_t wmi_handle) 11683 { 11684 wmi_pdev_dfs_disable_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_disable_cmd_fixed_param *)wmi_buf_data(buf); 11698 WMITLV_SET_HDR(&cmd->tlv_header, 11699 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 11700 WMITLV_GET_STRUCT_TLVLEN( 11701 wmi_pdev_dfs_disable_cmd_fixed_param)); 11702 /* Filling it with WMI_PDEV_ID_SOC for now */ 11703 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11704 WMI_HOST_PDEV_ID_SOC); 11705 11706 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11707 WMI_PDEV_DFS_DISABLE_CMDID); 11708 11709 if (ret != 0) { 11710 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 11711 wmi_buf_free(buf); 11712 } 11713 11714 return ret; 11715 } 11716 11717 /** 11718 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 11719 * 11720 * @param wmi_handle : handle to WMI. 11721 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11722 */ 11723 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 11724 { 11725 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 11726 wmi_buf_t buf; 11727 QDF_STATUS ret; 11728 int32_t len; 11729 11730 len = sizeof(*cmd); 11731 11732 buf = wmi_buf_alloc(wmi_handle, len); 11733 if (!buf) { 11734 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11735 return QDF_STATUS_E_FAILURE; 11736 } 11737 11738 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 11739 WMITLV_SET_HDR(&cmd->tlv_header, 11740 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 11741 WMITLV_GET_STRUCT_TLVLEN( 11742 wmi_pdev_dfs_enable_cmd_fixed_param)); 11743 /* Reserved for future use */ 11744 cmd->reserved0 = 0; 11745 11746 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11747 WMI_PDEV_DFS_ENABLE_CMDID); 11748 11749 if (ret != 0) { 11750 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 11751 wmi_buf_free(buf); 11752 } 11753 11754 return ret; 11755 } 11756 11757 /** 11758 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 11759 * to fw 11760 * @wmi_handle: wmi handle 11761 * @param: pointer to hold periodic chan stats param 11762 * 11763 * Return: 0 for success or error code 11764 */ 11765 static QDF_STATUS 11766 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 11767 struct periodic_chan_stats_params *param) 11768 { 11769 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 11770 wmi_buf_t buf; 11771 QDF_STATUS ret; 11772 int32_t len; 11773 11774 len = sizeof(*cmd); 11775 11776 buf = wmi_buf_alloc(wmi_handle, len); 11777 if (!buf) { 11778 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11779 return QDF_STATUS_E_FAILURE; 11780 } 11781 11782 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 11783 wmi_buf_data(buf); 11784 WMITLV_SET_HDR(&cmd->tlv_header, 11785 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 11786 WMITLV_GET_STRUCT_TLVLEN( 11787 wmi_set_periodic_channel_stats_config_fixed_param)); 11788 cmd->enable = param->enable; 11789 cmd->stats_period = param->stats_period; 11790 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11791 param->pdev_id); 11792 11793 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11794 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 11795 11796 if (ret != 0) { 11797 WMI_LOGE("Sending periodic chan stats config failed"); 11798 wmi_buf_free(buf); 11799 } 11800 11801 return ret; 11802 } 11803 11804 /** 11805 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 11806 * @wmi_handle: wmi handle 11807 * @mac_id: radio context 11808 * 11809 * Return: 0 for success or error code 11810 */ 11811 static QDF_STATUS 11812 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 11813 { 11814 wmi_buf_t buf; 11815 QDF_STATUS ret; 11816 wmi_pdev_get_nfcal_power_fixed_param *cmd; 11817 int32_t len = sizeof(*cmd); 11818 11819 buf = wmi_buf_alloc(wmi_handle, len); 11820 if (buf == NULL) 11821 return QDF_STATUS_E_NOMEM; 11822 11823 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 11824 WMITLV_SET_HDR(&cmd->tlv_header, 11825 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 11826 WMITLV_GET_STRUCT_TLVLEN 11827 (wmi_pdev_get_nfcal_power_fixed_param)); 11828 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 11829 11830 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11831 WMI_PDEV_GET_NFCAL_POWER_CMDID); 11832 if (ret != 0) { 11833 WMI_LOGE("Sending get nfcal power cmd failed\n"); 11834 wmi_buf_free(buf); 11835 } 11836 11837 return ret; 11838 } 11839 11840 /** 11841 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 11842 * @wmi_handle: wmi handle 11843 * @param: pointer to ht ie param 11844 * 11845 * Return: 0 for success or error code 11846 */ 11847 static QDF_STATUS 11848 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11849 struct ht_ie_params *param) 11850 { 11851 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 11852 wmi_buf_t buf; 11853 QDF_STATUS ret; 11854 int32_t len; 11855 uint8_t *buf_ptr; 11856 11857 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11858 roundup(param->ie_len, sizeof(uint32_t)); 11859 11860 buf = wmi_buf_alloc(wmi_handle, len); 11861 if (!buf) { 11862 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11863 return QDF_STATUS_E_FAILURE; 11864 } 11865 11866 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11867 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 11868 WMITLV_SET_HDR(&cmd->tlv_header, 11869 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 11870 WMITLV_GET_STRUCT_TLVLEN( 11871 wmi_pdev_set_ht_ie_cmd_fixed_param)); 11872 cmd->reserved0 = 0; 11873 cmd->ie_len = param->ie_len; 11874 cmd->tx_streams = param->tx_streams; 11875 cmd->rx_streams = param->rx_streams; 11876 11877 buf_ptr += sizeof(*cmd); 11878 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11879 buf_ptr += WMI_TLV_HDR_SIZE; 11880 if (param->ie_len) 11881 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11882 cmd->ie_len); 11883 11884 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11885 WMI_PDEV_SET_HT_CAP_IE_CMDID); 11886 11887 if (ret != 0) { 11888 WMI_LOGE("Sending set ht ie cmd failed\n"); 11889 wmi_buf_free(buf); 11890 } 11891 11892 return ret; 11893 } 11894 11895 /** 11896 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 11897 * @wmi_handle: wmi handle 11898 * @param: pointer to vht ie param 11899 * 11900 * Return: 0 for success or error code 11901 */ 11902 static QDF_STATUS 11903 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11904 struct vht_ie_params *param) 11905 { 11906 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 11907 wmi_buf_t buf; 11908 QDF_STATUS ret; 11909 int32_t len; 11910 uint8_t *buf_ptr; 11911 11912 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11913 roundup(param->ie_len, sizeof(uint32_t)); 11914 11915 buf = wmi_buf_alloc(wmi_handle, len); 11916 if (!buf) { 11917 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11918 return QDF_STATUS_E_FAILURE; 11919 } 11920 11921 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11922 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 11923 WMITLV_SET_HDR(&cmd->tlv_header, 11924 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 11925 WMITLV_GET_STRUCT_TLVLEN( 11926 wmi_pdev_set_vht_ie_cmd_fixed_param)); 11927 cmd->reserved0 = 0; 11928 cmd->ie_len = param->ie_len; 11929 cmd->tx_streams = param->tx_streams; 11930 cmd->rx_streams = param->rx_streams; 11931 11932 buf_ptr += sizeof(*cmd); 11933 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11934 buf_ptr += WMI_TLV_HDR_SIZE; 11935 if (param->ie_len) 11936 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11937 cmd->ie_len); 11938 11939 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11940 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 11941 11942 if (ret != 0) { 11943 WMI_LOGE("Sending set vht ie cmd failed\n"); 11944 wmi_buf_free(buf); 11945 } 11946 11947 return ret; 11948 } 11949 11950 /** 11951 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 11952 * @wmi_handle: wmi handle 11953 * @param: pointer to quiet mode params 11954 * 11955 * Return: 0 for success or error code 11956 */ 11957 static QDF_STATUS 11958 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 11959 struct set_quiet_mode_params *param) 11960 { 11961 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 11962 wmi_buf_t buf; 11963 QDF_STATUS ret; 11964 int32_t len; 11965 11966 len = sizeof(*quiet_cmd); 11967 buf = wmi_buf_alloc(wmi_handle, len); 11968 if (!buf) { 11969 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11970 return QDF_STATUS_E_FAILURE; 11971 } 11972 11973 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11974 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 11975 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 11976 WMITLV_GET_STRUCT_TLVLEN( 11977 wmi_pdev_set_quiet_cmd_fixed_param)); 11978 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11979 quiet_cmd->enabled = param->enabled; 11980 quiet_cmd->period = (param->period)*(param->intval); 11981 quiet_cmd->duration = param->duration; 11982 quiet_cmd->next_start = param->offset; 11983 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11984 WMI_HOST_PDEV_ID_SOC); 11985 11986 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11987 WMI_PDEV_SET_QUIET_MODE_CMDID); 11988 11989 if (ret != 0) { 11990 WMI_LOGE("Sending set quiet cmd failed\n"); 11991 wmi_buf_free(buf); 11992 } 11993 11994 return ret; 11995 } 11996 11997 /** 11998 * send_set_bwf_cmd_tlv() - send set bwf command to fw 11999 * @wmi_handle: wmi handle 12000 * @param: pointer to set bwf param 12001 * 12002 * Return: 0 for success or error code 12003 */ 12004 static QDF_STATUS 12005 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12006 struct set_bwf_params *param) 12007 { 12008 wmi_bwf_peer_info *peer_info; 12009 wmi_peer_bwf_request_fixed_param *cmd; 12010 wmi_buf_t buf; 12011 QDF_STATUS retval; 12012 int32_t len; 12013 uint8_t *buf_ptr; 12014 int i; 12015 12016 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12017 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12018 buf = wmi_buf_alloc(wmi_handle, len); 12019 if (!buf) { 12020 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12021 return QDF_STATUS_E_FAILURE; 12022 } 12023 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12024 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12025 WMITLV_SET_HDR(&cmd->tlv_header, 12026 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12027 WMITLV_GET_STRUCT_TLVLEN( 12028 wmi_peer_bwf_request_fixed_param)); 12029 cmd->num_peers = param->num_peers; 12030 12031 buf_ptr += sizeof(*cmd); 12032 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12033 sizeof(wmi_bwf_peer_info) * 12034 cmd->num_peers); 12035 buf_ptr += WMI_TLV_HDR_SIZE; 12036 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12037 12038 for (i = 0; i < cmd->num_peers; i++) { 12039 WMITLV_SET_HDR(&peer_info->tlv_header, 12040 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12041 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12042 peer_info->bwf_guaranteed_bandwidth = 12043 param->peer_info[i].throughput; 12044 peer_info->bwf_max_airtime = 12045 param->peer_info[i].max_airtime; 12046 peer_info->bwf_peer_priority = 12047 param->peer_info[i].priority; 12048 qdf_mem_copy(&peer_info->peer_macaddr, 12049 ¶m->peer_info[i].peer_macaddr, 12050 sizeof(param->peer_info[i].peer_macaddr)); 12051 peer_info->vdev_id = 12052 param->peer_info[i].vdev_id; 12053 peer_info->pdev_id = 12054 wmi_handle->ops->convert_pdev_id_host_to_target( 12055 param->peer_info[i].pdev_id); 12056 peer_info++; 12057 } 12058 12059 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12060 WMI_PEER_BWF_REQUEST_CMDID); 12061 12062 if (retval != QDF_STATUS_SUCCESS) { 12063 WMI_LOGE("%s : WMI Failed\n", __func__); 12064 wmi_buf_free(buf); 12065 } 12066 12067 return retval; 12068 } 12069 12070 /** 12071 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12072 * @wmi_handle: wmi handle 12073 * @param: pointer to hold mcast update param 12074 * 12075 * Return: 0 for success or error code 12076 */ 12077 static QDF_STATUS 12078 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12079 struct mcast_group_update_params *param) 12080 { 12081 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12082 wmi_buf_t buf; 12083 QDF_STATUS ret; 12084 int32_t len; 12085 int offset = 0; 12086 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12087 12088 len = sizeof(*cmd); 12089 buf = wmi_buf_alloc(wmi_handle, len); 12090 if (!buf) { 12091 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12092 return QDF_STATUS_E_FAILURE; 12093 } 12094 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12095 WMITLV_SET_HDR(&cmd->tlv_header, 12096 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12097 WMITLV_GET_STRUCT_TLVLEN( 12098 wmi_peer_mcast_group_cmd_fixed_param)); 12099 /* confirm the buffer is 4-byte aligned */ 12100 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12101 qdf_mem_zero(cmd, sizeof(*cmd)); 12102 12103 cmd->vdev_id = param->vap_id; 12104 /* construct the message assuming our endianness matches the target */ 12105 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12106 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12107 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12108 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12109 if (param->is_action_delete) 12110 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12111 12112 if (param->is_mcast_addr_len) 12113 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12114 12115 if (param->is_filter_mode_snoop) 12116 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12117 12118 /* unicast address spec only applies for non-wildcard cases */ 12119 if (!param->wildcard && param->ucast_mac_addr) { 12120 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12121 &cmd->ucast_mac_addr); 12122 } 12123 12124 if (param->mcast_ip_addr) { 12125 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12126 sizeof(cmd->mcast_ip_addr)); 12127 offset = sizeof(cmd->mcast_ip_addr) - 12128 param->mcast_ip_addr_bytes; 12129 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12130 param->mcast_ip_addr, 12131 param->mcast_ip_addr_bytes); 12132 } 12133 if (!param->mask) 12134 param->mask = &dummymask[0]; 12135 12136 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12137 param->mask, 12138 param->mcast_ip_addr_bytes); 12139 12140 if (param->srcs && param->nsrcs) { 12141 cmd->num_filter_addr = param->nsrcs; 12142 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12143 sizeof(cmd->filter_addr)); 12144 12145 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12146 param->nsrcs * param->mcast_ip_addr_bytes); 12147 } 12148 12149 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12150 WMI_PEER_MCAST_GROUP_CMDID); 12151 12152 if (ret != QDF_STATUS_SUCCESS) { 12153 WMI_LOGE("%s : WMI Failed\n", __func__); 12154 wmi_buf_free(buf); 12155 } 12156 12157 return ret; 12158 } 12159 12160 /** 12161 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12162 * command to fw 12163 * @wmi_handle: wmi handle 12164 * @param: pointer to hold spectral config parameter 12165 * 12166 * Return: 0 for success or error code 12167 */ 12168 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12169 struct vdev_spectral_configure_params *param) 12170 { 12171 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12172 wmi_buf_t buf; 12173 QDF_STATUS ret; 12174 int32_t len; 12175 12176 len = sizeof(*cmd); 12177 buf = wmi_buf_alloc(wmi_handle, len); 12178 if (!buf) { 12179 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12180 return QDF_STATUS_E_FAILURE; 12181 } 12182 12183 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12184 WMITLV_SET_HDR(&cmd->tlv_header, 12185 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12186 WMITLV_GET_STRUCT_TLVLEN( 12187 wmi_vdev_spectral_configure_cmd_fixed_param)); 12188 12189 cmd->vdev_id = param->vdev_id; 12190 cmd->spectral_scan_count = param->count; 12191 cmd->spectral_scan_period = param->period; 12192 cmd->spectral_scan_priority = param->spectral_pri; 12193 cmd->spectral_scan_fft_size = param->fft_size; 12194 cmd->spectral_scan_gc_ena = param->gc_enable; 12195 cmd->spectral_scan_restart_ena = param->restart_enable; 12196 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12197 cmd->spectral_scan_init_delay = param->init_delay; 12198 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12199 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12200 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12201 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12202 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12203 cmd->spectral_scan_pwr_format = param->pwr_format; 12204 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12205 cmd->spectral_scan_bin_scale = param->bin_scale; 12206 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12207 cmd->spectral_scan_chn_mask = param->chn_mask; 12208 12209 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12210 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12211 12212 if (ret != 0) { 12213 WMI_LOGE("Sending set quiet cmd failed\n"); 12214 wmi_buf_free(buf); 12215 } 12216 12217 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12218 __func__); 12219 12220 WMI_LOGI("vdev_id = %u\n" 12221 "spectral_scan_count = %u\n" 12222 "spectral_scan_period = %u\n" 12223 "spectral_scan_priority = %u\n" 12224 "spectral_scan_fft_size = %u\n" 12225 "spectral_scan_gc_ena = %u\n" 12226 "spectral_scan_restart_ena = %u\n" 12227 "spectral_scan_noise_floor_ref = %u\n" 12228 "spectral_scan_init_delay = %u\n" 12229 "spectral_scan_nb_tone_thr = %u\n" 12230 "spectral_scan_str_bin_thr = %u\n" 12231 "spectral_scan_wb_rpt_mode = %u\n" 12232 "spectral_scan_rssi_rpt_mode = %u\n" 12233 "spectral_scan_rssi_thr = %u\n" 12234 "spectral_scan_pwr_format = %u\n" 12235 "spectral_scan_rpt_mode = %u\n" 12236 "spectral_scan_bin_scale = %u\n" 12237 "spectral_scan_dBm_adj = %u\n" 12238 "spectral_scan_chn_mask = %u\n", 12239 param->vdev_id, 12240 param->count, 12241 param->period, 12242 param->spectral_pri, 12243 param->fft_size, 12244 param->gc_enable, 12245 param->restart_enable, 12246 param->noise_floor_ref, 12247 param->init_delay, 12248 param->nb_tone_thr, 12249 param->str_bin_thr, 12250 param->wb_rpt_mode, 12251 param->rssi_rpt_mode, 12252 param->rssi_thr, 12253 param->pwr_format, 12254 param->rpt_mode, 12255 param->bin_scale, 12256 param->dbm_adj, 12257 param->chn_mask); 12258 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12259 12260 return ret; 12261 } 12262 12263 /** 12264 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12265 * command to fw 12266 * @wmi_handle: wmi handle 12267 * @param: pointer to hold spectral enable parameter 12268 * 12269 * Return: 0 for success or error code 12270 */ 12271 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12272 struct vdev_spectral_enable_params *param) 12273 { 12274 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12275 wmi_buf_t buf; 12276 QDF_STATUS ret; 12277 int32_t len; 12278 12279 len = sizeof(*cmd); 12280 buf = wmi_buf_alloc(wmi_handle, len); 12281 if (!buf) { 12282 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12283 return QDF_STATUS_E_FAILURE; 12284 } 12285 12286 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12287 WMITLV_SET_HDR(&cmd->tlv_header, 12288 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12289 WMITLV_GET_STRUCT_TLVLEN( 12290 wmi_vdev_spectral_enable_cmd_fixed_param)); 12291 12292 cmd->vdev_id = param->vdev_id; 12293 12294 if (param->active_valid) { 12295 cmd->trigger_cmd = param->active ? 1 : 2; 12296 /* 1: Trigger, 2: Clear Trigger */ 12297 } else { 12298 cmd->trigger_cmd = 0; /* 0: Ignore */ 12299 } 12300 12301 if (param->enabled_valid) { 12302 cmd->enable_cmd = param->enabled ? 1 : 2; 12303 /* 1: Enable 2: Disable */ 12304 } else { 12305 cmd->enable_cmd = 0; /* 0: Ignore */ 12306 } 12307 12308 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12309 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12310 12311 if (ret != 0) { 12312 WMI_LOGE("Sending scan enable CMD failed\n"); 12313 wmi_buf_free(buf); 12314 } 12315 12316 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12317 12318 WMI_LOGI("vdev_id = %u\n" 12319 "trigger_cmd = %u\n" 12320 "enable_cmd = %u\n", 12321 cmd->vdev_id, 12322 cmd->trigger_cmd, 12323 cmd->enable_cmd); 12324 12325 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12326 12327 return ret; 12328 } 12329 12330 /** 12331 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12332 * @param wmi_handle : handle to WMI. 12333 * @param param : pointer to hold thermal mitigation param 12334 * 12335 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12336 */ 12337 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12338 wmi_unified_t wmi_handle, 12339 struct thermal_mitigation_params *param) 12340 { 12341 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 12342 wmi_therm_throt_level_config_info *lvl_conf = NULL; 12343 wmi_buf_t buf = NULL; 12344 uint8_t *buf_ptr = NULL; 12345 int error; 12346 int32_t len; 12347 int i; 12348 12349 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 12350 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 12351 12352 buf = wmi_buf_alloc(wmi_handle, len); 12353 if (!buf) { 12354 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12355 return QDF_STATUS_E_NOMEM; 12356 } 12357 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 12358 12359 /* init fixed params */ 12360 WMITLV_SET_HDR(tt_conf, 12361 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 12362 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 12363 12364 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12365 param->pdev_id); 12366 tt_conf->enable = param->enable; 12367 tt_conf->dc = param->dc; 12368 tt_conf->dc_per_event = param->dc_per_event; 12369 tt_conf->therm_throt_levels = THERMAL_LEVELS; 12370 12371 buf_ptr = (uint8_t *) ++tt_conf; 12372 /* init TLV params */ 12373 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12374 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 12375 12376 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 12377 for (i = 0; i < THERMAL_LEVELS; i++) { 12378 WMITLV_SET_HDR(&lvl_conf->tlv_header, 12379 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 12380 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 12381 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 12382 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 12383 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 12384 lvl_conf->prio = param->levelconf[i].priority; 12385 lvl_conf++; 12386 } 12387 12388 error = wmi_unified_cmd_send(wmi_handle, buf, len, 12389 WMI_THERM_THROT_SET_CONF_CMDID); 12390 if (QDF_IS_STATUS_ERROR(error)) { 12391 wmi_buf_free(buf); 12392 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 12393 } 12394 12395 return error; 12396 } 12397 12398 /** 12399 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 12400 * @wmi_handle: wmi handle 12401 * @param: pointer to pdev_qvit_params 12402 * 12403 * Return: 0 for success or error code 12404 */ 12405 static QDF_STATUS 12406 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 12407 struct pdev_qvit_params *param) 12408 { 12409 wmi_buf_t buf; 12410 QDF_STATUS ret = QDF_STATUS_E_INVAL; 12411 uint8_t *cmd; 12412 static uint8_t msgref = 1; 12413 uint8_t segnumber = 0, seginfo, numsegments; 12414 uint16_t chunk_len, total_bytes; 12415 uint8_t *bufpos; 12416 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 12417 12418 bufpos = param->utf_payload; 12419 total_bytes = param->len; 12420 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 12421 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 12422 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 12423 12424 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 12425 numsegments++; 12426 12427 while (param->len) { 12428 if (param->len > MAX_WMI_QVIT_LEN) 12429 chunk_len = MAX_WMI_QVIT_LEN; /* MAX message */ 12430 else 12431 chunk_len = param->len; 12432 12433 buf = wmi_buf_alloc(wmi_handle, 12434 (chunk_len + sizeof(seghdrinfo) + 12435 WMI_TLV_HDR_SIZE)); 12436 if (!buf) { 12437 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12438 return QDF_STATUS_E_NOMEM; 12439 } 12440 12441 cmd = (uint8_t *) wmi_buf_data(buf); 12442 12443 seghdrinfo.len = total_bytes; 12444 seghdrinfo.msgref = msgref; 12445 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 12446 seghdrinfo.segmentInfo = seginfo; 12447 12448 segnumber++; 12449 12450 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 12451 (chunk_len + sizeof(seghdrinfo))); 12452 cmd += WMI_TLV_HDR_SIZE; 12453 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 12454 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 12455 12456 ret = wmi_unified_cmd_send(wmi_handle, buf, 12457 (chunk_len + sizeof(seghdrinfo) + 12458 WMI_TLV_HDR_SIZE), 12459 WMI_PDEV_QVIT_CMDID); 12460 12461 if (ret != 0) { 12462 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 12463 wmi_buf_free(buf); 12464 break; 12465 } 12466 12467 param->len -= chunk_len; 12468 bufpos += chunk_len; 12469 } 12470 msgref++; 12471 12472 return ret; 12473 } 12474 12475 /** 12476 * send_wmm_update_cmd_tlv() - send wmm update command to fw 12477 * @wmi_handle: wmi handle 12478 * @param: pointer to wmm update param 12479 * 12480 * Return: 0 for success or error code 12481 */ 12482 static QDF_STATUS 12483 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 12484 struct wmm_update_params *param) 12485 { 12486 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 12487 wmi_wmm_params *wmm_param; 12488 wmi_buf_t buf; 12489 QDF_STATUS ret; 12490 int32_t len; 12491 int ac = 0; 12492 struct wmi_host_wmeParams *wmep; 12493 uint8_t *buf_ptr; 12494 12495 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 12496 buf = wmi_buf_alloc(wmi_handle, len); 12497 if (!buf) { 12498 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12499 return QDF_STATUS_E_FAILURE; 12500 } 12501 12502 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12503 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 12504 WMITLV_SET_HDR(&cmd->tlv_header, 12505 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 12506 WMITLV_GET_STRUCT_TLVLEN 12507 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 12508 12509 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 12510 12511 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 12512 12513 for (ac = 0; ac < WME_NUM_AC; ac++) { 12514 wmep = ¶m->wmep_array[ac]; 12515 wmm_param = (wmi_wmm_params *)buf_ptr; 12516 WMITLV_SET_HDR(&wmm_param->tlv_header, 12517 WMITLV_TAG_STRUC_wmi_wmm_params, 12518 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 12519 wmm_param->aifs = wmep->wmep_aifsn; 12520 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 12521 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 12522 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 12523 wmm_param->acm = wmep->wmep_acm; 12524 wmm_param->no_ack = wmep->wmep_noackPolicy; 12525 buf_ptr += sizeof(wmi_wmm_params); 12526 } 12527 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12528 WMI_PDEV_SET_WMM_PARAMS_CMDID); 12529 12530 if (ret != 0) { 12531 WMI_LOGE("Sending WMM update CMD failed\n"); 12532 wmi_buf_free(buf); 12533 } 12534 12535 return ret; 12536 } 12537 12538 /** 12539 * send_coex_config_cmd_tlv() - send coex config command to fw 12540 * @wmi_handle: wmi handle 12541 * @param: pointer to coex config param 12542 * 12543 * Return: 0 for success or error code 12544 */ 12545 static QDF_STATUS 12546 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 12547 struct coex_config_params *param) 12548 { 12549 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 12550 wmi_buf_t buf; 12551 QDF_STATUS ret; 12552 int32_t len; 12553 12554 len = sizeof(*cmd); 12555 buf = wmi_buf_alloc(wmi_handle, len); 12556 if (!buf) { 12557 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12558 return QDF_STATUS_E_FAILURE; 12559 } 12560 12561 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 12562 WMITLV_SET_HDR(&cmd->tlv_header, 12563 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 12564 WMITLV_GET_STRUCT_TLVLEN( 12565 WMI_COEX_CONFIG_CMD_fixed_param)); 12566 12567 cmd->vdev_id = param->vdev_id; 12568 cmd->config_type = param->config_type; 12569 cmd->config_arg1 = param->config_arg1; 12570 cmd->config_arg2 = param->config_arg2; 12571 cmd->config_arg3 = param->config_arg3; 12572 cmd->config_arg4 = param->config_arg4; 12573 cmd->config_arg5 = param->config_arg5; 12574 cmd->config_arg6 = param->config_arg6; 12575 12576 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12577 WMI_COEX_CONFIG_CMDID); 12578 12579 if (ret != 0) { 12580 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 12581 wmi_buf_free(buf); 12582 } 12583 12584 return ret; 12585 } 12586 12587 12588 #ifdef WLAN_SUPPORT_TWT 12589 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12590 target_resource_config *tgt_res_cfg) 12591 { 12592 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 12593 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 12594 } 12595 #else 12596 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12597 target_resource_config *tgt_res_cfg) 12598 { 12599 resource_cfg->twt_ap_pdev_count = 0; 12600 resource_cfg->twt_ap_sta_count = 0; 12601 } 12602 #endif 12603 12604 static 12605 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 12606 target_resource_config *tgt_res_cfg) 12607 { 12608 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 12609 resource_cfg->num_peers = tgt_res_cfg->num_peers; 12610 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 12611 resource_cfg->num_offload_reorder_buffs = 12612 tgt_res_cfg->num_offload_reorder_buffs; 12613 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 12614 resource_cfg->num_tids = tgt_res_cfg->num_tids; 12615 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 12616 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 12617 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 12618 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 12619 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 12620 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 12621 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 12622 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 12623 resource_cfg->scan_max_pending_req = 12624 tgt_res_cfg->scan_max_pending_req; 12625 resource_cfg->bmiss_offload_max_vdev = 12626 tgt_res_cfg->bmiss_offload_max_vdev; 12627 resource_cfg->roam_offload_max_vdev = 12628 tgt_res_cfg->roam_offload_max_vdev; 12629 resource_cfg->roam_offload_max_ap_profiles = 12630 tgt_res_cfg->roam_offload_max_ap_profiles; 12631 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 12632 resource_cfg->num_mcast_table_elems = 12633 tgt_res_cfg->num_mcast_table_elems; 12634 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 12635 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 12636 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 12637 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 12638 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 12639 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 12640 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 12641 resource_cfg->vow_config = tgt_res_cfg->vow_config; 12642 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 12643 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 12644 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 12645 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 12646 resource_cfg->num_tdls_conn_table_entries = 12647 tgt_res_cfg->num_tdls_conn_table_entries; 12648 resource_cfg->beacon_tx_offload_max_vdev = 12649 tgt_res_cfg->beacon_tx_offload_max_vdev; 12650 resource_cfg->num_multicast_filter_entries = 12651 tgt_res_cfg->num_multicast_filter_entries; 12652 resource_cfg->num_wow_filters = 12653 tgt_res_cfg->num_wow_filters; 12654 resource_cfg->num_keep_alive_pattern = 12655 tgt_res_cfg->num_keep_alive_pattern; 12656 resource_cfg->keep_alive_pattern_size = 12657 tgt_res_cfg->keep_alive_pattern_size; 12658 resource_cfg->max_tdls_concurrent_sleep_sta = 12659 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 12660 resource_cfg->max_tdls_concurrent_buffer_sta = 12661 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 12662 resource_cfg->wmi_send_separate = 12663 tgt_res_cfg->wmi_send_separate; 12664 resource_cfg->num_ocb_vdevs = 12665 tgt_res_cfg->num_ocb_vdevs; 12666 resource_cfg->num_ocb_channels = 12667 tgt_res_cfg->num_ocb_channels; 12668 resource_cfg->num_ocb_schedules = 12669 tgt_res_cfg->num_ocb_schedules; 12670 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 12671 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 12672 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 12673 resource_cfg->max_num_dbs_scan_duty_cycle = 12674 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 12675 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 12676 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 12677 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 12678 12679 if (tgt_res_cfg->atf_config) 12680 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 12681 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 12682 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 12683 resource_cfg->flag1, 1); 12684 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 12685 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 12686 resource_cfg->flag1, 1); 12687 if (tgt_res_cfg->cce_disable) 12688 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 12689 12690 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 12691 } 12692 12693 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 12694 * @wmi_handle: pointer to wmi handle 12695 * @buf_ptr: pointer to current position in init command buffer 12696 * @len: pointer to length. This will be updated with current length of cmd 12697 * @param: point host parameters for init command 12698 * 12699 * Return: Updated pointer of buf_ptr. 12700 */ 12701 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 12702 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 12703 { 12704 uint16_t idx; 12705 12706 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 12707 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 12708 wmi_pdev_band_to_mac *band_to_mac; 12709 12710 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 12711 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 12712 sizeof(wmi_resource_config) + 12713 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 12714 sizeof(wlan_host_memory_chunk))); 12715 12716 WMITLV_SET_HDR(&hw_mode->tlv_header, 12717 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 12718 (WMITLV_GET_STRUCT_TLVLEN 12719 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 12720 12721 hw_mode->hw_mode_index = param->hw_mode_id; 12722 hw_mode->num_band_to_mac = param->num_band_to_mac; 12723 12724 buf_ptr = (uint8_t *) (hw_mode + 1); 12725 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 12726 WMI_TLV_HDR_SIZE); 12727 for (idx = 0; idx < param->num_band_to_mac; idx++) { 12728 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 12729 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 12730 WMITLV_GET_STRUCT_TLVLEN 12731 (wmi_pdev_band_to_mac)); 12732 band_to_mac[idx].pdev_id = 12733 wmi_handle->ops->convert_pdev_id_host_to_target( 12734 param->band_to_mac[idx].pdev_id); 12735 band_to_mac[idx].start_freq = 12736 param->band_to_mac[idx].start_freq; 12737 band_to_mac[idx].end_freq = 12738 param->band_to_mac[idx].end_freq; 12739 } 12740 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12741 (param->num_band_to_mac * 12742 sizeof(wmi_pdev_band_to_mac)) + 12743 WMI_TLV_HDR_SIZE; 12744 12745 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12746 (param->num_band_to_mac * 12747 sizeof(wmi_pdev_band_to_mac))); 12748 } 12749 12750 return buf_ptr; 12751 } 12752 12753 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 12754 wmi_init_cmd_fixed_param *cmd) 12755 { 12756 int num_whitelist; 12757 wmi_abi_version my_vers; 12758 12759 num_whitelist = sizeof(version_whitelist) / 12760 sizeof(wmi_whitelist_version_info); 12761 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 12762 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 12763 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 12764 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 12765 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 12766 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 12767 12768 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 12769 &my_vers, 12770 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 12771 &cmd->host_abi_vers); 12772 12773 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 12774 __func__, 12775 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 12776 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 12777 cmd->host_abi_vers.abi_version_ns_0, 12778 cmd->host_abi_vers.abi_version_ns_1, 12779 cmd->host_abi_vers.abi_version_ns_2, 12780 cmd->host_abi_vers.abi_version_ns_3); 12781 12782 /* Save version sent from host - 12783 * Will be used to check ready event 12784 */ 12785 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 12786 sizeof(wmi_abi_version)); 12787 } 12788 12789 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12790 { 12791 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12792 wmi_service_ready_event_fixed_param *ev; 12793 12794 12795 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12796 12797 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12798 if (!ev) 12799 return QDF_STATUS_E_FAILURE; 12800 12801 /*Save fw version from service ready message */ 12802 /*This will be used while sending INIT message */ 12803 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12804 sizeof(wmi_handle->fw_abi_version)); 12805 12806 return QDF_STATUS_SUCCESS; 12807 } 12808 12809 /** 12810 * wmi_unified_save_fw_version_cmd() - save fw version 12811 * @wmi_handle: pointer to wmi handle 12812 * @res_cfg: resource config 12813 * @num_mem_chunks: no of mem chunck 12814 * @mem_chunk: pointer to mem chunck structure 12815 * 12816 * This function sends IE information to firmware 12817 * 12818 * Return: QDF_STATUS_SUCCESS for success otherwise failure 12819 * 12820 */ 12821 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 12822 void *evt_buf) 12823 { 12824 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12825 wmi_ready_event_fixed_param *ev = NULL; 12826 12827 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12828 ev = param_buf->fixed_param; 12829 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 12830 &wmi_handle->final_abi_vers, 12831 &ev->fw_abi_vers)) { 12832 /* 12833 * Error: Our host version and the given firmware version 12834 * are incompatible. 12835 **/ 12836 WMI_LOGD("%s: Error: Incompatible WMI version." 12837 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 12838 __func__, 12839 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 12840 abi_version_0), 12841 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 12842 abi_version_0), 12843 wmi_handle->final_abi_vers.abi_version_ns_0, 12844 wmi_handle->final_abi_vers.abi_version_ns_1, 12845 wmi_handle->final_abi_vers.abi_version_ns_2, 12846 wmi_handle->final_abi_vers.abi_version_ns_3, 12847 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 12848 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 12849 ev->fw_abi_vers.abi_version_ns_0, 12850 ev->fw_abi_vers.abi_version_ns_1, 12851 ev->fw_abi_vers.abi_version_ns_2, 12852 ev->fw_abi_vers.abi_version_ns_3); 12853 12854 return QDF_STATUS_E_FAILURE; 12855 } 12856 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 12857 sizeof(wmi_abi_version)); 12858 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12859 sizeof(wmi_abi_version)); 12860 12861 return QDF_STATUS_SUCCESS; 12862 } 12863 12864 /** 12865 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 12866 * @wmi_handle: wmi handle 12867 * @custom_addr: base mac address 12868 * 12869 * Return: QDF_STATUS_SUCCESS for success or error code 12870 */ 12871 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 12872 uint8_t *custom_addr) 12873 { 12874 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 12875 wmi_buf_t buf; 12876 int err; 12877 12878 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 12879 if (!buf) { 12880 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 12881 return QDF_STATUS_E_NOMEM; 12882 } 12883 12884 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 12885 qdf_mem_zero(cmd, sizeof(*cmd)); 12886 12887 WMITLV_SET_HDR(&cmd->tlv_header, 12888 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 12889 WMITLV_GET_STRUCT_TLVLEN 12890 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 12891 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 12892 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12893 WMI_HOST_PDEV_ID_SOC); 12894 err = wmi_unified_cmd_send(wmi_handle, buf, 12895 sizeof(*cmd), 12896 WMI_PDEV_SET_BASE_MACADDR_CMDID); 12897 if (err) { 12898 WMI_LOGE("Failed to send set_base_macaddr cmd"); 12899 wmi_buf_free(buf); 12900 return QDF_STATUS_E_FAILURE; 12901 } 12902 12903 return 0; 12904 } 12905 12906 /** 12907 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 12908 * @handle: wmi handle 12909 * @event: Event received from FW 12910 * @len: Length of the event 12911 * 12912 * Enables the low frequency events and disables the high frequency 12913 * events. Bit 17 indicates if the event if low/high frequency. 12914 * 1 - high frequency, 0 - low frequency 12915 * 12916 * Return: 0 on successfully enabling/disabling the events 12917 */ 12918 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 12919 uint8_t *event, 12920 uint32_t len) 12921 { 12922 uint32_t num_of_diag_events_logs; 12923 wmi_diag_event_log_config_fixed_param *cmd; 12924 wmi_buf_t buf; 12925 uint8_t *buf_ptr; 12926 uint32_t *cmd_args, *evt_args; 12927 uint32_t buf_len, i; 12928 12929 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 12930 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 12931 12932 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 12933 12934 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 12935 if (!param_buf) { 12936 WMI_LOGE("Invalid log supported event buffer"); 12937 return QDF_STATUS_E_INVAL; 12938 } 12939 wmi_event = param_buf->fixed_param; 12940 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 12941 12942 if (num_of_diag_events_logs > 12943 param_buf->num_diag_events_logs_list) { 12944 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 12945 num_of_diag_events_logs, 12946 param_buf->num_diag_events_logs_list); 12947 return QDF_STATUS_E_INVAL; 12948 } 12949 12950 evt_args = param_buf->diag_events_logs_list; 12951 if (!evt_args) { 12952 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 12953 __func__, num_of_diag_events_logs); 12954 return QDF_STATUS_E_INVAL; 12955 } 12956 12957 WMI_LOGD("%s: num_of_diag_events_logs=%d", 12958 __func__, num_of_diag_events_logs); 12959 12960 /* Free any previous allocation */ 12961 if (wmi_handle->events_logs_list) 12962 qdf_mem_free(wmi_handle->events_logs_list); 12963 12964 if (num_of_diag_events_logs > 12965 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 12966 WMI_LOGE("%s: excess num of logs:%d", __func__, 12967 num_of_diag_events_logs); 12968 QDF_ASSERT(0); 12969 return QDF_STATUS_E_INVAL; 12970 } 12971 /* Store the event list for run time enable/disable */ 12972 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 12973 sizeof(uint32_t)); 12974 if (!wmi_handle->events_logs_list) { 12975 WMI_LOGE("%s: event log list memory allocation failed", 12976 __func__); 12977 return QDF_STATUS_E_NOMEM; 12978 } 12979 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 12980 12981 /* Prepare the send buffer */ 12982 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12983 (num_of_diag_events_logs * sizeof(uint32_t)); 12984 12985 buf = wmi_buf_alloc(wmi_handle, buf_len); 12986 if (!buf) { 12987 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12988 qdf_mem_free(wmi_handle->events_logs_list); 12989 wmi_handle->events_logs_list = NULL; 12990 return QDF_STATUS_E_NOMEM; 12991 } 12992 12993 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 12994 buf_ptr = (uint8_t *) cmd; 12995 12996 WMITLV_SET_HDR(&cmd->tlv_header, 12997 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 12998 WMITLV_GET_STRUCT_TLVLEN( 12999 wmi_diag_event_log_config_fixed_param)); 13000 13001 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13002 13003 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13004 13005 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13006 (num_of_diag_events_logs * sizeof(uint32_t))); 13007 13008 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13009 13010 /* Populate the events */ 13011 for (i = 0; i < num_of_diag_events_logs; i++) { 13012 /* Low freq (0) - Enable (1) the event 13013 * High freq (1) - Disable (0) the event 13014 */ 13015 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13016 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13017 /* Set the event ID */ 13018 WMI_DIAG_ID_SET(cmd_args[i], 13019 WMI_DIAG_ID_GET(evt_args[i])); 13020 /* Set the type */ 13021 WMI_DIAG_TYPE_SET(cmd_args[i], 13022 WMI_DIAG_TYPE_GET(evt_args[i])); 13023 /* Storing the event/log list in WMI */ 13024 wmi_handle->events_logs_list[i] = evt_args[i]; 13025 } 13026 13027 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13028 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13029 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13030 __func__); 13031 wmi_buf_free(buf); 13032 /* Not clearing events_logs_list, though wmi cmd failed. 13033 * Host can still have this list 13034 */ 13035 return QDF_STATUS_E_INVAL; 13036 } 13037 13038 return 0; 13039 } 13040 13041 /** 13042 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13043 * @wmi_handle: wmi handle 13044 * @start_log: Start logging related parameters 13045 * 13046 * Send the command to the FW based on which specific logging of diag 13047 * event/log id can be started/stopped 13048 * 13049 * Return: None 13050 */ 13051 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13052 struct wmi_wifi_start_log *start_log) 13053 { 13054 wmi_diag_event_log_config_fixed_param *cmd; 13055 wmi_buf_t buf; 13056 uint8_t *buf_ptr; 13057 uint32_t len, count, log_level, i; 13058 uint32_t *cmd_args; 13059 uint32_t total_len; 13060 count = 0; 13061 13062 if (!wmi_handle->events_logs_list) { 13063 WMI_LOGE("%s: Not received event/log list from FW, yet", 13064 __func__); 13065 return QDF_STATUS_E_NOMEM; 13066 } 13067 /* total_len stores the number of events where BITS 17 and 18 are set. 13068 * i.e., events of high frequency (17) and for extended debugging (18) 13069 */ 13070 total_len = 0; 13071 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13072 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13073 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13074 total_len++; 13075 } 13076 13077 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13078 (total_len * sizeof(uint32_t)); 13079 13080 buf = wmi_buf_alloc(wmi_handle, len); 13081 if (!buf) { 13082 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13083 return QDF_STATUS_E_NOMEM; 13084 } 13085 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13086 buf_ptr = (uint8_t *) cmd; 13087 13088 WMITLV_SET_HDR(&cmd->tlv_header, 13089 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13090 WMITLV_GET_STRUCT_TLVLEN( 13091 wmi_diag_event_log_config_fixed_param)); 13092 13093 cmd->num_of_diag_events_logs = total_len; 13094 13095 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13096 13097 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13098 (total_len * sizeof(uint32_t))); 13099 13100 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13101 13102 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13103 log_level = 1; 13104 else 13105 log_level = 0; 13106 13107 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13108 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13109 uint32_t val = wmi_handle->events_logs_list[i]; 13110 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13111 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13112 13113 WMI_DIAG_ID_SET(cmd_args[count], 13114 WMI_DIAG_ID_GET(val)); 13115 WMI_DIAG_TYPE_SET(cmd_args[count], 13116 WMI_DIAG_TYPE_GET(val)); 13117 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13118 log_level); 13119 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13120 count++; 13121 } 13122 } 13123 13124 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13125 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13126 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13127 __func__); 13128 wmi_buf_free(buf); 13129 return QDF_STATUS_E_INVAL; 13130 } 13131 13132 return QDF_STATUS_SUCCESS; 13133 } 13134 13135 /** 13136 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13137 * @wmi_handle: WMI handle 13138 * 13139 * This function is used to send the flush command to the FW, 13140 * that will flush the fw logs that are residue in the FW 13141 * 13142 * Return: None 13143 */ 13144 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13145 { 13146 wmi_debug_mesg_flush_fixed_param *cmd; 13147 wmi_buf_t buf; 13148 int len = sizeof(*cmd); 13149 QDF_STATUS ret; 13150 13151 buf = wmi_buf_alloc(wmi_handle, len); 13152 if (!buf) { 13153 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13154 return QDF_STATUS_E_NOMEM; 13155 } 13156 13157 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13158 WMITLV_SET_HDR(&cmd->tlv_header, 13159 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13160 WMITLV_GET_STRUCT_TLVLEN( 13161 wmi_debug_mesg_flush_fixed_param)); 13162 cmd->reserved0 = 0; 13163 13164 ret = wmi_unified_cmd_send(wmi_handle, 13165 buf, 13166 len, 13167 WMI_DEBUG_MESG_FLUSH_CMDID); 13168 if (QDF_IS_STATUS_ERROR(ret)) { 13169 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13170 wmi_buf_free(buf); 13171 return QDF_STATUS_E_INVAL; 13172 } 13173 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13174 13175 return ret; 13176 } 13177 13178 /** 13179 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13180 * @wmi_handle: wmi handle 13181 * @msg: PCL structure containing the PCL and the number of channels 13182 * 13183 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13184 * firmware. The DBS Manager is the consumer of this information in the WLAN 13185 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13186 * to migrate to a new channel without host driver involvement. An example of 13187 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13188 * manage the channel selection without firmware involvement. 13189 * 13190 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13191 * channel list. The weights corresponds to the channels sent in 13192 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13193 * weightage compared to the non PCL channels. 13194 * 13195 * Return: Success if the cmd is sent successfully to the firmware 13196 */ 13197 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13198 struct wmi_pcl_chan_weights *msg) 13199 { 13200 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13201 wmi_buf_t buf; 13202 uint8_t *buf_ptr; 13203 uint32_t *cmd_args, i, len; 13204 uint32_t chan_len; 13205 13206 chan_len = msg->saved_num_chan; 13207 13208 len = sizeof(*cmd) + 13209 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13210 13211 buf = wmi_buf_alloc(wmi_handle, len); 13212 if (!buf) { 13213 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13214 return QDF_STATUS_E_NOMEM; 13215 } 13216 13217 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13218 buf_ptr = (uint8_t *) cmd; 13219 WMITLV_SET_HDR(&cmd->tlv_header, 13220 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13221 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13222 13223 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13224 WMI_HOST_PDEV_ID_SOC); 13225 cmd->num_chan = chan_len; 13226 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13227 13228 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13229 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13230 (chan_len * sizeof(uint32_t))); 13231 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13232 for (i = 0; i < chan_len ; i++) { 13233 cmd_args[i] = msg->weighed_valid_list[i]; 13234 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13235 msg->saved_chan_list[i], cmd_args[i]); 13236 } 13237 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13238 WMI_PDEV_SET_PCL_CMDID)) { 13239 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13240 wmi_buf_free(buf); 13241 return QDF_STATUS_E_FAILURE; 13242 } 13243 return QDF_STATUS_SUCCESS; 13244 } 13245 13246 /** 13247 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13248 * @wmi_handle: wmi handle 13249 * @msg: Structure containing the following parameters 13250 * 13251 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13252 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13253 * 13254 * Provides notification to the WLAN firmware that host driver is requesting a 13255 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13256 * configurations that include the Dual Band Simultaneous (DBS) feature. 13257 * 13258 * Return: Success if the cmd is sent successfully to the firmware 13259 */ 13260 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13261 uint32_t hw_mode_index) 13262 { 13263 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13264 wmi_buf_t buf; 13265 uint32_t len; 13266 13267 len = sizeof(*cmd); 13268 13269 buf = wmi_buf_alloc(wmi_handle, len); 13270 if (!buf) { 13271 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13272 return QDF_STATUS_E_NOMEM; 13273 } 13274 13275 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13276 WMITLV_SET_HDR(&cmd->tlv_header, 13277 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13278 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13279 13280 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13281 WMI_HOST_PDEV_ID_SOC); 13282 cmd->hw_mode_index = hw_mode_index; 13283 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13284 13285 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13286 WMI_PDEV_SET_HW_MODE_CMDID)) { 13287 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13288 __func__); 13289 wmi_buf_free(buf); 13290 return QDF_STATUS_E_FAILURE; 13291 } 13292 13293 return QDF_STATUS_SUCCESS; 13294 } 13295 13296 #ifdef WLAN_POLICY_MGR_ENABLE 13297 /** 13298 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13299 * @wmi_handle: wmi handle 13300 * @msg: Dual MAC config parameters 13301 * 13302 * Configures WLAN firmware with the dual MAC features 13303 * 13304 * Return: QDF_STATUS. 0 on success. 13305 */ 13306 static 13307 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13308 struct policy_mgr_dual_mac_config *msg) 13309 { 13310 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13311 wmi_buf_t buf; 13312 uint32_t len; 13313 13314 len = sizeof(*cmd); 13315 13316 buf = wmi_buf_alloc(wmi_handle, len); 13317 if (!buf) { 13318 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13319 return QDF_STATUS_E_FAILURE; 13320 } 13321 13322 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13323 WMITLV_SET_HDR(&cmd->tlv_header, 13324 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13325 WMITLV_GET_STRUCT_TLVLEN( 13326 wmi_pdev_set_mac_config_cmd_fixed_param)); 13327 13328 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13329 WMI_HOST_PDEV_ID_SOC); 13330 cmd->concurrent_scan_config_bits = msg->scan_config; 13331 cmd->fw_mode_config_bits = msg->fw_mode_config; 13332 WMI_LOGD("%s: scan_config:%x fw_mode_config:%x", 13333 __func__, msg->scan_config, msg->fw_mode_config); 13334 13335 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13336 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13337 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13338 __func__); 13339 wmi_buf_free(buf); 13340 } 13341 return QDF_STATUS_SUCCESS; 13342 } 13343 #endif 13344 13345 #ifdef BIG_ENDIAN_HOST 13346 /** 13347 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13348 * @param data_len - data length 13349 * @param data - pointer to data 13350 * 13351 * Return: QDF_STATUS - success or error status 13352 */ 13353 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13354 struct fips_params *param) 13355 { 13356 unsigned char *key_unaligned, *data_unaligned; 13357 int c; 13358 u_int8_t *key_aligned = NULL; 13359 u_int8_t *data_aligned = NULL; 13360 13361 /* Assigning unaligned space to copy the key */ 13362 key_unaligned = qdf_mem_malloc( 13363 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 13364 data_unaligned = qdf_mem_malloc( 13365 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 13366 13367 /* Checking if kmalloc is successful to allocate space */ 13368 if (key_unaligned == NULL) 13369 return QDF_STATUS_SUCCESS; 13370 /* Checking if space is aligned */ 13371 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 13372 /* align to 4 */ 13373 key_aligned = 13374 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 13375 FIPS_ALIGN); 13376 } else { 13377 key_aligned = (u_int8_t *)key_unaligned; 13378 } 13379 13380 /* memset and copy content from key to key aligned */ 13381 OS_MEMSET(key_aligned, 0, param->key_len); 13382 OS_MEMCPY(key_aligned, param->key, param->key_len); 13383 13384 /* print a hexdump for host debug */ 13385 print_hex_dump(KERN_DEBUG, 13386 "\t Aligned and Copied Key:@@@@ ", 13387 DUMP_PREFIX_NONE, 13388 16, 1, key_aligned, param->key_len, true); 13389 13390 /* Checking if kmalloc is successful to allocate space */ 13391 if (data_unaligned == NULL) 13392 return QDF_STATUS_SUCCESS; 13393 /* Checking of space is aligned */ 13394 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13395 /* align to 4 */ 13396 data_aligned = 13397 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 13398 FIPS_ALIGN); 13399 } else { 13400 data_aligned = (u_int8_t *)data_unaligned; 13401 } 13402 13403 /* memset and copy content from data to data aligned */ 13404 OS_MEMSET(data_aligned, 0, param->data_len); 13405 OS_MEMCPY(data_aligned, param->data, param->data_len); 13406 13407 /* print a hexdump for host debug */ 13408 print_hex_dump(KERN_DEBUG, 13409 "\t Properly Aligned and Copied Data:@@@@ ", 13410 DUMP_PREFIX_NONE, 13411 16, 1, data_aligned, param->data_len, true); 13412 13413 /* converting to little Endian both key_aligned and 13414 * data_aligned*/ 13415 for (c = 0; c < param->key_len/4; c++) { 13416 *((u_int32_t *)key_aligned+c) = 13417 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 13418 } 13419 for (c = 0; c < param->data_len/4; c++) { 13420 *((u_int32_t *)data_aligned+c) = 13421 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 13422 } 13423 13424 /* update endian data to key and data vectors */ 13425 OS_MEMCPY(param->key, key_aligned, param->key_len); 13426 OS_MEMCPY(param->data, data_aligned, param->data_len); 13427 13428 /* clean up allocated spaces */ 13429 qdf_mem_free(key_unaligned); 13430 key_unaligned = NULL; 13431 key_aligned = NULL; 13432 13433 qdf_mem_free(data_unaligned); 13434 data_unaligned = NULL; 13435 data_aligned = NULL; 13436 13437 return QDF_STATUS_SUCCESS; 13438 } 13439 #else 13440 /** 13441 * fips_align_data_be() - DUMMY for LE platform 13442 * 13443 * Return: QDF_STATUS - success 13444 */ 13445 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13446 struct fips_params *param) 13447 { 13448 return QDF_STATUS_SUCCESS; 13449 } 13450 #endif 13451 13452 13453 /** 13454 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 13455 * @wmi_handle: wmi handle 13456 * @param: pointer to hold pdev fips param 13457 * 13458 * Return: 0 for success or error code 13459 */ 13460 static QDF_STATUS 13461 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 13462 struct fips_params *param) 13463 { 13464 wmi_pdev_fips_cmd_fixed_param *cmd; 13465 wmi_buf_t buf; 13466 uint8_t *buf_ptr; 13467 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 13468 QDF_STATUS retval = QDF_STATUS_SUCCESS; 13469 13470 /* Length TLV placeholder for array of bytes */ 13471 len += WMI_TLV_HDR_SIZE; 13472 if (param->data_len) 13473 len += (param->data_len*sizeof(uint8_t)); 13474 13475 /* 13476 * Data length must be multiples of 16 bytes - checked against 0xF - 13477 * and must be less than WMI_SVC_MSG_SIZE - static size of 13478 * wmi_pdev_fips_cmd structure 13479 */ 13480 13481 /* do sanity on the input */ 13482 if (!(((param->data_len & 0xF) == 0) && 13483 ((param->data_len > 0) && 13484 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 13485 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 13486 return QDF_STATUS_E_INVAL; 13487 } 13488 13489 buf = wmi_buf_alloc(wmi_handle, len); 13490 if (!buf) { 13491 qdf_print("%s:wmi_buf_alloc failed", __func__); 13492 return QDF_STATUS_E_FAILURE; 13493 } 13494 13495 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13496 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 13497 WMITLV_SET_HDR(&cmd->tlv_header, 13498 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 13499 WMITLV_GET_STRUCT_TLVLEN 13500 (wmi_pdev_fips_cmd_fixed_param)); 13501 13502 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13503 param->pdev_id); 13504 if (param->key != NULL && param->data != NULL) { 13505 cmd->key_len = param->key_len; 13506 cmd->data_len = param->data_len; 13507 cmd->fips_cmd = !!(param->op); 13508 13509 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 13510 return QDF_STATUS_E_FAILURE; 13511 13512 qdf_mem_copy(cmd->key, param->key, param->key_len); 13513 13514 if (param->mode == FIPS_ENGINE_AES_CTR || 13515 param->mode == FIPS_ENGINE_AES_MIC) { 13516 cmd->mode = param->mode; 13517 } else { 13518 cmd->mode = FIPS_ENGINE_AES_CTR; 13519 } 13520 qdf_print("Key len = %d, Data len = %d", 13521 cmd->key_len, cmd->data_len); 13522 13523 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 13524 cmd->key, cmd->key_len, true); 13525 buf_ptr += sizeof(*cmd); 13526 13527 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 13528 13529 buf_ptr += WMI_TLV_HDR_SIZE; 13530 if (param->data_len) 13531 qdf_mem_copy(buf_ptr, 13532 (uint8_t *) param->data, param->data_len); 13533 13534 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 13535 16, 1, buf_ptr, cmd->data_len, true); 13536 13537 buf_ptr += param->data_len; 13538 13539 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 13540 WMI_PDEV_FIPS_CMDID); 13541 qdf_print("%s return value %d", __func__, retval); 13542 } else { 13543 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 13544 wmi_buf_free(buf); 13545 retval = -QDF_STATUS_E_BADMSG; 13546 } 13547 13548 return retval; 13549 } 13550 13551 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 13552 /** 13553 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 13554 * @wmi_handle: wmi handle 13555 * @vdev_id: vdev id 13556 * @bitmap: Event bitmap 13557 * @enable: enable/disable 13558 * 13559 * Return: CDF status 13560 */ 13561 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 13562 uint32_t vdev_id, 13563 uint32_t *bitmap, 13564 bool enable) 13565 { 13566 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 13567 uint16_t len; 13568 wmi_buf_t buf; 13569 int ret; 13570 13571 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 13572 buf = wmi_buf_alloc(wmi_handle, len); 13573 if (!buf) { 13574 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13575 return QDF_STATUS_E_NOMEM; 13576 } 13577 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 13578 WMITLV_SET_HDR(&cmd->tlv_header, 13579 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 13580 WMITLV_GET_STRUCT_TLVLEN 13581 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 13582 cmd->vdev_id = vdev_id; 13583 cmd->is_add = enable; 13584 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 13585 WMI_WOW_MAX_EVENT_BM_LEN); 13586 13587 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 13588 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 13589 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 13590 13591 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13592 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 13593 if (ret) { 13594 WMI_LOGE("Failed to config wow wakeup event"); 13595 wmi_buf_free(buf); 13596 return QDF_STATUS_E_FAILURE; 13597 } 13598 13599 return QDF_STATUS_SUCCESS; 13600 } 13601 13602 /** 13603 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 13604 * @wmi_handle: wmi handle 13605 * @vdev_id: vdev id 13606 * @ptrn_id: pattern id 13607 * @ptrn: pattern 13608 * @ptrn_len: pattern length 13609 * @ptrn_offset: pattern offset 13610 * @mask: mask 13611 * @mask_len: mask length 13612 * @user: true for user configured pattern and false for default pattern 13613 * @default_patterns: default patterns 13614 * 13615 * Return: CDF status 13616 */ 13617 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 13618 uint8_t vdev_id, uint8_t ptrn_id, 13619 const uint8_t *ptrn, uint8_t ptrn_len, 13620 uint8_t ptrn_offset, const uint8_t *mask, 13621 uint8_t mask_len, bool user, 13622 uint8_t default_patterns) 13623 { 13624 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13625 WOW_BITMAP_PATTERN_T *bitmap_pattern; 13626 wmi_buf_t buf; 13627 uint8_t *buf_ptr; 13628 int32_t len; 13629 int ret; 13630 13631 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13632 WMI_TLV_HDR_SIZE + 13633 1 * sizeof(WOW_BITMAP_PATTERN_T) + 13634 WMI_TLV_HDR_SIZE + 13635 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13636 WMI_TLV_HDR_SIZE + 13637 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13638 WMI_TLV_HDR_SIZE + 13639 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13640 WMI_TLV_HDR_SIZE + 13641 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13642 13643 buf = wmi_buf_alloc(wmi_handle, len); 13644 if (!buf) { 13645 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13646 return QDF_STATUS_E_NOMEM; 13647 } 13648 13649 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13650 buf_ptr = (uint8_t *) cmd; 13651 13652 WMITLV_SET_HDR(&cmd->tlv_header, 13653 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13654 WMITLV_GET_STRUCT_TLVLEN 13655 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13656 cmd->vdev_id = vdev_id; 13657 cmd->pattern_id = ptrn_id; 13658 13659 cmd->pattern_type = WOW_BITMAP_PATTERN; 13660 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13661 13662 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13663 sizeof(WOW_BITMAP_PATTERN_T)); 13664 buf_ptr += WMI_TLV_HDR_SIZE; 13665 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 13666 13667 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 13668 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 13669 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 13670 13671 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 13672 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 13673 13674 bitmap_pattern->pattern_offset = ptrn_offset; 13675 bitmap_pattern->pattern_len = ptrn_len; 13676 13677 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 13678 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 13679 13680 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 13681 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 13682 13683 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 13684 bitmap_pattern->pattern_id = ptrn_id; 13685 13686 WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 13687 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 13688 bitmap_pattern->pattern_offset, user); 13689 WMI_LOGD("Pattern : "); 13690 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13691 &bitmap_pattern->patternbuf[0], 13692 bitmap_pattern->pattern_len); 13693 13694 WMI_LOGD("Mask : "); 13695 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13696 &bitmap_pattern->bitmaskbuf[0], 13697 bitmap_pattern->pattern_len); 13698 13699 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 13700 13701 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 13702 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13703 buf_ptr += WMI_TLV_HDR_SIZE; 13704 13705 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 13706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13707 buf_ptr += WMI_TLV_HDR_SIZE; 13708 13709 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 13710 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13711 buf_ptr += WMI_TLV_HDR_SIZE; 13712 13713 /* Fill TLV for pattern_info_timeout but no data. */ 13714 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 13715 buf_ptr += WMI_TLV_HDR_SIZE; 13716 13717 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 13718 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 13719 buf_ptr += WMI_TLV_HDR_SIZE; 13720 *(uint32_t *) buf_ptr = 0; 13721 13722 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13723 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 13724 if (ret) { 13725 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 13726 wmi_buf_free(buf); 13727 return QDF_STATUS_E_FAILURE; 13728 } 13729 13730 return QDF_STATUS_SUCCESS; 13731 } 13732 13733 /** 13734 * fill_arp_offload_params_tlv() - Fill ARP offload data 13735 * @wmi_handle: wmi handle 13736 * @offload_req: offload request 13737 * @buf_ptr: buffer pointer 13738 * 13739 * To fill ARP offload data to firmware 13740 * when target goes to wow mode. 13741 * 13742 * Return: None 13743 */ 13744 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 13745 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 13746 { 13747 13748 int i; 13749 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 13750 bool enable_or_disable = offload_req->enable; 13751 13752 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13753 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 13754 *buf_ptr += WMI_TLV_HDR_SIZE; 13755 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 13756 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 13757 WMITLV_SET_HDR(&arp_tuple->tlv_header, 13758 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 13759 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 13760 13761 /* Fill data for ARP and NS in the first tupple for LA */ 13762 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 13763 /* Copy the target ip addr and flags */ 13764 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 13765 qdf_mem_copy(&arp_tuple->target_ipaddr, 13766 offload_req->host_ipv4_addr, 13767 WMI_IPV4_ADDR_LEN); 13768 WMI_LOGD("ARPOffload IP4 address: %pI4", 13769 offload_req->host_ipv4_addr); 13770 } 13771 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 13772 } 13773 } 13774 13775 #ifdef WLAN_NS_OFFLOAD 13776 /** 13777 * fill_ns_offload_params_tlv() - Fill NS offload data 13778 * @wmi|_handle: wmi handle 13779 * @offload_req: offload request 13780 * @buf_ptr: buffer pointer 13781 * 13782 * To fill NS offload data to firmware 13783 * when target goes to wow mode. 13784 * 13785 * Return: None 13786 */ 13787 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13788 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13789 { 13790 13791 int i; 13792 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13793 13794 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13795 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13796 *buf_ptr += WMI_TLV_HDR_SIZE; 13797 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 13798 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13799 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13800 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13801 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 13802 13803 /* 13804 * Fill data only for NS offload in the first ARP tuple for LA 13805 */ 13806 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13807 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13808 /* Copy the target/solicitation/remote ip addr */ 13809 if (ns_req->target_ipv6_addr_valid[i]) 13810 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13811 &ns_req->target_ipv6_addr[i], 13812 sizeof(WMI_IPV6_ADDR)); 13813 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13814 &ns_req->self_ipv6_addr[i], 13815 sizeof(WMI_IPV6_ADDR)); 13816 if (ns_req->target_ipv6_addr_ac_type[i]) { 13817 ns_tuple->flags |= 13818 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13819 } 13820 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13821 i, &ns_req->self_ipv6_addr[i], 13822 &ns_req->target_ipv6_addr[i]); 13823 13824 /* target MAC is optional, check if it is valid, 13825 * if this is not valid, the target will use the known 13826 * local MAC address rather than the tuple 13827 */ 13828 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13829 ns_req->self_macaddr.bytes, 13830 &ns_tuple->target_mac); 13831 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13832 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13833 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13834 } 13835 } 13836 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13837 } 13838 } 13839 13840 13841 /** 13842 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 13843 * @wmi: wmi handle 13844 * @offload_req: offload request 13845 * @buf_ptr: buffer pointer 13846 * 13847 * To fill extended NS offload extended data to firmware 13848 * when target goes to wow mode. 13849 * 13850 * Return: None 13851 */ 13852 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13853 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13854 { 13855 int i; 13856 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13857 uint32_t count, num_ns_ext_tuples; 13858 13859 count = ns_req->num_ns_offload_count; 13860 num_ns_ext_tuples = ns_req->num_ns_offload_count - 13861 WMI_MAX_NS_OFFLOADS; 13862 13863 /* Populate extended NS offload tuples */ 13864 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13865 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13866 *buf_ptr += WMI_TLV_HDR_SIZE; 13867 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 13868 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13869 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13870 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13871 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 13872 13873 /* 13874 * Fill data only for NS offload in the first ARP tuple for LA 13875 */ 13876 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13877 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13878 /* Copy the target/solicitation/remote ip addr */ 13879 if (ns_req->target_ipv6_addr_valid[i]) 13880 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13881 &ns_req->target_ipv6_addr[i], 13882 sizeof(WMI_IPV6_ADDR)); 13883 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13884 &ns_req->self_ipv6_addr[i], 13885 sizeof(WMI_IPV6_ADDR)); 13886 if (ns_req->target_ipv6_addr_ac_type[i]) { 13887 ns_tuple->flags |= 13888 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13889 } 13890 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13891 i, &ns_req->self_ipv6_addr[i], 13892 &ns_req->target_ipv6_addr[i]); 13893 13894 /* target MAC is optional, check if it is valid, 13895 * if this is not valid, the target will use the 13896 * known local MAC address rather than the tuple 13897 */ 13898 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13899 ns_req->self_macaddr.bytes, 13900 &ns_tuple->target_mac); 13901 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13902 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13903 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13904 } 13905 } 13906 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13907 } 13908 } 13909 #else 13910 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13911 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13912 { 13913 } 13914 13915 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13916 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13917 { 13918 } 13919 #endif 13920 13921 /** 13922 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 13923 * @wma: wmi handle 13924 * @arp_offload_req: arp offload request 13925 * @ns_offload_req: ns offload request 13926 * @arp_only: flag 13927 * 13928 * To configure ARP NS off load data to firmware 13929 * when target goes to wow mode. 13930 * 13931 * Return: QDF Status 13932 */ 13933 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 13934 struct pmo_arp_offload_params *arp_offload_req, 13935 struct pmo_ns_offload_params *ns_offload_req, 13936 uint8_t vdev_id) 13937 { 13938 int32_t res; 13939 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 13940 uint8_t *buf_ptr; 13941 wmi_buf_t buf; 13942 int32_t len; 13943 uint32_t count = 0, num_ns_ext_tuples = 0; 13944 13945 count = ns_offload_req->num_ns_offload_count; 13946 13947 /* 13948 * TLV place holder size for array of NS tuples 13949 * TLV place holder size for array of ARP tuples 13950 */ 13951 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 13952 WMI_TLV_HDR_SIZE + 13953 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 13954 WMI_TLV_HDR_SIZE + 13955 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 13956 13957 /* 13958 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 13959 * extra length for extended NS offload tuples which follows ARP offload 13960 * tuples. Host needs to fill this structure in following format: 13961 * 2 NS ofload tuples 13962 * 2 ARP offload tuples 13963 * N numbers of extended NS offload tuples if HDD has given more than 13964 * 2 NS offload addresses 13965 */ 13966 if (count > WMI_MAX_NS_OFFLOADS) { 13967 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 13968 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 13969 * sizeof(WMI_NS_OFFLOAD_TUPLE); 13970 } 13971 13972 buf = wmi_buf_alloc(wmi_handle, len); 13973 if (!buf) { 13974 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13975 return QDF_STATUS_E_NOMEM; 13976 } 13977 13978 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13979 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 13980 WMITLV_SET_HDR(&cmd->tlv_header, 13981 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 13982 WMITLV_GET_STRUCT_TLVLEN 13983 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 13984 cmd->flags = 0; 13985 cmd->vdev_id = vdev_id; 13986 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 13987 13988 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 13989 13990 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 13991 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13992 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 13993 if (num_ns_ext_tuples) 13994 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13995 13996 res = wmi_unified_cmd_send(wmi_handle, buf, len, 13997 WMI_SET_ARP_NS_OFFLOAD_CMDID); 13998 if (res) { 13999 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 14000 wmi_buf_free(buf); 14001 return QDF_STATUS_E_FAILURE; 14002 } 14003 14004 return QDF_STATUS_SUCCESS; 14005 } 14006 14007 /** 14008 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14009 * @wmi_handle: wmi handle 14010 * @vdev_id: vdev id 14011 * @action: true for enable else false 14012 * 14013 * To enable enhance multicast offload to firmware 14014 * when target goes to wow mode. 14015 * 14016 * Return: QDF Status 14017 */ 14018 14019 static 14020 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14021 wmi_unified_t wmi_handle, 14022 uint8_t vdev_id, bool action) 14023 { 14024 QDF_STATUS status; 14025 wmi_buf_t buf; 14026 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14027 14028 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14029 if (!buf) { 14030 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14031 return QDF_STATUS_E_NOMEM; 14032 } 14033 14034 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14035 wmi_buf_data(buf); 14036 14037 WMITLV_SET_HDR(&cmd->tlv_header, 14038 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14039 WMITLV_GET_STRUCT_TLVLEN( 14040 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14041 14042 cmd->vdev_id = vdev_id; 14043 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14044 ENHANCED_MCAST_FILTER_ENABLED); 14045 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14046 __func__, action, vdev_id); 14047 status = wmi_unified_cmd_send(wmi_handle, buf, 14048 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14049 if (status != QDF_STATUS_SUCCESS) { 14050 qdf_nbuf_free(buf); 14051 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14052 __func__); 14053 } 14054 14055 return status; 14056 } 14057 14058 /** 14059 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14060 * @wmi_handle: wmi handle 14061 * @param evt_buf: pointer to event buffer 14062 * @param hdr: Pointer to hold header 14063 * @param bufp: Pointer to hold pointer to rx param buffer 14064 * 14065 * Return: QDF_STATUS_SUCCESS for success or error code 14066 */ 14067 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14068 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14069 { 14070 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14071 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14072 14073 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14074 if (!param_buf) { 14075 WMI_LOGE("gtk param_buf is NULL"); 14076 return QDF_STATUS_E_INVAL; 14077 } 14078 14079 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14080 WMI_LOGE("Invalid length for GTK status"); 14081 return QDF_STATUS_E_INVAL; 14082 } 14083 14084 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14085 param_buf->fixed_param; 14086 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14087 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14088 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14089 qdf_mem_copy(>k_rsp_param->replay_counter, 14090 &fixed_param->replay_counter, 14091 GTK_REPLAY_COUNTER_BYTES); 14092 14093 return QDF_STATUS_SUCCESS; 14094 14095 } 14096 14097 #ifdef FEATURE_WLAN_RA_FILTERING 14098 /** 14099 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14100 * @wmi_handle: wmi handle 14101 * @vdev_id: vdev id 14102 * 14103 * Return: CDF status 14104 */ 14105 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14106 uint8_t vdev_id, uint8_t default_pattern, 14107 uint16_t rate_limit_interval) 14108 { 14109 14110 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14111 wmi_buf_t buf; 14112 uint8_t *buf_ptr; 14113 int32_t len; 14114 int ret; 14115 14116 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14117 WMI_TLV_HDR_SIZE + 14118 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14119 WMI_TLV_HDR_SIZE + 14120 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14121 WMI_TLV_HDR_SIZE + 14122 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14123 WMI_TLV_HDR_SIZE + 14124 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14125 WMI_TLV_HDR_SIZE + 14126 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14127 14128 buf = wmi_buf_alloc(wmi_handle, len); 14129 if (!buf) { 14130 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14131 return QDF_STATUS_E_NOMEM; 14132 } 14133 14134 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14135 buf_ptr = (uint8_t *) cmd; 14136 14137 WMITLV_SET_HDR(&cmd->tlv_header, 14138 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14139 WMITLV_GET_STRUCT_TLVLEN 14140 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14141 cmd->vdev_id = vdev_id; 14142 cmd->pattern_id = default_pattern, 14143 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14144 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14145 14146 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14147 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14148 buf_ptr += WMI_TLV_HDR_SIZE; 14149 14150 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14151 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14152 buf_ptr += WMI_TLV_HDR_SIZE; 14153 14154 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14155 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14156 buf_ptr += WMI_TLV_HDR_SIZE; 14157 14158 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14160 buf_ptr += WMI_TLV_HDR_SIZE; 14161 14162 /* Fill TLV for pattern_info_timeout but no data. */ 14163 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14164 buf_ptr += WMI_TLV_HDR_SIZE; 14165 14166 /* Fill TLV for ra_ratelimit_interval. */ 14167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14168 buf_ptr += WMI_TLV_HDR_SIZE; 14169 14170 *((uint32_t *) buf_ptr) = rate_limit_interval; 14171 14172 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14173 rate_limit_interval, vdev_id); 14174 14175 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14176 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14177 if (ret) { 14178 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14179 wmi_buf_free(buf); 14180 return QDF_STATUS_E_FAILURE; 14181 } 14182 14183 return QDF_STATUS_SUCCESS; 14184 14185 } 14186 #endif /* FEATURE_WLAN_RA_FILTERING */ 14187 14188 /** 14189 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14190 * @wmi_handle: wmi handle 14191 * @vdev_id: vdev id 14192 * @multicastAddr: mcast address 14193 * @clearList: clear list flag 14194 * 14195 * Return: QDF_STATUS_SUCCESS for success or error code 14196 */ 14197 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14198 uint8_t vdev_id, 14199 struct qdf_mac_addr multicast_addr, 14200 bool clearList) 14201 { 14202 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14203 wmi_buf_t buf; 14204 int err; 14205 14206 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14207 if (!buf) { 14208 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14209 return QDF_STATUS_E_NOMEM; 14210 } 14211 14212 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14213 qdf_mem_zero(cmd, sizeof(*cmd)); 14214 14215 WMITLV_SET_HDR(&cmd->tlv_header, 14216 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14217 WMITLV_GET_STRUCT_TLVLEN 14218 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14219 cmd->action = 14220 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14221 cmd->vdev_id = vdev_id; 14222 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14223 14224 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14225 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14226 14227 err = wmi_unified_cmd_send(wmi_handle, buf, 14228 sizeof(*cmd), 14229 WMI_SET_MCASTBCAST_FILTER_CMDID); 14230 if (err) { 14231 WMI_LOGE("Failed to send set_param cmd"); 14232 wmi_buf_free(buf); 14233 return QDF_STATUS_E_FAILURE; 14234 } 14235 14236 return QDF_STATUS_SUCCESS; 14237 } 14238 14239 /** 14240 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14241 * command to fw 14242 * @wmi_handle: wmi handle 14243 * @vdev_id: vdev id 14244 * @mcast_filter_params: mcast filter params 14245 * 14246 * Return: QDF_STATUS_SUCCESS for success or error code 14247 */ 14248 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14249 wmi_unified_t wmi_handle, 14250 uint8_t vdev_id, 14251 struct pmo_mcast_filter_params *filter_param) 14252 14253 { 14254 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14255 uint8_t *buf_ptr; 14256 wmi_buf_t buf; 14257 int err; 14258 int i; 14259 uint8_t *mac_addr_src_ptr = NULL; 14260 wmi_mac_addr *mac_addr_dst_ptr; 14261 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14262 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14263 14264 buf = wmi_buf_alloc(wmi_handle, len); 14265 if (!buf) { 14266 WMI_LOGE("Failed to allocate memory"); 14267 return QDF_STATUS_E_NOMEM; 14268 } 14269 14270 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14271 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14272 wmi_buf_data(buf); 14273 qdf_mem_zero(cmd, sizeof(*cmd)); 14274 14275 WMITLV_SET_HDR(&cmd->tlv_header, 14276 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14277 WMITLV_GET_STRUCT_TLVLEN 14278 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14279 cmd->operation = 14280 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14281 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14282 cmd->vdev_id = vdev_id; 14283 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14284 14285 buf_ptr += sizeof(*cmd); 14286 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14287 sizeof(wmi_mac_addr) * 14288 filter_param->multicast_addr_cnt); 14289 14290 if (filter_param->multicast_addr_cnt == 0) 14291 goto send_cmd; 14292 14293 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14294 mac_addr_dst_ptr = (wmi_mac_addr *) 14295 (buf_ptr + WMI_TLV_HDR_SIZE); 14296 14297 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14298 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14299 mac_addr_src_ptr += ATH_MAC_LEN; 14300 mac_addr_dst_ptr++; 14301 } 14302 14303 send_cmd: 14304 err = wmi_unified_cmd_send(wmi_handle, buf, 14305 len, 14306 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14307 if (err) { 14308 WMI_LOGE("Failed to send set_param cmd"); 14309 wmi_buf_free(buf); 14310 return QDF_STATUS_E_FAILURE; 14311 } 14312 14313 return QDF_STATUS_SUCCESS; 14314 } 14315 14316 static void 14317 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd, 14318 uint8_t vdev_id, 14319 struct pmo_gtk_req *params) 14320 { 14321 uint8_t *buf_ptr; 14322 wmi_gtk_offload_fils_tlv_param *ext_param; 14323 14324 buf_ptr = (uint8_t *) cmd + sizeof(*cmd); 14325 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14326 sizeof(*ext_param)); 14327 buf_ptr += WMI_TLV_HDR_SIZE; 14328 14329 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 14330 WMITLV_SET_HDR(&ext_param->tlv_header, 14331 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 14332 WMITLV_GET_STRUCT_TLVLEN( 14333 wmi_gtk_offload_fils_tlv_param)); 14334 ext_param->vdev_id = vdev_id; 14335 ext_param->flags = cmd->flags; 14336 ext_param->kek_len = params->kek_len; 14337 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 14338 qdf_mem_copy(ext_param->KCK, params->kck, 14339 WMI_GTK_OFFLOAD_KCK_BYTES); 14340 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 14341 GTK_REPLAY_COUNTER_BYTES); 14342 } 14343 14344 /** 14345 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14346 * @wmi_handle: wmi handle 14347 * @vdev_id: vdev id 14348 * @params: GTK offload parameters 14349 * 14350 * Return: CDF status 14351 */ 14352 static 14353 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14354 struct pmo_gtk_req *params, 14355 bool enable_offload, 14356 uint32_t gtk_offload_opcode) 14357 { 14358 int len; 14359 wmi_buf_t buf; 14360 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14361 QDF_STATUS status = QDF_STATUS_SUCCESS; 14362 14363 WMI_LOGD("%s Enter", __func__); 14364 14365 len = sizeof(*cmd); 14366 14367 if (params->is_fils_connection) 14368 len += WMI_TLV_HDR_SIZE + 14369 sizeof(wmi_gtk_offload_fils_tlv_param); 14370 14371 /* alloc wmi buffer */ 14372 buf = wmi_buf_alloc(wmi_handle, len); 14373 if (!buf) { 14374 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14375 status = QDF_STATUS_E_NOMEM; 14376 goto out; 14377 } 14378 14379 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14380 WMITLV_SET_HDR(&cmd->tlv_header, 14381 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14382 WMITLV_GET_STRUCT_TLVLEN 14383 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14384 14385 cmd->vdev_id = vdev_id; 14386 14387 /* Request target to enable GTK offload */ 14388 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 14389 cmd->flags = gtk_offload_opcode; 14390 14391 /* Copy the keys and replay counter */ 14392 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 14393 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 14394 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 14395 GTK_REPLAY_COUNTER_BYTES); 14396 } else { 14397 cmd->flags = gtk_offload_opcode; 14398 } 14399 if (params->is_fils_connection) 14400 fill_fils_tlv_params(cmd, vdev_id, params); 14401 14402 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 14403 /* send the wmi command */ 14404 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14405 WMI_GTK_OFFLOAD_CMDID)) { 14406 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 14407 wmi_buf_free(buf); 14408 status = QDF_STATUS_E_FAILURE; 14409 } 14410 14411 out: 14412 WMI_LOGD("%s Exit", __func__); 14413 return status; 14414 } 14415 14416 /** 14417 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 14418 * @wmi_handle: wmi handle 14419 * @params: GTK offload params 14420 * 14421 * Return: CDF status 14422 */ 14423 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 14424 wmi_unified_t wmi_handle, 14425 uint8_t vdev_id, 14426 uint64_t offload_req_opcode) 14427 { 14428 int len; 14429 wmi_buf_t buf; 14430 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14431 QDF_STATUS status = QDF_STATUS_SUCCESS; 14432 14433 len = sizeof(*cmd); 14434 14435 /* alloc wmi buffer */ 14436 buf = wmi_buf_alloc(wmi_handle, len); 14437 if (!buf) { 14438 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14439 status = QDF_STATUS_E_NOMEM; 14440 goto out; 14441 } 14442 14443 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14444 WMITLV_SET_HDR(&cmd->tlv_header, 14445 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14446 WMITLV_GET_STRUCT_TLVLEN 14447 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14448 14449 /* Request for GTK offload status */ 14450 cmd->flags = offload_req_opcode; 14451 cmd->vdev_id = vdev_id; 14452 14453 /* send the wmi command */ 14454 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14455 WMI_GTK_OFFLOAD_CMDID)) { 14456 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 14457 wmi_buf_free(buf); 14458 status = QDF_STATUS_E_FAILURE; 14459 } 14460 14461 out: 14462 return status; 14463 } 14464 14465 /** 14466 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 14467 * @wmi_handle: wmi handler 14468 * @action_params: pointer to action_params 14469 * 14470 * Return: 0 for success, otherwise appropriate error code 14471 */ 14472 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 14473 struct pmo_action_wakeup_set_params *action_params) 14474 { 14475 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 14476 wmi_buf_t buf; 14477 int i; 14478 int32_t err; 14479 uint32_t len = 0, *cmd_args; 14480 uint8_t *buf_ptr; 14481 14482 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 14483 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 14484 buf = wmi_buf_alloc(wmi_handle, len); 14485 if (!buf) { 14486 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 14487 return QDF_STATUS_E_NOMEM; 14488 } 14489 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 14490 buf_ptr = (uint8_t *)cmd; 14491 WMITLV_SET_HDR(&cmd->tlv_header, 14492 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 14493 WMITLV_GET_STRUCT_TLVLEN( 14494 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 14495 14496 cmd->vdev_id = action_params->vdev_id; 14497 cmd->operation = action_params->operation; 14498 14499 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 14500 cmd->action_category_map[i] = 14501 action_params->action_category_map[i]; 14502 14503 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 14504 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14505 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 14506 buf_ptr += WMI_TLV_HDR_SIZE; 14507 cmd_args = (uint32_t *) buf_ptr; 14508 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 14509 cmd_args[i] = action_params->action_per_category[i]; 14510 14511 err = wmi_unified_cmd_send(wmi_handle, buf, 14512 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 14513 if (err) { 14514 WMI_LOGE("Failed to send ap_ps_egap cmd"); 14515 wmi_buf_free(buf); 14516 return QDF_STATUS_E_FAILURE; 14517 } 14518 14519 return QDF_STATUS_SUCCESS; 14520 } 14521 14522 #ifdef FEATURE_WLAN_LPHB 14523 14524 /** 14525 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 14526 * @wmi_handle: wmi handle 14527 * @lphb_conf_req: configuration info 14528 * 14529 * Return: CDF status 14530 */ 14531 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 14532 wmi_hb_set_enable_cmd_fixed_param *params) 14533 { 14534 QDF_STATUS status; 14535 wmi_buf_t buf = NULL; 14536 uint8_t *buf_ptr; 14537 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 14538 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 14539 14540 14541 buf = wmi_buf_alloc(wmi_handle, len); 14542 if (!buf) { 14543 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14544 return QDF_STATUS_E_NOMEM; 14545 } 14546 14547 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14548 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 14549 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 14550 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 14551 WMITLV_GET_STRUCT_TLVLEN 14552 (wmi_hb_set_enable_cmd_fixed_param)); 14553 14554 /* fill in values */ 14555 hb_enable_fp->vdev_id = params->session; 14556 hb_enable_fp->enable = params->enable; 14557 hb_enable_fp->item = params->item; 14558 hb_enable_fp->session = params->session; 14559 14560 status = wmi_unified_cmd_send(wmi_handle, buf, 14561 len, WMI_HB_SET_ENABLE_CMDID); 14562 if (QDF_IS_STATUS_ERROR(status)) { 14563 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 14564 status); 14565 wmi_buf_free(buf); 14566 } 14567 14568 return status; 14569 } 14570 14571 /** 14572 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 14573 * @wmi_handle: wmi handle 14574 * @lphb_conf_req: lphb config request 14575 * 14576 * Return: CDF status 14577 */ 14578 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 14579 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 14580 { 14581 QDF_STATUS status; 14582 wmi_buf_t buf = NULL; 14583 uint8_t *buf_ptr; 14584 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 14585 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 14586 14587 buf = wmi_buf_alloc(wmi_handle, len); 14588 if (!buf) { 14589 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14590 return QDF_STATUS_E_NOMEM; 14591 } 14592 14593 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14594 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 14595 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 14596 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 14597 WMITLV_GET_STRUCT_TLVLEN 14598 (wmi_hb_set_tcp_params_cmd_fixed_param)); 14599 14600 /* fill in values */ 14601 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14602 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14603 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14604 hb_tcp_params_fp->seq = lphb_conf_req->seq; 14605 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 14606 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 14607 hb_tcp_params_fp->interval = lphb_conf_req->interval; 14608 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 14609 hb_tcp_params_fp->session = lphb_conf_req->session; 14610 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 14611 &lphb_conf_req->gateway_mac, 14612 sizeof(hb_tcp_params_fp->gateway_mac)); 14613 14614 status = wmi_unified_cmd_send(wmi_handle, buf, 14615 len, WMI_HB_SET_TCP_PARAMS_CMDID); 14616 if (QDF_IS_STATUS_ERROR(status)) { 14617 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 14618 status); 14619 wmi_buf_free(buf); 14620 } 14621 14622 return status; 14623 } 14624 14625 /** 14626 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 14627 * @wmi_handle: wmi handle 14628 * @lphb_conf_req: lphb config request 14629 * 14630 * Return: CDF status 14631 */ 14632 static 14633 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14634 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 14635 { 14636 QDF_STATUS status; 14637 wmi_buf_t buf = NULL; 14638 uint8_t *buf_ptr; 14639 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 14640 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 14641 14642 buf = wmi_buf_alloc(wmi_handle, len); 14643 if (!buf) { 14644 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14645 return QDF_STATUS_E_NOMEM; 14646 } 14647 14648 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14649 hb_tcp_filter_fp = 14650 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 14651 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 14652 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 14653 WMITLV_GET_STRUCT_TLVLEN 14654 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 14655 14656 /* fill in values */ 14657 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 14658 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 14659 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 14660 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 14661 memcpy((void *)&hb_tcp_filter_fp->filter, 14662 (void *)&g_hb_tcp_filter_fp->filter, 14663 WMI_WLAN_HB_MAX_FILTER_SIZE); 14664 14665 status = wmi_unified_cmd_send(wmi_handle, buf, 14666 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 14667 if (QDF_IS_STATUS_ERROR(status)) { 14668 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 14669 status); 14670 wmi_buf_free(buf); 14671 } 14672 14673 return status; 14674 } 14675 14676 /** 14677 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 14678 * @wmi_handle: wmi handle 14679 * @lphb_conf_req: lphb config request 14680 * 14681 * Return: CDF status 14682 */ 14683 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 14684 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 14685 { 14686 QDF_STATUS status; 14687 wmi_buf_t buf = NULL; 14688 uint8_t *buf_ptr; 14689 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 14690 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 14691 14692 buf = wmi_buf_alloc(wmi_handle, len); 14693 if (!buf) { 14694 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14695 return QDF_STATUS_E_NOMEM; 14696 } 14697 14698 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14699 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 14700 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 14701 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 14702 WMITLV_GET_STRUCT_TLVLEN 14703 (wmi_hb_set_udp_params_cmd_fixed_param)); 14704 14705 /* fill in values */ 14706 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14707 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14708 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14709 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 14710 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 14711 hb_udp_params_fp->interval = lphb_conf_req->interval; 14712 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 14713 hb_udp_params_fp->session = lphb_conf_req->session; 14714 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 14715 &lphb_conf_req->gateway_mac, 14716 sizeof(lphb_conf_req->gateway_mac)); 14717 14718 status = wmi_unified_cmd_send(wmi_handle, buf, 14719 len, WMI_HB_SET_UDP_PARAMS_CMDID); 14720 if (QDF_IS_STATUS_ERROR(status)) { 14721 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 14722 status); 14723 wmi_buf_free(buf); 14724 } 14725 14726 return status; 14727 } 14728 14729 /** 14730 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 14731 * @wmi_handle: wmi handle 14732 * @lphb_conf_req: lphb config request 14733 * 14734 * Return: CDF status 14735 */ 14736 static 14737 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14738 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 14739 { 14740 QDF_STATUS status; 14741 wmi_buf_t buf = NULL; 14742 uint8_t *buf_ptr; 14743 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 14744 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 14745 14746 buf = wmi_buf_alloc(wmi_handle, len); 14747 if (!buf) { 14748 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14749 return QDF_STATUS_E_NOMEM; 14750 } 14751 14752 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14753 hb_udp_filter_fp = 14754 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 14755 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 14756 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 14757 WMITLV_GET_STRUCT_TLVLEN 14758 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 14759 14760 /* fill in values */ 14761 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 14762 hb_udp_filter_fp->length = lphb_conf_req->length; 14763 hb_udp_filter_fp->offset = lphb_conf_req->offset; 14764 hb_udp_filter_fp->session = lphb_conf_req->session; 14765 memcpy((void *)&hb_udp_filter_fp->filter, 14766 (void *)&lphb_conf_req->filter, 14767 WMI_WLAN_HB_MAX_FILTER_SIZE); 14768 14769 status = wmi_unified_cmd_send(wmi_handle, buf, 14770 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 14771 if (QDF_IS_STATUS_ERROR(status)) { 14772 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 14773 status); 14774 wmi_buf_free(buf); 14775 } 14776 14777 return status; 14778 } 14779 #endif /* FEATURE_WLAN_LPHB */ 14780 14781 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 14782 struct pmo_hw_filter_params *req) 14783 { 14784 QDF_STATUS status; 14785 wmi_hw_data_filter_cmd_fixed_param *cmd; 14786 wmi_buf_t wmi_buf; 14787 14788 if (!req) { 14789 WMI_LOGE("req is null"); 14790 return QDF_STATUS_E_INVAL; 14791 } 14792 14793 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 14794 if (!wmi_buf) { 14795 WMI_LOGE(FL("Out of memory")); 14796 return QDF_STATUS_E_NOMEM; 14797 } 14798 14799 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 14800 WMITLV_SET_HDR(&cmd->tlv_header, 14801 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 14802 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 14803 cmd->vdev_id = req->vdev_id; 14804 cmd->enable = req->enable; 14805 /* Set all modes in case of disable */ 14806 if (!cmd->enable) 14807 cmd->hw_filter_bitmap = ((uint32_t)~0U); 14808 else 14809 cmd->hw_filter_bitmap = req->mode_bitmap; 14810 14811 WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d", 14812 req->enable ? "enable" : "disable", req->mode_bitmap, 14813 req->vdev_id); 14814 14815 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 14816 WMI_HW_DATA_FILTER_CMDID); 14817 if (QDF_IS_STATUS_ERROR(status)) { 14818 WMI_LOGE("Failed to configure hw filter"); 14819 wmi_buf_free(wmi_buf); 14820 } 14821 14822 return status; 14823 } 14824 14825 /** 14826 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 14827 * @wmi_handle: wmi handle 14828 * @vdev_id: vdev id 14829 * @enable: Flag to enable/disable packet filter 14830 * 14831 * Return: QDF_STATUS_SUCCESS for success or error code 14832 */ 14833 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 14834 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 14835 { 14836 int32_t len; 14837 int ret = 0; 14838 wmi_buf_t buf; 14839 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 14840 14841 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 14842 14843 buf = wmi_buf_alloc(wmi_handle, len); 14844 if (!buf) { 14845 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14846 return QDF_STATUS_E_NOMEM; 14847 } 14848 14849 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 14850 WMITLV_SET_HDR(&cmd->tlv_header, 14851 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 14852 WMITLV_GET_STRUCT_TLVLEN( 14853 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 14854 14855 cmd->vdev_id = vdev_id; 14856 if (enable) 14857 cmd->enable = PACKET_FILTER_SET_ENABLE; 14858 else 14859 cmd->enable = PACKET_FILTER_SET_DISABLE; 14860 14861 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 14862 __func__, cmd->enable, vdev_id); 14863 14864 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14865 WMI_PACKET_FILTER_ENABLE_CMDID); 14866 if (ret) { 14867 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 14868 wmi_buf_free(buf); 14869 } 14870 14871 return ret; 14872 } 14873 14874 /** 14875 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 14876 * @wmi_handle: wmi handle 14877 * @vdev_id: vdev id 14878 * @rcv_filter_param: Packet filter parameters 14879 * @filter_id: Filter id 14880 * @enable: Flag to add/delete packet filter configuration 14881 * 14882 * Return: QDF_STATUS_SUCCESS for success or error code 14883 */ 14884 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 14885 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 14886 uint8_t filter_id, bool enable) 14887 { 14888 int len, i; 14889 int err = 0; 14890 wmi_buf_t buf; 14891 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 14892 14893 14894 /* allocate the memory */ 14895 len = sizeof(*cmd); 14896 buf = wmi_buf_alloc(wmi_handle, len); 14897 if (!buf) { 14898 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14899 return QDF_STATUS_E_NOMEM; 14900 } 14901 14902 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 14903 WMITLV_SET_HDR(&cmd->tlv_header, 14904 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 14905 WMITLV_GET_STRUCT_TLVLEN 14906 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 14907 14908 cmd->vdev_id = vdev_id; 14909 cmd->filter_id = filter_id; 14910 if (enable) 14911 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 14912 else 14913 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 14914 14915 if (enable) { 14916 cmd->num_params = QDF_MIN( 14917 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 14918 rcv_filter_param->num_params); 14919 cmd->filter_type = rcv_filter_param->filter_type; 14920 cmd->coalesce_time = rcv_filter_param->coalesce_time; 14921 14922 for (i = 0; i < cmd->num_params; i++) { 14923 cmd->paramsData[i].proto_type = 14924 rcv_filter_param->params_data[i].protocol_layer; 14925 cmd->paramsData[i].cmp_type = 14926 rcv_filter_param->params_data[i].compare_flag; 14927 cmd->paramsData[i].data_length = 14928 rcv_filter_param->params_data[i].data_length; 14929 cmd->paramsData[i].data_offset = 14930 rcv_filter_param->params_data[i].data_offset; 14931 memcpy(&cmd->paramsData[i].compareData, 14932 rcv_filter_param->params_data[i].compare_data, 14933 sizeof(cmd->paramsData[i].compareData)); 14934 memcpy(&cmd->paramsData[i].dataMask, 14935 rcv_filter_param->params_data[i].data_mask, 14936 sizeof(cmd->paramsData[i].dataMask)); 14937 } 14938 } 14939 14940 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 14941 cmd->filter_action, cmd->filter_id, cmd->num_params); 14942 /* send the command along with data */ 14943 err = wmi_unified_cmd_send(wmi_handle, buf, len, 14944 WMI_PACKET_FILTER_CONFIG_CMDID); 14945 if (err) { 14946 WMI_LOGE("Failed to send pkt_filter cmd"); 14947 wmi_buf_free(buf); 14948 return QDF_STATUS_E_FAILURE; 14949 } 14950 14951 return QDF_STATUS_SUCCESS; 14952 } 14953 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 14954 14955 /** 14956 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 14957 * @wmi_handle: wmi handle 14958 * @request: SSID hotlist set request 14959 * 14960 * Return: QDF_STATUS enumeration 14961 */ 14962 static QDF_STATUS 14963 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 14964 struct ssid_hotlist_request_params *request) 14965 { 14966 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 14967 wmi_buf_t wmi_buf; 14968 uint32_t len; 14969 uint32_t array_size; 14970 uint8_t *buf_ptr; 14971 14972 /* length of fixed portion */ 14973 len = sizeof(*cmd); 14974 14975 /* length of variable portion */ 14976 array_size = 14977 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 14978 len += WMI_TLV_HDR_SIZE + array_size; 14979 14980 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14981 if (!wmi_buf) { 14982 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14983 return QDF_STATUS_E_NOMEM; 14984 } 14985 14986 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 14987 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 14988 buf_ptr; 14989 WMITLV_SET_HDR 14990 (&cmd->tlv_header, 14991 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 14992 WMITLV_GET_STRUCT_TLVLEN 14993 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 14994 14995 cmd->request_id = request->request_id; 14996 cmd->requestor_id = 0; 14997 cmd->vdev_id = request->session_id; 14998 cmd->table_id = 0; 14999 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 15000 cmd->total_entries = request->ssid_count; 15001 cmd->num_entries_in_page = request->ssid_count; 15002 cmd->first_entry_index = 0; 15003 15004 buf_ptr += sizeof(*cmd); 15005 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15006 15007 if (request->ssid_count) { 15008 wmi_extscan_hotlist_ssid_entry *entry; 15009 int i; 15010 15011 buf_ptr += WMI_TLV_HDR_SIZE; 15012 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15013 for (i = 0; i < request->ssid_count; i++) { 15014 WMITLV_SET_HDR 15015 (entry, 15016 WMITLV_TAG_ARRAY_STRUC, 15017 WMITLV_GET_STRUCT_TLVLEN 15018 (wmi_extscan_hotlist_ssid_entry)); 15019 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15020 qdf_mem_copy(entry->ssid.ssid, 15021 request->ssids[i].ssid.mac_ssid, 15022 request->ssids[i].ssid.length); 15023 entry->band = request->ssids[i].band; 15024 entry->min_rssi = request->ssids[i].rssi_low; 15025 entry->max_rssi = request->ssids[i].rssi_high; 15026 entry++; 15027 } 15028 cmd->mode = WMI_EXTSCAN_MODE_START; 15029 } else { 15030 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15031 } 15032 15033 if (wmi_unified_cmd_send 15034 (wmi_handle, wmi_buf, len, 15035 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15036 WMI_LOGE("%s: failed to send command", __func__); 15037 wmi_buf_free(wmi_buf); 15038 return QDF_STATUS_E_FAILURE; 15039 } 15040 15041 return QDF_STATUS_SUCCESS; 15042 } 15043 15044 /** 15045 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 15046 * @wmi_handle: wmi handle 15047 * @vdev_id: vdev id 15048 * 15049 * This function sends roam synch complete event to fw. 15050 * 15051 * Return: CDF STATUS 15052 */ 15053 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 15054 uint8_t vdev_id) 15055 { 15056 wmi_roam_synch_complete_fixed_param *cmd; 15057 wmi_buf_t wmi_buf; 15058 uint8_t *buf_ptr; 15059 uint16_t len; 15060 len = sizeof(wmi_roam_synch_complete_fixed_param); 15061 15062 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15063 if (!wmi_buf) { 15064 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15065 return QDF_STATUS_E_NOMEM; 15066 } 15067 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15068 buf_ptr = (uint8_t *) cmd; 15069 WMITLV_SET_HDR(&cmd->tlv_header, 15070 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15071 WMITLV_GET_STRUCT_TLVLEN 15072 (wmi_roam_synch_complete_fixed_param)); 15073 cmd->vdev_id = vdev_id; 15074 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15075 WMI_ROAM_SYNCH_COMPLETE)) { 15076 WMI_LOGP("%s: failed to send roam synch confirmation", 15077 __func__); 15078 wmi_buf_free(wmi_buf); 15079 return QDF_STATUS_E_FAILURE; 15080 } 15081 15082 return QDF_STATUS_SUCCESS; 15083 } 15084 15085 /** 15086 * send_fw_test_cmd_tlv() - send fw test command to fw. 15087 * @wmi_handle: wmi handle 15088 * @wmi_fwtest: fw test command 15089 * 15090 * This function sends fw test command to fw. 15091 * 15092 * Return: CDF STATUS 15093 */ 15094 static 15095 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15096 struct set_fwtest_params *wmi_fwtest) 15097 { 15098 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15099 wmi_buf_t wmi_buf; 15100 uint16_t len; 15101 15102 len = sizeof(*cmd); 15103 15104 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15105 if (!wmi_buf) { 15106 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15107 return QDF_STATUS_E_NOMEM; 15108 } 15109 15110 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15111 WMITLV_SET_HDR(&cmd->tlv_header, 15112 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15113 WMITLV_GET_STRUCT_TLVLEN( 15114 wmi_fwtest_set_param_cmd_fixed_param)); 15115 cmd->param_id = wmi_fwtest->arg; 15116 cmd->param_value = wmi_fwtest->value; 15117 15118 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15119 WMI_FWTEST_CMDID)) { 15120 WMI_LOGP("%s: failed to send fw test command", __func__); 15121 qdf_nbuf_free(wmi_buf); 15122 return QDF_STATUS_E_FAILURE; 15123 } 15124 15125 return QDF_STATUS_SUCCESS; 15126 } 15127 15128 /** 15129 * send_unit_test_cmd_tlv() - send unit test command to fw. 15130 * @wmi_handle: wmi handle 15131 * @wmi_utest: unit test command 15132 * 15133 * This function send unit test command to fw. 15134 * 15135 * Return: CDF STATUS 15136 */ 15137 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15138 struct wmi_unit_test_cmd *wmi_utest) 15139 { 15140 wmi_unit_test_cmd_fixed_param *cmd; 15141 wmi_buf_t wmi_buf; 15142 uint8_t *buf_ptr; 15143 int i; 15144 uint16_t len, args_tlv_len; 15145 uint32_t *unit_test_cmd_args; 15146 15147 args_tlv_len = 15148 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15149 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15150 15151 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15152 if (!wmi_buf) { 15153 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15154 return QDF_STATUS_E_NOMEM; 15155 } 15156 15157 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15158 buf_ptr = (uint8_t *) cmd; 15159 WMITLV_SET_HDR(&cmd->tlv_header, 15160 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15161 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15162 cmd->vdev_id = wmi_utest->vdev_id; 15163 cmd->module_id = wmi_utest->module_id; 15164 cmd->num_args = wmi_utest->num_args; 15165 cmd->diag_token = wmi_utest->diag_token; 15166 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15168 (wmi_utest->num_args * sizeof(uint32_t))); 15169 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15170 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15171 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15172 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15173 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15174 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15175 unit_test_cmd_args[i] = wmi_utest->args[i]; 15176 WMI_LOGI("%d,", wmi_utest->args[i]); 15177 } 15178 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15179 WMI_UNIT_TEST_CMDID)) { 15180 WMI_LOGP("%s: failed to send unit test command", __func__); 15181 wmi_buf_free(wmi_buf); 15182 return QDF_STATUS_E_FAILURE; 15183 } 15184 15185 return QDF_STATUS_SUCCESS; 15186 } 15187 15188 /** 15189 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15190 * @wmi_handle: wma handle 15191 * @roaminvoke: roam invoke command 15192 * 15193 * Send roam invoke command to fw for fastreassoc. 15194 * 15195 * Return: CDF STATUS 15196 */ 15197 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15198 struct wmi_roam_invoke_cmd *roaminvoke, 15199 uint32_t ch_hz) 15200 { 15201 wmi_roam_invoke_cmd_fixed_param *cmd; 15202 wmi_buf_t wmi_buf; 15203 u_int8_t *buf_ptr; 15204 u_int16_t len, args_tlv_len; 15205 uint32_t *channel_list; 15206 wmi_mac_addr *bssid_list; 15207 wmi_tlv_buf_len_param *buf_len_tlv; 15208 15209 /* Host sends only one channel and one bssid */ 15210 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15211 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15212 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15213 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15214 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15215 if (!wmi_buf) { 15216 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15217 return QDF_STATUS_E_NOMEM; 15218 } 15219 15220 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15221 buf_ptr = (u_int8_t *) cmd; 15222 WMITLV_SET_HDR(&cmd->tlv_header, 15223 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15224 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15225 cmd->vdev_id = roaminvoke->vdev_id; 15226 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15227 if (roaminvoke->is_same_bssid) 15228 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15229 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15230 15231 if (roaminvoke->frame_len) { 15232 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15233 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15234 cmd->num_buf = 1; 15235 } else { 15236 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15237 cmd->num_buf = 0; 15238 } 15239 15240 cmd->roam_ap_sel_mode = 0; 15241 cmd->roam_delay = 0; 15242 cmd->num_chan = 1; 15243 cmd->num_bssid = 1; 15244 15245 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15246 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15247 (sizeof(u_int32_t))); 15248 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15249 *channel_list = ch_hz; 15250 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15251 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15252 (sizeof(wmi_mac_addr))); 15253 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15254 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15255 15256 /* move to next tlv i.e. bcn_prb_buf_list */ 15257 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15258 15259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15260 sizeof(wmi_tlv_buf_len_param)); 15261 15262 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15263 buf_len_tlv->buf_len = roaminvoke->frame_len; 15264 15265 /* move to next tlv i.e. bcn_prb_frm */ 15266 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15267 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15268 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15269 15270 /* copy frame after the header */ 15271 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15272 roaminvoke->frame_buf, 15273 roaminvoke->frame_len); 15274 15275 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15276 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 15277 buf_ptr + WMI_TLV_HDR_SIZE, 15278 roaminvoke->frame_len); 15279 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15280 cmd->flags, cmd->roam_scan_mode, 15281 cmd->roam_ap_sel_mode, cmd->roam_delay, 15282 cmd->num_chan, cmd->num_bssid); 15283 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15284 15285 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15286 WMI_ROAM_INVOKE_CMDID)) { 15287 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15288 wmi_buf_free(wmi_buf); 15289 return QDF_STATUS_E_FAILURE; 15290 } 15291 15292 return QDF_STATUS_SUCCESS; 15293 } 15294 15295 /** 15296 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15297 * @wmi_handle: wmi handle 15298 * @command: command 15299 * @vdev_id: vdev id 15300 * 15301 * This function set roam offload command to fw. 15302 * 15303 * Return: CDF status 15304 */ 15305 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15306 uint32_t command, uint32_t vdev_id) 15307 { 15308 QDF_STATUS status; 15309 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15310 wmi_buf_t buf = NULL; 15311 int len; 15312 uint8_t *buf_ptr; 15313 15314 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15315 buf = wmi_buf_alloc(wmi_handle, len); 15316 if (!buf) { 15317 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15318 return QDF_STATUS_E_NOMEM; 15319 } 15320 15321 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15322 15323 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15324 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15325 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15326 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15327 cmd_fp->vdev_id = vdev_id; 15328 cmd_fp->command_arg = command; 15329 15330 status = wmi_unified_cmd_send(wmi_handle, buf, 15331 len, WMI_ROAM_SCAN_CMD); 15332 if (QDF_IS_STATUS_ERROR(status)) { 15333 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15334 status); 15335 goto error; 15336 } 15337 15338 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15339 return QDF_STATUS_SUCCESS; 15340 15341 error: 15342 wmi_buf_free(buf); 15343 15344 return status; 15345 } 15346 15347 /** 15348 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15349 * @wmi_handle: wmi handle 15350 * @ap_profile_p: ap profile 15351 * @vdev_id: vdev id 15352 * 15353 * Send WMI_ROAM_AP_PROFILE to firmware 15354 * 15355 * Return: CDF status 15356 */ 15357 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15358 struct ap_profile_params *ap_profile) 15359 { 15360 wmi_buf_t buf = NULL; 15361 QDF_STATUS status; 15362 int len; 15363 uint8_t *buf_ptr; 15364 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 15365 wmi_roam_cnd_scoring_param *score_param; 15366 wmi_ap_profile *profile; 15367 15368 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 15369 len += sizeof(*score_param); 15370 buf = wmi_buf_alloc(wmi_handle, len); 15371 if (!buf) { 15372 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15373 return QDF_STATUS_E_NOMEM; 15374 } 15375 15376 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15377 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 15378 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 15379 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 15380 WMITLV_GET_STRUCT_TLVLEN 15381 (wmi_roam_ap_profile_fixed_param)); 15382 /* fill in threshold values */ 15383 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 15384 roam_ap_profile_fp->id = 0; 15385 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 15386 15387 profile = (wmi_ap_profile *)buf_ptr; 15388 WMITLV_SET_HDR(&profile->tlv_header, 15389 WMITLV_TAG_STRUC_wmi_ap_profile, 15390 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 15391 profile->flags = ap_profile->profile.flags; 15392 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 15393 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 15394 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 15395 profile->ssid.ssid_len); 15396 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 15397 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 15398 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 15399 profile->rsn_mcastmgmtcipherset = 15400 ap_profile->profile.rsn_mcastmgmtcipherset; 15401 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 15402 15403 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", 15404 profile->flags, profile->rssi_threshold, 15405 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 15406 profile->rsn_authmode, profile->rsn_ucastcipherset, 15407 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 15408 profile->rssi_abs_thresh); 15409 15410 buf_ptr += sizeof(wmi_ap_profile); 15411 15412 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 15413 WMITLV_SET_HDR(&score_param->tlv_header, 15414 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 15415 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 15416 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 15417 score_param->rssi_weightage_pcnt = 15418 ap_profile->param.rssi_weightage; 15419 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 15420 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 15421 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 15422 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 15423 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 15424 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 15425 score_param->esp_qbss_weightage_pcnt = 15426 ap_profile->param.esp_qbss_weightage; 15427 score_param->beamforming_weightage_pcnt = 15428 ap_profile->param.beamforming_weightage; 15429 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 15430 score_param->oce_wan_weightage_pcnt = 15431 ap_profile->param.oce_wan_weightage; 15432 15433 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", 15434 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 15435 score_param->ht_weightage_pcnt, 15436 score_param->vht_weightage_pcnt, 15437 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 15438 score_param->band_weightage_pcnt, 15439 score_param->nss_weightage_pcnt, 15440 score_param->esp_qbss_weightage_pcnt, 15441 score_param->beamforming_weightage_pcnt, 15442 score_param->pcl_weightage_pcnt, 15443 score_param->oce_wan_weightage_pcnt); 15444 15445 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 15446 score_param->band_scoring.score_pcnt = 15447 ap_profile->param.band_index_score; 15448 score_param->nss_scoring.score_pcnt = 15449 ap_profile->param.nss_index_score; 15450 15451 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 15452 score_param->bw_scoring.score_pcnt, 15453 score_param->band_scoring.score_pcnt, 15454 score_param->nss_scoring.score_pcnt); 15455 15456 score_param->rssi_scoring.best_rssi_threshold = 15457 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 15458 score_param->rssi_scoring.good_rssi_threshold = 15459 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 15460 score_param->rssi_scoring.bad_rssi_threshold = 15461 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 15462 score_param->rssi_scoring.good_rssi_pcnt = 15463 ap_profile->param.rssi_scoring.good_rssi_pcnt; 15464 score_param->rssi_scoring.bad_rssi_pcnt = 15465 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 15466 score_param->rssi_scoring.good_bucket_size = 15467 ap_profile->param.rssi_scoring.good_bucket_size; 15468 score_param->rssi_scoring.bad_bucket_size = 15469 ap_profile->param.rssi_scoring.bad_bucket_size; 15470 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 15471 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 15472 15473 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 15474 score_param->rssi_scoring.best_rssi_threshold, 15475 score_param->rssi_scoring.good_rssi_threshold, 15476 score_param->rssi_scoring.bad_rssi_threshold, 15477 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 15478 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 15479 score_param->rssi_scoring.good_rssi_pcnt, 15480 score_param->rssi_scoring.bad_rssi_pcnt, 15481 score_param->rssi_scoring.good_bucket_size, 15482 score_param->rssi_scoring.bad_bucket_size); 15483 15484 score_param->esp_qbss_scoring.num_slot = 15485 ap_profile->param.esp_qbss_scoring.num_slot; 15486 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 15487 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 15488 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 15489 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 15490 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 15491 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 15492 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 15493 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 15494 15495 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15496 score_param->esp_qbss_scoring.num_slot, 15497 score_param->esp_qbss_scoring.score_pcnt3_to_0, 15498 score_param->esp_qbss_scoring.score_pcnt7_to_4, 15499 score_param->esp_qbss_scoring.score_pcnt11_to_8, 15500 score_param->esp_qbss_scoring.score_pcnt15_to_12); 15501 15502 score_param->oce_wan_scoring.num_slot = 15503 ap_profile->param.oce_wan_scoring.num_slot; 15504 score_param->oce_wan_scoring.score_pcnt3_to_0 = 15505 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 15506 score_param->oce_wan_scoring.score_pcnt7_to_4 = 15507 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 15508 score_param->oce_wan_scoring.score_pcnt11_to_8 = 15509 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 15510 score_param->oce_wan_scoring.score_pcnt15_to_12 = 15511 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 15512 15513 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15514 score_param->oce_wan_scoring.num_slot, 15515 score_param->oce_wan_scoring.score_pcnt3_to_0, 15516 score_param->oce_wan_scoring.score_pcnt7_to_4, 15517 score_param->oce_wan_scoring.score_pcnt11_to_8, 15518 score_param->oce_wan_scoring.score_pcnt15_to_12); 15519 15520 status = wmi_unified_cmd_send(wmi_handle, buf, 15521 len, WMI_ROAM_AP_PROFILE); 15522 if (QDF_IS_STATUS_ERROR(status)) { 15523 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 15524 status); 15525 wmi_buf_free(buf); 15526 } 15527 15528 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 15529 15530 return status; 15531 } 15532 15533 /** 15534 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 15535 * @wmi_handle: wmi handle 15536 * @scan_period: scan period 15537 * @scan_age: scan age 15538 * @vdev_id: vdev id 15539 * 15540 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 15541 * 15542 * Return: CDF status 15543 */ 15544 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 15545 uint32_t scan_period, 15546 uint32_t scan_age, 15547 uint32_t vdev_id) 15548 { 15549 QDF_STATUS status; 15550 wmi_buf_t buf = NULL; 15551 int len; 15552 uint8_t *buf_ptr; 15553 wmi_roam_scan_period_fixed_param *scan_period_fp; 15554 15555 /* Send scan period values */ 15556 len = sizeof(wmi_roam_scan_period_fixed_param); 15557 buf = wmi_buf_alloc(wmi_handle, len); 15558 if (!buf) { 15559 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15560 return QDF_STATUS_E_NOMEM; 15561 } 15562 15563 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15564 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 15565 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 15566 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 15567 WMITLV_GET_STRUCT_TLVLEN 15568 (wmi_roam_scan_period_fixed_param)); 15569 /* fill in scan period values */ 15570 scan_period_fp->vdev_id = vdev_id; 15571 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 15572 scan_period_fp->roam_scan_age = scan_age; 15573 15574 status = wmi_unified_cmd_send(wmi_handle, buf, 15575 len, WMI_ROAM_SCAN_PERIOD); 15576 if (QDF_IS_STATUS_ERROR(status)) { 15577 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 15578 status); 15579 goto error; 15580 } 15581 15582 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 15583 __func__, scan_period, scan_age); 15584 return QDF_STATUS_SUCCESS; 15585 error: 15586 wmi_buf_free(buf); 15587 15588 return status; 15589 } 15590 15591 /** 15592 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 15593 * @wmi_handle: wmi handle 15594 * @chan_count: channel count 15595 * @chan_list: channel list 15596 * @list_type: list type 15597 * @vdev_id: vdev id 15598 * 15599 * Set roam offload channel list. 15600 * 15601 * Return: CDF status 15602 */ 15603 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 15604 uint8_t chan_count, 15605 uint32_t *chan_list, 15606 uint8_t list_type, uint32_t vdev_id) 15607 { 15608 wmi_buf_t buf = NULL; 15609 QDF_STATUS status; 15610 int len, list_tlv_len; 15611 int i; 15612 uint8_t *buf_ptr; 15613 wmi_roam_chan_list_fixed_param *chan_list_fp; 15614 uint32_t *roam_chan_list_array; 15615 15616 if (chan_count == 0) { 15617 WMI_LOGD("%s : invalid number of channels %d", __func__, 15618 chan_count); 15619 return QDF_STATUS_E_EMPTY; 15620 } 15621 /* Channel list is a table of 2 TLV's */ 15622 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 15623 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 15624 buf = wmi_buf_alloc(wmi_handle, len); 15625 if (!buf) { 15626 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15627 return QDF_STATUS_E_NOMEM; 15628 } 15629 15630 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15631 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 15632 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 15633 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 15634 WMITLV_GET_STRUCT_TLVLEN 15635 (wmi_roam_chan_list_fixed_param)); 15636 chan_list_fp->vdev_id = vdev_id; 15637 chan_list_fp->num_chan = chan_count; 15638 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 15639 /* external app is controlling channel list */ 15640 chan_list_fp->chan_list_type = 15641 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 15642 } else { 15643 /* umac supplied occupied channel list in LFR */ 15644 chan_list_fp->chan_list_type = 15645 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 15646 } 15647 15648 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 15649 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15650 (chan_list_fp->num_chan * sizeof(uint32_t))); 15651 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15652 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 15653 for (i = 0; ((i < chan_list_fp->num_chan) && 15654 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 15655 roam_chan_list_array[i] = chan_list[i]; 15656 WMI_LOGD("%d,", roam_chan_list_array[i]); 15657 } 15658 15659 status = wmi_unified_cmd_send(wmi_handle, buf, 15660 len, WMI_ROAM_CHAN_LIST); 15661 if (QDF_IS_STATUS_ERROR(status)) { 15662 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 15663 status); 15664 goto error; 15665 } 15666 15667 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 15668 return QDF_STATUS_SUCCESS; 15669 error: 15670 wmi_buf_free(buf); 15671 15672 return status; 15673 } 15674 15675 /** 15676 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 15677 * @wmi_handle: wmi handle 15678 * @req_buf: per roam config buffer 15679 * 15680 * Return: QDF status 15681 */ 15682 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 15683 struct wmi_per_roam_config_req *req_buf) 15684 { 15685 wmi_buf_t buf = NULL; 15686 QDF_STATUS status; 15687 int len; 15688 uint8_t *buf_ptr; 15689 wmi_roam_per_config_fixed_param *wmi_per_config; 15690 15691 len = sizeof(wmi_roam_per_config_fixed_param); 15692 buf = wmi_buf_alloc(wmi_handle, len); 15693 if (!buf) { 15694 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15695 return QDF_STATUS_E_NOMEM; 15696 } 15697 15698 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15699 wmi_per_config = 15700 (wmi_roam_per_config_fixed_param *) buf_ptr; 15701 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 15702 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 15703 WMITLV_GET_STRUCT_TLVLEN 15704 (wmi_roam_per_config_fixed_param)); 15705 15706 /* fill in per roam config values */ 15707 wmi_per_config->vdev_id = req_buf->vdev_id; 15708 15709 wmi_per_config->enable = req_buf->per_config.enable; 15710 wmi_per_config->high_rate_thresh = 15711 (req_buf->per_config.tx_high_rate_thresh << 16) | 15712 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 15713 wmi_per_config->low_rate_thresh = 15714 (req_buf->per_config.tx_low_rate_thresh << 16) | 15715 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 15716 wmi_per_config->pkt_err_rate_thresh_pct = 15717 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 15718 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 15719 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 15720 wmi_per_config->pkt_err_rate_mon_time = 15721 (req_buf->per_config.tx_per_mon_time << 16) | 15722 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 15723 wmi_per_config->min_candidate_rssi = 15724 req_buf->per_config.min_candidate_rssi; 15725 15726 /* Send per roam config parameters */ 15727 status = wmi_unified_cmd_send(wmi_handle, buf, 15728 len, WMI_ROAM_PER_CONFIG_CMDID); 15729 if (QDF_IS_STATUS_ERROR(status)) { 15730 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 15731 status); 15732 wmi_buf_free(buf); 15733 return status; 15734 } 15735 15736 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 15737 req_buf->per_config.enable, req_buf->vdev_id); 15738 return QDF_STATUS_SUCCESS; 15739 } 15740 15741 /** 15742 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 15743 * @wmi_handle: wmi handle 15744 * @rssi_change_thresh: RSSI Change threshold 15745 * @bcn_rssi_weight: beacon RSSI weight 15746 * @vdev_id: vdev id 15747 * 15748 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 15749 * 15750 * Return: CDF status 15751 */ 15752 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 15753 uint32_t vdev_id, 15754 int32_t rssi_change_thresh, 15755 uint32_t bcn_rssi_weight, 15756 uint32_t hirssi_delay_btw_scans) 15757 { 15758 wmi_buf_t buf = NULL; 15759 QDF_STATUS status; 15760 int len; 15761 uint8_t *buf_ptr; 15762 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 15763 15764 /* Send rssi change parameters */ 15765 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 15766 buf = wmi_buf_alloc(wmi_handle, len); 15767 if (!buf) { 15768 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15769 return QDF_STATUS_E_NOMEM; 15770 } 15771 15772 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15773 rssi_change_fp = 15774 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 15775 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 15776 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 15777 WMITLV_GET_STRUCT_TLVLEN 15778 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 15779 /* fill in rssi change threshold (hysteresis) values */ 15780 rssi_change_fp->vdev_id = vdev_id; 15781 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 15782 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 15783 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 15784 15785 status = wmi_unified_cmd_send(wmi_handle, buf, 15786 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 15787 if (QDF_IS_STATUS_ERROR(status)) { 15788 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 15789 status); 15790 goto error; 15791 } 15792 15793 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 15794 rssi_change_thresh, bcn_rssi_weight); 15795 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 15796 return QDF_STATUS_SUCCESS; 15797 error: 15798 wmi_buf_free(buf); 15799 15800 return status; 15801 } 15802 15803 /** 15804 * send_power_dbg_cmd_tlv() - send power debug commands 15805 * @wmi_handle: wmi handle 15806 * @param: wmi power debug parameter 15807 * 15808 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 15809 * 15810 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15811 */ 15812 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 15813 struct wmi_power_dbg_params *param) 15814 { 15815 wmi_buf_t buf = NULL; 15816 QDF_STATUS status; 15817 int len, args_tlv_len; 15818 uint8_t *buf_ptr; 15819 uint8_t i; 15820 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 15821 uint32_t *cmd_args; 15822 15823 /* Prepare and send power debug cmd parameters */ 15824 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 15825 len = sizeof(*cmd) + args_tlv_len; 15826 buf = wmi_buf_alloc(wmi_handle, len); 15827 if (!buf) { 15828 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15829 return QDF_STATUS_E_NOMEM; 15830 } 15831 15832 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15833 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 15834 WMITLV_SET_HDR(&cmd->tlv_header, 15835 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 15836 WMITLV_GET_STRUCT_TLVLEN 15837 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 15838 15839 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15840 param->pdev_id); 15841 cmd->module_id = param->module_id; 15842 cmd->num_args = param->num_args; 15843 buf_ptr += sizeof(*cmd); 15844 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15845 (param->num_args * sizeof(uint32_t))); 15846 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15847 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 15848 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 15849 cmd_args[i] = param->args[i]; 15850 WMI_LOGI("%d,", param->args[i]); 15851 } 15852 15853 status = wmi_unified_cmd_send(wmi_handle, buf, 15854 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 15855 if (QDF_IS_STATUS_ERROR(status)) { 15856 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 15857 status); 15858 goto error; 15859 } 15860 15861 return QDF_STATUS_SUCCESS; 15862 error: 15863 wmi_buf_free(buf); 15864 15865 return status; 15866 } 15867 15868 /** 15869 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 15870 * @wmi_handle: wmi handle 15871 * @param: wmi multiple vdev restart req param 15872 * 15873 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 15874 * 15875 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15876 */ 15877 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 15878 wmi_unified_t wmi_handle, 15879 struct multiple_vdev_restart_params *param) 15880 { 15881 wmi_buf_t buf; 15882 QDF_STATUS qdf_status; 15883 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 15884 int i; 15885 uint8_t *buf_ptr; 15886 uint32_t *vdev_ids; 15887 wmi_channel *chan_info; 15888 struct channel_param *tchan_info; 15889 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 15890 15891 len += sizeof(wmi_channel); 15892 if (param->num_vdevs) 15893 len += sizeof(uint32_t) * param->num_vdevs; 15894 15895 buf = wmi_buf_alloc(wmi_handle, len); 15896 if (!buf) { 15897 WMI_LOGE("Failed to allocate memory\n"); 15898 qdf_status = QDF_STATUS_E_NOMEM; 15899 goto end; 15900 } 15901 15902 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15903 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 15904 buf_ptr; 15905 15906 WMITLV_SET_HDR(&cmd->tlv_header, 15907 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 15908 WMITLV_GET_STRUCT_TLVLEN 15909 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 15910 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15911 param->pdev_id); 15912 cmd->requestor_id = param->requestor_id; 15913 cmd->disable_hw_ack = param->disable_hw_ack; 15914 cmd->cac_duration_ms = param->cac_duration_ms; 15915 cmd->num_vdevs = param->num_vdevs; 15916 15917 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 15918 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 15919 " cmd->num_vdevs: %d ", 15920 __func__, cmd->pdev_id, cmd->requestor_id, 15921 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 15922 buf_ptr += sizeof(*cmd); 15923 15924 WMITLV_SET_HDR(buf_ptr, 15925 WMITLV_TAG_ARRAY_UINT32, 15926 sizeof(uint32_t) * param->num_vdevs); 15927 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15928 for (i = 0; i < param->num_vdevs; i++) { 15929 vdev_ids[i] = param->vdev_ids[i]; 15930 } 15931 15932 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 15933 15934 WMITLV_SET_HDR(buf_ptr, 15935 WMITLV_TAG_STRUC_wmi_channel, 15936 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 15937 chan_info = (wmi_channel *)buf_ptr; 15938 tchan_info = &(param->ch_param); 15939 chan_info->mhz = tchan_info->mhz; 15940 chan_info->band_center_freq1 = tchan_info->cfreq1; 15941 chan_info->band_center_freq2 = tchan_info->cfreq2; 15942 if (tchan_info->is_chan_passive) 15943 WMI_SET_CHANNEL_FLAG(chan_info, 15944 WMI_CHAN_FLAG_PASSIVE); 15945 if (tchan_info->dfs_set) 15946 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 15947 15948 if (tchan_info->allow_vht) 15949 WMI_SET_CHANNEL_FLAG(chan_info, 15950 WMI_CHAN_FLAG_ALLOW_VHT); 15951 else if (tchan_info->allow_ht) 15952 WMI_SET_CHANNEL_FLAG(chan_info, 15953 WMI_CHAN_FLAG_ALLOW_HT); 15954 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 15955 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 15956 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 15957 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 15958 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 15959 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 15960 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 15961 15962 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 15963 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 15964 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 15965 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 15966 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 15967 "tchan_info->reg_class_id: %d ," 15968 "tchan_info->maxregpower : %d ", __func__, 15969 tchan_info->is_chan_passive, tchan_info->dfs_set, 15970 tchan_info->allow_vht, tchan_info->allow_ht, 15971 tchan_info->antennamax, tchan_info->phy_mode, 15972 tchan_info->minpower, tchan_info->maxpower, 15973 tchan_info->maxregpower, tchan_info->reg_class_id, 15974 tchan_info->maxregpower); 15975 15976 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 15977 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 15978 15979 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15980 WMI_LOGE("%s: Failed to send\n", __func__); 15981 wmi_buf_free(buf); 15982 } 15983 15984 end: 15985 return qdf_status; 15986 } 15987 15988 /** 15989 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 15990 * @wmi_handle: wmi handle 15991 * @pdev_id: pdev id 15992 * 15993 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 15994 * 15995 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15996 */ 15997 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 15998 uint32_t pdev_id) 15999 { 16000 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 16001 wmi_buf_t buf; 16002 uint16_t len; 16003 QDF_STATUS ret; 16004 16005 len = sizeof(*cmd); 16006 buf = wmi_buf_alloc(wmi_handle, len); 16007 16008 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16009 16010 if (!buf) { 16011 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16012 return QDF_STATUS_E_NOMEM; 16013 } 16014 16015 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16016 wmi_buf_data(buf); 16017 16018 WMITLV_SET_HDR(&cmd->tlv_header, 16019 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16020 WMITLV_GET_STRUCT_TLVLEN( 16021 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16022 16023 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16024 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16025 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16026 if (QDF_IS_STATUS_ERROR(ret)) { 16027 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16028 __func__, ret, pdev_id); 16029 wmi_buf_free(buf); 16030 return QDF_STATUS_E_FAILURE; 16031 } 16032 16033 return QDF_STATUS_SUCCESS; 16034 } 16035 16036 /** 16037 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16038 * @wmi_handle: wmi handle 16039 * @pdev_id: pdev id 16040 * 16041 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16042 * 16043 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16044 */ 16045 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16046 uint32_t pdev_id) 16047 { 16048 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16049 wmi_buf_t buf; 16050 uint16_t len; 16051 QDF_STATUS ret; 16052 16053 len = sizeof(*cmd); 16054 buf = wmi_buf_alloc(wmi_handle, len); 16055 16056 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16057 16058 if (!buf) { 16059 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16060 return QDF_STATUS_E_NOMEM; 16061 } 16062 16063 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16064 wmi_buf_data(buf); 16065 16066 WMITLV_SET_HDR(&cmd->tlv_header, 16067 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16068 WMITLV_GET_STRUCT_TLVLEN( 16069 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16070 16071 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16072 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16073 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16074 if (QDF_IS_STATUS_ERROR(ret)) { 16075 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16076 __func__, ret, pdev_id); 16077 wmi_buf_free(buf); 16078 return QDF_STATUS_E_FAILURE; 16079 } 16080 16081 return QDF_STATUS_SUCCESS; 16082 } 16083 16084 /** 16085 * init_cmd_send_tlv() - send initialization cmd to fw 16086 * @wmi_handle: wmi handle 16087 * @param param: pointer to wmi init param 16088 * 16089 * Return: QDF_STATUS_SUCCESS for success or error code 16090 */ 16091 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16092 struct wmi_init_cmd_param *param) 16093 { 16094 wmi_buf_t buf; 16095 wmi_init_cmd_fixed_param *cmd; 16096 uint8_t *buf_ptr; 16097 wmi_resource_config *resource_cfg; 16098 wlan_host_memory_chunk *host_mem_chunks; 16099 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16100 uint16_t idx; 16101 int len; 16102 QDF_STATUS ret; 16103 16104 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16105 WMI_TLV_HDR_SIZE; 16106 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16107 16108 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16109 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16110 WMI_TLV_HDR_SIZE + 16111 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16112 16113 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16114 if (!buf) { 16115 qdf_print("%s: wmi_buf_alloc failed", __func__); 16116 return QDF_STATUS_E_FAILURE; 16117 } 16118 16119 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16120 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16121 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16122 16123 host_mem_chunks = (wlan_host_memory_chunk *) 16124 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16125 + WMI_TLV_HDR_SIZE); 16126 16127 WMITLV_SET_HDR(&cmd->tlv_header, 16128 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16129 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16130 16131 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16132 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16133 WMITLV_TAG_STRUC_wmi_resource_config, 16134 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16135 16136 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16137 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16138 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16139 WMITLV_GET_STRUCT_TLVLEN 16140 (wlan_host_memory_chunk)); 16141 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16142 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16143 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16144 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16145 "chunk %d len %d requested ,ptr 0x%x ", 16146 idx, host_mem_chunks[idx].size, 16147 host_mem_chunks[idx].ptr); 16148 } 16149 cmd->num_host_mem_chunks = param->num_mem_chunks; 16150 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16151 16152 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 16153 WMITLV_TAG_ARRAY_STRUC, 16154 (sizeof(wlan_host_memory_chunk) * 16155 param->num_mem_chunks)); 16156 16157 /* Fill hw mode id config */ 16158 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 16159 16160 /* Fill fw_abi_vers */ 16161 copy_fw_abi_version_tlv(wmi_handle, cmd); 16162 16163 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 16164 if (QDF_IS_STATUS_ERROR(ret)) { 16165 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 16166 ret); 16167 wmi_buf_free(buf); 16168 } 16169 16170 return ret; 16171 16172 } 16173 16174 /** 16175 * send_addba_send_cmd_tlv() - send addba send command to fw 16176 * @wmi_handle: wmi handle 16177 * @param: pointer to delba send params 16178 * @macaddr: peer mac address 16179 * 16180 * Send WMI_ADDBA_SEND_CMDID command to firmware 16181 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16182 */ 16183 static QDF_STATUS 16184 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 16185 uint8_t macaddr[IEEE80211_ADDR_LEN], 16186 struct addba_send_params *param) 16187 { 16188 wmi_addba_send_cmd_fixed_param *cmd; 16189 wmi_buf_t buf; 16190 uint16_t len; 16191 QDF_STATUS ret; 16192 16193 len = sizeof(*cmd); 16194 16195 buf = wmi_buf_alloc(wmi_handle, len); 16196 if (!buf) { 16197 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16198 return QDF_STATUS_E_NOMEM; 16199 } 16200 16201 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 16202 16203 WMITLV_SET_HDR(&cmd->tlv_header, 16204 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 16205 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 16206 16207 cmd->vdev_id = param->vdev_id; 16208 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16209 cmd->tid = param->tidno; 16210 cmd->buffersize = param->buffersize; 16211 16212 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 16213 if (QDF_IS_STATUS_ERROR(ret)) { 16214 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16215 wmi_buf_free(buf); 16216 return QDF_STATUS_E_FAILURE; 16217 } 16218 16219 return QDF_STATUS_SUCCESS; 16220 } 16221 16222 /** 16223 * send_delba_send_cmd_tlv() - send delba send command to fw 16224 * @wmi_handle: wmi handle 16225 * @param: pointer to delba send params 16226 * @macaddr: peer mac address 16227 * 16228 * Send WMI_DELBA_SEND_CMDID command to firmware 16229 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16230 */ 16231 static QDF_STATUS 16232 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 16233 uint8_t macaddr[IEEE80211_ADDR_LEN], 16234 struct delba_send_params *param) 16235 { 16236 wmi_delba_send_cmd_fixed_param *cmd; 16237 wmi_buf_t buf; 16238 uint16_t len; 16239 QDF_STATUS ret; 16240 16241 len = sizeof(*cmd); 16242 16243 buf = wmi_buf_alloc(wmi_handle, len); 16244 if (!buf) { 16245 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16246 return QDF_STATUS_E_NOMEM; 16247 } 16248 16249 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 16250 16251 WMITLV_SET_HDR(&cmd->tlv_header, 16252 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 16253 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 16254 16255 cmd->vdev_id = param->vdev_id; 16256 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16257 cmd->tid = param->tidno; 16258 cmd->initiator = param->initiator; 16259 cmd->reasoncode = param->reasoncode; 16260 16261 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 16262 if (QDF_IS_STATUS_ERROR(ret)) { 16263 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16264 wmi_buf_free(buf); 16265 return QDF_STATUS_E_FAILURE; 16266 } 16267 16268 return QDF_STATUS_SUCCESS; 16269 } 16270 16271 /** 16272 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 16273 * to fw 16274 * @wmi_handle: wmi handle 16275 * @param: pointer to addba clearresp params 16276 * @macaddr: peer mac address 16277 * Return: 0 for success or error code 16278 */ 16279 static QDF_STATUS 16280 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 16281 uint8_t macaddr[IEEE80211_ADDR_LEN], 16282 struct addba_clearresponse_params *param) 16283 { 16284 wmi_addba_clear_resp_cmd_fixed_param *cmd; 16285 wmi_buf_t buf; 16286 uint16_t len; 16287 QDF_STATUS ret; 16288 16289 len = sizeof(*cmd); 16290 16291 buf = wmi_buf_alloc(wmi_handle, len); 16292 if (!buf) { 16293 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 16294 return QDF_STATUS_E_FAILURE; 16295 } 16296 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 16297 16298 WMITLV_SET_HDR(&cmd->tlv_header, 16299 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 16300 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 16301 16302 cmd->vdev_id = param->vdev_id; 16303 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16304 16305 ret = wmi_unified_cmd_send(wmi_handle, 16306 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 16307 if (QDF_IS_STATUS_ERROR(ret)) { 16308 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16309 wmi_buf_free(buf); 16310 return QDF_STATUS_E_FAILURE; 16311 } 16312 16313 return QDF_STATUS_SUCCESS; 16314 } 16315 16316 /** 16317 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 16318 * @wmi_handle: wmi handle 16319 * @bcn_ctrl_param: pointer to bcn_offload_control param 16320 * 16321 * Return: QDF_STATUS_SUCCESS for success or error code 16322 */ 16323 static 16324 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 16325 struct bcn_offload_control *bcn_ctrl_param) 16326 { 16327 wmi_buf_t buf; 16328 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 16329 QDF_STATUS ret; 16330 uint32_t len; 16331 16332 len = sizeof(*cmd); 16333 16334 buf = wmi_buf_alloc(wmi_handle, len); 16335 if (!buf) { 16336 qdf_print("%s: wmi_buf_alloc failed", __func__); 16337 return QDF_STATUS_E_FAILURE; 16338 } 16339 16340 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 16341 WMITLV_SET_HDR(&cmd->tlv_header, 16342 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 16343 WMITLV_GET_STRUCT_TLVLEN 16344 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 16345 cmd->vdev_id = bcn_ctrl_param->vdev_id; 16346 switch (bcn_ctrl_param->bcn_ctrl_op) { 16347 case BCN_OFFLD_CTRL_TX_DISABLE: 16348 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 16349 break; 16350 case BCN_OFFLD_CTRL_TX_ENABLE: 16351 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 16352 break; 16353 case BCN_OFFLD_CTRL_SWBA_DISABLE: 16354 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 16355 break; 16356 case BCN_OFFLD_CTRL_SWBA_ENABLE: 16357 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 16358 break; 16359 default: 16360 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 16361 bcn_ctrl_param->bcn_ctrl_op); 16362 wmi_buf_free(buf); 16363 return QDF_STATUS_E_FAILURE; 16364 break; 16365 } 16366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16367 WMI_BCN_OFFLOAD_CTRL_CMDID); 16368 16369 if (QDF_IS_STATUS_ERROR(ret)) { 16370 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 16371 ret); 16372 wmi_buf_free(buf); 16373 } 16374 16375 return ret; 16376 } 16377 16378 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 16379 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 16380 struct nan_datapath_initiator_req *ndp_req) 16381 { 16382 uint16_t len; 16383 wmi_buf_t buf; 16384 uint8_t *tlv_ptr; 16385 QDF_STATUS status; 16386 wmi_channel *ch_tlv; 16387 wmi_ndp_initiator_req_fixed_param *cmd; 16388 uint32_t passphrase_len, service_name_len; 16389 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 16390 wmi_ndp_transport_ip_param *tcp_ip_param; 16391 16392 /* 16393 * WMI command expects 4 byte alligned len: 16394 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16395 */ 16396 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 16397 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 16398 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 16399 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 16400 service_name_len = 16401 qdf_roundup(ndp_req->service_name.service_name_len, 4); 16402 /* allocated memory for fixed params as well as variable size data */ 16403 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 16404 + ndp_cfg_len + ndp_app_info_len + pmk_len 16405 + passphrase_len + service_name_len; 16406 16407 if (ndp_req->is_ipv6_addr_present) 16408 len += sizeof(*tcp_ip_param); 16409 16410 buf = wmi_buf_alloc(wmi_handle, len); 16411 if (!buf) { 16412 WMI_LOGE("wmi_buf_alloc failed"); 16413 return QDF_STATUS_E_NOMEM; 16414 } 16415 16416 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 16417 WMITLV_SET_HDR(&cmd->tlv_header, 16418 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 16419 WMITLV_GET_STRUCT_TLVLEN( 16420 wmi_ndp_initiator_req_fixed_param)); 16421 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 16422 cmd->transaction_id = ndp_req->transaction_id; 16423 cmd->service_instance_id = ndp_req->service_instance_id; 16424 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 16425 &cmd->peer_discovery_mac_addr); 16426 16427 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 16428 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 16429 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 16430 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 16431 cmd->nan_csid = ndp_req->ncs_sk_type; 16432 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 16433 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 16434 16435 ch_tlv = (wmi_channel *)&cmd[1]; 16436 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 16437 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16438 ch_tlv->mhz = ndp_req->channel; 16439 tlv_ptr = (uint8_t *)&ch_tlv[1]; 16440 16441 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16442 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16443 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16444 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16445 16446 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16447 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16448 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 16449 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16450 16451 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16452 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 16453 cmd->nan_pmk_len); 16454 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16455 16456 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16457 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 16458 cmd->nan_passphrase_len); 16459 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16460 16461 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16462 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16463 ndp_req->service_name.service_name, 16464 cmd->nan_servicename_len); 16465 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16466 16467 if (ndp_req->is_ipv6_addr_present) { 16468 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16469 WMITLV_SET_HDR(tcp_ip_param, 16470 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16471 WMITLV_GET_STRUCT_TLVLEN( 16472 wmi_ndp_transport_ip_param)); 16473 tcp_ip_param->ipv6_addr_present = true; 16474 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16475 ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16476 } 16477 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16478 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr); 16479 16480 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 16481 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 16482 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 16483 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16484 cmd->peer_discovery_mac_addr.mac_addr31to0, 16485 cmd->peer_discovery_mac_addr.mac_addr47to32); 16486 16487 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 16488 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16489 ndp_req->ndp_config.ndp_cfg, 16490 ndp_req->ndp_config.ndp_cfg_len); 16491 16492 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 16493 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16494 ndp_req->ndp_info.ndp_app_info, 16495 ndp_req->ndp_info.ndp_app_info_len); 16496 16497 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16498 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16499 ndp_req->pmk.pmk, cmd->nan_pmk_len); 16500 16501 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16502 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16503 ndp_req->passphrase.passphrase, 16504 cmd->nan_passphrase_len); 16505 16506 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16507 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16508 ndp_req->service_name.service_name, 16509 cmd->nan_servicename_len); 16510 16511 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 16512 WMI_NDP_INITIATOR_REQ_CMDID); 16513 16514 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16515 WMI_NDP_INITIATOR_REQ_CMDID); 16516 if (QDF_IS_STATUS_ERROR(status)) { 16517 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 16518 wmi_buf_free(buf); 16519 } 16520 16521 return status; 16522 } 16523 16524 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 16525 struct nan_datapath_responder_req *req) 16526 { 16527 uint16_t len; 16528 wmi_buf_t buf; 16529 uint8_t *tlv_ptr; 16530 QDF_STATUS status; 16531 wmi_ndp_responder_req_fixed_param *cmd; 16532 wmi_ndp_transport_ip_param *tcp_ip_param; 16533 uint32_t passphrase_len, service_name_len; 16534 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 16535 16536 vdev_id = wlan_vdev_get_id(req->vdev); 16537 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 16538 vdev_id, req->transaction_id, 16539 req->ndp_rsp, 16540 req->ndp_instance_id, 16541 req->ndp_info.ndp_app_info_len); 16542 16543 /* 16544 * WMI command expects 4 byte alligned len: 16545 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16546 */ 16547 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 16548 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 16549 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 16550 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 16551 service_name_len = 16552 qdf_roundup(req->service_name.service_name_len, 4); 16553 16554 /* allocated memory for fixed params as well as variable size data */ 16555 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 16556 + pmk_len + passphrase_len + service_name_len; 16557 16558 if (req->is_ipv6_addr_present || req->is_port_present || 16559 req->is_protocol_present) 16560 len += sizeof(*tcp_ip_param); 16561 16562 buf = wmi_buf_alloc(wmi_handle, len); 16563 if (!buf) { 16564 WMI_LOGE("wmi_buf_alloc failed"); 16565 return QDF_STATUS_E_NOMEM; 16566 } 16567 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 16568 WMITLV_SET_HDR(&cmd->tlv_header, 16569 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 16570 WMITLV_GET_STRUCT_TLVLEN( 16571 wmi_ndp_responder_req_fixed_param)); 16572 cmd->vdev_id = vdev_id; 16573 cmd->transaction_id = req->transaction_id; 16574 cmd->ndp_instance_id = req->ndp_instance_id; 16575 cmd->rsp_code = req->ndp_rsp; 16576 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 16577 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 16578 cmd->nan_pmk_len = req->pmk.pmk_len; 16579 cmd->nan_csid = req->ncs_sk_type; 16580 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 16581 cmd->nan_servicename_len = req->service_name.service_name_len; 16582 16583 tlv_ptr = (uint8_t *)&cmd[1]; 16584 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16585 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16586 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16587 16588 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16589 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16590 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16591 req->ndp_info.ndp_app_info, 16592 req->ndp_info.ndp_app_info_len); 16593 16594 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16595 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16596 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 16597 cmd->nan_pmk_len); 16598 16599 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16600 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16601 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16602 req->passphrase.passphrase, 16603 cmd->nan_passphrase_len); 16604 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16605 16606 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16607 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16608 req->service_name.service_name, 16609 cmd->nan_servicename_len); 16610 16611 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16612 16613 if (req->is_ipv6_addr_present || req->is_port_present || 16614 req->is_protocol_present) { 16615 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16616 WMITLV_SET_HDR(tcp_ip_param, 16617 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16618 WMITLV_GET_STRUCT_TLVLEN( 16619 wmi_ndp_transport_ip_param)); 16620 tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present; 16621 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16622 req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16623 16624 tcp_ip_param->trans_port_present = req->is_port_present; 16625 tcp_ip_param->transport_port = req->port; 16626 16627 tcp_ip_param->trans_proto_present = req->is_protocol_present; 16628 tcp_ip_param->transport_protocol = req->protocol; 16629 } 16630 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16631 req->is_ipv6_addr_present, req->ipv6_addr); 16632 WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port); 16633 WMI_LOGD(FL("protocol: %d present: %d"), 16634 req->is_protocol_present, req->protocol); 16635 16636 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 16637 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 16638 16639 WMI_LOGD("ndp_config len: %d", 16640 req->ndp_config.ndp_cfg_len); 16641 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16642 req->ndp_config.ndp_cfg, 16643 req->ndp_config.ndp_cfg_len); 16644 16645 WMI_LOGD("ndp_app_info len: %d", 16646 req->ndp_info.ndp_app_info_len); 16647 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16648 req->ndp_info.ndp_app_info, 16649 req->ndp_info.ndp_app_info_len); 16650 16651 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16652 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16653 req->pmk.pmk, cmd->nan_pmk_len); 16654 16655 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16656 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16657 req->passphrase.passphrase, 16658 cmd->nan_passphrase_len); 16659 16660 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16661 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16662 req->service_name.service_name, 16663 cmd->nan_servicename_len); 16664 16665 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 16666 WMI_NDP_RESPONDER_REQ_CMDID); 16667 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16668 WMI_NDP_RESPONDER_REQ_CMDID); 16669 if (QDF_IS_STATUS_ERROR(status)) { 16670 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 16671 wmi_buf_free(buf); 16672 } 16673 return status; 16674 } 16675 16676 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 16677 struct nan_datapath_end_req *req) 16678 { 16679 uint16_t len; 16680 wmi_buf_t buf; 16681 QDF_STATUS status; 16682 uint32_t ndp_end_req_len, i; 16683 wmi_ndp_end_req *ndp_end_req_lst; 16684 wmi_ndp_end_req_fixed_param *cmd; 16685 16686 /* len of tlv following fixed param */ 16687 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 16688 /* above comes out to 4 byte alligned already, no need of padding */ 16689 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 16690 buf = wmi_buf_alloc(wmi_handle, len); 16691 if (!buf) { 16692 WMI_LOGE("Malloc failed"); 16693 return QDF_STATUS_E_NOMEM; 16694 } 16695 16696 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 16697 WMITLV_SET_HDR(&cmd->tlv_header, 16698 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 16699 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 16700 16701 cmd->transaction_id = req->transaction_id; 16702 16703 /* set tlv pointer to end of fixed param */ 16704 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 16705 ndp_end_req_len); 16706 16707 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 16708 WMI_TLV_HDR_SIZE); 16709 for (i = 0; i < req->num_ndp_instances; i++) { 16710 WMITLV_SET_HDR(&ndp_end_req_lst[i], 16711 WMITLV_TAG_ARRAY_FIXED_STRUC, 16712 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 16713 16714 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 16715 } 16716 16717 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 16718 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16719 WMI_NDP_END_REQ_CMDID); 16720 if (QDF_IS_STATUS_ERROR(status)) { 16721 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 16722 wmi_buf_free(buf); 16723 } 16724 16725 return status; 16726 } 16727 16728 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 16729 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 16730 { 16731 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 16732 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 16733 16734 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 16735 fixed_params = event->fixed_param; 16736 16737 rsp->vdev = 16738 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16739 fixed_params->vdev_id, 16740 WLAN_NAN_ID); 16741 if (!rsp->vdev) { 16742 WMI_LOGE("vdev is null"); 16743 return QDF_STATUS_E_INVAL; 16744 } 16745 16746 rsp->transaction_id = fixed_params->transaction_id; 16747 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16748 rsp->status = fixed_params->rsp_status; 16749 rsp->reason = fixed_params->reason_code; 16750 16751 return QDF_STATUS_SUCCESS; 16752 } 16753 16754 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 16755 uint8_t *data, struct nan_datapath_indication_event *rsp) 16756 { 16757 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 16758 wmi_ndp_indication_event_fixed_param *fixed_params; 16759 size_t total_array_len; 16760 16761 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 16762 fixed_params = 16763 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 16764 16765 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16766 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16767 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16768 return QDF_STATUS_E_INVAL; 16769 } 16770 16771 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16772 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16773 fixed_params->ndp_app_info_len, 16774 event->num_ndp_app_info); 16775 return QDF_STATUS_E_INVAL; 16776 } 16777 16778 if (fixed_params->ndp_cfg_len > 16779 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16780 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16781 __func__, fixed_params->ndp_cfg_len); 16782 return QDF_STATUS_E_INVAL; 16783 } 16784 16785 total_array_len = fixed_params->ndp_cfg_len + 16786 sizeof(*fixed_params); 16787 16788 if (fixed_params->ndp_app_info_len > 16789 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16790 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16791 __func__, fixed_params->ndp_app_info_len); 16792 return QDF_STATUS_E_INVAL; 16793 } 16794 total_array_len += fixed_params->ndp_app_info_len; 16795 16796 if (fixed_params->nan_scid_len > 16797 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16798 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16799 __func__, fixed_params->nan_scid_len); 16800 return QDF_STATUS_E_INVAL; 16801 } 16802 16803 rsp->vdev = 16804 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16805 fixed_params->vdev_id, 16806 WLAN_NAN_ID); 16807 if (!rsp->vdev) { 16808 WMI_LOGE("vdev is null"); 16809 return QDF_STATUS_E_INVAL; 16810 } 16811 rsp->service_instance_id = fixed_params->service_instance_id; 16812 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16813 rsp->role = fixed_params->self_ndp_role; 16814 rsp->policy = fixed_params->accept_policy; 16815 16816 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16817 rsp->peer_mac_addr.bytes); 16818 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 16819 rsp->peer_discovery_mac_addr.bytes); 16820 16821 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 16822 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 16823 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 16824 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 16825 fixed_params->service_instance_id, 16826 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 16827 fixed_params->accept_policy, 16828 fixed_params->nan_csid, fixed_params->nan_scid_len, 16829 rsp->peer_mac_addr.bytes, 16830 rsp->peer_discovery_mac_addr.bytes); 16831 16832 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16833 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16834 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16835 16836 WMI_LOGD("ndp_app_info - %d bytes", 16837 fixed_params->ndp_app_info_len); 16838 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16839 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16840 16841 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 16842 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16843 rsp->ncs_sk_type = fixed_params->nan_csid; 16844 rsp->scid.scid_len = fixed_params->nan_scid_len; 16845 16846 if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN) 16847 rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN; 16848 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 16849 rsp->ndp_config.ndp_cfg_len); 16850 16851 if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN) 16852 rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN; 16853 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16854 rsp->ndp_info.ndp_app_info_len); 16855 16856 if (rsp->scid.scid_len > NDP_SCID_BUF_LEN) 16857 rsp->scid.scid_len = NDP_SCID_BUF_LEN; 16858 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 16859 16860 if (event->ndp_transport_ip_param && 16861 event->num_ndp_transport_ip_param) { 16862 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16863 rsp->is_ipv6_addr_present = true; 16864 qdf_mem_copy(rsp->ipv6_addr, 16865 event->ndp_transport_ip_param->ipv6_intf_addr, 16866 WMI_NDP_IPV6_INTF_ADDR_LEN); 16867 } 16868 } 16869 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16870 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16871 16872 WMI_LOGD("scid hex dump:"); 16873 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16874 rsp->scid.scid, rsp->scid.scid_len); 16875 16876 return QDF_STATUS_SUCCESS; 16877 } 16878 16879 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 16880 uint8_t *data, struct nan_datapath_confirm_event *rsp) 16881 { 16882 uint8_t i; 16883 WMI_HOST_WLAN_PHY_MODE ch_mode; 16884 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 16885 wmi_ndp_confirm_event_fixed_param *fixed_params; 16886 size_t total_array_len; 16887 16888 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 16889 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 16890 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", 16891 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 16892 fixed_params->ndp_instance_id, fixed_params->rsp_code, 16893 fixed_params->reason_code, 16894 fixed_params->num_active_ndps_on_peer); 16895 WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels); 16896 16897 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16898 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16899 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16900 return QDF_STATUS_E_INVAL; 16901 } 16902 16903 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16904 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16905 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16906 16907 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16908 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16909 fixed_params->ndp_app_info_len, 16910 event->num_ndp_app_info); 16911 return QDF_STATUS_E_INVAL; 16912 } 16913 16914 WMI_LOGD("ndp_app_info - %d bytes", 16915 fixed_params->ndp_app_info_len); 16916 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16917 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16918 16919 if (fixed_params->ndp_cfg_len > 16920 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16921 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16922 __func__, fixed_params->ndp_cfg_len); 16923 return QDF_STATUS_E_INVAL; 16924 } 16925 16926 total_array_len = fixed_params->ndp_cfg_len + 16927 sizeof(*fixed_params); 16928 16929 if (fixed_params->ndp_app_info_len > 16930 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16931 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16932 __func__, fixed_params->ndp_app_info_len); 16933 return QDF_STATUS_E_INVAL; 16934 } 16935 16936 rsp->vdev = 16937 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16938 fixed_params->vdev_id, 16939 WLAN_NAN_ID); 16940 if (!rsp->vdev) { 16941 WMI_LOGE("vdev is null"); 16942 return QDF_STATUS_E_INVAL; 16943 } 16944 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16945 rsp->rsp_code = fixed_params->rsp_code; 16946 rsp->reason_code = fixed_params->reason_code; 16947 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 16948 rsp->num_channels = fixed_params->num_ndp_channels; 16949 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16950 rsp->peer_ndi_mac_addr.bytes); 16951 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16952 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16953 rsp->ndp_info.ndp_app_info_len); 16954 16955 if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 16956 WMI_LOGE(FL("too many channels")); 16957 rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS; 16958 } 16959 16960 for (i = 0; i < rsp->num_channels; i++) { 16961 rsp->ch[i].channel = event->ndp_channel_list[i].mhz; 16962 rsp->ch[i].nss = event->nss_list[i]; 16963 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]); 16964 rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 16965 ch_mode); 16966 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 16967 rsp->ch[i].channel, 16968 rsp->ch[i].ch_width, 16969 rsp->ch[i].nss); 16970 } 16971 16972 if (event->ndp_transport_ip_param && 16973 event->num_ndp_transport_ip_param) { 16974 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16975 rsp->is_ipv6_addr_present = true; 16976 qdf_mem_copy(rsp->ipv6_addr, 16977 event->ndp_transport_ip_param->ipv6_intf_addr, 16978 WMI_NDP_IPV6_INTF_ADDR_LEN); 16979 } 16980 16981 if (event->ndp_transport_ip_param->trans_port_present) { 16982 rsp->is_port_present = true; 16983 rsp->port = 16984 event->ndp_transport_ip_param->transport_port; 16985 } 16986 16987 if (event->ndp_transport_ip_param->trans_proto_present) { 16988 rsp->is_protocol_present = true; 16989 rsp->protocol = 16990 event->ndp_transport_ip_param->transport_protocol; 16991 } 16992 } 16993 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16994 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16995 WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present); 16996 WMI_LOGD(FL("protocol: %d present: %d"), 16997 rsp->protocol, rsp->is_protocol_present); 16998 16999 return QDF_STATUS_SUCCESS; 17000 } 17001 17002 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 17003 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 17004 { 17005 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17006 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17007 17008 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17009 fixed_params = event->fixed_param; 17010 17011 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", 17012 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17013 rsp->peer_mac_addr.bytes, rsp->transaction_id, 17014 rsp->status, rsp->reason, rsp->create_peer); 17015 17016 rsp->vdev = 17017 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17018 fixed_params->vdev_id, 17019 WLAN_NAN_ID); 17020 if (!rsp->vdev) { 17021 WMI_LOGE("vdev is null"); 17022 return QDF_STATUS_E_INVAL; 17023 } 17024 rsp->transaction_id = fixed_params->transaction_id; 17025 rsp->reason = fixed_params->reason_code; 17026 rsp->status = fixed_params->rsp_status; 17027 rsp->create_peer = fixed_params->create_peer; 17028 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17029 rsp->peer_mac_addr.bytes); 17030 17031 return QDF_STATUS_SUCCESS; 17032 } 17033 17034 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17035 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 17036 { 17037 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17038 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17039 17040 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17041 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17042 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 17043 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17044 fixed_params->rsp_status, fixed_params->reason_code); 17045 17046 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17047 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17048 if (!rsp->vdev) { 17049 WMI_LOGE("vdev is null"); 17050 return QDF_STATUS_E_INVAL; 17051 } 17052 rsp->transaction_id = fixed_params->transaction_id; 17053 rsp->reason = fixed_params->reason_code; 17054 rsp->status = fixed_params->rsp_status; 17055 17056 return QDF_STATUS_SUCCESS; 17057 } 17058 17059 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17060 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17061 { 17062 uint32_t i, buf_size; 17063 wmi_ndp_end_indication *ind; 17064 struct qdf_mac_addr peer_addr; 17065 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17066 17067 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17068 ind = event->ndp_end_indication_list; 17069 17070 if (event->num_ndp_end_indication_list == 0) { 17071 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17072 return QDF_STATUS_E_INVAL; 17073 } 17074 17075 WMI_LOGD("number of ndp instances = %d", 17076 event->num_ndp_end_indication_list); 17077 17078 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17079 sizeof((*rsp)->ndp_map[0]))) { 17080 WMI_LOGE("num_ndp_end_ind_list %d too large", 17081 event->num_ndp_end_indication_list); 17082 return QDF_STATUS_E_INVAL; 17083 } 17084 17085 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17086 sizeof((*rsp)->ndp_map[0]); 17087 *rsp = qdf_mem_malloc(buf_size); 17088 if (!(*rsp)) { 17089 WMI_LOGE("Failed to allocate memory"); 17090 return QDF_STATUS_E_NOMEM; 17091 } 17092 17093 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17094 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17095 if (!(*rsp)->vdev) { 17096 WMI_LOGE("vdev is null"); 17097 qdf_mem_free(*rsp); 17098 *rsp = NULL; 17099 return QDF_STATUS_E_INVAL; 17100 } 17101 17102 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17103 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17104 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17105 peer_addr.bytes); 17106 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17107 i, ind[i].type, ind[i].reason_code, 17108 ind[i].ndp_instance_id, 17109 ind[i].num_active_ndps_on_peer); 17110 /* Add each instance entry to the list */ 17111 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17112 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17113 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17114 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17115 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17116 ind[i].num_active_ndps_on_peer; 17117 (*rsp)->ndp_map[i].type = ind[i].type; 17118 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17119 } 17120 17121 return QDF_STATUS_SUCCESS; 17122 } 17123 17124 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 17125 uint8_t *data, struct nan_datapath_sch_update_event *ind) 17126 { 17127 uint8_t i; 17128 WMI_HOST_WLAN_PHY_MODE ch_mode; 17129 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 17130 wmi_ndl_schedule_update_fixed_param *fixed_params; 17131 17132 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 17133 fixed_params = event->fixed_param; 17134 17135 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 17136 fixed_params->flags, fixed_params->num_channels, 17137 fixed_params->num_ndp_instances); 17138 17139 ind->vdev = 17140 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17141 fixed_params->vdev_id, 17142 WLAN_NAN_ID); 17143 if (!ind->vdev) { 17144 WMI_LOGE("vdev is null"); 17145 return QDF_STATUS_E_INVAL; 17146 } 17147 17148 ind->flags = fixed_params->flags; 17149 ind->num_channels = fixed_params->num_channels; 17150 ind->num_ndp_instances = fixed_params->num_ndp_instances; 17151 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 17152 ind->peer_addr.bytes); 17153 17154 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 17155 WMI_LOGE(FL("uint32 overflow")); 17156 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 17157 return QDF_STATUS_E_INVAL; 17158 } 17159 17160 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 17161 sizeof(uint32_t) * ind->num_ndp_instances); 17162 17163 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 17164 WMI_LOGE(FL("too many channels")); 17165 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 17166 } 17167 for (i = 0; i < ind->num_channels; i++) { 17168 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 17169 ind->ch[i].nss = event->nss_list[i]; 17170 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 17171 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 17172 ch_mode); 17173 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 17174 ind->ch[i].channel, 17175 ind->ch[i].ch_width, 17176 ind->ch[i].nss); 17177 } 17178 17179 for (i = 0; i < fixed_params->num_ndp_instances; i++) 17180 WMI_LOGD(FL("instance_id[%d]: %d"), 17181 i, event->ndp_instance_list[i]); 17182 17183 return QDF_STATUS_SUCCESS; 17184 } 17185 17186 #endif 17187 17188 #ifdef QCA_SUPPORT_CP_STATS 17189 /** 17190 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17191 * @wmi_handle: wma handle 17192 * @evt_buf: event buffer 17193 * @out_buff: buffer to populated after stats extraction 17194 * 17195 * Return: status of operation 17196 */ 17197 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17198 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17199 { 17200 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17201 wmi_congestion_stats *congestion_stats; 17202 17203 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17204 congestion_stats = param_buf->congestion_stats; 17205 if (!congestion_stats) { 17206 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17207 return QDF_STATUS_E_INVAL; 17208 } 17209 17210 out_buff->vdev_id = congestion_stats->vdev_id; 17211 out_buff->congestion = congestion_stats->congestion; 17212 17213 WMI_LOGD("%s: cca stats event processed", __func__); 17214 return QDF_STATUS_SUCCESS; 17215 } 17216 #endif /* QCA_SUPPORT_CP_STATS */ 17217 17218 /** 17219 * save_service_bitmap_tlv() - save service bitmap 17220 * @wmi_handle: wmi handle 17221 * @param evt_buf: pointer to event buffer 17222 * @param bitmap_buf: bitmap buffer, for converged legacy support 17223 * 17224 * Return: QDF_STATUS 17225 */ 17226 static 17227 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17228 void *bitmap_buf) 17229 { 17230 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17231 struct wmi_soc *soc = wmi_handle->soc; 17232 17233 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17234 17235 /* If it is already allocated, use that buffer. This can happen 17236 * during target stop/start scenarios where host allocation is skipped. 17237 */ 17238 if (!soc->wmi_service_bitmap) { 17239 soc->wmi_service_bitmap = 17240 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17241 if (!soc->wmi_service_bitmap) { 17242 WMI_LOGE("Failed memory allocation for service bitmap"); 17243 return QDF_STATUS_E_NOMEM; 17244 } 17245 } 17246 17247 qdf_mem_copy(soc->wmi_service_bitmap, 17248 param_buf->wmi_service_bitmap, 17249 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17250 17251 if (bitmap_buf) 17252 qdf_mem_copy(bitmap_buf, 17253 param_buf->wmi_service_bitmap, 17254 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17255 17256 return QDF_STATUS_SUCCESS; 17257 } 17258 17259 /** 17260 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17261 * @wmi_handle: wmi handle 17262 * @param evt_buf: pointer to event buffer 17263 * @param bitmap_buf: bitmap buffer, for converged legacy support 17264 * 17265 * Return: QDF_STATUS 17266 */ 17267 static 17268 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17269 void *bitmap_buf) 17270 { 17271 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17272 wmi_service_available_event_fixed_param *ev; 17273 struct wmi_soc *soc = wmi_handle->soc; 17274 17275 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17276 17277 ev = param_buf->fixed_param; 17278 17279 /* If it is already allocated, use that buffer. This can happen 17280 * during target stop/start scenarios where host allocation is skipped. 17281 */ 17282 if (!soc->wmi_ext_service_bitmap) { 17283 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17284 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17285 if (!soc->wmi_ext_service_bitmap) { 17286 WMI_LOGE("Failed memory allocation for service bitmap"); 17287 return QDF_STATUS_E_NOMEM; 17288 } 17289 } 17290 17291 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17292 ev->wmi_service_segment_bitmap, 17293 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17294 17295 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17296 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17297 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17298 17299 if (bitmap_buf) 17300 qdf_mem_copy(bitmap_buf, 17301 soc->wmi_ext_service_bitmap, 17302 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17303 17304 return QDF_STATUS_SUCCESS; 17305 } 17306 /** 17307 * is_service_enabled_tlv() - Check if service enabled 17308 * @param wmi_handle: wmi handle 17309 * @param service_id: service identifier 17310 * 17311 * Return: 1 enabled, 0 disabled 17312 */ 17313 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17314 uint32_t service_id) 17315 { 17316 struct wmi_soc *soc = wmi_handle->soc; 17317 17318 if (!soc->wmi_service_bitmap) { 17319 WMI_LOGE("WMI service bit map is not saved yet\n"); 17320 return false; 17321 } 17322 17323 /* if wmi_service_enabled was received with extended bitmap, 17324 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17325 */ 17326 if (soc->wmi_ext_service_bitmap) 17327 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17328 soc->wmi_ext_service_bitmap, 17329 service_id); 17330 17331 if (service_id >= WMI_MAX_SERVICE) { 17332 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 17333 service_id); 17334 return false; 17335 } 17336 17337 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17338 service_id); 17339 } 17340 17341 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17342 struct wlan_psoc_target_capability_info *cap) 17343 { 17344 /* except LDPC all flags are common betwen legacy and here 17345 * also IBFEER is not defined for TLV 17346 */ 17347 cap->ht_cap_info |= ev_target_cap & ( 17348 WMI_HT_CAP_ENABLED 17349 | WMI_HT_CAP_HT20_SGI 17350 | WMI_HT_CAP_DYNAMIC_SMPS 17351 | WMI_HT_CAP_TX_STBC 17352 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17353 | WMI_HT_CAP_RX_STBC 17354 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17355 | WMI_HT_CAP_LDPC 17356 | WMI_HT_CAP_L_SIG_TXOP_PROT 17357 | WMI_HT_CAP_MPDU_DENSITY 17358 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17359 | WMI_HT_CAP_HT40_SGI); 17360 if (ev_target_cap & WMI_HT_CAP_LDPC) 17361 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17362 WMI_HOST_HT_CAP_TX_LDPC; 17363 } 17364 /** 17365 * extract_service_ready_tlv() - extract service ready event 17366 * @wmi_handle: wmi handle 17367 * @param evt_buf: pointer to received event buffer 17368 * @param cap: pointer to hold target capability information extracted from even 17369 * 17370 * Return: QDF_STATUS_SUCCESS for success or error code 17371 */ 17372 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17373 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17374 { 17375 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17376 wmi_service_ready_event_fixed_param *ev; 17377 17378 17379 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17380 17381 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17382 if (!ev) { 17383 qdf_print("%s: wmi_buf_alloc failed", __func__); 17384 return QDF_STATUS_E_FAILURE; 17385 } 17386 17387 cap->phy_capability = ev->phy_capability; 17388 cap->max_frag_entry = ev->max_frag_entry; 17389 cap->num_rf_chains = ev->num_rf_chains; 17390 copy_ht_cap_info(ev->ht_cap_info, cap); 17391 cap->vht_cap_info = ev->vht_cap_info; 17392 cap->vht_supp_mcs = ev->vht_supp_mcs; 17393 cap->hw_min_tx_power = ev->hw_min_tx_power; 17394 cap->hw_max_tx_power = ev->hw_max_tx_power; 17395 cap->sys_cap_info = ev->sys_cap_info; 17396 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17397 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17398 cap->max_num_scan_channels = ev->max_num_scan_channels; 17399 cap->max_supported_macs = ev->max_supported_macs; 17400 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17401 cap->txrx_chainmask = ev->txrx_chainmask; 17402 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17403 cap->num_msdu_desc = ev->num_msdu_desc; 17404 cap->fw_version = ev->fw_build_vers; 17405 /* fw_version_1 is not available in TLV. */ 17406 cap->fw_version_1 = 0; 17407 17408 return QDF_STATUS_SUCCESS; 17409 } 17410 17411 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 17412 * to host internal WMI_HOST_REGDMN_MODE values. 17413 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 17414 * host currently. Add this in the future if required. 17415 * 11AX (Phase II) : 11ax related values are not currently 17416 * advertised separately by FW. As part of phase II regulatory bring-up, 17417 * finalize the advertisement mechanism. 17418 * @target_wireless_mode: target wireless mode received in message 17419 * 17420 * Return: returns the host internal wireless mode. 17421 */ 17422 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 17423 { 17424 17425 uint32_t wireless_modes = 0; 17426 17427 if (target_wireless_mode & REGDMN_MODE_11A) 17428 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 17429 17430 if (target_wireless_mode & REGDMN_MODE_TURBO) 17431 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 17432 17433 if (target_wireless_mode & REGDMN_MODE_11B) 17434 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 17435 17436 if (target_wireless_mode & REGDMN_MODE_PUREG) 17437 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 17438 17439 if (target_wireless_mode & REGDMN_MODE_11G) 17440 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 17441 17442 if (target_wireless_mode & REGDMN_MODE_108G) 17443 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 17444 17445 if (target_wireless_mode & REGDMN_MODE_108A) 17446 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 17447 17448 if (target_wireless_mode & REGDMN_MODE_XR) 17449 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 17450 17451 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 17452 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 17453 17454 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 17455 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 17456 17457 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 17458 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 17459 17460 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 17461 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 17462 17463 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 17464 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 17465 17466 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 17467 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 17468 17469 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 17470 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 17471 17472 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 17473 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 17474 17475 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 17476 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 17477 17478 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 17479 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 17480 17481 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 17482 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 17483 17484 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 17485 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 17486 17487 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 17488 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 17489 17490 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 17491 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 17492 17493 return wireless_modes; 17494 } 17495 17496 /** 17497 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 17498 * @wmi_handle: wmi handle 17499 * @param evt_buf: Pointer to event buffer 17500 * @param cap: pointer to hold HAL reg capabilities 17501 * 17502 * Return: QDF_STATUS_SUCCESS for success or error code 17503 */ 17504 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 17505 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 17506 { 17507 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17508 17509 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17510 17511 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 17512 sizeof(uint32_t)), 17513 sizeof(struct wlan_psoc_hal_reg_capability)); 17514 17515 cap->wireless_modes = convert_wireless_modes_tlv( 17516 param_buf->hal_reg_capabilities->wireless_modes); 17517 17518 return QDF_STATUS_SUCCESS; 17519 } 17520 17521 /** 17522 * extract_host_mem_req_tlv() - Extract host memory request event 17523 * @wmi_handle: wmi handle 17524 * @param evt_buf: pointer to event buffer 17525 * @param num_entries: pointer to hold number of entries requested 17526 * 17527 * Return: Number of entries requested 17528 */ 17529 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 17530 void *evt_buf, uint8_t *num_entries) 17531 { 17532 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17533 wmi_service_ready_event_fixed_param *ev; 17534 17535 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17536 17537 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17538 if (!ev) { 17539 qdf_print("%s: wmi_buf_alloc failed", __func__); 17540 return NULL; 17541 } 17542 17543 *num_entries = ev->num_mem_reqs; 17544 17545 return (host_mem_req *)param_buf->mem_reqs; 17546 } 17547 17548 /** 17549 * save_fw_version_in_service_ready_tlv() - Save fw version in service 17550 * ready function 17551 * @wmi_handle: wmi handle 17552 * @param evt_buf: pointer to event buffer 17553 * 17554 * Return: QDF_STATUS_SUCCESS for success or error code 17555 */ 17556 static QDF_STATUS 17557 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 17558 { 17559 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17560 wmi_service_ready_event_fixed_param *ev; 17561 17562 17563 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17564 17565 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17566 if (!ev) { 17567 qdf_print("%s: wmi_buf_alloc failed", __func__); 17568 return QDF_STATUS_E_FAILURE; 17569 } 17570 17571 /*Save fw version from service ready message */ 17572 /*This will be used while sending INIT message */ 17573 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 17574 sizeof(wmi_handle->fw_abi_version)); 17575 17576 return QDF_STATUS_SUCCESS; 17577 } 17578 17579 /** 17580 * ready_extract_init_status_tlv() - Extract init status from ready event 17581 * @wmi_handle: wmi handle 17582 * @param evt_buf: Pointer to event buffer 17583 * 17584 * Return: ready status 17585 */ 17586 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 17587 void *evt_buf) 17588 { 17589 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17590 wmi_ready_event_fixed_param *ev = NULL; 17591 17592 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17593 ev = param_buf->fixed_param; 17594 17595 qdf_print("%s:%d", __func__, ev->status); 17596 17597 return ev->status; 17598 } 17599 17600 /** 17601 * ready_extract_mac_addr_tlv() - extract mac address from ready event 17602 * @wmi_handle: wmi handle 17603 * @param evt_buf: pointer to event buffer 17604 * @param macaddr: Pointer to hold MAC address 17605 * 17606 * Return: QDF_STATUS_SUCCESS for success or error code 17607 */ 17608 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 17609 void *evt_buf, uint8_t *macaddr) 17610 { 17611 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17612 wmi_ready_event_fixed_param *ev = NULL; 17613 17614 17615 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17616 ev = param_buf->fixed_param; 17617 17618 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 17619 17620 return QDF_STATUS_SUCCESS; 17621 } 17622 17623 /** 17624 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 17625 * @wmi_handle: wmi handle 17626 * @param evt_buf: pointer to event buffer 17627 * @param macaddr: Pointer to hold number of MAC addresses 17628 * 17629 * Return: Pointer to addr list 17630 */ 17631 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 17632 void *evt_buf, uint8_t *num_mac) 17633 { 17634 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17635 wmi_ready_event_fixed_param *ev = NULL; 17636 17637 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17638 ev = param_buf->fixed_param; 17639 17640 *num_mac = ev->num_extra_mac_addr; 17641 17642 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 17643 } 17644 17645 /** 17646 * extract_ready_params_tlv() - Extract data from ready event apart from 17647 * status, macaddr and version. 17648 * @wmi_handle: Pointer to WMI handle. 17649 * @evt_buf: Pointer to Ready event buffer. 17650 * @ev_param: Pointer to host defined struct to copy the data from event. 17651 * 17652 * Return: QDF_STATUS_SUCCESS on success. 17653 */ 17654 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 17655 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 17656 { 17657 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17658 wmi_ready_event_fixed_param *ev = NULL; 17659 17660 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17661 ev = param_buf->fixed_param; 17662 17663 ev_param->status = ev->status; 17664 ev_param->num_dscp_table = ev->num_dscp_table; 17665 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 17666 ev_param->num_total_peer = ev->num_total_peers; 17667 ev_param->num_extra_peer = ev->num_extra_peers; 17668 /* Agile_cap in ready event is not supported in TLV target */ 17669 ev_param->agile_capability = false; 17670 17671 return QDF_STATUS_SUCCESS; 17672 } 17673 17674 /** 17675 * extract_dbglog_data_len_tlv() - extract debuglog data length 17676 * @wmi_handle: wmi handle 17677 * @param evt_buf: pointer to event buffer 17678 * 17679 * Return: length 17680 */ 17681 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 17682 void *evt_buf, uint32_t *len) 17683 { 17684 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 17685 17686 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 17687 17688 *len = param_buf->num_bufp; 17689 17690 return param_buf->bufp; 17691 } 17692 17693 /** 17694 * extract_vdev_start_resp_tlv() - extract vdev start response 17695 * @wmi_handle: wmi handle 17696 * @param evt_buf: pointer to event buffer 17697 * @param vdev_rsp: Pointer to hold vdev response 17698 * 17699 * Return: QDF_STATUS_SUCCESS for success or error code 17700 */ 17701 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 17702 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 17703 { 17704 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 17705 wmi_vdev_start_response_event_fixed_param *ev; 17706 17707 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 17708 if (!param_buf) { 17709 qdf_print("Invalid start response event buffer"); 17710 return QDF_STATUS_E_INVAL; 17711 } 17712 17713 ev = param_buf->fixed_param; 17714 if (!ev) { 17715 qdf_print("Invalid start response event buffer"); 17716 return QDF_STATUS_E_INVAL; 17717 } 17718 17719 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 17720 17721 vdev_rsp->vdev_id = ev->vdev_id; 17722 vdev_rsp->requestor_id = ev->requestor_id; 17723 switch (ev->resp_type) { 17724 case WMI_VDEV_START_RESP_EVENT: 17725 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 17726 break; 17727 case WMI_VDEV_RESTART_RESP_EVENT: 17728 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 17729 break; 17730 default: 17731 qdf_print("Invalid start response event buffer"); 17732 break; 17733 }; 17734 vdev_rsp->status = ev->status; 17735 vdev_rsp->chain_mask = ev->chain_mask; 17736 vdev_rsp->smps_mode = ev->smps_mode; 17737 vdev_rsp->mac_id = ev->mac_id; 17738 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 17739 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 17740 17741 return QDF_STATUS_SUCCESS; 17742 } 17743 17744 /** 17745 * extract_vdev_delete_resp_tlv() - extract vdev delete response 17746 * @wmi_handle: wmi handle 17747 * @param evt_buf: pointer to event buffer 17748 * @param delete_rsp: Pointer to hold vdev delete response 17749 * 17750 * Return: QDF_STATUS_SUCCESS for success or error code 17751 */ 17752 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 17753 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 17754 { 17755 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 17756 wmi_vdev_delete_resp_event_fixed_param *ev; 17757 17758 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 17759 if (!param_buf) { 17760 WMI_LOGE("Invalid vdev delete response event buffer\n"); 17761 return QDF_STATUS_E_INVAL; 17762 } 17763 17764 ev = param_buf->fixed_param; 17765 if (!ev) { 17766 WMI_LOGE("Invalid vdev delete response event\n"); 17767 return QDF_STATUS_E_INVAL; 17768 } 17769 17770 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 17771 delete_rsp->vdev_id = ev->vdev_id; 17772 17773 return QDF_STATUS_SUCCESS; 17774 } 17775 17776 17777 /** 17778 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 17779 * @wmi_handle: wmi handle 17780 * @param evt_buf: pointer to event buffer 17781 * @param num_vdevs: Pointer to hold num vdev 17782 * 17783 * Return: QDF_STATUS_SUCCESS for success or error code 17784 */ 17785 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17786 void *evt_buf, uint32_t *num_vdevs) 17787 { 17788 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17789 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17790 uint32_t vdev_map; 17791 17792 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 17793 if (!param_buf) { 17794 qdf_print("Invalid tbtt update ext event buffer"); 17795 return QDF_STATUS_E_INVAL; 17796 } 17797 tbtt_offset_event = param_buf->fixed_param; 17798 vdev_map = tbtt_offset_event->vdev_map; 17799 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 17800 17801 return QDF_STATUS_SUCCESS; 17802 } 17803 17804 /** 17805 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 17806 * @wmi_handle: wmi handle 17807 * @param evt_buf: pointer to event buffer 17808 * @param num_vdevs: Pointer to hold num vdev 17809 * 17810 * Return: QDF_STATUS_SUCCESS for success or error code 17811 */ 17812 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17813 void *evt_buf, uint32_t *num_vdevs) 17814 { 17815 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17816 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 17817 17818 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17819 if (!param_buf) { 17820 qdf_print("Invalid tbtt update ext event buffer"); 17821 return QDF_STATUS_E_INVAL; 17822 } 17823 tbtt_offset_ext_event = param_buf->fixed_param; 17824 17825 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 17826 17827 return QDF_STATUS_SUCCESS; 17828 } 17829 17830 /** 17831 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 17832 * @wmi_handle: wmi handle 17833 * @param evt_buf: pointer to event buffer 17834 * @param idx: Index referring to a vdev 17835 * @param tbtt_param: Pointer to tbttoffset event param 17836 * 17837 * Return: QDF_STATUS_SUCCESS for success or error code 17838 */ 17839 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 17840 void *evt_buf, uint8_t idx, 17841 struct tbttoffset_params *tbtt_param) 17842 { 17843 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17844 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17845 uint32_t vdev_map; 17846 17847 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 17848 if (!param_buf) { 17849 qdf_print("Invalid tbtt update event buffer"); 17850 return QDF_STATUS_E_INVAL; 17851 } 17852 17853 tbtt_offset_event = param_buf->fixed_param; 17854 vdev_map = tbtt_offset_event->vdev_map; 17855 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 17856 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 17857 return QDF_STATUS_E_INVAL; 17858 tbtt_param->tbttoffset = 17859 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 17860 17861 return QDF_STATUS_SUCCESS; 17862 } 17863 17864 /** 17865 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 17866 * @wmi_handle: wmi handle 17867 * @param evt_buf: pointer to event buffer 17868 * @param idx: Index referring to a vdev 17869 * @param tbtt_param: Pointer to tbttoffset event param 17870 * 17871 * Return: QDF_STATUS_SUCCESS for success or error code 17872 */ 17873 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 17874 void *evt_buf, uint8_t idx, 17875 struct tbttoffset_params *tbtt_param) 17876 { 17877 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17878 wmi_tbtt_offset_info *tbtt_offset_info; 17879 17880 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17881 if (!param_buf) { 17882 qdf_print("Invalid tbtt update event buffer"); 17883 return QDF_STATUS_E_INVAL; 17884 } 17885 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 17886 17887 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 17888 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 17889 17890 return QDF_STATUS_SUCCESS; 17891 } 17892 17893 /** 17894 * extract_mgmt_rx_params_tlv() - extract management rx params from event 17895 * @wmi_handle: wmi handle 17896 * @param evt_buf: pointer to event buffer 17897 * @param hdr: Pointer to hold header 17898 * @param bufp: Pointer to hold pointer to rx param buffer 17899 * 17900 * Return: QDF_STATUS_SUCCESS for success or error code 17901 */ 17902 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 17903 void *evt_buf, struct mgmt_rx_event_params *hdr, 17904 uint8_t **bufp) 17905 { 17906 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 17907 wmi_mgmt_rx_hdr *ev_hdr = NULL; 17908 int i; 17909 17910 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 17911 if (!param_tlvs) { 17912 WMI_LOGE("Get NULL point message from FW"); 17913 return QDF_STATUS_E_INVAL; 17914 } 17915 17916 ev_hdr = param_tlvs->hdr; 17917 if (!hdr) { 17918 WMI_LOGE("Rx event is NULL"); 17919 return QDF_STATUS_E_INVAL; 17920 } 17921 17922 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17923 ev_hdr->pdev_id); 17924 17925 hdr->channel = ev_hdr->channel; 17926 hdr->snr = ev_hdr->snr; 17927 hdr->rate = ev_hdr->rate; 17928 hdr->phy_mode = ev_hdr->phy_mode; 17929 hdr->buf_len = ev_hdr->buf_len; 17930 hdr->status = ev_hdr->status; 17931 hdr->flags = ev_hdr->flags; 17932 hdr->rssi = ev_hdr->rssi; 17933 hdr->tsf_delta = ev_hdr->tsf_delta; 17934 for (i = 0; i < ATH_MAX_ANTENNA; i++) 17935 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 17936 17937 *bufp = param_tlvs->bufp; 17938 17939 return QDF_STATUS_SUCCESS; 17940 } 17941 17942 /** 17943 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 17944 * @wmi_handle: wmi handle 17945 * @param evt_buf: pointer to event buffer 17946 * @param vdev_id: Pointer to hold vdev identifier 17947 * 17948 * Return: QDF_STATUS_SUCCESS for success or error code 17949 */ 17950 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 17951 void *evt_buf, uint32_t *vdev_id) 17952 { 17953 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 17954 wmi_vdev_stopped_event_fixed_param *resp_event; 17955 17956 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 17957 if (!param_buf) { 17958 WMI_LOGE("Invalid event buffer"); 17959 return QDF_STATUS_E_INVAL; 17960 } 17961 resp_event = param_buf->fixed_param; 17962 *vdev_id = resp_event->vdev_id; 17963 17964 return QDF_STATUS_SUCCESS; 17965 } 17966 17967 /** 17968 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 17969 * @wmi_handle: wmi handle 17970 * @param evt_buf: pointer to event buffer 17971 * @param param: Pointer to hold roam param 17972 * 17973 * Return: QDF_STATUS_SUCCESS for success or error code 17974 */ 17975 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 17976 void *evt_buf, wmi_host_roam_event *param) 17977 { 17978 WMI_ROAM_EVENTID_param_tlvs *param_buf; 17979 wmi_roam_event_fixed_param *evt; 17980 17981 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 17982 if (!param_buf) { 17983 WMI_LOGE("Invalid roam event buffer"); 17984 return QDF_STATUS_E_INVAL; 17985 } 17986 17987 evt = param_buf->fixed_param; 17988 qdf_mem_zero(param, sizeof(*param)); 17989 17990 param->vdev_id = evt->vdev_id; 17991 param->reason = evt->reason; 17992 param->rssi = evt->rssi; 17993 17994 return QDF_STATUS_SUCCESS; 17995 } 17996 17997 /** 17998 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 17999 * @wmi_handle: wmi handle 18000 * @param evt_buf: pointer to event buffer 18001 * @param param: Pointer to hold vdev scan param 18002 * 18003 * Return: QDF_STATUS_SUCCESS for success or error code 18004 */ 18005 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18006 void *evt_buf, struct scan_event *param) 18007 { 18008 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18009 wmi_scan_event_fixed_param *evt = NULL; 18010 18011 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18012 evt = param_buf->fixed_param; 18013 18014 qdf_mem_zero(param, sizeof(*param)); 18015 18016 switch (evt->event) { 18017 case WMI_SCAN_EVENT_STARTED: 18018 param->type = SCAN_EVENT_TYPE_STARTED; 18019 break; 18020 case WMI_SCAN_EVENT_COMPLETED: 18021 param->type = SCAN_EVENT_TYPE_COMPLETED; 18022 break; 18023 case WMI_SCAN_EVENT_BSS_CHANNEL: 18024 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18025 break; 18026 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18027 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18028 break; 18029 case WMI_SCAN_EVENT_DEQUEUED: 18030 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18031 break; 18032 case WMI_SCAN_EVENT_PREEMPTED: 18033 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18034 break; 18035 case WMI_SCAN_EVENT_START_FAILED: 18036 param->type = SCAN_EVENT_TYPE_START_FAILED; 18037 break; 18038 case WMI_SCAN_EVENT_RESTARTED: 18039 param->type = SCAN_EVENT_TYPE_RESTARTED; 18040 break; 18041 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18042 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18043 break; 18044 case WMI_SCAN_EVENT_MAX: 18045 default: 18046 param->type = SCAN_EVENT_TYPE_MAX; 18047 break; 18048 }; 18049 18050 switch (evt->reason) { 18051 case WMI_SCAN_REASON_NONE: 18052 param->reason = SCAN_REASON_NONE; 18053 break; 18054 case WMI_SCAN_REASON_COMPLETED: 18055 param->reason = SCAN_REASON_COMPLETED; 18056 break; 18057 case WMI_SCAN_REASON_CANCELLED: 18058 param->reason = SCAN_REASON_CANCELLED; 18059 break; 18060 case WMI_SCAN_REASON_PREEMPTED: 18061 param->reason = SCAN_REASON_PREEMPTED; 18062 break; 18063 case WMI_SCAN_REASON_TIMEDOUT: 18064 param->reason = SCAN_REASON_TIMEDOUT; 18065 break; 18066 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18067 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18068 break; 18069 case WMI_SCAN_REASON_SUSPENDED: 18070 param->reason = SCAN_REASON_SUSPENDED; 18071 break; 18072 case WMI_SCAN_REASON_MAX: 18073 param->reason = SCAN_REASON_MAX; 18074 break; 18075 default: 18076 param->reason = SCAN_REASON_MAX; 18077 break; 18078 }; 18079 18080 param->chan_freq = evt->channel_freq; 18081 param->requester = evt->requestor; 18082 param->scan_id = evt->scan_id; 18083 param->vdev_id = evt->vdev_id; 18084 param->timestamp = evt->tsf_timestamp; 18085 18086 return QDF_STATUS_SUCCESS; 18087 } 18088 18089 #ifdef CONVERGED_TDLS_ENABLE 18090 /** 18091 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18092 * @wmi_handle: wmi handle 18093 * @param evt_buf: pointer to event buffer 18094 * @param param: Pointer to hold vdev tdls param 18095 * 18096 * Return: QDF_STATUS_SUCCESS for success or error code 18097 */ 18098 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18099 void *evt_buf, struct tdls_event_info *param) 18100 { 18101 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18102 wmi_tdls_peer_event_fixed_param *evt; 18103 18104 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18105 if (!param_buf) { 18106 WMI_LOGE("%s: NULL param_buf", __func__); 18107 return QDF_STATUS_E_NULL_VALUE; 18108 } 18109 18110 evt = param_buf->fixed_param; 18111 18112 qdf_mem_zero(param, sizeof(*param)); 18113 18114 param->vdev_id = evt->vdev_id; 18115 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18116 param->peermac.bytes); 18117 switch (evt->peer_status) { 18118 case WMI_TDLS_SHOULD_DISCOVER: 18119 param->message_type = TDLS_SHOULD_DISCOVER; 18120 break; 18121 case WMI_TDLS_SHOULD_TEARDOWN: 18122 param->message_type = TDLS_SHOULD_TEARDOWN; 18123 break; 18124 case WMI_TDLS_PEER_DISCONNECTED: 18125 param->message_type = TDLS_PEER_DISCONNECTED; 18126 break; 18127 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18128 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18129 break; 18130 default: 18131 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18132 __func__, evt->peer_status); 18133 return QDF_STATUS_E_INVAL; 18134 }; 18135 18136 switch (evt->peer_reason) { 18137 case WMI_TDLS_TEARDOWN_REASON_TX: 18138 param->peer_reason = TDLS_TEARDOWN_TX; 18139 break; 18140 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18141 param->peer_reason = TDLS_TEARDOWN_RSSI; 18142 break; 18143 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18144 param->peer_reason = TDLS_TEARDOWN_SCAN; 18145 break; 18146 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18147 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18148 break; 18149 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18150 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18151 break; 18152 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18153 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18154 break; 18155 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18156 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18157 break; 18158 case WMI_TDLS_ENTER_BUF_STA: 18159 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18160 break; 18161 case WMI_TDLS_EXIT_BUF_STA: 18162 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18163 break; 18164 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18165 param->peer_reason = TDLS_ENTER_BT_BUSY; 18166 break; 18167 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18168 param->peer_reason = TDLS_EXIT_BT_BUSY; 18169 break; 18170 case WMI_TDLS_SCAN_STARTED_EVENT: 18171 param->peer_reason = TDLS_SCAN_STARTED; 18172 break; 18173 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18174 param->peer_reason = TDLS_SCAN_COMPLETED; 18175 break; 18176 18177 default: 18178 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18179 __func__, evt->peer_reason, evt->peer_status); 18180 return QDF_STATUS_E_INVAL; 18181 }; 18182 18183 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18184 __func__, param->peermac.bytes, param->message_type, 18185 param->peer_reason, param->vdev_id); 18186 18187 return QDF_STATUS_SUCCESS; 18188 } 18189 #endif 18190 18191 /** 18192 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18193 * @wmi_handle: wmi handle 18194 * @param evt_buf: pointer to event buffer 18195 * @param param: Pointer to hold MGMT TX completion params 18196 * 18197 * Return: QDF_STATUS_SUCCESS for success or error code 18198 */ 18199 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18200 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18201 { 18202 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18203 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18204 18205 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18206 evt_buf; 18207 if (!param_buf) { 18208 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18209 return QDF_STATUS_E_INVAL; 18210 } 18211 cmpl_params = param_buf->fixed_param; 18212 18213 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18214 cmpl_params->pdev_id); 18215 param->desc_id = cmpl_params->desc_id; 18216 param->status = cmpl_params->status; 18217 param->ppdu_id = cmpl_params->ppdu_id; 18218 18219 return QDF_STATUS_SUCCESS; 18220 } 18221 18222 /** 18223 * extract_offchan_data_tx_compl_param_tlv() - 18224 * extract Offchan data tx completion event params 18225 * @wmi_handle: wmi handle 18226 * @param evt_buf: pointer to event buffer 18227 * @param param: Pointer to hold offchan data TX completion params 18228 * 18229 * Return: QDF_STATUS_SUCCESS for success or error code 18230 */ 18231 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18232 wmi_unified_t wmi_handle, void *evt_buf, 18233 struct wmi_host_offchan_data_tx_compl_event *param) 18234 { 18235 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18236 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18237 18238 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18239 evt_buf; 18240 if (!param_buf) { 18241 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18242 return QDF_STATUS_E_INVAL; 18243 } 18244 cmpl_params = param_buf->fixed_param; 18245 18246 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18247 cmpl_params->pdev_id); 18248 param->desc_id = cmpl_params->desc_id; 18249 param->status = cmpl_params->status; 18250 18251 return QDF_STATUS_SUCCESS; 18252 } 18253 18254 /** 18255 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18256 * status tlv 18257 * @wmi_handle: wmi handle 18258 * @param evt_buf: pointer to event buffer 18259 * @param param: Pointer to hold csa switch count status event param 18260 * 18261 * Return: QDF_STATUS_SUCCESS for success or error code 18262 */ 18263 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18264 wmi_unified_t wmi_handle, 18265 void *evt_buf, 18266 struct pdev_csa_switch_count_status *param) 18267 { 18268 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18269 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18270 18271 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18272 evt_buf; 18273 if (!param_buf) { 18274 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18275 return QDF_STATUS_E_INVAL; 18276 } 18277 18278 csa_status = param_buf->fixed_param; 18279 18280 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18281 csa_status->pdev_id); 18282 param->current_switch_count = csa_status->current_switch_count; 18283 param->num_vdevs = csa_status->num_vdevs; 18284 param->vdev_ids = param_buf->vdev_ids; 18285 18286 return QDF_STATUS_SUCCESS; 18287 } 18288 18289 /** 18290 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18291 * param from event 18292 * @wmi_handle: wmi handle 18293 * @param evt_buf: pointer to event buffer 18294 * @param param: Pointer to hold tpc configuration 18295 * 18296 * Return: 0 for success or error code 18297 */ 18298 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18299 void *evt_buf, 18300 wmi_host_pdev_tpc_config_event *param) 18301 { 18302 wmi_pdev_tpc_config_event_fixed_param *event = 18303 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18304 18305 if (!event) { 18306 WMI_LOGE("Invalid event buffer"); 18307 return QDF_STATUS_E_INVAL; 18308 } 18309 18310 param->pdev_id = event->pdev_id; 18311 param->regDomain = event->regDomain; 18312 param->chanFreq = event->chanFreq; 18313 param->phyMode = event->phyMode; 18314 param->twiceAntennaReduction = event->twiceAntennaReduction; 18315 param->twiceAntennaGain = event->twiceAntennaGain; 18316 param->twiceMaxRDPower = event->twiceMaxRDPower; 18317 param->powerLimit = event->powerLimit; 18318 param->rateMax = event->rateMax; 18319 param->numTxChain = event->numTxChain; 18320 param->ctl = event->ctl; 18321 param->flags = event->flags; 18322 18323 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18324 sizeof(param->maxRegAllowedPower)); 18325 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18326 event->maxRegAllowedPowerAGCDD, 18327 sizeof(param->maxRegAllowedPowerAGCDD)); 18328 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18329 event->maxRegAllowedPowerAGSTBC, 18330 sizeof(param->maxRegAllowedPowerAGSTBC)); 18331 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18332 event->maxRegAllowedPowerAGTXBF, 18333 sizeof(param->maxRegAllowedPowerAGTXBF)); 18334 WMI_LOGD("%s:extract success", __func__); 18335 18336 return QDF_STATUS_SUCCESS; 18337 } 18338 18339 /** 18340 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18341 * @wmi_handle: wmi handle 18342 * @param evt_buf: pointer to event buffer 18343 * @param num_vdevs: Pointer to hold num vdevs 18344 * 18345 * Return: QDF_STATUS_SUCCESS for success or error code 18346 */ 18347 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18348 void *evt_buf, uint32_t *num_vdevs) 18349 { 18350 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18351 wmi_host_swba_event_fixed_param *swba_event; 18352 uint32_t vdev_map; 18353 18354 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18355 if (!param_buf) { 18356 WMI_LOGE("Invalid swba event buffer"); 18357 return QDF_STATUS_E_INVAL; 18358 } 18359 18360 swba_event = param_buf->fixed_param; 18361 *num_vdevs = swba_event->num_vdevs; 18362 if (!(*num_vdevs)) { 18363 vdev_map = swba_event->vdev_map; 18364 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18365 } 18366 18367 return QDF_STATUS_SUCCESS; 18368 } 18369 18370 /** 18371 * extract_swba_tim_info_tlv() - extract swba tim info from event 18372 * @wmi_handle: wmi handle 18373 * @param evt_buf: pointer to event buffer 18374 * @param idx: Index to bcn info 18375 * @param tim_info: Pointer to hold tim info 18376 * 18377 * Return: QDF_STATUS_SUCCESS for success or error code 18378 */ 18379 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18380 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18381 { 18382 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18383 wmi_tim_info *tim_info_ev; 18384 18385 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18386 if (!param_buf) { 18387 WMI_LOGE("Invalid swba event buffer"); 18388 return QDF_STATUS_E_INVAL; 18389 } 18390 18391 tim_info_ev = ¶m_buf->tim_info[idx]; 18392 18393 tim_info->tim_len = tim_info_ev->tim_len; 18394 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18395 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18396 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18397 tim_info->tim_changed = tim_info_ev->tim_changed; 18398 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18399 tim_info->vdev_id = tim_info_ev->vdev_id; 18400 18401 return QDF_STATUS_SUCCESS; 18402 } 18403 18404 /** 18405 * extract_swba_noa_info_tlv() - extract swba NoA information from event 18406 * @wmi_handle: wmi handle 18407 * @param evt_buf: pointer to event buffer 18408 * @param idx: Index to bcn info 18409 * @param p2p_desc: Pointer to hold p2p NoA info 18410 * 18411 * Return: QDF_STATUS_SUCCESS for success or error code 18412 */ 18413 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 18414 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 18415 { 18416 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18417 wmi_p2p_noa_info *p2p_noa_info; 18418 uint8_t i = 0; 18419 18420 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18421 if (!param_buf) { 18422 WMI_LOGE("Invalid swba event buffer"); 18423 return QDF_STATUS_E_INVAL; 18424 } 18425 18426 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 18427 18428 p2p_desc->modified = false; 18429 p2p_desc->num_descriptors = 0; 18430 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 18431 p2p_desc->modified = true; 18432 p2p_desc->index = 18433 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 18434 p2p_desc->oppPS = 18435 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 18436 p2p_desc->ctwindow = 18437 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 18438 p2p_desc->num_descriptors = 18439 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 18440 (p2p_noa_info); 18441 for (i = 0; i < p2p_desc->num_descriptors; i++) { 18442 p2p_desc->noa_descriptors[i].type_count = 18443 (uint8_t) p2p_noa_info->noa_descriptors[i]. 18444 type_count; 18445 p2p_desc->noa_descriptors[i].duration = 18446 p2p_noa_info->noa_descriptors[i].duration; 18447 p2p_desc->noa_descriptors[i].interval = 18448 p2p_noa_info->noa_descriptors[i].interval; 18449 p2p_desc->noa_descriptors[i].start_time = 18450 p2p_noa_info->noa_descriptors[i].start_time; 18451 } 18452 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 18453 } 18454 18455 return QDF_STATUS_SUCCESS; 18456 } 18457 18458 #ifdef CONVERGED_P2P_ENABLE 18459 /** 18460 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 18461 * @wmi_handle: wmi handle 18462 * @param evt_buf: pointer to event buffer 18463 * @param param: Pointer to hold p2p noa info 18464 * 18465 * Return: QDF_STATUS_SUCCESS for success or error code 18466 */ 18467 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 18468 wmi_unified_t wmi_handle, void *evt_buf, 18469 struct p2p_noa_info *param) 18470 { 18471 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 18472 wmi_p2p_noa_event_fixed_param *fixed_param; 18473 uint8_t i; 18474 wmi_p2p_noa_info *wmi_noa_info; 18475 uint8_t *buf_ptr; 18476 uint32_t descriptors; 18477 18478 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 18479 if (!param_tlvs) { 18480 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 18481 return QDF_STATUS_E_INVAL; 18482 } 18483 18484 if (!param) { 18485 WMI_LOGE("noa information param is null"); 18486 return QDF_STATUS_E_INVAL; 18487 } 18488 18489 fixed_param = param_tlvs->fixed_param; 18490 buf_ptr = (uint8_t *) fixed_param; 18491 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 18492 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 18493 18494 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 18495 WMI_LOGE("%s: noa attr is not modified", __func__); 18496 return QDF_STATUS_E_INVAL; 18497 } 18498 18499 param->vdev_id = fixed_param->vdev_id; 18500 param->index = 18501 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 18502 param->opps_ps = 18503 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 18504 param->ct_window = 18505 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 18506 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 18507 param->num_desc = (uint8_t) descriptors; 18508 18509 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 18510 param->index, param->opps_ps, param->ct_window, 18511 param->num_desc); 18512 for (i = 0; i < param->num_desc; i++) { 18513 param->noa_desc[i].type_count = 18514 (uint8_t) wmi_noa_info->noa_descriptors[i]. 18515 type_count; 18516 param->noa_desc[i].duration = 18517 wmi_noa_info->noa_descriptors[i].duration; 18518 param->noa_desc[i].interval = 18519 wmi_noa_info->noa_descriptors[i].interval; 18520 param->noa_desc[i].start_time = 18521 wmi_noa_info->noa_descriptors[i].start_time; 18522 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 18523 __func__, i, param->noa_desc[i].type_count, 18524 param->noa_desc[i].duration, 18525 param->noa_desc[i].interval, 18526 param->noa_desc[i].start_time); 18527 } 18528 18529 return QDF_STATUS_SUCCESS; 18530 } 18531 18532 /** 18533 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 18534 * information from event 18535 * @wmi_handle: wmi handle 18536 * @param evt_buf: pointer to event buffer 18537 * @param param: Pointer to hold p2p lo stop event information 18538 * 18539 * Return: QDF_STATUS_SUCCESS for success or error code 18540 */ 18541 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 18542 wmi_unified_t wmi_handle, void *evt_buf, 18543 struct p2p_lo_event *param) 18544 { 18545 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 18546 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 18547 18548 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 18549 evt_buf; 18550 if (!param_tlvs) { 18551 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 18552 return QDF_STATUS_E_INVAL; 18553 } 18554 18555 if (!param) { 18556 WMI_LOGE("lo stop event param is null"); 18557 return QDF_STATUS_E_INVAL; 18558 } 18559 18560 lo_param = param_tlvs->fixed_param; 18561 param->vdev_id = lo_param->vdev_id; 18562 param->reason_code = lo_param->reason; 18563 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 18564 param->vdev_id, param->reason_code); 18565 18566 return QDF_STATUS_SUCCESS; 18567 } 18568 #endif /* End of CONVERGED_P2P_ENABLE */ 18569 18570 /** 18571 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 18572 * @wmi_handle: wmi handle 18573 * @param evt_buf: pointer to event buffer 18574 * @param ev: Pointer to hold peer param 18575 * 18576 * Return: QDF_STATUS_SUCCESS for success or error code 18577 */ 18578 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 18579 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 18580 { 18581 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 18582 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 18583 18584 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 18585 kickout_event = param_buf->fixed_param; 18586 18587 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 18588 ev->peer_macaddr); 18589 18590 ev->reason = kickout_event->reason; 18591 ev->rssi = kickout_event->rssi; 18592 18593 return QDF_STATUS_SUCCESS; 18594 } 18595 18596 /** 18597 * extract_all_stats_counts_tlv() - extract all stats count from event 18598 * @wmi_handle: wmi handle 18599 * @param evt_buf: pointer to event buffer 18600 * @param stats_param: Pointer to hold stats count 18601 * 18602 * Return: QDF_STATUS_SUCCESS for success or error code 18603 */ 18604 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 18605 void *evt_buf, wmi_host_stats_event *stats_param) 18606 { 18607 wmi_stats_event_fixed_param *ev; 18608 wmi_per_chain_rssi_stats *rssi_event; 18609 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18610 18611 qdf_mem_zero(stats_param, sizeof(*stats_param)); 18612 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18613 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18614 rssi_event = param_buf->chain_stats; 18615 if (!ev) { 18616 WMI_LOGE("%s: event fixed param NULL\n", __func__); 18617 return QDF_STATUS_E_FAILURE; 18618 } 18619 18620 switch (ev->stats_id) { 18621 case WMI_REQUEST_PEER_STAT: 18622 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 18623 break; 18624 18625 case WMI_REQUEST_AP_STAT: 18626 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 18627 break; 18628 18629 case WMI_REQUEST_PDEV_STAT: 18630 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 18631 break; 18632 18633 case WMI_REQUEST_VDEV_STAT: 18634 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 18635 break; 18636 18637 case WMI_REQUEST_BCNFLT_STAT: 18638 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 18639 break; 18640 18641 case WMI_REQUEST_VDEV_RATE_STAT: 18642 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 18643 break; 18644 18645 case WMI_REQUEST_BCN_STAT: 18646 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 18647 break; 18648 18649 default: 18650 stats_param->stats_id = 0; 18651 break; 18652 18653 } 18654 18655 stats_param->num_pdev_stats = ev->num_pdev_stats; 18656 stats_param->num_pdev_ext_stats = 0; 18657 stats_param->num_vdev_stats = ev->num_vdev_stats; 18658 stats_param->num_peer_stats = ev->num_peer_stats; 18659 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 18660 stats_param->num_chan_stats = ev->num_chan_stats; 18661 stats_param->num_bcn_stats = ev->num_bcn_stats; 18662 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18663 ev->pdev_id); 18664 18665 /* if chain_stats is not populated */ 18666 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 18667 return QDF_STATUS_SUCCESS; 18668 18669 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 18670 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 18671 return QDF_STATUS_SUCCESS; 18672 18673 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 18674 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 18675 return QDF_STATUS_SUCCESS; 18676 18677 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 18678 18679 return QDF_STATUS_SUCCESS; 18680 } 18681 18682 /** 18683 * extract_pdev_tx_stats() - extract pdev tx stats from event 18684 */ 18685 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 18686 { 18687 /* Tx Stats */ 18688 tx->comp_queued = tx_stats->comp_queued; 18689 tx->comp_delivered = tx_stats->comp_delivered; 18690 tx->msdu_enqued = tx_stats->msdu_enqued; 18691 tx->mpdu_enqued = tx_stats->mpdu_enqued; 18692 tx->wmm_drop = tx_stats->wmm_drop; 18693 tx->local_enqued = tx_stats->local_enqued; 18694 tx->local_freed = tx_stats->local_freed; 18695 tx->hw_queued = tx_stats->hw_queued; 18696 tx->hw_reaped = tx_stats->hw_reaped; 18697 tx->underrun = tx_stats->underrun; 18698 tx->tx_abort = tx_stats->tx_abort; 18699 tx->mpdus_requed = tx_stats->mpdus_requed; 18700 tx->data_rc = tx_stats->data_rc; 18701 tx->self_triggers = tx_stats->self_triggers; 18702 tx->sw_retry_failure = tx_stats->sw_retry_failure; 18703 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 18704 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 18705 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 18706 tx->pdev_resets = tx_stats->pdev_resets; 18707 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 18708 tx->phy_underrun = tx_stats->phy_underrun; 18709 tx->txop_ovf = tx_stats->txop_ovf; 18710 18711 return; 18712 } 18713 18714 18715 /** 18716 * extract_pdev_rx_stats() - extract pdev rx stats from event 18717 */ 18718 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 18719 { 18720 /* Rx Stats */ 18721 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 18722 rx->status_rcvd = rx_stats->status_rcvd; 18723 rx->r0_frags = rx_stats->r0_frags; 18724 rx->r1_frags = rx_stats->r1_frags; 18725 rx->r2_frags = rx_stats->r2_frags; 18726 /* Only TLV */ 18727 rx->r3_frags = 0; 18728 rx->htt_msdus = rx_stats->htt_msdus; 18729 rx->htt_mpdus = rx_stats->htt_mpdus; 18730 rx->loc_msdus = rx_stats->loc_msdus; 18731 rx->loc_mpdus = rx_stats->loc_mpdus; 18732 rx->oversize_amsdu = rx_stats->oversize_amsdu; 18733 rx->phy_errs = rx_stats->phy_errs; 18734 rx->phy_err_drop = rx_stats->phy_err_drop; 18735 rx->mpdu_errs = rx_stats->mpdu_errs; 18736 18737 return; 18738 } 18739 18740 /** 18741 * extract_pdev_stats_tlv() - extract pdev stats from event 18742 * @wmi_handle: wmi handle 18743 * @param evt_buf: pointer to event buffer 18744 * @param index: Index into pdev stats 18745 * @param pdev_stats: Pointer to hold pdev stats 18746 * 18747 * Return: QDF_STATUS_SUCCESS for success or error code 18748 */ 18749 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 18750 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 18751 { 18752 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18753 wmi_stats_event_fixed_param *ev_param; 18754 uint8_t *data; 18755 18756 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18757 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18758 18759 data = param_buf->data; 18760 18761 if (index < ev_param->num_pdev_stats) { 18762 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 18763 (index * sizeof(wmi_pdev_stats))); 18764 18765 pdev_stats->chan_nf = ev->chan_nf; 18766 pdev_stats->tx_frame_count = ev->tx_frame_count; 18767 pdev_stats->rx_frame_count = ev->rx_frame_count; 18768 pdev_stats->rx_clear_count = ev->rx_clear_count; 18769 pdev_stats->cycle_count = ev->cycle_count; 18770 pdev_stats->phy_err_count = ev->phy_err_count; 18771 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 18772 18773 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 18774 &(ev->pdev_stats.tx)); 18775 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 18776 &(ev->pdev_stats.rx)); 18777 } 18778 18779 return QDF_STATUS_SUCCESS; 18780 } 18781 18782 /** 18783 * extract_unit_test_tlv() - extract unit test data 18784 * @wmi_handle: wmi handle 18785 * @param evt_buf: pointer to event buffer 18786 * @param unit_test: pointer to hold unit test data 18787 * @param maxspace: Amount of space in evt_buf 18788 * 18789 * Return: QDF_STATUS_SUCCESS for success or error code 18790 */ 18791 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 18792 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 18793 { 18794 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 18795 wmi_unit_test_event_fixed_param *ev_param; 18796 uint32_t num_bufp; 18797 uint32_t copy_size; 18798 uint8_t *bufp; 18799 18800 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 18801 ev_param = param_buf->fixed_param; 18802 bufp = param_buf->bufp; 18803 num_bufp = param_buf->num_bufp; 18804 unit_test->vdev_id = ev_param->vdev_id; 18805 unit_test->module_id = ev_param->module_id; 18806 unit_test->diag_token = ev_param->diag_token; 18807 unit_test->flag = ev_param->flag; 18808 unit_test->payload_len = ev_param->payload_len; 18809 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 18810 ev_param->vdev_id, 18811 ev_param->module_id, 18812 ev_param->diag_token, 18813 ev_param->flag); 18814 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 18815 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 18816 bufp, num_bufp); 18817 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 18818 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 18819 unit_test->buffer_len = copy_size; 18820 18821 return QDF_STATUS_SUCCESS; 18822 } 18823 18824 /** 18825 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 18826 * @wmi_handle: wmi handle 18827 * @param evt_buf: pointer to event buffer 18828 * @param index: Index into extended pdev stats 18829 * @param pdev_ext_stats: Pointer to hold extended pdev stats 18830 * 18831 * Return: QDF_STATUS_SUCCESS for success or error code 18832 */ 18833 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 18834 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 18835 { 18836 return QDF_STATUS_SUCCESS; 18837 } 18838 18839 /** 18840 * extract_vdev_stats_tlv() - extract vdev stats from event 18841 * @wmi_handle: wmi handle 18842 * @param evt_buf: pointer to event buffer 18843 * @param index: Index into vdev stats 18844 * @param vdev_stats: Pointer to hold vdev stats 18845 * 18846 * Return: QDF_STATUS_SUCCESS for success or error code 18847 */ 18848 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 18849 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 18850 { 18851 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18852 wmi_stats_event_fixed_param *ev_param; 18853 uint8_t *data; 18854 18855 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18856 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18857 data = (uint8_t *) param_buf->data; 18858 18859 if (index < ev_param->num_vdev_stats) { 18860 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 18861 ((ev_param->num_pdev_stats) * 18862 sizeof(wmi_pdev_stats)) + 18863 (index * sizeof(wmi_vdev_stats))); 18864 18865 vdev_stats->vdev_id = ev->vdev_id; 18866 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 18867 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 18868 18869 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 18870 sizeof(ev->tx_frm_cnt)); 18871 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 18872 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 18873 ev->multiple_retry_cnt, 18874 sizeof(ev->multiple_retry_cnt)); 18875 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 18876 sizeof(ev->fail_cnt)); 18877 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 18878 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 18879 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 18880 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 18881 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 18882 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 18883 sizeof(ev->tx_rate_history)); 18884 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 18885 sizeof(ev->bcn_rssi_history)); 18886 18887 } 18888 18889 return QDF_STATUS_SUCCESS; 18890 } 18891 18892 /** 18893 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 18894 * buffer 18895 * @wmi_handle: wmi handle 18896 * @evt_buf: pointer to event buffer 18897 * @index: Index into vdev stats 18898 * @rssi_stats: Pointer to hold rssi stats 18899 * 18900 * Return: QDF_STATUS_SUCCESS for success or error code 18901 */ 18902 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 18903 void *evt_buf, uint32_t index, 18904 struct wmi_host_per_chain_rssi_stats *rssi_stats) 18905 { 18906 uint8_t *data; 18907 wmi_rssi_stats *fw_rssi_stats; 18908 wmi_per_chain_rssi_stats *rssi_event; 18909 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18910 18911 if (!evt_buf) { 18912 WMI_LOGE("evt_buf is null"); 18913 return QDF_STATUS_E_NULL_VALUE; 18914 } 18915 18916 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18917 rssi_event = param_buf->chain_stats; 18918 18919 if (index >= rssi_event->num_per_chain_rssi_stats) { 18920 WMI_LOGE("invalid index"); 18921 return QDF_STATUS_E_INVAL; 18922 } 18923 18924 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 18925 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 18926 18927 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 18928 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 18929 fw_rssi_stats->rssi_avg_beacon, 18930 sizeof(fw_rssi_stats->rssi_avg_beacon)); 18931 qdf_mem_copy(rssi_stats->rssi_avg_data, 18932 fw_rssi_stats->rssi_avg_data, 18933 sizeof(fw_rssi_stats->rssi_avg_data)); 18934 qdf_mem_copy(&rssi_stats->peer_macaddr, 18935 &fw_rssi_stats->peer_macaddr, 18936 sizeof(fw_rssi_stats->peer_macaddr)); 18937 18938 return QDF_STATUS_SUCCESS; 18939 } 18940 18941 18942 18943 /** 18944 * extract_bcn_stats_tlv() - extract bcn stats from event 18945 * @wmi_handle: wmi handle 18946 * @param evt_buf: pointer to event buffer 18947 * @param index: Index into vdev stats 18948 * @param bcn_stats: Pointer to hold bcn stats 18949 * 18950 * Return: QDF_STATUS_SUCCESS for success or error code 18951 */ 18952 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 18953 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 18954 { 18955 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18956 wmi_stats_event_fixed_param *ev_param; 18957 uint8_t *data; 18958 18959 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18960 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18961 data = (uint8_t *) param_buf->data; 18962 18963 if (index < ev_param->num_bcn_stats) { 18964 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 18965 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18966 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18967 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 18968 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 18969 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 18970 (index * sizeof(wmi_bcn_stats))); 18971 18972 bcn_stats->vdev_id = ev->vdev_id; 18973 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 18974 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 18975 } 18976 18977 return QDF_STATUS_SUCCESS; 18978 } 18979 18980 /** 18981 * extract_peer_stats_tlv() - extract peer stats from event 18982 * @wmi_handle: wmi handle 18983 * @param evt_buf: pointer to event buffer 18984 * @param index: Index into peer stats 18985 * @param peer_stats: Pointer to hold peer stats 18986 * 18987 * Return: QDF_STATUS_SUCCESS for success or error code 18988 */ 18989 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 18990 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 18991 { 18992 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18993 wmi_stats_event_fixed_param *ev_param; 18994 uint8_t *data; 18995 18996 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18997 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18998 data = (uint8_t *) param_buf->data; 18999 19000 if (index < ev_param->num_peer_stats) { 19001 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 19002 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19003 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19004 (index * sizeof(wmi_peer_stats))); 19005 19006 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19007 19008 OS_MEMCPY(&(peer_stats->peer_macaddr), 19009 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19010 19011 peer_stats->peer_rssi = ev->peer_rssi; 19012 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19013 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19014 } 19015 19016 return QDF_STATUS_SUCCESS; 19017 } 19018 19019 /** 19020 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19021 * @wmi_handle: wmi handle 19022 * @param evt_buf: pointer to event buffer 19023 * @param index: Index into bcn fault stats 19024 * @param bcnflt_stats: Pointer to hold bcn fault stats 19025 * 19026 * Return: QDF_STATUS_SUCCESS for success or error code 19027 */ 19028 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19029 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19030 { 19031 return QDF_STATUS_SUCCESS; 19032 } 19033 19034 /** 19035 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19036 * @wmi_handle: wmi handle 19037 * @param evt_buf: pointer to event buffer 19038 * @param index: Index into extended peer stats 19039 * @param peer_extd_stats: Pointer to hold extended peer stats 19040 * 19041 * Return: QDF_STATUS_SUCCESS for success or error code 19042 */ 19043 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19044 void *evt_buf, uint32_t index, 19045 wmi_host_peer_extd_stats *peer_extd_stats) 19046 { 19047 return QDF_STATUS_SUCCESS; 19048 } 19049 19050 /** 19051 * extract_chan_stats_tlv() - extract chan stats from event 19052 * @wmi_handle: wmi handle 19053 * @param evt_buf: pointer to event buffer 19054 * @param index: Index into chan stats 19055 * @param vdev_extd_stats: Pointer to hold chan stats 19056 * 19057 * Return: QDF_STATUS_SUCCESS for success or error code 19058 */ 19059 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19060 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19061 { 19062 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19063 wmi_stats_event_fixed_param *ev_param; 19064 uint8_t *data; 19065 19066 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19067 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19068 data = (uint8_t *) param_buf->data; 19069 19070 if (index < ev_param->num_chan_stats) { 19071 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19072 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19073 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19074 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19075 (index * sizeof(wmi_chan_stats))); 19076 19077 19078 /* Non-TLV doesn't have num_chan_stats */ 19079 chan_stats->chan_mhz = ev->chan_mhz; 19080 chan_stats->sampling_period_us = ev->sampling_period_us; 19081 chan_stats->rx_clear_count = ev->rx_clear_count; 19082 chan_stats->tx_duration_us = ev->tx_duration_us; 19083 chan_stats->rx_duration_us = ev->rx_duration_us; 19084 } 19085 19086 return QDF_STATUS_SUCCESS; 19087 } 19088 19089 /** 19090 * extract_profile_ctx_tlv() - extract profile context from event 19091 * @wmi_handle: wmi handle 19092 * @param evt_buf: pointer to event buffer 19093 * @idx: profile stats index to extract 19094 * @param profile_ctx: Pointer to hold profile context 19095 * 19096 * Return: QDF_STATUS_SUCCESS for success or error code 19097 */ 19098 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19099 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19100 { 19101 return QDF_STATUS_SUCCESS; 19102 } 19103 19104 /** 19105 * extract_profile_data_tlv() - extract profile data from event 19106 * @wmi_handle: wmi handle 19107 * @param evt_buf: pointer to event buffer 19108 * @param profile_data: Pointer to hold profile data 19109 * 19110 * Return: QDF_STATUS_SUCCESS for success or error code 19111 */ 19112 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19113 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19114 { 19115 19116 return QDF_STATUS_SUCCESS; 19117 } 19118 19119 /** 19120 * extract_chan_info_event_tlv() - extract chan information from event 19121 * @wmi_handle: wmi handle 19122 * @param evt_buf: pointer to event buffer 19123 * @param chan_info: Pointer to hold chan information 19124 * 19125 * Return: QDF_STATUS_SUCCESS for success or error code 19126 */ 19127 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19128 void *evt_buf, wmi_host_chan_info_event *chan_info) 19129 { 19130 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19131 wmi_chan_info_event_fixed_param *ev; 19132 19133 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19134 19135 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19136 if (!ev) { 19137 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19138 return QDF_STATUS_E_FAILURE; 19139 } 19140 19141 chan_info->err_code = ev->err_code; 19142 chan_info->freq = ev->freq; 19143 chan_info->cmd_flags = ev->cmd_flags; 19144 chan_info->noise_floor = ev->noise_floor; 19145 chan_info->rx_clear_count = ev->rx_clear_count; 19146 chan_info->cycle_count = ev->cycle_count; 19147 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19148 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19149 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19150 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19151 ev->vdev_id, WLAN_SCAN_ID); 19152 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19153 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19154 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19155 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19156 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19157 chan_info->rx_frame_count = ev->rx_frame_count; 19158 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19159 chan_info->vdev_id = ev->vdev_id; 19160 19161 return QDF_STATUS_SUCCESS; 19162 } 19163 19164 /** 19165 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19166 * @wmi_handle: WMI handle 19167 * @param evt_buf: Pointer to event buffer 19168 * @param param: Pointer to hold data 19169 * 19170 * Return : QDF_STATUS_SUCCESS for success or error code 19171 */ 19172 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19173 uint8_t *evt_buf, 19174 struct wmi_host_pdev_utf_event *event) 19175 { 19176 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19177 struct wmi_host_utf_seg_header_info *seg_hdr; 19178 19179 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19180 event->data = param_buf->data; 19181 event->datalen = param_buf->num_data; 19182 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19183 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19184 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19185 seg_hdr->pdev_id); 19186 19187 return QDF_STATUS_SUCCESS; 19188 } 19189 19190 /** 19191 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19192 * @wmi_handle: wmi handle 19193 * @param evt_buf: pointer to event buffer 19194 * @param param: Pointer to hold evt buf 19195 * 19196 * Return: QDF_STATUS_SUCCESS for success or error code 19197 */ 19198 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19199 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19200 { 19201 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19202 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19203 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19204 uint8_t i = 0, j = 0; 19205 19206 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19207 if (!param_buf) 19208 return QDF_STATUS_E_INVAL; 19209 19210 hw_caps = param_buf->soc_hw_mode_caps; 19211 if (!hw_caps) 19212 return QDF_STATUS_E_INVAL; 19213 19214 if (!hw_caps->num_chainmask_tables) 19215 return QDF_STATUS_E_INVAL; 19216 19217 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19218 19219 if (chainmask_caps == NULL) 19220 return QDF_STATUS_E_INVAL; 19221 19222 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19223 19224 qdf_print("Dumping chain mask combo data for table : %d", i); 19225 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19226 19227 chainmask_table[i].cap_list[j].chainmask = 19228 chainmask_caps->chainmask; 19229 19230 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19231 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19232 19233 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19234 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19235 19236 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19237 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19238 19239 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19240 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19241 19242 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19243 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19244 19245 chainmask_table[i].cap_list[j].chain_mask_2G = 19246 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19247 19248 chainmask_table[i].cap_list[j].chain_mask_5G = 19249 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19250 19251 chainmask_table[i].cap_list[j].chain_mask_tx = 19252 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19253 19254 chainmask_table[i].cap_list[j].chain_mask_rx = 19255 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19256 19257 chainmask_table[i].cap_list[j].supports_aDFS = 19258 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19259 19260 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x", 19261 chainmask_caps->supported_flags, 19262 chainmask_caps->chainmask 19263 ); 19264 chainmask_caps++; 19265 } 19266 } 19267 19268 return QDF_STATUS_SUCCESS; 19269 } 19270 19271 /** 19272 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19273 * from event 19274 * @wmi_handle: wmi handle 19275 * @param evt_buf: pointer to event buffer 19276 * @param param: Pointer to hold evt buf 19277 * 19278 * Return: QDF_STATUS_SUCCESS for success or error code 19279 */ 19280 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19281 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19282 { 19283 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19284 wmi_service_ready_ext_event_fixed_param *ev; 19285 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19286 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19287 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19288 uint8_t i = 0; 19289 19290 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19291 if (!param_buf) 19292 return QDF_STATUS_E_INVAL; 19293 19294 ev = param_buf->fixed_param; 19295 if (!ev) 19296 return QDF_STATUS_E_INVAL; 19297 19298 /* Move this to host based bitmap */ 19299 param->default_conc_scan_config_bits = 19300 ev->default_conc_scan_config_bits; 19301 param->default_fw_config_bits = ev->default_fw_config_bits; 19302 param->he_cap_info = ev->he_cap_info; 19303 param->mpdu_density = ev->mpdu_density; 19304 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19305 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19306 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19307 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19308 19309 hw_caps = param_buf->soc_hw_mode_caps; 19310 if (hw_caps) 19311 param->num_hw_modes = hw_caps->num_hw_modes; 19312 else 19313 param->num_hw_modes = 0; 19314 19315 reg_caps = param_buf->soc_hal_reg_caps; 19316 if (reg_caps) 19317 param->num_phy = reg_caps->num_phy; 19318 else 19319 param->num_phy = 0; 19320 19321 if (hw_caps) { 19322 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19323 qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables); 19324 } else 19325 param->num_chainmask_tables = 0; 19326 19327 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19328 19329 if (chain_mask_combo == NULL) 19330 return QDF_STATUS_SUCCESS; 19331 19332 qdf_print("Dumping chain mask combo data"); 19333 19334 for (i = 0; i < param->num_chainmask_tables; i++) { 19335 19336 qdf_print("table_id : %d Num valid chainmasks: %d", 19337 chain_mask_combo->chainmask_table_id, 19338 chain_mask_combo->num_valid_chainmask 19339 ); 19340 19341 param->chainmask_table[i].table_id = 19342 chain_mask_combo->chainmask_table_id; 19343 param->chainmask_table[i].num_valid_chainmasks = 19344 chain_mask_combo->num_valid_chainmask; 19345 chain_mask_combo++; 19346 } 19347 qdf_print("chain mask combo end"); 19348 19349 return QDF_STATUS_SUCCESS; 19350 } 19351 19352 /** 19353 * extract_sar_cap_service_ready_ext_tlv() - 19354 * extract SAR cap from service ready event 19355 * @wmi_handle: wmi handle 19356 * @event: pointer to event buffer 19357 * @ext_param: extended target info 19358 * 19359 * Return: QDF_STATUS_SUCCESS for success or error code 19360 */ 19361 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 19362 wmi_unified_t wmi_handle, 19363 uint8_t *event, 19364 struct wlan_psoc_host_service_ext_param *ext_param) 19365 { 19366 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19367 WMI_SAR_CAPABILITIES *sar_caps; 19368 19369 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19370 19371 if (!param_buf) 19372 return QDF_STATUS_E_INVAL; 19373 19374 sar_caps = param_buf->sar_caps; 19375 if (sar_caps) 19376 ext_param->sar_version = sar_caps->active_version; 19377 else 19378 ext_param->sar_version = 0; 19379 19380 return QDF_STATUS_SUCCESS; 19381 } 19382 19383 /** 19384 * extract_hw_mode_cap_service_ready_ext_tlv() - 19385 * extract HW mode cap from service ready event 19386 * @wmi_handle: wmi handle 19387 * @param evt_buf: pointer to event buffer 19388 * @param param: Pointer to hold evt buf 19389 * @param hw_mode_idx: hw mode idx should be less than num_mode 19390 * 19391 * Return: QDF_STATUS_SUCCESS for success or error code 19392 */ 19393 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19394 wmi_unified_t wmi_handle, 19395 uint8_t *event, uint8_t hw_mode_idx, 19396 struct wlan_psoc_host_hw_mode_caps *param) 19397 { 19398 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19399 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19400 19401 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19402 if (!param_buf) 19403 return QDF_STATUS_E_INVAL; 19404 19405 hw_caps = param_buf->soc_hw_mode_caps; 19406 if (!hw_caps) 19407 return QDF_STATUS_E_INVAL; 19408 19409 if (hw_mode_idx >= hw_caps->num_hw_modes) 19410 return QDF_STATUS_E_INVAL; 19411 19412 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19413 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19414 19415 param->hw_mode_config_type = 19416 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19417 19418 return QDF_STATUS_SUCCESS; 19419 } 19420 19421 /** 19422 * extract_mac_phy_cap_service_ready_ext_tlv() - 19423 * extract MAC phy cap from service ready event 19424 * @wmi_handle: wmi handle 19425 * @param evt_buf: pointer to event buffer 19426 * @param param: Pointer to hold evt buf 19427 * @param hw_mode_idx: hw mode idx should be less than num_mode 19428 * @param phy_id: phy id within hw_mode 19429 * 19430 * Return: QDF_STATUS_SUCCESS for success or error code 19431 */ 19432 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19433 wmi_unified_t wmi_handle, 19434 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19435 struct wlan_psoc_host_mac_phy_caps *param) 19436 { 19437 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19438 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19439 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19440 uint32_t phy_map; 19441 uint8_t hw_idx, phy_idx = 0; 19442 19443 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19444 if (!param_buf) 19445 return QDF_STATUS_E_INVAL; 19446 19447 hw_caps = param_buf->soc_hw_mode_caps; 19448 if (!hw_caps) 19449 return QDF_STATUS_E_INVAL; 19450 19451 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19452 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19453 break; 19454 19455 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19456 while (phy_map) { 19457 phy_map >>= 1; 19458 phy_idx++; 19459 } 19460 } 19461 19462 if (hw_idx == hw_caps->num_hw_modes) 19463 return QDF_STATUS_E_INVAL; 19464 19465 phy_idx += phy_id; 19466 if (phy_idx >= param_buf->num_mac_phy_caps) 19467 return QDF_STATUS_E_INVAL; 19468 19469 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19470 19471 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19472 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19473 mac_phy_caps->pdev_id); 19474 param->phy_id = mac_phy_caps->phy_id; 19475 param->supports_11b = 19476 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19477 param->supports_11g = 19478 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19479 param->supports_11a = 19480 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19481 param->supports_11n = 19482 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19483 param->supports_11ac = 19484 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19485 param->supports_11ax = 19486 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19487 19488 param->supported_bands = mac_phy_caps->supported_bands; 19489 param->ampdu_density = mac_phy_caps->ampdu_density; 19490 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19491 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19492 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19493 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19494 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 19495 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19496 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19497 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19498 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19499 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19500 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19501 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19502 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 19503 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 19504 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 19505 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 19506 qdf_mem_copy(¶m->he_cap_phy_info_2G, 19507 &mac_phy_caps->he_cap_phy_info_2G, 19508 sizeof(param->he_cap_phy_info_2G)); 19509 qdf_mem_copy(¶m->he_cap_phy_info_5G, 19510 &mac_phy_caps->he_cap_phy_info_5G, 19511 sizeof(param->he_cap_phy_info_5G)); 19512 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 19513 sizeof(param->he_ppet2G)); 19514 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 19515 sizeof(param->he_ppet5G)); 19516 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 19517 19518 return QDF_STATUS_SUCCESS; 19519 } 19520 19521 /** 19522 * extract_reg_cap_service_ready_ext_tlv() - 19523 * extract REG cap from service ready event 19524 * @wmi_handle: wmi handle 19525 * @param evt_buf: pointer to event buffer 19526 * @param param: Pointer to hold evt buf 19527 * @param phy_idx: phy idx should be less than num_mode 19528 * 19529 * Return: QDF_STATUS_SUCCESS for success or error code 19530 */ 19531 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 19532 wmi_unified_t wmi_handle, 19533 uint8_t *event, uint8_t phy_idx, 19534 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 19535 { 19536 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19537 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19538 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 19539 19540 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19541 if (!param_buf) 19542 return QDF_STATUS_E_INVAL; 19543 19544 reg_caps = param_buf->soc_hal_reg_caps; 19545 if (!reg_caps) 19546 return QDF_STATUS_E_INVAL; 19547 19548 if (phy_idx >= reg_caps->num_phy) 19549 return QDF_STATUS_E_INVAL; 19550 19551 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 19552 19553 param->phy_id = ext_reg_cap->phy_id; 19554 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 19555 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 19556 param->regcap1 = ext_reg_cap->regcap1; 19557 param->regcap2 = ext_reg_cap->regcap2; 19558 param->wireless_modes = convert_wireless_modes_tlv( 19559 ext_reg_cap->wireless_modes); 19560 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 19561 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 19562 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 19563 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 19564 19565 return QDF_STATUS_SUCCESS; 19566 } 19567 19568 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 19569 wmi_unified_t wmi_handle, 19570 uint8_t *event, uint8_t idx, 19571 struct wlan_psoc_host_dbr_ring_caps *param) 19572 { 19573 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19574 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 19575 19576 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19577 if (!param_buf) 19578 return QDF_STATUS_E_INVAL; 19579 19580 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 19581 19582 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19583 dbr_ring_caps->pdev_id); 19584 param->mod_id = dbr_ring_caps->mod_id; 19585 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 19586 param->min_buf_size = dbr_ring_caps->min_buf_size; 19587 param->min_buf_align = dbr_ring_caps->min_buf_align; 19588 19589 return QDF_STATUS_SUCCESS; 19590 } 19591 19592 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 19593 uint8_t *event, struct direct_buf_rx_rsp *param) 19594 { 19595 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19596 wmi_dma_buf_release_fixed_param *ev; 19597 19598 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19599 if (!param_buf) 19600 return QDF_STATUS_E_INVAL; 19601 19602 ev = param_buf->fixed_param; 19603 if (!ev) 19604 return QDF_STATUS_E_INVAL; 19605 19606 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19607 ev->pdev_id); 19608 param->mod_id = ev->mod_id; 19609 param->num_buf_release_entry = ev->num_buf_release_entry; 19610 param->num_meta_data_entry = ev->num_meta_data_entry; 19611 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 19612 param->pdev_id, param->mod_id, param->num_buf_release_entry); 19613 19614 return QDF_STATUS_SUCCESS; 19615 } 19616 19617 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 19618 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 19619 { 19620 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19621 wmi_dma_buf_release_entry *entry; 19622 19623 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19624 if (!param_buf) 19625 return QDF_STATUS_E_INVAL; 19626 19627 entry = ¶m_buf->entries[idx]; 19628 19629 if (!entry) { 19630 WMI_LOGE("%s: Entry is NULL\n", __func__); 19631 return QDF_STATUS_E_FAILURE; 19632 } 19633 19634 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 19635 19636 param->paddr_lo = entry->paddr_lo; 19637 param->paddr_hi = entry->paddr_hi; 19638 19639 return QDF_STATUS_SUCCESS; 19640 } 19641 19642 static QDF_STATUS extract_dbr_buf_metadata_tlv( 19643 wmi_unified_t wmi_handle, uint8_t *event, 19644 uint8_t idx, struct direct_buf_rx_metadata *param) 19645 { 19646 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19647 wmi_dma_buf_release_spectral_meta_data *entry; 19648 19649 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19650 if (!param_buf) 19651 return QDF_STATUS_E_INVAL; 19652 19653 entry = ¶m_buf->meta_data[idx]; 19654 19655 if (!entry) { 19656 WMI_LOGE("%s: Entry is NULL\n", __func__); 19657 return QDF_STATUS_E_FAILURE; 19658 } 19659 19660 qdf_mem_copy(param->noisefloor, entry->noise_floor, 19661 sizeof(entry->noise_floor)); 19662 return QDF_STATUS_SUCCESS; 19663 } 19664 19665 /** 19666 * extract_dcs_interference_type_tlv() - extract dcs interference type 19667 * from event 19668 * @wmi_handle: wmi handle 19669 * @param evt_buf: pointer to event buffer 19670 * @param param: Pointer to hold dcs interference param 19671 * 19672 * Return: 0 for success or error code 19673 */ 19674 static QDF_STATUS extract_dcs_interference_type_tlv( 19675 wmi_unified_t wmi_handle, 19676 void *evt_buf, struct wmi_host_dcs_interference_param *param) 19677 { 19678 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19679 19680 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19681 if (!param_buf) 19682 return QDF_STATUS_E_INVAL; 19683 19684 param->interference_type = param_buf->fixed_param->interference_type; 19685 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19686 param_buf->fixed_param->pdev_id); 19687 19688 return QDF_STATUS_SUCCESS; 19689 } 19690 19691 /* 19692 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 19693 * @wmi_handle: wmi handle 19694 * @param evt_buf: pointer to event buffer 19695 * @param cw_int: Pointer to hold cw interference 19696 * 19697 * Return: 0 for success or error code 19698 */ 19699 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 19700 void *evt_buf, 19701 wmi_host_ath_dcs_cw_int *cw_int) 19702 { 19703 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19704 wlan_dcs_cw_int *ev; 19705 19706 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19707 if (!param_buf) 19708 return QDF_STATUS_E_INVAL; 19709 19710 ev = param_buf->cw_int; 19711 19712 cw_int->channel = ev->channel; 19713 19714 return QDF_STATUS_SUCCESS; 19715 } 19716 19717 /** 19718 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 19719 * @wmi_handle: wmi handle 19720 * @param evt_buf: pointer to event buffer 19721 * @param wlan_stat: Pointer to hold wlan stats 19722 * 19723 * Return: 0 for success or error code 19724 */ 19725 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 19726 void *evt_buf, 19727 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 19728 { 19729 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19730 wlan_dcs_im_tgt_stats_t *ev; 19731 19732 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19733 if (!param_buf) 19734 return QDF_STATUS_E_INVAL; 19735 19736 ev = param_buf->wlan_stat; 19737 wlan_stat->reg_tsf32 = ev->reg_tsf32; 19738 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 19739 wlan_stat->tx_waste_time = ev->tx_waste_time; 19740 wlan_stat->rx_time = ev->rx_time; 19741 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 19742 wlan_stat->mib_stats.listen_time = ev->listen_time; 19743 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 19744 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 19745 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 19746 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 19747 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 19748 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 19749 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 19750 wlan_stat->chan_nf = ev->chan_nf; 19751 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19752 19753 return QDF_STATUS_SUCCESS; 19754 } 19755 19756 /** 19757 * extract_thermal_stats_tlv() - extract thermal stats from event 19758 * @wmi_handle: wmi handle 19759 * @param evt_buf: Pointer to event buffer 19760 * @param temp: Pointer to hold extracted temperature 19761 * @param level: Pointer to hold extracted level 19762 * 19763 * Return: 0 for success or error code 19764 */ 19765 static QDF_STATUS 19766 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 19767 void *evt_buf, uint32_t *temp, 19768 uint32_t *level, uint32_t *pdev_id) 19769 { 19770 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19771 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 19772 19773 param_buf = 19774 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19775 if (!param_buf) 19776 return QDF_STATUS_E_INVAL; 19777 19778 tt_stats_event = param_buf->fixed_param; 19779 19780 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19781 tt_stats_event->pdev_id); 19782 *temp = tt_stats_event->temp; 19783 *level = tt_stats_event->level; 19784 19785 return QDF_STATUS_SUCCESS; 19786 } 19787 19788 /** 19789 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 19790 * @wmi_handle: wmi handle 19791 * @param evt_buf: pointer to event buffer 19792 * @param idx: Index to level stats 19793 * @param levelcount: Pointer to hold levelcount 19794 * @param dccount: Pointer to hold dccount 19795 * 19796 * Return: 0 for success or error code 19797 */ 19798 static QDF_STATUS 19799 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 19800 void *evt_buf, uint8_t idx, uint32_t *levelcount, 19801 uint32_t *dccount) 19802 { 19803 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19804 wmi_therm_throt_level_stats_info *tt_level_info; 19805 19806 param_buf = 19807 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19808 if (!param_buf) 19809 return QDF_STATUS_E_INVAL; 19810 19811 tt_level_info = param_buf->therm_throt_level_stats_info; 19812 19813 if (idx < THERMAL_LEVELS) { 19814 *levelcount = tt_level_info[idx].level_count; 19815 *dccount = tt_level_info[idx].dc_count; 19816 return QDF_STATUS_SUCCESS; 19817 } 19818 19819 return QDF_STATUS_E_FAILURE; 19820 } 19821 #ifdef BIG_ENDIAN_HOST 19822 /** 19823 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 19824 * @param data_len - data length 19825 * @param data - pointer to data 19826 * 19827 * Return: QDF_STATUS - success or error status 19828 */ 19829 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19830 { 19831 uint8_t *data_aligned = NULL; 19832 int c; 19833 unsigned char *data_unaligned; 19834 19835 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 19836 FIPS_ALIGN)); 19837 /* Assigning unaligned space to copy the data */ 19838 /* Checking if kmalloc does successful allocation */ 19839 if (data_unaligned == NULL) 19840 return QDF_STATUS_E_FAILURE; 19841 19842 /* Checking if space is alligned */ 19843 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 19844 /* align the data space */ 19845 data_aligned = 19846 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 19847 } else { 19848 data_aligned = (u_int8_t *)data_unaligned; 19849 } 19850 19851 /* memset and copy content from data to data aligned */ 19852 OS_MEMSET(data_aligned, 0, data_len); 19853 OS_MEMCPY(data_aligned, data, data_len); 19854 /* Endianness to LE */ 19855 for (c = 0; c < data_len/4; c++) { 19856 *((u_int32_t *)data_aligned + c) = 19857 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 19858 } 19859 19860 /* Copy content to event->data */ 19861 OS_MEMCPY(data, data_aligned, data_len); 19862 19863 /* clean up allocated space */ 19864 qdf_mem_free(data_unaligned); 19865 data_aligned = NULL; 19866 data_unaligned = NULL; 19867 19868 /*************************************************************/ 19869 19870 return QDF_STATUS_SUCCESS; 19871 } 19872 #else 19873 /** 19874 * fips_conv_data_be() - DUMMY for LE platform 19875 * 19876 * Return: QDF_STATUS - success 19877 */ 19878 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19879 { 19880 return QDF_STATUS_SUCCESS; 19881 } 19882 #endif 19883 19884 /** 19885 * extract_fips_event_data_tlv() - extract fips event data 19886 * @wmi_handle: wmi handle 19887 * @param evt_buf: pointer to event buffer 19888 * @param param: pointer FIPS event params 19889 * 19890 * Return: 0 for success or error code 19891 */ 19892 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 19893 void *evt_buf, struct wmi_host_fips_event_param *param) 19894 { 19895 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 19896 wmi_pdev_fips_event_fixed_param *event; 19897 19898 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 19899 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 19900 19901 if (fips_conv_data_be(event->data_len, param_buf->data) != 19902 QDF_STATUS_SUCCESS) 19903 return QDF_STATUS_E_FAILURE; 19904 19905 param->data = (uint32_t *)param_buf->data; 19906 param->data_len = event->data_len; 19907 param->error_status = event->error_status; 19908 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19909 event->pdev_id); 19910 19911 return QDF_STATUS_SUCCESS; 19912 } 19913 19914 /* 19915 * extract_peer_delete_response_event_tlv() - extract peer delete response event 19916 * @wmi_handle: wmi handle 19917 * @param evt_buf: pointer to event buffer 19918 * @param vdev_id: Pointer to hold vdev_id 19919 * @param mac_addr: Pointer to hold peer mac address 19920 * 19921 * Return: QDF_STATUS_SUCCESS for success or error code 19922 */ 19923 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 19924 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 19925 { 19926 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 19927 wmi_peer_delete_resp_event_fixed_param *ev; 19928 19929 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 19930 19931 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 19932 if (!ev) { 19933 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 19934 return QDF_STATUS_E_FAILURE; 19935 } 19936 19937 param->vdev_id = ev->vdev_id; 19938 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 19939 ¶m->mac_address.bytes[0]); 19940 19941 return QDF_STATUS_SUCCESS; 19942 } 19943 19944 static bool is_management_record_tlv(uint32_t cmd_id) 19945 { 19946 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 19947 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 19948 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 19949 return true; 19950 } 19951 19952 return false; 19953 } 19954 19955 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19956 { 19957 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 19958 19959 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 19960 19961 switch (set_cmd->param_id) { 19962 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 19963 case WMI_VDEV_PARAM_DTIM_POLICY: 19964 return HTC_TX_PACKET_TAG_AUTO_PM; 19965 default: 19966 break; 19967 } 19968 19969 return 0; 19970 } 19971 19972 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19973 { 19974 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 19975 19976 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 19977 19978 switch (ps_cmd->param) { 19979 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 19980 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 19981 case WMI_STA_PS_ENABLE_QPOWER: 19982 return HTC_TX_PACKET_TAG_AUTO_PM; 19983 default: 19984 break; 19985 } 19986 19987 return 0; 19988 } 19989 19990 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 19991 uint32_t cmd_id) 19992 { 19993 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 19994 return 0; 19995 19996 switch (cmd_id) { 19997 case WMI_VDEV_SET_PARAM_CMDID: 19998 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 19999 case WMI_STA_POWERSAVE_PARAM_CMDID: 20000 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 20001 default: 20002 break; 20003 } 20004 20005 return 0; 20006 } 20007 20008 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20009 { 20010 uint16_t tag = 0; 20011 20012 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20013 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20014 __func__); 20015 return tag; 20016 } 20017 20018 if (wmi_handle->tag_crash_inject) 20019 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20020 20021 wmi_handle->tag_crash_inject = false; 20022 return tag; 20023 } 20024 20025 /** 20026 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20027 * @wmi_handle: WMI handle 20028 * @buf: WMI buffer 20029 * @cmd_id: WMI command Id 20030 * 20031 * Return htc_tx_tag 20032 */ 20033 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20034 wmi_buf_t buf, 20035 uint32_t cmd_id) 20036 { 20037 uint16_t htc_tx_tag = 0; 20038 20039 switch (cmd_id) { 20040 case WMI_WOW_ENABLE_CMDID: 20041 case WMI_PDEV_SUSPEND_CMDID: 20042 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20043 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20044 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20045 case WMI_PDEV_RESUME_CMDID: 20046 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20047 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20048 #ifdef FEATURE_WLAN_D0WOW 20049 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20050 #endif 20051 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20052 break; 20053 case WMI_FORCE_FW_HANG_CMDID: 20054 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20055 break; 20056 case WMI_VDEV_SET_PARAM_CMDID: 20057 case WMI_STA_POWERSAVE_PARAM_CMDID: 20058 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20059 default: 20060 break; 20061 } 20062 20063 return htc_tx_tag; 20064 } 20065 20066 /** 20067 * extract_channel_hopping_event_tlv() - extract channel hopping param 20068 * from event 20069 * @wmi_handle: wmi handle 20070 * @param evt_buf: pointer to event buffer 20071 * @param ch_hopping: Pointer to hold channel hopping param 20072 * 20073 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20074 */ 20075 static QDF_STATUS extract_channel_hopping_event_tlv( 20076 wmi_unified_t wmi_handle, void *evt_buf, 20077 wmi_host_pdev_channel_hopping_event *ch_hopping) 20078 { 20079 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20080 wmi_pdev_channel_hopping_event_fixed_param *event; 20081 20082 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20083 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20084 param_buf->fixed_param; 20085 20086 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20087 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20088 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20089 event->pdev_id); 20090 20091 return QDF_STATUS_SUCCESS; 20092 } 20093 20094 /** 20095 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20096 * @wmi_handle: wmi handle 20097 * @param evt_buf: pointer to event buffer 20098 * @param param: Pointer to hold tpc param 20099 * 20100 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20101 */ 20102 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20103 void *evt_buf, 20104 wmi_host_pdev_tpc_event *param) 20105 { 20106 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20107 wmi_pdev_tpc_event_fixed_param *event; 20108 20109 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20110 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20111 20112 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20113 event->pdev_id); 20114 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20115 20116 return QDF_STATUS_SUCCESS; 20117 } 20118 20119 /** 20120 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20121 * power param from event 20122 * @wmi_handle: wmi handle 20123 * @param evt_buf: pointer to event buffer 20124 * @param param: Pointer to hold nf cal power param 20125 * 20126 * Return: 0 for success or error code 20127 */ 20128 static QDF_STATUS 20129 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20130 void *evt_buf, 20131 wmi_host_pdev_nfcal_power_all_channels_event *param) 20132 { 20133 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20134 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20135 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20136 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20137 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20138 uint32_t i; 20139 20140 param_buf = 20141 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20142 event = param_buf->fixed_param; 20143 ch_nfdbr = param_buf->nfdbr; 20144 ch_nfdbm = param_buf->nfdbm; 20145 ch_freqnum = param_buf->freqnum; 20146 20147 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20148 event->pdev_id, param_buf->num_nfdbr, 20149 param_buf->num_nfdbm, param_buf->num_freqnum); 20150 20151 if (param_buf->num_nfdbr > 20152 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20153 WMI_LOGE("invalid number of nfdBr"); 20154 return QDF_STATUS_E_FAILURE; 20155 } 20156 20157 if (param_buf->num_nfdbm > 20158 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20159 WMI_LOGE("invalid number of nfdBm"); 20160 return QDF_STATUS_E_FAILURE; 20161 } 20162 20163 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20164 WMI_LOGE("invalid number of freqNum"); 20165 return QDF_STATUS_E_FAILURE; 20166 } 20167 20168 for (i = 0; i < param_buf->num_nfdbr; i++) { 20169 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20170 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20171 ch_nfdbr++; 20172 ch_nfdbm++; 20173 } 20174 20175 for (i = 0; i < param_buf->num_freqnum; i++) { 20176 param->freqnum[i] = ch_freqnum->freqNum; 20177 ch_freqnum++; 20178 } 20179 20180 param->pdev_id = wmi_handle->ops-> 20181 convert_pdev_id_target_to_host(event->pdev_id); 20182 20183 return QDF_STATUS_SUCCESS; 20184 } 20185 20186 20187 #ifdef BIG_ENDIAN_HOST 20188 /** 20189 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20190 * @param data_len - data length 20191 * @param data - pointer to data 20192 * 20193 * Return: QDF_STATUS - success or error status 20194 */ 20195 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20196 { 20197 uint8_t *datap = (uint8_t *)ev; 20198 int i; 20199 /* Skip swapping the first word */ 20200 datap += sizeof(uint32_t); 20201 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20202 i++, datap += sizeof(uint32_t)) { 20203 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20204 } 20205 20206 return QDF_STATUS_SUCCESS; 20207 } 20208 #else 20209 /** 20210 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20211 * @param data_len - data length 20212 * @param data - pointer to data 20213 * 20214 * Return: QDF_STATUS - success or error status 20215 */ 20216 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20217 { 20218 return QDF_STATUS_SUCCESS; 20219 } 20220 #endif 20221 20222 /** 20223 * extract_wds_addr_event_tlv() - extract wds address from event 20224 * @wmi_handle: wmi handle 20225 * @param evt_buf: pointer to event buffer 20226 * @param wds_ev: Pointer to hold wds address 20227 * 20228 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20229 */ 20230 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20231 void *evt_buf, 20232 uint16_t len, wds_addr_event_t *wds_ev) 20233 { 20234 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20235 wmi_wds_addr_event_fixed_param *ev; 20236 int i; 20237 20238 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20239 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20240 20241 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20242 return QDF_STATUS_E_FAILURE; 20243 20244 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20245 sizeof(wds_ev->event_type)); 20246 for (i = 0; i < 4; i++) { 20247 wds_ev->peer_mac[i] = 20248 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20249 wds_ev->dest_mac[i] = 20250 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20251 } 20252 for (i = 0; i < 2; i++) { 20253 wds_ev->peer_mac[4+i] = 20254 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20255 wds_ev->dest_mac[4+i] = 20256 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20257 } 20258 return QDF_STATUS_SUCCESS; 20259 } 20260 20261 /** 20262 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20263 * from event 20264 * @wmi_handle: wmi handle 20265 * @param evt_buf: pointer to event buffer 20266 * @param ev: Pointer to hold peer param and ps state 20267 * 20268 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20269 */ 20270 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20271 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20272 { 20273 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20274 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20275 20276 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20277 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20278 param_buf->fixed_param; 20279 20280 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20281 ev->peer_ps_state = event->peer_ps_state; 20282 20283 return QDF_STATUS_SUCCESS; 20284 } 20285 20286 /** 20287 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20288 * @wmi_handle: wmi handle 20289 * @param evt_buf: pointer to event buffer 20290 * @param inst_rssi_resp: Pointer to hold inst rssi response 20291 * 20292 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20293 */ 20294 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20295 wmi_unified_t wmi_handle, void *evt_buf, 20296 wmi_host_inst_stats_resp *inst_rssi_resp) 20297 { 20298 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20299 wmi_inst_rssi_stats_resp_fixed_param *event; 20300 20301 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20302 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20303 20304 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20305 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20306 inst_rssi_resp->iRSSI = event->iRSSI; 20307 20308 return QDF_STATUS_SUCCESS; 20309 } 20310 20311 static struct cur_reg_rule 20312 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20313 wmi_regulatory_rule_struct *wmi_reg_rule) 20314 { 20315 struct cur_reg_rule *reg_rule_ptr; 20316 uint32_t count; 20317 20318 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20319 20320 if (NULL == reg_rule_ptr) { 20321 WMI_LOGE("memory allocation failure"); 20322 return NULL; 20323 } 20324 20325 for (count = 0; count < num_reg_rules; count++) { 20326 reg_rule_ptr[count].start_freq = 20327 WMI_REG_RULE_START_FREQ_GET( 20328 wmi_reg_rule[count].freq_info); 20329 reg_rule_ptr[count].end_freq = 20330 WMI_REG_RULE_END_FREQ_GET( 20331 wmi_reg_rule[count].freq_info); 20332 reg_rule_ptr[count].max_bw = 20333 WMI_REG_RULE_MAX_BW_GET( 20334 wmi_reg_rule[count].bw_pwr_info); 20335 reg_rule_ptr[count].reg_power = 20336 WMI_REG_RULE_REG_POWER_GET( 20337 wmi_reg_rule[count].bw_pwr_info); 20338 reg_rule_ptr[count].ant_gain = 20339 WMI_REG_RULE_ANTENNA_GAIN_GET( 20340 wmi_reg_rule[count].bw_pwr_info); 20341 reg_rule_ptr[count].flags = 20342 WMI_REG_RULE_FLAGS_GET( 20343 wmi_reg_rule[count].flag_info); 20344 } 20345 20346 return reg_rule_ptr; 20347 } 20348 20349 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20350 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20351 struct cur_regulatory_info *reg_info, uint32_t len) 20352 { 20353 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20354 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20355 wmi_regulatory_rule_struct *wmi_reg_rule; 20356 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20357 20358 WMI_LOGD("processing regulatory channel list"); 20359 20360 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20361 if (!param_buf) { 20362 WMI_LOGE("invalid channel list event buf"); 20363 return QDF_STATUS_E_FAILURE; 20364 } 20365 20366 chan_list_event_hdr = param_buf->fixed_param; 20367 20368 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20369 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20370 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20371 REG_ALPHA2_LEN); 20372 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20373 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20374 reg_info->offload_enabled = true; 20375 reg_info->num_phy = chan_list_event_hdr->num_phy; 20376 reg_info->phy_id = chan_list_event_hdr->phy_id; 20377 reg_info->ctry_code = chan_list_event_hdr->country_id; 20378 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20379 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20380 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20381 else if (chan_list_event_hdr->status_code == 20382 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20383 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20384 else if (chan_list_event_hdr->status_code == 20385 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20386 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20387 else if (chan_list_event_hdr->status_code == 20388 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20389 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20390 else if (chan_list_event_hdr->status_code == 20391 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20392 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20393 else if (chan_list_event_hdr->status_code == 20394 WMI_REG_SET_CC_STATUS_FAIL) 20395 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20396 20397 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20398 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20399 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20400 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20401 20402 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20403 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20404 20405 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20406 __func__, reg_info->alpha2, reg_info->dfs_region, 20407 reg_info->min_bw_2g, reg_info->max_bw_2g, 20408 reg_info->min_bw_5g, reg_info->max_bw_5g); 20409 20410 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20411 num_2g_reg_rules, num_5g_reg_rules); 20412 wmi_reg_rule = 20413 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20414 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20415 + WMI_TLV_HDR_SIZE); 20416 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20417 wmi_reg_rule); 20418 wmi_reg_rule += num_2g_reg_rules; 20419 20420 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20421 wmi_reg_rule); 20422 20423 WMI_LOGD("processed regulatory channel list"); 20424 20425 return QDF_STATUS_SUCCESS; 20426 } 20427 20428 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20429 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20430 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20431 { 20432 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20433 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20434 20435 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20436 if (!param_buf) { 20437 WMI_LOGE("invalid 11d country event buf"); 20438 return QDF_STATUS_E_FAILURE; 20439 } 20440 20441 reg_11d_country_event = param_buf->fixed_param; 20442 20443 qdf_mem_copy(reg_11d_country->alpha2, 20444 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20445 20446 WMI_LOGD("processed 11d country event, new cc %s", 20447 reg_11d_country->alpha2); 20448 20449 return QDF_STATUS_SUCCESS; 20450 } 20451 20452 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20453 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20454 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20455 { 20456 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20457 wmi_avoid_freq_range_desc *afr_desc; 20458 uint32_t num_freq_ranges, freq_range_idx; 20459 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20460 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20461 20462 if (!param_buf) { 20463 WMI_LOGE("Invalid channel avoid event buffer"); 20464 return QDF_STATUS_E_INVAL; 20465 } 20466 20467 afr_fixed_param = param_buf->fixed_param; 20468 if (!afr_fixed_param) { 20469 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20470 return QDF_STATUS_E_INVAL; 20471 } 20472 20473 if (!ch_avoid_ind) { 20474 WMI_LOGE("Invalid channel avoid indication buffer"); 20475 return QDF_STATUS_E_INVAL; 20476 } 20477 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20478 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20479 afr_fixed_param->num_freq_ranges; 20480 20481 WMI_LOGD("Channel avoid event received with %d ranges", 20482 num_freq_ranges); 20483 20484 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20485 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20486 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20487 freq_range_idx++) { 20488 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20489 afr_desc->start_freq; 20490 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20491 afr_desc->end_freq; 20492 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20493 freq_range_idx, afr_desc->tlv_header, 20494 afr_desc->start_freq, afr_desc->end_freq); 20495 afr_desc++; 20496 } 20497 20498 return QDF_STATUS_SUCCESS; 20499 } 20500 #ifdef DFS_COMPONENT_ENABLE 20501 /** 20502 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20503 * @wmi_handle: wma handle 20504 * @evt_buf: event buffer 20505 * @vdev_id: vdev id 20506 * @len: length of buffer 20507 * 20508 * Return: 0 for success or error code 20509 */ 20510 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20511 uint8_t *evt_buf, 20512 uint32_t *vdev_id, 20513 uint32_t len) 20514 { 20515 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20516 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20517 20518 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20519 if (!param_tlvs) { 20520 WMI_LOGE("invalid cac complete event buf"); 20521 return QDF_STATUS_E_FAILURE; 20522 } 20523 20524 cac_event = param_tlvs->fixed_param; 20525 *vdev_id = cac_event->vdev_id; 20526 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20527 20528 return QDF_STATUS_SUCCESS; 20529 } 20530 20531 /** 20532 * extract_dfs_radar_detection_event_tlv() - extract radar found event 20533 * @wmi_handle: wma handle 20534 * @evt_buf: event buffer 20535 * @radar_found: radar found event info 20536 * @len: length of buffer 20537 * 20538 * Return: 0 for success or error code 20539 */ 20540 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 20541 wmi_unified_t wmi_handle, 20542 uint8_t *evt_buf, 20543 struct radar_found_info *radar_found, 20544 uint32_t len) 20545 { 20546 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 20547 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 20548 20549 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 20550 if (!param_tlv) { 20551 WMI_LOGE("invalid radar detection event buf"); 20552 return QDF_STATUS_E_FAILURE; 20553 } 20554 20555 radar_event = param_tlv->fixed_param; 20556 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 20557 radar_event->pdev_id); 20558 radar_found->detection_mode = radar_event->detection_mode; 20559 radar_found->chan_freq = radar_event->chan_freq; 20560 radar_found->chan_width = radar_event->chan_width; 20561 radar_found->detector_id = radar_event->detector_id; 20562 radar_found->segment_id = radar_event->segment_id; 20563 radar_found->timestamp = radar_event->timestamp; 20564 radar_found->is_chirp = radar_event->is_chirp; 20565 radar_found->freq_offset = radar_event->freq_offset; 20566 radar_found->sidx = radar_event->sidx; 20567 20568 WMI_LOGI("processed radar found event pdev %d," 20569 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 20570 "chan_width (RSSI) %d,detector_id (false_radar) %d," 20571 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 20572 "is_chirp %d,detection mode %d\n", 20573 radar_event->pdev_id, radar_found->pdev_id, 20574 radar_event->timestamp, radar_event->chan_freq, 20575 radar_event->chan_width, radar_event->detector_id, 20576 radar_event->freq_offset, radar_event->segment_id, 20577 radar_event->sidx, radar_event->is_chirp, 20578 radar_event->detection_mode); 20579 20580 return QDF_STATUS_SUCCESS; 20581 } 20582 20583 #ifdef QCA_MCL_DFS_SUPPORT 20584 /** 20585 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 20586 * @wmi_handle: wma handle 20587 * @evt_buf: event buffer 20588 * @wlan_radar_event: Pointer to struct radar_event_info 20589 * @len: length of buffer 20590 * 20591 * Return: QDF_STATUS 20592 */ 20593 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20594 wmi_unified_t wmi_handle, 20595 uint8_t *evt_buf, 20596 struct radar_event_info *wlan_radar_event, 20597 uint32_t len) 20598 { 20599 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 20600 wmi_dfs_radar_event_fixed_param *radar_event; 20601 20602 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 20603 if (!param_tlv) { 20604 WMI_LOGE("invalid wlan radar event buf"); 20605 return QDF_STATUS_E_FAILURE; 20606 } 20607 20608 radar_event = param_tlv->fixed_param; 20609 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 20610 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 20611 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 20612 wlan_radar_event->rssi = radar_event->rssi; 20613 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 20614 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 20615 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 20616 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 20617 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 20618 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 20619 if (radar_event->pulse_flags & 20620 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 20621 wlan_radar_event->is_psidx_diff_valid = true; 20622 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 20623 } else { 20624 wlan_radar_event->is_psidx_diff_valid = false; 20625 } 20626 20627 wlan_radar_event->pdev_id = radar_event->pdev_id; 20628 20629 return QDF_STATUS_SUCCESS; 20630 } 20631 #else 20632 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20633 wmi_unified_t wmi_handle, 20634 uint8_t *evt_buf, 20635 struct radar_event_info *wlan_radar_event, 20636 uint32_t len) 20637 { 20638 return QDF_STATUS_SUCCESS; 20639 } 20640 #endif 20641 #endif 20642 20643 /** 20644 * send_get_rcpi_cmd_tlv() - send request for rcpi value 20645 * @wmi_handle: wmi handle 20646 * @get_rcpi_param: rcpi params 20647 * 20648 * Return: QDF status 20649 */ 20650 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 20651 struct rcpi_req *get_rcpi_param) 20652 { 20653 wmi_buf_t buf; 20654 wmi_request_rcpi_cmd_fixed_param *cmd; 20655 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 20656 20657 buf = wmi_buf_alloc(wmi_handle, len); 20658 if (!buf) { 20659 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 20660 return QDF_STATUS_E_NOMEM; 20661 } 20662 20663 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 20664 WMITLV_SET_HDR(&cmd->tlv_header, 20665 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 20666 WMITLV_GET_STRUCT_TLVLEN 20667 (wmi_request_rcpi_cmd_fixed_param)); 20668 20669 cmd->vdev_id = get_rcpi_param->vdev_id; 20670 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 20671 &cmd->peer_macaddr); 20672 20673 switch (get_rcpi_param->measurement_type) { 20674 20675 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20676 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20677 break; 20678 20679 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 20680 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 20681 break; 20682 20683 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20684 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20685 break; 20686 20687 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 20688 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 20689 break; 20690 20691 default: 20692 /* 20693 * invalid rcpi measurement type, fall back to 20694 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 20695 */ 20696 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20697 break; 20698 } 20699 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 20700 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20701 WMI_REQUEST_RCPI_CMDID)) { 20702 20703 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 20704 __func__); 20705 wmi_buf_free(buf); 20706 return QDF_STATUS_E_FAILURE; 20707 } 20708 20709 return QDF_STATUS_SUCCESS; 20710 } 20711 20712 /** 20713 * extract_rcpi_response_event_tlv() - Extract RCPI event params 20714 * @wmi_handle: wmi handle 20715 * @evt_buf: pointer to event buffer 20716 * @res: pointer to hold rcpi response from firmware 20717 * 20718 * Return: QDF_STATUS_SUCCESS for successful event parse 20719 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 20720 */ 20721 static QDF_STATUS 20722 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 20723 void *evt_buf, struct rcpi_res *res) 20724 { 20725 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 20726 wmi_update_rcpi_event_fixed_param *event; 20727 20728 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 20729 if (!param_buf) { 20730 WMI_LOGE(FL("Invalid rcpi event")); 20731 return QDF_STATUS_E_INVAL; 20732 } 20733 20734 event = param_buf->fixed_param; 20735 res->vdev_id = event->vdev_id; 20736 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 20737 20738 switch (event->measurement_type) { 20739 20740 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20741 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20742 break; 20743 20744 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 20745 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 20746 break; 20747 20748 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20749 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20750 break; 20751 20752 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 20753 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 20754 break; 20755 20756 default: 20757 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 20758 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 20759 return QDF_STATUS_E_FAILURE; 20760 } 20761 20762 if (event->status) 20763 return QDF_STATUS_E_FAILURE; 20764 else 20765 return QDF_STATUS_SUCCESS; 20766 } 20767 20768 /** 20769 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 20770 * host to target defines. For legacy there is not conversion 20771 * required. Just return pdev_id as it is. 20772 * @param pdev_id: host pdev_id to be converted. 20773 * Return: target pdev_id after conversion. 20774 */ 20775 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 20776 uint32_t pdev_id) 20777 { 20778 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 20779 return WMI_PDEV_ID_SOC; 20780 20781 /*No conversion required*/ 20782 return pdev_id; 20783 } 20784 20785 /** 20786 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 20787 * target to host defines. For legacy there is not conversion 20788 * required. Just return pdev_id as it is. 20789 * @param pdev_id: target pdev_id to be converted. 20790 * Return: host pdev_id after conversion. 20791 */ 20792 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 20793 uint32_t pdev_id) 20794 { 20795 /*No conversion required*/ 20796 return pdev_id; 20797 } 20798 20799 /** 20800 * send_set_country_cmd_tlv() - WMI scan channel list function 20801 * @param wmi_handle : handle to WMI. 20802 * @param param : pointer to hold scan channel list parameter 20803 * 20804 * Return: 0 on success and -ve on failure. 20805 */ 20806 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 20807 struct set_country *params) 20808 { 20809 wmi_buf_t buf; 20810 QDF_STATUS qdf_status; 20811 wmi_set_current_country_cmd_fixed_param *cmd; 20812 uint16_t len = sizeof(*cmd); 20813 20814 buf = wmi_buf_alloc(wmi_handle, len); 20815 if (!buf) { 20816 WMI_LOGE("Failed to allocate memory"); 20817 qdf_status = QDF_STATUS_E_NOMEM; 20818 goto end; 20819 } 20820 20821 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 20822 WMITLV_SET_HDR(&cmd->tlv_header, 20823 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 20824 WMITLV_GET_STRUCT_TLVLEN 20825 (wmi_set_current_country_cmd_fixed_param)); 20826 20827 WMI_LOGD("setting cuurnet country to %s", params->country); 20828 20829 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 20830 20831 cmd->pdev_id = params->pdev_id; 20832 20833 qdf_status = wmi_unified_cmd_send(wmi_handle, 20834 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 20835 20836 if (QDF_IS_STATUS_ERROR(qdf_status)) { 20837 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 20838 wmi_buf_free(buf); 20839 } 20840 20841 end: 20842 return qdf_status; 20843 } 20844 20845 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 20846 WMI_SET_BITS(alpha, 0, 8, val0); \ 20847 WMI_SET_BITS(alpha, 8, 8, val1); \ 20848 WMI_SET_BITS(alpha, 16, 8, val2); \ 20849 } while (0) 20850 20851 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 20852 uint8_t pdev_id, struct cc_regdmn_s *rd) 20853 { 20854 wmi_set_init_country_cmd_fixed_param *cmd; 20855 uint16_t len; 20856 wmi_buf_t buf; 20857 int ret; 20858 20859 len = sizeof(wmi_set_init_country_cmd_fixed_param); 20860 buf = wmi_buf_alloc(wmi_handle, len); 20861 if (!buf) { 20862 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 20863 return QDF_STATUS_E_NOMEM; 20864 } 20865 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 20866 WMITLV_SET_HDR(&cmd->tlv_header, 20867 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 20868 WMITLV_GET_STRUCT_TLVLEN 20869 (wmi_set_init_country_cmd_fixed_param)); 20870 20871 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 20872 20873 if (rd->flags == CC_IS_SET) { 20874 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 20875 cmd->country_code.country_id = rd->cc.country_code; 20876 } else if (rd->flags == ALPHA_IS_SET) { 20877 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 20878 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 20879 rd->cc.alpha[0], 20880 rd->cc.alpha[1], 20881 rd->cc.alpha[2]); 20882 } else if (rd->flags == REGDMN_IS_SET) { 20883 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 20884 cmd->country_code.domain_code = rd->cc.regdmn_id; 20885 } 20886 20887 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20888 WMI_SET_INIT_COUNTRY_CMDID); 20889 if (ret) { 20890 WMI_LOGE("Failed to config wow wakeup event"); 20891 wmi_buf_free(buf); 20892 return QDF_STATUS_E_FAILURE; 20893 } 20894 20895 return QDF_STATUS_SUCCESS; 20896 } 20897 20898 /** 20899 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 20900 * configuration params 20901 * @wmi_handle: wmi handler 20902 * @limit_off_chan_param: pointer to wmi_off_chan_param 20903 * 20904 * Return: 0 for success and non zero for failure 20905 */ 20906 static 20907 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 20908 struct wmi_limit_off_chan_param *limit_off_chan_param) 20909 { 20910 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 20911 wmi_buf_t buf; 20912 uint32_t len = sizeof(*cmd); 20913 int err; 20914 20915 buf = wmi_buf_alloc(wmi_handle, len); 20916 if (!buf) { 20917 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 20918 __func__); 20919 return QDF_STATUS_E_NOMEM; 20920 } 20921 20922 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 20923 20924 WMITLV_SET_HDR(&cmd->tlv_header, 20925 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 20926 WMITLV_GET_STRUCT_TLVLEN( 20927 wmi_vdev_limit_offchan_cmd_fixed_param)); 20928 20929 cmd->vdev_id = limit_off_chan_param->vdev_id; 20930 20931 cmd->flags &= 0; 20932 if (limit_off_chan_param->status) 20933 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 20934 if (limit_off_chan_param->skip_dfs_chans) 20935 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 20936 20937 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 20938 cmd->rest_time = limit_off_chan_param->rest_time; 20939 20940 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 20941 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 20942 cmd->rest_time); 20943 20944 err = wmi_unified_cmd_send(wmi_handle, buf, 20945 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 20946 if (QDF_IS_STATUS_ERROR(err)) { 20947 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 20948 wmi_buf_free(buf); 20949 return QDF_STATUS_E_FAILURE; 20950 } 20951 20952 return QDF_STATUS_SUCCESS; 20953 } 20954 20955 /** 20956 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 20957 * @wmi_handle: wmi handler 20958 * @req_buf: set arp stats request buffer 20959 * 20960 * Return: 0 for success and non zero for failure 20961 */ 20962 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20963 struct set_arp_stats *req_buf) 20964 { 20965 wmi_buf_t buf = NULL; 20966 QDF_STATUS status; 20967 int len; 20968 uint8_t *buf_ptr; 20969 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 20970 20971 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20972 if (req_buf->pkt_type_bitmap) { 20973 len += WMI_TLV_HDR_SIZE; 20974 len += sizeof(wmi_vdev_set_connectivity_check_stats); 20975 } 20976 buf = wmi_buf_alloc(wmi_handle, len); 20977 if (!buf) { 20978 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 20979 return QDF_STATUS_E_NOMEM; 20980 } 20981 20982 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20983 wmi_set_arp = 20984 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 20985 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 20986 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 20987 WMITLV_GET_STRUCT_TLVLEN 20988 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 20989 20990 /* fill in per roam config values */ 20991 wmi_set_arp->vdev_id = req_buf->vdev_id; 20992 20993 wmi_set_arp->set_clr = req_buf->flag; 20994 wmi_set_arp->pkt_type = req_buf->pkt_type; 20995 wmi_set_arp->ipv4 = req_buf->ip_addr; 20996 20997 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 20998 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 20999 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 21000 21001 /* 21002 * pkt_type_bitmap should be non-zero to ensure 21003 * presence of additional stats. 21004 */ 21005 if (req_buf->pkt_type_bitmap) { 21006 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21007 21008 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21009 WMITLV_SET_HDR(buf_ptr, 21010 WMITLV_TAG_ARRAY_STRUC, 21011 sizeof(wmi_vdev_set_connectivity_check_stats)); 21012 buf_ptr += WMI_TLV_HDR_SIZE; 21013 wmi_set_connect_stats = 21014 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21015 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21016 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21017 WMITLV_GET_STRUCT_TLVLEN( 21018 wmi_vdev_set_connectivity_check_stats)); 21019 wmi_set_connect_stats->pkt_type_bitmap = 21020 req_buf->pkt_type_bitmap; 21021 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21022 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21023 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21024 21025 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21026 wmi_set_connect_stats->pkt_type_bitmap, 21027 wmi_set_connect_stats->tcp_src_port, 21028 wmi_set_connect_stats->tcp_dst_port, 21029 wmi_set_connect_stats->icmp_ipv4); 21030 } 21031 21032 /* Send per roam config parameters */ 21033 status = wmi_unified_cmd_send(wmi_handle, buf, 21034 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21035 if (QDF_IS_STATUS_ERROR(status)) { 21036 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21037 status); 21038 goto error; 21039 } 21040 21041 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 21042 req_buf->flag, req_buf->vdev_id); 21043 return QDF_STATUS_SUCCESS; 21044 error: 21045 wmi_buf_free(buf); 21046 21047 return status; 21048 } 21049 21050 /** 21051 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21052 * @wmi_handle: wmi handler 21053 * @req_buf: get arp stats request buffer 21054 * 21055 * Return: 0 for success and non zero for failure 21056 */ 21057 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21058 struct get_arp_stats *req_buf) 21059 { 21060 wmi_buf_t buf = NULL; 21061 QDF_STATUS status; 21062 int len; 21063 uint8_t *buf_ptr; 21064 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21065 21066 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21067 buf = wmi_buf_alloc(wmi_handle, len); 21068 if (!buf) { 21069 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21070 return QDF_STATUS_E_NOMEM; 21071 } 21072 21073 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21074 get_arp_stats = 21075 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21076 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21077 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21078 WMITLV_GET_STRUCT_TLVLEN 21079 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21080 21081 /* fill in arp stats req cmd values */ 21082 get_arp_stats->vdev_id = req_buf->vdev_id; 21083 21084 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21085 /* Send per roam config parameters */ 21086 status = wmi_unified_cmd_send(wmi_handle, buf, 21087 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21088 if (QDF_IS_STATUS_ERROR(status)) { 21089 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21090 status); 21091 goto error; 21092 } 21093 21094 return QDF_STATUS_SUCCESS; 21095 error: 21096 wmi_buf_free(buf); 21097 21098 return status; 21099 } 21100 21101 /** 21102 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21103 * @wmi_handle: wmi handler 21104 * @pmk_info: pointer to PMK cache entry 21105 * @vdev_id: vdev id 21106 * 21107 * Return: 0 for success and non zero for failure 21108 */ 21109 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21110 struct wmi_unified_pmk_cache *pmk_info) 21111 { 21112 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21113 wmi_buf_t buf; 21114 QDF_STATUS status; 21115 uint8_t *buf_ptr; 21116 wmi_pmk_cache *pmksa; 21117 uint32_t len = sizeof(*cmd); 21118 21119 if (pmk_info->pmk_len) 21120 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21121 21122 buf = wmi_buf_alloc(wmi_handle, len); 21123 if (!buf) { 21124 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21125 __func__); 21126 return QDF_STATUS_E_NOMEM; 21127 } 21128 21129 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21130 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21131 21132 WMITLV_SET_HDR(&cmd->tlv_header, 21133 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21134 WMITLV_GET_STRUCT_TLVLEN( 21135 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21136 21137 cmd->vdev_id = pmk_info->session_id; 21138 21139 /* If pmk_info->pmk_len is 0, this is a flush request */ 21140 if (!pmk_info->pmk_len) { 21141 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21142 cmd->num_cache = 0; 21143 goto send_cmd; 21144 } 21145 21146 cmd->num_cache = 1; 21147 buf_ptr += sizeof(*cmd); 21148 21149 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21150 sizeof(*pmksa)); 21151 buf_ptr += WMI_TLV_HDR_SIZE; 21152 21153 pmksa = (wmi_pmk_cache *)buf_ptr; 21154 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21155 WMITLV_GET_STRUCT_TLVLEN 21156 (wmi_pmk_cache)); 21157 pmksa->pmk_len = pmk_info->pmk_len; 21158 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21159 pmksa->pmkid_len = pmk_info->pmkid_len; 21160 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21161 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21162 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21163 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21164 pmksa->ssid.ssid_len); 21165 pmksa->cache_id = pmk_info->cache_id; 21166 pmksa->cat_flag = pmk_info->cat_flag; 21167 pmksa->action_flag = pmk_info->action_flag; 21168 21169 send_cmd: 21170 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21171 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21172 if (status != QDF_STATUS_SUCCESS) { 21173 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21174 __func__, status); 21175 wmi_buf_free(buf); 21176 } 21177 21178 return status; 21179 } 21180 21181 /** 21182 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21183 * @wmi_handle: wmi handle 21184 * @param: reserved param 21185 * 21186 * Return: 0 for success or error code 21187 */ 21188 static QDF_STATUS 21189 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21190 uint32_t param) 21191 { 21192 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21193 wmi_buf_t buf; 21194 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21195 21196 buf = wmi_buf_alloc(wmi_handle, len); 21197 if (!buf) { 21198 qdf_print("%s:wmi_buf_alloc failed", __func__); 21199 return QDF_STATUS_E_FAILURE; 21200 } 21201 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21202 WMITLV_SET_HDR(&cmd->tlv_header, 21203 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21204 WMITLV_GET_STRUCT_TLVLEN 21205 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21206 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21207 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21208 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21209 wmi_buf_free(buf); 21210 return QDF_STATUS_E_FAILURE; 21211 } 21212 21213 return QDF_STATUS_SUCCESS; 21214 } 21215 21216 /** 21217 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21218 * @wmi_handle: wmi handle 21219 * @param evt_buf: pointer to event buffer 21220 * @param param: Pointer to hold peer caldata version data 21221 * 21222 * Return: 0 for success or error code 21223 */ 21224 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21225 wmi_unified_t wmi_handle, 21226 void *evt_buf, 21227 wmi_host_pdev_check_cal_version_event *param) 21228 { 21229 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21230 wmi_pdev_check_cal_version_event_fixed_param *event; 21231 21232 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21233 if (!param_tlvs) { 21234 WMI_LOGE("invalid cal version event buf"); 21235 return QDF_STATUS_E_FAILURE; 21236 } 21237 event = param_tlvs->fixed_param; 21238 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21239 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21240 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21241 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21242 21243 param->software_cal_version = event->software_cal_version; 21244 param->board_cal_version = event->board_cal_version; 21245 param->cal_ok = event->cal_status; 21246 21247 return QDF_STATUS_SUCCESS; 21248 } 21249 21250 /* 21251 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21252 * @wmi_handle: wmi handle 21253 * @params: pointer to wmi_btm_config 21254 * 21255 * Return: QDF_STATUS 21256 */ 21257 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21258 struct wmi_btm_config *params) 21259 { 21260 21261 wmi_btm_config_fixed_param *cmd; 21262 wmi_buf_t buf; 21263 uint32_t len; 21264 21265 len = sizeof(*cmd); 21266 buf = wmi_buf_alloc(wmi_handle, len); 21267 if (!buf) { 21268 qdf_print("%s:wmi_buf_alloc failed", __func__); 21269 return QDF_STATUS_E_NOMEM; 21270 } 21271 21272 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21273 WMITLV_SET_HDR(&cmd->tlv_header, 21274 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21275 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21276 cmd->vdev_id = params->vdev_id; 21277 cmd->flags = params->btm_offload_config; 21278 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21279 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21280 cmd->stick_time_seconds = params->btm_sticky_time; 21281 21282 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21283 WMI_ROAM_BTM_CONFIG_CMDID)) { 21284 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21285 __func__); 21286 wmi_buf_free(buf); 21287 return QDF_STATUS_E_FAILURE; 21288 } 21289 21290 return QDF_STATUS_SUCCESS; 21291 } 21292 21293 /** 21294 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21295 * configurations to firmware. 21296 * @wmi_handle: wmi handle 21297 * @obss_cfg_param: obss detection configurations 21298 * 21299 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21300 * 21301 * Return: QDF_STATUS 21302 */ 21303 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21304 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21305 { 21306 wmi_buf_t buf; 21307 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21308 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21309 21310 buf = wmi_buf_alloc(wmi_handle, len); 21311 if (!buf) { 21312 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21313 return QDF_STATUS_E_NOMEM; 21314 } 21315 21316 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21317 WMITLV_SET_HDR(&cmd->tlv_header, 21318 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21319 WMITLV_GET_STRUCT_TLVLEN 21320 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21321 21322 cmd->vdev_id = obss_cfg_param->vdev_id; 21323 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21324 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21325 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21326 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21327 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21328 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21329 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21330 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21331 21332 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21333 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21334 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21335 wmi_buf_free(buf); 21336 return QDF_STATUS_E_FAILURE; 21337 } 21338 21339 return QDF_STATUS_SUCCESS; 21340 } 21341 21342 /** 21343 * extract_obss_detection_info_tlv() - Extract obss detection info 21344 * received from firmware. 21345 * @evt_buf: pointer to event buffer 21346 * @obss_detection: Pointer to hold obss detection info 21347 * 21348 * Return: QDF_STATUS 21349 */ 21350 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21351 struct wmi_obss_detect_info 21352 *obss_detection) 21353 { 21354 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21355 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21356 21357 if (!obss_detection) { 21358 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21359 return QDF_STATUS_E_INVAL; 21360 } 21361 21362 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21363 if (!param_buf) { 21364 WMI_LOGE("%s: Invalid evt_buf", __func__); 21365 return QDF_STATUS_E_INVAL; 21366 } 21367 21368 fix_param = param_buf->fixed_param; 21369 obss_detection->vdev_id = fix_param->vdev_id; 21370 obss_detection->matched_detection_masks = 21371 fix_param->matched_detection_masks; 21372 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21373 &obss_detection->matched_bssid_addr[0]); 21374 switch (fix_param->reason) { 21375 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21376 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21377 break; 21378 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21379 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21380 break; 21381 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21382 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21383 break; 21384 default: 21385 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21386 return QDF_STATUS_E_INVAL; 21387 } 21388 21389 return QDF_STATUS_SUCCESS; 21390 } 21391 21392 /** 21393 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 21394 * @wmi_handle: wmi handler 21395 * @params: pointer to 11k offload params 21396 * 21397 * Return: 0 for success and non zero for failure 21398 */ 21399 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 21400 struct wmi_11k_offload_params *params) 21401 { 21402 wmi_11k_offload_report_fixed_param *cmd; 21403 wmi_buf_t buf; 21404 QDF_STATUS status; 21405 uint8_t *buf_ptr; 21406 wmi_neighbor_report_11k_offload_tlv_param 21407 *neighbor_report_offload_params; 21408 wmi_neighbor_report_offload *neighbor_report_offload; 21409 21410 uint32_t len = sizeof(*cmd); 21411 21412 if (params->offload_11k_bitmask & 21413 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 21414 len += WMI_TLV_HDR_SIZE + 21415 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 21416 21417 buf = wmi_buf_alloc(wmi_handle, len); 21418 if (!buf) { 21419 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 21420 __func__); 21421 return QDF_STATUS_E_NOMEM; 21422 } 21423 21424 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21425 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 21426 21427 WMITLV_SET_HDR(&cmd->tlv_header, 21428 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 21429 WMITLV_GET_STRUCT_TLVLEN( 21430 wmi_11k_offload_report_fixed_param)); 21431 21432 cmd->vdev_id = params->vdev_id; 21433 cmd->offload_11k = params->offload_11k_bitmask; 21434 21435 if (params->offload_11k_bitmask & 21436 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 21437 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 21438 21439 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21440 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 21441 buf_ptr += WMI_TLV_HDR_SIZE; 21442 21443 neighbor_report_offload_params = 21444 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 21445 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 21446 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 21447 WMITLV_GET_STRUCT_TLVLEN( 21448 wmi_neighbor_report_11k_offload_tlv_param)); 21449 21450 neighbor_report_offload = &neighbor_report_offload_params-> 21451 neighbor_rep_ofld_params; 21452 21453 neighbor_report_offload->time_offset = 21454 params->neighbor_report_params.time_offset; 21455 neighbor_report_offload->low_rssi_offset = 21456 params->neighbor_report_params.low_rssi_offset; 21457 neighbor_report_offload->bmiss_count_trigger = 21458 params->neighbor_report_params.bmiss_count_trigger; 21459 neighbor_report_offload->per_threshold_offset = 21460 params->neighbor_report_params.per_threshold_offset; 21461 neighbor_report_offload->neighbor_report_cache_timeout = 21462 params->neighbor_report_params. 21463 neighbor_report_cache_timeout; 21464 neighbor_report_offload->max_neighbor_report_req_cap = 21465 params->neighbor_report_params. 21466 max_neighbor_report_req_cap; 21467 neighbor_report_offload->ssid.ssid_len = 21468 params->neighbor_report_params.ssid.length; 21469 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 21470 ¶ms->neighbor_report_params.ssid.mac_ssid, 21471 neighbor_report_offload->ssid.ssid_len); 21472 } 21473 21474 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21475 WMI_11K_OFFLOAD_REPORT_CMDID); 21476 if (status != QDF_STATUS_SUCCESS) { 21477 WMI_LOGE("%s: failed to send 11k offload command %d", 21478 __func__, status); 21479 wmi_buf_free(buf); 21480 } 21481 21482 return status; 21483 } 21484 21485 /** 21486 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 21487 * command 21488 * @wmi_handle: wmi handler 21489 * @params: pointer to neighbor report invoke params 21490 * 21491 * Return: 0 for success and non zero for failure 21492 */ 21493 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 21494 struct wmi_invoke_neighbor_report_params *params) 21495 { 21496 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 21497 wmi_buf_t buf; 21498 QDF_STATUS status; 21499 uint8_t *buf_ptr; 21500 uint32_t len = sizeof(*cmd); 21501 21502 buf = wmi_buf_alloc(wmi_handle, len); 21503 if (!buf) { 21504 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 21505 __func__); 21506 return QDF_STATUS_E_NOMEM; 21507 } 21508 21509 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21510 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 21511 21512 WMITLV_SET_HDR(&cmd->tlv_header, 21513 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 21514 WMITLV_GET_STRUCT_TLVLEN( 21515 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 21516 21517 cmd->vdev_id = params->vdev_id; 21518 cmd->flags = params->send_resp_to_host; 21519 21520 cmd->ssid.ssid_len = params->ssid.length; 21521 qdf_mem_copy(cmd->ssid.ssid, 21522 ¶ms->ssid.mac_ssid, 21523 cmd->ssid.ssid_len); 21524 21525 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21526 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 21527 if (status != QDF_STATUS_SUCCESS) { 21528 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 21529 __func__, status); 21530 wmi_buf_free(buf); 21531 } 21532 21533 return status; 21534 } 21535 21536 #ifdef WLAN_SUPPORT_GREEN_AP 21537 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 21538 uint8_t *evt_buf, 21539 struct wlan_green_ap_egap_status_info *egap_status_info_params) 21540 { 21541 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 21542 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 21543 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 21544 21545 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 21546 if (!param_buf) { 21547 WMI_LOGE("Invalid EGAP Info status event buffer"); 21548 return QDF_STATUS_E_INVAL; 21549 } 21550 21551 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 21552 param_buf->fixed_param; 21553 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 21554 param_buf->chainmask_list; 21555 21556 egap_status_info_params->status = egap_info_event->status; 21557 egap_status_info_params->mac_id = chainmask_event->mac_id; 21558 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 21559 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 21560 21561 return QDF_STATUS_SUCCESS; 21562 } 21563 #endif 21564 21565 /* 21566 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 21567 * updating bss color change within firmware when AP announces bss color change. 21568 * @wmi_handle: wmi handle 21569 * @vdev_id: vdev ID 21570 * @enable: enable bss color change within firmware 21571 * 21572 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 21573 * 21574 * Return: QDF_STATUS 21575 */ 21576 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 21577 uint32_t vdev_id, 21578 bool enable) 21579 { 21580 wmi_buf_t buf; 21581 wmi_bss_color_change_enable_fixed_param *cmd; 21582 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 21583 21584 buf = wmi_buf_alloc(wmi_handle, len); 21585 if (!buf) { 21586 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21587 return QDF_STATUS_E_NOMEM; 21588 } 21589 21590 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 21591 WMITLV_SET_HDR(&cmd->tlv_header, 21592 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 21593 WMITLV_GET_STRUCT_TLVLEN 21594 (wmi_bss_color_change_enable_fixed_param)); 21595 cmd->vdev_id = vdev_id; 21596 cmd->enable = enable; 21597 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21598 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 21599 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 21600 wmi_buf_free(buf); 21601 return QDF_STATUS_E_FAILURE; 21602 } 21603 21604 return QDF_STATUS_SUCCESS; 21605 } 21606 21607 /** 21608 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 21609 * configurations to firmware. 21610 * @wmi_handle: wmi handle 21611 * @cfg_param: obss detection configurations 21612 * 21613 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 21614 * 21615 * Return: QDF_STATUS 21616 */ 21617 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 21618 wmi_unified_t wmi_handle, 21619 struct wmi_obss_color_collision_cfg_param *cfg_param) 21620 { 21621 wmi_buf_t buf; 21622 wmi_obss_color_collision_det_config_fixed_param *cmd; 21623 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 21624 21625 buf = wmi_buf_alloc(wmi_handle, len); 21626 if (!buf) { 21627 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21628 return QDF_STATUS_E_NOMEM; 21629 } 21630 21631 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 21632 buf); 21633 WMITLV_SET_HDR(&cmd->tlv_header, 21634 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 21635 WMITLV_GET_STRUCT_TLVLEN 21636 (wmi_obss_color_collision_det_config_fixed_param)); 21637 cmd->vdev_id = cfg_param->vdev_id; 21638 cmd->flags = cfg_param->flags; 21639 cmd->current_bss_color = cfg_param->current_bss_color; 21640 cmd->detection_period_ms = cfg_param->detection_period_ms; 21641 cmd->scan_period_ms = cfg_param->scan_period_ms; 21642 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 21643 21644 switch (cfg_param->evt_type) { 21645 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 21646 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 21647 break; 21648 case OBSS_COLOR_COLLISION_DETECTION: 21649 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 21650 break; 21651 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21652 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21653 break; 21654 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 21655 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 21656 break; 21657 default: 21658 WMI_LOGE("%s: invalid event type: %d", 21659 __func__, cfg_param->evt_type); 21660 wmi_buf_free(buf); 21661 return QDF_STATUS_E_FAILURE; 21662 } 21663 21664 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21665 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 21666 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 21667 __func__, cfg_param->vdev_id); 21668 wmi_buf_free(buf); 21669 return QDF_STATUS_E_FAILURE; 21670 } 21671 21672 return QDF_STATUS_SUCCESS; 21673 } 21674 21675 /** 21676 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 21677 * received from firmware. 21678 * @evt_buf: pointer to event buffer 21679 * @info: Pointer to hold bss collision info 21680 * 21681 * Return: QDF_STATUS 21682 */ 21683 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 21684 struct wmi_obss_color_collision_info *info) 21685 { 21686 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 21687 wmi_obss_color_collision_evt_fixed_param *fix_param; 21688 21689 if (!info) { 21690 WMI_LOGE("%s: Invalid obss color buffer", __func__); 21691 return QDF_STATUS_E_INVAL; 21692 } 21693 21694 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 21695 evt_buf; 21696 if (!param_buf) { 21697 WMI_LOGE("%s: Invalid evt_buf", __func__); 21698 return QDF_STATUS_E_INVAL; 21699 } 21700 21701 fix_param = param_buf->fixed_param; 21702 info->vdev_id = fix_param->vdev_id; 21703 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 21704 info->obss_color_bitmap_bit32to63 = 21705 fix_param->bss_color_bitmap_bit32to63; 21706 21707 switch (fix_param->evt_type) { 21708 case WMI_BSS_COLOR_COLLISION_DISABLE: 21709 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 21710 break; 21711 case WMI_BSS_COLOR_COLLISION_DETECTION: 21712 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 21713 break; 21714 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21715 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21716 break; 21717 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 21718 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 21719 break; 21720 default: 21721 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 21722 __func__, fix_param->evt_type, fix_param->vdev_id); 21723 return QDF_STATUS_E_FAILURE; 21724 } 21725 21726 return QDF_STATUS_SUCCESS; 21727 } 21728 21729 /* 21730 * extract_comb_phyerr_tlv() - extract comb phy error from event 21731 * @wmi_handle: wmi handle 21732 * @evt_buf: pointer to event buffer 21733 * @datalen: data length of event buffer 21734 * @buf_offset: Pointer to hold value of current event buffer offset 21735 * post extraction 21736 * @phyerr: Pointer to hold phyerr 21737 * 21738 * Return: QDF_STATUS 21739 */ 21740 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 21741 void *evt_buf, 21742 uint16_t datalen, 21743 uint16_t *buf_offset, 21744 wmi_host_phyerr_t *phyerr) 21745 { 21746 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 21747 wmi_comb_phyerr_rx_hdr *pe_hdr; 21748 21749 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 21750 if (!param_tlvs) { 21751 WMI_LOGD("%s: Received null data from FW", __func__); 21752 return QDF_STATUS_E_FAILURE; 21753 } 21754 21755 pe_hdr = param_tlvs->hdr; 21756 if (!pe_hdr) { 21757 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 21758 return QDF_STATUS_E_FAILURE; 21759 } 21760 21761 /* Ensure it's at least the size of the header */ 21762 if (datalen < sizeof(*pe_hdr)) { 21763 WMI_LOGD("%s: Expected minimum size %zu, received %d", 21764 __func__, sizeof(*pe_hdr), datalen); 21765 return QDF_STATUS_E_FAILURE; 21766 } 21767 21768 phyerr->pdev_id = wmi_handle->ops-> 21769 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 21770 phyerr->tsf64 = pe_hdr->tsf_l32; 21771 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 21772 phyerr->bufp = param_tlvs->bufp; 21773 phyerr->buf_len = pe_hdr->buf_len; 21774 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 21775 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 21776 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 21777 21778 return QDF_STATUS_SUCCESS; 21779 } 21780 21781 /** 21782 * extract_single_phyerr_tlv() - extract single phy error from event 21783 * @wmi_handle: wmi handle 21784 * @evt_buf: pointer to event buffer 21785 * @datalen: data length of event buffer 21786 * @buf_offset: Pointer to hold value of current event buffer offset 21787 * post extraction 21788 * @phyerr: Pointer to hold phyerr 21789 * 21790 * Return: QDF_STATUS 21791 */ 21792 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 21793 void *evt_buf, 21794 uint16_t datalen, 21795 uint16_t *buf_offset, 21796 wmi_host_phyerr_t *phyerr) 21797 { 21798 wmi_single_phyerr_rx_event *ev; 21799 uint16_t n = *buf_offset; 21800 uint8_t *data = (uint8_t *)evt_buf; 21801 21802 if (n < datalen) { 21803 if ((datalen - n) < sizeof(ev->hdr)) { 21804 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 21805 __func__, datalen, n, sizeof(ev->hdr)); 21806 return QDF_STATUS_E_FAILURE; 21807 } 21808 21809 /* 21810 * Obtain a pointer to the beginning of the current event. 21811 * data[0] is the beginning of the WMI payload. 21812 */ 21813 ev = (wmi_single_phyerr_rx_event *)&data[n]; 21814 21815 /* 21816 * Sanity check the buffer length of the event against 21817 * what we currently have. 21818 * 21819 * Since buf_len is 32 bits, we check if it overflows 21820 * a large 32 bit value. It's not 0x7fffffff because 21821 * we increase n by (buf_len + sizeof(hdr)), which would 21822 * in itself cause n to overflow. 21823 * 21824 * If "int" is 64 bits then this becomes a moot point. 21825 */ 21826 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 21827 WMI_LOGD("%s: buf_len is garbage 0x%x", 21828 __func__, ev->hdr.buf_len); 21829 return QDF_STATUS_E_FAILURE; 21830 } 21831 21832 if ((n + ev->hdr.buf_len) > datalen) { 21833 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 21834 __func__, n, ev->hdr.buf_len, datalen); 21835 return QDF_STATUS_E_FAILURE; 21836 } 21837 21838 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 21839 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 21840 phyerr->bufp = &ev->bufp[0]; 21841 phyerr->buf_len = ev->hdr.buf_len; 21842 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 21843 21844 /* 21845 * Advance the buffer pointer to the next PHY error. 21846 * buflen is the length of this payload, so we need to 21847 * advance past the current header _AND_ the payload. 21848 */ 21849 n += sizeof(*ev) + ev->hdr.buf_len; 21850 } 21851 *buf_offset = n; 21852 21853 return QDF_STATUS_SUCCESS; 21854 } 21855 21856 struct wmi_ops tlv_ops = { 21857 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21858 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21859 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21860 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21861 .send_hidden_ssid_vdev_restart_cmd = 21862 send_hidden_ssid_vdev_restart_cmd_tlv, 21863 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21864 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21865 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21866 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21867 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21868 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21869 .send_peer_rx_reorder_queue_setup_cmd = 21870 send_peer_rx_reorder_queue_setup_cmd_tlv, 21871 .send_peer_rx_reorder_queue_remove_cmd = 21872 send_peer_rx_reorder_queue_remove_cmd_tlv, 21873 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 21874 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 21875 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 21876 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21877 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21878 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 21879 .send_suspend_cmd = send_suspend_cmd_tlv, 21880 .send_resume_cmd = send_resume_cmd_tlv, 21881 #ifdef FEATURE_WLAN_D0WOW 21882 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 21883 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 21884 #endif 21885 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21886 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21887 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21888 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21889 #ifdef FEATURE_FW_LOG_PARSING 21890 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21891 #endif 21892 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21893 .send_stats_request_cmd = send_stats_request_cmd_tlv, 21894 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21895 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21896 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21897 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 21898 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21899 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21900 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21901 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21902 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21903 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21904 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21905 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21906 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21907 .send_set_sta_uapsd_auto_trig_cmd = 21908 send_set_sta_uapsd_auto_trig_cmd_tlv, 21909 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21910 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 21911 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 21912 #ifdef CONVERGED_P2P_ENABLE 21913 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 21914 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 21915 #endif 21916 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21917 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21918 #ifdef WLAN_FEATURE_DSRC 21919 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 21920 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 21921 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 21922 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 21923 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 21924 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 21925 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 21926 .send_ocb_start_timing_advert_cmd = 21927 send_ocb_start_timing_advert_cmd_tlv, 21928 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 21929 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 21930 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 21931 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 21932 #endif 21933 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 21934 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 21935 .send_set_mcc_channel_time_latency_cmd = 21936 send_set_mcc_channel_time_latency_cmd_tlv, 21937 .send_set_mcc_channel_time_quota_cmd = 21938 send_set_mcc_channel_time_quota_cmd_tlv, 21939 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21940 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21941 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21942 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 21943 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 21944 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 21945 .send_probe_rsp_tmpl_send_cmd = 21946 send_probe_rsp_tmpl_send_cmd_tlv, 21947 .send_p2p_go_set_beacon_ie_cmd = 21948 send_p2p_go_set_beacon_ie_cmd_tlv, 21949 .send_setup_install_key_cmd = 21950 send_setup_install_key_cmd_tlv, 21951 .send_set_gateway_params_cmd = 21952 send_set_gateway_params_cmd_tlv, 21953 .send_set_rssi_monitoring_cmd = 21954 send_set_rssi_monitoring_cmd_tlv, 21955 .send_scan_probe_setoui_cmd = 21956 send_scan_probe_setoui_cmd_tlv, 21957 .send_roam_scan_offload_rssi_thresh_cmd = 21958 send_roam_scan_offload_rssi_thresh_cmd_tlv, 21959 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 21960 .send_roam_scan_filter_cmd = 21961 send_roam_scan_filter_cmd_tlv, 21962 #ifdef IPA_OFFLOAD 21963 .send_ipa_offload_control_cmd = 21964 send_ipa_offload_control_cmd_tlv, 21965 #endif 21966 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 21967 .send_plm_start_cmd = send_plm_start_cmd_tlv, 21968 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21969 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21970 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21971 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 21972 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21973 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21974 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21975 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21976 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21977 .send_congestion_cmd = send_congestion_cmd_tlv, 21978 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21979 .send_snr_cmd = send_snr_cmd_tlv, 21980 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21981 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 21982 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 21983 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 21984 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 21985 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 21986 .send_multiple_add_clear_mcbc_filter_cmd = 21987 send_multiple_add_clear_mcbc_filter_cmd_tlv, 21988 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 21989 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 21990 .send_process_gtk_offload_getinfo_cmd = 21991 send_process_gtk_offload_getinfo_cmd_tlv, 21992 .send_enable_enhance_multicast_offload_cmd = 21993 send_enable_enhance_multicast_offload_tlv, 21994 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 21995 #ifdef FEATURE_WLAN_RA_FILTERING 21996 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 21997 #endif 21998 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 21999 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 22000 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 22001 .send_lphb_config_tcp_pkt_filter_cmd = 22002 send_lphb_config_tcp_pkt_filter_cmd_tlv, 22003 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22004 .send_lphb_config_udp_pkt_filter_cmd = 22005 send_lphb_config_udp_pkt_filter_cmd_tlv, 22006 .send_enable_disable_packet_filter_cmd = 22007 send_enable_disable_packet_filter_cmd_tlv, 22008 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22009 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 22010 #ifdef CONFIG_MCL 22011 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22012 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22013 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22014 .send_roam_scan_offload_mode_cmd = 22015 send_roam_scan_offload_mode_cmd_tlv, 22016 #ifndef REMOVE_PKT_LOG 22017 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22018 #endif 22019 .send_roam_scan_offload_ap_profile_cmd = 22020 send_roam_scan_offload_ap_profile_cmd_tlv, 22021 #endif 22022 #ifdef WLAN_SUPPORT_GREEN_AP 22023 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22024 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22025 .extract_green_ap_egap_status_info = 22026 extract_green_ap_egap_status_info_tlv, 22027 #endif 22028 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22029 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22030 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22031 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22032 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22033 #ifdef WLAN_FEATURE_CIF_CFR 22034 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22035 #endif 22036 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22037 .send_dfs_phyerr_filter_offload_en_cmd = 22038 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22039 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22040 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22041 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22042 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22043 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22044 .send_process_add_periodic_tx_ptrn_cmd = 22045 send_process_add_periodic_tx_ptrn_cmd_tlv, 22046 .send_process_del_periodic_tx_ptrn_cmd = 22047 send_process_del_periodic_tx_ptrn_cmd_tlv, 22048 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22049 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22050 .send_set_app_type2_params_in_fw_cmd = 22051 send_set_app_type2_params_in_fw_cmd_tlv, 22052 .send_set_auto_shutdown_timer_cmd = 22053 send_set_auto_shutdown_timer_cmd_tlv, 22054 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22055 .send_process_dhcpserver_offload_cmd = 22056 send_process_dhcpserver_offload_cmd_tlv, 22057 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22058 .send_process_ch_avoid_update_cmd = 22059 send_process_ch_avoid_update_cmd_tlv, 22060 .send_pdev_set_regdomain_cmd = 22061 send_pdev_set_regdomain_cmd_tlv, 22062 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22063 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22064 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22065 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22066 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22067 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22068 .check_and_update_fw_version = 22069 check_and_update_fw_version_cmd_tlv, 22070 .send_set_base_macaddr_indicate_cmd = 22071 send_set_base_macaddr_indicate_cmd_tlv, 22072 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22073 .send_enable_specific_fw_logs_cmd = 22074 send_enable_specific_fw_logs_cmd_tlv, 22075 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22076 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22077 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22078 #ifdef WLAN_POLICY_MGR_ENABLE 22079 .send_pdev_set_dual_mac_config_cmd = 22080 send_pdev_set_dual_mac_config_cmd_tlv, 22081 #endif 22082 .send_app_type1_params_in_fw_cmd = 22083 send_app_type1_params_in_fw_cmd_tlv, 22084 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22085 .send_process_roam_synch_complete_cmd = 22086 send_process_roam_synch_complete_cmd_tlv, 22087 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22088 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22089 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22090 .send_roam_scan_offload_scan_period_cmd = 22091 send_roam_scan_offload_scan_period_cmd_tlv, 22092 .send_roam_scan_offload_chan_list_cmd = 22093 send_roam_scan_offload_chan_list_cmd_tlv, 22094 .send_roam_scan_offload_rssi_change_cmd = 22095 send_roam_scan_offload_rssi_change_cmd_tlv, 22096 #ifdef FEATURE_WLAN_APF 22097 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 22098 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 22099 .send_apf_write_work_memory_cmd = 22100 wmi_send_apf_write_work_memory_cmd_tlv, 22101 .send_apf_read_work_memory_cmd = 22102 wmi_send_apf_read_work_memory_cmd_tlv, 22103 .extract_apf_read_memory_resp_event = 22104 wmi_extract_apf_read_memory_resp_event_tlv, 22105 #endif /* FEATURE_WLAN_APF */ 22106 .send_adapt_dwelltime_params_cmd = 22107 send_adapt_dwelltime_params_cmd_tlv, 22108 .send_dbs_scan_sel_params_cmd = 22109 send_dbs_scan_sel_params_cmd_tlv, 22110 .init_cmd_send = init_cmd_send_tlv, 22111 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22112 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22113 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22114 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22115 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22116 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22117 .send_vdev_set_custom_aggr_size_cmd = 22118 send_vdev_set_custom_aggr_size_cmd_tlv, 22119 .send_vdev_set_qdepth_thresh_cmd = 22120 send_vdev_set_qdepth_thresh_cmd_tlv, 22121 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22122 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22123 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22124 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22125 .send_smart_ant_set_training_info_cmd = 22126 send_smart_ant_set_training_info_cmd_tlv, 22127 .send_smart_ant_set_node_config_cmd = 22128 send_smart_ant_set_node_config_cmd_tlv, 22129 #ifdef WLAN_ATF_ENABLE 22130 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22131 #endif 22132 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22133 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22134 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22135 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22136 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22137 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22138 .send_periodic_chan_stats_config_cmd = 22139 send_periodic_chan_stats_config_cmd_tlv, 22140 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22141 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22142 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22143 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22144 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22145 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22146 .send_vdev_spectral_configure_cmd = 22147 send_vdev_spectral_configure_cmd_tlv, 22148 .send_vdev_spectral_enable_cmd = 22149 send_vdev_spectral_enable_cmd_tlv, 22150 .send_thermal_mitigation_param_cmd = 22151 send_thermal_mitigation_param_cmd_tlv, 22152 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22153 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22154 .send_process_update_edca_param_cmd = 22155 send_process_update_edca_param_cmd_tlv, 22156 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22157 .send_set_country_cmd = send_set_country_cmd_tlv, 22158 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22159 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22160 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22161 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22162 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22163 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22164 .extract_host_mem_req = extract_host_mem_req_tlv, 22165 .save_service_bitmap = save_service_bitmap_tlv, 22166 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22167 .is_service_enabled = is_service_enabled_tlv, 22168 .save_fw_version = save_fw_version_in_service_ready_tlv, 22169 .ready_extract_init_status = ready_extract_init_status_tlv, 22170 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22171 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22172 .extract_ready_event_params = extract_ready_event_params_tlv, 22173 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22174 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22175 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22176 .extract_tbttoffset_update_params = 22177 extract_tbttoffset_update_params_tlv, 22178 .extract_ext_tbttoffset_update_params = 22179 extract_ext_tbttoffset_update_params_tlv, 22180 .extract_tbttoffset_num_vdevs = 22181 extract_tbttoffset_num_vdevs_tlv, 22182 .extract_ext_tbttoffset_num_vdevs = 22183 extract_ext_tbttoffset_num_vdevs_tlv, 22184 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22185 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22186 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22187 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22188 #ifdef CONVERGED_TDLS_ENABLE 22189 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22190 #endif 22191 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22192 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22193 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22194 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22195 #ifdef CONVERGED_P2P_ENABLE 22196 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22197 .extract_p2p_lo_stop_ev_param = 22198 extract_p2p_lo_stop_ev_param_tlv, 22199 #endif 22200 .extract_offchan_data_tx_compl_param = 22201 extract_offchan_data_tx_compl_param_tlv, 22202 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22203 .extract_all_stats_count = extract_all_stats_counts_tlv, 22204 .extract_pdev_stats = extract_pdev_stats_tlv, 22205 .extract_unit_test = extract_unit_test_tlv, 22206 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22207 .extract_vdev_stats = extract_vdev_stats_tlv, 22208 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22209 .extract_peer_stats = extract_peer_stats_tlv, 22210 .extract_bcn_stats = extract_bcn_stats_tlv, 22211 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22212 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22213 .extract_chan_stats = extract_chan_stats_tlv, 22214 .extract_profile_ctx = extract_profile_ctx_tlv, 22215 .extract_profile_data = extract_profile_data_tlv, 22216 .extract_chan_info_event = extract_chan_info_event_tlv, 22217 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22218 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22219 #ifdef WLAN_FEATURE_DISA 22220 .send_encrypt_decrypt_send_cmd = 22221 send_encrypt_decrypt_send_cmd_tlv, 22222 .extract_encrypt_decrypt_resp_event = 22223 extract_encrypt_decrypt_resp_event_tlv, 22224 #endif 22225 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22226 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22227 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22228 .extract_sar2_result_event = extract_sar2_result_event_tlv, 22229 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22230 .send_multiple_vdev_restart_req_cmd = 22231 send_multiple_vdev_restart_req_cmd_tlv, 22232 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22233 .extract_hw_mode_cap_service_ready_ext = 22234 extract_hw_mode_cap_service_ready_ext_tlv, 22235 .extract_mac_phy_cap_service_ready_ext = 22236 extract_mac_phy_cap_service_ready_ext_tlv, 22237 .extract_reg_cap_service_ready_ext = 22238 extract_reg_cap_service_ready_ext_tlv, 22239 .extract_dbr_ring_cap_service_ready_ext = 22240 extract_dbr_ring_cap_service_ready_ext_tlv, 22241 .extract_sar_cap_service_ready_ext = 22242 extract_sar_cap_service_ready_ext_tlv, 22243 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22244 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22245 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22246 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22247 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22248 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22249 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22250 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22251 .extract_fips_event_data = extract_fips_event_data_tlv, 22252 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22253 .extract_peer_delete_response_event = 22254 extract_peer_delete_response_event_tlv, 22255 .is_management_record = is_management_record_tlv, 22256 .extract_pdev_csa_switch_count_status = 22257 extract_pdev_csa_switch_count_status_tlv, 22258 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22259 .extract_pdev_tpc_config_ev_param = 22260 extract_pdev_tpc_config_ev_param_tlv, 22261 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22262 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22263 .extract_peer_sta_ps_statechange_ev = 22264 extract_peer_sta_ps_statechange_ev_tlv, 22265 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22266 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22267 #ifdef WLAN_FEATURE_ACTION_OUI 22268 .send_action_oui_cmd = send_action_oui_cmd_tlv, 22269 #endif 22270 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22271 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22272 .extract_reg_chan_list_update_event = 22273 extract_reg_chan_list_update_event_tlv, 22274 .extract_chainmask_tables = 22275 extract_chainmask_tables_tlv, 22276 .extract_thermal_stats = extract_thermal_stats_tlv, 22277 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22278 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22279 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22280 #ifdef DFS_COMPONENT_ENABLE 22281 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22282 .extract_dfs_radar_detection_event = 22283 extract_dfs_radar_detection_event_tlv, 22284 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22285 #endif 22286 .convert_pdev_id_host_to_target = 22287 convert_host_pdev_id_to_target_pdev_id_legacy, 22288 .convert_pdev_id_target_to_host = 22289 convert_target_pdev_id_to_host_pdev_id_legacy, 22290 22291 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22292 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22293 .extract_reg_11d_new_country_event = 22294 extract_reg_11d_new_country_event_tlv, 22295 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22296 .send_limit_off_chan_cmd = 22297 send_limit_off_chan_cmd_tlv, 22298 .extract_reg_ch_avoid_event = 22299 extract_reg_ch_avoid_event_tlv, 22300 .send_pdev_caldata_version_check_cmd = 22301 send_pdev_caldata_version_check_cmd_tlv, 22302 .extract_pdev_caldata_version_check_ev_param = 22303 extract_pdev_caldata_version_check_ev_param_tlv, 22304 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22305 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22306 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22307 #if defined(WLAN_FEATURE_FILS_SK) 22308 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22309 #endif 22310 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22311 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22312 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22313 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22314 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22315 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22316 .extract_ndp_ind = extract_ndp_ind_tlv, 22317 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22318 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22319 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22320 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22321 .extract_ndp_sch_update = extract_ndp_sch_update_tlv, 22322 #endif 22323 .send_btm_config = send_btm_config_cmd_tlv, 22324 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22325 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22326 #ifdef WLAN_SUPPORT_FILS 22327 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22328 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22329 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22330 #endif /* WLAN_SUPPORT_FILS */ 22331 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22332 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22333 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22334 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22335 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22336 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22337 .send_bss_color_change_enable_cmd = 22338 send_bss_color_change_enable_cmd_tlv, 22339 .send_obss_color_collision_cfg_cmd = 22340 send_obss_color_collision_cfg_cmd_tlv, 22341 .extract_obss_color_collision_info = 22342 extract_obss_color_collision_info_tlv, 22343 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22344 .extract_single_phyerr = extract_single_phyerr_tlv, 22345 #ifdef QCA_SUPPORT_CP_STATS 22346 .extract_cca_stats = extract_cca_stats_tlv, 22347 #endif 22348 }; 22349 22350 /** 22351 * populate_tlv_event_id() - populates wmi event ids 22352 * 22353 * @param event_ids: Pointer to hold event ids 22354 * Return: None 22355 */ 22356 static void populate_tlv_events_id(uint32_t *event_ids) 22357 { 22358 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22359 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22360 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22361 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22362 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22363 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22364 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22365 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22366 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22367 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22368 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22369 event_ids[wmi_service_ready_ext_event_id] = 22370 WMI_SERVICE_READY_EXT_EVENTID; 22371 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22372 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22373 event_ids[wmi_vdev_install_key_complete_event_id] = 22374 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22375 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22376 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22377 22378 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22379 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22380 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22381 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22382 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22383 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22384 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22385 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22386 event_ids[wmi_peer_delete_response_event_id] = 22387 WMI_PEER_DELETE_RESP_EVENTID; 22388 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22389 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22390 event_ids[wmi_tbttoffset_update_event_id] = 22391 WMI_TBTTOFFSET_UPDATE_EVENTID; 22392 event_ids[wmi_ext_tbttoffset_update_event_id] = 22393 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22394 event_ids[wmi_offload_bcn_tx_status_event_id] = 22395 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22396 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22397 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22398 event_ids[wmi_mgmt_tx_completion_event_id] = 22399 WMI_MGMT_TX_COMPLETION_EVENTID; 22400 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22401 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22402 event_ids[wmi_tx_delba_complete_event_id] = 22403 WMI_TX_DELBA_COMPLETE_EVENTID; 22404 event_ids[wmi_tx_addba_complete_event_id] = 22405 WMI_TX_ADDBA_COMPLETE_EVENTID; 22406 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22407 22408 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22409 22410 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22411 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22412 22413 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22414 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22415 22416 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22417 22418 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22419 event_ids[wmi_p2p_lo_stop_event_id] = 22420 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22421 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22422 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22423 event_ids[wmi_d0_wow_disable_ack_event_id] = 22424 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22425 event_ids[wmi_wow_initial_wakeup_event_id] = 22426 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22427 22428 event_ids[wmi_rtt_meas_report_event_id] = 22429 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22430 event_ids[wmi_tsf_meas_report_event_id] = 22431 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22432 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22433 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22434 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22435 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22436 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22437 event_ids[wmi_diag_event_id_log_supported_event_id] = 22438 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22439 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22440 event_ids[wmi_nlo_scan_complete_event_id] = 22441 WMI_NLO_SCAN_COMPLETE_EVENTID; 22442 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22443 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22444 22445 event_ids[wmi_gtk_offload_status_event_id] = 22446 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22447 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22448 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22449 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22450 22451 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22452 22453 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22454 22455 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22456 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22457 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22458 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22459 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22460 event_ids[wmi_wlan_profile_data_event_id] = 22461 WMI_WLAN_PROFILE_DATA_EVENTID; 22462 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22463 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22464 event_ids[wmi_vdev_get_keepalive_event_id] = 22465 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22466 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22467 22468 event_ids[wmi_diag_container_event_id] = 22469 WMI_DIAG_DATA_CONTAINER_EVENTID; 22470 22471 event_ids[wmi_host_auto_shutdown_event_id] = 22472 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22473 22474 event_ids[wmi_update_whal_mib_stats_event_id] = 22475 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22476 22477 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22478 event_ids[wmi_update_vdev_rate_stats_event_id] = 22479 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22480 22481 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22482 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22483 22484 /** Set OCB Sched Response, deprecated */ 22485 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22486 22487 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22488 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22489 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22490 22491 /* GPIO Event */ 22492 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22493 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22494 22495 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22496 event_ids[wmi_rfkill_state_change_event_id] = 22497 WMI_RFKILL_STATE_CHANGE_EVENTID; 22498 22499 /* TDLS Event */ 22500 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22501 22502 event_ids[wmi_batch_scan_enabled_event_id] = 22503 WMI_BATCH_SCAN_ENABLED_EVENTID; 22504 event_ids[wmi_batch_scan_result_event_id] = 22505 WMI_BATCH_SCAN_RESULT_EVENTID; 22506 /* OEM Event */ 22507 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22508 event_ids[wmi_oem_meas_report_event_id] = 22509 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22510 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22511 22512 /* NAN Event */ 22513 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22514 22515 /* LPI Event */ 22516 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22517 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22518 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22519 22520 /* ExtScan events */ 22521 event_ids[wmi_extscan_start_stop_event_id] = 22522 WMI_EXTSCAN_START_STOP_EVENTID; 22523 event_ids[wmi_extscan_operation_event_id] = 22524 WMI_EXTSCAN_OPERATION_EVENTID; 22525 event_ids[wmi_extscan_table_usage_event_id] = 22526 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22527 event_ids[wmi_extscan_cached_results_event_id] = 22528 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22529 event_ids[wmi_extscan_wlan_change_results_event_id] = 22530 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22531 event_ids[wmi_extscan_hotlist_match_event_id] = 22532 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22533 event_ids[wmi_extscan_capabilities_event_id] = 22534 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22535 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22536 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22537 22538 /* mDNS offload events */ 22539 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22540 22541 /* SAP Authentication offload events */ 22542 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22543 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22544 22545 /** Out-of-context-of-bss (OCB) events */ 22546 event_ids[wmi_ocb_set_config_resp_event_id] = 22547 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22548 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22549 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22550 event_ids[wmi_dcc_get_stats_resp_event_id] = 22551 WMI_DCC_GET_STATS_RESP_EVENTID; 22552 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22553 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22554 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22555 /* System-On-Chip events */ 22556 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22557 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22558 event_ids[wmi_soc_hw_mode_transition_event_id] = 22559 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22560 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22561 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22562 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22563 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22564 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22565 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22566 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22567 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22568 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22569 WMI_PEER_STA_PS_STATECHG_EVENTID; 22570 event_ids[wmi_pdev_channel_hopping_event_id] = 22571 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22572 event_ids[wmi_offchan_data_tx_completion_event] = 22573 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22574 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22575 event_ids[wmi_dfs_radar_detection_event_id] = 22576 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22577 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22578 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22579 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22580 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22581 event_ids[wmi_service_available_event_id] = 22582 WMI_SERVICE_AVAILABLE_EVENTID; 22583 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22584 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22585 /* NDP events */ 22586 event_ids[wmi_ndp_initiator_rsp_event_id] = 22587 WMI_NDP_INITIATOR_RSP_EVENTID; 22588 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22589 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22590 event_ids[wmi_ndp_responder_rsp_event_id] = 22591 WMI_NDP_RESPONDER_RSP_EVENTID; 22592 event_ids[wmi_ndp_end_indication_event_id] = 22593 WMI_NDP_END_INDICATION_EVENTID; 22594 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22595 event_ids[wmi_ndl_schedule_update_event_id] = 22596 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22597 22598 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22599 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22600 event_ids[wmi_pdev_chip_power_stats_event_id] = 22601 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22602 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22603 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22604 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22605 event_ids[wmi_apf_capability_info_event_id] = 22606 WMI_BPF_CAPABILIY_INFO_EVENTID; 22607 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22608 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22609 event_ids[wmi_report_rx_aggr_failure_event_id] = 22610 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22611 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22612 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22613 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22614 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22615 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22616 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22617 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22618 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22619 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22620 event_ids[wmi_coex_bt_activity_event_id] = 22621 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22622 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22623 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22624 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22625 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22626 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22627 event_ids[wmi_dma_buf_release_event_id] = 22628 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22629 event_ids[wmi_sap_obss_detection_report_event_id] = 22630 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22631 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22632 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22633 event_ids[wmi_obss_color_collision_report_event_id] = 22634 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22635 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22636 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22637 event_ids[wmi_twt_enable_complete_event_id] = 22638 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22639 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22640 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22641 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22642 } 22643 22644 /** 22645 * populate_tlv_service() - populates wmi services 22646 * 22647 * @param wmi_service: Pointer to hold wmi_service 22648 * Return: None 22649 */ 22650 static void populate_tlv_service(uint32_t *wmi_service) 22651 { 22652 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22653 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22654 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22655 wmi_service[wmi_service_roam_scan_offload] = 22656 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22657 wmi_service[wmi_service_bcn_miss_offload] = 22658 WMI_SERVICE_BCN_MISS_OFFLOAD; 22659 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22660 wmi_service[wmi_service_sta_advanced_pwrsave] = 22661 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22662 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22663 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22664 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22665 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22666 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22667 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22668 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22669 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22670 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22671 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22672 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22673 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22674 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22675 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22676 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22677 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22678 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22679 wmi_service[wmi_service_packet_power_save] = 22680 WMI_SERVICE_PACKET_POWER_SAVE; 22681 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22682 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22683 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22684 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22685 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22686 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22687 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22688 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22689 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22690 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22691 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22692 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22693 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22694 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22695 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22696 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22697 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22698 wmi_service[wmi_service_mcc_bcn_interval_change] = 22699 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22700 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22701 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22702 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22703 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22704 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22705 wmi_service[wmi_service_lte_ant_share_support] = 22706 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22707 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22708 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22709 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22710 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22711 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22712 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22713 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22714 wmi_service[wmi_service_bcn_txrate_override] = 22715 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22716 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22717 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22718 wmi_service[wmi_service_estimate_linkspeed] = 22719 WMI_SERVICE_ESTIMATE_LINKSPEED; 22720 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22721 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22722 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22723 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22724 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22725 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22726 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22727 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22728 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22729 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22730 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22731 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22732 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22733 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22734 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22735 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22736 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22737 wmi_service[wmi_service_sap_auth_offload] = 22738 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22739 wmi_service[wmi_service_dual_band_simultaneous_support] = 22740 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22741 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22742 wmi_service[wmi_service_ap_arpns_offload] = 22743 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22744 wmi_service[wmi_service_per_band_chainmask_support] = 22745 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22746 wmi_service[wmi_service_packet_filter_offload] = 22747 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22748 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22749 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22750 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22751 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22752 wmi_service[wmi_service_multiple_vdev_restart] = 22753 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22754 22755 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22756 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22757 wmi_service[wmi_service_smart_antenna_sw_support] = 22758 WMI_SERVICE_UNAVAILABLE; 22759 wmi_service[wmi_service_smart_antenna_hw_support] = 22760 WMI_SERVICE_UNAVAILABLE; 22761 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22762 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22763 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22764 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22765 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22766 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22767 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22768 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22769 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22770 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22771 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22772 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22773 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22774 wmi_service[wmi_service_periodic_chan_stat_support] = 22775 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22776 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22777 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22778 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22779 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22780 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22781 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22782 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22783 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22784 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22785 wmi_service[wmi_service_unified_wow_capability] = 22786 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22787 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22788 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22789 wmi_service[wmi_service_sync_delete_cmds] = 22790 WMI_SERVICE_SYNC_DELETE_CMDS; 22791 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22792 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22793 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22794 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22795 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22796 wmi_service[wmi_service_deprecated_replace] = 22797 WMI_SERVICE_DEPRECATED_REPLACE; 22798 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22799 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22800 wmi_service[wmi_service_enhanced_mcast_filter] = 22801 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22802 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22803 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22804 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22805 wmi_service[wmi_service_p2p_listen_offload_support] = 22806 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22807 wmi_service[wmi_service_mark_first_wakeup_packet] = 22808 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22809 wmi_service[wmi_service_multiple_mcast_filter_set] = 22810 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22811 wmi_service[wmi_service_host_managed_rx_reorder] = 22812 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22813 wmi_service[wmi_service_flash_rdwr_support] = 22814 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22815 wmi_service[wmi_service_wlan_stats_report] = 22816 WMI_SERVICE_WLAN_STATS_REPORT; 22817 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22818 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22819 wmi_service[wmi_service_dfs_phyerr_offload] = 22820 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22821 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22822 wmi_service[wmi_service_fw_mem_dump_support] = 22823 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22824 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22825 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22826 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22827 wmi_service[wmi_service_hw_data_filtering] = 22828 WMI_SERVICE_HW_DATA_FILTERING; 22829 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22830 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22831 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22832 wmi_service[wmi_service_extended_nss_support] = 22833 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22834 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22835 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22836 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22837 wmi_service[wmi_service_offchan_data_tid_support] = 22838 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22839 wmi_service[wmi_service_support_dma] = 22840 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22841 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22842 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22843 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22844 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22845 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22846 wmi_service[wmi_service_11k_neighbour_report_support] = 22847 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22848 wmi_service[wmi_service_ap_obss_detection_offload] = 22849 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22850 wmi_service[wmi_service_bss_color_offload] = 22851 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22852 wmi_service[wmi_service_gmac_offload_support] = 22853 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22854 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22855 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22856 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22857 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22858 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22859 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22860 wmi_service[wmi_service_listen_interval_offload_support] = 22861 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22862 22863 } 22864 22865 #ifndef CONFIG_MCL 22866 22867 /** 22868 * populate_pdev_param_tlv() - populates pdev params 22869 * 22870 * @param pdev_param: Pointer to hold pdev params 22871 * Return: None 22872 */ 22873 static void populate_pdev_param_tlv(uint32_t *pdev_param) 22874 { 22875 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 22876 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 22877 pdev_param[wmi_pdev_param_txpower_limit2g] = 22878 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 22879 pdev_param[wmi_pdev_param_txpower_limit5g] = 22880 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 22881 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 22882 pdev_param[wmi_pdev_param_beacon_gen_mode] = 22883 WMI_PDEV_PARAM_BEACON_GEN_MODE; 22884 pdev_param[wmi_pdev_param_beacon_tx_mode] = 22885 WMI_PDEV_PARAM_BEACON_TX_MODE; 22886 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 22887 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 22888 pdev_param[wmi_pdev_param_protection_mode] = 22889 WMI_PDEV_PARAM_PROTECTION_MODE; 22890 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 22891 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 22892 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 22893 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 22894 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 22895 pdev_param[wmi_pdev_param_sta_kickout_th] = 22896 WMI_PDEV_PARAM_STA_KICKOUT_TH; 22897 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 22898 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 22899 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 22900 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 22901 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 22902 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 22903 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 22904 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 22905 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 22906 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 22907 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 22908 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 22909 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 22910 pdev_param[wmi_pdev_param_ltr_sleep_override] = 22911 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 22912 pdev_param[wmi_pdev_param_ltr_rx_override] = 22913 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 22914 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 22915 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 22916 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 22917 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 22918 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 22919 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 22920 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 22921 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 22922 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 22923 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 22924 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 22925 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 22926 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 22927 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 22928 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 22929 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 22930 pdev_param[wmi_pdev_param_peer_stats_update_period] = 22931 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 22932 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 22933 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 22934 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 22935 pdev_param[wmi_pdev_param_arp_ac_override] = 22936 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 22937 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 22938 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 22939 pdev_param[wmi_pdev_param_ani_poll_period] = 22940 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 22941 pdev_param[wmi_pdev_param_ani_listen_period] = 22942 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 22943 pdev_param[wmi_pdev_param_ani_ofdm_level] = 22944 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 22945 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 22946 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 22947 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 22948 pdev_param[wmi_pdev_param_idle_ps_config] = 22949 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 22950 pdev_param[wmi_pdev_param_power_gating_sleep] = 22951 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 22952 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 22953 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 22954 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 22955 pdev_param[wmi_pdev_param_hw_rfkill_config] = 22956 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 22957 pdev_param[wmi_pdev_param_low_power_rf_enable] = 22958 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 22959 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 22960 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 22961 pdev_param[wmi_pdev_param_power_collapse_enable] = 22962 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 22963 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 22964 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 22965 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 22966 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 22967 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 22968 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 22969 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 22970 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 22971 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 22972 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 22973 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 22974 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 22975 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 22976 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 22977 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 22978 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 22979 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 22980 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 22981 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 22982 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 22983 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 22984 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 22985 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 22986 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 22987 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 22988 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 22989 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 22990 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 22991 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 22992 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 22993 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 22994 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 22995 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 22996 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 22997 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 22998 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 22999 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 23000 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 23001 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 23002 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 23003 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 23004 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 23005 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23006 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23007 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23008 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23009 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23010 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23011 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23012 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23013 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23014 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23015 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23016 WMI_PDEV_PARAM_PROXY_STA_MODE; 23017 pdev_param[wmi_pdev_param_mu_group_policy] = 23018 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23019 pdev_param[wmi_pdev_param_noise_detection] = 23020 WMI_PDEV_PARAM_NOISE_DETECTION; 23021 pdev_param[wmi_pdev_param_noise_threshold] = 23022 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23023 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23024 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23025 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23026 pdev_param[wmi_pdev_param_atf_strict_sch] = 23027 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23028 pdev_param[wmi_pdev_param_atf_sched_duration] = 23029 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23030 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23031 pdev_param[wmi_pdev_param_sensitivity_level] = 23032 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23033 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23034 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23035 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23036 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23037 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23038 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23039 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23040 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23041 pdev_param[wmi_pdev_param_cca_threshold] = 23042 WMI_PDEV_PARAM_CCA_THRESHOLD; 23043 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23044 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23045 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23046 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23047 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23048 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23049 pdev_param[wmi_pdev_param_arp_srcaddr] = 23050 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23051 pdev_param[wmi_pdev_param_arp_dstaddr] = 23052 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23053 pdev_param[wmi_pdev_param_txpower_decr_db] = 23054 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23055 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23056 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23057 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23058 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23059 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23060 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23061 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23062 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23063 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23064 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23065 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23066 WMI_UNAVAILABLE_PARAM; 23067 pdev_param[wmi_pdev_param_igmpmld_override] = 23068 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23069 pdev_param[wmi_pdev_param_igmpmld_tid] = 23070 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23071 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23072 pdev_param[wmi_pdev_param_block_interbss] = 23073 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23074 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23075 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23076 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23077 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23078 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23079 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23080 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23081 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23082 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23083 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23084 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23085 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23086 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23087 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23088 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23089 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23090 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23091 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23092 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23093 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23094 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23095 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23096 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23097 pdev_param[wmi_pdev_param_fast_channel_reset] = 23098 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23099 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23100 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23101 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23102 pdev_param[wmi_pdev_param_antenna_gain_half_db] = 23103 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB; 23104 } 23105 23106 /** 23107 * populate_vdev_param_tlv() - populates vdev params 23108 * 23109 * @param vdev_param: Pointer to hold vdev params 23110 * Return: None 23111 */ 23112 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23113 { 23114 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23115 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23116 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23117 vdev_param[wmi_vdev_param_beacon_interval] = 23118 WMI_VDEV_PARAM_BEACON_INTERVAL; 23119 vdev_param[wmi_vdev_param_listen_interval] = 23120 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23121 vdev_param[wmi_vdev_param_multicast_rate] = 23122 WMI_VDEV_PARAM_MULTICAST_RATE; 23123 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23124 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23125 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23126 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23127 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23128 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23129 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23130 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23131 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23132 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23133 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23134 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23135 vdev_param[wmi_vdev_param_bmiss_count_max] = 23136 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23137 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23138 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23139 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23140 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23141 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23142 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23143 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23144 vdev_param[wmi_vdev_param_disable_htprotection] = 23145 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23146 vdev_param[wmi_vdev_param_sta_quickkickout] = 23147 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23148 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23149 vdev_param[wmi_vdev_param_protection_mode] = 23150 WMI_VDEV_PARAM_PROTECTION_MODE; 23151 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23152 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23153 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23154 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23155 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23156 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23157 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23158 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23159 vdev_param[wmi_vdev_param_bcast_data_rate] = 23160 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23161 vdev_param[wmi_vdev_param_mcast_data_rate] = 23162 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23163 vdev_param[wmi_vdev_param_mcast_indicate] = 23164 WMI_VDEV_PARAM_MCAST_INDICATE; 23165 vdev_param[wmi_vdev_param_dhcp_indicate] = 23166 WMI_VDEV_PARAM_DHCP_INDICATE; 23167 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23168 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23169 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23170 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23171 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23172 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23173 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23174 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23175 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23176 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23177 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23178 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23179 vdev_param[wmi_vdev_param_packet_powersave] = 23180 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23181 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23182 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23183 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23184 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23185 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23186 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23187 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23188 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23189 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23190 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23191 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23192 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23193 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23194 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23195 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23196 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23197 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23198 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23199 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23200 vdev_param[wmi_vdev_param_roam_fw_offload] = 23201 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23202 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23203 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23204 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23205 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23206 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23207 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23208 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23209 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23210 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23211 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23212 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23213 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23214 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23215 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23216 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23217 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23218 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23219 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23220 vdev_param[wmi_vdev_param_inactivity_cnt] = 23221 WMI_VDEV_PARAM_INACTIVITY_CNT; 23222 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23223 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23224 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23225 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23226 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23227 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23228 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23229 vdev_param[wmi_vdev_param_rx_leak_window] = 23230 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23231 vdev_param[wmi_vdev_param_stats_avg_factor] = 23232 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23233 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23234 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23235 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23236 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23237 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23238 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23239 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23240 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23241 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23242 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23243 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23244 WMI_VDEV_PARAM_HE_RANGE_EXT; 23245 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23246 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23247 vdev_param[wmi_vdev_param_set_he_sounding_mode] 23248 = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 23249 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23250 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23251 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23252 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23253 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23254 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23255 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23256 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23257 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23258 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23259 vdev_param[wmi_vdev_param_rc_num_retries] = 23260 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23261 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23262 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23263 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23264 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23265 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23266 vdev_param[wmi_vdev_param_vht80_ratemask] = 23267 WMI_VDEV_PARAM_VHT80_RATEMASK; 23268 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23269 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23270 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23271 vdev_param[wmi_vdev_param_set_he_ltf] = 23272 WMI_VDEV_PARAM_HE_LTF; 23273 vdev_param[wmi_vdev_param_disable_cabq] = 23274 WMI_VDEV_PARAM_DISABLE_CABQ; 23275 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23276 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23277 vdev_param[wmi_vdev_param_set_ba_mode] = 23278 WMI_VDEV_PARAM_BA_MODE; 23279 vdev_param[wmi_vdev_param_capabilities] = 23280 WMI_VDEV_PARAM_CAPABILITIES; 23281 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 23282 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 23283 } 23284 #endif 23285 23286 /** 23287 * populate_target_defines_tlv() - Populate target defines and params 23288 * @wmi_handle: pointer to wmi handle 23289 * 23290 * Return: None 23291 */ 23292 #ifndef CONFIG_MCL 23293 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23294 { 23295 populate_pdev_param_tlv(wmi_handle->pdev_param); 23296 populate_vdev_param_tlv(wmi_handle->vdev_param); 23297 } 23298 #else 23299 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23300 { } 23301 #endif 23302 23303 /** 23304 * wmi_ocb_ut_attach() - Attach OCB test framework 23305 * @wmi_handle: wmi handle 23306 * 23307 * Return: None 23308 */ 23309 #ifdef WLAN_OCB_UT 23310 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23311 #else 23312 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23313 { 23314 return; 23315 } 23316 #endif 23317 23318 /** 23319 * wmi_tlv_attach() - Attach TLV APIs 23320 * 23321 * Return: None 23322 */ 23323 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23324 { 23325 wmi_handle->ops = &tlv_ops; 23326 wmi_ocb_ut_attach(wmi_handle); 23327 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23328 #ifdef WMI_INTERFACE_EVENT_LOGGING 23329 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23330 wmi_handle->log_info.buf_offset_command = 8; 23331 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23332 wmi_handle->log_info.buf_offset_event = 4; 23333 #endif 23334 populate_tlv_events_id(wmi_handle->wmi_events); 23335 populate_tlv_service(wmi_handle->services); 23336 populate_target_defines_tlv(wmi_handle); 23337 wmi_twt_attach_tlv(wmi_handle); 23338 wmi_extscan_attach_tlv(wmi_handle); 23339 } 23340 qdf_export_symbol(wmi_tlv_attach); 23341 23342 /** 23343 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23344 * 23345 * Return: None 23346 */ 23347 void wmi_tlv_init(void) 23348 { 23349 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23350 } 23351