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 /** 11417 * send_set_atf_cmd_tlv() - send set atf command to fw 11418 * @wmi_handle: wmi handle 11419 * @param: pointer to set atf param 11420 * 11421 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11422 */ 11423 static QDF_STATUS 11424 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 11425 struct set_atf_params *param) 11426 { 11427 wmi_atf_peer_info *peer_info; 11428 wmi_peer_atf_request_fixed_param *cmd; 11429 wmi_buf_t buf; 11430 uint8_t *buf_ptr; 11431 int i; 11432 int32_t len = 0; 11433 QDF_STATUS retval; 11434 11435 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11436 len += param->num_peers * sizeof(wmi_atf_peer_info); 11437 buf = wmi_buf_alloc(wmi_handle, len); 11438 if (!buf) { 11439 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11440 return QDF_STATUS_E_FAILURE; 11441 } 11442 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11443 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 11444 WMITLV_SET_HDR(&cmd->tlv_header, 11445 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 11446 WMITLV_GET_STRUCT_TLVLEN( 11447 wmi_peer_atf_request_fixed_param)); 11448 cmd->num_peers = param->num_peers; 11449 11450 buf_ptr += sizeof(*cmd); 11451 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11452 sizeof(wmi_atf_peer_info) * 11453 cmd->num_peers); 11454 buf_ptr += WMI_TLV_HDR_SIZE; 11455 peer_info = (wmi_atf_peer_info *)buf_ptr; 11456 11457 for (i = 0; i < cmd->num_peers; i++) { 11458 WMITLV_SET_HDR(&peer_info->tlv_header, 11459 WMITLV_TAG_STRUC_wmi_atf_peer_info, 11460 WMITLV_GET_STRUCT_TLVLEN( 11461 wmi_atf_peer_info)); 11462 qdf_mem_copy(&(peer_info->peer_macaddr), 11463 &(param->peer_info[i].peer_macaddr), 11464 sizeof(wmi_mac_addr)); 11465 peer_info->atf_units = param->peer_info[i].percentage_peer; 11466 peer_info->vdev_id = param->peer_info[i].vdev_id; 11467 peer_info->pdev_id = 11468 wmi_handle->ops->convert_pdev_id_host_to_target( 11469 param->peer_info[i].pdev_id); 11470 /* 11471 * TLV definition for peer atf request fixed param combines 11472 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 11473 * stats and atf extension stats as two different 11474 * implementations. 11475 * Need to discuss with FW on this. 11476 * 11477 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 11478 * peer_info->atf_units_reserved = 11479 * param->peer_ext_info[i].atf_index_reserved; 11480 */ 11481 peer_info++; 11482 } 11483 11484 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11485 WMI_PEER_ATF_REQUEST_CMDID); 11486 11487 if (retval != QDF_STATUS_SUCCESS) { 11488 WMI_LOGE("%s : WMI Failed\n", __func__); 11489 wmi_buf_free(buf); 11490 } 11491 11492 return retval; 11493 } 11494 11495 /** 11496 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 11497 * @wmi_handle: wmi handle 11498 * @param: pointer to hold fwtest param 11499 * 11500 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11501 */ 11502 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 11503 struct set_fwtest_params *param) 11504 { 11505 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11506 wmi_buf_t buf; 11507 int32_t len = sizeof(*cmd); 11508 11509 buf = wmi_buf_alloc(wmi_handle, len); 11510 11511 if (!buf) { 11512 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11513 return QDF_STATUS_E_FAILURE; 11514 } 11515 11516 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 11517 WMITLV_SET_HDR(&cmd->tlv_header, 11518 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11519 WMITLV_GET_STRUCT_TLVLEN( 11520 wmi_fwtest_set_param_cmd_fixed_param)); 11521 cmd->param_id = param->arg; 11522 cmd->param_value = param->value; 11523 11524 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 11525 WMI_LOGE("Setting FW test param failed\n"); 11526 wmi_buf_free(buf); 11527 return QDF_STATUS_E_FAILURE; 11528 } 11529 11530 return QDF_STATUS_SUCCESS; 11531 } 11532 11533 /** 11534 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 11535 * @wmi_handle: wmi handle 11536 * @param: pointer to qboost params 11537 * @macaddr: vdev mac address 11538 * 11539 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11540 */ 11541 static QDF_STATUS 11542 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 11543 uint8_t macaddr[IEEE80211_ADDR_LEN], 11544 struct set_qboost_params *param) 11545 { 11546 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 11547 wmi_buf_t buf; 11548 int32_t len; 11549 QDF_STATUS ret; 11550 11551 len = sizeof(*cmd); 11552 11553 buf = wmi_buf_alloc(wmi_handle, len); 11554 if (!buf) { 11555 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11556 return QDF_STATUS_E_FAILURE; 11557 } 11558 11559 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 11560 WMITLV_SET_HDR(&cmd->tlv_header, 11561 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 11562 WMITLV_GET_STRUCT_TLVLEN( 11563 WMI_QBOOST_CFG_CMD_fixed_param)); 11564 cmd->vdev_id = param->vdev_id; 11565 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11566 cmd->qb_enable = param->value; 11567 11568 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11569 WMI_QBOOST_CFG_CMDID); 11570 11571 if (ret != 0) { 11572 WMI_LOGE("Setting qboost cmd failed\n"); 11573 wmi_buf_free(buf); 11574 } 11575 11576 return ret; 11577 } 11578 11579 /** 11580 * send_gpio_config_cmd_tlv() - send gpio config to fw 11581 * @wmi_handle: wmi handle 11582 * @param: pointer to hold gpio config param 11583 * 11584 * Return: 0 for success or error code 11585 */ 11586 static QDF_STATUS 11587 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 11588 struct gpio_config_params *param) 11589 { 11590 wmi_gpio_config_cmd_fixed_param *cmd; 11591 wmi_buf_t buf; 11592 int32_t len; 11593 QDF_STATUS ret; 11594 11595 len = sizeof(*cmd); 11596 11597 /* Sanity Checks */ 11598 if (param->pull_type > WMI_GPIO_PULL_DOWN || 11599 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 11600 return QDF_STATUS_E_FAILURE; 11601 } 11602 11603 buf = wmi_buf_alloc(wmi_handle, len); 11604 if (!buf) { 11605 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11606 return QDF_STATUS_E_FAILURE; 11607 } 11608 11609 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 11610 WMITLV_SET_HDR(&cmd->tlv_header, 11611 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 11612 WMITLV_GET_STRUCT_TLVLEN( 11613 wmi_gpio_config_cmd_fixed_param)); 11614 cmd->gpio_num = param->gpio_num; 11615 cmd->input = param->input; 11616 cmd->pull_type = param->pull_type; 11617 cmd->intr_mode = param->intr_mode; 11618 11619 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11620 WMI_GPIO_CONFIG_CMDID); 11621 11622 if (ret != 0) { 11623 WMI_LOGE("Sending GPIO config cmd failed\n"); 11624 wmi_buf_free(buf); 11625 } 11626 11627 return ret; 11628 } 11629 11630 /** 11631 * send_gpio_output_cmd_tlv() - send gpio output to fw 11632 * @wmi_handle: wmi handle 11633 * @param: pointer to hold gpio output param 11634 * 11635 * Return: 0 for success or error code 11636 */ 11637 static QDF_STATUS 11638 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 11639 struct gpio_output_params *param) 11640 { 11641 wmi_gpio_output_cmd_fixed_param *cmd; 11642 wmi_buf_t buf; 11643 int32_t len; 11644 QDF_STATUS ret; 11645 11646 len = sizeof(*cmd); 11647 11648 buf = wmi_buf_alloc(wmi_handle, len); 11649 if (!buf) { 11650 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11651 return QDF_STATUS_E_FAILURE; 11652 } 11653 11654 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 11655 WMITLV_SET_HDR(&cmd->tlv_header, 11656 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 11657 WMITLV_GET_STRUCT_TLVLEN( 11658 wmi_gpio_output_cmd_fixed_param)); 11659 cmd->gpio_num = param->gpio_num; 11660 cmd->set = param->set; 11661 11662 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11663 WMI_GPIO_OUTPUT_CMDID); 11664 11665 if (ret != 0) { 11666 WMI_LOGE("Sending GPIO output cmd failed\n"); 11667 wmi_buf_free(buf); 11668 } 11669 11670 return ret; 11671 11672 } 11673 11674 /** 11675 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 11676 * 11677 * @param wmi_handle : handle to WMI. 11678 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11679 */ 11680 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 11681 { 11682 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 11683 wmi_buf_t buf; 11684 QDF_STATUS ret; 11685 int32_t len; 11686 11687 len = sizeof(*cmd); 11688 11689 buf = wmi_buf_alloc(wmi_handle, len); 11690 if (!buf) { 11691 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11692 return QDF_STATUS_E_FAILURE; 11693 } 11694 11695 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 11696 WMITLV_SET_HDR(&cmd->tlv_header, 11697 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 11698 WMITLV_GET_STRUCT_TLVLEN( 11699 wmi_pdev_dfs_disable_cmd_fixed_param)); 11700 /* Filling it with WMI_PDEV_ID_SOC for now */ 11701 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11702 WMI_HOST_PDEV_ID_SOC); 11703 11704 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11705 WMI_PDEV_DFS_DISABLE_CMDID); 11706 11707 if (ret != 0) { 11708 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 11709 wmi_buf_free(buf); 11710 } 11711 11712 return ret; 11713 } 11714 11715 /** 11716 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 11717 * 11718 * @param wmi_handle : handle to WMI. 11719 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11720 */ 11721 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 11722 { 11723 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 11724 wmi_buf_t buf; 11725 QDF_STATUS ret; 11726 int32_t len; 11727 11728 len = sizeof(*cmd); 11729 11730 buf = wmi_buf_alloc(wmi_handle, len); 11731 if (!buf) { 11732 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11733 return QDF_STATUS_E_FAILURE; 11734 } 11735 11736 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 11737 WMITLV_SET_HDR(&cmd->tlv_header, 11738 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 11739 WMITLV_GET_STRUCT_TLVLEN( 11740 wmi_pdev_dfs_enable_cmd_fixed_param)); 11741 /* Reserved for future use */ 11742 cmd->reserved0 = 0; 11743 11744 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11745 WMI_PDEV_DFS_ENABLE_CMDID); 11746 11747 if (ret != 0) { 11748 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 11749 wmi_buf_free(buf); 11750 } 11751 11752 return ret; 11753 } 11754 11755 /** 11756 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 11757 * to fw 11758 * @wmi_handle: wmi handle 11759 * @param: pointer to hold periodic chan stats param 11760 * 11761 * Return: 0 for success or error code 11762 */ 11763 static QDF_STATUS 11764 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 11765 struct periodic_chan_stats_params *param) 11766 { 11767 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 11768 wmi_buf_t buf; 11769 QDF_STATUS ret; 11770 int32_t len; 11771 11772 len = sizeof(*cmd); 11773 11774 buf = wmi_buf_alloc(wmi_handle, len); 11775 if (!buf) { 11776 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11777 return QDF_STATUS_E_FAILURE; 11778 } 11779 11780 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 11781 wmi_buf_data(buf); 11782 WMITLV_SET_HDR(&cmd->tlv_header, 11783 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 11784 WMITLV_GET_STRUCT_TLVLEN( 11785 wmi_set_periodic_channel_stats_config_fixed_param)); 11786 cmd->enable = param->enable; 11787 cmd->stats_period = param->stats_period; 11788 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11789 param->pdev_id); 11790 11791 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11792 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 11793 11794 if (ret != 0) { 11795 WMI_LOGE("Sending periodic chan stats config failed"); 11796 wmi_buf_free(buf); 11797 } 11798 11799 return ret; 11800 } 11801 11802 /** 11803 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 11804 * @wmi_handle: wmi handle 11805 * @mac_id: radio context 11806 * 11807 * Return: 0 for success or error code 11808 */ 11809 static QDF_STATUS 11810 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 11811 { 11812 wmi_buf_t buf; 11813 QDF_STATUS ret; 11814 wmi_pdev_get_nfcal_power_fixed_param *cmd; 11815 int32_t len = sizeof(*cmd); 11816 11817 buf = wmi_buf_alloc(wmi_handle, len); 11818 if (buf == NULL) 11819 return QDF_STATUS_E_NOMEM; 11820 11821 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 11822 WMITLV_SET_HDR(&cmd->tlv_header, 11823 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 11824 WMITLV_GET_STRUCT_TLVLEN 11825 (wmi_pdev_get_nfcal_power_fixed_param)); 11826 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 11827 11828 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11829 WMI_PDEV_GET_NFCAL_POWER_CMDID); 11830 if (ret != 0) { 11831 WMI_LOGE("Sending get nfcal power cmd failed\n"); 11832 wmi_buf_free(buf); 11833 } 11834 11835 return ret; 11836 } 11837 11838 /** 11839 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 11840 * @wmi_handle: wmi handle 11841 * @param: pointer to ht ie param 11842 * 11843 * Return: 0 for success or error code 11844 */ 11845 static QDF_STATUS 11846 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11847 struct ht_ie_params *param) 11848 { 11849 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 11850 wmi_buf_t buf; 11851 QDF_STATUS ret; 11852 int32_t len; 11853 uint8_t *buf_ptr; 11854 11855 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11856 roundup(param->ie_len, sizeof(uint32_t)); 11857 11858 buf = wmi_buf_alloc(wmi_handle, len); 11859 if (!buf) { 11860 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11861 return QDF_STATUS_E_FAILURE; 11862 } 11863 11864 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11865 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 11866 WMITLV_SET_HDR(&cmd->tlv_header, 11867 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 11868 WMITLV_GET_STRUCT_TLVLEN( 11869 wmi_pdev_set_ht_ie_cmd_fixed_param)); 11870 cmd->reserved0 = 0; 11871 cmd->ie_len = param->ie_len; 11872 cmd->tx_streams = param->tx_streams; 11873 cmd->rx_streams = param->rx_streams; 11874 11875 buf_ptr += sizeof(*cmd); 11876 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11877 buf_ptr += WMI_TLV_HDR_SIZE; 11878 if (param->ie_len) 11879 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11880 cmd->ie_len); 11881 11882 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11883 WMI_PDEV_SET_HT_CAP_IE_CMDID); 11884 11885 if (ret != 0) { 11886 WMI_LOGE("Sending set ht ie cmd failed\n"); 11887 wmi_buf_free(buf); 11888 } 11889 11890 return ret; 11891 } 11892 11893 /** 11894 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 11895 * @wmi_handle: wmi handle 11896 * @param: pointer to vht ie param 11897 * 11898 * Return: 0 for success or error code 11899 */ 11900 static QDF_STATUS 11901 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 11902 struct vht_ie_params *param) 11903 { 11904 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 11905 wmi_buf_t buf; 11906 QDF_STATUS ret; 11907 int32_t len; 11908 uint8_t *buf_ptr; 11909 11910 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 11911 roundup(param->ie_len, sizeof(uint32_t)); 11912 11913 buf = wmi_buf_alloc(wmi_handle, len); 11914 if (!buf) { 11915 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11916 return QDF_STATUS_E_FAILURE; 11917 } 11918 11919 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11920 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 11921 WMITLV_SET_HDR(&cmd->tlv_header, 11922 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 11923 WMITLV_GET_STRUCT_TLVLEN( 11924 wmi_pdev_set_vht_ie_cmd_fixed_param)); 11925 cmd->reserved0 = 0; 11926 cmd->ie_len = param->ie_len; 11927 cmd->tx_streams = param->tx_streams; 11928 cmd->rx_streams = param->rx_streams; 11929 11930 buf_ptr += sizeof(*cmd); 11931 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 11932 buf_ptr += WMI_TLV_HDR_SIZE; 11933 if (param->ie_len) 11934 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 11935 cmd->ie_len); 11936 11937 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11938 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 11939 11940 if (ret != 0) { 11941 WMI_LOGE("Sending set vht ie cmd failed\n"); 11942 wmi_buf_free(buf); 11943 } 11944 11945 return ret; 11946 } 11947 11948 /** 11949 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 11950 * @wmi_handle: wmi handle 11951 * @param: pointer to quiet mode params 11952 * 11953 * Return: 0 for success or error code 11954 */ 11955 static QDF_STATUS 11956 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 11957 struct set_quiet_mode_params *param) 11958 { 11959 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 11960 wmi_buf_t buf; 11961 QDF_STATUS ret; 11962 int32_t len; 11963 11964 len = sizeof(*quiet_cmd); 11965 buf = wmi_buf_alloc(wmi_handle, len); 11966 if (!buf) { 11967 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11968 return QDF_STATUS_E_FAILURE; 11969 } 11970 11971 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11972 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 11973 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 11974 WMITLV_GET_STRUCT_TLVLEN( 11975 wmi_pdev_set_quiet_cmd_fixed_param)); 11976 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 11977 quiet_cmd->enabled = param->enabled; 11978 quiet_cmd->period = (param->period)*(param->intval); 11979 quiet_cmd->duration = param->duration; 11980 quiet_cmd->next_start = param->offset; 11981 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11982 WMI_HOST_PDEV_ID_SOC); 11983 11984 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11985 WMI_PDEV_SET_QUIET_MODE_CMDID); 11986 11987 if (ret != 0) { 11988 WMI_LOGE("Sending set quiet cmd failed\n"); 11989 wmi_buf_free(buf); 11990 } 11991 11992 return ret; 11993 } 11994 11995 /** 11996 * send_set_bwf_cmd_tlv() - send set bwf command to fw 11997 * @wmi_handle: wmi handle 11998 * @param: pointer to set bwf param 11999 * 12000 * Return: 0 for success or error code 12001 */ 12002 static QDF_STATUS 12003 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12004 struct set_bwf_params *param) 12005 { 12006 wmi_bwf_peer_info *peer_info; 12007 wmi_peer_bwf_request_fixed_param *cmd; 12008 wmi_buf_t buf; 12009 QDF_STATUS retval; 12010 int32_t len; 12011 uint8_t *buf_ptr; 12012 int i; 12013 12014 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12015 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12016 buf = wmi_buf_alloc(wmi_handle, len); 12017 if (!buf) { 12018 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12019 return QDF_STATUS_E_FAILURE; 12020 } 12021 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12022 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12023 WMITLV_SET_HDR(&cmd->tlv_header, 12024 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12025 WMITLV_GET_STRUCT_TLVLEN( 12026 wmi_peer_bwf_request_fixed_param)); 12027 cmd->num_peers = param->num_peers; 12028 12029 buf_ptr += sizeof(*cmd); 12030 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12031 sizeof(wmi_bwf_peer_info) * 12032 cmd->num_peers); 12033 buf_ptr += WMI_TLV_HDR_SIZE; 12034 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12035 12036 for (i = 0; i < cmd->num_peers; i++) { 12037 WMITLV_SET_HDR(&peer_info->tlv_header, 12038 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12039 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12040 peer_info->bwf_guaranteed_bandwidth = 12041 param->peer_info[i].throughput; 12042 peer_info->bwf_max_airtime = 12043 param->peer_info[i].max_airtime; 12044 peer_info->bwf_peer_priority = 12045 param->peer_info[i].priority; 12046 qdf_mem_copy(&peer_info->peer_macaddr, 12047 ¶m->peer_info[i].peer_macaddr, 12048 sizeof(param->peer_info[i].peer_macaddr)); 12049 peer_info->vdev_id = 12050 param->peer_info[i].vdev_id; 12051 peer_info->pdev_id = 12052 wmi_handle->ops->convert_pdev_id_host_to_target( 12053 param->peer_info[i].pdev_id); 12054 peer_info++; 12055 } 12056 12057 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12058 WMI_PEER_BWF_REQUEST_CMDID); 12059 12060 if (retval != QDF_STATUS_SUCCESS) { 12061 WMI_LOGE("%s : WMI Failed\n", __func__); 12062 wmi_buf_free(buf); 12063 } 12064 12065 return retval; 12066 } 12067 12068 /** 12069 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12070 * @wmi_handle: wmi handle 12071 * @param: pointer to hold mcast update param 12072 * 12073 * Return: 0 for success or error code 12074 */ 12075 static QDF_STATUS 12076 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12077 struct mcast_group_update_params *param) 12078 { 12079 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12080 wmi_buf_t buf; 12081 QDF_STATUS ret; 12082 int32_t len; 12083 int offset = 0; 12084 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12085 12086 len = sizeof(*cmd); 12087 buf = wmi_buf_alloc(wmi_handle, len); 12088 if (!buf) { 12089 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12090 return QDF_STATUS_E_FAILURE; 12091 } 12092 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12093 WMITLV_SET_HDR(&cmd->tlv_header, 12094 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12095 WMITLV_GET_STRUCT_TLVLEN( 12096 wmi_peer_mcast_group_cmd_fixed_param)); 12097 /* confirm the buffer is 4-byte aligned */ 12098 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12099 qdf_mem_zero(cmd, sizeof(*cmd)); 12100 12101 cmd->vdev_id = param->vap_id; 12102 /* construct the message assuming our endianness matches the target */ 12103 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12104 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12105 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12106 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12107 if (param->is_action_delete) 12108 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12109 12110 if (param->is_mcast_addr_len) 12111 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12112 12113 if (param->is_filter_mode_snoop) 12114 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12115 12116 /* unicast address spec only applies for non-wildcard cases */ 12117 if (!param->wildcard && param->ucast_mac_addr) { 12118 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12119 &cmd->ucast_mac_addr); 12120 } 12121 12122 if (param->mcast_ip_addr) { 12123 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12124 sizeof(cmd->mcast_ip_addr)); 12125 offset = sizeof(cmd->mcast_ip_addr) - 12126 param->mcast_ip_addr_bytes; 12127 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12128 param->mcast_ip_addr, 12129 param->mcast_ip_addr_bytes); 12130 } 12131 if (!param->mask) 12132 param->mask = &dummymask[0]; 12133 12134 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12135 param->mask, 12136 param->mcast_ip_addr_bytes); 12137 12138 if (param->srcs && param->nsrcs) { 12139 cmd->num_filter_addr = param->nsrcs; 12140 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12141 sizeof(cmd->filter_addr)); 12142 12143 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12144 param->nsrcs * param->mcast_ip_addr_bytes); 12145 } 12146 12147 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12148 WMI_PEER_MCAST_GROUP_CMDID); 12149 12150 if (ret != QDF_STATUS_SUCCESS) { 12151 WMI_LOGE("%s : WMI Failed\n", __func__); 12152 wmi_buf_free(buf); 12153 } 12154 12155 return ret; 12156 } 12157 12158 /** 12159 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12160 * command to fw 12161 * @wmi_handle: wmi handle 12162 * @param: pointer to hold spectral config parameter 12163 * 12164 * Return: 0 for success or error code 12165 */ 12166 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12167 struct vdev_spectral_configure_params *param) 12168 { 12169 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12170 wmi_buf_t buf; 12171 QDF_STATUS ret; 12172 int32_t len; 12173 12174 len = sizeof(*cmd); 12175 buf = wmi_buf_alloc(wmi_handle, len); 12176 if (!buf) { 12177 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12178 return QDF_STATUS_E_FAILURE; 12179 } 12180 12181 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12182 WMITLV_SET_HDR(&cmd->tlv_header, 12183 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12184 WMITLV_GET_STRUCT_TLVLEN( 12185 wmi_vdev_spectral_configure_cmd_fixed_param)); 12186 12187 cmd->vdev_id = param->vdev_id; 12188 cmd->spectral_scan_count = param->count; 12189 cmd->spectral_scan_period = param->period; 12190 cmd->spectral_scan_priority = param->spectral_pri; 12191 cmd->spectral_scan_fft_size = param->fft_size; 12192 cmd->spectral_scan_gc_ena = param->gc_enable; 12193 cmd->spectral_scan_restart_ena = param->restart_enable; 12194 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12195 cmd->spectral_scan_init_delay = param->init_delay; 12196 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12197 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12198 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12199 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12200 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12201 cmd->spectral_scan_pwr_format = param->pwr_format; 12202 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12203 cmd->spectral_scan_bin_scale = param->bin_scale; 12204 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12205 cmd->spectral_scan_chn_mask = param->chn_mask; 12206 12207 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12208 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12209 12210 if (ret != 0) { 12211 WMI_LOGE("Sending set quiet cmd failed\n"); 12212 wmi_buf_free(buf); 12213 } 12214 12215 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12216 __func__); 12217 12218 WMI_LOGI("vdev_id = %u\n" 12219 "spectral_scan_count = %u\n" 12220 "spectral_scan_period = %u\n" 12221 "spectral_scan_priority = %u\n" 12222 "spectral_scan_fft_size = %u\n" 12223 "spectral_scan_gc_ena = %u\n" 12224 "spectral_scan_restart_ena = %u\n" 12225 "spectral_scan_noise_floor_ref = %u\n" 12226 "spectral_scan_init_delay = %u\n" 12227 "spectral_scan_nb_tone_thr = %u\n" 12228 "spectral_scan_str_bin_thr = %u\n" 12229 "spectral_scan_wb_rpt_mode = %u\n" 12230 "spectral_scan_rssi_rpt_mode = %u\n" 12231 "spectral_scan_rssi_thr = %u\n" 12232 "spectral_scan_pwr_format = %u\n" 12233 "spectral_scan_rpt_mode = %u\n" 12234 "spectral_scan_bin_scale = %u\n" 12235 "spectral_scan_dBm_adj = %u\n" 12236 "spectral_scan_chn_mask = %u\n", 12237 param->vdev_id, 12238 param->count, 12239 param->period, 12240 param->spectral_pri, 12241 param->fft_size, 12242 param->gc_enable, 12243 param->restart_enable, 12244 param->noise_floor_ref, 12245 param->init_delay, 12246 param->nb_tone_thr, 12247 param->str_bin_thr, 12248 param->wb_rpt_mode, 12249 param->rssi_rpt_mode, 12250 param->rssi_thr, 12251 param->pwr_format, 12252 param->rpt_mode, 12253 param->bin_scale, 12254 param->dbm_adj, 12255 param->chn_mask); 12256 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12257 12258 return ret; 12259 } 12260 12261 /** 12262 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12263 * command to fw 12264 * @wmi_handle: wmi handle 12265 * @param: pointer to hold spectral enable parameter 12266 * 12267 * Return: 0 for success or error code 12268 */ 12269 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12270 struct vdev_spectral_enable_params *param) 12271 { 12272 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12273 wmi_buf_t buf; 12274 QDF_STATUS ret; 12275 int32_t len; 12276 12277 len = sizeof(*cmd); 12278 buf = wmi_buf_alloc(wmi_handle, len); 12279 if (!buf) { 12280 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12281 return QDF_STATUS_E_FAILURE; 12282 } 12283 12284 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12285 WMITLV_SET_HDR(&cmd->tlv_header, 12286 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12287 WMITLV_GET_STRUCT_TLVLEN( 12288 wmi_vdev_spectral_enable_cmd_fixed_param)); 12289 12290 cmd->vdev_id = param->vdev_id; 12291 12292 if (param->active_valid) { 12293 cmd->trigger_cmd = param->active ? 1 : 2; 12294 /* 1: Trigger, 2: Clear Trigger */ 12295 } else { 12296 cmd->trigger_cmd = 0; /* 0: Ignore */ 12297 } 12298 12299 if (param->enabled_valid) { 12300 cmd->enable_cmd = param->enabled ? 1 : 2; 12301 /* 1: Enable 2: Disable */ 12302 } else { 12303 cmd->enable_cmd = 0; /* 0: Ignore */ 12304 } 12305 12306 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12307 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12308 12309 if (ret != 0) { 12310 WMI_LOGE("Sending scan enable CMD failed\n"); 12311 wmi_buf_free(buf); 12312 } 12313 12314 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12315 12316 WMI_LOGI("vdev_id = %u\n" 12317 "trigger_cmd = %u\n" 12318 "enable_cmd = %u\n", 12319 cmd->vdev_id, 12320 cmd->trigger_cmd, 12321 cmd->enable_cmd); 12322 12323 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12324 12325 return ret; 12326 } 12327 12328 /** 12329 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12330 * @param wmi_handle : handle to WMI. 12331 * @param param : pointer to hold thermal mitigation param 12332 * 12333 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12334 */ 12335 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12336 wmi_unified_t wmi_handle, 12337 struct thermal_mitigation_params *param) 12338 { 12339 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 12340 wmi_therm_throt_level_config_info *lvl_conf = NULL; 12341 wmi_buf_t buf = NULL; 12342 uint8_t *buf_ptr = NULL; 12343 int error; 12344 int32_t len; 12345 int i; 12346 12347 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 12348 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 12349 12350 buf = wmi_buf_alloc(wmi_handle, len); 12351 if (!buf) { 12352 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12353 return QDF_STATUS_E_NOMEM; 12354 } 12355 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 12356 12357 /* init fixed params */ 12358 WMITLV_SET_HDR(tt_conf, 12359 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 12360 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 12361 12362 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12363 param->pdev_id); 12364 tt_conf->enable = param->enable; 12365 tt_conf->dc = param->dc; 12366 tt_conf->dc_per_event = param->dc_per_event; 12367 tt_conf->therm_throt_levels = THERMAL_LEVELS; 12368 12369 buf_ptr = (uint8_t *) ++tt_conf; 12370 /* init TLV params */ 12371 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12372 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 12373 12374 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 12375 for (i = 0; i < THERMAL_LEVELS; i++) { 12376 WMITLV_SET_HDR(&lvl_conf->tlv_header, 12377 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 12378 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 12379 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 12380 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 12381 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 12382 lvl_conf->prio = param->levelconf[i].priority; 12383 lvl_conf++; 12384 } 12385 12386 error = wmi_unified_cmd_send(wmi_handle, buf, len, 12387 WMI_THERM_THROT_SET_CONF_CMDID); 12388 if (QDF_IS_STATUS_ERROR(error)) { 12389 wmi_buf_free(buf); 12390 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 12391 } 12392 12393 return error; 12394 } 12395 12396 /** 12397 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 12398 * @wmi_handle: wmi handle 12399 * @param: pointer to pdev_qvit_params 12400 * 12401 * Return: 0 for success or error code 12402 */ 12403 static QDF_STATUS 12404 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 12405 struct pdev_qvit_params *param) 12406 { 12407 wmi_buf_t buf; 12408 QDF_STATUS ret = QDF_STATUS_E_INVAL; 12409 uint8_t *cmd; 12410 static uint8_t msgref = 1; 12411 uint8_t segnumber = 0, seginfo, numsegments; 12412 uint16_t chunk_len, total_bytes; 12413 uint8_t *bufpos; 12414 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 12415 12416 bufpos = param->utf_payload; 12417 total_bytes = param->len; 12418 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 12419 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 12420 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 12421 12422 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 12423 numsegments++; 12424 12425 while (param->len) { 12426 if (param->len > MAX_WMI_QVIT_LEN) 12427 chunk_len = MAX_WMI_QVIT_LEN; /* MAX message */ 12428 else 12429 chunk_len = param->len; 12430 12431 buf = wmi_buf_alloc(wmi_handle, 12432 (chunk_len + sizeof(seghdrinfo) + 12433 WMI_TLV_HDR_SIZE)); 12434 if (!buf) { 12435 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12436 return QDF_STATUS_E_NOMEM; 12437 } 12438 12439 cmd = (uint8_t *) wmi_buf_data(buf); 12440 12441 seghdrinfo.len = total_bytes; 12442 seghdrinfo.msgref = msgref; 12443 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 12444 seghdrinfo.segmentInfo = seginfo; 12445 12446 segnumber++; 12447 12448 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 12449 (chunk_len + sizeof(seghdrinfo))); 12450 cmd += WMI_TLV_HDR_SIZE; 12451 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 12452 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 12453 12454 ret = wmi_unified_cmd_send(wmi_handle, buf, 12455 (chunk_len + sizeof(seghdrinfo) + 12456 WMI_TLV_HDR_SIZE), 12457 WMI_PDEV_QVIT_CMDID); 12458 12459 if (ret != 0) { 12460 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 12461 wmi_buf_free(buf); 12462 break; 12463 } 12464 12465 param->len -= chunk_len; 12466 bufpos += chunk_len; 12467 } 12468 msgref++; 12469 12470 return ret; 12471 } 12472 12473 /** 12474 * send_wmm_update_cmd_tlv() - send wmm update command to fw 12475 * @wmi_handle: wmi handle 12476 * @param: pointer to wmm update param 12477 * 12478 * Return: 0 for success or error code 12479 */ 12480 static QDF_STATUS 12481 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 12482 struct wmm_update_params *param) 12483 { 12484 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 12485 wmi_wmm_params *wmm_param; 12486 wmi_buf_t buf; 12487 QDF_STATUS ret; 12488 int32_t len; 12489 int ac = 0; 12490 struct wmi_host_wmeParams *wmep; 12491 uint8_t *buf_ptr; 12492 12493 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 12494 buf = wmi_buf_alloc(wmi_handle, len); 12495 if (!buf) { 12496 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12497 return QDF_STATUS_E_FAILURE; 12498 } 12499 12500 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12501 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 12502 WMITLV_SET_HDR(&cmd->tlv_header, 12503 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 12504 WMITLV_GET_STRUCT_TLVLEN 12505 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 12506 12507 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 12508 12509 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 12510 12511 for (ac = 0; ac < WME_NUM_AC; ac++) { 12512 wmep = ¶m->wmep_array[ac]; 12513 wmm_param = (wmi_wmm_params *)buf_ptr; 12514 WMITLV_SET_HDR(&wmm_param->tlv_header, 12515 WMITLV_TAG_STRUC_wmi_wmm_params, 12516 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 12517 wmm_param->aifs = wmep->wmep_aifsn; 12518 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 12519 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 12520 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 12521 wmm_param->acm = wmep->wmep_acm; 12522 wmm_param->no_ack = wmep->wmep_noackPolicy; 12523 buf_ptr += sizeof(wmi_wmm_params); 12524 } 12525 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12526 WMI_PDEV_SET_WMM_PARAMS_CMDID); 12527 12528 if (ret != 0) { 12529 WMI_LOGE("Sending WMM update CMD failed\n"); 12530 wmi_buf_free(buf); 12531 } 12532 12533 return ret; 12534 } 12535 12536 /** 12537 * send_coex_config_cmd_tlv() - send coex config command to fw 12538 * @wmi_handle: wmi handle 12539 * @param: pointer to coex config param 12540 * 12541 * Return: 0 for success or error code 12542 */ 12543 static QDF_STATUS 12544 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 12545 struct coex_config_params *param) 12546 { 12547 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 12548 wmi_buf_t buf; 12549 QDF_STATUS ret; 12550 int32_t len; 12551 12552 len = sizeof(*cmd); 12553 buf = wmi_buf_alloc(wmi_handle, len); 12554 if (!buf) { 12555 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12556 return QDF_STATUS_E_FAILURE; 12557 } 12558 12559 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 12560 WMITLV_SET_HDR(&cmd->tlv_header, 12561 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 12562 WMITLV_GET_STRUCT_TLVLEN( 12563 WMI_COEX_CONFIG_CMD_fixed_param)); 12564 12565 cmd->vdev_id = param->vdev_id; 12566 cmd->config_type = param->config_type; 12567 cmd->config_arg1 = param->config_arg1; 12568 cmd->config_arg2 = param->config_arg2; 12569 cmd->config_arg3 = param->config_arg3; 12570 cmd->config_arg4 = param->config_arg4; 12571 cmd->config_arg5 = param->config_arg5; 12572 cmd->config_arg6 = param->config_arg6; 12573 12574 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12575 WMI_COEX_CONFIG_CMDID); 12576 12577 if (ret != 0) { 12578 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 12579 wmi_buf_free(buf); 12580 } 12581 12582 return ret; 12583 } 12584 12585 12586 #ifdef WLAN_SUPPORT_TWT 12587 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12588 target_resource_config *tgt_res_cfg) 12589 { 12590 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 12591 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 12592 } 12593 #else 12594 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12595 target_resource_config *tgt_res_cfg) 12596 { 12597 resource_cfg->twt_ap_pdev_count = 0; 12598 resource_cfg->twt_ap_sta_count = 0; 12599 } 12600 #endif 12601 12602 static 12603 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 12604 target_resource_config *tgt_res_cfg) 12605 { 12606 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 12607 resource_cfg->num_peers = tgt_res_cfg->num_peers; 12608 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 12609 resource_cfg->num_offload_reorder_buffs = 12610 tgt_res_cfg->num_offload_reorder_buffs; 12611 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 12612 resource_cfg->num_tids = tgt_res_cfg->num_tids; 12613 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 12614 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 12615 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 12616 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 12617 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 12618 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 12619 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 12620 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 12621 resource_cfg->scan_max_pending_req = 12622 tgt_res_cfg->scan_max_pending_req; 12623 resource_cfg->bmiss_offload_max_vdev = 12624 tgt_res_cfg->bmiss_offload_max_vdev; 12625 resource_cfg->roam_offload_max_vdev = 12626 tgt_res_cfg->roam_offload_max_vdev; 12627 resource_cfg->roam_offload_max_ap_profiles = 12628 tgt_res_cfg->roam_offload_max_ap_profiles; 12629 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 12630 resource_cfg->num_mcast_table_elems = 12631 tgt_res_cfg->num_mcast_table_elems; 12632 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 12633 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 12634 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 12635 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 12636 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 12637 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 12638 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 12639 resource_cfg->vow_config = tgt_res_cfg->vow_config; 12640 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 12641 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 12642 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 12643 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 12644 resource_cfg->num_tdls_conn_table_entries = 12645 tgt_res_cfg->num_tdls_conn_table_entries; 12646 resource_cfg->beacon_tx_offload_max_vdev = 12647 tgt_res_cfg->beacon_tx_offload_max_vdev; 12648 resource_cfg->num_multicast_filter_entries = 12649 tgt_res_cfg->num_multicast_filter_entries; 12650 resource_cfg->num_wow_filters = 12651 tgt_res_cfg->num_wow_filters; 12652 resource_cfg->num_keep_alive_pattern = 12653 tgt_res_cfg->num_keep_alive_pattern; 12654 resource_cfg->keep_alive_pattern_size = 12655 tgt_res_cfg->keep_alive_pattern_size; 12656 resource_cfg->max_tdls_concurrent_sleep_sta = 12657 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 12658 resource_cfg->max_tdls_concurrent_buffer_sta = 12659 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 12660 resource_cfg->wmi_send_separate = 12661 tgt_res_cfg->wmi_send_separate; 12662 resource_cfg->num_ocb_vdevs = 12663 tgt_res_cfg->num_ocb_vdevs; 12664 resource_cfg->num_ocb_channels = 12665 tgt_res_cfg->num_ocb_channels; 12666 resource_cfg->num_ocb_schedules = 12667 tgt_res_cfg->num_ocb_schedules; 12668 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 12669 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 12670 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 12671 resource_cfg->max_num_dbs_scan_duty_cycle = 12672 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 12673 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 12674 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 12675 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 12676 12677 if (tgt_res_cfg->atf_config) 12678 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 12679 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 12680 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 12681 resource_cfg->flag1, 1); 12682 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 12683 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 12684 resource_cfg->flag1, 1); 12685 if (tgt_res_cfg->cce_disable) 12686 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 12687 12688 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 12689 } 12690 12691 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 12692 * @wmi_handle: pointer to wmi handle 12693 * @buf_ptr: pointer to current position in init command buffer 12694 * @len: pointer to length. This will be updated with current length of cmd 12695 * @param: point host parameters for init command 12696 * 12697 * Return: Updated pointer of buf_ptr. 12698 */ 12699 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 12700 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 12701 { 12702 uint16_t idx; 12703 12704 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 12705 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 12706 wmi_pdev_band_to_mac *band_to_mac; 12707 12708 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 12709 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 12710 sizeof(wmi_resource_config) + 12711 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 12712 sizeof(wlan_host_memory_chunk))); 12713 12714 WMITLV_SET_HDR(&hw_mode->tlv_header, 12715 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 12716 (WMITLV_GET_STRUCT_TLVLEN 12717 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 12718 12719 hw_mode->hw_mode_index = param->hw_mode_id; 12720 hw_mode->num_band_to_mac = param->num_band_to_mac; 12721 12722 buf_ptr = (uint8_t *) (hw_mode + 1); 12723 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 12724 WMI_TLV_HDR_SIZE); 12725 for (idx = 0; idx < param->num_band_to_mac; idx++) { 12726 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 12727 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 12728 WMITLV_GET_STRUCT_TLVLEN 12729 (wmi_pdev_band_to_mac)); 12730 band_to_mac[idx].pdev_id = 12731 wmi_handle->ops->convert_pdev_id_host_to_target( 12732 param->band_to_mac[idx].pdev_id); 12733 band_to_mac[idx].start_freq = 12734 param->band_to_mac[idx].start_freq; 12735 band_to_mac[idx].end_freq = 12736 param->band_to_mac[idx].end_freq; 12737 } 12738 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12739 (param->num_band_to_mac * 12740 sizeof(wmi_pdev_band_to_mac)) + 12741 WMI_TLV_HDR_SIZE; 12742 12743 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12744 (param->num_band_to_mac * 12745 sizeof(wmi_pdev_band_to_mac))); 12746 } 12747 12748 return buf_ptr; 12749 } 12750 12751 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 12752 wmi_init_cmd_fixed_param *cmd) 12753 { 12754 int num_whitelist; 12755 wmi_abi_version my_vers; 12756 12757 num_whitelist = sizeof(version_whitelist) / 12758 sizeof(wmi_whitelist_version_info); 12759 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 12760 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 12761 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 12762 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 12763 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 12764 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 12765 12766 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 12767 &my_vers, 12768 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 12769 &cmd->host_abi_vers); 12770 12771 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 12772 __func__, 12773 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 12774 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 12775 cmd->host_abi_vers.abi_version_ns_0, 12776 cmd->host_abi_vers.abi_version_ns_1, 12777 cmd->host_abi_vers.abi_version_ns_2, 12778 cmd->host_abi_vers.abi_version_ns_3); 12779 12780 /* Save version sent from host - 12781 * Will be used to check ready event 12782 */ 12783 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 12784 sizeof(wmi_abi_version)); 12785 } 12786 12787 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12788 { 12789 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12790 wmi_service_ready_event_fixed_param *ev; 12791 12792 12793 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12794 12795 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12796 if (!ev) 12797 return QDF_STATUS_E_FAILURE; 12798 12799 /*Save fw version from service ready message */ 12800 /*This will be used while sending INIT message */ 12801 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12802 sizeof(wmi_handle->fw_abi_version)); 12803 12804 return QDF_STATUS_SUCCESS; 12805 } 12806 12807 /** 12808 * wmi_unified_save_fw_version_cmd() - save fw version 12809 * @wmi_handle: pointer to wmi handle 12810 * @res_cfg: resource config 12811 * @num_mem_chunks: no of mem chunck 12812 * @mem_chunk: pointer to mem chunck structure 12813 * 12814 * This function sends IE information to firmware 12815 * 12816 * Return: QDF_STATUS_SUCCESS for success otherwise failure 12817 * 12818 */ 12819 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 12820 void *evt_buf) 12821 { 12822 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12823 wmi_ready_event_fixed_param *ev = NULL; 12824 12825 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12826 ev = param_buf->fixed_param; 12827 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 12828 &wmi_handle->final_abi_vers, 12829 &ev->fw_abi_vers)) { 12830 /* 12831 * Error: Our host version and the given firmware version 12832 * are incompatible. 12833 **/ 12834 WMI_LOGD("%s: Error: Incompatible WMI version." 12835 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 12836 __func__, 12837 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 12838 abi_version_0), 12839 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 12840 abi_version_0), 12841 wmi_handle->final_abi_vers.abi_version_ns_0, 12842 wmi_handle->final_abi_vers.abi_version_ns_1, 12843 wmi_handle->final_abi_vers.abi_version_ns_2, 12844 wmi_handle->final_abi_vers.abi_version_ns_3, 12845 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 12846 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 12847 ev->fw_abi_vers.abi_version_ns_0, 12848 ev->fw_abi_vers.abi_version_ns_1, 12849 ev->fw_abi_vers.abi_version_ns_2, 12850 ev->fw_abi_vers.abi_version_ns_3); 12851 12852 return QDF_STATUS_E_FAILURE; 12853 } 12854 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 12855 sizeof(wmi_abi_version)); 12856 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12857 sizeof(wmi_abi_version)); 12858 12859 return QDF_STATUS_SUCCESS; 12860 } 12861 12862 /** 12863 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 12864 * @wmi_handle: wmi handle 12865 * @custom_addr: base mac address 12866 * 12867 * Return: QDF_STATUS_SUCCESS for success or error code 12868 */ 12869 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 12870 uint8_t *custom_addr) 12871 { 12872 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 12873 wmi_buf_t buf; 12874 int err; 12875 12876 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 12877 if (!buf) { 12878 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 12879 return QDF_STATUS_E_NOMEM; 12880 } 12881 12882 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 12883 qdf_mem_zero(cmd, sizeof(*cmd)); 12884 12885 WMITLV_SET_HDR(&cmd->tlv_header, 12886 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 12887 WMITLV_GET_STRUCT_TLVLEN 12888 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 12889 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 12890 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12891 WMI_HOST_PDEV_ID_SOC); 12892 err = wmi_unified_cmd_send(wmi_handle, buf, 12893 sizeof(*cmd), 12894 WMI_PDEV_SET_BASE_MACADDR_CMDID); 12895 if (err) { 12896 WMI_LOGE("Failed to send set_base_macaddr cmd"); 12897 wmi_buf_free(buf); 12898 return QDF_STATUS_E_FAILURE; 12899 } 12900 12901 return 0; 12902 } 12903 12904 /** 12905 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 12906 * @handle: wmi handle 12907 * @event: Event received from FW 12908 * @len: Length of the event 12909 * 12910 * Enables the low frequency events and disables the high frequency 12911 * events. Bit 17 indicates if the event if low/high frequency. 12912 * 1 - high frequency, 0 - low frequency 12913 * 12914 * Return: 0 on successfully enabling/disabling the events 12915 */ 12916 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 12917 uint8_t *event, 12918 uint32_t len) 12919 { 12920 uint32_t num_of_diag_events_logs; 12921 wmi_diag_event_log_config_fixed_param *cmd; 12922 wmi_buf_t buf; 12923 uint8_t *buf_ptr; 12924 uint32_t *cmd_args, *evt_args; 12925 uint32_t buf_len, i; 12926 12927 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 12928 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 12929 12930 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 12931 12932 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 12933 if (!param_buf) { 12934 WMI_LOGE("Invalid log supported event buffer"); 12935 return QDF_STATUS_E_INVAL; 12936 } 12937 wmi_event = param_buf->fixed_param; 12938 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 12939 12940 if (num_of_diag_events_logs > 12941 param_buf->num_diag_events_logs_list) { 12942 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 12943 num_of_diag_events_logs, 12944 param_buf->num_diag_events_logs_list); 12945 return QDF_STATUS_E_INVAL; 12946 } 12947 12948 evt_args = param_buf->diag_events_logs_list; 12949 if (!evt_args) { 12950 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 12951 __func__, num_of_diag_events_logs); 12952 return QDF_STATUS_E_INVAL; 12953 } 12954 12955 WMI_LOGD("%s: num_of_diag_events_logs=%d", 12956 __func__, num_of_diag_events_logs); 12957 12958 /* Free any previous allocation */ 12959 if (wmi_handle->events_logs_list) 12960 qdf_mem_free(wmi_handle->events_logs_list); 12961 12962 if (num_of_diag_events_logs > 12963 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 12964 WMI_LOGE("%s: excess num of logs:%d", __func__, 12965 num_of_diag_events_logs); 12966 QDF_ASSERT(0); 12967 return QDF_STATUS_E_INVAL; 12968 } 12969 /* Store the event list for run time enable/disable */ 12970 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 12971 sizeof(uint32_t)); 12972 if (!wmi_handle->events_logs_list) { 12973 WMI_LOGE("%s: event log list memory allocation failed", 12974 __func__); 12975 return QDF_STATUS_E_NOMEM; 12976 } 12977 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 12978 12979 /* Prepare the send buffer */ 12980 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12981 (num_of_diag_events_logs * sizeof(uint32_t)); 12982 12983 buf = wmi_buf_alloc(wmi_handle, buf_len); 12984 if (!buf) { 12985 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 12986 qdf_mem_free(wmi_handle->events_logs_list); 12987 wmi_handle->events_logs_list = NULL; 12988 return QDF_STATUS_E_NOMEM; 12989 } 12990 12991 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 12992 buf_ptr = (uint8_t *) cmd; 12993 12994 WMITLV_SET_HDR(&cmd->tlv_header, 12995 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 12996 WMITLV_GET_STRUCT_TLVLEN( 12997 wmi_diag_event_log_config_fixed_param)); 12998 12999 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13000 13001 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13002 13003 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13004 (num_of_diag_events_logs * sizeof(uint32_t))); 13005 13006 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13007 13008 /* Populate the events */ 13009 for (i = 0; i < num_of_diag_events_logs; i++) { 13010 /* Low freq (0) - Enable (1) the event 13011 * High freq (1) - Disable (0) the event 13012 */ 13013 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13014 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13015 /* Set the event ID */ 13016 WMI_DIAG_ID_SET(cmd_args[i], 13017 WMI_DIAG_ID_GET(evt_args[i])); 13018 /* Set the type */ 13019 WMI_DIAG_TYPE_SET(cmd_args[i], 13020 WMI_DIAG_TYPE_GET(evt_args[i])); 13021 /* Storing the event/log list in WMI */ 13022 wmi_handle->events_logs_list[i] = evt_args[i]; 13023 } 13024 13025 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13026 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13027 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13028 __func__); 13029 wmi_buf_free(buf); 13030 /* Not clearing events_logs_list, though wmi cmd failed. 13031 * Host can still have this list 13032 */ 13033 return QDF_STATUS_E_INVAL; 13034 } 13035 13036 return 0; 13037 } 13038 13039 /** 13040 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13041 * @wmi_handle: wmi handle 13042 * @start_log: Start logging related parameters 13043 * 13044 * Send the command to the FW based on which specific logging of diag 13045 * event/log id can be started/stopped 13046 * 13047 * Return: None 13048 */ 13049 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13050 struct wmi_wifi_start_log *start_log) 13051 { 13052 wmi_diag_event_log_config_fixed_param *cmd; 13053 wmi_buf_t buf; 13054 uint8_t *buf_ptr; 13055 uint32_t len, count, log_level, i; 13056 uint32_t *cmd_args; 13057 uint32_t total_len; 13058 count = 0; 13059 13060 if (!wmi_handle->events_logs_list) { 13061 WMI_LOGE("%s: Not received event/log list from FW, yet", 13062 __func__); 13063 return QDF_STATUS_E_NOMEM; 13064 } 13065 /* total_len stores the number of events where BITS 17 and 18 are set. 13066 * i.e., events of high frequency (17) and for extended debugging (18) 13067 */ 13068 total_len = 0; 13069 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13070 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13071 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13072 total_len++; 13073 } 13074 13075 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13076 (total_len * sizeof(uint32_t)); 13077 13078 buf = wmi_buf_alloc(wmi_handle, len); 13079 if (!buf) { 13080 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13081 return QDF_STATUS_E_NOMEM; 13082 } 13083 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13084 buf_ptr = (uint8_t *) cmd; 13085 13086 WMITLV_SET_HDR(&cmd->tlv_header, 13087 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13088 WMITLV_GET_STRUCT_TLVLEN( 13089 wmi_diag_event_log_config_fixed_param)); 13090 13091 cmd->num_of_diag_events_logs = total_len; 13092 13093 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13094 13095 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13096 (total_len * sizeof(uint32_t))); 13097 13098 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13099 13100 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13101 log_level = 1; 13102 else 13103 log_level = 0; 13104 13105 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13106 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13107 uint32_t val = wmi_handle->events_logs_list[i]; 13108 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13109 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13110 13111 WMI_DIAG_ID_SET(cmd_args[count], 13112 WMI_DIAG_ID_GET(val)); 13113 WMI_DIAG_TYPE_SET(cmd_args[count], 13114 WMI_DIAG_TYPE_GET(val)); 13115 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13116 log_level); 13117 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13118 count++; 13119 } 13120 } 13121 13122 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13123 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13124 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13125 __func__); 13126 wmi_buf_free(buf); 13127 return QDF_STATUS_E_INVAL; 13128 } 13129 13130 return QDF_STATUS_SUCCESS; 13131 } 13132 13133 /** 13134 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13135 * @wmi_handle: WMI handle 13136 * 13137 * This function is used to send the flush command to the FW, 13138 * that will flush the fw logs that are residue in the FW 13139 * 13140 * Return: None 13141 */ 13142 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13143 { 13144 wmi_debug_mesg_flush_fixed_param *cmd; 13145 wmi_buf_t buf; 13146 int len = sizeof(*cmd); 13147 QDF_STATUS ret; 13148 13149 buf = wmi_buf_alloc(wmi_handle, len); 13150 if (!buf) { 13151 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13152 return QDF_STATUS_E_NOMEM; 13153 } 13154 13155 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13156 WMITLV_SET_HDR(&cmd->tlv_header, 13157 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13158 WMITLV_GET_STRUCT_TLVLEN( 13159 wmi_debug_mesg_flush_fixed_param)); 13160 cmd->reserved0 = 0; 13161 13162 ret = wmi_unified_cmd_send(wmi_handle, 13163 buf, 13164 len, 13165 WMI_DEBUG_MESG_FLUSH_CMDID); 13166 if (QDF_IS_STATUS_ERROR(ret)) { 13167 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13168 wmi_buf_free(buf); 13169 return QDF_STATUS_E_INVAL; 13170 } 13171 WMI_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13172 13173 return ret; 13174 } 13175 13176 /** 13177 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13178 * @wmi_handle: wmi handle 13179 * @msg: PCL structure containing the PCL and the number of channels 13180 * 13181 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13182 * firmware. The DBS Manager is the consumer of this information in the WLAN 13183 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13184 * to migrate to a new channel without host driver involvement. An example of 13185 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13186 * manage the channel selection without firmware involvement. 13187 * 13188 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13189 * channel list. The weights corresponds to the channels sent in 13190 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13191 * weightage compared to the non PCL channels. 13192 * 13193 * Return: Success if the cmd is sent successfully to the firmware 13194 */ 13195 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13196 struct wmi_pcl_chan_weights *msg) 13197 { 13198 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13199 wmi_buf_t buf; 13200 uint8_t *buf_ptr; 13201 uint32_t *cmd_args, i, len; 13202 uint32_t chan_len; 13203 13204 chan_len = msg->saved_num_chan; 13205 13206 len = sizeof(*cmd) + 13207 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13208 13209 buf = wmi_buf_alloc(wmi_handle, len); 13210 if (!buf) { 13211 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13212 return QDF_STATUS_E_NOMEM; 13213 } 13214 13215 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13216 buf_ptr = (uint8_t *) cmd; 13217 WMITLV_SET_HDR(&cmd->tlv_header, 13218 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13219 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13220 13221 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13222 WMI_HOST_PDEV_ID_SOC); 13223 cmd->num_chan = chan_len; 13224 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13225 13226 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13227 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13228 (chan_len * sizeof(uint32_t))); 13229 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13230 for (i = 0; i < chan_len ; i++) { 13231 cmd_args[i] = msg->weighed_valid_list[i]; 13232 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13233 msg->saved_chan_list[i], cmd_args[i]); 13234 } 13235 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13236 WMI_PDEV_SET_PCL_CMDID)) { 13237 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13238 wmi_buf_free(buf); 13239 return QDF_STATUS_E_FAILURE; 13240 } 13241 return QDF_STATUS_SUCCESS; 13242 } 13243 13244 /** 13245 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13246 * @wmi_handle: wmi handle 13247 * @msg: Structure containing the following parameters 13248 * 13249 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13250 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13251 * 13252 * Provides notification to the WLAN firmware that host driver is requesting a 13253 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13254 * configurations that include the Dual Band Simultaneous (DBS) feature. 13255 * 13256 * Return: Success if the cmd is sent successfully to the firmware 13257 */ 13258 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13259 uint32_t hw_mode_index) 13260 { 13261 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13262 wmi_buf_t buf; 13263 uint32_t len; 13264 13265 len = sizeof(*cmd); 13266 13267 buf = wmi_buf_alloc(wmi_handle, len); 13268 if (!buf) { 13269 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13270 return QDF_STATUS_E_NOMEM; 13271 } 13272 13273 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13274 WMITLV_SET_HDR(&cmd->tlv_header, 13275 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13276 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13277 13278 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13279 WMI_HOST_PDEV_ID_SOC); 13280 cmd->hw_mode_index = hw_mode_index; 13281 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13282 13283 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13284 WMI_PDEV_SET_HW_MODE_CMDID)) { 13285 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13286 __func__); 13287 wmi_buf_free(buf); 13288 return QDF_STATUS_E_FAILURE; 13289 } 13290 13291 return QDF_STATUS_SUCCESS; 13292 } 13293 13294 #ifdef WLAN_POLICY_MGR_ENABLE 13295 /** 13296 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13297 * @wmi_handle: wmi handle 13298 * @msg: Dual MAC config parameters 13299 * 13300 * Configures WLAN firmware with the dual MAC features 13301 * 13302 * Return: QDF_STATUS. 0 on success. 13303 */ 13304 static 13305 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13306 struct policy_mgr_dual_mac_config *msg) 13307 { 13308 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13309 wmi_buf_t buf; 13310 uint32_t len; 13311 13312 len = sizeof(*cmd); 13313 13314 buf = wmi_buf_alloc(wmi_handle, len); 13315 if (!buf) { 13316 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13317 return QDF_STATUS_E_FAILURE; 13318 } 13319 13320 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13321 WMITLV_SET_HDR(&cmd->tlv_header, 13322 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13323 WMITLV_GET_STRUCT_TLVLEN( 13324 wmi_pdev_set_mac_config_cmd_fixed_param)); 13325 13326 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13327 WMI_HOST_PDEV_ID_SOC); 13328 cmd->concurrent_scan_config_bits = msg->scan_config; 13329 cmd->fw_mode_config_bits = msg->fw_mode_config; 13330 WMI_LOGI("%s: scan_config:%x fw_mode_config:%x", 13331 __func__, msg->scan_config, msg->fw_mode_config); 13332 13333 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13334 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13335 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13336 __func__); 13337 wmi_buf_free(buf); 13338 } 13339 return QDF_STATUS_SUCCESS; 13340 } 13341 #endif 13342 13343 #ifdef BIG_ENDIAN_HOST 13344 /** 13345 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13346 * @param data_len - data length 13347 * @param data - pointer to data 13348 * 13349 * Return: QDF_STATUS - success or error status 13350 */ 13351 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13352 struct fips_params *param) 13353 { 13354 unsigned char *key_unaligned, *data_unaligned; 13355 int c; 13356 u_int8_t *key_aligned = NULL; 13357 u_int8_t *data_aligned = NULL; 13358 13359 /* Assigning unaligned space to copy the key */ 13360 key_unaligned = qdf_mem_malloc( 13361 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 13362 data_unaligned = qdf_mem_malloc( 13363 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 13364 13365 /* Checking if kmalloc is successful to allocate space */ 13366 if (key_unaligned == NULL) 13367 return QDF_STATUS_SUCCESS; 13368 /* Checking if space is aligned */ 13369 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 13370 /* align to 4 */ 13371 key_aligned = 13372 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 13373 FIPS_ALIGN); 13374 } else { 13375 key_aligned = (u_int8_t *)key_unaligned; 13376 } 13377 13378 /* memset and copy content from key to key aligned */ 13379 OS_MEMSET(key_aligned, 0, param->key_len); 13380 OS_MEMCPY(key_aligned, param->key, param->key_len); 13381 13382 /* print a hexdump for host debug */ 13383 print_hex_dump(KERN_DEBUG, 13384 "\t Aligned and Copied Key:@@@@ ", 13385 DUMP_PREFIX_NONE, 13386 16, 1, key_aligned, param->key_len, true); 13387 13388 /* Checking if kmalloc is successful to allocate space */ 13389 if (data_unaligned == NULL) 13390 return QDF_STATUS_SUCCESS; 13391 /* Checking of space is aligned */ 13392 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13393 /* align to 4 */ 13394 data_aligned = 13395 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 13396 FIPS_ALIGN); 13397 } else { 13398 data_aligned = (u_int8_t *)data_unaligned; 13399 } 13400 13401 /* memset and copy content from data to data aligned */ 13402 OS_MEMSET(data_aligned, 0, param->data_len); 13403 OS_MEMCPY(data_aligned, param->data, param->data_len); 13404 13405 /* print a hexdump for host debug */ 13406 print_hex_dump(KERN_DEBUG, 13407 "\t Properly Aligned and Copied Data:@@@@ ", 13408 DUMP_PREFIX_NONE, 13409 16, 1, data_aligned, param->data_len, true); 13410 13411 /* converting to little Endian both key_aligned and 13412 * data_aligned*/ 13413 for (c = 0; c < param->key_len/4; c++) { 13414 *((u_int32_t *)key_aligned+c) = 13415 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 13416 } 13417 for (c = 0; c < param->data_len/4; c++) { 13418 *((u_int32_t *)data_aligned+c) = 13419 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 13420 } 13421 13422 /* update endian data to key and data vectors */ 13423 OS_MEMCPY(param->key, key_aligned, param->key_len); 13424 OS_MEMCPY(param->data, data_aligned, param->data_len); 13425 13426 /* clean up allocated spaces */ 13427 qdf_mem_free(key_unaligned); 13428 key_unaligned = NULL; 13429 key_aligned = NULL; 13430 13431 qdf_mem_free(data_unaligned); 13432 data_unaligned = NULL; 13433 data_aligned = NULL; 13434 13435 return QDF_STATUS_SUCCESS; 13436 } 13437 #else 13438 /** 13439 * fips_align_data_be() - DUMMY for LE platform 13440 * 13441 * Return: QDF_STATUS - success 13442 */ 13443 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13444 struct fips_params *param) 13445 { 13446 return QDF_STATUS_SUCCESS; 13447 } 13448 #endif 13449 13450 13451 /** 13452 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 13453 * @wmi_handle: wmi handle 13454 * @param: pointer to hold pdev fips param 13455 * 13456 * Return: 0 for success or error code 13457 */ 13458 static QDF_STATUS 13459 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 13460 struct fips_params *param) 13461 { 13462 wmi_pdev_fips_cmd_fixed_param *cmd; 13463 wmi_buf_t buf; 13464 uint8_t *buf_ptr; 13465 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 13466 QDF_STATUS retval = QDF_STATUS_SUCCESS; 13467 13468 /* Length TLV placeholder for array of bytes */ 13469 len += WMI_TLV_HDR_SIZE; 13470 if (param->data_len) 13471 len += (param->data_len*sizeof(uint8_t)); 13472 13473 /* 13474 * Data length must be multiples of 16 bytes - checked against 0xF - 13475 * and must be less than WMI_SVC_MSG_SIZE - static size of 13476 * wmi_pdev_fips_cmd structure 13477 */ 13478 13479 /* do sanity on the input */ 13480 if (!(((param->data_len & 0xF) == 0) && 13481 ((param->data_len > 0) && 13482 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 13483 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 13484 return QDF_STATUS_E_INVAL; 13485 } 13486 13487 buf = wmi_buf_alloc(wmi_handle, len); 13488 if (!buf) { 13489 qdf_print("%s:wmi_buf_alloc failed", __func__); 13490 return QDF_STATUS_E_FAILURE; 13491 } 13492 13493 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13494 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 13495 WMITLV_SET_HDR(&cmd->tlv_header, 13496 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 13497 WMITLV_GET_STRUCT_TLVLEN 13498 (wmi_pdev_fips_cmd_fixed_param)); 13499 13500 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13501 param->pdev_id); 13502 if (param->key != NULL && param->data != NULL) { 13503 cmd->key_len = param->key_len; 13504 cmd->data_len = param->data_len; 13505 cmd->fips_cmd = !!(param->op); 13506 13507 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 13508 return QDF_STATUS_E_FAILURE; 13509 13510 qdf_mem_copy(cmd->key, param->key, param->key_len); 13511 13512 if (param->mode == FIPS_ENGINE_AES_CTR || 13513 param->mode == FIPS_ENGINE_AES_MIC) { 13514 cmd->mode = param->mode; 13515 } else { 13516 cmd->mode = FIPS_ENGINE_AES_CTR; 13517 } 13518 qdf_print("Key len = %d, Data len = %d", 13519 cmd->key_len, cmd->data_len); 13520 13521 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 13522 cmd->key, cmd->key_len, true); 13523 buf_ptr += sizeof(*cmd); 13524 13525 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 13526 13527 buf_ptr += WMI_TLV_HDR_SIZE; 13528 if (param->data_len) 13529 qdf_mem_copy(buf_ptr, 13530 (uint8_t *) param->data, param->data_len); 13531 13532 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 13533 16, 1, buf_ptr, cmd->data_len, true); 13534 13535 buf_ptr += param->data_len; 13536 13537 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 13538 WMI_PDEV_FIPS_CMDID); 13539 qdf_print("%s return value %d", __func__, retval); 13540 } else { 13541 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 13542 wmi_buf_free(buf); 13543 retval = -QDF_STATUS_E_BADMSG; 13544 } 13545 13546 return retval; 13547 } 13548 13549 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 13550 /** 13551 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 13552 * @wmi_handle: wmi handle 13553 * @vdev_id: vdev id 13554 * @bitmap: Event bitmap 13555 * @enable: enable/disable 13556 * 13557 * Return: CDF status 13558 */ 13559 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 13560 uint32_t vdev_id, 13561 uint32_t *bitmap, 13562 bool enable) 13563 { 13564 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 13565 uint16_t len; 13566 wmi_buf_t buf; 13567 int ret; 13568 13569 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 13570 buf = wmi_buf_alloc(wmi_handle, len); 13571 if (!buf) { 13572 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13573 return QDF_STATUS_E_NOMEM; 13574 } 13575 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 13576 WMITLV_SET_HDR(&cmd->tlv_header, 13577 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 13578 WMITLV_GET_STRUCT_TLVLEN 13579 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 13580 cmd->vdev_id = vdev_id; 13581 cmd->is_add = enable; 13582 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 13583 WMI_WOW_MAX_EVENT_BM_LEN); 13584 13585 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 13586 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 13587 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 13588 13589 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13590 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 13591 if (ret) { 13592 WMI_LOGE("Failed to config wow wakeup event"); 13593 wmi_buf_free(buf); 13594 return QDF_STATUS_E_FAILURE; 13595 } 13596 13597 return QDF_STATUS_SUCCESS; 13598 } 13599 13600 /** 13601 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 13602 * @wmi_handle: wmi handle 13603 * @vdev_id: vdev id 13604 * @ptrn_id: pattern id 13605 * @ptrn: pattern 13606 * @ptrn_len: pattern length 13607 * @ptrn_offset: pattern offset 13608 * @mask: mask 13609 * @mask_len: mask length 13610 * @user: true for user configured pattern and false for default pattern 13611 * @default_patterns: default patterns 13612 * 13613 * Return: CDF status 13614 */ 13615 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 13616 uint8_t vdev_id, uint8_t ptrn_id, 13617 const uint8_t *ptrn, uint8_t ptrn_len, 13618 uint8_t ptrn_offset, const uint8_t *mask, 13619 uint8_t mask_len, bool user, 13620 uint8_t default_patterns) 13621 { 13622 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13623 WOW_BITMAP_PATTERN_T *bitmap_pattern; 13624 wmi_buf_t buf; 13625 uint8_t *buf_ptr; 13626 int32_t len; 13627 int ret; 13628 13629 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13630 WMI_TLV_HDR_SIZE + 13631 1 * sizeof(WOW_BITMAP_PATTERN_T) + 13632 WMI_TLV_HDR_SIZE + 13633 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13634 WMI_TLV_HDR_SIZE + 13635 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13636 WMI_TLV_HDR_SIZE + 13637 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13638 WMI_TLV_HDR_SIZE + 13639 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13640 13641 buf = wmi_buf_alloc(wmi_handle, len); 13642 if (!buf) { 13643 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13644 return QDF_STATUS_E_NOMEM; 13645 } 13646 13647 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13648 buf_ptr = (uint8_t *) cmd; 13649 13650 WMITLV_SET_HDR(&cmd->tlv_header, 13651 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13652 WMITLV_GET_STRUCT_TLVLEN 13653 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13654 cmd->vdev_id = vdev_id; 13655 cmd->pattern_id = ptrn_id; 13656 13657 cmd->pattern_type = WOW_BITMAP_PATTERN; 13658 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13659 13660 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13661 sizeof(WOW_BITMAP_PATTERN_T)); 13662 buf_ptr += WMI_TLV_HDR_SIZE; 13663 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 13664 13665 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 13666 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 13667 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 13668 13669 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 13670 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 13671 13672 bitmap_pattern->pattern_offset = ptrn_offset; 13673 bitmap_pattern->pattern_len = ptrn_len; 13674 13675 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 13676 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 13677 13678 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 13679 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 13680 13681 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 13682 bitmap_pattern->pattern_id = ptrn_id; 13683 13684 WMI_LOGI("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 13685 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 13686 bitmap_pattern->pattern_offset, user); 13687 WMI_LOGI("Pattern : "); 13688 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13689 &bitmap_pattern->patternbuf[0], bitmap_pattern->pattern_len); 13690 13691 WMI_LOGI("Mask : "); 13692 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO, 13693 &bitmap_pattern->bitmaskbuf[0], bitmap_pattern->pattern_len); 13694 13695 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 13696 13697 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 13698 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 13699 buf_ptr += WMI_TLV_HDR_SIZE; 13700 13701 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_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_MAGIC_PATTERN_CMD 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 pattern_info_timeout but no data. */ 13710 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 13711 buf_ptr += WMI_TLV_HDR_SIZE; 13712 13713 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 13714 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 13715 buf_ptr += WMI_TLV_HDR_SIZE; 13716 *(uint32_t *) buf_ptr = 0; 13717 13718 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13719 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 13720 if (ret) { 13721 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 13722 wmi_buf_free(buf); 13723 return QDF_STATUS_E_FAILURE; 13724 } 13725 13726 return QDF_STATUS_SUCCESS; 13727 } 13728 13729 /** 13730 * fill_arp_offload_params_tlv() - Fill ARP offload data 13731 * @wmi_handle: wmi handle 13732 * @offload_req: offload request 13733 * @buf_ptr: buffer pointer 13734 * 13735 * To fill ARP offload data to firmware 13736 * when target goes to wow mode. 13737 * 13738 * Return: None 13739 */ 13740 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 13741 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 13742 { 13743 13744 int i; 13745 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 13746 bool enable_or_disable = offload_req->enable; 13747 13748 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13749 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 13750 *buf_ptr += WMI_TLV_HDR_SIZE; 13751 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 13752 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 13753 WMITLV_SET_HDR(&arp_tuple->tlv_header, 13754 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 13755 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 13756 13757 /* Fill data for ARP and NS in the first tupple for LA */ 13758 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 13759 /* Copy the target ip addr and flags */ 13760 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 13761 qdf_mem_copy(&arp_tuple->target_ipaddr, 13762 offload_req->host_ipv4_addr, 13763 WMI_IPV4_ADDR_LEN); 13764 WMI_LOGD("ARPOffload IP4 address: %pI4", 13765 offload_req->host_ipv4_addr); 13766 } 13767 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 13768 } 13769 } 13770 13771 #ifdef WLAN_NS_OFFLOAD 13772 /** 13773 * fill_ns_offload_params_tlv() - Fill NS offload data 13774 * @wmi|_handle: wmi handle 13775 * @offload_req: offload request 13776 * @buf_ptr: buffer pointer 13777 * 13778 * To fill NS offload data to firmware 13779 * when target goes to wow mode. 13780 * 13781 * Return: None 13782 */ 13783 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13784 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13785 { 13786 13787 int i; 13788 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13789 13790 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13791 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13792 *buf_ptr += WMI_TLV_HDR_SIZE; 13793 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 13794 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13795 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13796 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13797 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 13798 13799 /* 13800 * Fill data only for NS offload in the first ARP tuple for LA 13801 */ 13802 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13803 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13804 /* Copy the target/solicitation/remote ip addr */ 13805 if (ns_req->target_ipv6_addr_valid[i]) 13806 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13807 &ns_req->target_ipv6_addr[i], 13808 sizeof(WMI_IPV6_ADDR)); 13809 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13810 &ns_req->self_ipv6_addr[i], 13811 sizeof(WMI_IPV6_ADDR)); 13812 if (ns_req->target_ipv6_addr_ac_type[i]) { 13813 ns_tuple->flags |= 13814 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13815 } 13816 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13817 i, &ns_req->self_ipv6_addr[i], 13818 &ns_req->target_ipv6_addr[i]); 13819 13820 /* target MAC is optional, check if it is valid, 13821 * if this is not valid, the target will use the known 13822 * local MAC address rather than the tuple 13823 */ 13824 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13825 ns_req->self_macaddr.bytes, 13826 &ns_tuple->target_mac); 13827 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13828 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13829 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13830 } 13831 } 13832 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13833 } 13834 } 13835 13836 13837 /** 13838 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 13839 * @wmi: wmi handle 13840 * @offload_req: offload request 13841 * @buf_ptr: buffer pointer 13842 * 13843 * To fill extended NS offload extended data to firmware 13844 * when target goes to wow mode. 13845 * 13846 * Return: None 13847 */ 13848 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13849 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13850 { 13851 int i; 13852 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 13853 uint32_t count, num_ns_ext_tuples; 13854 13855 count = ns_req->num_ns_offload_count; 13856 num_ns_ext_tuples = ns_req->num_ns_offload_count - 13857 WMI_MAX_NS_OFFLOADS; 13858 13859 /* Populate extended NS offload tuples */ 13860 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13861 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 13862 *buf_ptr += WMI_TLV_HDR_SIZE; 13863 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 13864 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 13865 WMITLV_SET_HDR(&ns_tuple->tlv_header, 13866 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 13867 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 13868 13869 /* 13870 * Fill data only for NS offload in the first ARP tuple for LA 13871 */ 13872 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 13873 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 13874 /* Copy the target/solicitation/remote ip addr */ 13875 if (ns_req->target_ipv6_addr_valid[i]) 13876 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 13877 &ns_req->target_ipv6_addr[i], 13878 sizeof(WMI_IPV6_ADDR)); 13879 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 13880 &ns_req->self_ipv6_addr[i], 13881 sizeof(WMI_IPV6_ADDR)); 13882 if (ns_req->target_ipv6_addr_ac_type[i]) { 13883 ns_tuple->flags |= 13884 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 13885 } 13886 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 13887 i, &ns_req->self_ipv6_addr[i], 13888 &ns_req->target_ipv6_addr[i]); 13889 13890 /* target MAC is optional, check if it is valid, 13891 * if this is not valid, the target will use the 13892 * known local MAC address rather than the tuple 13893 */ 13894 WMI_CHAR_ARRAY_TO_MAC_ADDR( 13895 ns_req->self_macaddr.bytes, 13896 &ns_tuple->target_mac); 13897 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 13898 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 13899 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 13900 } 13901 } 13902 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 13903 } 13904 } 13905 #else 13906 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 13907 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13908 { 13909 } 13910 13911 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 13912 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 13913 { 13914 } 13915 #endif 13916 13917 /** 13918 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 13919 * @wma: wmi handle 13920 * @arp_offload_req: arp offload request 13921 * @ns_offload_req: ns offload request 13922 * @arp_only: flag 13923 * 13924 * To configure ARP NS off load data to firmware 13925 * when target goes to wow mode. 13926 * 13927 * Return: QDF Status 13928 */ 13929 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 13930 struct pmo_arp_offload_params *arp_offload_req, 13931 struct pmo_ns_offload_params *ns_offload_req, 13932 uint8_t vdev_id) 13933 { 13934 int32_t res; 13935 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 13936 uint8_t *buf_ptr; 13937 wmi_buf_t buf; 13938 int32_t len; 13939 uint32_t count = 0, num_ns_ext_tuples = 0; 13940 13941 count = ns_offload_req->num_ns_offload_count; 13942 13943 /* 13944 * TLV place holder size for array of NS tuples 13945 * TLV place holder size for array of ARP tuples 13946 */ 13947 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 13948 WMI_TLV_HDR_SIZE + 13949 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 13950 WMI_TLV_HDR_SIZE + 13951 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 13952 13953 /* 13954 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 13955 * extra length for extended NS offload tuples which follows ARP offload 13956 * tuples. Host needs to fill this structure in following format: 13957 * 2 NS ofload tuples 13958 * 2 ARP offload tuples 13959 * N numbers of extended NS offload tuples if HDD has given more than 13960 * 2 NS offload addresses 13961 */ 13962 if (count > WMI_MAX_NS_OFFLOADS) { 13963 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 13964 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 13965 * sizeof(WMI_NS_OFFLOAD_TUPLE); 13966 } 13967 13968 buf = wmi_buf_alloc(wmi_handle, len); 13969 if (!buf) { 13970 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13971 return QDF_STATUS_E_NOMEM; 13972 } 13973 13974 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13975 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 13976 WMITLV_SET_HDR(&cmd->tlv_header, 13977 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 13978 WMITLV_GET_STRUCT_TLVLEN 13979 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 13980 cmd->flags = 0; 13981 cmd->vdev_id = vdev_id; 13982 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 13983 13984 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 13985 13986 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 13987 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13988 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 13989 if (num_ns_ext_tuples) 13990 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 13991 13992 res = wmi_unified_cmd_send(wmi_handle, buf, len, 13993 WMI_SET_ARP_NS_OFFLOAD_CMDID); 13994 if (res) { 13995 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 13996 wmi_buf_free(buf); 13997 return QDF_STATUS_E_FAILURE; 13998 } 13999 14000 return QDF_STATUS_SUCCESS; 14001 } 14002 14003 /** 14004 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14005 * @wmi_handle: wmi handle 14006 * @vdev_id: vdev id 14007 * @action: true for enable else false 14008 * 14009 * To enable enhance multicast offload to firmware 14010 * when target goes to wow mode. 14011 * 14012 * Return: QDF Status 14013 */ 14014 14015 static 14016 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14017 wmi_unified_t wmi_handle, 14018 uint8_t vdev_id, bool action) 14019 { 14020 QDF_STATUS status; 14021 wmi_buf_t buf; 14022 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14023 14024 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14025 if (!buf) { 14026 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14027 return QDF_STATUS_E_NOMEM; 14028 } 14029 14030 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14031 wmi_buf_data(buf); 14032 14033 WMITLV_SET_HDR(&cmd->tlv_header, 14034 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14035 WMITLV_GET_STRUCT_TLVLEN( 14036 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14037 14038 cmd->vdev_id = vdev_id; 14039 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14040 ENHANCED_MCAST_FILTER_ENABLED); 14041 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14042 __func__, action, vdev_id); 14043 status = wmi_unified_cmd_send(wmi_handle, buf, 14044 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14045 if (status != QDF_STATUS_SUCCESS) { 14046 qdf_nbuf_free(buf); 14047 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14048 __func__); 14049 } 14050 14051 return status; 14052 } 14053 14054 /** 14055 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14056 * @wmi_handle: wmi handle 14057 * @param evt_buf: pointer to event buffer 14058 * @param hdr: Pointer to hold header 14059 * @param bufp: Pointer to hold pointer to rx param buffer 14060 * 14061 * Return: QDF_STATUS_SUCCESS for success or error code 14062 */ 14063 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14064 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14065 { 14066 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14067 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14068 14069 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14070 if (!param_buf) { 14071 WMI_LOGE("gtk param_buf is NULL"); 14072 return QDF_STATUS_E_INVAL; 14073 } 14074 14075 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14076 WMI_LOGE("Invalid length for GTK status"); 14077 return QDF_STATUS_E_INVAL; 14078 } 14079 14080 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14081 param_buf->fixed_param; 14082 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14083 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14084 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14085 qdf_mem_copy(>k_rsp_param->replay_counter, 14086 &fixed_param->replay_counter, 14087 GTK_REPLAY_COUNTER_BYTES); 14088 14089 return QDF_STATUS_SUCCESS; 14090 14091 } 14092 14093 #ifdef FEATURE_WLAN_RA_FILTERING 14094 /** 14095 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14096 * @wmi_handle: wmi handle 14097 * @vdev_id: vdev id 14098 * 14099 * Return: CDF status 14100 */ 14101 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14102 uint8_t vdev_id, uint8_t default_pattern, 14103 uint16_t rate_limit_interval) 14104 { 14105 14106 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14107 wmi_buf_t buf; 14108 uint8_t *buf_ptr; 14109 int32_t len; 14110 int ret; 14111 14112 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14113 WMI_TLV_HDR_SIZE + 14114 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14115 WMI_TLV_HDR_SIZE + 14116 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14117 WMI_TLV_HDR_SIZE + 14118 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14119 WMI_TLV_HDR_SIZE + 14120 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14121 WMI_TLV_HDR_SIZE + 14122 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14123 14124 buf = wmi_buf_alloc(wmi_handle, len); 14125 if (!buf) { 14126 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14127 return QDF_STATUS_E_NOMEM; 14128 } 14129 14130 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14131 buf_ptr = (uint8_t *) cmd; 14132 14133 WMITLV_SET_HDR(&cmd->tlv_header, 14134 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14135 WMITLV_GET_STRUCT_TLVLEN 14136 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14137 cmd->vdev_id = vdev_id; 14138 cmd->pattern_id = default_pattern, 14139 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14140 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14141 14142 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14143 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14144 buf_ptr += WMI_TLV_HDR_SIZE; 14145 14146 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_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_IPV6_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_MAGIC_PATTERN_CMD 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 pattern_info_timeout but no data. */ 14159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14160 buf_ptr += WMI_TLV_HDR_SIZE; 14161 14162 /* Fill TLV for ra_ratelimit_interval. */ 14163 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14164 buf_ptr += WMI_TLV_HDR_SIZE; 14165 14166 *((uint32_t *) buf_ptr) = rate_limit_interval; 14167 14168 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14169 rate_limit_interval, vdev_id); 14170 14171 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14172 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14173 if (ret) { 14174 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14175 wmi_buf_free(buf); 14176 return QDF_STATUS_E_FAILURE; 14177 } 14178 14179 return QDF_STATUS_SUCCESS; 14180 14181 } 14182 #endif /* FEATURE_WLAN_RA_FILTERING */ 14183 14184 /** 14185 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14186 * @wmi_handle: wmi handle 14187 * @vdev_id: vdev id 14188 * @multicastAddr: mcast address 14189 * @clearList: clear list flag 14190 * 14191 * Return: QDF_STATUS_SUCCESS for success or error code 14192 */ 14193 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14194 uint8_t vdev_id, 14195 struct qdf_mac_addr multicast_addr, 14196 bool clearList) 14197 { 14198 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14199 wmi_buf_t buf; 14200 int err; 14201 14202 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14203 if (!buf) { 14204 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14205 return QDF_STATUS_E_NOMEM; 14206 } 14207 14208 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14209 qdf_mem_zero(cmd, sizeof(*cmd)); 14210 14211 WMITLV_SET_HDR(&cmd->tlv_header, 14212 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14213 WMITLV_GET_STRUCT_TLVLEN 14214 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14215 cmd->action = 14216 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14217 cmd->vdev_id = vdev_id; 14218 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14219 14220 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14221 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14222 14223 err = wmi_unified_cmd_send(wmi_handle, buf, 14224 sizeof(*cmd), 14225 WMI_SET_MCASTBCAST_FILTER_CMDID); 14226 if (err) { 14227 WMI_LOGE("Failed to send set_param cmd"); 14228 wmi_buf_free(buf); 14229 return QDF_STATUS_E_FAILURE; 14230 } 14231 14232 return QDF_STATUS_SUCCESS; 14233 } 14234 14235 /** 14236 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14237 * command to fw 14238 * @wmi_handle: wmi handle 14239 * @vdev_id: vdev id 14240 * @mcast_filter_params: mcast filter params 14241 * 14242 * Return: QDF_STATUS_SUCCESS for success or error code 14243 */ 14244 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14245 wmi_unified_t wmi_handle, 14246 uint8_t vdev_id, 14247 struct pmo_mcast_filter_params *filter_param) 14248 14249 { 14250 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14251 uint8_t *buf_ptr; 14252 wmi_buf_t buf; 14253 int err; 14254 int i; 14255 uint8_t *mac_addr_src_ptr = NULL; 14256 wmi_mac_addr *mac_addr_dst_ptr; 14257 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14258 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14259 14260 buf = wmi_buf_alloc(wmi_handle, len); 14261 if (!buf) { 14262 WMI_LOGE("Failed to allocate memory"); 14263 return QDF_STATUS_E_NOMEM; 14264 } 14265 14266 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14267 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14268 wmi_buf_data(buf); 14269 qdf_mem_zero(cmd, sizeof(*cmd)); 14270 14271 WMITLV_SET_HDR(&cmd->tlv_header, 14272 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14273 WMITLV_GET_STRUCT_TLVLEN 14274 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14275 cmd->operation = 14276 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14277 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14278 cmd->vdev_id = vdev_id; 14279 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14280 14281 buf_ptr += sizeof(*cmd); 14282 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14283 sizeof(wmi_mac_addr) * 14284 filter_param->multicast_addr_cnt); 14285 14286 if (filter_param->multicast_addr_cnt == 0) 14287 goto send_cmd; 14288 14289 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14290 mac_addr_dst_ptr = (wmi_mac_addr *) 14291 (buf_ptr + WMI_TLV_HDR_SIZE); 14292 14293 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14294 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14295 mac_addr_src_ptr += ATH_MAC_LEN; 14296 mac_addr_dst_ptr++; 14297 } 14298 14299 send_cmd: 14300 err = wmi_unified_cmd_send(wmi_handle, buf, 14301 len, 14302 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14303 if (err) { 14304 WMI_LOGE("Failed to send set_param cmd"); 14305 wmi_buf_free(buf); 14306 return QDF_STATUS_E_FAILURE; 14307 } 14308 14309 return QDF_STATUS_SUCCESS; 14310 } 14311 14312 static void 14313 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd, 14314 uint8_t vdev_id, 14315 struct pmo_gtk_req *params) 14316 { 14317 uint8_t *buf_ptr; 14318 wmi_gtk_offload_fils_tlv_param *ext_param; 14319 14320 buf_ptr = (uint8_t *) cmd + sizeof(*cmd); 14321 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14322 sizeof(*ext_param)); 14323 buf_ptr += WMI_TLV_HDR_SIZE; 14324 14325 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 14326 WMITLV_SET_HDR(&ext_param->tlv_header, 14327 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 14328 WMITLV_GET_STRUCT_TLVLEN( 14329 wmi_gtk_offload_fils_tlv_param)); 14330 ext_param->vdev_id = vdev_id; 14331 ext_param->flags = cmd->flags; 14332 ext_param->kek_len = params->kek_len; 14333 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 14334 qdf_mem_copy(ext_param->KCK, params->kck, 14335 WMI_GTK_OFFLOAD_KCK_BYTES); 14336 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 14337 GTK_REPLAY_COUNTER_BYTES); 14338 } 14339 14340 /** 14341 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14342 * @wmi_handle: wmi handle 14343 * @vdev_id: vdev id 14344 * @params: GTK offload parameters 14345 * 14346 * Return: CDF status 14347 */ 14348 static 14349 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14350 struct pmo_gtk_req *params, 14351 bool enable_offload, 14352 uint32_t gtk_offload_opcode) 14353 { 14354 int len; 14355 wmi_buf_t buf; 14356 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14357 QDF_STATUS status = QDF_STATUS_SUCCESS; 14358 14359 WMI_LOGD("%s Enter", __func__); 14360 14361 len = sizeof(*cmd); 14362 14363 if (params->is_fils_connection) 14364 len += WMI_TLV_HDR_SIZE + 14365 sizeof(wmi_gtk_offload_fils_tlv_param); 14366 14367 /* alloc wmi buffer */ 14368 buf = wmi_buf_alloc(wmi_handle, len); 14369 if (!buf) { 14370 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14371 status = QDF_STATUS_E_NOMEM; 14372 goto out; 14373 } 14374 14375 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14376 WMITLV_SET_HDR(&cmd->tlv_header, 14377 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14378 WMITLV_GET_STRUCT_TLVLEN 14379 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14380 14381 cmd->vdev_id = vdev_id; 14382 14383 /* Request target to enable GTK offload */ 14384 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 14385 cmd->flags = gtk_offload_opcode; 14386 14387 /* Copy the keys and replay counter */ 14388 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 14389 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 14390 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 14391 GTK_REPLAY_COUNTER_BYTES); 14392 } else { 14393 cmd->flags = gtk_offload_opcode; 14394 } 14395 if (params->is_fils_connection) 14396 fill_fils_tlv_params(cmd, vdev_id, params); 14397 14398 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 14399 /* send the wmi command */ 14400 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14401 WMI_GTK_OFFLOAD_CMDID)) { 14402 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 14403 wmi_buf_free(buf); 14404 status = QDF_STATUS_E_FAILURE; 14405 } 14406 14407 out: 14408 WMI_LOGD("%s Exit", __func__); 14409 return status; 14410 } 14411 14412 /** 14413 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 14414 * @wmi_handle: wmi handle 14415 * @params: GTK offload params 14416 * 14417 * Return: CDF status 14418 */ 14419 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 14420 wmi_unified_t wmi_handle, 14421 uint8_t vdev_id, 14422 uint64_t offload_req_opcode) 14423 { 14424 int len; 14425 wmi_buf_t buf; 14426 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14427 QDF_STATUS status = QDF_STATUS_SUCCESS; 14428 14429 len = sizeof(*cmd); 14430 14431 /* alloc wmi buffer */ 14432 buf = wmi_buf_alloc(wmi_handle, len); 14433 if (!buf) { 14434 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14435 status = QDF_STATUS_E_NOMEM; 14436 goto out; 14437 } 14438 14439 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14440 WMITLV_SET_HDR(&cmd->tlv_header, 14441 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14442 WMITLV_GET_STRUCT_TLVLEN 14443 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14444 14445 /* Request for GTK offload status */ 14446 cmd->flags = offload_req_opcode; 14447 cmd->vdev_id = vdev_id; 14448 14449 /* send the wmi command */ 14450 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14451 WMI_GTK_OFFLOAD_CMDID)) { 14452 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 14453 wmi_buf_free(buf); 14454 status = QDF_STATUS_E_FAILURE; 14455 } 14456 14457 out: 14458 return status; 14459 } 14460 14461 /** 14462 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 14463 * @wmi_handle: wmi handler 14464 * @action_params: pointer to action_params 14465 * 14466 * Return: 0 for success, otherwise appropriate error code 14467 */ 14468 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 14469 struct pmo_action_wakeup_set_params *action_params) 14470 { 14471 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 14472 wmi_buf_t buf; 14473 int i; 14474 int32_t err; 14475 uint32_t len = 0, *cmd_args; 14476 uint8_t *buf_ptr; 14477 14478 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 14479 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 14480 buf = wmi_buf_alloc(wmi_handle, len); 14481 if (!buf) { 14482 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 14483 return QDF_STATUS_E_NOMEM; 14484 } 14485 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 14486 buf_ptr = (uint8_t *)cmd; 14487 WMITLV_SET_HDR(&cmd->tlv_header, 14488 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 14489 WMITLV_GET_STRUCT_TLVLEN( 14490 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 14491 14492 cmd->vdev_id = action_params->vdev_id; 14493 cmd->operation = action_params->operation; 14494 14495 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 14496 cmd->action_category_map[i] = 14497 action_params->action_category_map[i]; 14498 14499 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 14500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14501 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 14502 buf_ptr += WMI_TLV_HDR_SIZE; 14503 cmd_args = (uint32_t *) buf_ptr; 14504 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 14505 cmd_args[i] = action_params->action_per_category[i]; 14506 14507 err = wmi_unified_cmd_send(wmi_handle, buf, 14508 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 14509 if (err) { 14510 WMI_LOGE("Failed to send ap_ps_egap cmd"); 14511 wmi_buf_free(buf); 14512 return QDF_STATUS_E_FAILURE; 14513 } 14514 14515 return QDF_STATUS_SUCCESS; 14516 } 14517 14518 #ifdef FEATURE_WLAN_LPHB 14519 14520 /** 14521 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 14522 * @wmi_handle: wmi handle 14523 * @lphb_conf_req: configuration info 14524 * 14525 * Return: CDF status 14526 */ 14527 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 14528 wmi_hb_set_enable_cmd_fixed_param *params) 14529 { 14530 QDF_STATUS status; 14531 wmi_buf_t buf = NULL; 14532 uint8_t *buf_ptr; 14533 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 14534 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 14535 14536 14537 buf = wmi_buf_alloc(wmi_handle, len); 14538 if (!buf) { 14539 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14540 return QDF_STATUS_E_NOMEM; 14541 } 14542 14543 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14544 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 14545 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 14546 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 14547 WMITLV_GET_STRUCT_TLVLEN 14548 (wmi_hb_set_enable_cmd_fixed_param)); 14549 14550 /* fill in values */ 14551 hb_enable_fp->vdev_id = params->session; 14552 hb_enable_fp->enable = params->enable; 14553 hb_enable_fp->item = params->item; 14554 hb_enable_fp->session = params->session; 14555 14556 status = wmi_unified_cmd_send(wmi_handle, buf, 14557 len, WMI_HB_SET_ENABLE_CMDID); 14558 if (QDF_IS_STATUS_ERROR(status)) { 14559 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 14560 status); 14561 wmi_buf_free(buf); 14562 } 14563 14564 return status; 14565 } 14566 14567 /** 14568 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 14569 * @wmi_handle: wmi handle 14570 * @lphb_conf_req: lphb config request 14571 * 14572 * Return: CDF status 14573 */ 14574 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 14575 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 14576 { 14577 QDF_STATUS status; 14578 wmi_buf_t buf = NULL; 14579 uint8_t *buf_ptr; 14580 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 14581 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 14582 14583 buf = wmi_buf_alloc(wmi_handle, len); 14584 if (!buf) { 14585 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14586 return QDF_STATUS_E_NOMEM; 14587 } 14588 14589 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14590 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 14591 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 14592 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 14593 WMITLV_GET_STRUCT_TLVLEN 14594 (wmi_hb_set_tcp_params_cmd_fixed_param)); 14595 14596 /* fill in values */ 14597 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14598 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14599 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14600 hb_tcp_params_fp->seq = lphb_conf_req->seq; 14601 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 14602 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 14603 hb_tcp_params_fp->interval = lphb_conf_req->interval; 14604 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 14605 hb_tcp_params_fp->session = lphb_conf_req->session; 14606 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 14607 &lphb_conf_req->gateway_mac, 14608 sizeof(hb_tcp_params_fp->gateway_mac)); 14609 14610 status = wmi_unified_cmd_send(wmi_handle, buf, 14611 len, WMI_HB_SET_TCP_PARAMS_CMDID); 14612 if (QDF_IS_STATUS_ERROR(status)) { 14613 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 14614 status); 14615 wmi_buf_free(buf); 14616 } 14617 14618 return status; 14619 } 14620 14621 /** 14622 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 14623 * @wmi_handle: wmi handle 14624 * @lphb_conf_req: lphb config request 14625 * 14626 * Return: CDF status 14627 */ 14628 static 14629 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14630 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 14631 { 14632 QDF_STATUS status; 14633 wmi_buf_t buf = NULL; 14634 uint8_t *buf_ptr; 14635 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 14636 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 14637 14638 buf = wmi_buf_alloc(wmi_handle, len); 14639 if (!buf) { 14640 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14641 return QDF_STATUS_E_NOMEM; 14642 } 14643 14644 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14645 hb_tcp_filter_fp = 14646 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 14647 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 14648 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 14649 WMITLV_GET_STRUCT_TLVLEN 14650 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 14651 14652 /* fill in values */ 14653 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 14654 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 14655 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 14656 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 14657 memcpy((void *)&hb_tcp_filter_fp->filter, 14658 (void *)&g_hb_tcp_filter_fp->filter, 14659 WMI_WLAN_HB_MAX_FILTER_SIZE); 14660 14661 status = wmi_unified_cmd_send(wmi_handle, buf, 14662 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 14663 if (QDF_IS_STATUS_ERROR(status)) { 14664 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 14665 status); 14666 wmi_buf_free(buf); 14667 } 14668 14669 return status; 14670 } 14671 14672 /** 14673 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 14674 * @wmi_handle: wmi handle 14675 * @lphb_conf_req: lphb config request 14676 * 14677 * Return: CDF status 14678 */ 14679 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 14680 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 14681 { 14682 QDF_STATUS status; 14683 wmi_buf_t buf = NULL; 14684 uint8_t *buf_ptr; 14685 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 14686 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 14687 14688 buf = wmi_buf_alloc(wmi_handle, len); 14689 if (!buf) { 14690 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14691 return QDF_STATUS_E_NOMEM; 14692 } 14693 14694 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14695 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 14696 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 14697 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 14698 WMITLV_GET_STRUCT_TLVLEN 14699 (wmi_hb_set_udp_params_cmd_fixed_param)); 14700 14701 /* fill in values */ 14702 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14703 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14704 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14705 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 14706 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 14707 hb_udp_params_fp->interval = lphb_conf_req->interval; 14708 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 14709 hb_udp_params_fp->session = lphb_conf_req->session; 14710 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 14711 &lphb_conf_req->gateway_mac, 14712 sizeof(lphb_conf_req->gateway_mac)); 14713 14714 status = wmi_unified_cmd_send(wmi_handle, buf, 14715 len, WMI_HB_SET_UDP_PARAMS_CMDID); 14716 if (QDF_IS_STATUS_ERROR(status)) { 14717 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 14718 status); 14719 wmi_buf_free(buf); 14720 } 14721 14722 return status; 14723 } 14724 14725 /** 14726 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 14727 * @wmi_handle: wmi handle 14728 * @lphb_conf_req: lphb config request 14729 * 14730 * Return: CDF status 14731 */ 14732 static 14733 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14734 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 14735 { 14736 QDF_STATUS status; 14737 wmi_buf_t buf = NULL; 14738 uint8_t *buf_ptr; 14739 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 14740 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 14741 14742 buf = wmi_buf_alloc(wmi_handle, len); 14743 if (!buf) { 14744 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14745 return QDF_STATUS_E_NOMEM; 14746 } 14747 14748 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14749 hb_udp_filter_fp = 14750 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 14751 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 14752 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 14753 WMITLV_GET_STRUCT_TLVLEN 14754 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 14755 14756 /* fill in values */ 14757 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 14758 hb_udp_filter_fp->length = lphb_conf_req->length; 14759 hb_udp_filter_fp->offset = lphb_conf_req->offset; 14760 hb_udp_filter_fp->session = lphb_conf_req->session; 14761 memcpy((void *)&hb_udp_filter_fp->filter, 14762 (void *)&lphb_conf_req->filter, 14763 WMI_WLAN_HB_MAX_FILTER_SIZE); 14764 14765 status = wmi_unified_cmd_send(wmi_handle, buf, 14766 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 14767 if (QDF_IS_STATUS_ERROR(status)) { 14768 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 14769 status); 14770 wmi_buf_free(buf); 14771 } 14772 14773 return status; 14774 } 14775 #endif /* FEATURE_WLAN_LPHB */ 14776 14777 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 14778 struct pmo_hw_filter_params *req) 14779 { 14780 QDF_STATUS status; 14781 wmi_hw_data_filter_cmd_fixed_param *cmd; 14782 wmi_buf_t wmi_buf; 14783 14784 if (!req) { 14785 WMI_LOGE("req is null"); 14786 return QDF_STATUS_E_INVAL; 14787 } 14788 14789 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 14790 if (!wmi_buf) { 14791 WMI_LOGE(FL("Out of memory")); 14792 return QDF_STATUS_E_NOMEM; 14793 } 14794 14795 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 14796 WMITLV_SET_HDR(&cmd->tlv_header, 14797 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 14798 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 14799 cmd->vdev_id = req->vdev_id; 14800 cmd->enable = req->enable; 14801 /* Set all modes in case of disable */ 14802 if (!cmd->enable) 14803 cmd->hw_filter_bitmap = ((uint32_t)~0U); 14804 else 14805 cmd->hw_filter_bitmap = req->mode_bitmap; 14806 14807 WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d", 14808 req->enable ? "enable" : "disable", req->mode_bitmap, 14809 req->vdev_id); 14810 14811 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 14812 WMI_HW_DATA_FILTER_CMDID); 14813 if (QDF_IS_STATUS_ERROR(status)) { 14814 WMI_LOGE("Failed to configure hw filter"); 14815 wmi_buf_free(wmi_buf); 14816 } 14817 14818 return status; 14819 } 14820 14821 /** 14822 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 14823 * @wmi_handle: wmi handle 14824 * @vdev_id: vdev id 14825 * @enable: Flag to enable/disable packet filter 14826 * 14827 * Return: QDF_STATUS_SUCCESS for success or error code 14828 */ 14829 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 14830 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 14831 { 14832 int32_t len; 14833 int ret = 0; 14834 wmi_buf_t buf; 14835 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 14836 14837 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 14838 14839 buf = wmi_buf_alloc(wmi_handle, len); 14840 if (!buf) { 14841 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14842 return QDF_STATUS_E_NOMEM; 14843 } 14844 14845 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 14846 WMITLV_SET_HDR(&cmd->tlv_header, 14847 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 14848 WMITLV_GET_STRUCT_TLVLEN( 14849 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 14850 14851 cmd->vdev_id = vdev_id; 14852 if (enable) 14853 cmd->enable = PACKET_FILTER_SET_ENABLE; 14854 else 14855 cmd->enable = PACKET_FILTER_SET_DISABLE; 14856 14857 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 14858 __func__, cmd->enable, vdev_id); 14859 14860 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14861 WMI_PACKET_FILTER_ENABLE_CMDID); 14862 if (ret) { 14863 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 14864 wmi_buf_free(buf); 14865 } 14866 14867 return ret; 14868 } 14869 14870 /** 14871 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 14872 * @wmi_handle: wmi handle 14873 * @vdev_id: vdev id 14874 * @rcv_filter_param: Packet filter parameters 14875 * @filter_id: Filter id 14876 * @enable: Flag to add/delete packet filter configuration 14877 * 14878 * Return: QDF_STATUS_SUCCESS for success or error code 14879 */ 14880 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 14881 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 14882 uint8_t filter_id, bool enable) 14883 { 14884 int len, i; 14885 int err = 0; 14886 wmi_buf_t buf; 14887 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 14888 14889 14890 /* allocate the memory */ 14891 len = sizeof(*cmd); 14892 buf = wmi_buf_alloc(wmi_handle, len); 14893 if (!buf) { 14894 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14895 return QDF_STATUS_E_NOMEM; 14896 } 14897 14898 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 14899 WMITLV_SET_HDR(&cmd->tlv_header, 14900 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 14901 WMITLV_GET_STRUCT_TLVLEN 14902 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 14903 14904 cmd->vdev_id = vdev_id; 14905 cmd->filter_id = filter_id; 14906 if (enable) 14907 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 14908 else 14909 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 14910 14911 if (enable) { 14912 cmd->num_params = QDF_MIN( 14913 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 14914 rcv_filter_param->num_params); 14915 cmd->filter_type = rcv_filter_param->filter_type; 14916 cmd->coalesce_time = rcv_filter_param->coalesce_time; 14917 14918 for (i = 0; i < cmd->num_params; i++) { 14919 cmd->paramsData[i].proto_type = 14920 rcv_filter_param->params_data[i].protocol_layer; 14921 cmd->paramsData[i].cmp_type = 14922 rcv_filter_param->params_data[i].compare_flag; 14923 cmd->paramsData[i].data_length = 14924 rcv_filter_param->params_data[i].data_length; 14925 cmd->paramsData[i].data_offset = 14926 rcv_filter_param->params_data[i].data_offset; 14927 memcpy(&cmd->paramsData[i].compareData, 14928 rcv_filter_param->params_data[i].compare_data, 14929 sizeof(cmd->paramsData[i].compareData)); 14930 memcpy(&cmd->paramsData[i].dataMask, 14931 rcv_filter_param->params_data[i].data_mask, 14932 sizeof(cmd->paramsData[i].dataMask)); 14933 } 14934 } 14935 14936 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 14937 cmd->filter_action, cmd->filter_id, cmd->num_params); 14938 /* send the command along with data */ 14939 err = wmi_unified_cmd_send(wmi_handle, buf, len, 14940 WMI_PACKET_FILTER_CONFIG_CMDID); 14941 if (err) { 14942 WMI_LOGE("Failed to send pkt_filter cmd"); 14943 wmi_buf_free(buf); 14944 return QDF_STATUS_E_FAILURE; 14945 } 14946 14947 return QDF_STATUS_SUCCESS; 14948 } 14949 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 14950 14951 /** 14952 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 14953 * @wmi_handle: wmi handle 14954 * @request: SSID hotlist set request 14955 * 14956 * Return: QDF_STATUS enumeration 14957 */ 14958 static QDF_STATUS 14959 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 14960 struct ssid_hotlist_request_params *request) 14961 { 14962 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 14963 wmi_buf_t wmi_buf; 14964 uint32_t len; 14965 uint32_t array_size; 14966 uint8_t *buf_ptr; 14967 14968 /* length of fixed portion */ 14969 len = sizeof(*cmd); 14970 14971 /* length of variable portion */ 14972 array_size = 14973 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 14974 len += WMI_TLV_HDR_SIZE + array_size; 14975 14976 wmi_buf = wmi_buf_alloc(wmi_handle, len); 14977 if (!wmi_buf) { 14978 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14979 return QDF_STATUS_E_NOMEM; 14980 } 14981 14982 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 14983 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 14984 buf_ptr; 14985 WMITLV_SET_HDR 14986 (&cmd->tlv_header, 14987 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 14988 WMITLV_GET_STRUCT_TLVLEN 14989 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 14990 14991 cmd->request_id = request->request_id; 14992 cmd->requestor_id = 0; 14993 cmd->vdev_id = request->session_id; 14994 cmd->table_id = 0; 14995 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 14996 cmd->total_entries = request->ssid_count; 14997 cmd->num_entries_in_page = request->ssid_count; 14998 cmd->first_entry_index = 0; 14999 15000 buf_ptr += sizeof(*cmd); 15001 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15002 15003 if (request->ssid_count) { 15004 wmi_extscan_hotlist_ssid_entry *entry; 15005 int i; 15006 15007 buf_ptr += WMI_TLV_HDR_SIZE; 15008 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15009 for (i = 0; i < request->ssid_count; i++) { 15010 WMITLV_SET_HDR 15011 (entry, 15012 WMITLV_TAG_ARRAY_STRUC, 15013 WMITLV_GET_STRUCT_TLVLEN 15014 (wmi_extscan_hotlist_ssid_entry)); 15015 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15016 qdf_mem_copy(entry->ssid.ssid, 15017 request->ssids[i].ssid.mac_ssid, 15018 request->ssids[i].ssid.length); 15019 entry->band = request->ssids[i].band; 15020 entry->min_rssi = request->ssids[i].rssi_low; 15021 entry->max_rssi = request->ssids[i].rssi_high; 15022 entry++; 15023 } 15024 cmd->mode = WMI_EXTSCAN_MODE_START; 15025 } else { 15026 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15027 } 15028 15029 if (wmi_unified_cmd_send 15030 (wmi_handle, wmi_buf, len, 15031 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15032 WMI_LOGE("%s: failed to send command", __func__); 15033 wmi_buf_free(wmi_buf); 15034 return QDF_STATUS_E_FAILURE; 15035 } 15036 15037 return QDF_STATUS_SUCCESS; 15038 } 15039 15040 /** 15041 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 15042 * @wmi_handle: wmi handle 15043 * @vdev_id: vdev id 15044 * 15045 * This function sends roam synch complete event to fw. 15046 * 15047 * Return: CDF STATUS 15048 */ 15049 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 15050 uint8_t vdev_id) 15051 { 15052 wmi_roam_synch_complete_fixed_param *cmd; 15053 wmi_buf_t wmi_buf; 15054 uint8_t *buf_ptr; 15055 uint16_t len; 15056 len = sizeof(wmi_roam_synch_complete_fixed_param); 15057 15058 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15059 if (!wmi_buf) { 15060 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15061 return QDF_STATUS_E_NOMEM; 15062 } 15063 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 15064 buf_ptr = (uint8_t *) cmd; 15065 WMITLV_SET_HDR(&cmd->tlv_header, 15066 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 15067 WMITLV_GET_STRUCT_TLVLEN 15068 (wmi_roam_synch_complete_fixed_param)); 15069 cmd->vdev_id = vdev_id; 15070 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15071 WMI_ROAM_SYNCH_COMPLETE)) { 15072 WMI_LOGP("%s: failed to send roam synch confirmation", 15073 __func__); 15074 wmi_buf_free(wmi_buf); 15075 return QDF_STATUS_E_FAILURE; 15076 } 15077 15078 return QDF_STATUS_SUCCESS; 15079 } 15080 15081 /** 15082 * send_fw_test_cmd_tlv() - send fw test command to fw. 15083 * @wmi_handle: wmi handle 15084 * @wmi_fwtest: fw test command 15085 * 15086 * This function sends fw test command to fw. 15087 * 15088 * Return: CDF STATUS 15089 */ 15090 static 15091 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15092 struct set_fwtest_params *wmi_fwtest) 15093 { 15094 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15095 wmi_buf_t wmi_buf; 15096 uint16_t len; 15097 15098 len = sizeof(*cmd); 15099 15100 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15101 if (!wmi_buf) { 15102 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15103 return QDF_STATUS_E_NOMEM; 15104 } 15105 15106 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15107 WMITLV_SET_HDR(&cmd->tlv_header, 15108 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15109 WMITLV_GET_STRUCT_TLVLEN( 15110 wmi_fwtest_set_param_cmd_fixed_param)); 15111 cmd->param_id = wmi_fwtest->arg; 15112 cmd->param_value = wmi_fwtest->value; 15113 15114 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15115 WMI_FWTEST_CMDID)) { 15116 WMI_LOGP("%s: failed to send fw test command", __func__); 15117 qdf_nbuf_free(wmi_buf); 15118 return QDF_STATUS_E_FAILURE; 15119 } 15120 15121 return QDF_STATUS_SUCCESS; 15122 } 15123 15124 /** 15125 * send_unit_test_cmd_tlv() - send unit test command to fw. 15126 * @wmi_handle: wmi handle 15127 * @wmi_utest: unit test command 15128 * 15129 * This function send unit test command to fw. 15130 * 15131 * Return: CDF STATUS 15132 */ 15133 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15134 struct wmi_unit_test_cmd *wmi_utest) 15135 { 15136 wmi_unit_test_cmd_fixed_param *cmd; 15137 wmi_buf_t wmi_buf; 15138 uint8_t *buf_ptr; 15139 int i; 15140 uint16_t len, args_tlv_len; 15141 uint32_t *unit_test_cmd_args; 15142 15143 args_tlv_len = 15144 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15145 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15146 15147 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15148 if (!wmi_buf) { 15149 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15150 return QDF_STATUS_E_NOMEM; 15151 } 15152 15153 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15154 buf_ptr = (uint8_t *) cmd; 15155 WMITLV_SET_HDR(&cmd->tlv_header, 15156 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15157 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15158 cmd->vdev_id = wmi_utest->vdev_id; 15159 cmd->module_id = wmi_utest->module_id; 15160 cmd->num_args = wmi_utest->num_args; 15161 cmd->diag_token = wmi_utest->diag_token; 15162 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15163 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15164 (wmi_utest->num_args * sizeof(uint32_t))); 15165 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15166 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15167 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15168 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15169 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15170 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15171 unit_test_cmd_args[i] = wmi_utest->args[i]; 15172 WMI_LOGI("%d,", wmi_utest->args[i]); 15173 } 15174 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15175 WMI_UNIT_TEST_CMDID)) { 15176 WMI_LOGP("%s: failed to send unit test command", __func__); 15177 wmi_buf_free(wmi_buf); 15178 return QDF_STATUS_E_FAILURE; 15179 } 15180 15181 return QDF_STATUS_SUCCESS; 15182 } 15183 15184 /** 15185 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15186 * @wmi_handle: wma handle 15187 * @roaminvoke: roam invoke command 15188 * 15189 * Send roam invoke command to fw for fastreassoc. 15190 * 15191 * Return: CDF STATUS 15192 */ 15193 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15194 struct wmi_roam_invoke_cmd *roaminvoke, 15195 uint32_t ch_hz) 15196 { 15197 wmi_roam_invoke_cmd_fixed_param *cmd; 15198 wmi_buf_t wmi_buf; 15199 u_int8_t *buf_ptr; 15200 u_int16_t len, args_tlv_len; 15201 uint32_t *channel_list; 15202 wmi_mac_addr *bssid_list; 15203 wmi_tlv_buf_len_param *buf_len_tlv; 15204 15205 /* Host sends only one channel and one bssid */ 15206 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15207 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15208 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15209 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15210 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15211 if (!wmi_buf) { 15212 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15213 return QDF_STATUS_E_NOMEM; 15214 } 15215 15216 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15217 buf_ptr = (u_int8_t *) cmd; 15218 WMITLV_SET_HDR(&cmd->tlv_header, 15219 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15220 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15221 cmd->vdev_id = roaminvoke->vdev_id; 15222 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15223 if (roaminvoke->is_same_bssid) 15224 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15225 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15226 15227 if (roaminvoke->frame_len) { 15228 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15229 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15230 cmd->num_buf = 1; 15231 } else { 15232 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15233 cmd->num_buf = 0; 15234 } 15235 15236 cmd->roam_ap_sel_mode = 0; 15237 cmd->roam_delay = 0; 15238 cmd->num_chan = 1; 15239 cmd->num_bssid = 1; 15240 15241 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15242 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15243 (sizeof(u_int32_t))); 15244 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15245 *channel_list = ch_hz; 15246 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15247 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15248 (sizeof(wmi_mac_addr))); 15249 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15250 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15251 15252 /* move to next tlv i.e. bcn_prb_buf_list */ 15253 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15254 15255 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15256 sizeof(wmi_tlv_buf_len_param)); 15257 15258 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15259 buf_len_tlv->buf_len = roaminvoke->frame_len; 15260 15261 /* move to next tlv i.e. bcn_prb_frm */ 15262 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15263 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15264 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15265 15266 /* copy frame after the header */ 15267 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15268 roaminvoke->frame_buf, 15269 roaminvoke->frame_len); 15270 15271 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15272 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 15273 buf_ptr + WMI_TLV_HDR_SIZE, 15274 roaminvoke->frame_len); 15275 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15276 cmd->flags, cmd->roam_scan_mode, 15277 cmd->roam_ap_sel_mode, cmd->roam_delay, 15278 cmd->num_chan, cmd->num_bssid); 15279 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15280 15281 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15282 WMI_ROAM_INVOKE_CMDID)) { 15283 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15284 wmi_buf_free(wmi_buf); 15285 return QDF_STATUS_E_FAILURE; 15286 } 15287 15288 return QDF_STATUS_SUCCESS; 15289 } 15290 15291 /** 15292 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15293 * @wmi_handle: wmi handle 15294 * @command: command 15295 * @vdev_id: vdev id 15296 * 15297 * This function set roam offload command to fw. 15298 * 15299 * Return: CDF status 15300 */ 15301 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15302 uint32_t command, uint32_t vdev_id) 15303 { 15304 QDF_STATUS status; 15305 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15306 wmi_buf_t buf = NULL; 15307 int len; 15308 uint8_t *buf_ptr; 15309 15310 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15311 buf = wmi_buf_alloc(wmi_handle, len); 15312 if (!buf) { 15313 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15314 return QDF_STATUS_E_NOMEM; 15315 } 15316 15317 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15318 15319 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15320 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15321 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15322 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15323 cmd_fp->vdev_id = vdev_id; 15324 cmd_fp->command_arg = command; 15325 15326 status = wmi_unified_cmd_send(wmi_handle, buf, 15327 len, WMI_ROAM_SCAN_CMD); 15328 if (QDF_IS_STATUS_ERROR(status)) { 15329 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15330 status); 15331 goto error; 15332 } 15333 15334 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15335 return QDF_STATUS_SUCCESS; 15336 15337 error: 15338 wmi_buf_free(buf); 15339 15340 return status; 15341 } 15342 15343 /** 15344 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15345 * @wmi_handle: wmi handle 15346 * @ap_profile_p: ap profile 15347 * @vdev_id: vdev id 15348 * 15349 * Send WMI_ROAM_AP_PROFILE to firmware 15350 * 15351 * Return: CDF status 15352 */ 15353 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15354 struct ap_profile_params *ap_profile) 15355 { 15356 wmi_buf_t buf = NULL; 15357 QDF_STATUS status; 15358 int len; 15359 uint8_t *buf_ptr; 15360 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 15361 wmi_roam_cnd_scoring_param *score_param; 15362 wmi_ap_profile *profile; 15363 15364 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 15365 len += sizeof(*score_param); 15366 buf = wmi_buf_alloc(wmi_handle, len); 15367 if (!buf) { 15368 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15369 return QDF_STATUS_E_NOMEM; 15370 } 15371 15372 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15373 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 15374 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 15375 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 15376 WMITLV_GET_STRUCT_TLVLEN 15377 (wmi_roam_ap_profile_fixed_param)); 15378 /* fill in threshold values */ 15379 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 15380 roam_ap_profile_fp->id = 0; 15381 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 15382 15383 profile = (wmi_ap_profile *)buf_ptr; 15384 WMITLV_SET_HDR(&profile->tlv_header, 15385 WMITLV_TAG_STRUC_wmi_ap_profile, 15386 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 15387 profile->flags = ap_profile->profile.flags; 15388 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 15389 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 15390 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 15391 profile->ssid.ssid_len); 15392 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 15393 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 15394 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 15395 profile->rsn_mcastmgmtcipherset = 15396 ap_profile->profile.rsn_mcastmgmtcipherset; 15397 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 15398 15399 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", 15400 profile->flags, profile->rssi_threshold, 15401 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 15402 profile->rsn_authmode, profile->rsn_ucastcipherset, 15403 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 15404 profile->rssi_abs_thresh); 15405 15406 buf_ptr += sizeof(wmi_ap_profile); 15407 15408 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 15409 WMITLV_SET_HDR(&score_param->tlv_header, 15410 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 15411 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 15412 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 15413 score_param->rssi_weightage_pcnt = 15414 ap_profile->param.rssi_weightage; 15415 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 15416 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 15417 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 15418 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 15419 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 15420 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 15421 score_param->esp_qbss_weightage_pcnt = 15422 ap_profile->param.esp_qbss_weightage; 15423 score_param->beamforming_weightage_pcnt = 15424 ap_profile->param.beamforming_weightage; 15425 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 15426 score_param->oce_wan_weightage_pcnt = 15427 ap_profile->param.oce_wan_weightage; 15428 15429 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", 15430 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 15431 score_param->ht_weightage_pcnt, 15432 score_param->vht_weightage_pcnt, 15433 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 15434 score_param->band_weightage_pcnt, 15435 score_param->nss_weightage_pcnt, 15436 score_param->esp_qbss_weightage_pcnt, 15437 score_param->beamforming_weightage_pcnt, 15438 score_param->pcl_weightage_pcnt, 15439 score_param->oce_wan_weightage_pcnt); 15440 15441 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 15442 score_param->band_scoring.score_pcnt = 15443 ap_profile->param.band_index_score; 15444 score_param->nss_scoring.score_pcnt = 15445 ap_profile->param.nss_index_score; 15446 15447 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 15448 score_param->bw_scoring.score_pcnt, 15449 score_param->band_scoring.score_pcnt, 15450 score_param->nss_scoring.score_pcnt); 15451 15452 score_param->rssi_scoring.best_rssi_threshold = 15453 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 15454 score_param->rssi_scoring.good_rssi_threshold = 15455 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 15456 score_param->rssi_scoring.bad_rssi_threshold = 15457 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 15458 score_param->rssi_scoring.good_rssi_pcnt = 15459 ap_profile->param.rssi_scoring.good_rssi_pcnt; 15460 score_param->rssi_scoring.bad_rssi_pcnt = 15461 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 15462 score_param->rssi_scoring.good_bucket_size = 15463 ap_profile->param.rssi_scoring.good_bucket_size; 15464 score_param->rssi_scoring.bad_bucket_size = 15465 ap_profile->param.rssi_scoring.bad_bucket_size; 15466 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 15467 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 15468 15469 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 15470 score_param->rssi_scoring.best_rssi_threshold, 15471 score_param->rssi_scoring.good_rssi_threshold, 15472 score_param->rssi_scoring.bad_rssi_threshold, 15473 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 15474 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 15475 score_param->rssi_scoring.good_rssi_pcnt, 15476 score_param->rssi_scoring.bad_rssi_pcnt, 15477 score_param->rssi_scoring.good_bucket_size, 15478 score_param->rssi_scoring.bad_bucket_size); 15479 15480 score_param->esp_qbss_scoring.num_slot = 15481 ap_profile->param.esp_qbss_scoring.num_slot; 15482 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 15483 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 15484 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 15485 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 15486 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 15487 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 15488 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 15489 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 15490 15491 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15492 score_param->esp_qbss_scoring.num_slot, 15493 score_param->esp_qbss_scoring.score_pcnt3_to_0, 15494 score_param->esp_qbss_scoring.score_pcnt7_to_4, 15495 score_param->esp_qbss_scoring.score_pcnt11_to_8, 15496 score_param->esp_qbss_scoring.score_pcnt15_to_12); 15497 15498 score_param->oce_wan_scoring.num_slot = 15499 ap_profile->param.oce_wan_scoring.num_slot; 15500 score_param->oce_wan_scoring.score_pcnt3_to_0 = 15501 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 15502 score_param->oce_wan_scoring.score_pcnt7_to_4 = 15503 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 15504 score_param->oce_wan_scoring.score_pcnt11_to_8 = 15505 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 15506 score_param->oce_wan_scoring.score_pcnt15_to_12 = 15507 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 15508 15509 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15510 score_param->oce_wan_scoring.num_slot, 15511 score_param->oce_wan_scoring.score_pcnt3_to_0, 15512 score_param->oce_wan_scoring.score_pcnt7_to_4, 15513 score_param->oce_wan_scoring.score_pcnt11_to_8, 15514 score_param->oce_wan_scoring.score_pcnt15_to_12); 15515 15516 status = wmi_unified_cmd_send(wmi_handle, buf, 15517 len, WMI_ROAM_AP_PROFILE); 15518 if (QDF_IS_STATUS_ERROR(status)) { 15519 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 15520 status); 15521 wmi_buf_free(buf); 15522 } 15523 15524 WMI_LOGI("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 15525 15526 return status; 15527 } 15528 15529 /** 15530 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 15531 * @wmi_handle: wmi handle 15532 * @scan_period: scan period 15533 * @scan_age: scan age 15534 * @vdev_id: vdev id 15535 * 15536 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 15537 * 15538 * Return: CDF status 15539 */ 15540 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 15541 uint32_t scan_period, 15542 uint32_t scan_age, 15543 uint32_t vdev_id) 15544 { 15545 QDF_STATUS status; 15546 wmi_buf_t buf = NULL; 15547 int len; 15548 uint8_t *buf_ptr; 15549 wmi_roam_scan_period_fixed_param *scan_period_fp; 15550 15551 /* Send scan period values */ 15552 len = sizeof(wmi_roam_scan_period_fixed_param); 15553 buf = wmi_buf_alloc(wmi_handle, len); 15554 if (!buf) { 15555 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15556 return QDF_STATUS_E_NOMEM; 15557 } 15558 15559 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15560 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 15561 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 15562 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 15563 WMITLV_GET_STRUCT_TLVLEN 15564 (wmi_roam_scan_period_fixed_param)); 15565 /* fill in scan period values */ 15566 scan_period_fp->vdev_id = vdev_id; 15567 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 15568 scan_period_fp->roam_scan_age = scan_age; 15569 15570 status = wmi_unified_cmd_send(wmi_handle, buf, 15571 len, WMI_ROAM_SCAN_PERIOD); 15572 if (QDF_IS_STATUS_ERROR(status)) { 15573 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 15574 status); 15575 goto error; 15576 } 15577 15578 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 15579 __func__, scan_period, scan_age); 15580 return QDF_STATUS_SUCCESS; 15581 error: 15582 wmi_buf_free(buf); 15583 15584 return status; 15585 } 15586 15587 /** 15588 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 15589 * @wmi_handle: wmi handle 15590 * @chan_count: channel count 15591 * @chan_list: channel list 15592 * @list_type: list type 15593 * @vdev_id: vdev id 15594 * 15595 * Set roam offload channel list. 15596 * 15597 * Return: CDF status 15598 */ 15599 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 15600 uint8_t chan_count, 15601 uint32_t *chan_list, 15602 uint8_t list_type, uint32_t vdev_id) 15603 { 15604 wmi_buf_t buf = NULL; 15605 QDF_STATUS status; 15606 int len, list_tlv_len; 15607 int i; 15608 uint8_t *buf_ptr; 15609 wmi_roam_chan_list_fixed_param *chan_list_fp; 15610 uint32_t *roam_chan_list_array; 15611 15612 if (chan_count == 0) { 15613 WMI_LOGD("%s : invalid number of channels %d", __func__, 15614 chan_count); 15615 return QDF_STATUS_E_EMPTY; 15616 } 15617 /* Channel list is a table of 2 TLV's */ 15618 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 15619 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 15620 buf = wmi_buf_alloc(wmi_handle, len); 15621 if (!buf) { 15622 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15623 return QDF_STATUS_E_NOMEM; 15624 } 15625 15626 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15627 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 15628 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 15629 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 15630 WMITLV_GET_STRUCT_TLVLEN 15631 (wmi_roam_chan_list_fixed_param)); 15632 chan_list_fp->vdev_id = vdev_id; 15633 chan_list_fp->num_chan = chan_count; 15634 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 15635 /* external app is controlling channel list */ 15636 chan_list_fp->chan_list_type = 15637 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 15638 } else { 15639 /* umac supplied occupied channel list in LFR */ 15640 chan_list_fp->chan_list_type = 15641 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 15642 } 15643 15644 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 15645 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15646 (chan_list_fp->num_chan * sizeof(uint32_t))); 15647 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15648 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 15649 for (i = 0; ((i < chan_list_fp->num_chan) && 15650 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 15651 roam_chan_list_array[i] = chan_list[i]; 15652 WMI_LOGD("%d,", roam_chan_list_array[i]); 15653 } 15654 15655 status = wmi_unified_cmd_send(wmi_handle, buf, 15656 len, WMI_ROAM_CHAN_LIST); 15657 if (QDF_IS_STATUS_ERROR(status)) { 15658 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 15659 status); 15660 goto error; 15661 } 15662 15663 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 15664 return QDF_STATUS_SUCCESS; 15665 error: 15666 wmi_buf_free(buf); 15667 15668 return status; 15669 } 15670 15671 /** 15672 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 15673 * @wmi_handle: wmi handle 15674 * @req_buf: per roam config buffer 15675 * 15676 * Return: QDF status 15677 */ 15678 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 15679 struct wmi_per_roam_config_req *req_buf) 15680 { 15681 wmi_buf_t buf = NULL; 15682 QDF_STATUS status; 15683 int len; 15684 uint8_t *buf_ptr; 15685 wmi_roam_per_config_fixed_param *wmi_per_config; 15686 15687 len = sizeof(wmi_roam_per_config_fixed_param); 15688 buf = wmi_buf_alloc(wmi_handle, len); 15689 if (!buf) { 15690 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15691 return QDF_STATUS_E_NOMEM; 15692 } 15693 15694 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15695 wmi_per_config = 15696 (wmi_roam_per_config_fixed_param *) buf_ptr; 15697 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 15698 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 15699 WMITLV_GET_STRUCT_TLVLEN 15700 (wmi_roam_per_config_fixed_param)); 15701 15702 /* fill in per roam config values */ 15703 wmi_per_config->vdev_id = req_buf->vdev_id; 15704 15705 wmi_per_config->enable = req_buf->per_config.enable; 15706 wmi_per_config->high_rate_thresh = 15707 (req_buf->per_config.tx_high_rate_thresh << 16) | 15708 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 15709 wmi_per_config->low_rate_thresh = 15710 (req_buf->per_config.tx_low_rate_thresh << 16) | 15711 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 15712 wmi_per_config->pkt_err_rate_thresh_pct = 15713 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 15714 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 15715 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 15716 wmi_per_config->pkt_err_rate_mon_time = 15717 (req_buf->per_config.tx_per_mon_time << 16) | 15718 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 15719 wmi_per_config->min_candidate_rssi = 15720 req_buf->per_config.min_candidate_rssi; 15721 15722 /* Send per roam config parameters */ 15723 status = wmi_unified_cmd_send(wmi_handle, buf, 15724 len, WMI_ROAM_PER_CONFIG_CMDID); 15725 if (QDF_IS_STATUS_ERROR(status)) { 15726 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 15727 status); 15728 wmi_buf_free(buf); 15729 return status; 15730 } 15731 15732 WMI_LOGI(FL("per roam enable=%d, vdev=%d"), 15733 req_buf->per_config.enable, req_buf->vdev_id); 15734 return QDF_STATUS_SUCCESS; 15735 } 15736 15737 /** 15738 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 15739 * @wmi_handle: wmi handle 15740 * @rssi_change_thresh: RSSI Change threshold 15741 * @bcn_rssi_weight: beacon RSSI weight 15742 * @vdev_id: vdev id 15743 * 15744 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 15745 * 15746 * Return: CDF status 15747 */ 15748 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 15749 uint32_t vdev_id, 15750 int32_t rssi_change_thresh, 15751 uint32_t bcn_rssi_weight, 15752 uint32_t hirssi_delay_btw_scans) 15753 { 15754 wmi_buf_t buf = NULL; 15755 QDF_STATUS status; 15756 int len; 15757 uint8_t *buf_ptr; 15758 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 15759 15760 /* Send rssi change parameters */ 15761 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 15762 buf = wmi_buf_alloc(wmi_handle, len); 15763 if (!buf) { 15764 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15765 return QDF_STATUS_E_NOMEM; 15766 } 15767 15768 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15769 rssi_change_fp = 15770 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 15771 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 15772 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 15773 WMITLV_GET_STRUCT_TLVLEN 15774 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 15775 /* fill in rssi change threshold (hysteresis) values */ 15776 rssi_change_fp->vdev_id = vdev_id; 15777 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 15778 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 15779 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 15780 15781 status = wmi_unified_cmd_send(wmi_handle, buf, 15782 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 15783 if (QDF_IS_STATUS_ERROR(status)) { 15784 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 15785 status); 15786 goto error; 15787 } 15788 15789 WMI_LOGI(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 15790 rssi_change_thresh, bcn_rssi_weight); 15791 WMI_LOGI(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 15792 return QDF_STATUS_SUCCESS; 15793 error: 15794 wmi_buf_free(buf); 15795 15796 return status; 15797 } 15798 15799 /** 15800 * send_power_dbg_cmd_tlv() - send power debug commands 15801 * @wmi_handle: wmi handle 15802 * @param: wmi power debug parameter 15803 * 15804 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 15805 * 15806 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15807 */ 15808 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 15809 struct wmi_power_dbg_params *param) 15810 { 15811 wmi_buf_t buf = NULL; 15812 QDF_STATUS status; 15813 int len, args_tlv_len; 15814 uint8_t *buf_ptr; 15815 uint8_t i; 15816 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 15817 uint32_t *cmd_args; 15818 15819 /* Prepare and send power debug cmd parameters */ 15820 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 15821 len = sizeof(*cmd) + args_tlv_len; 15822 buf = wmi_buf_alloc(wmi_handle, len); 15823 if (!buf) { 15824 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15825 return QDF_STATUS_E_NOMEM; 15826 } 15827 15828 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15829 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 15830 WMITLV_SET_HDR(&cmd->tlv_header, 15831 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 15832 WMITLV_GET_STRUCT_TLVLEN 15833 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 15834 15835 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15836 param->pdev_id); 15837 cmd->module_id = param->module_id; 15838 cmd->num_args = param->num_args; 15839 buf_ptr += sizeof(*cmd); 15840 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15841 (param->num_args * sizeof(uint32_t))); 15842 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15843 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 15844 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 15845 cmd_args[i] = param->args[i]; 15846 WMI_LOGI("%d,", param->args[i]); 15847 } 15848 15849 status = wmi_unified_cmd_send(wmi_handle, buf, 15850 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 15851 if (QDF_IS_STATUS_ERROR(status)) { 15852 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 15853 status); 15854 goto error; 15855 } 15856 15857 return QDF_STATUS_SUCCESS; 15858 error: 15859 wmi_buf_free(buf); 15860 15861 return status; 15862 } 15863 15864 /** 15865 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 15866 * @wmi_handle: wmi handle 15867 * @param: wmi multiple vdev restart req param 15868 * 15869 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 15870 * 15871 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15872 */ 15873 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 15874 wmi_unified_t wmi_handle, 15875 struct multiple_vdev_restart_params *param) 15876 { 15877 wmi_buf_t buf; 15878 QDF_STATUS qdf_status; 15879 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 15880 int i; 15881 uint8_t *buf_ptr; 15882 uint32_t *vdev_ids; 15883 wmi_channel *chan_info; 15884 struct channel_param *tchan_info; 15885 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 15886 15887 len += sizeof(wmi_channel); 15888 if (param->num_vdevs) 15889 len += sizeof(uint32_t) * param->num_vdevs; 15890 15891 buf = wmi_buf_alloc(wmi_handle, len); 15892 if (!buf) { 15893 WMI_LOGE("Failed to allocate memory\n"); 15894 qdf_status = QDF_STATUS_E_NOMEM; 15895 goto end; 15896 } 15897 15898 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15899 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 15900 buf_ptr; 15901 15902 WMITLV_SET_HDR(&cmd->tlv_header, 15903 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 15904 WMITLV_GET_STRUCT_TLVLEN 15905 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 15906 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15907 param->pdev_id); 15908 cmd->requestor_id = param->requestor_id; 15909 cmd->disable_hw_ack = param->disable_hw_ack; 15910 cmd->cac_duration_ms = param->cac_duration_ms; 15911 cmd->num_vdevs = param->num_vdevs; 15912 15913 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 15914 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 15915 " cmd->num_vdevs: %d ", 15916 __func__, cmd->pdev_id, cmd->requestor_id, 15917 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 15918 buf_ptr += sizeof(*cmd); 15919 15920 WMITLV_SET_HDR(buf_ptr, 15921 WMITLV_TAG_ARRAY_UINT32, 15922 sizeof(uint32_t) * param->num_vdevs); 15923 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15924 for (i = 0; i < param->num_vdevs; i++) { 15925 vdev_ids[i] = param->vdev_ids[i]; 15926 } 15927 15928 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 15929 15930 WMITLV_SET_HDR(buf_ptr, 15931 WMITLV_TAG_STRUC_wmi_channel, 15932 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 15933 chan_info = (wmi_channel *)buf_ptr; 15934 tchan_info = &(param->ch_param); 15935 chan_info->mhz = tchan_info->mhz; 15936 chan_info->band_center_freq1 = tchan_info->cfreq1; 15937 chan_info->band_center_freq2 = tchan_info->cfreq2; 15938 if (tchan_info->is_chan_passive) 15939 WMI_SET_CHANNEL_FLAG(chan_info, 15940 WMI_CHAN_FLAG_PASSIVE); 15941 if (tchan_info->dfs_set) 15942 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 15943 15944 if (tchan_info->allow_vht) 15945 WMI_SET_CHANNEL_FLAG(chan_info, 15946 WMI_CHAN_FLAG_ALLOW_VHT); 15947 else if (tchan_info->allow_ht) 15948 WMI_SET_CHANNEL_FLAG(chan_info, 15949 WMI_CHAN_FLAG_ALLOW_HT); 15950 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 15951 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 15952 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 15953 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 15954 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 15955 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 15956 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 15957 15958 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 15959 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 15960 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 15961 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 15962 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 15963 "tchan_info->reg_class_id: %d ," 15964 "tchan_info->maxregpower : %d ", __func__, 15965 tchan_info->is_chan_passive, tchan_info->dfs_set, 15966 tchan_info->allow_vht, tchan_info->allow_ht, 15967 tchan_info->antennamax, tchan_info->phy_mode, 15968 tchan_info->minpower, tchan_info->maxpower, 15969 tchan_info->maxregpower, tchan_info->reg_class_id, 15970 tchan_info->maxregpower); 15971 15972 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 15973 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 15974 15975 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15976 WMI_LOGE("%s: Failed to send\n", __func__); 15977 wmi_buf_free(buf); 15978 } 15979 15980 end: 15981 return qdf_status; 15982 } 15983 15984 /** 15985 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 15986 * @wmi_handle: wmi handle 15987 * @pdev_id: pdev id 15988 * 15989 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 15990 * 15991 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15992 */ 15993 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 15994 uint32_t pdev_id) 15995 { 15996 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 15997 wmi_buf_t buf; 15998 uint16_t len; 15999 QDF_STATUS ret; 16000 16001 len = sizeof(*cmd); 16002 buf = wmi_buf_alloc(wmi_handle, len); 16003 16004 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16005 16006 if (!buf) { 16007 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16008 return QDF_STATUS_E_NOMEM; 16009 } 16010 16011 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16012 wmi_buf_data(buf); 16013 16014 WMITLV_SET_HDR(&cmd->tlv_header, 16015 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16016 WMITLV_GET_STRUCT_TLVLEN( 16017 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16018 16019 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16020 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16021 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16022 if (QDF_IS_STATUS_ERROR(ret)) { 16023 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16024 __func__, ret, pdev_id); 16025 wmi_buf_free(buf); 16026 return QDF_STATUS_E_FAILURE; 16027 } 16028 16029 return QDF_STATUS_SUCCESS; 16030 } 16031 16032 /** 16033 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16034 * @wmi_handle: wmi handle 16035 * @pdev_id: pdev id 16036 * 16037 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16038 * 16039 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16040 */ 16041 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16042 uint32_t pdev_id) 16043 { 16044 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16045 wmi_buf_t buf; 16046 uint16_t len; 16047 QDF_STATUS ret; 16048 16049 len = sizeof(*cmd); 16050 buf = wmi_buf_alloc(wmi_handle, len); 16051 16052 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16053 16054 if (!buf) { 16055 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16056 return QDF_STATUS_E_NOMEM; 16057 } 16058 16059 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16060 wmi_buf_data(buf); 16061 16062 WMITLV_SET_HDR(&cmd->tlv_header, 16063 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16064 WMITLV_GET_STRUCT_TLVLEN( 16065 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16066 16067 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16068 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16069 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16070 if (QDF_IS_STATUS_ERROR(ret)) { 16071 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16072 __func__, ret, pdev_id); 16073 wmi_buf_free(buf); 16074 return QDF_STATUS_E_FAILURE; 16075 } 16076 16077 return QDF_STATUS_SUCCESS; 16078 } 16079 16080 /** 16081 * init_cmd_send_tlv() - send initialization cmd to fw 16082 * @wmi_handle: wmi handle 16083 * @param param: pointer to wmi init param 16084 * 16085 * Return: QDF_STATUS_SUCCESS for success or error code 16086 */ 16087 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16088 struct wmi_init_cmd_param *param) 16089 { 16090 wmi_buf_t buf; 16091 wmi_init_cmd_fixed_param *cmd; 16092 uint8_t *buf_ptr; 16093 wmi_resource_config *resource_cfg; 16094 wlan_host_memory_chunk *host_mem_chunks; 16095 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16096 uint16_t idx; 16097 int len; 16098 QDF_STATUS ret; 16099 16100 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16101 WMI_TLV_HDR_SIZE; 16102 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16103 16104 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16105 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16106 WMI_TLV_HDR_SIZE + 16107 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16108 16109 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16110 if (!buf) { 16111 qdf_print("%s: wmi_buf_alloc failed", __func__); 16112 return QDF_STATUS_E_FAILURE; 16113 } 16114 16115 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16116 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16117 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16118 16119 host_mem_chunks = (wlan_host_memory_chunk *) 16120 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16121 + WMI_TLV_HDR_SIZE); 16122 16123 WMITLV_SET_HDR(&cmd->tlv_header, 16124 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16125 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16126 16127 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16128 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16129 WMITLV_TAG_STRUC_wmi_resource_config, 16130 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16131 16132 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16133 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16134 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16135 WMITLV_GET_STRUCT_TLVLEN 16136 (wlan_host_memory_chunk)); 16137 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16138 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16139 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16140 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16141 "chunk %d len %d requested ,ptr 0x%x ", 16142 idx, host_mem_chunks[idx].size, 16143 host_mem_chunks[idx].ptr); 16144 } 16145 cmd->num_host_mem_chunks = param->num_mem_chunks; 16146 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16147 16148 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 16149 WMITLV_TAG_ARRAY_STRUC, 16150 (sizeof(wlan_host_memory_chunk) * 16151 param->num_mem_chunks)); 16152 16153 /* Fill hw mode id config */ 16154 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 16155 16156 /* Fill fw_abi_vers */ 16157 copy_fw_abi_version_tlv(wmi_handle, cmd); 16158 16159 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 16160 if (QDF_IS_STATUS_ERROR(ret)) { 16161 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 16162 ret); 16163 wmi_buf_free(buf); 16164 } 16165 16166 return ret; 16167 16168 } 16169 16170 /** 16171 * send_addba_send_cmd_tlv() - send addba send command to fw 16172 * @wmi_handle: wmi handle 16173 * @param: pointer to delba send params 16174 * @macaddr: peer mac address 16175 * 16176 * Send WMI_ADDBA_SEND_CMDID command to firmware 16177 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16178 */ 16179 static QDF_STATUS 16180 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 16181 uint8_t macaddr[IEEE80211_ADDR_LEN], 16182 struct addba_send_params *param) 16183 { 16184 wmi_addba_send_cmd_fixed_param *cmd; 16185 wmi_buf_t buf; 16186 uint16_t len; 16187 QDF_STATUS ret; 16188 16189 len = sizeof(*cmd); 16190 16191 buf = wmi_buf_alloc(wmi_handle, len); 16192 if (!buf) { 16193 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16194 return QDF_STATUS_E_NOMEM; 16195 } 16196 16197 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 16198 16199 WMITLV_SET_HDR(&cmd->tlv_header, 16200 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 16201 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 16202 16203 cmd->vdev_id = param->vdev_id; 16204 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16205 cmd->tid = param->tidno; 16206 cmd->buffersize = param->buffersize; 16207 16208 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 16209 if (QDF_IS_STATUS_ERROR(ret)) { 16210 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16211 wmi_buf_free(buf); 16212 return QDF_STATUS_E_FAILURE; 16213 } 16214 16215 return QDF_STATUS_SUCCESS; 16216 } 16217 16218 /** 16219 * send_delba_send_cmd_tlv() - send delba send command to fw 16220 * @wmi_handle: wmi handle 16221 * @param: pointer to delba send params 16222 * @macaddr: peer mac address 16223 * 16224 * Send WMI_DELBA_SEND_CMDID command to firmware 16225 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16226 */ 16227 static QDF_STATUS 16228 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 16229 uint8_t macaddr[IEEE80211_ADDR_LEN], 16230 struct delba_send_params *param) 16231 { 16232 wmi_delba_send_cmd_fixed_param *cmd; 16233 wmi_buf_t buf; 16234 uint16_t len; 16235 QDF_STATUS ret; 16236 16237 len = sizeof(*cmd); 16238 16239 buf = wmi_buf_alloc(wmi_handle, len); 16240 if (!buf) { 16241 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16242 return QDF_STATUS_E_NOMEM; 16243 } 16244 16245 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 16246 16247 WMITLV_SET_HDR(&cmd->tlv_header, 16248 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 16249 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 16250 16251 cmd->vdev_id = param->vdev_id; 16252 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16253 cmd->tid = param->tidno; 16254 cmd->initiator = param->initiator; 16255 cmd->reasoncode = param->reasoncode; 16256 16257 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 16258 if (QDF_IS_STATUS_ERROR(ret)) { 16259 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16260 wmi_buf_free(buf); 16261 return QDF_STATUS_E_FAILURE; 16262 } 16263 16264 return QDF_STATUS_SUCCESS; 16265 } 16266 16267 /** 16268 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 16269 * to fw 16270 * @wmi_handle: wmi handle 16271 * @param: pointer to addba clearresp params 16272 * @macaddr: peer mac address 16273 * Return: 0 for success or error code 16274 */ 16275 static QDF_STATUS 16276 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 16277 uint8_t macaddr[IEEE80211_ADDR_LEN], 16278 struct addba_clearresponse_params *param) 16279 { 16280 wmi_addba_clear_resp_cmd_fixed_param *cmd; 16281 wmi_buf_t buf; 16282 uint16_t len; 16283 QDF_STATUS ret; 16284 16285 len = sizeof(*cmd); 16286 16287 buf = wmi_buf_alloc(wmi_handle, len); 16288 if (!buf) { 16289 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 16290 return QDF_STATUS_E_FAILURE; 16291 } 16292 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 16293 16294 WMITLV_SET_HDR(&cmd->tlv_header, 16295 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 16296 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 16297 16298 cmd->vdev_id = param->vdev_id; 16299 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16300 16301 ret = wmi_unified_cmd_send(wmi_handle, 16302 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 16303 if (QDF_IS_STATUS_ERROR(ret)) { 16304 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16305 wmi_buf_free(buf); 16306 return QDF_STATUS_E_FAILURE; 16307 } 16308 16309 return QDF_STATUS_SUCCESS; 16310 } 16311 16312 /** 16313 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 16314 * @wmi_handle: wmi handle 16315 * @bcn_ctrl_param: pointer to bcn_offload_control param 16316 * 16317 * Return: QDF_STATUS_SUCCESS for success or error code 16318 */ 16319 static 16320 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 16321 struct bcn_offload_control *bcn_ctrl_param) 16322 { 16323 wmi_buf_t buf; 16324 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 16325 QDF_STATUS ret; 16326 uint32_t len; 16327 16328 len = sizeof(*cmd); 16329 16330 buf = wmi_buf_alloc(wmi_handle, len); 16331 if (!buf) { 16332 qdf_print("%s: wmi_buf_alloc failed", __func__); 16333 return QDF_STATUS_E_FAILURE; 16334 } 16335 16336 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 16337 WMITLV_SET_HDR(&cmd->tlv_header, 16338 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 16339 WMITLV_GET_STRUCT_TLVLEN 16340 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 16341 cmd->vdev_id = bcn_ctrl_param->vdev_id; 16342 switch (bcn_ctrl_param->bcn_ctrl_op) { 16343 case BCN_OFFLD_CTRL_TX_DISABLE: 16344 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 16345 break; 16346 case BCN_OFFLD_CTRL_TX_ENABLE: 16347 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 16348 break; 16349 case BCN_OFFLD_CTRL_SWBA_DISABLE: 16350 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 16351 break; 16352 case BCN_OFFLD_CTRL_SWBA_ENABLE: 16353 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 16354 break; 16355 default: 16356 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 16357 bcn_ctrl_param->bcn_ctrl_op); 16358 wmi_buf_free(buf); 16359 return QDF_STATUS_E_FAILURE; 16360 break; 16361 } 16362 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16363 WMI_BCN_OFFLOAD_CTRL_CMDID); 16364 16365 if (QDF_IS_STATUS_ERROR(ret)) { 16366 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 16367 ret); 16368 wmi_buf_free(buf); 16369 } 16370 16371 return ret; 16372 } 16373 16374 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 16375 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 16376 struct nan_datapath_initiator_req *ndp_req) 16377 { 16378 uint16_t len; 16379 wmi_buf_t buf; 16380 uint8_t *tlv_ptr; 16381 QDF_STATUS status; 16382 wmi_channel *ch_tlv; 16383 wmi_ndp_initiator_req_fixed_param *cmd; 16384 uint32_t passphrase_len, service_name_len; 16385 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 16386 wmi_ndp_transport_ip_param *tcp_ip_param; 16387 16388 /* 16389 * WMI command expects 4 byte alligned len: 16390 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16391 */ 16392 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 16393 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 16394 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 16395 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 16396 service_name_len = 16397 qdf_roundup(ndp_req->service_name.service_name_len, 4); 16398 /* allocated memory for fixed params as well as variable size data */ 16399 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 16400 + ndp_cfg_len + ndp_app_info_len + pmk_len 16401 + passphrase_len + service_name_len; 16402 16403 if (ndp_req->is_ipv6_addr_present) 16404 len += sizeof(*tcp_ip_param); 16405 16406 buf = wmi_buf_alloc(wmi_handle, len); 16407 if (!buf) { 16408 WMI_LOGE("wmi_buf_alloc failed"); 16409 return QDF_STATUS_E_NOMEM; 16410 } 16411 16412 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 16413 WMITLV_SET_HDR(&cmd->tlv_header, 16414 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 16415 WMITLV_GET_STRUCT_TLVLEN( 16416 wmi_ndp_initiator_req_fixed_param)); 16417 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 16418 cmd->transaction_id = ndp_req->transaction_id; 16419 cmd->service_instance_id = ndp_req->service_instance_id; 16420 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 16421 &cmd->peer_discovery_mac_addr); 16422 16423 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 16424 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 16425 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 16426 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 16427 cmd->nan_csid = ndp_req->ncs_sk_type; 16428 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 16429 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 16430 16431 ch_tlv = (wmi_channel *)&cmd[1]; 16432 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 16433 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16434 ch_tlv->mhz = ndp_req->channel; 16435 tlv_ptr = (uint8_t *)&ch_tlv[1]; 16436 16437 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16438 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16439 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16440 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16441 16442 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16443 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16444 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 16445 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16446 16447 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16448 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 16449 cmd->nan_pmk_len); 16450 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16451 16452 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16453 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 16454 cmd->nan_passphrase_len); 16455 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16456 16457 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16458 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16459 ndp_req->service_name.service_name, 16460 cmd->nan_servicename_len); 16461 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16462 16463 if (ndp_req->is_ipv6_addr_present) { 16464 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16465 WMITLV_SET_HDR(tcp_ip_param, 16466 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16467 WMITLV_GET_STRUCT_TLVLEN( 16468 wmi_ndp_transport_ip_param)); 16469 tcp_ip_param->ipv6_addr_present = true; 16470 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16471 ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16472 } 16473 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16474 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr); 16475 16476 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 16477 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 16478 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 16479 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16480 cmd->peer_discovery_mac_addr.mac_addr31to0, 16481 cmd->peer_discovery_mac_addr.mac_addr47to32); 16482 16483 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 16484 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16485 ndp_req->ndp_config.ndp_cfg, 16486 ndp_req->ndp_config.ndp_cfg_len); 16487 16488 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 16489 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16490 ndp_req->ndp_info.ndp_app_info, 16491 ndp_req->ndp_info.ndp_app_info_len); 16492 16493 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16494 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16495 ndp_req->pmk.pmk, cmd->nan_pmk_len); 16496 16497 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16498 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16499 ndp_req->passphrase.passphrase, 16500 cmd->nan_passphrase_len); 16501 16502 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16503 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16504 ndp_req->service_name.service_name, 16505 cmd->nan_servicename_len); 16506 16507 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 16508 WMI_NDP_INITIATOR_REQ_CMDID); 16509 16510 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16511 WMI_NDP_INITIATOR_REQ_CMDID); 16512 if (QDF_IS_STATUS_ERROR(status)) { 16513 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 16514 wmi_buf_free(buf); 16515 } 16516 16517 return status; 16518 } 16519 16520 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 16521 struct nan_datapath_responder_req *req) 16522 { 16523 uint16_t len; 16524 wmi_buf_t buf; 16525 uint8_t *tlv_ptr; 16526 QDF_STATUS status; 16527 wmi_ndp_responder_req_fixed_param *cmd; 16528 wmi_ndp_transport_ip_param *tcp_ip_param; 16529 uint32_t passphrase_len, service_name_len; 16530 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 16531 16532 vdev_id = wlan_vdev_get_id(req->vdev); 16533 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 16534 vdev_id, req->transaction_id, 16535 req->ndp_rsp, 16536 req->ndp_instance_id, 16537 req->ndp_info.ndp_app_info_len); 16538 16539 /* 16540 * WMI command expects 4 byte alligned len: 16541 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16542 */ 16543 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 16544 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 16545 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 16546 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 16547 service_name_len = 16548 qdf_roundup(req->service_name.service_name_len, 4); 16549 16550 /* allocated memory for fixed params as well as variable size data */ 16551 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 16552 + pmk_len + passphrase_len + service_name_len; 16553 16554 if (req->is_ipv6_addr_present || req->is_port_present || 16555 req->is_protocol_present) 16556 len += sizeof(*tcp_ip_param); 16557 16558 buf = wmi_buf_alloc(wmi_handle, len); 16559 if (!buf) { 16560 WMI_LOGE("wmi_buf_alloc failed"); 16561 return QDF_STATUS_E_NOMEM; 16562 } 16563 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 16564 WMITLV_SET_HDR(&cmd->tlv_header, 16565 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 16566 WMITLV_GET_STRUCT_TLVLEN( 16567 wmi_ndp_responder_req_fixed_param)); 16568 cmd->vdev_id = vdev_id; 16569 cmd->transaction_id = req->transaction_id; 16570 cmd->ndp_instance_id = req->ndp_instance_id; 16571 cmd->rsp_code = req->ndp_rsp; 16572 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 16573 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 16574 cmd->nan_pmk_len = req->pmk.pmk_len; 16575 cmd->nan_csid = req->ncs_sk_type; 16576 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 16577 cmd->nan_servicename_len = req->service_name.service_name_len; 16578 16579 tlv_ptr = (uint8_t *)&cmd[1]; 16580 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16581 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16582 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16583 16584 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16585 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16586 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16587 req->ndp_info.ndp_app_info, 16588 req->ndp_info.ndp_app_info_len); 16589 16590 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16591 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16592 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 16593 cmd->nan_pmk_len); 16594 16595 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16596 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16597 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16598 req->passphrase.passphrase, 16599 cmd->nan_passphrase_len); 16600 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16601 16602 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16603 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16604 req->service_name.service_name, 16605 cmd->nan_servicename_len); 16606 16607 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16608 16609 if (req->is_ipv6_addr_present || req->is_port_present || 16610 req->is_protocol_present) { 16611 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16612 WMITLV_SET_HDR(tcp_ip_param, 16613 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16614 WMITLV_GET_STRUCT_TLVLEN( 16615 wmi_ndp_transport_ip_param)); 16616 tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present; 16617 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16618 req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16619 16620 tcp_ip_param->trans_port_present = req->is_port_present; 16621 tcp_ip_param->transport_port = req->port; 16622 16623 tcp_ip_param->trans_proto_present = req->is_protocol_present; 16624 tcp_ip_param->transport_protocol = req->protocol; 16625 } 16626 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16627 req->is_ipv6_addr_present, req->ipv6_addr); 16628 WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port); 16629 WMI_LOGD(FL("protocol: %d present: %d"), 16630 req->is_protocol_present, req->protocol); 16631 16632 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 16633 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 16634 16635 WMI_LOGD("ndp_config len: %d", 16636 req->ndp_config.ndp_cfg_len); 16637 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16638 req->ndp_config.ndp_cfg, 16639 req->ndp_config.ndp_cfg_len); 16640 16641 WMI_LOGD("ndp_app_info len: %d", 16642 req->ndp_info.ndp_app_info_len); 16643 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16644 req->ndp_info.ndp_app_info, 16645 req->ndp_info.ndp_app_info_len); 16646 16647 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16648 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16649 req->pmk.pmk, cmd->nan_pmk_len); 16650 16651 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16652 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16653 req->passphrase.passphrase, 16654 cmd->nan_passphrase_len); 16655 16656 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16657 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16658 req->service_name.service_name, 16659 cmd->nan_servicename_len); 16660 16661 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 16662 WMI_NDP_RESPONDER_REQ_CMDID); 16663 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16664 WMI_NDP_RESPONDER_REQ_CMDID); 16665 if (QDF_IS_STATUS_ERROR(status)) { 16666 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 16667 wmi_buf_free(buf); 16668 } 16669 return status; 16670 } 16671 16672 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 16673 struct nan_datapath_end_req *req) 16674 { 16675 uint16_t len; 16676 wmi_buf_t buf; 16677 QDF_STATUS status; 16678 uint32_t ndp_end_req_len, i; 16679 wmi_ndp_end_req *ndp_end_req_lst; 16680 wmi_ndp_end_req_fixed_param *cmd; 16681 16682 /* len of tlv following fixed param */ 16683 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 16684 /* above comes out to 4 byte alligned already, no need of padding */ 16685 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 16686 buf = wmi_buf_alloc(wmi_handle, len); 16687 if (!buf) { 16688 WMI_LOGE("Malloc failed"); 16689 return QDF_STATUS_E_NOMEM; 16690 } 16691 16692 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 16693 WMITLV_SET_HDR(&cmd->tlv_header, 16694 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 16695 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 16696 16697 cmd->transaction_id = req->transaction_id; 16698 16699 /* set tlv pointer to end of fixed param */ 16700 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 16701 ndp_end_req_len); 16702 16703 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 16704 WMI_TLV_HDR_SIZE); 16705 for (i = 0; i < req->num_ndp_instances; i++) { 16706 WMITLV_SET_HDR(&ndp_end_req_lst[i], 16707 WMITLV_TAG_ARRAY_FIXED_STRUC, 16708 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 16709 16710 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 16711 } 16712 16713 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 16714 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16715 WMI_NDP_END_REQ_CMDID); 16716 if (QDF_IS_STATUS_ERROR(status)) { 16717 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 16718 wmi_buf_free(buf); 16719 } 16720 16721 return status; 16722 } 16723 16724 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 16725 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 16726 { 16727 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 16728 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 16729 16730 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 16731 fixed_params = event->fixed_param; 16732 16733 rsp->vdev = 16734 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16735 fixed_params->vdev_id, 16736 WLAN_NAN_ID); 16737 if (!rsp->vdev) { 16738 WMI_LOGE("vdev is null"); 16739 return QDF_STATUS_E_INVAL; 16740 } 16741 16742 rsp->transaction_id = fixed_params->transaction_id; 16743 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16744 rsp->status = fixed_params->rsp_status; 16745 rsp->reason = fixed_params->reason_code; 16746 16747 return QDF_STATUS_SUCCESS; 16748 } 16749 16750 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 16751 uint8_t *data, struct nan_datapath_indication_event *rsp) 16752 { 16753 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 16754 wmi_ndp_indication_event_fixed_param *fixed_params; 16755 size_t total_array_len; 16756 16757 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 16758 fixed_params = 16759 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 16760 16761 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16762 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16763 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16764 return QDF_STATUS_E_INVAL; 16765 } 16766 16767 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16768 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16769 fixed_params->ndp_app_info_len, 16770 event->num_ndp_app_info); 16771 return QDF_STATUS_E_INVAL; 16772 } 16773 16774 if (fixed_params->ndp_cfg_len > 16775 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16776 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16777 __func__, fixed_params->ndp_cfg_len); 16778 return QDF_STATUS_E_INVAL; 16779 } 16780 16781 total_array_len = fixed_params->ndp_cfg_len + 16782 sizeof(*fixed_params); 16783 16784 if (fixed_params->ndp_app_info_len > 16785 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16786 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16787 __func__, fixed_params->ndp_app_info_len); 16788 return QDF_STATUS_E_INVAL; 16789 } 16790 total_array_len += fixed_params->ndp_app_info_len; 16791 16792 if (fixed_params->nan_scid_len > 16793 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16794 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16795 __func__, fixed_params->nan_scid_len); 16796 return QDF_STATUS_E_INVAL; 16797 } 16798 16799 rsp->vdev = 16800 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16801 fixed_params->vdev_id, 16802 WLAN_NAN_ID); 16803 if (!rsp->vdev) { 16804 WMI_LOGE("vdev is null"); 16805 return QDF_STATUS_E_INVAL; 16806 } 16807 rsp->service_instance_id = fixed_params->service_instance_id; 16808 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16809 rsp->role = fixed_params->self_ndp_role; 16810 rsp->policy = fixed_params->accept_policy; 16811 16812 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16813 rsp->peer_mac_addr.bytes); 16814 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 16815 rsp->peer_discovery_mac_addr.bytes); 16816 16817 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 16818 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 16819 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 16820 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 16821 fixed_params->service_instance_id, 16822 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 16823 fixed_params->accept_policy, 16824 fixed_params->nan_csid, fixed_params->nan_scid_len, 16825 rsp->peer_mac_addr.bytes, 16826 rsp->peer_discovery_mac_addr.bytes); 16827 16828 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16829 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16830 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16831 16832 WMI_LOGD("ndp_app_info - %d bytes", 16833 fixed_params->ndp_app_info_len); 16834 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16835 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16836 16837 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 16838 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16839 rsp->ncs_sk_type = fixed_params->nan_csid; 16840 rsp->scid.scid_len = fixed_params->nan_scid_len; 16841 16842 if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN) 16843 rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN; 16844 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 16845 rsp->ndp_config.ndp_cfg_len); 16846 16847 if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN) 16848 rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN; 16849 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16850 rsp->ndp_info.ndp_app_info_len); 16851 16852 if (rsp->scid.scid_len > NDP_SCID_BUF_LEN) 16853 rsp->scid.scid_len = NDP_SCID_BUF_LEN; 16854 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 16855 16856 if (event->ndp_transport_ip_param && 16857 event->num_ndp_transport_ip_param) { 16858 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16859 rsp->is_ipv6_addr_present = true; 16860 qdf_mem_copy(rsp->ipv6_addr, 16861 event->ndp_transport_ip_param->ipv6_intf_addr, 16862 WMI_NDP_IPV6_INTF_ADDR_LEN); 16863 } 16864 } 16865 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16866 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16867 16868 WMI_LOGD("scid hex dump:"); 16869 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16870 rsp->scid.scid, rsp->scid.scid_len); 16871 16872 return QDF_STATUS_SUCCESS; 16873 } 16874 16875 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 16876 uint8_t *data, struct nan_datapath_confirm_event *rsp) 16877 { 16878 uint8_t i; 16879 WMI_HOST_WLAN_PHY_MODE ch_mode; 16880 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 16881 wmi_ndp_confirm_event_fixed_param *fixed_params; 16882 size_t total_array_len; 16883 16884 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 16885 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 16886 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", 16887 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 16888 fixed_params->ndp_instance_id, fixed_params->rsp_code, 16889 fixed_params->reason_code, 16890 fixed_params->num_active_ndps_on_peer); 16891 WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels); 16892 16893 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 16894 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 16895 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 16896 return QDF_STATUS_E_INVAL; 16897 } 16898 16899 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 16900 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16901 &event->ndp_cfg, fixed_params->ndp_cfg_len); 16902 16903 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 16904 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 16905 fixed_params->ndp_app_info_len, 16906 event->num_ndp_app_info); 16907 return QDF_STATUS_E_INVAL; 16908 } 16909 16910 WMI_LOGD("ndp_app_info - %d bytes", 16911 fixed_params->ndp_app_info_len); 16912 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16913 &event->ndp_app_info, fixed_params->ndp_app_info_len); 16914 16915 if (fixed_params->ndp_cfg_len > 16916 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 16917 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16918 __func__, fixed_params->ndp_cfg_len); 16919 return QDF_STATUS_E_INVAL; 16920 } 16921 16922 total_array_len = fixed_params->ndp_cfg_len + 16923 sizeof(*fixed_params); 16924 16925 if (fixed_params->ndp_app_info_len > 16926 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 16927 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 16928 __func__, fixed_params->ndp_app_info_len); 16929 return QDF_STATUS_E_INVAL; 16930 } 16931 16932 rsp->vdev = 16933 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 16934 fixed_params->vdev_id, 16935 WLAN_NAN_ID); 16936 if (!rsp->vdev) { 16937 WMI_LOGE("vdev is null"); 16938 return QDF_STATUS_E_INVAL; 16939 } 16940 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 16941 rsp->rsp_code = fixed_params->rsp_code; 16942 rsp->reason_code = fixed_params->reason_code; 16943 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 16944 rsp->num_channels = fixed_params->num_ndp_channels; 16945 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 16946 rsp->peer_ndi_mac_addr.bytes); 16947 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 16948 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 16949 rsp->ndp_info.ndp_app_info_len); 16950 16951 if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 16952 WMI_LOGE(FL("too many channels")); 16953 rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS; 16954 } 16955 16956 for (i = 0; i < rsp->num_channels; i++) { 16957 rsp->ch[i].channel = event->ndp_channel_list[i].mhz; 16958 rsp->ch[i].nss = event->nss_list[i]; 16959 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]); 16960 rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 16961 ch_mode); 16962 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 16963 rsp->ch[i].channel, 16964 rsp->ch[i].ch_width, 16965 rsp->ch[i].nss); 16966 } 16967 16968 if (event->ndp_transport_ip_param && 16969 event->num_ndp_transport_ip_param) { 16970 if (event->ndp_transport_ip_param->ipv6_addr_present) { 16971 rsp->is_ipv6_addr_present = true; 16972 qdf_mem_copy(rsp->ipv6_addr, 16973 event->ndp_transport_ip_param->ipv6_intf_addr, 16974 WMI_NDP_IPV6_INTF_ADDR_LEN); 16975 } 16976 16977 if (event->ndp_transport_ip_param->trans_port_present) { 16978 rsp->is_port_present = true; 16979 rsp->port = 16980 event->ndp_transport_ip_param->transport_port; 16981 } 16982 16983 if (event->ndp_transport_ip_param->trans_proto_present) { 16984 rsp->is_protocol_present = true; 16985 rsp->protocol = 16986 event->ndp_transport_ip_param->transport_protocol; 16987 } 16988 } 16989 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16990 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 16991 WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present); 16992 WMI_LOGD(FL("protocol: %d present: %d"), 16993 rsp->protocol, rsp->is_protocol_present); 16994 16995 return QDF_STATUS_SUCCESS; 16996 } 16997 16998 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 16999 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 17000 { 17001 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17002 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17003 17004 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17005 fixed_params = event->fixed_param; 17006 17007 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", 17008 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17009 rsp->peer_mac_addr.bytes, rsp->transaction_id, 17010 rsp->status, rsp->reason, rsp->create_peer); 17011 17012 rsp->vdev = 17013 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17014 fixed_params->vdev_id, 17015 WLAN_NAN_ID); 17016 if (!rsp->vdev) { 17017 WMI_LOGE("vdev is null"); 17018 return QDF_STATUS_E_INVAL; 17019 } 17020 rsp->transaction_id = fixed_params->transaction_id; 17021 rsp->reason = fixed_params->reason_code; 17022 rsp->status = fixed_params->rsp_status; 17023 rsp->create_peer = fixed_params->create_peer; 17024 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17025 rsp->peer_mac_addr.bytes); 17026 17027 return QDF_STATUS_SUCCESS; 17028 } 17029 17030 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17031 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 17032 { 17033 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17034 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17035 17036 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17037 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17038 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 17039 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17040 fixed_params->rsp_status, fixed_params->reason_code); 17041 17042 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17043 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17044 if (!rsp->vdev) { 17045 WMI_LOGE("vdev is null"); 17046 return QDF_STATUS_E_INVAL; 17047 } 17048 rsp->transaction_id = fixed_params->transaction_id; 17049 rsp->reason = fixed_params->reason_code; 17050 rsp->status = fixed_params->rsp_status; 17051 17052 return QDF_STATUS_SUCCESS; 17053 } 17054 17055 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17056 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17057 { 17058 uint32_t i, buf_size; 17059 wmi_ndp_end_indication *ind; 17060 struct qdf_mac_addr peer_addr; 17061 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17062 17063 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17064 ind = event->ndp_end_indication_list; 17065 17066 if (event->num_ndp_end_indication_list == 0) { 17067 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17068 return QDF_STATUS_E_INVAL; 17069 } 17070 17071 WMI_LOGD("number of ndp instances = %d", 17072 event->num_ndp_end_indication_list); 17073 17074 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17075 sizeof((*rsp)->ndp_map[0]))) { 17076 WMI_LOGE("num_ndp_end_ind_list %d too large", 17077 event->num_ndp_end_indication_list); 17078 return QDF_STATUS_E_INVAL; 17079 } 17080 17081 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17082 sizeof((*rsp)->ndp_map[0]); 17083 *rsp = qdf_mem_malloc(buf_size); 17084 if (!(*rsp)) { 17085 WMI_LOGE("Failed to allocate memory"); 17086 return QDF_STATUS_E_NOMEM; 17087 } 17088 17089 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17090 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17091 if (!(*rsp)->vdev) { 17092 WMI_LOGE("vdev is null"); 17093 qdf_mem_free(*rsp); 17094 *rsp = NULL; 17095 return QDF_STATUS_E_INVAL; 17096 } 17097 17098 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17099 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17100 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17101 peer_addr.bytes); 17102 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17103 i, ind[i].type, ind[i].reason_code, 17104 ind[i].ndp_instance_id, 17105 ind[i].num_active_ndps_on_peer); 17106 /* Add each instance entry to the list */ 17107 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17108 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17109 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17110 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17111 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17112 ind[i].num_active_ndps_on_peer; 17113 (*rsp)->ndp_map[i].type = ind[i].type; 17114 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17115 } 17116 17117 return QDF_STATUS_SUCCESS; 17118 } 17119 17120 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 17121 uint8_t *data, struct nan_datapath_sch_update_event *ind) 17122 { 17123 uint8_t i; 17124 WMI_HOST_WLAN_PHY_MODE ch_mode; 17125 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 17126 wmi_ndl_schedule_update_fixed_param *fixed_params; 17127 17128 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 17129 fixed_params = event->fixed_param; 17130 17131 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 17132 fixed_params->flags, fixed_params->num_channels, 17133 fixed_params->num_ndp_instances); 17134 17135 ind->vdev = 17136 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17137 fixed_params->vdev_id, 17138 WLAN_NAN_ID); 17139 if (!ind->vdev) { 17140 WMI_LOGE("vdev is null"); 17141 return QDF_STATUS_E_INVAL; 17142 } 17143 17144 ind->flags = fixed_params->flags; 17145 ind->num_channels = fixed_params->num_channels; 17146 ind->num_ndp_instances = fixed_params->num_ndp_instances; 17147 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 17148 ind->peer_addr.bytes); 17149 17150 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 17151 WMI_LOGE(FL("uint32 overflow")); 17152 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 17153 return QDF_STATUS_E_INVAL; 17154 } 17155 17156 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 17157 sizeof(uint32_t) * ind->num_ndp_instances); 17158 17159 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 17160 WMI_LOGE(FL("too many channels")); 17161 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 17162 } 17163 for (i = 0; i < ind->num_channels; i++) { 17164 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 17165 ind->ch[i].nss = event->nss_list[i]; 17166 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 17167 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 17168 ch_mode); 17169 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 17170 ind->ch[i].channel, 17171 ind->ch[i].ch_width, 17172 ind->ch[i].nss); 17173 } 17174 17175 for (i = 0; i < fixed_params->num_ndp_instances; i++) 17176 WMI_LOGD(FL("instance_id[%d]: %d"), 17177 i, event->ndp_instance_list[i]); 17178 17179 return QDF_STATUS_SUCCESS; 17180 } 17181 17182 #endif 17183 17184 #ifdef QCA_SUPPORT_CP_STATS 17185 /** 17186 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17187 * @wmi_handle: wma handle 17188 * @evt_buf: event buffer 17189 * @out_buff: buffer to populated after stats extraction 17190 * 17191 * Return: status of operation 17192 */ 17193 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17194 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17195 { 17196 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17197 wmi_congestion_stats *congestion_stats; 17198 17199 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17200 congestion_stats = param_buf->congestion_stats; 17201 if (!congestion_stats) { 17202 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17203 return QDF_STATUS_E_INVAL; 17204 } 17205 17206 out_buff->vdev_id = congestion_stats->vdev_id; 17207 out_buff->congestion = congestion_stats->congestion; 17208 17209 WMI_LOGD("%s: cca stats event processed", __func__); 17210 return QDF_STATUS_SUCCESS; 17211 } 17212 #endif /* QCA_SUPPORT_CP_STATS */ 17213 17214 /** 17215 * save_service_bitmap_tlv() - save service bitmap 17216 * @wmi_handle: wmi handle 17217 * @param evt_buf: pointer to event buffer 17218 * @param bitmap_buf: bitmap buffer, for converged legacy support 17219 * 17220 * Return: QDF_STATUS 17221 */ 17222 static 17223 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17224 void *bitmap_buf) 17225 { 17226 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17227 struct wmi_soc *soc = wmi_handle->soc; 17228 17229 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17230 17231 /* If it is already allocated, use that buffer. This can happen 17232 * during target stop/start scenarios where host allocation is skipped. 17233 */ 17234 if (!soc->wmi_service_bitmap) { 17235 soc->wmi_service_bitmap = 17236 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17237 if (!soc->wmi_service_bitmap) { 17238 WMI_LOGE("Failed memory allocation for service bitmap"); 17239 return QDF_STATUS_E_NOMEM; 17240 } 17241 } 17242 17243 qdf_mem_copy(soc->wmi_service_bitmap, 17244 param_buf->wmi_service_bitmap, 17245 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17246 17247 if (bitmap_buf) 17248 qdf_mem_copy(bitmap_buf, 17249 param_buf->wmi_service_bitmap, 17250 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17251 17252 return QDF_STATUS_SUCCESS; 17253 } 17254 17255 /** 17256 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17257 * @wmi_handle: wmi handle 17258 * @param evt_buf: pointer to event buffer 17259 * @param bitmap_buf: bitmap buffer, for converged legacy support 17260 * 17261 * Return: QDF_STATUS 17262 */ 17263 static 17264 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17265 void *bitmap_buf) 17266 { 17267 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17268 wmi_service_available_event_fixed_param *ev; 17269 struct wmi_soc *soc = wmi_handle->soc; 17270 17271 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17272 17273 ev = param_buf->fixed_param; 17274 17275 /* If it is already allocated, use that buffer. This can happen 17276 * during target stop/start scenarios where host allocation is skipped. 17277 */ 17278 if (!soc->wmi_ext_service_bitmap) { 17279 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17280 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17281 if (!soc->wmi_ext_service_bitmap) { 17282 WMI_LOGE("Failed memory allocation for service bitmap"); 17283 return QDF_STATUS_E_NOMEM; 17284 } 17285 } 17286 17287 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17288 ev->wmi_service_segment_bitmap, 17289 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17290 17291 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17292 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17293 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17294 17295 if (bitmap_buf) 17296 qdf_mem_copy(bitmap_buf, 17297 soc->wmi_ext_service_bitmap, 17298 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17299 17300 return QDF_STATUS_SUCCESS; 17301 } 17302 /** 17303 * is_service_enabled_tlv() - Check if service enabled 17304 * @param wmi_handle: wmi handle 17305 * @param service_id: service identifier 17306 * 17307 * Return: 1 enabled, 0 disabled 17308 */ 17309 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17310 uint32_t service_id) 17311 { 17312 struct wmi_soc *soc = wmi_handle->soc; 17313 17314 if (!soc->wmi_service_bitmap) { 17315 WMI_LOGE("WMI service bit map is not saved yet\n"); 17316 return false; 17317 } 17318 17319 /* if wmi_service_enabled was received with extended bitmap, 17320 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17321 */ 17322 if (soc->wmi_ext_service_bitmap) 17323 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17324 soc->wmi_ext_service_bitmap, 17325 service_id); 17326 17327 if (service_id >= WMI_MAX_SERVICE) { 17328 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 17329 service_id); 17330 return false; 17331 } 17332 17333 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17334 service_id); 17335 } 17336 17337 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17338 struct wlan_psoc_target_capability_info *cap) 17339 { 17340 /* except LDPC all flags are common betwen legacy and here 17341 * also IBFEER is not defined for TLV 17342 */ 17343 cap->ht_cap_info |= ev_target_cap & ( 17344 WMI_HT_CAP_ENABLED 17345 | WMI_HT_CAP_HT20_SGI 17346 | WMI_HT_CAP_DYNAMIC_SMPS 17347 | WMI_HT_CAP_TX_STBC 17348 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17349 | WMI_HT_CAP_RX_STBC 17350 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17351 | WMI_HT_CAP_LDPC 17352 | WMI_HT_CAP_L_SIG_TXOP_PROT 17353 | WMI_HT_CAP_MPDU_DENSITY 17354 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17355 | WMI_HT_CAP_HT40_SGI); 17356 if (ev_target_cap & WMI_HT_CAP_LDPC) 17357 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17358 WMI_HOST_HT_CAP_TX_LDPC; 17359 } 17360 /** 17361 * extract_service_ready_tlv() - extract service ready event 17362 * @wmi_handle: wmi handle 17363 * @param evt_buf: pointer to received event buffer 17364 * @param cap: pointer to hold target capability information extracted from even 17365 * 17366 * Return: QDF_STATUS_SUCCESS for success or error code 17367 */ 17368 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17369 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17370 { 17371 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17372 wmi_service_ready_event_fixed_param *ev; 17373 17374 17375 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17376 17377 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17378 if (!ev) { 17379 qdf_print("%s: wmi_buf_alloc failed", __func__); 17380 return QDF_STATUS_E_FAILURE; 17381 } 17382 17383 cap->phy_capability = ev->phy_capability; 17384 cap->max_frag_entry = ev->max_frag_entry; 17385 cap->num_rf_chains = ev->num_rf_chains; 17386 copy_ht_cap_info(ev->ht_cap_info, cap); 17387 cap->vht_cap_info = ev->vht_cap_info; 17388 cap->vht_supp_mcs = ev->vht_supp_mcs; 17389 cap->hw_min_tx_power = ev->hw_min_tx_power; 17390 cap->hw_max_tx_power = ev->hw_max_tx_power; 17391 cap->sys_cap_info = ev->sys_cap_info; 17392 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17393 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17394 cap->max_num_scan_channels = ev->max_num_scan_channels; 17395 cap->max_supported_macs = ev->max_supported_macs; 17396 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17397 cap->txrx_chainmask = ev->txrx_chainmask; 17398 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17399 cap->num_msdu_desc = ev->num_msdu_desc; 17400 cap->fw_version = ev->fw_build_vers; 17401 /* fw_version_1 is not available in TLV. */ 17402 cap->fw_version_1 = 0; 17403 17404 return QDF_STATUS_SUCCESS; 17405 } 17406 17407 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 17408 * to host internal WMI_HOST_REGDMN_MODE values. 17409 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 17410 * host currently. Add this in the future if required. 17411 * 11AX (Phase II) : 11ax related values are not currently 17412 * advertised separately by FW. As part of phase II regulatory bring-up, 17413 * finalize the advertisement mechanism. 17414 * @target_wireless_mode: target wireless mode received in message 17415 * 17416 * Return: returns the host internal wireless mode. 17417 */ 17418 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 17419 { 17420 17421 uint32_t wireless_modes = 0; 17422 17423 if (target_wireless_mode & REGDMN_MODE_11A) 17424 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 17425 17426 if (target_wireless_mode & REGDMN_MODE_TURBO) 17427 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 17428 17429 if (target_wireless_mode & REGDMN_MODE_11B) 17430 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 17431 17432 if (target_wireless_mode & REGDMN_MODE_PUREG) 17433 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 17434 17435 if (target_wireless_mode & REGDMN_MODE_11G) 17436 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 17437 17438 if (target_wireless_mode & REGDMN_MODE_108G) 17439 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 17440 17441 if (target_wireless_mode & REGDMN_MODE_108A) 17442 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 17443 17444 if (target_wireless_mode & REGDMN_MODE_XR) 17445 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 17446 17447 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 17448 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 17449 17450 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 17451 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 17452 17453 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 17454 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 17455 17456 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 17457 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 17458 17459 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 17460 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 17461 17462 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 17463 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 17464 17465 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 17466 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 17467 17468 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 17469 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 17470 17471 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 17472 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 17473 17474 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 17475 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 17476 17477 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 17478 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 17479 17480 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 17481 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 17482 17483 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 17484 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 17485 17486 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 17487 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 17488 17489 return wireless_modes; 17490 } 17491 17492 /** 17493 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 17494 * @wmi_handle: wmi handle 17495 * @param evt_buf: Pointer to event buffer 17496 * @param cap: pointer to hold HAL reg capabilities 17497 * 17498 * Return: QDF_STATUS_SUCCESS for success or error code 17499 */ 17500 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 17501 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 17502 { 17503 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17504 17505 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17506 17507 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 17508 sizeof(uint32_t)), 17509 sizeof(struct wlan_psoc_hal_reg_capability)); 17510 17511 cap->wireless_modes = convert_wireless_modes_tlv( 17512 param_buf->hal_reg_capabilities->wireless_modes); 17513 17514 return QDF_STATUS_SUCCESS; 17515 } 17516 17517 /** 17518 * extract_host_mem_req_tlv() - Extract host memory request event 17519 * @wmi_handle: wmi handle 17520 * @param evt_buf: pointer to event buffer 17521 * @param num_entries: pointer to hold number of entries requested 17522 * 17523 * Return: Number of entries requested 17524 */ 17525 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 17526 void *evt_buf, uint8_t *num_entries) 17527 { 17528 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17529 wmi_service_ready_event_fixed_param *ev; 17530 17531 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17532 17533 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17534 if (!ev) { 17535 qdf_print("%s: wmi_buf_alloc failed", __func__); 17536 return NULL; 17537 } 17538 17539 *num_entries = ev->num_mem_reqs; 17540 17541 return (host_mem_req *)param_buf->mem_reqs; 17542 } 17543 17544 /** 17545 * save_fw_version_in_service_ready_tlv() - Save fw version in service 17546 * ready function 17547 * @wmi_handle: wmi handle 17548 * @param evt_buf: pointer to event buffer 17549 * 17550 * Return: QDF_STATUS_SUCCESS for success or error code 17551 */ 17552 static QDF_STATUS 17553 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 17554 { 17555 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17556 wmi_service_ready_event_fixed_param *ev; 17557 17558 17559 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17560 17561 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17562 if (!ev) { 17563 qdf_print("%s: wmi_buf_alloc failed", __func__); 17564 return QDF_STATUS_E_FAILURE; 17565 } 17566 17567 /*Save fw version from service ready message */ 17568 /*This will be used while sending INIT message */ 17569 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 17570 sizeof(wmi_handle->fw_abi_version)); 17571 17572 return QDF_STATUS_SUCCESS; 17573 } 17574 17575 /** 17576 * ready_extract_init_status_tlv() - Extract init status from ready event 17577 * @wmi_handle: wmi handle 17578 * @param evt_buf: Pointer to event buffer 17579 * 17580 * Return: ready status 17581 */ 17582 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 17583 void *evt_buf) 17584 { 17585 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17586 wmi_ready_event_fixed_param *ev = NULL; 17587 17588 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17589 ev = param_buf->fixed_param; 17590 17591 qdf_print("%s:%d", __func__, ev->status); 17592 17593 return ev->status; 17594 } 17595 17596 /** 17597 * ready_extract_mac_addr_tlv() - extract mac address from ready event 17598 * @wmi_handle: wmi handle 17599 * @param evt_buf: pointer to event buffer 17600 * @param macaddr: Pointer to hold MAC address 17601 * 17602 * Return: QDF_STATUS_SUCCESS for success or error code 17603 */ 17604 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 17605 void *evt_buf, uint8_t *macaddr) 17606 { 17607 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17608 wmi_ready_event_fixed_param *ev = NULL; 17609 17610 17611 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17612 ev = param_buf->fixed_param; 17613 17614 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 17615 17616 return QDF_STATUS_SUCCESS; 17617 } 17618 17619 /** 17620 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 17621 * @wmi_handle: wmi handle 17622 * @param evt_buf: pointer to event buffer 17623 * @param macaddr: Pointer to hold number of MAC addresses 17624 * 17625 * Return: Pointer to addr list 17626 */ 17627 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 17628 void *evt_buf, uint8_t *num_mac) 17629 { 17630 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17631 wmi_ready_event_fixed_param *ev = NULL; 17632 17633 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17634 ev = param_buf->fixed_param; 17635 17636 *num_mac = ev->num_extra_mac_addr; 17637 17638 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 17639 } 17640 17641 /** 17642 * extract_ready_params_tlv() - Extract data from ready event apart from 17643 * status, macaddr and version. 17644 * @wmi_handle: Pointer to WMI handle. 17645 * @evt_buf: Pointer to Ready event buffer. 17646 * @ev_param: Pointer to host defined struct to copy the data from event. 17647 * 17648 * Return: QDF_STATUS_SUCCESS on success. 17649 */ 17650 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 17651 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 17652 { 17653 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17654 wmi_ready_event_fixed_param *ev = NULL; 17655 17656 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17657 ev = param_buf->fixed_param; 17658 17659 ev_param->status = ev->status; 17660 ev_param->num_dscp_table = ev->num_dscp_table; 17661 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 17662 ev_param->num_total_peer = ev->num_total_peers; 17663 ev_param->num_extra_peer = ev->num_extra_peers; 17664 /* Agile_cap in ready event is not supported in TLV target */ 17665 ev_param->agile_capability = false; 17666 17667 return QDF_STATUS_SUCCESS; 17668 } 17669 17670 /** 17671 * extract_dbglog_data_len_tlv() - extract debuglog data length 17672 * @wmi_handle: wmi handle 17673 * @param evt_buf: pointer to event buffer 17674 * 17675 * Return: length 17676 */ 17677 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 17678 void *evt_buf, uint32_t *len) 17679 { 17680 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 17681 17682 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 17683 17684 *len = param_buf->num_bufp; 17685 17686 return param_buf->bufp; 17687 } 17688 17689 /** 17690 * extract_vdev_start_resp_tlv() - extract vdev start response 17691 * @wmi_handle: wmi handle 17692 * @param evt_buf: pointer to event buffer 17693 * @param vdev_rsp: Pointer to hold vdev response 17694 * 17695 * Return: QDF_STATUS_SUCCESS for success or error code 17696 */ 17697 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 17698 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 17699 { 17700 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 17701 wmi_vdev_start_response_event_fixed_param *ev; 17702 17703 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 17704 if (!param_buf) { 17705 qdf_print("Invalid start response event buffer"); 17706 return QDF_STATUS_E_INVAL; 17707 } 17708 17709 ev = param_buf->fixed_param; 17710 if (!ev) { 17711 qdf_print("Invalid start response event buffer"); 17712 return QDF_STATUS_E_INVAL; 17713 } 17714 17715 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 17716 17717 vdev_rsp->vdev_id = ev->vdev_id; 17718 vdev_rsp->requestor_id = ev->requestor_id; 17719 switch (ev->resp_type) { 17720 case WMI_VDEV_START_RESP_EVENT: 17721 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 17722 break; 17723 case WMI_VDEV_RESTART_RESP_EVENT: 17724 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 17725 break; 17726 default: 17727 qdf_print("Invalid start response event buffer"); 17728 break; 17729 }; 17730 vdev_rsp->status = ev->status; 17731 vdev_rsp->chain_mask = ev->chain_mask; 17732 vdev_rsp->smps_mode = ev->smps_mode; 17733 vdev_rsp->mac_id = ev->mac_id; 17734 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 17735 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 17736 17737 return QDF_STATUS_SUCCESS; 17738 } 17739 17740 /** 17741 * extract_vdev_delete_resp_tlv() - extract vdev delete response 17742 * @wmi_handle: wmi handle 17743 * @param evt_buf: pointer to event buffer 17744 * @param delete_rsp: Pointer to hold vdev delete response 17745 * 17746 * Return: QDF_STATUS_SUCCESS for success or error code 17747 */ 17748 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 17749 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 17750 { 17751 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 17752 wmi_vdev_delete_resp_event_fixed_param *ev; 17753 17754 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 17755 if (!param_buf) { 17756 WMI_LOGE("Invalid vdev delete response event buffer\n"); 17757 return QDF_STATUS_E_INVAL; 17758 } 17759 17760 ev = param_buf->fixed_param; 17761 if (!ev) { 17762 WMI_LOGE("Invalid vdev delete response event\n"); 17763 return QDF_STATUS_E_INVAL; 17764 } 17765 17766 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 17767 delete_rsp->vdev_id = ev->vdev_id; 17768 17769 return QDF_STATUS_SUCCESS; 17770 } 17771 17772 17773 /** 17774 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 17775 * @wmi_handle: wmi handle 17776 * @param evt_buf: pointer to event buffer 17777 * @param num_vdevs: Pointer to hold num vdev 17778 * 17779 * Return: QDF_STATUS_SUCCESS for success or error code 17780 */ 17781 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17782 void *evt_buf, uint32_t *num_vdevs) 17783 { 17784 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17785 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17786 uint32_t vdev_map; 17787 17788 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 17789 if (!param_buf) { 17790 qdf_print("Invalid tbtt update ext event buffer"); 17791 return QDF_STATUS_E_INVAL; 17792 } 17793 tbtt_offset_event = param_buf->fixed_param; 17794 vdev_map = tbtt_offset_event->vdev_map; 17795 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 17796 17797 return QDF_STATUS_SUCCESS; 17798 } 17799 17800 /** 17801 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 17802 * @wmi_handle: wmi handle 17803 * @param evt_buf: pointer to event buffer 17804 * @param num_vdevs: Pointer to hold num vdev 17805 * 17806 * Return: QDF_STATUS_SUCCESS for success or error code 17807 */ 17808 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 17809 void *evt_buf, uint32_t *num_vdevs) 17810 { 17811 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17812 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 17813 17814 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17815 if (!param_buf) { 17816 qdf_print("Invalid tbtt update ext event buffer"); 17817 return QDF_STATUS_E_INVAL; 17818 } 17819 tbtt_offset_ext_event = param_buf->fixed_param; 17820 17821 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 17822 17823 return QDF_STATUS_SUCCESS; 17824 } 17825 17826 /** 17827 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 17828 * @wmi_handle: wmi handle 17829 * @param evt_buf: pointer to event buffer 17830 * @param idx: Index referring to a vdev 17831 * @param tbtt_param: Pointer to tbttoffset event param 17832 * 17833 * Return: QDF_STATUS_SUCCESS for success or error code 17834 */ 17835 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 17836 void *evt_buf, uint8_t idx, 17837 struct tbttoffset_params *tbtt_param) 17838 { 17839 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 17840 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 17841 uint32_t vdev_map; 17842 17843 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 17844 if (!param_buf) { 17845 qdf_print("Invalid tbtt update event buffer"); 17846 return QDF_STATUS_E_INVAL; 17847 } 17848 17849 tbtt_offset_event = param_buf->fixed_param; 17850 vdev_map = tbtt_offset_event->vdev_map; 17851 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 17852 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 17853 return QDF_STATUS_E_INVAL; 17854 tbtt_param->tbttoffset = 17855 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 17856 17857 return QDF_STATUS_SUCCESS; 17858 } 17859 17860 /** 17861 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 17862 * @wmi_handle: wmi handle 17863 * @param evt_buf: pointer to event buffer 17864 * @param idx: Index referring to a vdev 17865 * @param tbtt_param: Pointer to tbttoffset event param 17866 * 17867 * Return: QDF_STATUS_SUCCESS for success or error code 17868 */ 17869 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 17870 void *evt_buf, uint8_t idx, 17871 struct tbttoffset_params *tbtt_param) 17872 { 17873 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 17874 wmi_tbtt_offset_info *tbtt_offset_info; 17875 17876 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 17877 if (!param_buf) { 17878 qdf_print("Invalid tbtt update event buffer"); 17879 return QDF_STATUS_E_INVAL; 17880 } 17881 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 17882 17883 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 17884 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 17885 17886 return QDF_STATUS_SUCCESS; 17887 } 17888 17889 /** 17890 * extract_mgmt_rx_params_tlv() - extract management rx params from event 17891 * @wmi_handle: wmi handle 17892 * @param evt_buf: pointer to event buffer 17893 * @param hdr: Pointer to hold header 17894 * @param bufp: Pointer to hold pointer to rx param buffer 17895 * 17896 * Return: QDF_STATUS_SUCCESS for success or error code 17897 */ 17898 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 17899 void *evt_buf, struct mgmt_rx_event_params *hdr, 17900 uint8_t **bufp) 17901 { 17902 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 17903 wmi_mgmt_rx_hdr *ev_hdr = NULL; 17904 int i; 17905 17906 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 17907 if (!param_tlvs) { 17908 WMI_LOGE("Get NULL point message from FW"); 17909 return QDF_STATUS_E_INVAL; 17910 } 17911 17912 ev_hdr = param_tlvs->hdr; 17913 if (!hdr) { 17914 WMI_LOGE("Rx event is NULL"); 17915 return QDF_STATUS_E_INVAL; 17916 } 17917 17918 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17919 ev_hdr->pdev_id); 17920 17921 hdr->channel = ev_hdr->channel; 17922 hdr->snr = ev_hdr->snr; 17923 hdr->rate = ev_hdr->rate; 17924 hdr->phy_mode = ev_hdr->phy_mode; 17925 hdr->buf_len = ev_hdr->buf_len; 17926 hdr->status = ev_hdr->status; 17927 hdr->flags = ev_hdr->flags; 17928 hdr->rssi = ev_hdr->rssi; 17929 hdr->tsf_delta = ev_hdr->tsf_delta; 17930 for (i = 0; i < ATH_MAX_ANTENNA; i++) 17931 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 17932 17933 *bufp = param_tlvs->bufp; 17934 17935 return QDF_STATUS_SUCCESS; 17936 } 17937 17938 /** 17939 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 17940 * @wmi_handle: wmi handle 17941 * @param evt_buf: pointer to event buffer 17942 * @param vdev_id: Pointer to hold vdev identifier 17943 * 17944 * Return: QDF_STATUS_SUCCESS for success or error code 17945 */ 17946 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 17947 void *evt_buf, uint32_t *vdev_id) 17948 { 17949 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 17950 wmi_vdev_stopped_event_fixed_param *resp_event; 17951 17952 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 17953 if (!param_buf) { 17954 WMI_LOGE("Invalid event buffer"); 17955 return QDF_STATUS_E_INVAL; 17956 } 17957 resp_event = param_buf->fixed_param; 17958 *vdev_id = resp_event->vdev_id; 17959 17960 return QDF_STATUS_SUCCESS; 17961 } 17962 17963 /** 17964 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 17965 * @wmi_handle: wmi handle 17966 * @param evt_buf: pointer to event buffer 17967 * @param param: Pointer to hold roam param 17968 * 17969 * Return: QDF_STATUS_SUCCESS for success or error code 17970 */ 17971 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 17972 void *evt_buf, wmi_host_roam_event *param) 17973 { 17974 WMI_ROAM_EVENTID_param_tlvs *param_buf; 17975 wmi_roam_event_fixed_param *evt; 17976 17977 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 17978 if (!param_buf) { 17979 WMI_LOGE("Invalid roam event buffer"); 17980 return QDF_STATUS_E_INVAL; 17981 } 17982 17983 evt = param_buf->fixed_param; 17984 qdf_mem_zero(param, sizeof(*param)); 17985 17986 param->vdev_id = evt->vdev_id; 17987 param->reason = evt->reason; 17988 param->rssi = evt->rssi; 17989 17990 return QDF_STATUS_SUCCESS; 17991 } 17992 17993 /** 17994 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 17995 * @wmi_handle: wmi handle 17996 * @param evt_buf: pointer to event buffer 17997 * @param param: Pointer to hold vdev scan param 17998 * 17999 * Return: QDF_STATUS_SUCCESS for success or error code 18000 */ 18001 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18002 void *evt_buf, struct scan_event *param) 18003 { 18004 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18005 wmi_scan_event_fixed_param *evt = NULL; 18006 18007 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18008 evt = param_buf->fixed_param; 18009 18010 qdf_mem_zero(param, sizeof(*param)); 18011 18012 switch (evt->event) { 18013 case WMI_SCAN_EVENT_STARTED: 18014 param->type = SCAN_EVENT_TYPE_STARTED; 18015 break; 18016 case WMI_SCAN_EVENT_COMPLETED: 18017 param->type = SCAN_EVENT_TYPE_COMPLETED; 18018 break; 18019 case WMI_SCAN_EVENT_BSS_CHANNEL: 18020 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18021 break; 18022 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18023 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18024 break; 18025 case WMI_SCAN_EVENT_DEQUEUED: 18026 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18027 break; 18028 case WMI_SCAN_EVENT_PREEMPTED: 18029 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18030 break; 18031 case WMI_SCAN_EVENT_START_FAILED: 18032 param->type = SCAN_EVENT_TYPE_START_FAILED; 18033 break; 18034 case WMI_SCAN_EVENT_RESTARTED: 18035 param->type = SCAN_EVENT_TYPE_RESTARTED; 18036 break; 18037 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18038 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18039 break; 18040 case WMI_SCAN_EVENT_MAX: 18041 default: 18042 param->type = SCAN_EVENT_TYPE_MAX; 18043 break; 18044 }; 18045 18046 switch (evt->reason) { 18047 case WMI_SCAN_REASON_NONE: 18048 param->reason = SCAN_REASON_NONE; 18049 break; 18050 case WMI_SCAN_REASON_COMPLETED: 18051 param->reason = SCAN_REASON_COMPLETED; 18052 break; 18053 case WMI_SCAN_REASON_CANCELLED: 18054 param->reason = SCAN_REASON_CANCELLED; 18055 break; 18056 case WMI_SCAN_REASON_PREEMPTED: 18057 param->reason = SCAN_REASON_PREEMPTED; 18058 break; 18059 case WMI_SCAN_REASON_TIMEDOUT: 18060 param->reason = SCAN_REASON_TIMEDOUT; 18061 break; 18062 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18063 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18064 break; 18065 case WMI_SCAN_REASON_SUSPENDED: 18066 param->reason = SCAN_REASON_SUSPENDED; 18067 break; 18068 case WMI_SCAN_REASON_MAX: 18069 param->reason = SCAN_REASON_MAX; 18070 break; 18071 default: 18072 param->reason = SCAN_REASON_MAX; 18073 break; 18074 }; 18075 18076 param->chan_freq = evt->channel_freq; 18077 param->requester = evt->requestor; 18078 param->scan_id = evt->scan_id; 18079 param->vdev_id = evt->vdev_id; 18080 param->timestamp = evt->tsf_timestamp; 18081 18082 return QDF_STATUS_SUCCESS; 18083 } 18084 18085 #ifdef CONVERGED_TDLS_ENABLE 18086 /** 18087 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18088 * @wmi_handle: wmi handle 18089 * @param evt_buf: pointer to event buffer 18090 * @param param: Pointer to hold vdev tdls param 18091 * 18092 * Return: QDF_STATUS_SUCCESS for success or error code 18093 */ 18094 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18095 void *evt_buf, struct tdls_event_info *param) 18096 { 18097 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18098 wmi_tdls_peer_event_fixed_param *evt; 18099 18100 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18101 if (!param_buf) { 18102 WMI_LOGE("%s: NULL param_buf", __func__); 18103 return QDF_STATUS_E_NULL_VALUE; 18104 } 18105 18106 evt = param_buf->fixed_param; 18107 18108 qdf_mem_zero(param, sizeof(*param)); 18109 18110 param->vdev_id = evt->vdev_id; 18111 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18112 param->peermac.bytes); 18113 switch (evt->peer_status) { 18114 case WMI_TDLS_SHOULD_DISCOVER: 18115 param->message_type = TDLS_SHOULD_DISCOVER; 18116 break; 18117 case WMI_TDLS_SHOULD_TEARDOWN: 18118 param->message_type = TDLS_SHOULD_TEARDOWN; 18119 break; 18120 case WMI_TDLS_PEER_DISCONNECTED: 18121 param->message_type = TDLS_PEER_DISCONNECTED; 18122 break; 18123 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18124 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18125 break; 18126 default: 18127 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18128 __func__, evt->peer_status); 18129 return QDF_STATUS_E_INVAL; 18130 }; 18131 18132 switch (evt->peer_reason) { 18133 case WMI_TDLS_TEARDOWN_REASON_TX: 18134 param->peer_reason = TDLS_TEARDOWN_TX; 18135 break; 18136 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18137 param->peer_reason = TDLS_TEARDOWN_RSSI; 18138 break; 18139 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18140 param->peer_reason = TDLS_TEARDOWN_SCAN; 18141 break; 18142 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18143 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18144 break; 18145 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18146 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18147 break; 18148 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18149 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18150 break; 18151 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18152 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18153 break; 18154 case WMI_TDLS_ENTER_BUF_STA: 18155 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18156 break; 18157 case WMI_TDLS_EXIT_BUF_STA: 18158 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18159 break; 18160 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18161 param->peer_reason = TDLS_ENTER_BT_BUSY; 18162 break; 18163 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18164 param->peer_reason = TDLS_EXIT_BT_BUSY; 18165 break; 18166 case WMI_TDLS_SCAN_STARTED_EVENT: 18167 param->peer_reason = TDLS_SCAN_STARTED; 18168 break; 18169 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18170 param->peer_reason = TDLS_SCAN_COMPLETED; 18171 break; 18172 18173 default: 18174 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18175 __func__, evt->peer_reason, evt->peer_status); 18176 return QDF_STATUS_E_INVAL; 18177 }; 18178 18179 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18180 __func__, param->peermac.bytes, param->message_type, 18181 param->peer_reason, param->vdev_id); 18182 18183 return QDF_STATUS_SUCCESS; 18184 } 18185 #endif 18186 18187 /** 18188 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18189 * @wmi_handle: wmi handle 18190 * @param evt_buf: pointer to event buffer 18191 * @param param: Pointer to hold MGMT TX completion params 18192 * 18193 * Return: QDF_STATUS_SUCCESS for success or error code 18194 */ 18195 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18196 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18197 { 18198 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18199 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18200 18201 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18202 evt_buf; 18203 if (!param_buf) { 18204 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18205 return QDF_STATUS_E_INVAL; 18206 } 18207 cmpl_params = param_buf->fixed_param; 18208 18209 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18210 cmpl_params->pdev_id); 18211 param->desc_id = cmpl_params->desc_id; 18212 param->status = cmpl_params->status; 18213 param->ppdu_id = cmpl_params->ppdu_id; 18214 18215 return QDF_STATUS_SUCCESS; 18216 } 18217 18218 /** 18219 * extract_offchan_data_tx_compl_param_tlv() - 18220 * extract Offchan data tx completion event params 18221 * @wmi_handle: wmi handle 18222 * @param evt_buf: pointer to event buffer 18223 * @param param: Pointer to hold offchan data TX completion params 18224 * 18225 * Return: QDF_STATUS_SUCCESS for success or error code 18226 */ 18227 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18228 wmi_unified_t wmi_handle, void *evt_buf, 18229 struct wmi_host_offchan_data_tx_compl_event *param) 18230 { 18231 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18232 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18233 18234 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18235 evt_buf; 18236 if (!param_buf) { 18237 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18238 return QDF_STATUS_E_INVAL; 18239 } 18240 cmpl_params = param_buf->fixed_param; 18241 18242 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18243 cmpl_params->pdev_id); 18244 param->desc_id = cmpl_params->desc_id; 18245 param->status = cmpl_params->status; 18246 18247 return QDF_STATUS_SUCCESS; 18248 } 18249 18250 /** 18251 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18252 * status tlv 18253 * @wmi_handle: wmi handle 18254 * @param evt_buf: pointer to event buffer 18255 * @param param: Pointer to hold csa switch count status event param 18256 * 18257 * Return: QDF_STATUS_SUCCESS for success or error code 18258 */ 18259 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18260 wmi_unified_t wmi_handle, 18261 void *evt_buf, 18262 struct pdev_csa_switch_count_status *param) 18263 { 18264 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18265 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18266 18267 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18268 evt_buf; 18269 if (!param_buf) { 18270 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18271 return QDF_STATUS_E_INVAL; 18272 } 18273 18274 csa_status = param_buf->fixed_param; 18275 18276 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18277 csa_status->pdev_id); 18278 param->current_switch_count = csa_status->current_switch_count; 18279 param->num_vdevs = csa_status->num_vdevs; 18280 param->vdev_ids = param_buf->vdev_ids; 18281 18282 return QDF_STATUS_SUCCESS; 18283 } 18284 18285 /** 18286 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18287 * param from event 18288 * @wmi_handle: wmi handle 18289 * @param evt_buf: pointer to event buffer 18290 * @param param: Pointer to hold tpc configuration 18291 * 18292 * Return: 0 for success or error code 18293 */ 18294 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18295 void *evt_buf, 18296 wmi_host_pdev_tpc_config_event *param) 18297 { 18298 wmi_pdev_tpc_config_event_fixed_param *event = 18299 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18300 18301 if (!event) { 18302 WMI_LOGE("Invalid event buffer"); 18303 return QDF_STATUS_E_INVAL; 18304 } 18305 18306 param->pdev_id = event->pdev_id; 18307 param->regDomain = event->regDomain; 18308 param->chanFreq = event->chanFreq; 18309 param->phyMode = event->phyMode; 18310 param->twiceAntennaReduction = event->twiceAntennaReduction; 18311 param->twiceAntennaGain = event->twiceAntennaGain; 18312 param->twiceMaxRDPower = event->twiceMaxRDPower; 18313 param->powerLimit = event->powerLimit; 18314 param->rateMax = event->rateMax; 18315 param->numTxChain = event->numTxChain; 18316 param->ctl = event->ctl; 18317 param->flags = event->flags; 18318 18319 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18320 sizeof(param->maxRegAllowedPower)); 18321 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18322 event->maxRegAllowedPowerAGCDD, 18323 sizeof(param->maxRegAllowedPowerAGCDD)); 18324 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18325 event->maxRegAllowedPowerAGSTBC, 18326 sizeof(param->maxRegAllowedPowerAGSTBC)); 18327 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18328 event->maxRegAllowedPowerAGTXBF, 18329 sizeof(param->maxRegAllowedPowerAGTXBF)); 18330 WMI_LOGD("%s:extract success", __func__); 18331 18332 return QDF_STATUS_SUCCESS; 18333 } 18334 18335 /** 18336 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18337 * @wmi_handle: wmi handle 18338 * @param evt_buf: pointer to event buffer 18339 * @param num_vdevs: Pointer to hold num vdevs 18340 * 18341 * Return: QDF_STATUS_SUCCESS for success or error code 18342 */ 18343 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18344 void *evt_buf, uint32_t *num_vdevs) 18345 { 18346 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18347 wmi_host_swba_event_fixed_param *swba_event; 18348 uint32_t vdev_map; 18349 18350 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18351 if (!param_buf) { 18352 WMI_LOGE("Invalid swba event buffer"); 18353 return QDF_STATUS_E_INVAL; 18354 } 18355 18356 swba_event = param_buf->fixed_param; 18357 *num_vdevs = swba_event->num_vdevs; 18358 if (!(*num_vdevs)) { 18359 vdev_map = swba_event->vdev_map; 18360 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18361 } 18362 18363 return QDF_STATUS_SUCCESS; 18364 } 18365 18366 /** 18367 * extract_swba_tim_info_tlv() - extract swba tim info from event 18368 * @wmi_handle: wmi handle 18369 * @param evt_buf: pointer to event buffer 18370 * @param idx: Index to bcn info 18371 * @param tim_info: Pointer to hold tim info 18372 * 18373 * Return: QDF_STATUS_SUCCESS for success or error code 18374 */ 18375 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18376 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18377 { 18378 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18379 wmi_tim_info *tim_info_ev; 18380 18381 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18382 if (!param_buf) { 18383 WMI_LOGE("Invalid swba event buffer"); 18384 return QDF_STATUS_E_INVAL; 18385 } 18386 18387 tim_info_ev = ¶m_buf->tim_info[idx]; 18388 18389 tim_info->tim_len = tim_info_ev->tim_len; 18390 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18391 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18392 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18393 tim_info->tim_changed = tim_info_ev->tim_changed; 18394 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18395 tim_info->vdev_id = tim_info_ev->vdev_id; 18396 18397 return QDF_STATUS_SUCCESS; 18398 } 18399 18400 /** 18401 * extract_swba_noa_info_tlv() - extract swba NoA information from event 18402 * @wmi_handle: wmi handle 18403 * @param evt_buf: pointer to event buffer 18404 * @param idx: Index to bcn info 18405 * @param p2p_desc: Pointer to hold p2p NoA info 18406 * 18407 * Return: QDF_STATUS_SUCCESS for success or error code 18408 */ 18409 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 18410 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 18411 { 18412 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18413 wmi_p2p_noa_info *p2p_noa_info; 18414 uint8_t i = 0; 18415 18416 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18417 if (!param_buf) { 18418 WMI_LOGE("Invalid swba event buffer"); 18419 return QDF_STATUS_E_INVAL; 18420 } 18421 18422 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 18423 18424 p2p_desc->modified = false; 18425 p2p_desc->num_descriptors = 0; 18426 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 18427 p2p_desc->modified = true; 18428 p2p_desc->index = 18429 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 18430 p2p_desc->oppPS = 18431 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 18432 p2p_desc->ctwindow = 18433 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 18434 p2p_desc->num_descriptors = 18435 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 18436 (p2p_noa_info); 18437 for (i = 0; i < p2p_desc->num_descriptors; i++) { 18438 p2p_desc->noa_descriptors[i].type_count = 18439 (uint8_t) p2p_noa_info->noa_descriptors[i]. 18440 type_count; 18441 p2p_desc->noa_descriptors[i].duration = 18442 p2p_noa_info->noa_descriptors[i].duration; 18443 p2p_desc->noa_descriptors[i].interval = 18444 p2p_noa_info->noa_descriptors[i].interval; 18445 p2p_desc->noa_descriptors[i].start_time = 18446 p2p_noa_info->noa_descriptors[i].start_time; 18447 } 18448 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 18449 } 18450 18451 return QDF_STATUS_SUCCESS; 18452 } 18453 18454 #ifdef CONVERGED_P2P_ENABLE 18455 /** 18456 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 18457 * @wmi_handle: wmi handle 18458 * @param evt_buf: pointer to event buffer 18459 * @param param: Pointer to hold p2p noa info 18460 * 18461 * Return: QDF_STATUS_SUCCESS for success or error code 18462 */ 18463 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 18464 wmi_unified_t wmi_handle, void *evt_buf, 18465 struct p2p_noa_info *param) 18466 { 18467 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 18468 wmi_p2p_noa_event_fixed_param *fixed_param; 18469 uint8_t i; 18470 wmi_p2p_noa_info *wmi_noa_info; 18471 uint8_t *buf_ptr; 18472 uint32_t descriptors; 18473 18474 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 18475 if (!param_tlvs) { 18476 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 18477 return QDF_STATUS_E_INVAL; 18478 } 18479 18480 if (!param) { 18481 WMI_LOGE("noa information param is null"); 18482 return QDF_STATUS_E_INVAL; 18483 } 18484 18485 fixed_param = param_tlvs->fixed_param; 18486 buf_ptr = (uint8_t *) fixed_param; 18487 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 18488 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 18489 18490 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 18491 WMI_LOGE("%s: noa attr is not modified", __func__); 18492 return QDF_STATUS_E_INVAL; 18493 } 18494 18495 param->vdev_id = fixed_param->vdev_id; 18496 param->index = 18497 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 18498 param->opps_ps = 18499 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 18500 param->ct_window = 18501 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 18502 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 18503 param->num_desc = (uint8_t) descriptors; 18504 18505 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 18506 param->index, param->opps_ps, param->ct_window, 18507 param->num_desc); 18508 for (i = 0; i < param->num_desc; i++) { 18509 param->noa_desc[i].type_count = 18510 (uint8_t) wmi_noa_info->noa_descriptors[i]. 18511 type_count; 18512 param->noa_desc[i].duration = 18513 wmi_noa_info->noa_descriptors[i].duration; 18514 param->noa_desc[i].interval = 18515 wmi_noa_info->noa_descriptors[i].interval; 18516 param->noa_desc[i].start_time = 18517 wmi_noa_info->noa_descriptors[i].start_time; 18518 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 18519 __func__, i, param->noa_desc[i].type_count, 18520 param->noa_desc[i].duration, 18521 param->noa_desc[i].interval, 18522 param->noa_desc[i].start_time); 18523 } 18524 18525 return QDF_STATUS_SUCCESS; 18526 } 18527 18528 /** 18529 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 18530 * information from event 18531 * @wmi_handle: wmi handle 18532 * @param evt_buf: pointer to event buffer 18533 * @param param: Pointer to hold p2p lo stop event information 18534 * 18535 * Return: QDF_STATUS_SUCCESS for success or error code 18536 */ 18537 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 18538 wmi_unified_t wmi_handle, void *evt_buf, 18539 struct p2p_lo_event *param) 18540 { 18541 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 18542 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 18543 18544 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 18545 evt_buf; 18546 if (!param_tlvs) { 18547 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 18548 return QDF_STATUS_E_INVAL; 18549 } 18550 18551 if (!param) { 18552 WMI_LOGE("lo stop event param is null"); 18553 return QDF_STATUS_E_INVAL; 18554 } 18555 18556 lo_param = param_tlvs->fixed_param; 18557 param->vdev_id = lo_param->vdev_id; 18558 param->reason_code = lo_param->reason; 18559 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 18560 param->vdev_id, param->reason_code); 18561 18562 return QDF_STATUS_SUCCESS; 18563 } 18564 #endif /* End of CONVERGED_P2P_ENABLE */ 18565 18566 /** 18567 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 18568 * @wmi_handle: wmi handle 18569 * @param evt_buf: pointer to event buffer 18570 * @param ev: Pointer to hold peer param 18571 * 18572 * Return: QDF_STATUS_SUCCESS for success or error code 18573 */ 18574 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 18575 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 18576 { 18577 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 18578 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 18579 18580 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 18581 kickout_event = param_buf->fixed_param; 18582 18583 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 18584 ev->peer_macaddr); 18585 18586 ev->reason = kickout_event->reason; 18587 ev->rssi = kickout_event->rssi; 18588 18589 return QDF_STATUS_SUCCESS; 18590 } 18591 18592 /** 18593 * extract_all_stats_counts_tlv() - extract all stats count from event 18594 * @wmi_handle: wmi handle 18595 * @param evt_buf: pointer to event buffer 18596 * @param stats_param: Pointer to hold stats count 18597 * 18598 * Return: QDF_STATUS_SUCCESS for success or error code 18599 */ 18600 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 18601 void *evt_buf, wmi_host_stats_event *stats_param) 18602 { 18603 wmi_stats_event_fixed_param *ev; 18604 wmi_per_chain_rssi_stats *rssi_event; 18605 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18606 18607 qdf_mem_zero(stats_param, sizeof(*stats_param)); 18608 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18609 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18610 rssi_event = param_buf->chain_stats; 18611 if (!ev) { 18612 WMI_LOGE("%s: event fixed param NULL\n", __func__); 18613 return QDF_STATUS_E_FAILURE; 18614 } 18615 18616 switch (ev->stats_id) { 18617 case WMI_REQUEST_PEER_STAT: 18618 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 18619 break; 18620 18621 case WMI_REQUEST_AP_STAT: 18622 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 18623 break; 18624 18625 case WMI_REQUEST_PDEV_STAT: 18626 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 18627 break; 18628 18629 case WMI_REQUEST_VDEV_STAT: 18630 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 18631 break; 18632 18633 case WMI_REQUEST_BCNFLT_STAT: 18634 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 18635 break; 18636 18637 case WMI_REQUEST_VDEV_RATE_STAT: 18638 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 18639 break; 18640 18641 case WMI_REQUEST_BCN_STAT: 18642 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 18643 break; 18644 18645 default: 18646 stats_param->stats_id = 0; 18647 break; 18648 18649 } 18650 18651 stats_param->num_pdev_stats = ev->num_pdev_stats; 18652 stats_param->num_pdev_ext_stats = 0; 18653 stats_param->num_vdev_stats = ev->num_vdev_stats; 18654 stats_param->num_peer_stats = ev->num_peer_stats; 18655 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 18656 stats_param->num_chan_stats = ev->num_chan_stats; 18657 stats_param->num_bcn_stats = ev->num_bcn_stats; 18658 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18659 ev->pdev_id); 18660 18661 /* if chain_stats is not populated */ 18662 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 18663 return QDF_STATUS_SUCCESS; 18664 18665 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 18666 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 18667 return QDF_STATUS_SUCCESS; 18668 18669 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 18670 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 18671 return QDF_STATUS_SUCCESS; 18672 18673 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 18674 18675 return QDF_STATUS_SUCCESS; 18676 } 18677 18678 /** 18679 * extract_pdev_tx_stats() - extract pdev tx stats from event 18680 */ 18681 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 18682 { 18683 /* Tx Stats */ 18684 tx->comp_queued = tx_stats->comp_queued; 18685 tx->comp_delivered = tx_stats->comp_delivered; 18686 tx->msdu_enqued = tx_stats->msdu_enqued; 18687 tx->mpdu_enqued = tx_stats->mpdu_enqued; 18688 tx->wmm_drop = tx_stats->wmm_drop; 18689 tx->local_enqued = tx_stats->local_enqued; 18690 tx->local_freed = tx_stats->local_freed; 18691 tx->hw_queued = tx_stats->hw_queued; 18692 tx->hw_reaped = tx_stats->hw_reaped; 18693 tx->underrun = tx_stats->underrun; 18694 tx->tx_abort = tx_stats->tx_abort; 18695 tx->mpdus_requed = tx_stats->mpdus_requed; 18696 tx->data_rc = tx_stats->data_rc; 18697 tx->self_triggers = tx_stats->self_triggers; 18698 tx->sw_retry_failure = tx_stats->sw_retry_failure; 18699 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 18700 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 18701 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 18702 tx->pdev_resets = tx_stats->pdev_resets; 18703 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 18704 tx->phy_underrun = tx_stats->phy_underrun; 18705 tx->txop_ovf = tx_stats->txop_ovf; 18706 18707 return; 18708 } 18709 18710 18711 /** 18712 * extract_pdev_rx_stats() - extract pdev rx stats from event 18713 */ 18714 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 18715 { 18716 /* Rx Stats */ 18717 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 18718 rx->status_rcvd = rx_stats->status_rcvd; 18719 rx->r0_frags = rx_stats->r0_frags; 18720 rx->r1_frags = rx_stats->r1_frags; 18721 rx->r2_frags = rx_stats->r2_frags; 18722 /* Only TLV */ 18723 rx->r3_frags = 0; 18724 rx->htt_msdus = rx_stats->htt_msdus; 18725 rx->htt_mpdus = rx_stats->htt_mpdus; 18726 rx->loc_msdus = rx_stats->loc_msdus; 18727 rx->loc_mpdus = rx_stats->loc_mpdus; 18728 rx->oversize_amsdu = rx_stats->oversize_amsdu; 18729 rx->phy_errs = rx_stats->phy_errs; 18730 rx->phy_err_drop = rx_stats->phy_err_drop; 18731 rx->mpdu_errs = rx_stats->mpdu_errs; 18732 18733 return; 18734 } 18735 18736 /** 18737 * extract_pdev_stats_tlv() - extract pdev stats from event 18738 * @wmi_handle: wmi handle 18739 * @param evt_buf: pointer to event buffer 18740 * @param index: Index into pdev stats 18741 * @param pdev_stats: Pointer to hold pdev stats 18742 * 18743 * Return: QDF_STATUS_SUCCESS for success or error code 18744 */ 18745 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 18746 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 18747 { 18748 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18749 wmi_stats_event_fixed_param *ev_param; 18750 uint8_t *data; 18751 18752 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18753 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18754 18755 data = param_buf->data; 18756 18757 if (index < ev_param->num_pdev_stats) { 18758 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 18759 (index * sizeof(wmi_pdev_stats))); 18760 18761 pdev_stats->chan_nf = ev->chan_nf; 18762 pdev_stats->tx_frame_count = ev->tx_frame_count; 18763 pdev_stats->rx_frame_count = ev->rx_frame_count; 18764 pdev_stats->rx_clear_count = ev->rx_clear_count; 18765 pdev_stats->cycle_count = ev->cycle_count; 18766 pdev_stats->phy_err_count = ev->phy_err_count; 18767 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 18768 18769 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 18770 &(ev->pdev_stats.tx)); 18771 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 18772 &(ev->pdev_stats.rx)); 18773 } 18774 18775 return QDF_STATUS_SUCCESS; 18776 } 18777 18778 /** 18779 * extract_unit_test_tlv() - extract unit test data 18780 * @wmi_handle: wmi handle 18781 * @param evt_buf: pointer to event buffer 18782 * @param unit_test: pointer to hold unit test data 18783 * @param maxspace: Amount of space in evt_buf 18784 * 18785 * Return: QDF_STATUS_SUCCESS for success or error code 18786 */ 18787 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 18788 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 18789 { 18790 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 18791 wmi_unit_test_event_fixed_param *ev_param; 18792 uint32_t num_bufp; 18793 uint32_t copy_size; 18794 uint8_t *bufp; 18795 18796 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 18797 ev_param = param_buf->fixed_param; 18798 bufp = param_buf->bufp; 18799 num_bufp = param_buf->num_bufp; 18800 unit_test->vdev_id = ev_param->vdev_id; 18801 unit_test->module_id = ev_param->module_id; 18802 unit_test->diag_token = ev_param->diag_token; 18803 unit_test->flag = ev_param->flag; 18804 unit_test->payload_len = ev_param->payload_len; 18805 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 18806 ev_param->vdev_id, 18807 ev_param->module_id, 18808 ev_param->diag_token, 18809 ev_param->flag); 18810 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 18811 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 18812 bufp, num_bufp); 18813 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 18814 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 18815 unit_test->buffer_len = copy_size; 18816 18817 return QDF_STATUS_SUCCESS; 18818 } 18819 18820 /** 18821 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 18822 * @wmi_handle: wmi handle 18823 * @param evt_buf: pointer to event buffer 18824 * @param index: Index into extended pdev stats 18825 * @param pdev_ext_stats: Pointer to hold extended pdev stats 18826 * 18827 * Return: QDF_STATUS_SUCCESS for success or error code 18828 */ 18829 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 18830 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 18831 { 18832 return QDF_STATUS_SUCCESS; 18833 } 18834 18835 /** 18836 * extract_vdev_stats_tlv() - extract vdev stats from event 18837 * @wmi_handle: wmi handle 18838 * @param evt_buf: pointer to event buffer 18839 * @param index: Index into vdev stats 18840 * @param vdev_stats: Pointer to hold vdev stats 18841 * 18842 * Return: QDF_STATUS_SUCCESS for success or error code 18843 */ 18844 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 18845 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 18846 { 18847 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18848 wmi_stats_event_fixed_param *ev_param; 18849 uint8_t *data; 18850 18851 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18852 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18853 data = (uint8_t *) param_buf->data; 18854 18855 if (index < ev_param->num_vdev_stats) { 18856 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 18857 ((ev_param->num_pdev_stats) * 18858 sizeof(wmi_pdev_stats)) + 18859 (index * sizeof(wmi_vdev_stats))); 18860 18861 vdev_stats->vdev_id = ev->vdev_id; 18862 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 18863 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 18864 18865 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 18866 sizeof(ev->tx_frm_cnt)); 18867 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 18868 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 18869 ev->multiple_retry_cnt, 18870 sizeof(ev->multiple_retry_cnt)); 18871 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 18872 sizeof(ev->fail_cnt)); 18873 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 18874 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 18875 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 18876 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 18877 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 18878 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 18879 sizeof(ev->tx_rate_history)); 18880 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 18881 sizeof(ev->bcn_rssi_history)); 18882 18883 } 18884 18885 return QDF_STATUS_SUCCESS; 18886 } 18887 18888 /** 18889 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 18890 * buffer 18891 * @wmi_handle: wmi handle 18892 * @evt_buf: pointer to event buffer 18893 * @index: Index into vdev stats 18894 * @rssi_stats: Pointer to hold rssi stats 18895 * 18896 * Return: QDF_STATUS_SUCCESS for success or error code 18897 */ 18898 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 18899 void *evt_buf, uint32_t index, 18900 struct wmi_host_per_chain_rssi_stats *rssi_stats) 18901 { 18902 uint8_t *data; 18903 wmi_rssi_stats *fw_rssi_stats; 18904 wmi_per_chain_rssi_stats *rssi_event; 18905 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18906 18907 if (!evt_buf) { 18908 WMI_LOGE("evt_buf is null"); 18909 return QDF_STATUS_E_NULL_VALUE; 18910 } 18911 18912 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18913 rssi_event = param_buf->chain_stats; 18914 18915 if (index >= rssi_event->num_per_chain_rssi_stats) { 18916 WMI_LOGE("invalid index"); 18917 return QDF_STATUS_E_INVAL; 18918 } 18919 18920 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 18921 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 18922 18923 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 18924 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 18925 fw_rssi_stats->rssi_avg_beacon, 18926 sizeof(fw_rssi_stats->rssi_avg_beacon)); 18927 qdf_mem_copy(rssi_stats->rssi_avg_data, 18928 fw_rssi_stats->rssi_avg_data, 18929 sizeof(fw_rssi_stats->rssi_avg_data)); 18930 qdf_mem_copy(&rssi_stats->peer_macaddr, 18931 &fw_rssi_stats->peer_macaddr, 18932 sizeof(fw_rssi_stats->peer_macaddr)); 18933 18934 return QDF_STATUS_SUCCESS; 18935 } 18936 18937 18938 18939 /** 18940 * extract_bcn_stats_tlv() - extract bcn stats from event 18941 * @wmi_handle: wmi handle 18942 * @param evt_buf: pointer to event buffer 18943 * @param index: Index into vdev stats 18944 * @param bcn_stats: Pointer to hold bcn stats 18945 * 18946 * Return: QDF_STATUS_SUCCESS for success or error code 18947 */ 18948 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 18949 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 18950 { 18951 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18952 wmi_stats_event_fixed_param *ev_param; 18953 uint8_t *data; 18954 18955 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18956 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18957 data = (uint8_t *) param_buf->data; 18958 18959 if (index < ev_param->num_bcn_stats) { 18960 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 18961 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18962 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 18963 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 18964 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 18965 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 18966 (index * sizeof(wmi_bcn_stats))); 18967 18968 bcn_stats->vdev_id = ev->vdev_id; 18969 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 18970 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 18971 } 18972 18973 return QDF_STATUS_SUCCESS; 18974 } 18975 18976 /** 18977 * extract_peer_stats_tlv() - extract peer stats from event 18978 * @wmi_handle: wmi handle 18979 * @param evt_buf: pointer to event buffer 18980 * @param index: Index into peer stats 18981 * @param peer_stats: Pointer to hold peer stats 18982 * 18983 * Return: QDF_STATUS_SUCCESS for success or error code 18984 */ 18985 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 18986 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 18987 { 18988 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18989 wmi_stats_event_fixed_param *ev_param; 18990 uint8_t *data; 18991 18992 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18993 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 18994 data = (uint8_t *) param_buf->data; 18995 18996 if (index < ev_param->num_peer_stats) { 18997 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 18998 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 18999 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19000 (index * sizeof(wmi_peer_stats))); 19001 19002 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19003 19004 OS_MEMCPY(&(peer_stats->peer_macaddr), 19005 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19006 19007 peer_stats->peer_rssi = ev->peer_rssi; 19008 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19009 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19010 } 19011 19012 return QDF_STATUS_SUCCESS; 19013 } 19014 19015 /** 19016 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19017 * @wmi_handle: wmi handle 19018 * @param evt_buf: pointer to event buffer 19019 * @param index: Index into bcn fault stats 19020 * @param bcnflt_stats: Pointer to hold bcn fault stats 19021 * 19022 * Return: QDF_STATUS_SUCCESS for success or error code 19023 */ 19024 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19025 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19026 { 19027 return QDF_STATUS_SUCCESS; 19028 } 19029 19030 /** 19031 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19032 * @wmi_handle: wmi handle 19033 * @param evt_buf: pointer to event buffer 19034 * @param index: Index into extended peer stats 19035 * @param peer_extd_stats: Pointer to hold extended peer stats 19036 * 19037 * Return: QDF_STATUS_SUCCESS for success or error code 19038 */ 19039 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19040 void *evt_buf, uint32_t index, 19041 wmi_host_peer_extd_stats *peer_extd_stats) 19042 { 19043 return QDF_STATUS_SUCCESS; 19044 } 19045 19046 /** 19047 * extract_chan_stats_tlv() - extract chan stats from event 19048 * @wmi_handle: wmi handle 19049 * @param evt_buf: pointer to event buffer 19050 * @param index: Index into chan stats 19051 * @param vdev_extd_stats: Pointer to hold chan stats 19052 * 19053 * Return: QDF_STATUS_SUCCESS for success or error code 19054 */ 19055 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19056 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19057 { 19058 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19059 wmi_stats_event_fixed_param *ev_param; 19060 uint8_t *data; 19061 19062 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19063 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19064 data = (uint8_t *) param_buf->data; 19065 19066 if (index < ev_param->num_chan_stats) { 19067 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19068 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19069 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19070 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19071 (index * sizeof(wmi_chan_stats))); 19072 19073 19074 /* Non-TLV doesn't have num_chan_stats */ 19075 chan_stats->chan_mhz = ev->chan_mhz; 19076 chan_stats->sampling_period_us = ev->sampling_period_us; 19077 chan_stats->rx_clear_count = ev->rx_clear_count; 19078 chan_stats->tx_duration_us = ev->tx_duration_us; 19079 chan_stats->rx_duration_us = ev->rx_duration_us; 19080 } 19081 19082 return QDF_STATUS_SUCCESS; 19083 } 19084 19085 /** 19086 * extract_profile_ctx_tlv() - extract profile context from event 19087 * @wmi_handle: wmi handle 19088 * @param evt_buf: pointer to event buffer 19089 * @idx: profile stats index to extract 19090 * @param profile_ctx: Pointer to hold profile context 19091 * 19092 * Return: QDF_STATUS_SUCCESS for success or error code 19093 */ 19094 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19095 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19096 { 19097 return QDF_STATUS_SUCCESS; 19098 } 19099 19100 /** 19101 * extract_profile_data_tlv() - extract profile data from event 19102 * @wmi_handle: wmi handle 19103 * @param evt_buf: pointer to event buffer 19104 * @param profile_data: Pointer to hold profile data 19105 * 19106 * Return: QDF_STATUS_SUCCESS for success or error code 19107 */ 19108 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19109 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19110 { 19111 19112 return QDF_STATUS_SUCCESS; 19113 } 19114 19115 /** 19116 * extract_chan_info_event_tlv() - extract chan information from event 19117 * @wmi_handle: wmi handle 19118 * @param evt_buf: pointer to event buffer 19119 * @param chan_info: Pointer to hold chan information 19120 * 19121 * Return: QDF_STATUS_SUCCESS for success or error code 19122 */ 19123 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19124 void *evt_buf, wmi_host_chan_info_event *chan_info) 19125 { 19126 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19127 wmi_chan_info_event_fixed_param *ev; 19128 19129 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19130 19131 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19132 if (!ev) { 19133 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19134 return QDF_STATUS_E_FAILURE; 19135 } 19136 19137 chan_info->err_code = ev->err_code; 19138 chan_info->freq = ev->freq; 19139 chan_info->cmd_flags = ev->cmd_flags; 19140 chan_info->noise_floor = ev->noise_floor; 19141 chan_info->rx_clear_count = ev->rx_clear_count; 19142 chan_info->cycle_count = ev->cycle_count; 19143 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19144 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19145 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19146 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19147 ev->vdev_id, WLAN_SCAN_ID); 19148 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19149 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19150 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19151 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19152 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19153 chan_info->rx_frame_count = ev->rx_frame_count; 19154 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19155 chan_info->vdev_id = ev->vdev_id; 19156 19157 return QDF_STATUS_SUCCESS; 19158 } 19159 19160 /** 19161 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19162 * @wmi_handle: WMI handle 19163 * @param evt_buf: Pointer to event buffer 19164 * @param param: Pointer to hold data 19165 * 19166 * Return : QDF_STATUS_SUCCESS for success or error code 19167 */ 19168 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19169 uint8_t *evt_buf, 19170 struct wmi_host_pdev_utf_event *event) 19171 { 19172 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19173 struct wmi_host_utf_seg_header_info *seg_hdr; 19174 19175 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19176 event->data = param_buf->data; 19177 event->datalen = param_buf->num_data; 19178 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19179 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19180 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19181 seg_hdr->pdev_id); 19182 19183 return QDF_STATUS_SUCCESS; 19184 } 19185 19186 /** 19187 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19188 * @wmi_handle: wmi handle 19189 * @param evt_buf: pointer to event buffer 19190 * @param param: Pointer to hold evt buf 19191 * 19192 * Return: QDF_STATUS_SUCCESS for success or error code 19193 */ 19194 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19195 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19196 { 19197 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19198 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19199 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19200 uint8_t i = 0, j = 0; 19201 19202 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19203 if (!param_buf) 19204 return QDF_STATUS_E_INVAL; 19205 19206 hw_caps = param_buf->soc_hw_mode_caps; 19207 if (!hw_caps) 19208 return QDF_STATUS_E_INVAL; 19209 19210 if (!hw_caps->num_chainmask_tables) 19211 return QDF_STATUS_E_INVAL; 19212 19213 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19214 19215 if (chainmask_caps == NULL) 19216 return QDF_STATUS_E_INVAL; 19217 19218 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19219 19220 qdf_print("Dumping chain mask combo data for table : %d", i); 19221 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19222 19223 chainmask_table[i].cap_list[j].chainmask = 19224 chainmask_caps->chainmask; 19225 19226 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19227 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19228 19229 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19230 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19231 19232 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19233 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19234 19235 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19236 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19237 19238 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19239 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19240 19241 chainmask_table[i].cap_list[j].chain_mask_2G = 19242 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19243 19244 chainmask_table[i].cap_list[j].chain_mask_5G = 19245 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19246 19247 chainmask_table[i].cap_list[j].chain_mask_tx = 19248 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19249 19250 chainmask_table[i].cap_list[j].chain_mask_rx = 19251 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19252 19253 chainmask_table[i].cap_list[j].supports_aDFS = 19254 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19255 19256 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x", 19257 chainmask_caps->supported_flags, 19258 chainmask_caps->chainmask 19259 ); 19260 chainmask_caps++; 19261 } 19262 } 19263 19264 return QDF_STATUS_SUCCESS; 19265 } 19266 19267 /** 19268 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19269 * from event 19270 * @wmi_handle: wmi handle 19271 * @param evt_buf: pointer to event buffer 19272 * @param param: Pointer to hold evt buf 19273 * 19274 * Return: QDF_STATUS_SUCCESS for success or error code 19275 */ 19276 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19277 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19278 { 19279 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19280 wmi_service_ready_ext_event_fixed_param *ev; 19281 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19282 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19283 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19284 uint8_t i = 0; 19285 19286 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19287 if (!param_buf) 19288 return QDF_STATUS_E_INVAL; 19289 19290 ev = param_buf->fixed_param; 19291 if (!ev) 19292 return QDF_STATUS_E_INVAL; 19293 19294 /* Move this to host based bitmap */ 19295 param->default_conc_scan_config_bits = 19296 ev->default_conc_scan_config_bits; 19297 param->default_fw_config_bits = ev->default_fw_config_bits; 19298 param->he_cap_info = ev->he_cap_info; 19299 param->mpdu_density = ev->mpdu_density; 19300 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19301 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19302 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19303 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19304 19305 hw_caps = param_buf->soc_hw_mode_caps; 19306 if (hw_caps) 19307 param->num_hw_modes = hw_caps->num_hw_modes; 19308 else 19309 param->num_hw_modes = 0; 19310 19311 reg_caps = param_buf->soc_hal_reg_caps; 19312 if (reg_caps) 19313 param->num_phy = reg_caps->num_phy; 19314 else 19315 param->num_phy = 0; 19316 19317 if (hw_caps) { 19318 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19319 qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables); 19320 } else 19321 param->num_chainmask_tables = 0; 19322 19323 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19324 19325 if (chain_mask_combo == NULL) 19326 return QDF_STATUS_SUCCESS; 19327 19328 qdf_print("Dumping chain mask combo data"); 19329 19330 for (i = 0; i < param->num_chainmask_tables; i++) { 19331 19332 qdf_print("table_id : %d Num valid chainmasks: %d", 19333 chain_mask_combo->chainmask_table_id, 19334 chain_mask_combo->num_valid_chainmask 19335 ); 19336 19337 param->chainmask_table[i].table_id = 19338 chain_mask_combo->chainmask_table_id; 19339 param->chainmask_table[i].num_valid_chainmasks = 19340 chain_mask_combo->num_valid_chainmask; 19341 chain_mask_combo++; 19342 } 19343 qdf_print("chain mask combo end"); 19344 19345 return QDF_STATUS_SUCCESS; 19346 } 19347 19348 /** 19349 * extract_sar_cap_service_ready_ext_tlv() - 19350 * extract SAR cap from service ready event 19351 * @wmi_handle: wmi handle 19352 * @event: pointer to event buffer 19353 * @ext_param: extended target info 19354 * 19355 * Return: QDF_STATUS_SUCCESS for success or error code 19356 */ 19357 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 19358 wmi_unified_t wmi_handle, 19359 uint8_t *event, 19360 struct wlan_psoc_host_service_ext_param *ext_param) 19361 { 19362 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19363 WMI_SAR_CAPABILITIES *sar_caps; 19364 19365 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19366 19367 if (!param_buf) 19368 return QDF_STATUS_E_INVAL; 19369 19370 sar_caps = param_buf->sar_caps; 19371 if (sar_caps) 19372 ext_param->sar_version = sar_caps->active_version; 19373 else 19374 ext_param->sar_version = 0; 19375 19376 return QDF_STATUS_SUCCESS; 19377 } 19378 19379 /** 19380 * extract_hw_mode_cap_service_ready_ext_tlv() - 19381 * extract HW mode cap from service ready event 19382 * @wmi_handle: wmi handle 19383 * @param evt_buf: pointer to event buffer 19384 * @param param: Pointer to hold evt buf 19385 * @param hw_mode_idx: hw mode idx should be less than num_mode 19386 * 19387 * Return: QDF_STATUS_SUCCESS for success or error code 19388 */ 19389 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19390 wmi_unified_t wmi_handle, 19391 uint8_t *event, uint8_t hw_mode_idx, 19392 struct wlan_psoc_host_hw_mode_caps *param) 19393 { 19394 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19395 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19396 19397 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19398 if (!param_buf) 19399 return QDF_STATUS_E_INVAL; 19400 19401 hw_caps = param_buf->soc_hw_mode_caps; 19402 if (!hw_caps) 19403 return QDF_STATUS_E_INVAL; 19404 19405 if (hw_mode_idx >= hw_caps->num_hw_modes) 19406 return QDF_STATUS_E_INVAL; 19407 19408 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19409 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19410 19411 param->hw_mode_config_type = 19412 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19413 19414 return QDF_STATUS_SUCCESS; 19415 } 19416 19417 /** 19418 * extract_mac_phy_cap_service_ready_ext_tlv() - 19419 * extract MAC phy cap from service ready event 19420 * @wmi_handle: wmi handle 19421 * @param evt_buf: pointer to event buffer 19422 * @param param: Pointer to hold evt buf 19423 * @param hw_mode_idx: hw mode idx should be less than num_mode 19424 * @param phy_id: phy id within hw_mode 19425 * 19426 * Return: QDF_STATUS_SUCCESS for success or error code 19427 */ 19428 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19429 wmi_unified_t wmi_handle, 19430 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19431 struct wlan_psoc_host_mac_phy_caps *param) 19432 { 19433 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19434 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19435 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19436 uint32_t phy_map; 19437 uint8_t hw_idx, phy_idx = 0; 19438 19439 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19440 if (!param_buf) 19441 return QDF_STATUS_E_INVAL; 19442 19443 hw_caps = param_buf->soc_hw_mode_caps; 19444 if (!hw_caps) 19445 return QDF_STATUS_E_INVAL; 19446 19447 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19448 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19449 break; 19450 19451 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19452 while (phy_map) { 19453 phy_map >>= 1; 19454 phy_idx++; 19455 } 19456 } 19457 19458 if (hw_idx == hw_caps->num_hw_modes) 19459 return QDF_STATUS_E_INVAL; 19460 19461 phy_idx += phy_id; 19462 if (phy_idx >= param_buf->num_mac_phy_caps) 19463 return QDF_STATUS_E_INVAL; 19464 19465 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19466 19467 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19468 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19469 mac_phy_caps->pdev_id); 19470 param->phy_id = mac_phy_caps->phy_id; 19471 param->supports_11b = 19472 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19473 param->supports_11g = 19474 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19475 param->supports_11a = 19476 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19477 param->supports_11n = 19478 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19479 param->supports_11ac = 19480 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19481 param->supports_11ax = 19482 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19483 19484 param->supported_bands = mac_phy_caps->supported_bands; 19485 param->ampdu_density = mac_phy_caps->ampdu_density; 19486 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19487 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19488 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19489 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19490 param->he_cap_info_2G = mac_phy_caps->he_cap_info_2G; 19491 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19492 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19493 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19494 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19495 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19496 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19497 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19498 param->he_cap_info_5G = mac_phy_caps->he_cap_info_5G; 19499 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 19500 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 19501 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 19502 qdf_mem_copy(¶m->he_cap_phy_info_2G, 19503 &mac_phy_caps->he_cap_phy_info_2G, 19504 sizeof(param->he_cap_phy_info_2G)); 19505 qdf_mem_copy(¶m->he_cap_phy_info_5G, 19506 &mac_phy_caps->he_cap_phy_info_5G, 19507 sizeof(param->he_cap_phy_info_5G)); 19508 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 19509 sizeof(param->he_ppet2G)); 19510 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 19511 sizeof(param->he_ppet5G)); 19512 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 19513 19514 return QDF_STATUS_SUCCESS; 19515 } 19516 19517 /** 19518 * extract_reg_cap_service_ready_ext_tlv() - 19519 * extract REG cap from service ready event 19520 * @wmi_handle: wmi handle 19521 * @param evt_buf: pointer to event buffer 19522 * @param param: Pointer to hold evt buf 19523 * @param phy_idx: phy idx should be less than num_mode 19524 * 19525 * Return: QDF_STATUS_SUCCESS for success or error code 19526 */ 19527 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 19528 wmi_unified_t wmi_handle, 19529 uint8_t *event, uint8_t phy_idx, 19530 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 19531 { 19532 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19533 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19534 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 19535 19536 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19537 if (!param_buf) 19538 return QDF_STATUS_E_INVAL; 19539 19540 reg_caps = param_buf->soc_hal_reg_caps; 19541 if (!reg_caps) 19542 return QDF_STATUS_E_INVAL; 19543 19544 if (phy_idx >= reg_caps->num_phy) 19545 return QDF_STATUS_E_INVAL; 19546 19547 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 19548 19549 param->phy_id = ext_reg_cap->phy_id; 19550 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 19551 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 19552 param->regcap1 = ext_reg_cap->regcap1; 19553 param->regcap2 = ext_reg_cap->regcap2; 19554 param->wireless_modes = convert_wireless_modes_tlv( 19555 ext_reg_cap->wireless_modes); 19556 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 19557 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 19558 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 19559 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 19560 19561 return QDF_STATUS_SUCCESS; 19562 } 19563 19564 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 19565 wmi_unified_t wmi_handle, 19566 uint8_t *event, uint8_t idx, 19567 struct wlan_psoc_host_dbr_ring_caps *param) 19568 { 19569 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19570 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 19571 19572 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19573 if (!param_buf) 19574 return QDF_STATUS_E_INVAL; 19575 19576 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 19577 19578 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19579 dbr_ring_caps->pdev_id); 19580 param->mod_id = dbr_ring_caps->mod_id; 19581 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 19582 param->min_buf_size = dbr_ring_caps->min_buf_size; 19583 param->min_buf_align = dbr_ring_caps->min_buf_align; 19584 19585 return QDF_STATUS_SUCCESS; 19586 } 19587 19588 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 19589 uint8_t *event, struct direct_buf_rx_rsp *param) 19590 { 19591 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19592 wmi_dma_buf_release_fixed_param *ev; 19593 19594 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19595 if (!param_buf) 19596 return QDF_STATUS_E_INVAL; 19597 19598 ev = param_buf->fixed_param; 19599 if (!ev) 19600 return QDF_STATUS_E_INVAL; 19601 19602 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19603 ev->pdev_id); 19604 param->mod_id = ev->mod_id; 19605 param->num_buf_release_entry = ev->num_buf_release_entry; 19606 param->num_meta_data_entry = ev->num_meta_data_entry; 19607 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 19608 param->pdev_id, param->mod_id, param->num_buf_release_entry); 19609 19610 return QDF_STATUS_SUCCESS; 19611 } 19612 19613 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 19614 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 19615 { 19616 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19617 wmi_dma_buf_release_entry *entry; 19618 19619 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19620 if (!param_buf) 19621 return QDF_STATUS_E_INVAL; 19622 19623 entry = ¶m_buf->entries[idx]; 19624 19625 if (!entry) { 19626 WMI_LOGE("%s: Entry is NULL\n", __func__); 19627 return QDF_STATUS_E_FAILURE; 19628 } 19629 19630 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 19631 19632 param->paddr_lo = entry->paddr_lo; 19633 param->paddr_hi = entry->paddr_hi; 19634 19635 return QDF_STATUS_SUCCESS; 19636 } 19637 19638 static QDF_STATUS extract_dbr_buf_metadata_tlv( 19639 wmi_unified_t wmi_handle, uint8_t *event, 19640 uint8_t idx, struct direct_buf_rx_metadata *param) 19641 { 19642 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 19643 wmi_dma_buf_release_spectral_meta_data *entry; 19644 19645 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 19646 if (!param_buf) 19647 return QDF_STATUS_E_INVAL; 19648 19649 entry = ¶m_buf->meta_data[idx]; 19650 19651 if (!entry) { 19652 WMI_LOGE("%s: Entry is NULL\n", __func__); 19653 return QDF_STATUS_E_FAILURE; 19654 } 19655 19656 qdf_mem_copy(param->noisefloor, entry->noise_floor, 19657 sizeof(entry->noise_floor)); 19658 return QDF_STATUS_SUCCESS; 19659 } 19660 19661 /** 19662 * extract_dcs_interference_type_tlv() - extract dcs interference type 19663 * from event 19664 * @wmi_handle: wmi handle 19665 * @param evt_buf: pointer to event buffer 19666 * @param param: Pointer to hold dcs interference param 19667 * 19668 * Return: 0 for success or error code 19669 */ 19670 static QDF_STATUS extract_dcs_interference_type_tlv( 19671 wmi_unified_t wmi_handle, 19672 void *evt_buf, struct wmi_host_dcs_interference_param *param) 19673 { 19674 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19675 19676 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19677 if (!param_buf) 19678 return QDF_STATUS_E_INVAL; 19679 19680 param->interference_type = param_buf->fixed_param->interference_type; 19681 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19682 param_buf->fixed_param->pdev_id); 19683 19684 return QDF_STATUS_SUCCESS; 19685 } 19686 19687 /* 19688 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 19689 * @wmi_handle: wmi handle 19690 * @param evt_buf: pointer to event buffer 19691 * @param cw_int: Pointer to hold cw interference 19692 * 19693 * Return: 0 for success or error code 19694 */ 19695 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 19696 void *evt_buf, 19697 wmi_host_ath_dcs_cw_int *cw_int) 19698 { 19699 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19700 wlan_dcs_cw_int *ev; 19701 19702 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19703 if (!param_buf) 19704 return QDF_STATUS_E_INVAL; 19705 19706 ev = param_buf->cw_int; 19707 19708 cw_int->channel = ev->channel; 19709 19710 return QDF_STATUS_SUCCESS; 19711 } 19712 19713 /** 19714 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 19715 * @wmi_handle: wmi handle 19716 * @param evt_buf: pointer to event buffer 19717 * @param wlan_stat: Pointer to hold wlan stats 19718 * 19719 * Return: 0 for success or error code 19720 */ 19721 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 19722 void *evt_buf, 19723 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 19724 { 19725 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 19726 wlan_dcs_im_tgt_stats_t *ev; 19727 19728 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 19729 if (!param_buf) 19730 return QDF_STATUS_E_INVAL; 19731 19732 ev = param_buf->wlan_stat; 19733 wlan_stat->reg_tsf32 = ev->reg_tsf32; 19734 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 19735 wlan_stat->tx_waste_time = ev->tx_waste_time; 19736 wlan_stat->rx_time = ev->rx_time; 19737 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 19738 wlan_stat->mib_stats.listen_time = ev->listen_time; 19739 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 19740 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 19741 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 19742 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 19743 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 19744 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 19745 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 19746 wlan_stat->chan_nf = ev->chan_nf; 19747 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19748 19749 return QDF_STATUS_SUCCESS; 19750 } 19751 19752 /** 19753 * extract_thermal_stats_tlv() - extract thermal stats from event 19754 * @wmi_handle: wmi handle 19755 * @param evt_buf: Pointer to event buffer 19756 * @param temp: Pointer to hold extracted temperature 19757 * @param level: Pointer to hold extracted level 19758 * 19759 * Return: 0 for success or error code 19760 */ 19761 static QDF_STATUS 19762 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 19763 void *evt_buf, uint32_t *temp, 19764 uint32_t *level, uint32_t *pdev_id) 19765 { 19766 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19767 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 19768 19769 param_buf = 19770 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19771 if (!param_buf) 19772 return QDF_STATUS_E_INVAL; 19773 19774 tt_stats_event = param_buf->fixed_param; 19775 19776 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19777 tt_stats_event->pdev_id); 19778 *temp = tt_stats_event->temp; 19779 *level = tt_stats_event->level; 19780 19781 return QDF_STATUS_SUCCESS; 19782 } 19783 19784 /** 19785 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 19786 * @wmi_handle: wmi handle 19787 * @param evt_buf: pointer to event buffer 19788 * @param idx: Index to level stats 19789 * @param levelcount: Pointer to hold levelcount 19790 * @param dccount: Pointer to hold dccount 19791 * 19792 * Return: 0 for success or error code 19793 */ 19794 static QDF_STATUS 19795 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 19796 void *evt_buf, uint8_t idx, uint32_t *levelcount, 19797 uint32_t *dccount) 19798 { 19799 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 19800 wmi_therm_throt_level_stats_info *tt_level_info; 19801 19802 param_buf = 19803 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 19804 if (!param_buf) 19805 return QDF_STATUS_E_INVAL; 19806 19807 tt_level_info = param_buf->therm_throt_level_stats_info; 19808 19809 if (idx < THERMAL_LEVELS) { 19810 *levelcount = tt_level_info[idx].level_count; 19811 *dccount = tt_level_info[idx].dc_count; 19812 return QDF_STATUS_SUCCESS; 19813 } 19814 19815 return QDF_STATUS_E_FAILURE; 19816 } 19817 #ifdef BIG_ENDIAN_HOST 19818 /** 19819 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 19820 * @param data_len - data length 19821 * @param data - pointer to data 19822 * 19823 * Return: QDF_STATUS - success or error status 19824 */ 19825 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19826 { 19827 uint8_t *data_aligned = NULL; 19828 int c; 19829 unsigned char *data_unaligned; 19830 19831 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 19832 FIPS_ALIGN)); 19833 /* Assigning unaligned space to copy the data */ 19834 /* Checking if kmalloc does successful allocation */ 19835 if (data_unaligned == NULL) 19836 return QDF_STATUS_E_FAILURE; 19837 19838 /* Checking if space is alligned */ 19839 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 19840 /* align the data space */ 19841 data_aligned = 19842 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 19843 } else { 19844 data_aligned = (u_int8_t *)data_unaligned; 19845 } 19846 19847 /* memset and copy content from data to data aligned */ 19848 OS_MEMSET(data_aligned, 0, data_len); 19849 OS_MEMCPY(data_aligned, data, data_len); 19850 /* Endianness to LE */ 19851 for (c = 0; c < data_len/4; c++) { 19852 *((u_int32_t *)data_aligned + c) = 19853 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 19854 } 19855 19856 /* Copy content to event->data */ 19857 OS_MEMCPY(data, data_aligned, data_len); 19858 19859 /* clean up allocated space */ 19860 qdf_mem_free(data_unaligned); 19861 data_aligned = NULL; 19862 data_unaligned = NULL; 19863 19864 /*************************************************************/ 19865 19866 return QDF_STATUS_SUCCESS; 19867 } 19868 #else 19869 /** 19870 * fips_conv_data_be() - DUMMY for LE platform 19871 * 19872 * Return: QDF_STATUS - success 19873 */ 19874 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 19875 { 19876 return QDF_STATUS_SUCCESS; 19877 } 19878 #endif 19879 19880 /** 19881 * extract_fips_event_data_tlv() - extract fips event data 19882 * @wmi_handle: wmi handle 19883 * @param evt_buf: pointer to event buffer 19884 * @param param: pointer FIPS event params 19885 * 19886 * Return: 0 for success or error code 19887 */ 19888 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 19889 void *evt_buf, struct wmi_host_fips_event_param *param) 19890 { 19891 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 19892 wmi_pdev_fips_event_fixed_param *event; 19893 19894 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 19895 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 19896 19897 if (fips_conv_data_be(event->data_len, param_buf->data) != 19898 QDF_STATUS_SUCCESS) 19899 return QDF_STATUS_E_FAILURE; 19900 19901 param->data = (uint32_t *)param_buf->data; 19902 param->data_len = event->data_len; 19903 param->error_status = event->error_status; 19904 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19905 event->pdev_id); 19906 19907 return QDF_STATUS_SUCCESS; 19908 } 19909 19910 /* 19911 * extract_peer_delete_response_event_tlv() - extract peer delete response event 19912 * @wmi_handle: wmi handle 19913 * @param evt_buf: pointer to event buffer 19914 * @param vdev_id: Pointer to hold vdev_id 19915 * @param mac_addr: Pointer to hold peer mac address 19916 * 19917 * Return: QDF_STATUS_SUCCESS for success or error code 19918 */ 19919 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 19920 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 19921 { 19922 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 19923 wmi_peer_delete_resp_event_fixed_param *ev; 19924 19925 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 19926 19927 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 19928 if (!ev) { 19929 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 19930 return QDF_STATUS_E_FAILURE; 19931 } 19932 19933 param->vdev_id = ev->vdev_id; 19934 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 19935 ¶m->mac_address.bytes[0]); 19936 19937 return QDF_STATUS_SUCCESS; 19938 } 19939 19940 static bool is_management_record_tlv(uint32_t cmd_id) 19941 { 19942 if ((cmd_id == WMI_MGMT_TX_COMPLETION_EVENTID) || 19943 (cmd_id == WMI_MGMT_TX_SEND_CMDID) || 19944 (cmd_id == WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 19945 return true; 19946 } 19947 19948 return false; 19949 } 19950 19951 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19952 { 19953 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 19954 19955 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 19956 19957 switch (set_cmd->param_id) { 19958 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 19959 case WMI_VDEV_PARAM_DTIM_POLICY: 19960 return HTC_TX_PACKET_TAG_AUTO_PM; 19961 default: 19962 break; 19963 } 19964 19965 return 0; 19966 } 19967 19968 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 19969 { 19970 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 19971 19972 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 19973 19974 switch (ps_cmd->param) { 19975 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 19976 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 19977 case WMI_STA_PS_ENABLE_QPOWER: 19978 return HTC_TX_PACKET_TAG_AUTO_PM; 19979 default: 19980 break; 19981 } 19982 19983 return 0; 19984 } 19985 19986 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 19987 uint32_t cmd_id) 19988 { 19989 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 19990 return 0; 19991 19992 switch (cmd_id) { 19993 case WMI_VDEV_SET_PARAM_CMDID: 19994 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 19995 case WMI_STA_POWERSAVE_PARAM_CMDID: 19996 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 19997 default: 19998 break; 19999 } 20000 20001 return 0; 20002 } 20003 20004 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20005 { 20006 uint16_t tag = 0; 20007 20008 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20009 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20010 __func__); 20011 return tag; 20012 } 20013 20014 if (wmi_handle->tag_crash_inject) 20015 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20016 20017 wmi_handle->tag_crash_inject = false; 20018 return tag; 20019 } 20020 20021 /** 20022 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20023 * @wmi_handle: WMI handle 20024 * @buf: WMI buffer 20025 * @cmd_id: WMI command Id 20026 * 20027 * Return htc_tx_tag 20028 */ 20029 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20030 wmi_buf_t buf, 20031 uint32_t cmd_id) 20032 { 20033 uint16_t htc_tx_tag = 0; 20034 20035 switch (cmd_id) { 20036 case WMI_WOW_ENABLE_CMDID: 20037 case WMI_PDEV_SUSPEND_CMDID: 20038 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20039 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20040 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20041 case WMI_PDEV_RESUME_CMDID: 20042 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20043 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20044 #ifdef FEATURE_WLAN_D0WOW 20045 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20046 #endif 20047 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20048 break; 20049 case WMI_FORCE_FW_HANG_CMDID: 20050 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20051 break; 20052 case WMI_VDEV_SET_PARAM_CMDID: 20053 case WMI_STA_POWERSAVE_PARAM_CMDID: 20054 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20055 default: 20056 break; 20057 } 20058 20059 return htc_tx_tag; 20060 } 20061 20062 /** 20063 * extract_channel_hopping_event_tlv() - extract channel hopping param 20064 * from event 20065 * @wmi_handle: wmi handle 20066 * @param evt_buf: pointer to event buffer 20067 * @param ch_hopping: Pointer to hold channel hopping param 20068 * 20069 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20070 */ 20071 static QDF_STATUS extract_channel_hopping_event_tlv( 20072 wmi_unified_t wmi_handle, void *evt_buf, 20073 wmi_host_pdev_channel_hopping_event *ch_hopping) 20074 { 20075 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20076 wmi_pdev_channel_hopping_event_fixed_param *event; 20077 20078 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20079 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20080 param_buf->fixed_param; 20081 20082 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20083 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20084 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20085 event->pdev_id); 20086 20087 return QDF_STATUS_SUCCESS; 20088 } 20089 20090 /** 20091 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20092 * @wmi_handle: wmi handle 20093 * @param evt_buf: pointer to event buffer 20094 * @param param: Pointer to hold tpc param 20095 * 20096 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20097 */ 20098 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20099 void *evt_buf, 20100 wmi_host_pdev_tpc_event *param) 20101 { 20102 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20103 wmi_pdev_tpc_event_fixed_param *event; 20104 20105 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20106 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20107 20108 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20109 event->pdev_id); 20110 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20111 20112 return QDF_STATUS_SUCCESS; 20113 } 20114 20115 /** 20116 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20117 * power param from event 20118 * @wmi_handle: wmi handle 20119 * @param evt_buf: pointer to event buffer 20120 * @param param: Pointer to hold nf cal power param 20121 * 20122 * Return: 0 for success or error code 20123 */ 20124 static QDF_STATUS 20125 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20126 void *evt_buf, 20127 wmi_host_pdev_nfcal_power_all_channels_event *param) 20128 { 20129 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20130 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20131 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20132 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20133 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20134 uint32_t i; 20135 20136 param_buf = 20137 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20138 event = param_buf->fixed_param; 20139 ch_nfdbr = param_buf->nfdbr; 20140 ch_nfdbm = param_buf->nfdbm; 20141 ch_freqnum = param_buf->freqnum; 20142 20143 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20144 event->pdev_id, param_buf->num_nfdbr, 20145 param_buf->num_nfdbm, param_buf->num_freqnum); 20146 20147 if (param_buf->num_nfdbr > 20148 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20149 WMI_LOGE("invalid number of nfdBr"); 20150 return QDF_STATUS_E_FAILURE; 20151 } 20152 20153 if (param_buf->num_nfdbm > 20154 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20155 WMI_LOGE("invalid number of nfdBm"); 20156 return QDF_STATUS_E_FAILURE; 20157 } 20158 20159 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20160 WMI_LOGE("invalid number of freqNum"); 20161 return QDF_STATUS_E_FAILURE; 20162 } 20163 20164 for (i = 0; i < param_buf->num_nfdbr; i++) { 20165 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20166 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20167 ch_nfdbr++; 20168 ch_nfdbm++; 20169 } 20170 20171 for (i = 0; i < param_buf->num_freqnum; i++) { 20172 param->freqnum[i] = ch_freqnum->freqNum; 20173 ch_freqnum++; 20174 } 20175 20176 param->pdev_id = wmi_handle->ops-> 20177 convert_pdev_id_target_to_host(event->pdev_id); 20178 20179 return QDF_STATUS_SUCCESS; 20180 } 20181 20182 20183 #ifdef BIG_ENDIAN_HOST 20184 /** 20185 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20186 * @param data_len - data length 20187 * @param data - pointer to data 20188 * 20189 * Return: QDF_STATUS - success or error status 20190 */ 20191 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20192 { 20193 uint8_t *datap = (uint8_t *)ev; 20194 int i; 20195 /* Skip swapping the first word */ 20196 datap += sizeof(uint32_t); 20197 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20198 i++, datap += sizeof(uint32_t)) { 20199 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20200 } 20201 20202 return QDF_STATUS_SUCCESS; 20203 } 20204 #else 20205 /** 20206 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20207 * @param data_len - data length 20208 * @param data - pointer to data 20209 * 20210 * Return: QDF_STATUS - success or error status 20211 */ 20212 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20213 { 20214 return QDF_STATUS_SUCCESS; 20215 } 20216 #endif 20217 20218 /** 20219 * extract_wds_addr_event_tlv() - extract wds address from event 20220 * @wmi_handle: wmi handle 20221 * @param evt_buf: pointer to event buffer 20222 * @param wds_ev: Pointer to hold wds address 20223 * 20224 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20225 */ 20226 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20227 void *evt_buf, 20228 uint16_t len, wds_addr_event_t *wds_ev) 20229 { 20230 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20231 wmi_wds_addr_event_fixed_param *ev; 20232 int i; 20233 20234 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20235 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20236 20237 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20238 return QDF_STATUS_E_FAILURE; 20239 20240 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20241 sizeof(wds_ev->event_type)); 20242 for (i = 0; i < 4; i++) { 20243 wds_ev->peer_mac[i] = 20244 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20245 wds_ev->dest_mac[i] = 20246 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20247 } 20248 for (i = 0; i < 2; i++) { 20249 wds_ev->peer_mac[4+i] = 20250 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20251 wds_ev->dest_mac[4+i] = 20252 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20253 } 20254 return QDF_STATUS_SUCCESS; 20255 } 20256 20257 /** 20258 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20259 * from event 20260 * @wmi_handle: wmi handle 20261 * @param evt_buf: pointer to event buffer 20262 * @param ev: Pointer to hold peer param and ps state 20263 * 20264 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20265 */ 20266 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20267 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20268 { 20269 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20270 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20271 20272 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20273 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20274 param_buf->fixed_param; 20275 20276 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20277 ev->peer_ps_state = event->peer_ps_state; 20278 20279 return QDF_STATUS_SUCCESS; 20280 } 20281 20282 /** 20283 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20284 * @wmi_handle: wmi handle 20285 * @param evt_buf: pointer to event buffer 20286 * @param inst_rssi_resp: Pointer to hold inst rssi response 20287 * 20288 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20289 */ 20290 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20291 wmi_unified_t wmi_handle, void *evt_buf, 20292 wmi_host_inst_stats_resp *inst_rssi_resp) 20293 { 20294 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20295 wmi_inst_rssi_stats_resp_fixed_param *event; 20296 20297 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20298 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20299 20300 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20301 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20302 inst_rssi_resp->iRSSI = event->iRSSI; 20303 20304 return QDF_STATUS_SUCCESS; 20305 } 20306 20307 static struct cur_reg_rule 20308 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20309 wmi_regulatory_rule_struct *wmi_reg_rule) 20310 { 20311 struct cur_reg_rule *reg_rule_ptr; 20312 uint32_t count; 20313 20314 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20315 20316 if (NULL == reg_rule_ptr) { 20317 WMI_LOGE("memory allocation failure"); 20318 return NULL; 20319 } 20320 20321 for (count = 0; count < num_reg_rules; count++) { 20322 reg_rule_ptr[count].start_freq = 20323 WMI_REG_RULE_START_FREQ_GET( 20324 wmi_reg_rule[count].freq_info); 20325 reg_rule_ptr[count].end_freq = 20326 WMI_REG_RULE_END_FREQ_GET( 20327 wmi_reg_rule[count].freq_info); 20328 reg_rule_ptr[count].max_bw = 20329 WMI_REG_RULE_MAX_BW_GET( 20330 wmi_reg_rule[count].bw_pwr_info); 20331 reg_rule_ptr[count].reg_power = 20332 WMI_REG_RULE_REG_POWER_GET( 20333 wmi_reg_rule[count].bw_pwr_info); 20334 reg_rule_ptr[count].ant_gain = 20335 WMI_REG_RULE_ANTENNA_GAIN_GET( 20336 wmi_reg_rule[count].bw_pwr_info); 20337 reg_rule_ptr[count].flags = 20338 WMI_REG_RULE_FLAGS_GET( 20339 wmi_reg_rule[count].flag_info); 20340 } 20341 20342 return reg_rule_ptr; 20343 } 20344 20345 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20346 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20347 struct cur_regulatory_info *reg_info, uint32_t len) 20348 { 20349 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20350 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20351 wmi_regulatory_rule_struct *wmi_reg_rule; 20352 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20353 20354 WMI_LOGD("processing regulatory channel list"); 20355 20356 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20357 if (!param_buf) { 20358 WMI_LOGE("invalid channel list event buf"); 20359 return QDF_STATUS_E_FAILURE; 20360 } 20361 20362 chan_list_event_hdr = param_buf->fixed_param; 20363 20364 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20365 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20366 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20367 REG_ALPHA2_LEN); 20368 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20369 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20370 reg_info->offload_enabled = true; 20371 reg_info->num_phy = chan_list_event_hdr->num_phy; 20372 reg_info->phy_id = chan_list_event_hdr->phy_id; 20373 reg_info->ctry_code = chan_list_event_hdr->country_id; 20374 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20375 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20376 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20377 else if (chan_list_event_hdr->status_code == 20378 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20379 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20380 else if (chan_list_event_hdr->status_code == 20381 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20382 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20383 else if (chan_list_event_hdr->status_code == 20384 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20385 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20386 else if (chan_list_event_hdr->status_code == 20387 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20388 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20389 else if (chan_list_event_hdr->status_code == 20390 WMI_REG_SET_CC_STATUS_FAIL) 20391 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20392 20393 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20394 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20395 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20396 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20397 20398 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20399 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20400 20401 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20402 __func__, reg_info->alpha2, reg_info->dfs_region, 20403 reg_info->min_bw_2g, reg_info->max_bw_2g, 20404 reg_info->min_bw_5g, reg_info->max_bw_5g); 20405 20406 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20407 num_2g_reg_rules, num_5g_reg_rules); 20408 wmi_reg_rule = 20409 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20410 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20411 + WMI_TLV_HDR_SIZE); 20412 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20413 wmi_reg_rule); 20414 wmi_reg_rule += num_2g_reg_rules; 20415 20416 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20417 wmi_reg_rule); 20418 20419 WMI_LOGD("processed regulatory channel list"); 20420 20421 return QDF_STATUS_SUCCESS; 20422 } 20423 20424 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20425 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20426 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20427 { 20428 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20429 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20430 20431 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20432 if (!param_buf) { 20433 WMI_LOGE("invalid 11d country event buf"); 20434 return QDF_STATUS_E_FAILURE; 20435 } 20436 20437 reg_11d_country_event = param_buf->fixed_param; 20438 20439 qdf_mem_copy(reg_11d_country->alpha2, 20440 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20441 20442 WMI_LOGD("processed 11d country event, new cc %s", 20443 reg_11d_country->alpha2); 20444 20445 return QDF_STATUS_SUCCESS; 20446 } 20447 20448 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20449 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20450 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20451 { 20452 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20453 wmi_avoid_freq_range_desc *afr_desc; 20454 uint32_t num_freq_ranges, freq_range_idx; 20455 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20456 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20457 20458 if (!param_buf) { 20459 WMI_LOGE("Invalid channel avoid event buffer"); 20460 return QDF_STATUS_E_INVAL; 20461 } 20462 20463 afr_fixed_param = param_buf->fixed_param; 20464 if (!afr_fixed_param) { 20465 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20466 return QDF_STATUS_E_INVAL; 20467 } 20468 20469 if (!ch_avoid_ind) { 20470 WMI_LOGE("Invalid channel avoid indication buffer"); 20471 return QDF_STATUS_E_INVAL; 20472 } 20473 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20474 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20475 afr_fixed_param->num_freq_ranges; 20476 20477 WMI_LOGD("Channel avoid event received with %d ranges", 20478 num_freq_ranges); 20479 20480 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20481 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20482 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20483 freq_range_idx++) { 20484 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20485 afr_desc->start_freq; 20486 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20487 afr_desc->end_freq; 20488 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20489 freq_range_idx, afr_desc->tlv_header, 20490 afr_desc->start_freq, afr_desc->end_freq); 20491 afr_desc++; 20492 } 20493 20494 return QDF_STATUS_SUCCESS; 20495 } 20496 #ifdef DFS_COMPONENT_ENABLE 20497 /** 20498 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20499 * @wmi_handle: wma handle 20500 * @evt_buf: event buffer 20501 * @vdev_id: vdev id 20502 * @len: length of buffer 20503 * 20504 * Return: 0 for success or error code 20505 */ 20506 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20507 uint8_t *evt_buf, 20508 uint32_t *vdev_id, 20509 uint32_t len) 20510 { 20511 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20512 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20513 20514 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20515 if (!param_tlvs) { 20516 WMI_LOGE("invalid cac complete event buf"); 20517 return QDF_STATUS_E_FAILURE; 20518 } 20519 20520 cac_event = param_tlvs->fixed_param; 20521 *vdev_id = cac_event->vdev_id; 20522 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20523 20524 return QDF_STATUS_SUCCESS; 20525 } 20526 20527 /** 20528 * extract_dfs_radar_detection_event_tlv() - extract radar found event 20529 * @wmi_handle: wma handle 20530 * @evt_buf: event buffer 20531 * @radar_found: radar found event info 20532 * @len: length of buffer 20533 * 20534 * Return: 0 for success or error code 20535 */ 20536 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 20537 wmi_unified_t wmi_handle, 20538 uint8_t *evt_buf, 20539 struct radar_found_info *radar_found, 20540 uint32_t len) 20541 { 20542 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 20543 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 20544 20545 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 20546 if (!param_tlv) { 20547 WMI_LOGE("invalid radar detection event buf"); 20548 return QDF_STATUS_E_FAILURE; 20549 } 20550 20551 radar_event = param_tlv->fixed_param; 20552 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 20553 radar_event->pdev_id); 20554 radar_found->detection_mode = radar_event->detection_mode; 20555 radar_found->chan_freq = radar_event->chan_freq; 20556 radar_found->chan_width = radar_event->chan_width; 20557 radar_found->detector_id = radar_event->detector_id; 20558 radar_found->segment_id = radar_event->segment_id; 20559 radar_found->timestamp = radar_event->timestamp; 20560 radar_found->is_chirp = radar_event->is_chirp; 20561 radar_found->freq_offset = radar_event->freq_offset; 20562 radar_found->sidx = radar_event->sidx; 20563 20564 WMI_LOGI("processed radar found event pdev %d," 20565 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 20566 "chan_width (RSSI) %d,detector_id (false_radar) %d," 20567 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 20568 "is_chirp %d,detection mode %d\n", 20569 radar_event->pdev_id, radar_found->pdev_id, 20570 radar_event->timestamp, radar_event->chan_freq, 20571 radar_event->chan_width, radar_event->detector_id, 20572 radar_event->freq_offset, radar_event->segment_id, 20573 radar_event->sidx, radar_event->is_chirp, 20574 radar_event->detection_mode); 20575 20576 return QDF_STATUS_SUCCESS; 20577 } 20578 20579 #ifdef QCA_MCL_DFS_SUPPORT 20580 /** 20581 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 20582 * @wmi_handle: wma handle 20583 * @evt_buf: event buffer 20584 * @wlan_radar_event: Pointer to struct radar_event_info 20585 * @len: length of buffer 20586 * 20587 * Return: QDF_STATUS 20588 */ 20589 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20590 wmi_unified_t wmi_handle, 20591 uint8_t *evt_buf, 20592 struct radar_event_info *wlan_radar_event, 20593 uint32_t len) 20594 { 20595 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 20596 wmi_dfs_radar_event_fixed_param *radar_event; 20597 20598 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 20599 if (!param_tlv) { 20600 WMI_LOGE("invalid wlan radar event buf"); 20601 return QDF_STATUS_E_FAILURE; 20602 } 20603 20604 radar_event = param_tlv->fixed_param; 20605 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 20606 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 20607 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 20608 wlan_radar_event->rssi = radar_event->rssi; 20609 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 20610 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 20611 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 20612 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 20613 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 20614 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 20615 if (radar_event->pulse_flags & 20616 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 20617 wlan_radar_event->is_psidx_diff_valid = true; 20618 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 20619 } else { 20620 wlan_radar_event->is_psidx_diff_valid = false; 20621 } 20622 20623 wlan_radar_event->pdev_id = radar_event->pdev_id; 20624 20625 return QDF_STATUS_SUCCESS; 20626 } 20627 #else 20628 static QDF_STATUS extract_wlan_radar_event_info_tlv( 20629 wmi_unified_t wmi_handle, 20630 uint8_t *evt_buf, 20631 struct radar_event_info *wlan_radar_event, 20632 uint32_t len) 20633 { 20634 return QDF_STATUS_SUCCESS; 20635 } 20636 #endif 20637 #endif 20638 20639 /** 20640 * send_get_rcpi_cmd_tlv() - send request for rcpi value 20641 * @wmi_handle: wmi handle 20642 * @get_rcpi_param: rcpi params 20643 * 20644 * Return: QDF status 20645 */ 20646 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 20647 struct rcpi_req *get_rcpi_param) 20648 { 20649 wmi_buf_t buf; 20650 wmi_request_rcpi_cmd_fixed_param *cmd; 20651 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 20652 20653 buf = wmi_buf_alloc(wmi_handle, len); 20654 if (!buf) { 20655 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 20656 return QDF_STATUS_E_NOMEM; 20657 } 20658 20659 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 20660 WMITLV_SET_HDR(&cmd->tlv_header, 20661 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 20662 WMITLV_GET_STRUCT_TLVLEN 20663 (wmi_request_rcpi_cmd_fixed_param)); 20664 20665 cmd->vdev_id = get_rcpi_param->vdev_id; 20666 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 20667 &cmd->peer_macaddr); 20668 20669 switch (get_rcpi_param->measurement_type) { 20670 20671 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20672 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20673 break; 20674 20675 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 20676 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 20677 break; 20678 20679 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20680 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20681 break; 20682 20683 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 20684 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 20685 break; 20686 20687 default: 20688 /* 20689 * invalid rcpi measurement type, fall back to 20690 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 20691 */ 20692 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20693 break; 20694 } 20695 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 20696 if (wmi_unified_cmd_send(wmi_handle, buf, len, 20697 WMI_REQUEST_RCPI_CMDID)) { 20698 20699 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 20700 __func__); 20701 wmi_buf_free(buf); 20702 return QDF_STATUS_E_FAILURE; 20703 } 20704 20705 return QDF_STATUS_SUCCESS; 20706 } 20707 20708 /** 20709 * extract_rcpi_response_event_tlv() - Extract RCPI event params 20710 * @wmi_handle: wmi handle 20711 * @evt_buf: pointer to event buffer 20712 * @res: pointer to hold rcpi response from firmware 20713 * 20714 * Return: QDF_STATUS_SUCCESS for successful event parse 20715 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 20716 */ 20717 static QDF_STATUS 20718 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 20719 void *evt_buf, struct rcpi_res *res) 20720 { 20721 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 20722 wmi_update_rcpi_event_fixed_param *event; 20723 20724 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 20725 if (!param_buf) { 20726 WMI_LOGE(FL("Invalid rcpi event")); 20727 return QDF_STATUS_E_INVAL; 20728 } 20729 20730 event = param_buf->fixed_param; 20731 res->vdev_id = event->vdev_id; 20732 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 20733 20734 switch (event->measurement_type) { 20735 20736 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 20737 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 20738 break; 20739 20740 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 20741 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 20742 break; 20743 20744 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 20745 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 20746 break; 20747 20748 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 20749 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 20750 break; 20751 20752 default: 20753 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 20754 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 20755 return QDF_STATUS_E_FAILURE; 20756 } 20757 20758 if (event->status) 20759 return QDF_STATUS_E_FAILURE; 20760 else 20761 return QDF_STATUS_SUCCESS; 20762 } 20763 20764 /** 20765 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 20766 * host to target defines. For legacy there is not conversion 20767 * required. Just return pdev_id as it is. 20768 * @param pdev_id: host pdev_id to be converted. 20769 * Return: target pdev_id after conversion. 20770 */ 20771 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 20772 uint32_t pdev_id) 20773 { 20774 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 20775 return WMI_PDEV_ID_SOC; 20776 20777 /*No conversion required*/ 20778 return pdev_id; 20779 } 20780 20781 /** 20782 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 20783 * target to host defines. For legacy there is not conversion 20784 * required. Just return pdev_id as it is. 20785 * @param pdev_id: target pdev_id to be converted. 20786 * Return: host pdev_id after conversion. 20787 */ 20788 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 20789 uint32_t pdev_id) 20790 { 20791 /*No conversion required*/ 20792 return pdev_id; 20793 } 20794 20795 /** 20796 * send_set_country_cmd_tlv() - WMI scan channel list function 20797 * @param wmi_handle : handle to WMI. 20798 * @param param : pointer to hold scan channel list parameter 20799 * 20800 * Return: 0 on success and -ve on failure. 20801 */ 20802 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 20803 struct set_country *params) 20804 { 20805 wmi_buf_t buf; 20806 QDF_STATUS qdf_status; 20807 wmi_set_current_country_cmd_fixed_param *cmd; 20808 uint16_t len = sizeof(*cmd); 20809 20810 buf = wmi_buf_alloc(wmi_handle, len); 20811 if (!buf) { 20812 WMI_LOGE("Failed to allocate memory"); 20813 qdf_status = QDF_STATUS_E_NOMEM; 20814 goto end; 20815 } 20816 20817 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 20818 WMITLV_SET_HDR(&cmd->tlv_header, 20819 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 20820 WMITLV_GET_STRUCT_TLVLEN 20821 (wmi_set_current_country_cmd_fixed_param)); 20822 20823 WMI_LOGD("setting cuurnet country to %s", params->country); 20824 20825 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 20826 20827 cmd->pdev_id = params->pdev_id; 20828 20829 qdf_status = wmi_unified_cmd_send(wmi_handle, 20830 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 20831 20832 if (QDF_IS_STATUS_ERROR(qdf_status)) { 20833 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 20834 wmi_buf_free(buf); 20835 } 20836 20837 end: 20838 return qdf_status; 20839 } 20840 20841 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 20842 WMI_SET_BITS(alpha, 0, 8, val0); \ 20843 WMI_SET_BITS(alpha, 8, 8, val1); \ 20844 WMI_SET_BITS(alpha, 16, 8, val2); \ 20845 } while (0) 20846 20847 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 20848 uint8_t pdev_id, struct cc_regdmn_s *rd) 20849 { 20850 wmi_set_init_country_cmd_fixed_param *cmd; 20851 uint16_t len; 20852 wmi_buf_t buf; 20853 int ret; 20854 20855 len = sizeof(wmi_set_init_country_cmd_fixed_param); 20856 buf = wmi_buf_alloc(wmi_handle, len); 20857 if (!buf) { 20858 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 20859 return QDF_STATUS_E_NOMEM; 20860 } 20861 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 20862 WMITLV_SET_HDR(&cmd->tlv_header, 20863 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 20864 WMITLV_GET_STRUCT_TLVLEN 20865 (wmi_set_init_country_cmd_fixed_param)); 20866 20867 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 20868 20869 if (rd->flags == CC_IS_SET) { 20870 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 20871 cmd->country_code.country_id = rd->cc.country_code; 20872 } else if (rd->flags == ALPHA_IS_SET) { 20873 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 20874 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 20875 rd->cc.alpha[0], 20876 rd->cc.alpha[1], 20877 rd->cc.alpha[2]); 20878 } else if (rd->flags == REGDMN_IS_SET) { 20879 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 20880 cmd->country_code.domain_code = rd->cc.regdmn_id; 20881 } 20882 20883 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20884 WMI_SET_INIT_COUNTRY_CMDID); 20885 if (ret) { 20886 WMI_LOGE("Failed to config wow wakeup event"); 20887 wmi_buf_free(buf); 20888 return QDF_STATUS_E_FAILURE; 20889 } 20890 20891 return QDF_STATUS_SUCCESS; 20892 } 20893 20894 /** 20895 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 20896 * configuration params 20897 * @wmi_handle: wmi handler 20898 * @limit_off_chan_param: pointer to wmi_off_chan_param 20899 * 20900 * Return: 0 for success and non zero for failure 20901 */ 20902 static 20903 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 20904 struct wmi_limit_off_chan_param *limit_off_chan_param) 20905 { 20906 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 20907 wmi_buf_t buf; 20908 uint32_t len = sizeof(*cmd); 20909 int err; 20910 20911 buf = wmi_buf_alloc(wmi_handle, len); 20912 if (!buf) { 20913 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 20914 __func__); 20915 return QDF_STATUS_E_NOMEM; 20916 } 20917 20918 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 20919 20920 WMITLV_SET_HDR(&cmd->tlv_header, 20921 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 20922 WMITLV_GET_STRUCT_TLVLEN( 20923 wmi_vdev_limit_offchan_cmd_fixed_param)); 20924 20925 cmd->vdev_id = limit_off_chan_param->vdev_id; 20926 20927 cmd->flags &= 0; 20928 if (limit_off_chan_param->status) 20929 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 20930 if (limit_off_chan_param->skip_dfs_chans) 20931 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 20932 20933 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 20934 cmd->rest_time = limit_off_chan_param->rest_time; 20935 20936 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 20937 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 20938 cmd->rest_time); 20939 20940 err = wmi_unified_cmd_send(wmi_handle, buf, 20941 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 20942 if (QDF_IS_STATUS_ERROR(err)) { 20943 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 20944 wmi_buf_free(buf); 20945 return QDF_STATUS_E_FAILURE; 20946 } 20947 20948 return QDF_STATUS_SUCCESS; 20949 } 20950 20951 /** 20952 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 20953 * @wmi_handle: wmi handler 20954 * @req_buf: set arp stats request buffer 20955 * 20956 * Return: 0 for success and non zero for failure 20957 */ 20958 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 20959 struct set_arp_stats *req_buf) 20960 { 20961 wmi_buf_t buf = NULL; 20962 QDF_STATUS status; 20963 int len; 20964 uint8_t *buf_ptr; 20965 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 20966 20967 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 20968 if (req_buf->pkt_type_bitmap) { 20969 len += WMI_TLV_HDR_SIZE; 20970 len += sizeof(wmi_vdev_set_connectivity_check_stats); 20971 } 20972 buf = wmi_buf_alloc(wmi_handle, len); 20973 if (!buf) { 20974 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 20975 return QDF_STATUS_E_NOMEM; 20976 } 20977 20978 buf_ptr = (uint8_t *) wmi_buf_data(buf); 20979 wmi_set_arp = 20980 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 20981 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 20982 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 20983 WMITLV_GET_STRUCT_TLVLEN 20984 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 20985 20986 /* fill in per roam config values */ 20987 wmi_set_arp->vdev_id = req_buf->vdev_id; 20988 20989 wmi_set_arp->set_clr = req_buf->flag; 20990 wmi_set_arp->pkt_type = req_buf->pkt_type; 20991 wmi_set_arp->ipv4 = req_buf->ip_addr; 20992 20993 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 20994 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 20995 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 20996 20997 /* 20998 * pkt_type_bitmap should be non-zero to ensure 20999 * presence of additional stats. 21000 */ 21001 if (req_buf->pkt_type_bitmap) { 21002 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21003 21004 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21005 WMITLV_SET_HDR(buf_ptr, 21006 WMITLV_TAG_ARRAY_STRUC, 21007 sizeof(wmi_vdev_set_connectivity_check_stats)); 21008 buf_ptr += WMI_TLV_HDR_SIZE; 21009 wmi_set_connect_stats = 21010 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21011 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21012 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21013 WMITLV_GET_STRUCT_TLVLEN( 21014 wmi_vdev_set_connectivity_check_stats)); 21015 wmi_set_connect_stats->pkt_type_bitmap = 21016 req_buf->pkt_type_bitmap; 21017 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21018 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21019 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21020 21021 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21022 wmi_set_connect_stats->pkt_type_bitmap, 21023 wmi_set_connect_stats->tcp_src_port, 21024 wmi_set_connect_stats->tcp_dst_port, 21025 wmi_set_connect_stats->icmp_ipv4); 21026 } 21027 21028 /* Send per roam config parameters */ 21029 status = wmi_unified_cmd_send(wmi_handle, buf, 21030 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21031 if (QDF_IS_STATUS_ERROR(status)) { 21032 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21033 status); 21034 goto error; 21035 } 21036 21037 WMI_LOGI(FL("set arp stats flag=%d, vdev=%d"), 21038 req_buf->flag, req_buf->vdev_id); 21039 return QDF_STATUS_SUCCESS; 21040 error: 21041 wmi_buf_free(buf); 21042 21043 return status; 21044 } 21045 21046 /** 21047 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21048 * @wmi_handle: wmi handler 21049 * @req_buf: get arp stats request buffer 21050 * 21051 * Return: 0 for success and non zero for failure 21052 */ 21053 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21054 struct get_arp_stats *req_buf) 21055 { 21056 wmi_buf_t buf = NULL; 21057 QDF_STATUS status; 21058 int len; 21059 uint8_t *buf_ptr; 21060 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21061 21062 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21063 buf = wmi_buf_alloc(wmi_handle, len); 21064 if (!buf) { 21065 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21066 return QDF_STATUS_E_NOMEM; 21067 } 21068 21069 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21070 get_arp_stats = 21071 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21072 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21073 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21074 WMITLV_GET_STRUCT_TLVLEN 21075 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21076 21077 /* fill in arp stats req cmd values */ 21078 get_arp_stats->vdev_id = req_buf->vdev_id; 21079 21080 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21081 /* Send per roam config parameters */ 21082 status = wmi_unified_cmd_send(wmi_handle, buf, 21083 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21084 if (QDF_IS_STATUS_ERROR(status)) { 21085 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21086 status); 21087 goto error; 21088 } 21089 21090 return QDF_STATUS_SUCCESS; 21091 error: 21092 wmi_buf_free(buf); 21093 21094 return status; 21095 } 21096 21097 /** 21098 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21099 * @wmi_handle: wmi handler 21100 * @pmk_info: pointer to PMK cache entry 21101 * @vdev_id: vdev id 21102 * 21103 * Return: 0 for success and non zero for failure 21104 */ 21105 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21106 struct wmi_unified_pmk_cache *pmk_info) 21107 { 21108 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21109 wmi_buf_t buf; 21110 QDF_STATUS status; 21111 uint8_t *buf_ptr; 21112 wmi_pmk_cache *pmksa; 21113 uint32_t len = sizeof(*cmd); 21114 21115 if (pmk_info->pmk_len) 21116 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21117 21118 buf = wmi_buf_alloc(wmi_handle, len); 21119 if (!buf) { 21120 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21121 __func__); 21122 return QDF_STATUS_E_NOMEM; 21123 } 21124 21125 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21126 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21127 21128 WMITLV_SET_HDR(&cmd->tlv_header, 21129 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21130 WMITLV_GET_STRUCT_TLVLEN( 21131 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21132 21133 cmd->vdev_id = pmk_info->session_id; 21134 21135 /* If pmk_info->pmk_len is 0, this is a flush request */ 21136 if (!pmk_info->pmk_len) { 21137 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21138 cmd->num_cache = 0; 21139 goto send_cmd; 21140 } 21141 21142 cmd->num_cache = 1; 21143 buf_ptr += sizeof(*cmd); 21144 21145 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21146 sizeof(*pmksa)); 21147 buf_ptr += WMI_TLV_HDR_SIZE; 21148 21149 pmksa = (wmi_pmk_cache *)buf_ptr; 21150 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21151 WMITLV_GET_STRUCT_TLVLEN 21152 (wmi_pmk_cache)); 21153 pmksa->pmk_len = pmk_info->pmk_len; 21154 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21155 pmksa->pmkid_len = pmk_info->pmkid_len; 21156 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21157 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21158 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21159 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21160 pmksa->ssid.ssid_len); 21161 pmksa->cache_id = pmk_info->cache_id; 21162 pmksa->cat_flag = pmk_info->cat_flag; 21163 pmksa->action_flag = pmk_info->action_flag; 21164 21165 send_cmd: 21166 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21167 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21168 if (status != QDF_STATUS_SUCCESS) { 21169 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21170 __func__, status); 21171 wmi_buf_free(buf); 21172 } 21173 21174 return status; 21175 } 21176 21177 /** 21178 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21179 * @wmi_handle: wmi handle 21180 * @param: reserved param 21181 * 21182 * Return: 0 for success or error code 21183 */ 21184 static QDF_STATUS 21185 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21186 uint32_t param) 21187 { 21188 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21189 wmi_buf_t buf; 21190 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21191 21192 buf = wmi_buf_alloc(wmi_handle, len); 21193 if (!buf) { 21194 qdf_print("%s:wmi_buf_alloc failed", __func__); 21195 return QDF_STATUS_E_FAILURE; 21196 } 21197 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21198 WMITLV_SET_HDR(&cmd->tlv_header, 21199 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21200 WMITLV_GET_STRUCT_TLVLEN 21201 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21202 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21203 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21204 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21205 wmi_buf_free(buf); 21206 return QDF_STATUS_E_FAILURE; 21207 } 21208 21209 return QDF_STATUS_SUCCESS; 21210 } 21211 21212 /** 21213 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21214 * @wmi_handle: wmi handle 21215 * @param evt_buf: pointer to event buffer 21216 * @param param: Pointer to hold peer caldata version data 21217 * 21218 * Return: 0 for success or error code 21219 */ 21220 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21221 wmi_unified_t wmi_handle, 21222 void *evt_buf, 21223 wmi_host_pdev_check_cal_version_event *param) 21224 { 21225 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21226 wmi_pdev_check_cal_version_event_fixed_param *event; 21227 21228 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21229 if (!param_tlvs) { 21230 WMI_LOGE("invalid cal version event buf"); 21231 return QDF_STATUS_E_FAILURE; 21232 } 21233 event = param_tlvs->fixed_param; 21234 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21235 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21236 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21237 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21238 21239 param->software_cal_version = event->software_cal_version; 21240 param->board_cal_version = event->board_cal_version; 21241 param->cal_ok = event->cal_status; 21242 21243 return QDF_STATUS_SUCCESS; 21244 } 21245 21246 /* 21247 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21248 * @wmi_handle: wmi handle 21249 * @params: pointer to wmi_btm_config 21250 * 21251 * Return: QDF_STATUS 21252 */ 21253 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21254 struct wmi_btm_config *params) 21255 { 21256 21257 wmi_btm_config_fixed_param *cmd; 21258 wmi_buf_t buf; 21259 uint32_t len; 21260 21261 len = sizeof(*cmd); 21262 buf = wmi_buf_alloc(wmi_handle, len); 21263 if (!buf) { 21264 qdf_print("%s:wmi_buf_alloc failed", __func__); 21265 return QDF_STATUS_E_NOMEM; 21266 } 21267 21268 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21269 WMITLV_SET_HDR(&cmd->tlv_header, 21270 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21271 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21272 cmd->vdev_id = params->vdev_id; 21273 cmd->flags = params->btm_offload_config; 21274 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21275 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21276 cmd->stick_time_seconds = params->btm_sticky_time; 21277 21278 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21279 WMI_ROAM_BTM_CONFIG_CMDID)) { 21280 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21281 __func__); 21282 wmi_buf_free(buf); 21283 return QDF_STATUS_E_FAILURE; 21284 } 21285 21286 return QDF_STATUS_SUCCESS; 21287 } 21288 21289 /** 21290 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21291 * configurations to firmware. 21292 * @wmi_handle: wmi handle 21293 * @obss_cfg_param: obss detection configurations 21294 * 21295 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21296 * 21297 * Return: QDF_STATUS 21298 */ 21299 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21300 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21301 { 21302 wmi_buf_t buf; 21303 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21304 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21305 21306 buf = wmi_buf_alloc(wmi_handle, len); 21307 if (!buf) { 21308 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21309 return QDF_STATUS_E_NOMEM; 21310 } 21311 21312 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21313 WMITLV_SET_HDR(&cmd->tlv_header, 21314 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21315 WMITLV_GET_STRUCT_TLVLEN 21316 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21317 21318 cmd->vdev_id = obss_cfg_param->vdev_id; 21319 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21320 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21321 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21322 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21323 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21324 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21325 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21326 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21327 21328 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21329 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21330 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21331 wmi_buf_free(buf); 21332 return QDF_STATUS_E_FAILURE; 21333 } 21334 21335 return QDF_STATUS_SUCCESS; 21336 } 21337 21338 /** 21339 * extract_obss_detection_info_tlv() - Extract obss detection info 21340 * received from firmware. 21341 * @evt_buf: pointer to event buffer 21342 * @obss_detection: Pointer to hold obss detection info 21343 * 21344 * Return: QDF_STATUS 21345 */ 21346 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21347 struct wmi_obss_detect_info 21348 *obss_detection) 21349 { 21350 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21351 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21352 21353 if (!obss_detection) { 21354 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21355 return QDF_STATUS_E_INVAL; 21356 } 21357 21358 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21359 if (!param_buf) { 21360 WMI_LOGE("%s: Invalid evt_buf", __func__); 21361 return QDF_STATUS_E_INVAL; 21362 } 21363 21364 fix_param = param_buf->fixed_param; 21365 obss_detection->vdev_id = fix_param->vdev_id; 21366 obss_detection->matched_detection_masks = 21367 fix_param->matched_detection_masks; 21368 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21369 &obss_detection->matched_bssid_addr[0]); 21370 switch (fix_param->reason) { 21371 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21372 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21373 break; 21374 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21375 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21376 break; 21377 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21378 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21379 break; 21380 default: 21381 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21382 return QDF_STATUS_E_INVAL; 21383 } 21384 21385 return QDF_STATUS_SUCCESS; 21386 } 21387 21388 /** 21389 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 21390 * @wmi_handle: wmi handler 21391 * @params: pointer to 11k offload params 21392 * 21393 * Return: 0 for success and non zero for failure 21394 */ 21395 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 21396 struct wmi_11k_offload_params *params) 21397 { 21398 wmi_11k_offload_report_fixed_param *cmd; 21399 wmi_buf_t buf; 21400 QDF_STATUS status; 21401 uint8_t *buf_ptr; 21402 wmi_neighbor_report_11k_offload_tlv_param 21403 *neighbor_report_offload_params; 21404 wmi_neighbor_report_offload *neighbor_report_offload; 21405 21406 uint32_t len = sizeof(*cmd); 21407 21408 if (params->offload_11k_bitmask & 21409 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 21410 len += WMI_TLV_HDR_SIZE + 21411 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 21412 21413 buf = wmi_buf_alloc(wmi_handle, len); 21414 if (!buf) { 21415 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 21416 __func__); 21417 return QDF_STATUS_E_NOMEM; 21418 } 21419 21420 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21421 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 21422 21423 WMITLV_SET_HDR(&cmd->tlv_header, 21424 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 21425 WMITLV_GET_STRUCT_TLVLEN( 21426 wmi_11k_offload_report_fixed_param)); 21427 21428 cmd->vdev_id = params->vdev_id; 21429 cmd->offload_11k = params->offload_11k_bitmask; 21430 21431 if (params->offload_11k_bitmask & 21432 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 21433 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 21434 21435 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21436 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 21437 buf_ptr += WMI_TLV_HDR_SIZE; 21438 21439 neighbor_report_offload_params = 21440 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 21441 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 21442 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 21443 WMITLV_GET_STRUCT_TLVLEN( 21444 wmi_neighbor_report_11k_offload_tlv_param)); 21445 21446 neighbor_report_offload = &neighbor_report_offload_params-> 21447 neighbor_rep_ofld_params; 21448 21449 neighbor_report_offload->time_offset = 21450 params->neighbor_report_params.time_offset; 21451 neighbor_report_offload->low_rssi_offset = 21452 params->neighbor_report_params.low_rssi_offset; 21453 neighbor_report_offload->bmiss_count_trigger = 21454 params->neighbor_report_params.bmiss_count_trigger; 21455 neighbor_report_offload->per_threshold_offset = 21456 params->neighbor_report_params.per_threshold_offset; 21457 neighbor_report_offload->neighbor_report_cache_timeout = 21458 params->neighbor_report_params. 21459 neighbor_report_cache_timeout; 21460 neighbor_report_offload->max_neighbor_report_req_cap = 21461 params->neighbor_report_params. 21462 max_neighbor_report_req_cap; 21463 neighbor_report_offload->ssid.ssid_len = 21464 params->neighbor_report_params.ssid.length; 21465 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 21466 ¶ms->neighbor_report_params.ssid.mac_ssid, 21467 neighbor_report_offload->ssid.ssid_len); 21468 } 21469 21470 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21471 WMI_11K_OFFLOAD_REPORT_CMDID); 21472 if (status != QDF_STATUS_SUCCESS) { 21473 WMI_LOGE("%s: failed to send 11k offload command %d", 21474 __func__, status); 21475 wmi_buf_free(buf); 21476 } 21477 21478 return status; 21479 } 21480 21481 /** 21482 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 21483 * command 21484 * @wmi_handle: wmi handler 21485 * @params: pointer to neighbor report invoke params 21486 * 21487 * Return: 0 for success and non zero for failure 21488 */ 21489 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 21490 struct wmi_invoke_neighbor_report_params *params) 21491 { 21492 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 21493 wmi_buf_t buf; 21494 QDF_STATUS status; 21495 uint8_t *buf_ptr; 21496 uint32_t len = sizeof(*cmd); 21497 21498 buf = wmi_buf_alloc(wmi_handle, len); 21499 if (!buf) { 21500 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 21501 __func__); 21502 return QDF_STATUS_E_NOMEM; 21503 } 21504 21505 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21506 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 21507 21508 WMITLV_SET_HDR(&cmd->tlv_header, 21509 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 21510 WMITLV_GET_STRUCT_TLVLEN( 21511 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 21512 21513 cmd->vdev_id = params->vdev_id; 21514 cmd->flags = params->send_resp_to_host; 21515 21516 cmd->ssid.ssid_len = params->ssid.length; 21517 qdf_mem_copy(cmd->ssid.ssid, 21518 ¶ms->ssid.mac_ssid, 21519 cmd->ssid.ssid_len); 21520 21521 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21522 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 21523 if (status != QDF_STATUS_SUCCESS) { 21524 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 21525 __func__, status); 21526 wmi_buf_free(buf); 21527 } 21528 21529 return status; 21530 } 21531 21532 #ifdef WLAN_SUPPORT_GREEN_AP 21533 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 21534 uint8_t *evt_buf, 21535 struct wlan_green_ap_egap_status_info *egap_status_info_params) 21536 { 21537 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 21538 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 21539 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 21540 21541 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 21542 if (!param_buf) { 21543 WMI_LOGE("Invalid EGAP Info status event buffer"); 21544 return QDF_STATUS_E_INVAL; 21545 } 21546 21547 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 21548 param_buf->fixed_param; 21549 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 21550 param_buf->chainmask_list; 21551 21552 egap_status_info_params->status = egap_info_event->status; 21553 egap_status_info_params->mac_id = chainmask_event->mac_id; 21554 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 21555 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 21556 21557 return QDF_STATUS_SUCCESS; 21558 } 21559 #endif 21560 21561 /* 21562 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 21563 * updating bss color change within firmware when AP announces bss color change. 21564 * @wmi_handle: wmi handle 21565 * @vdev_id: vdev ID 21566 * @enable: enable bss color change within firmware 21567 * 21568 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 21569 * 21570 * Return: QDF_STATUS 21571 */ 21572 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 21573 uint32_t vdev_id, 21574 bool enable) 21575 { 21576 wmi_buf_t buf; 21577 wmi_bss_color_change_enable_fixed_param *cmd; 21578 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 21579 21580 buf = wmi_buf_alloc(wmi_handle, len); 21581 if (!buf) { 21582 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21583 return QDF_STATUS_E_NOMEM; 21584 } 21585 21586 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 21587 WMITLV_SET_HDR(&cmd->tlv_header, 21588 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 21589 WMITLV_GET_STRUCT_TLVLEN 21590 (wmi_bss_color_change_enable_fixed_param)); 21591 cmd->vdev_id = vdev_id; 21592 cmd->enable = enable; 21593 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21594 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 21595 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 21596 wmi_buf_free(buf); 21597 return QDF_STATUS_E_FAILURE; 21598 } 21599 21600 return QDF_STATUS_SUCCESS; 21601 } 21602 21603 /** 21604 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 21605 * configurations to firmware. 21606 * @wmi_handle: wmi handle 21607 * @cfg_param: obss detection configurations 21608 * 21609 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 21610 * 21611 * Return: QDF_STATUS 21612 */ 21613 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 21614 wmi_unified_t wmi_handle, 21615 struct wmi_obss_color_collision_cfg_param *cfg_param) 21616 { 21617 wmi_buf_t buf; 21618 wmi_obss_color_collision_det_config_fixed_param *cmd; 21619 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 21620 21621 buf = wmi_buf_alloc(wmi_handle, len); 21622 if (!buf) { 21623 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21624 return QDF_STATUS_E_NOMEM; 21625 } 21626 21627 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 21628 buf); 21629 WMITLV_SET_HDR(&cmd->tlv_header, 21630 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 21631 WMITLV_GET_STRUCT_TLVLEN 21632 (wmi_obss_color_collision_det_config_fixed_param)); 21633 cmd->vdev_id = cfg_param->vdev_id; 21634 cmd->flags = cfg_param->flags; 21635 cmd->current_bss_color = cfg_param->current_bss_color; 21636 cmd->detection_period_ms = cfg_param->detection_period_ms; 21637 cmd->scan_period_ms = cfg_param->scan_period_ms; 21638 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 21639 21640 switch (cfg_param->evt_type) { 21641 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 21642 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 21643 break; 21644 case OBSS_COLOR_COLLISION_DETECTION: 21645 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 21646 break; 21647 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21648 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21649 break; 21650 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 21651 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 21652 break; 21653 default: 21654 WMI_LOGE("%s: invalid event type: %d", 21655 __func__, cfg_param->evt_type); 21656 wmi_buf_free(buf); 21657 return QDF_STATUS_E_FAILURE; 21658 } 21659 21660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21661 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 21662 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 21663 __func__, cfg_param->vdev_id); 21664 wmi_buf_free(buf); 21665 return QDF_STATUS_E_FAILURE; 21666 } 21667 21668 return QDF_STATUS_SUCCESS; 21669 } 21670 21671 /** 21672 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 21673 * received from firmware. 21674 * @evt_buf: pointer to event buffer 21675 * @info: Pointer to hold bss collision info 21676 * 21677 * Return: QDF_STATUS 21678 */ 21679 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 21680 struct wmi_obss_color_collision_info *info) 21681 { 21682 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 21683 wmi_obss_color_collision_evt_fixed_param *fix_param; 21684 21685 if (!info) { 21686 WMI_LOGE("%s: Invalid obss color buffer", __func__); 21687 return QDF_STATUS_E_INVAL; 21688 } 21689 21690 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 21691 evt_buf; 21692 if (!param_buf) { 21693 WMI_LOGE("%s: Invalid evt_buf", __func__); 21694 return QDF_STATUS_E_INVAL; 21695 } 21696 21697 fix_param = param_buf->fixed_param; 21698 info->vdev_id = fix_param->vdev_id; 21699 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 21700 info->obss_color_bitmap_bit32to63 = 21701 fix_param->bss_color_bitmap_bit32to63; 21702 21703 switch (fix_param->evt_type) { 21704 case WMI_BSS_COLOR_COLLISION_DISABLE: 21705 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 21706 break; 21707 case WMI_BSS_COLOR_COLLISION_DETECTION: 21708 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 21709 break; 21710 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 21711 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 21712 break; 21713 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 21714 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 21715 break; 21716 default: 21717 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 21718 __func__, fix_param->evt_type, fix_param->vdev_id); 21719 return QDF_STATUS_E_FAILURE; 21720 } 21721 21722 return QDF_STATUS_SUCCESS; 21723 } 21724 21725 /* 21726 * extract_comb_phyerr_tlv() - extract comb phy error from event 21727 * @wmi_handle: wmi handle 21728 * @evt_buf: pointer to event buffer 21729 * @datalen: data length of event buffer 21730 * @buf_offset: Pointer to hold value of current event buffer offset 21731 * post extraction 21732 * @phyerr: Pointer to hold phyerr 21733 * 21734 * Return: QDF_STATUS 21735 */ 21736 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 21737 void *evt_buf, 21738 uint16_t datalen, 21739 uint16_t *buf_offset, 21740 wmi_host_phyerr_t *phyerr) 21741 { 21742 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 21743 wmi_comb_phyerr_rx_hdr *pe_hdr; 21744 21745 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 21746 if (!param_tlvs) { 21747 WMI_LOGD("%s: Received null data from FW", __func__); 21748 return QDF_STATUS_E_FAILURE; 21749 } 21750 21751 pe_hdr = param_tlvs->hdr; 21752 if (!pe_hdr) { 21753 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 21754 return QDF_STATUS_E_FAILURE; 21755 } 21756 21757 /* Ensure it's at least the size of the header */ 21758 if (datalen < sizeof(*pe_hdr)) { 21759 WMI_LOGD("%s: Expected minimum size %zu, received %d", 21760 __func__, sizeof(*pe_hdr), datalen); 21761 return QDF_STATUS_E_FAILURE; 21762 } 21763 21764 phyerr->pdev_id = wmi_handle->ops-> 21765 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 21766 phyerr->tsf64 = pe_hdr->tsf_l32; 21767 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 21768 phyerr->bufp = param_tlvs->bufp; 21769 phyerr->buf_len = pe_hdr->buf_len; 21770 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 21771 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 21772 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 21773 21774 return QDF_STATUS_SUCCESS; 21775 } 21776 21777 /** 21778 * extract_single_phyerr_tlv() - extract single phy error from event 21779 * @wmi_handle: wmi handle 21780 * @evt_buf: pointer to event buffer 21781 * @datalen: data length of event buffer 21782 * @buf_offset: Pointer to hold value of current event buffer offset 21783 * post extraction 21784 * @phyerr: Pointer to hold phyerr 21785 * 21786 * Return: QDF_STATUS 21787 */ 21788 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 21789 void *evt_buf, 21790 uint16_t datalen, 21791 uint16_t *buf_offset, 21792 wmi_host_phyerr_t *phyerr) 21793 { 21794 wmi_single_phyerr_rx_event *ev; 21795 uint16_t n = *buf_offset; 21796 uint8_t *data = (uint8_t *)evt_buf; 21797 21798 if (n < datalen) { 21799 if ((datalen - n) < sizeof(ev->hdr)) { 21800 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 21801 __func__, datalen, n, sizeof(ev->hdr)); 21802 return QDF_STATUS_E_FAILURE; 21803 } 21804 21805 /* 21806 * Obtain a pointer to the beginning of the current event. 21807 * data[0] is the beginning of the WMI payload. 21808 */ 21809 ev = (wmi_single_phyerr_rx_event *)&data[n]; 21810 21811 /* 21812 * Sanity check the buffer length of the event against 21813 * what we currently have. 21814 * 21815 * Since buf_len is 32 bits, we check if it overflows 21816 * a large 32 bit value. It's not 0x7fffffff because 21817 * we increase n by (buf_len + sizeof(hdr)), which would 21818 * in itself cause n to overflow. 21819 * 21820 * If "int" is 64 bits then this becomes a moot point. 21821 */ 21822 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 21823 WMI_LOGD("%s: buf_len is garbage 0x%x", 21824 __func__, ev->hdr.buf_len); 21825 return QDF_STATUS_E_FAILURE; 21826 } 21827 21828 if ((n + ev->hdr.buf_len) > datalen) { 21829 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 21830 __func__, n, ev->hdr.buf_len, datalen); 21831 return QDF_STATUS_E_FAILURE; 21832 } 21833 21834 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 21835 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 21836 phyerr->bufp = &ev->bufp[0]; 21837 phyerr->buf_len = ev->hdr.buf_len; 21838 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 21839 21840 /* 21841 * Advance the buffer pointer to the next PHY error. 21842 * buflen is the length of this payload, so we need to 21843 * advance past the current header _AND_ the payload. 21844 */ 21845 n += sizeof(*ev) + ev->hdr.buf_len; 21846 } 21847 *buf_offset = n; 21848 21849 return QDF_STATUS_SUCCESS; 21850 } 21851 21852 struct wmi_ops tlv_ops = { 21853 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21854 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21855 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21856 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21857 .send_hidden_ssid_vdev_restart_cmd = 21858 send_hidden_ssid_vdev_restart_cmd_tlv, 21859 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21860 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21861 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21862 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21863 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21864 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21865 .send_peer_rx_reorder_queue_setup_cmd = 21866 send_peer_rx_reorder_queue_setup_cmd_tlv, 21867 .send_peer_rx_reorder_queue_remove_cmd = 21868 send_peer_rx_reorder_queue_remove_cmd_tlv, 21869 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 21870 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 21871 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 21872 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21873 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21874 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 21875 .send_suspend_cmd = send_suspend_cmd_tlv, 21876 .send_resume_cmd = send_resume_cmd_tlv, 21877 #ifdef FEATURE_WLAN_D0WOW 21878 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 21879 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 21880 #endif 21881 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21882 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21883 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21884 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21885 #ifdef FEATURE_FW_LOG_PARSING 21886 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21887 #endif 21888 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21889 .send_stats_request_cmd = send_stats_request_cmd_tlv, 21890 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21891 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21892 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21893 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 21894 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21895 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21896 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21897 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21898 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21899 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21900 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21901 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21902 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21903 .send_set_sta_uapsd_auto_trig_cmd = 21904 send_set_sta_uapsd_auto_trig_cmd_tlv, 21905 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21906 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 21907 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 21908 #ifdef CONVERGED_P2P_ENABLE 21909 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 21910 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 21911 #endif 21912 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21913 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21914 #ifdef WLAN_FEATURE_DSRC 21915 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 21916 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 21917 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 21918 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 21919 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 21920 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 21921 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 21922 .send_ocb_start_timing_advert_cmd = 21923 send_ocb_start_timing_advert_cmd_tlv, 21924 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 21925 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 21926 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 21927 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 21928 #endif 21929 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 21930 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 21931 .send_set_mcc_channel_time_latency_cmd = 21932 send_set_mcc_channel_time_latency_cmd_tlv, 21933 .send_set_mcc_channel_time_quota_cmd = 21934 send_set_mcc_channel_time_quota_cmd_tlv, 21935 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21936 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21937 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21938 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 21939 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 21940 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 21941 .send_probe_rsp_tmpl_send_cmd = 21942 send_probe_rsp_tmpl_send_cmd_tlv, 21943 .send_p2p_go_set_beacon_ie_cmd = 21944 send_p2p_go_set_beacon_ie_cmd_tlv, 21945 .send_setup_install_key_cmd = 21946 send_setup_install_key_cmd_tlv, 21947 .send_set_gateway_params_cmd = 21948 send_set_gateway_params_cmd_tlv, 21949 .send_set_rssi_monitoring_cmd = 21950 send_set_rssi_monitoring_cmd_tlv, 21951 .send_scan_probe_setoui_cmd = 21952 send_scan_probe_setoui_cmd_tlv, 21953 .send_roam_scan_offload_rssi_thresh_cmd = 21954 send_roam_scan_offload_rssi_thresh_cmd_tlv, 21955 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 21956 .send_roam_scan_filter_cmd = 21957 send_roam_scan_filter_cmd_tlv, 21958 #ifdef IPA_OFFLOAD 21959 .send_ipa_offload_control_cmd = 21960 send_ipa_offload_control_cmd_tlv, 21961 #endif 21962 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 21963 .send_plm_start_cmd = send_plm_start_cmd_tlv, 21964 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21965 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21966 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21967 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 21968 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21969 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21970 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21971 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21972 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21973 .send_congestion_cmd = send_congestion_cmd_tlv, 21974 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21975 .send_snr_cmd = send_snr_cmd_tlv, 21976 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21977 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 21978 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 21979 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 21980 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 21981 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 21982 .send_multiple_add_clear_mcbc_filter_cmd = 21983 send_multiple_add_clear_mcbc_filter_cmd_tlv, 21984 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 21985 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 21986 .send_process_gtk_offload_getinfo_cmd = 21987 send_process_gtk_offload_getinfo_cmd_tlv, 21988 .send_enable_enhance_multicast_offload_cmd = 21989 send_enable_enhance_multicast_offload_tlv, 21990 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 21991 #ifdef FEATURE_WLAN_RA_FILTERING 21992 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 21993 #endif 21994 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 21995 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 21996 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 21997 .send_lphb_config_tcp_pkt_filter_cmd = 21998 send_lphb_config_tcp_pkt_filter_cmd_tlv, 21999 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22000 .send_lphb_config_udp_pkt_filter_cmd = 22001 send_lphb_config_udp_pkt_filter_cmd_tlv, 22002 .send_enable_disable_packet_filter_cmd = 22003 send_enable_disable_packet_filter_cmd_tlv, 22004 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22005 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 22006 #ifdef CONFIG_MCL 22007 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22008 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22009 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22010 .send_roam_scan_offload_mode_cmd = 22011 send_roam_scan_offload_mode_cmd_tlv, 22012 #ifndef REMOVE_PKT_LOG 22013 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22014 #endif 22015 .send_roam_scan_offload_ap_profile_cmd = 22016 send_roam_scan_offload_ap_profile_cmd_tlv, 22017 #endif 22018 #ifdef WLAN_SUPPORT_GREEN_AP 22019 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22020 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22021 .extract_green_ap_egap_status_info = 22022 extract_green_ap_egap_status_info_tlv, 22023 #endif 22024 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22025 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22026 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22027 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22028 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22029 #ifdef WLAN_FEATURE_CIF_CFR 22030 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22031 #endif 22032 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22033 .send_dfs_phyerr_filter_offload_en_cmd = 22034 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22035 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22036 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22037 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22038 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22039 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22040 .send_process_add_periodic_tx_ptrn_cmd = 22041 send_process_add_periodic_tx_ptrn_cmd_tlv, 22042 .send_process_del_periodic_tx_ptrn_cmd = 22043 send_process_del_periodic_tx_ptrn_cmd_tlv, 22044 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22045 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22046 .send_set_app_type2_params_in_fw_cmd = 22047 send_set_app_type2_params_in_fw_cmd_tlv, 22048 .send_set_auto_shutdown_timer_cmd = 22049 send_set_auto_shutdown_timer_cmd_tlv, 22050 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22051 .send_process_dhcpserver_offload_cmd = 22052 send_process_dhcpserver_offload_cmd_tlv, 22053 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22054 .send_process_ch_avoid_update_cmd = 22055 send_process_ch_avoid_update_cmd_tlv, 22056 .send_pdev_set_regdomain_cmd = 22057 send_pdev_set_regdomain_cmd_tlv, 22058 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22059 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22060 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22061 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22062 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22063 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22064 .check_and_update_fw_version = 22065 check_and_update_fw_version_cmd_tlv, 22066 .send_set_base_macaddr_indicate_cmd = 22067 send_set_base_macaddr_indicate_cmd_tlv, 22068 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22069 .send_enable_specific_fw_logs_cmd = 22070 send_enable_specific_fw_logs_cmd_tlv, 22071 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22072 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22073 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22074 #ifdef WLAN_POLICY_MGR_ENABLE 22075 .send_pdev_set_dual_mac_config_cmd = 22076 send_pdev_set_dual_mac_config_cmd_tlv, 22077 #endif 22078 .send_app_type1_params_in_fw_cmd = 22079 send_app_type1_params_in_fw_cmd_tlv, 22080 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22081 .send_process_roam_synch_complete_cmd = 22082 send_process_roam_synch_complete_cmd_tlv, 22083 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22084 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22085 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22086 .send_roam_scan_offload_scan_period_cmd = 22087 send_roam_scan_offload_scan_period_cmd_tlv, 22088 .send_roam_scan_offload_chan_list_cmd = 22089 send_roam_scan_offload_chan_list_cmd_tlv, 22090 .send_roam_scan_offload_rssi_change_cmd = 22091 send_roam_scan_offload_rssi_change_cmd_tlv, 22092 #ifdef FEATURE_WLAN_APF 22093 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 22094 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 22095 .send_apf_write_work_memory_cmd = 22096 wmi_send_apf_write_work_memory_cmd_tlv, 22097 .send_apf_read_work_memory_cmd = 22098 wmi_send_apf_read_work_memory_cmd_tlv, 22099 .extract_apf_read_memory_resp_event = 22100 wmi_extract_apf_read_memory_resp_event_tlv, 22101 #endif /* FEATURE_WLAN_APF */ 22102 .send_adapt_dwelltime_params_cmd = 22103 send_adapt_dwelltime_params_cmd_tlv, 22104 .send_dbs_scan_sel_params_cmd = 22105 send_dbs_scan_sel_params_cmd_tlv, 22106 .init_cmd_send = init_cmd_send_tlv, 22107 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22108 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22109 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22110 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22111 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22112 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22113 .send_vdev_set_custom_aggr_size_cmd = 22114 send_vdev_set_custom_aggr_size_cmd_tlv, 22115 .send_vdev_set_qdepth_thresh_cmd = 22116 send_vdev_set_qdepth_thresh_cmd_tlv, 22117 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22118 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22119 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22120 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22121 .send_smart_ant_set_training_info_cmd = 22122 send_smart_ant_set_training_info_cmd_tlv, 22123 .send_smart_ant_set_node_config_cmd = 22124 send_smart_ant_set_node_config_cmd_tlv, 22125 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22126 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22127 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22128 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22129 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22130 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22131 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22132 .send_periodic_chan_stats_config_cmd = 22133 send_periodic_chan_stats_config_cmd_tlv, 22134 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22135 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22136 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22137 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22138 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22139 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22140 .send_vdev_spectral_configure_cmd = 22141 send_vdev_spectral_configure_cmd_tlv, 22142 .send_vdev_spectral_enable_cmd = 22143 send_vdev_spectral_enable_cmd_tlv, 22144 .send_thermal_mitigation_param_cmd = 22145 send_thermal_mitigation_param_cmd_tlv, 22146 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22147 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22148 .send_process_update_edca_param_cmd = 22149 send_process_update_edca_param_cmd_tlv, 22150 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22151 .send_set_country_cmd = send_set_country_cmd_tlv, 22152 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22153 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22154 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22155 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22156 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22157 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22158 .extract_host_mem_req = extract_host_mem_req_tlv, 22159 .save_service_bitmap = save_service_bitmap_tlv, 22160 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22161 .is_service_enabled = is_service_enabled_tlv, 22162 .save_fw_version = save_fw_version_in_service_ready_tlv, 22163 .ready_extract_init_status = ready_extract_init_status_tlv, 22164 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22165 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22166 .extract_ready_event_params = extract_ready_event_params_tlv, 22167 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22168 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22169 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22170 .extract_tbttoffset_update_params = 22171 extract_tbttoffset_update_params_tlv, 22172 .extract_ext_tbttoffset_update_params = 22173 extract_ext_tbttoffset_update_params_tlv, 22174 .extract_tbttoffset_num_vdevs = 22175 extract_tbttoffset_num_vdevs_tlv, 22176 .extract_ext_tbttoffset_num_vdevs = 22177 extract_ext_tbttoffset_num_vdevs_tlv, 22178 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22179 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22180 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22181 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22182 #ifdef CONVERGED_TDLS_ENABLE 22183 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22184 #endif 22185 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22186 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22187 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22188 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22189 #ifdef CONVERGED_P2P_ENABLE 22190 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22191 .extract_p2p_lo_stop_ev_param = 22192 extract_p2p_lo_stop_ev_param_tlv, 22193 #endif 22194 .extract_offchan_data_tx_compl_param = 22195 extract_offchan_data_tx_compl_param_tlv, 22196 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22197 .extract_all_stats_count = extract_all_stats_counts_tlv, 22198 .extract_pdev_stats = extract_pdev_stats_tlv, 22199 .extract_unit_test = extract_unit_test_tlv, 22200 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22201 .extract_vdev_stats = extract_vdev_stats_tlv, 22202 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22203 .extract_peer_stats = extract_peer_stats_tlv, 22204 .extract_bcn_stats = extract_bcn_stats_tlv, 22205 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22206 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22207 .extract_chan_stats = extract_chan_stats_tlv, 22208 .extract_profile_ctx = extract_profile_ctx_tlv, 22209 .extract_profile_data = extract_profile_data_tlv, 22210 .extract_chan_info_event = extract_chan_info_event_tlv, 22211 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22212 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22213 #ifdef WLAN_FEATURE_DISA 22214 .send_encrypt_decrypt_send_cmd = 22215 send_encrypt_decrypt_send_cmd_tlv, 22216 .extract_encrypt_decrypt_resp_event = 22217 extract_encrypt_decrypt_resp_event_tlv, 22218 #endif 22219 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22220 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22221 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22222 .extract_sar2_result_event = extract_sar2_result_event_tlv, 22223 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22224 .send_multiple_vdev_restart_req_cmd = 22225 send_multiple_vdev_restart_req_cmd_tlv, 22226 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22227 .extract_hw_mode_cap_service_ready_ext = 22228 extract_hw_mode_cap_service_ready_ext_tlv, 22229 .extract_mac_phy_cap_service_ready_ext = 22230 extract_mac_phy_cap_service_ready_ext_tlv, 22231 .extract_reg_cap_service_ready_ext = 22232 extract_reg_cap_service_ready_ext_tlv, 22233 .extract_dbr_ring_cap_service_ready_ext = 22234 extract_dbr_ring_cap_service_ready_ext_tlv, 22235 .extract_sar_cap_service_ready_ext = 22236 extract_sar_cap_service_ready_ext_tlv, 22237 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22238 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22239 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22240 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22241 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22242 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22243 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22244 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22245 .extract_fips_event_data = extract_fips_event_data_tlv, 22246 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22247 .extract_peer_delete_response_event = 22248 extract_peer_delete_response_event_tlv, 22249 .is_management_record = is_management_record_tlv, 22250 .extract_pdev_csa_switch_count_status = 22251 extract_pdev_csa_switch_count_status_tlv, 22252 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22253 .extract_pdev_tpc_config_ev_param = 22254 extract_pdev_tpc_config_ev_param_tlv, 22255 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22256 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22257 .extract_peer_sta_ps_statechange_ev = 22258 extract_peer_sta_ps_statechange_ev_tlv, 22259 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22260 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22261 #ifdef WLAN_FEATURE_ACTION_OUI 22262 .send_action_oui_cmd = send_action_oui_cmd_tlv, 22263 #endif 22264 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22265 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22266 .extract_reg_chan_list_update_event = 22267 extract_reg_chan_list_update_event_tlv, 22268 .extract_chainmask_tables = 22269 extract_chainmask_tables_tlv, 22270 .extract_thermal_stats = extract_thermal_stats_tlv, 22271 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 22272 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 22273 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 22274 #ifdef DFS_COMPONENT_ENABLE 22275 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 22276 .extract_dfs_radar_detection_event = 22277 extract_dfs_radar_detection_event_tlv, 22278 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 22279 #endif 22280 .convert_pdev_id_host_to_target = 22281 convert_host_pdev_id_to_target_pdev_id_legacy, 22282 .convert_pdev_id_target_to_host = 22283 convert_target_pdev_id_to_host_pdev_id_legacy, 22284 22285 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 22286 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 22287 .extract_reg_11d_new_country_event = 22288 extract_reg_11d_new_country_event_tlv, 22289 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 22290 .send_limit_off_chan_cmd = 22291 send_limit_off_chan_cmd_tlv, 22292 .extract_reg_ch_avoid_event = 22293 extract_reg_ch_avoid_event_tlv, 22294 .send_pdev_caldata_version_check_cmd = 22295 send_pdev_caldata_version_check_cmd_tlv, 22296 .extract_pdev_caldata_version_check_ev_param = 22297 extract_pdev_caldata_version_check_ev_param_tlv, 22298 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 22299 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 22300 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 22301 #if defined(WLAN_FEATURE_FILS_SK) 22302 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 22303 #endif 22304 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 22305 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 22306 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 22307 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 22308 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 22309 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 22310 .extract_ndp_ind = extract_ndp_ind_tlv, 22311 .extract_ndp_confirm = extract_ndp_confirm_tlv, 22312 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 22313 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 22314 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 22315 .extract_ndp_sch_update = extract_ndp_sch_update_tlv, 22316 #endif 22317 .send_btm_config = send_btm_config_cmd_tlv, 22318 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 22319 .extract_obss_detection_info = extract_obss_detection_info_tlv, 22320 #ifdef WLAN_SUPPORT_FILS 22321 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 22322 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 22323 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 22324 #endif /* WLAN_SUPPORT_FILS */ 22325 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 22326 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 22327 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 22328 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 22329 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 22330 .wmi_check_command_params = wmitlv_check_command_tlv_params, 22331 .send_bss_color_change_enable_cmd = 22332 send_bss_color_change_enable_cmd_tlv, 22333 .send_obss_color_collision_cfg_cmd = 22334 send_obss_color_collision_cfg_cmd_tlv, 22335 .extract_obss_color_collision_info = 22336 extract_obss_color_collision_info_tlv, 22337 .extract_comb_phyerr = extract_comb_phyerr_tlv, 22338 .extract_single_phyerr = extract_single_phyerr_tlv, 22339 #ifdef QCA_SUPPORT_CP_STATS 22340 .extract_cca_stats = extract_cca_stats_tlv, 22341 #endif 22342 }; 22343 22344 /** 22345 * populate_tlv_event_id() - populates wmi event ids 22346 * 22347 * @param event_ids: Pointer to hold event ids 22348 * Return: None 22349 */ 22350 static void populate_tlv_events_id(uint32_t *event_ids) 22351 { 22352 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22353 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22354 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22355 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22356 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22357 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22358 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22359 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22360 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22361 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22362 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22363 event_ids[wmi_service_ready_ext_event_id] = 22364 WMI_SERVICE_READY_EXT_EVENTID; 22365 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22366 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22367 event_ids[wmi_vdev_install_key_complete_event_id] = 22368 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22369 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22370 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22371 22372 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22373 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22374 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22375 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22376 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22377 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22378 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22379 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22380 event_ids[wmi_peer_delete_response_event_id] = 22381 WMI_PEER_DELETE_RESP_EVENTID; 22382 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22383 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22384 event_ids[wmi_tbttoffset_update_event_id] = 22385 WMI_TBTTOFFSET_UPDATE_EVENTID; 22386 event_ids[wmi_ext_tbttoffset_update_event_id] = 22387 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22388 event_ids[wmi_offload_bcn_tx_status_event_id] = 22389 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22390 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22391 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22392 event_ids[wmi_mgmt_tx_completion_event_id] = 22393 WMI_MGMT_TX_COMPLETION_EVENTID; 22394 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22395 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22396 event_ids[wmi_tx_delba_complete_event_id] = 22397 WMI_TX_DELBA_COMPLETE_EVENTID; 22398 event_ids[wmi_tx_addba_complete_event_id] = 22399 WMI_TX_ADDBA_COMPLETE_EVENTID; 22400 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22401 22402 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22403 22404 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22405 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22406 22407 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22408 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22409 22410 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22411 22412 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22413 event_ids[wmi_p2p_lo_stop_event_id] = 22414 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22415 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22416 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22417 event_ids[wmi_d0_wow_disable_ack_event_id] = 22418 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22419 event_ids[wmi_wow_initial_wakeup_event_id] = 22420 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22421 22422 event_ids[wmi_rtt_meas_report_event_id] = 22423 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22424 event_ids[wmi_tsf_meas_report_event_id] = 22425 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22426 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22427 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22428 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22429 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22430 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22431 event_ids[wmi_diag_event_id_log_supported_event_id] = 22432 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22433 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22434 event_ids[wmi_nlo_scan_complete_event_id] = 22435 WMI_NLO_SCAN_COMPLETE_EVENTID; 22436 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22437 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22438 22439 event_ids[wmi_gtk_offload_status_event_id] = 22440 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22441 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22442 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22443 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22444 22445 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22446 22447 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22448 22449 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22450 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22451 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22452 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22453 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22454 event_ids[wmi_wlan_profile_data_event_id] = 22455 WMI_WLAN_PROFILE_DATA_EVENTID; 22456 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22457 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22458 event_ids[wmi_vdev_get_keepalive_event_id] = 22459 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22460 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22461 22462 event_ids[wmi_diag_container_event_id] = 22463 WMI_DIAG_DATA_CONTAINER_EVENTID; 22464 22465 event_ids[wmi_host_auto_shutdown_event_id] = 22466 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22467 22468 event_ids[wmi_update_whal_mib_stats_event_id] = 22469 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22470 22471 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22472 event_ids[wmi_update_vdev_rate_stats_event_id] = 22473 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22474 22475 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22476 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22477 22478 /** Set OCB Sched Response, deprecated */ 22479 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22480 22481 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22482 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22483 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22484 22485 /* GPIO Event */ 22486 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22487 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22488 22489 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22490 event_ids[wmi_rfkill_state_change_event_id] = 22491 WMI_RFKILL_STATE_CHANGE_EVENTID; 22492 22493 /* TDLS Event */ 22494 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22495 22496 event_ids[wmi_batch_scan_enabled_event_id] = 22497 WMI_BATCH_SCAN_ENABLED_EVENTID; 22498 event_ids[wmi_batch_scan_result_event_id] = 22499 WMI_BATCH_SCAN_RESULT_EVENTID; 22500 /* OEM Event */ 22501 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22502 event_ids[wmi_oem_meas_report_event_id] = 22503 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22504 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22505 22506 /* NAN Event */ 22507 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22508 22509 /* LPI Event */ 22510 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22511 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22512 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22513 22514 /* ExtScan events */ 22515 event_ids[wmi_extscan_start_stop_event_id] = 22516 WMI_EXTSCAN_START_STOP_EVENTID; 22517 event_ids[wmi_extscan_operation_event_id] = 22518 WMI_EXTSCAN_OPERATION_EVENTID; 22519 event_ids[wmi_extscan_table_usage_event_id] = 22520 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22521 event_ids[wmi_extscan_cached_results_event_id] = 22522 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22523 event_ids[wmi_extscan_wlan_change_results_event_id] = 22524 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22525 event_ids[wmi_extscan_hotlist_match_event_id] = 22526 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22527 event_ids[wmi_extscan_capabilities_event_id] = 22528 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22529 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22530 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22531 22532 /* mDNS offload events */ 22533 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22534 22535 /* SAP Authentication offload events */ 22536 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22537 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22538 22539 /** Out-of-context-of-bss (OCB) events */ 22540 event_ids[wmi_ocb_set_config_resp_event_id] = 22541 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22542 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22543 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22544 event_ids[wmi_dcc_get_stats_resp_event_id] = 22545 WMI_DCC_GET_STATS_RESP_EVENTID; 22546 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22547 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22548 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22549 /* System-On-Chip events */ 22550 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22551 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22552 event_ids[wmi_soc_hw_mode_transition_event_id] = 22553 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22554 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22555 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22556 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22557 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22558 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22559 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22560 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22561 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22562 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22563 WMI_PEER_STA_PS_STATECHG_EVENTID; 22564 event_ids[wmi_pdev_channel_hopping_event_id] = 22565 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22566 event_ids[wmi_offchan_data_tx_completion_event] = 22567 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22568 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22569 event_ids[wmi_dfs_radar_detection_event_id] = 22570 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22571 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22572 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22573 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22574 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22575 event_ids[wmi_service_available_event_id] = 22576 WMI_SERVICE_AVAILABLE_EVENTID; 22577 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22578 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22579 /* NDP events */ 22580 event_ids[wmi_ndp_initiator_rsp_event_id] = 22581 WMI_NDP_INITIATOR_RSP_EVENTID; 22582 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22583 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22584 event_ids[wmi_ndp_responder_rsp_event_id] = 22585 WMI_NDP_RESPONDER_RSP_EVENTID; 22586 event_ids[wmi_ndp_end_indication_event_id] = 22587 WMI_NDP_END_INDICATION_EVENTID; 22588 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22589 event_ids[wmi_ndl_schedule_update_event_id] = 22590 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22591 22592 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22593 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22594 event_ids[wmi_pdev_chip_power_stats_event_id] = 22595 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22596 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22597 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22598 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22599 event_ids[wmi_apf_capability_info_event_id] = 22600 WMI_BPF_CAPABILIY_INFO_EVENTID; 22601 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22602 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22603 event_ids[wmi_report_rx_aggr_failure_event_id] = 22604 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22605 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22606 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22607 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22608 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22609 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22610 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22611 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22612 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22613 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22614 event_ids[wmi_coex_bt_activity_event_id] = 22615 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22616 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22617 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22618 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22619 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22620 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22621 event_ids[wmi_dma_buf_release_event_id] = 22622 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22623 event_ids[wmi_sap_obss_detection_report_event_id] = 22624 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22625 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22626 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22627 event_ids[wmi_obss_color_collision_report_event_id] = 22628 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22629 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22630 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22631 event_ids[wmi_twt_enable_complete_event_id] = 22632 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22633 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22634 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22635 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22636 } 22637 22638 /** 22639 * populate_tlv_service() - populates wmi services 22640 * 22641 * @param wmi_service: Pointer to hold wmi_service 22642 * Return: None 22643 */ 22644 static void populate_tlv_service(uint32_t *wmi_service) 22645 { 22646 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22647 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22648 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22649 wmi_service[wmi_service_roam_scan_offload] = 22650 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22651 wmi_service[wmi_service_bcn_miss_offload] = 22652 WMI_SERVICE_BCN_MISS_OFFLOAD; 22653 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22654 wmi_service[wmi_service_sta_advanced_pwrsave] = 22655 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22656 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22657 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22658 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22659 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22660 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22661 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22662 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22663 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22664 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22665 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22666 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22667 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22668 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22669 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22670 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22671 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22672 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22673 wmi_service[wmi_service_packet_power_save] = 22674 WMI_SERVICE_PACKET_POWER_SAVE; 22675 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22676 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22677 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22678 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22679 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22680 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22681 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22682 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22683 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22684 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22685 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22686 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22687 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22688 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22689 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22690 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22691 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22692 wmi_service[wmi_service_mcc_bcn_interval_change] = 22693 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22694 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22695 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22696 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22697 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22698 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22699 wmi_service[wmi_service_lte_ant_share_support] = 22700 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22701 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22702 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22703 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22704 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22705 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22706 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22707 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22708 wmi_service[wmi_service_bcn_txrate_override] = 22709 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22710 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22711 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22712 wmi_service[wmi_service_estimate_linkspeed] = 22713 WMI_SERVICE_ESTIMATE_LINKSPEED; 22714 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22715 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22716 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22717 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22718 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22719 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22720 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22721 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22722 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22723 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22724 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22725 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22726 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22727 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22728 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22729 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22730 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22731 wmi_service[wmi_service_sap_auth_offload] = 22732 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22733 wmi_service[wmi_service_dual_band_simultaneous_support] = 22734 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22735 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22736 wmi_service[wmi_service_ap_arpns_offload] = 22737 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22738 wmi_service[wmi_service_per_band_chainmask_support] = 22739 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22740 wmi_service[wmi_service_packet_filter_offload] = 22741 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22742 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22743 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22744 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22745 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22746 wmi_service[wmi_service_multiple_vdev_restart] = 22747 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22748 22749 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22750 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22751 wmi_service[wmi_service_smart_antenna_sw_support] = 22752 WMI_SERVICE_UNAVAILABLE; 22753 wmi_service[wmi_service_smart_antenna_hw_support] = 22754 WMI_SERVICE_UNAVAILABLE; 22755 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22756 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22757 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22758 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22759 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22760 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22761 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22762 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22763 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22764 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22765 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22766 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22767 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22768 wmi_service[wmi_service_periodic_chan_stat_support] = 22769 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22770 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22771 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22772 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22773 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22774 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22775 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22776 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22777 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22778 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22779 wmi_service[wmi_service_unified_wow_capability] = 22780 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22781 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22782 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22783 wmi_service[wmi_service_sync_delete_cmds] = 22784 WMI_SERVICE_SYNC_DELETE_CMDS; 22785 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22786 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22787 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22788 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22789 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22790 wmi_service[wmi_service_deprecated_replace] = 22791 WMI_SERVICE_DEPRECATED_REPLACE; 22792 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22793 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22794 wmi_service[wmi_service_enhanced_mcast_filter] = 22795 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22796 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22797 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22798 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22799 wmi_service[wmi_service_p2p_listen_offload_support] = 22800 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22801 wmi_service[wmi_service_mark_first_wakeup_packet] = 22802 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22803 wmi_service[wmi_service_multiple_mcast_filter_set] = 22804 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22805 wmi_service[wmi_service_host_managed_rx_reorder] = 22806 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22807 wmi_service[wmi_service_flash_rdwr_support] = 22808 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22809 wmi_service[wmi_service_wlan_stats_report] = 22810 WMI_SERVICE_WLAN_STATS_REPORT; 22811 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22812 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22813 wmi_service[wmi_service_dfs_phyerr_offload] = 22814 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22815 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22816 wmi_service[wmi_service_fw_mem_dump_support] = 22817 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22818 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22819 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22820 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22821 wmi_service[wmi_service_hw_data_filtering] = 22822 WMI_SERVICE_HW_DATA_FILTERING; 22823 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22824 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22825 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22826 wmi_service[wmi_service_extended_nss_support] = 22827 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22828 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22829 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22830 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22831 wmi_service[wmi_service_offchan_data_tid_support] = 22832 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22833 wmi_service[wmi_service_support_dma] = 22834 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22835 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22836 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22837 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22838 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22839 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22840 wmi_service[wmi_service_11k_neighbour_report_support] = 22841 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22842 wmi_service[wmi_service_ap_obss_detection_offload] = 22843 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22844 wmi_service[wmi_service_bss_color_offload] = 22845 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22846 wmi_service[wmi_service_gmac_offload_support] = 22847 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22848 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22849 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22850 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22851 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22852 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22853 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22854 wmi_service[wmi_service_listen_interval_offload_support] = 22855 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22856 22857 } 22858 22859 #ifndef CONFIG_MCL 22860 22861 /** 22862 * populate_pdev_param_tlv() - populates pdev params 22863 * 22864 * @param pdev_param: Pointer to hold pdev params 22865 * Return: None 22866 */ 22867 static void populate_pdev_param_tlv(uint32_t *pdev_param) 22868 { 22869 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 22870 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 22871 pdev_param[wmi_pdev_param_txpower_limit2g] = 22872 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 22873 pdev_param[wmi_pdev_param_txpower_limit5g] = 22874 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 22875 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 22876 pdev_param[wmi_pdev_param_beacon_gen_mode] = 22877 WMI_PDEV_PARAM_BEACON_GEN_MODE; 22878 pdev_param[wmi_pdev_param_beacon_tx_mode] = 22879 WMI_PDEV_PARAM_BEACON_TX_MODE; 22880 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 22881 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 22882 pdev_param[wmi_pdev_param_protection_mode] = 22883 WMI_PDEV_PARAM_PROTECTION_MODE; 22884 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 22885 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 22886 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 22887 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 22888 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 22889 pdev_param[wmi_pdev_param_sta_kickout_th] = 22890 WMI_PDEV_PARAM_STA_KICKOUT_TH; 22891 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 22892 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 22893 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 22894 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 22895 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 22896 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 22897 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 22898 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 22899 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 22900 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 22901 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 22902 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 22903 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 22904 pdev_param[wmi_pdev_param_ltr_sleep_override] = 22905 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 22906 pdev_param[wmi_pdev_param_ltr_rx_override] = 22907 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 22908 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 22909 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 22910 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 22911 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 22912 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 22913 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 22914 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 22915 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 22916 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 22917 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 22918 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 22919 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 22920 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 22921 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 22922 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 22923 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 22924 pdev_param[wmi_pdev_param_peer_stats_update_period] = 22925 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 22926 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 22927 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 22928 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 22929 pdev_param[wmi_pdev_param_arp_ac_override] = 22930 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 22931 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 22932 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 22933 pdev_param[wmi_pdev_param_ani_poll_period] = 22934 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 22935 pdev_param[wmi_pdev_param_ani_listen_period] = 22936 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 22937 pdev_param[wmi_pdev_param_ani_ofdm_level] = 22938 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 22939 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 22940 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 22941 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 22942 pdev_param[wmi_pdev_param_idle_ps_config] = 22943 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 22944 pdev_param[wmi_pdev_param_power_gating_sleep] = 22945 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 22946 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 22947 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 22948 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 22949 pdev_param[wmi_pdev_param_hw_rfkill_config] = 22950 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 22951 pdev_param[wmi_pdev_param_low_power_rf_enable] = 22952 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 22953 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 22954 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 22955 pdev_param[wmi_pdev_param_power_collapse_enable] = 22956 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 22957 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 22958 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 22959 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 22960 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 22961 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 22962 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 22963 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 22964 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 22965 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 22966 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 22967 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 22968 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 22969 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 22970 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 22971 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 22972 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 22973 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 22974 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 22975 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 22976 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 22977 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 22978 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 22979 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 22980 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 22981 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 22982 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 22983 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 22984 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 22985 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 22986 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 22987 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 22988 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 22989 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 22990 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 22991 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 22992 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 22993 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 22994 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 22995 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 22996 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 22997 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 22998 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 22999 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23000 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23001 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23002 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23003 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23004 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23005 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23006 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23007 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23008 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23009 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23010 WMI_PDEV_PARAM_PROXY_STA_MODE; 23011 pdev_param[wmi_pdev_param_mu_group_policy] = 23012 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23013 pdev_param[wmi_pdev_param_noise_detection] = 23014 WMI_PDEV_PARAM_NOISE_DETECTION; 23015 pdev_param[wmi_pdev_param_noise_threshold] = 23016 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23017 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23018 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23019 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23020 pdev_param[wmi_pdev_param_atf_strict_sch] = 23021 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23022 pdev_param[wmi_pdev_param_atf_sched_duration] = 23023 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23024 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23025 pdev_param[wmi_pdev_param_sensitivity_level] = 23026 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23027 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23028 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23029 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23030 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23031 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23032 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23033 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23034 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23035 pdev_param[wmi_pdev_param_cca_threshold] = 23036 WMI_PDEV_PARAM_CCA_THRESHOLD; 23037 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23038 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23039 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23040 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23041 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23042 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23043 pdev_param[wmi_pdev_param_arp_srcaddr] = 23044 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23045 pdev_param[wmi_pdev_param_arp_dstaddr] = 23046 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23047 pdev_param[wmi_pdev_param_txpower_decr_db] = 23048 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23049 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23050 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23051 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23052 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23053 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23054 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23055 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23056 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23057 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23058 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23059 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23060 WMI_UNAVAILABLE_PARAM; 23061 pdev_param[wmi_pdev_param_igmpmld_override] = 23062 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23063 pdev_param[wmi_pdev_param_igmpmld_tid] = 23064 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23065 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23066 pdev_param[wmi_pdev_param_block_interbss] = 23067 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23068 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23069 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23070 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23071 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23072 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23073 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23074 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23075 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23076 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23077 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23078 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23079 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23080 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23081 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23082 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23083 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23084 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23085 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23086 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23087 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23088 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23089 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23090 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23091 pdev_param[wmi_pdev_param_fast_channel_reset] = 23092 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23093 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23094 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23095 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23096 pdev_param[wmi_pdev_param_antenna_gain_half_db] = 23097 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB; 23098 } 23099 23100 /** 23101 * populate_vdev_param_tlv() - populates vdev params 23102 * 23103 * @param vdev_param: Pointer to hold vdev params 23104 * Return: None 23105 */ 23106 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23107 { 23108 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23109 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23110 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23111 vdev_param[wmi_vdev_param_beacon_interval] = 23112 WMI_VDEV_PARAM_BEACON_INTERVAL; 23113 vdev_param[wmi_vdev_param_listen_interval] = 23114 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23115 vdev_param[wmi_vdev_param_multicast_rate] = 23116 WMI_VDEV_PARAM_MULTICAST_RATE; 23117 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23118 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23119 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23120 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23121 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23122 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23123 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23124 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23125 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23126 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23127 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23128 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23129 vdev_param[wmi_vdev_param_bmiss_count_max] = 23130 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23131 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23132 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23133 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23134 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23135 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23136 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23137 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23138 vdev_param[wmi_vdev_param_disable_htprotection] = 23139 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23140 vdev_param[wmi_vdev_param_sta_quickkickout] = 23141 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23142 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23143 vdev_param[wmi_vdev_param_protection_mode] = 23144 WMI_VDEV_PARAM_PROTECTION_MODE; 23145 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23146 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23147 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23148 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23149 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23150 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23151 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23152 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23153 vdev_param[wmi_vdev_param_bcast_data_rate] = 23154 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23155 vdev_param[wmi_vdev_param_mcast_data_rate] = 23156 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23157 vdev_param[wmi_vdev_param_mcast_indicate] = 23158 WMI_VDEV_PARAM_MCAST_INDICATE; 23159 vdev_param[wmi_vdev_param_dhcp_indicate] = 23160 WMI_VDEV_PARAM_DHCP_INDICATE; 23161 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23162 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23163 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23164 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23165 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23166 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23167 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23168 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23169 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23170 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23171 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23172 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23173 vdev_param[wmi_vdev_param_packet_powersave] = 23174 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23175 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23176 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23177 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23178 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23179 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23180 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23181 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23182 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23183 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23184 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23185 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23186 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23187 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23188 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23189 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23190 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23191 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23192 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23193 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23194 vdev_param[wmi_vdev_param_roam_fw_offload] = 23195 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23196 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23197 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23198 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23199 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23200 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23201 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23202 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23203 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23204 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23205 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23206 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23207 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23208 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23209 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23210 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23211 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23212 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23213 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23214 vdev_param[wmi_vdev_param_inactivity_cnt] = 23215 WMI_VDEV_PARAM_INACTIVITY_CNT; 23216 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23217 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23218 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23219 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23220 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23221 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23222 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23223 vdev_param[wmi_vdev_param_rx_leak_window] = 23224 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23225 vdev_param[wmi_vdev_param_stats_avg_factor] = 23226 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23227 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23228 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23229 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23230 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23231 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23232 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23233 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23234 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23235 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23236 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23237 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23238 WMI_VDEV_PARAM_HE_RANGE_EXT; 23239 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23240 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23241 vdev_param[wmi_vdev_param_set_he_sounding_mode] 23242 = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 23243 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 23244 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 23245 vdev_param[wmi_vdev_param_dtim_enable_cts] = 23246 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 23247 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 23248 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 23249 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 23250 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 23251 vdev_param[wmi_vdev_param_mcast2ucast_set] = 23252 WMI_VDEV_PARAM_MCAST2UCAST_SET; 23253 vdev_param[wmi_vdev_param_rc_num_retries] = 23254 WMI_VDEV_PARAM_RC_NUM_RETRIES; 23255 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 23256 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 23257 vdev_param[wmi_vdev_param_rts_fixed_rate] = 23258 WMI_VDEV_PARAM_RTS_FIXED_RATE; 23259 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 23260 vdev_param[wmi_vdev_param_vht80_ratemask] = 23261 WMI_VDEV_PARAM_VHT80_RATEMASK; 23262 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 23263 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 23264 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 23265 vdev_param[wmi_vdev_param_set_he_ltf] = 23266 WMI_VDEV_PARAM_HE_LTF; 23267 vdev_param[wmi_vdev_param_disable_cabq] = 23268 WMI_VDEV_PARAM_DISABLE_CABQ; 23269 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 23270 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 23271 vdev_param[wmi_vdev_param_set_ba_mode] = 23272 WMI_VDEV_PARAM_BA_MODE; 23273 vdev_param[wmi_vdev_param_capabilities] = 23274 WMI_VDEV_PARAM_CAPABILITIES; 23275 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 23276 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 23277 } 23278 #endif 23279 23280 /** 23281 * populate_target_defines_tlv() - Populate target defines and params 23282 * @wmi_handle: pointer to wmi handle 23283 * 23284 * Return: None 23285 */ 23286 #ifndef CONFIG_MCL 23287 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23288 { 23289 populate_pdev_param_tlv(wmi_handle->pdev_param); 23290 populate_vdev_param_tlv(wmi_handle->vdev_param); 23291 } 23292 #else 23293 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 23294 { } 23295 #endif 23296 23297 /** 23298 * wmi_ocb_ut_attach() - Attach OCB test framework 23299 * @wmi_handle: wmi handle 23300 * 23301 * Return: None 23302 */ 23303 #ifdef WLAN_OCB_UT 23304 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23305 #else 23306 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23307 { 23308 return; 23309 } 23310 #endif 23311 23312 /** 23313 * wmi_tlv_attach() - Attach TLV APIs 23314 * 23315 * Return: None 23316 */ 23317 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23318 { 23319 wmi_handle->ops = &tlv_ops; 23320 wmi_ocb_ut_attach(wmi_handle); 23321 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23322 #ifdef WMI_INTERFACE_EVENT_LOGGING 23323 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23324 wmi_handle->log_info.buf_offset_command = 8; 23325 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23326 wmi_handle->log_info.buf_offset_event = 4; 23327 #endif 23328 populate_tlv_events_id(wmi_handle->wmi_events); 23329 populate_tlv_service(wmi_handle->services); 23330 populate_target_defines_tlv(wmi_handle); 23331 wmi_twt_attach_tlv(wmi_handle); 23332 wmi_extscan_attach_tlv(wmi_handle); 23333 } 23334 qdf_export_symbol(wmi_tlv_attach); 23335 23336 /** 23337 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23338 * 23339 * Return: None 23340 */ 23341 void wmi_tlv_init(void) 23342 { 23343 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23344 } 23345