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 #ifdef FEATURE_WLAN_TDLS 54 #include "wlan_tdls_public_structs.h" 55 #endif 56 57 /* HTC service ids for WMI for multi-radio */ 58 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 59 WMI_CONTROL_SVC_WMAC1, 60 WMI_CONTROL_SVC_WMAC2}; 61 62 /** 63 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 64 * host to target defines. 65 * @param pdev_id: host pdev_id to be converted. 66 * Return: target pdev_id after conversion. 67 */ 68 static uint32_t convert_host_pdev_id_to_target_pdev_id(uint32_t pdev_id) 69 { 70 switch (pdev_id) { 71 case WMI_HOST_PDEV_ID_SOC: 72 return WMI_PDEV_ID_SOC; 73 case WMI_HOST_PDEV_ID_0: 74 return WMI_PDEV_ID_1ST; 75 case WMI_HOST_PDEV_ID_1: 76 return WMI_PDEV_ID_2ND; 77 case WMI_HOST_PDEV_ID_2: 78 return WMI_PDEV_ID_3RD; 79 } 80 81 QDF_ASSERT(0); 82 83 return WMI_PDEV_ID_SOC; 84 } 85 86 /** 87 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 88 * target to host defines. 89 * @param pdev_id: target pdev_id to be converted. 90 * Return: host pdev_id after conversion. 91 */ 92 static uint32_t convert_target_pdev_id_to_host_pdev_id(uint32_t pdev_id) 93 { 94 switch (pdev_id) { 95 case WMI_PDEV_ID_SOC: 96 return WMI_HOST_PDEV_ID_SOC; 97 case WMI_PDEV_ID_1ST: 98 return WMI_HOST_PDEV_ID_0; 99 case WMI_PDEV_ID_2ND: 100 return WMI_HOST_PDEV_ID_1; 101 case WMI_PDEV_ID_3RD: 102 return WMI_HOST_PDEV_ID_2; 103 } 104 105 QDF_ASSERT(0); 106 107 return WMI_HOST_PDEV_ID_SOC; 108 } 109 110 /** 111 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 112 * 113 * Return None. 114 */ 115 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle) 116 { 117 wmi_handle->ops->convert_pdev_id_host_to_target = 118 convert_host_pdev_id_to_target_pdev_id; 119 wmi_handle->ops->convert_pdev_id_target_to_host = 120 convert_target_pdev_id_to_host_pdev_id; 121 } 122 123 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 124 * buffer. 125 * @wmi_handle: pointer to wmi_handle 126 * @cmd: pointer target vdev create command buffer 127 * @param: pointer host params for vdev create 128 * 129 * Return: None 130 */ 131 #ifdef CONFIG_MCL 132 static inline void copy_vdev_create_pdev_id( 133 struct wmi_unified *wmi_handle, 134 wmi_vdev_create_cmd_fixed_param * cmd, 135 struct vdev_create_params *param) 136 { 137 cmd->pdev_id = WMI_PDEV_ID_SOC; 138 } 139 #else 140 static inline void copy_vdev_create_pdev_id( 141 struct wmi_unified *wmi_handle, 142 wmi_vdev_create_cmd_fixed_param * cmd, 143 struct vdev_create_params *param) 144 { 145 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 146 param->pdev_id); 147 } 148 #endif 149 150 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 151 { 152 uint16_t mtrace_message_id; 153 154 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 155 (QDF_WMI_MTRACE_GRP_ID(message_id) << 156 QDF_WMI_MTRACE_CMD_NUM_BITS); 157 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 158 mtrace_message_id, vdev_id, data); 159 } 160 161 qdf_export_symbol(wmi_mtrace); 162 163 /** 164 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 165 * @wmi_handle: wmi handle 166 * @param: pointer to hold vdev create parameter 167 * @macaddr: vdev mac address 168 * 169 * Return: QDF_STATUS_SUCCESS for success or error code 170 */ 171 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 172 uint8_t macaddr[IEEE80211_ADDR_LEN], 173 struct vdev_create_params *param) 174 { 175 wmi_vdev_create_cmd_fixed_param *cmd; 176 wmi_buf_t buf; 177 int32_t len = sizeof(*cmd); 178 QDF_STATUS ret; 179 int num_bands = 2; 180 uint8_t *buf_ptr; 181 wmi_vdev_txrx_streams *txrx_streams; 182 183 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 184 buf = wmi_buf_alloc(wmi_handle, len); 185 if (!buf) { 186 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 187 return QDF_STATUS_E_NOMEM; 188 } 189 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 190 WMITLV_SET_HDR(&cmd->tlv_header, 191 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 192 WMITLV_GET_STRUCT_TLVLEN 193 (wmi_vdev_create_cmd_fixed_param)); 194 cmd->vdev_id = param->if_id; 195 cmd->vdev_type = param->type; 196 cmd->vdev_subtype = param->subtype; 197 cmd->flags = param->mbssid_flags; 198 cmd->vdevid_trans = param->vdevid_trans; 199 cmd->num_cfg_txrx_streams = num_bands; 200 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 201 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 202 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 203 __func__, param->if_id, cmd->pdev_id, 204 macaddr[0], macaddr[1], macaddr[2], 205 macaddr[3], macaddr[4], macaddr[5]); 206 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 207 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 208 (num_bands * sizeof(wmi_vdev_txrx_streams))); 209 buf_ptr += WMI_TLV_HDR_SIZE; 210 211 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 212 param->type, param->subtype, 213 param->nss_2g, param->nss_5g); 214 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 215 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 216 txrx_streams->supported_tx_streams = param->nss_2g; 217 txrx_streams->supported_rx_streams = param->nss_2g; 218 WMITLV_SET_HDR(&txrx_streams->tlv_header, 219 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 220 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 221 222 txrx_streams++; 223 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 224 txrx_streams->supported_tx_streams = param->nss_5g; 225 txrx_streams->supported_rx_streams = param->nss_5g; 226 WMITLV_SET_HDR(&txrx_streams->tlv_header, 227 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 228 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 229 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 230 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 231 if (QDF_IS_STATUS_ERROR(ret)) { 232 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 233 wmi_buf_free(buf); 234 } 235 236 return ret; 237 } 238 239 /** 240 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 241 * @wmi_handle: wmi handle 242 * @if_id: vdev id 243 * 244 * Return: QDF_STATUS_SUCCESS for success or error code 245 */ 246 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 247 uint8_t if_id) 248 { 249 wmi_vdev_delete_cmd_fixed_param *cmd; 250 wmi_buf_t buf; 251 QDF_STATUS ret; 252 253 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 254 if (!buf) { 255 WMI_LOGP("%s:wmi_buf_alloc failed", __func__); 256 return QDF_STATUS_E_NOMEM; 257 } 258 259 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 260 WMITLV_SET_HDR(&cmd->tlv_header, 261 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 262 WMITLV_GET_STRUCT_TLVLEN 263 (wmi_vdev_delete_cmd_fixed_param)); 264 cmd->vdev_id = if_id; 265 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 266 ret = wmi_unified_cmd_send(wmi_handle, buf, 267 sizeof(wmi_vdev_delete_cmd_fixed_param), 268 WMI_VDEV_DELETE_CMDID); 269 if (QDF_IS_STATUS_ERROR(ret)) { 270 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 271 wmi_buf_free(buf); 272 } 273 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 274 275 return ret; 276 } 277 278 /** 279 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 280 * @wmi: wmi handle 281 * @vdev_id: vdev id 282 * 283 * Return: QDF_STATUS_SUCCESS for success or erro code 284 */ 285 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 286 uint8_t vdev_id) 287 { 288 wmi_vdev_stop_cmd_fixed_param *cmd; 289 wmi_buf_t buf; 290 int32_t len = sizeof(*cmd); 291 292 buf = wmi_buf_alloc(wmi, len); 293 if (!buf) { 294 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 295 return QDF_STATUS_E_NOMEM; 296 } 297 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 298 WMITLV_SET_HDR(&cmd->tlv_header, 299 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 300 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 301 cmd->vdev_id = vdev_id; 302 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 303 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 304 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 305 wmi_buf_free(buf); 306 return QDF_STATUS_E_FAILURE; 307 } 308 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 309 310 return 0; 311 } 312 313 /** 314 * send_vdev_down_cmd_tlv() - send vdev down command to fw 315 * @wmi: wmi handle 316 * @vdev_id: vdev id 317 * 318 * Return: QDF_STATUS_SUCCESS for success or error code 319 */ 320 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 321 { 322 wmi_vdev_down_cmd_fixed_param *cmd; 323 wmi_buf_t buf; 324 int32_t len = sizeof(*cmd); 325 326 buf = wmi_buf_alloc(wmi, len); 327 if (!buf) { 328 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 329 return QDF_STATUS_E_NOMEM; 330 } 331 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 332 WMITLV_SET_HDR(&cmd->tlv_header, 333 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 334 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 335 cmd->vdev_id = vdev_id; 336 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 337 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 338 WMI_LOGP("%s: Failed to send vdev down", __func__); 339 wmi_buf_free(buf); 340 return QDF_STATUS_E_FAILURE; 341 } 342 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 343 344 return 0; 345 } 346 347 #ifdef CONFIG_MCL 348 static inline void copy_channel_info( 349 wmi_vdev_start_request_cmd_fixed_param * cmd, 350 wmi_channel *chan, 351 struct vdev_start_params *req) 352 { 353 chan->mhz = req->chan_freq; 354 355 WMI_SET_CHANNEL_MODE(chan, req->chan_mode); 356 357 chan->band_center_freq1 = req->band_center_freq1; 358 chan->band_center_freq2 = req->band_center_freq2; 359 360 if (req->is_half_rate) 361 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 362 else if (req->is_quarter_rate) 363 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 364 365 if (req->is_dfs && req->flag_dfs) { 366 WMI_SET_CHANNEL_FLAG(chan, req->flag_dfs); 367 cmd->disable_hw_ack = req->dis_hw_ack; 368 } 369 370 WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); 371 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); 372 373 } 374 #else 375 static inline void copy_channel_info( 376 wmi_vdev_start_request_cmd_fixed_param * cmd, 377 wmi_channel *chan, 378 struct vdev_start_params *req) 379 { 380 chan->mhz = req->channel.mhz; 381 382 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 383 384 chan->band_center_freq1 = req->channel.cfreq1; 385 chan->band_center_freq2 = req->channel.cfreq2; 386 WMI_LOGI("%s: req->channel.phy_mode: %d ", req->channel.phy_mode); 387 388 if (req->channel.half_rate) 389 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 390 else if (req->channel.quarter_rate) 391 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 392 393 WMI_LOGI("%s: req->channel.dfs_set: %d ", req->channel.dfs_set); 394 395 if (req->channel.dfs_set) { 396 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 397 cmd->disable_hw_ack = req->disable_hw_ack; 398 } 399 400 if (req->channel.dfs_set_cfreq2) 401 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 402 403 /* According to firmware both reg power and max tx power 404 * on set channel power is used and set it to max reg 405 * power from regulatory. 406 */ 407 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 408 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 409 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 410 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 411 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 412 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 413 414 } 415 #endif 416 /** 417 * send_vdev_start_cmd_tlv() - send vdev start request to fw 418 * @wmi_handle: wmi handle 419 * @req: vdev start params 420 * 421 * Return: QDF status 422 */ 423 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 424 struct vdev_start_params *req) 425 { 426 wmi_vdev_start_request_cmd_fixed_param *cmd; 427 wmi_buf_t buf; 428 wmi_channel *chan; 429 int32_t len, ret; 430 uint8_t *buf_ptr; 431 432 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 433 buf = wmi_buf_alloc(wmi_handle, len); 434 if (!buf) { 435 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 436 return QDF_STATUS_E_NOMEM; 437 } 438 buf_ptr = (uint8_t *) wmi_buf_data(buf); 439 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 440 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 441 WMITLV_SET_HDR(&cmd->tlv_header, 442 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 443 WMITLV_GET_STRUCT_TLVLEN 444 (wmi_vdev_start_request_cmd_fixed_param)); 445 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 446 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 447 cmd->vdev_id = req->vdev_id; 448 449 /* Fill channel info */ 450 copy_channel_info(cmd, chan, req); 451 452 cmd->beacon_interval = req->beacon_intval; 453 cmd->dtim_period = req->dtim_period; 454 455 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 456 if (req->bcn_tx_rate_code) 457 cmd->flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; 458 459 if (!req->is_restart) { 460 cmd->beacon_interval = req->beacon_intval; 461 cmd->dtim_period = req->dtim_period; 462 463 /* Copy the SSID */ 464 if (req->ssid.length) { 465 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 466 cmd->ssid.ssid_len = req->ssid.length; 467 else 468 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 469 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 470 cmd->ssid.ssid_len); 471 } 472 473 if (req->hidden_ssid) 474 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 475 476 if (req->pmf_enabled) 477 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 478 } 479 480 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 481 cmd->num_noa_descriptors = req->num_noa_descriptors; 482 cmd->preferred_rx_streams = req->preferred_rx_streams; 483 cmd->preferred_tx_streams = req->preferred_tx_streams; 484 cmd->cac_duration_ms = req->cac_duration_ms; 485 cmd->regdomain = req->regdomain; 486 cmd->he_ops = req->he_ops; 487 488 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 489 sizeof(wmi_channel)); 490 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 491 cmd->num_noa_descriptors * 492 sizeof(wmi_p2p_noa_descriptor)); 493 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 494 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 495 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 496 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 497 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 498 chan->mhz, req->chan_mode, chan->info, 499 req->is_dfs, req->beacon_intval, cmd->dtim_period, 500 chan->band_center_freq1, chan->band_center_freq2, 501 chan->reg_info_1, chan->reg_info_2, req->max_txpow, 502 req->preferred_tx_streams, req->preferred_rx_streams, 503 req->ldpc_rx_enabled, req->cac_duration_ms, 504 req->regdomain, req->he_ops, 505 req->dis_hw_ack); 506 507 if (req->is_restart) { 508 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 509 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 510 WMI_VDEV_RESTART_REQUEST_CMDID); 511 } else { 512 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 513 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 514 WMI_VDEV_START_REQUEST_CMDID); 515 } 516 if (ret) { 517 WMI_LOGP("%s: Failed to send vdev start command", __func__); 518 wmi_buf_free(buf); 519 return QDF_STATUS_E_FAILURE; 520 } 521 522 return QDF_STATUS_SUCCESS; 523 } 524 525 /** 526 * send_hidden_ssid_vdev_restart_cmd_tlv() - restart vdev to set hidden ssid 527 * @wmi_handle: wmi handle 528 * @restart_params: vdev restart params 529 * 530 * Return: QDF_STATUS_SUCCESS for success or error code 531 */ 532 static QDF_STATUS send_hidden_ssid_vdev_restart_cmd_tlv(wmi_unified_t wmi_handle, 533 struct hidden_ssid_vdev_restart_params *restart_params) 534 { 535 wmi_vdev_start_request_cmd_fixed_param *cmd; 536 wmi_buf_t buf; 537 wmi_channel *chan; 538 int32_t len; 539 uint8_t *buf_ptr; 540 QDF_STATUS ret = 0; 541 542 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 543 buf = wmi_buf_alloc(wmi_handle, len); 544 if (!buf) { 545 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 546 return QDF_STATUS_E_NOMEM; 547 } 548 buf_ptr = (uint8_t *) wmi_buf_data(buf); 549 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 550 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 551 552 WMITLV_SET_HDR(&cmd->tlv_header, 553 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 554 WMITLV_GET_STRUCT_TLVLEN 555 (wmi_vdev_start_request_cmd_fixed_param)); 556 557 WMITLV_SET_HDR(&chan->tlv_header, 558 WMITLV_TAG_STRUC_wmi_channel, 559 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 560 561 cmd->vdev_id = restart_params->session_id; 562 cmd->ssid.ssid_len = restart_params->ssid_len; 563 qdf_mem_copy(cmd->ssid.ssid, 564 restart_params->ssid, 565 cmd->ssid.ssid_len); 566 cmd->flags = restart_params->flags; 567 cmd->requestor_id = restart_params->requestor_id; 568 cmd->disable_hw_ack = restart_params->disable_hw_ack; 569 570 chan->mhz = restart_params->mhz; 571 chan->band_center_freq1 = 572 restart_params->band_center_freq1; 573 chan->band_center_freq2 = 574 restart_params->band_center_freq2; 575 chan->info = restart_params->info; 576 chan->reg_info_1 = restart_params->reg_info_1; 577 chan->reg_info_2 = restart_params->reg_info_2; 578 579 cmd->num_noa_descriptors = 0; 580 buf_ptr = (uint8_t *) (((uint8_t *) cmd) + sizeof(*cmd) + 581 sizeof(wmi_channel)); 582 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 583 cmd->num_noa_descriptors * 584 sizeof(wmi_p2p_noa_descriptor)); 585 586 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 587 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 588 WMI_VDEV_RESTART_REQUEST_CMDID); 589 if (QDF_IS_STATUS_ERROR(ret)) { 590 wmi_buf_free(buf); 591 return QDF_STATUS_E_FAILURE; 592 } 593 return QDF_STATUS_SUCCESS; 594 } 595 596 597 /** 598 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 599 * @wmi: wmi handle 600 * @peer_addr: peer mac address 601 * @param: pointer to hold peer flush tid parameter 602 * 603 * Return: 0 for success or error code 604 */ 605 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 606 uint8_t peer_addr[IEEE80211_ADDR_LEN], 607 struct peer_flush_params *param) 608 { 609 wmi_peer_flush_tids_cmd_fixed_param *cmd; 610 wmi_buf_t buf; 611 int32_t len = sizeof(*cmd); 612 613 buf = wmi_buf_alloc(wmi, len); 614 if (!buf) { 615 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 616 return QDF_STATUS_E_NOMEM; 617 } 618 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 619 WMITLV_SET_HDR(&cmd->tlv_header, 620 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 621 WMITLV_GET_STRUCT_TLVLEN 622 (wmi_peer_flush_tids_cmd_fixed_param)); 623 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 624 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 625 cmd->vdev_id = param->vdev_id; 626 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 627 peer_addr, param->vdev_id, 628 param->peer_tid_bitmap); 629 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 630 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 631 WMI_LOGP("%s: Failed to send flush tid command", __func__); 632 wmi_buf_free(buf); 633 return QDF_STATUS_E_FAILURE; 634 } 635 636 return 0; 637 } 638 639 /** 640 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 641 * @wmi: wmi handle 642 * @peer_addr: peer mac addr 643 * @vdev_id: vdev id 644 * 645 * Return: QDF_STATUS_SUCCESS for success or error code 646 */ 647 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 648 uint8_t peer_addr[IEEE80211_ADDR_LEN], 649 uint8_t vdev_id) 650 { 651 wmi_peer_delete_cmd_fixed_param *cmd; 652 wmi_buf_t buf; 653 int32_t len = sizeof(*cmd); 654 buf = wmi_buf_alloc(wmi, len); 655 if (!buf) { 656 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 657 return QDF_STATUS_E_NOMEM; 658 } 659 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 660 WMITLV_SET_HDR(&cmd->tlv_header, 661 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 662 WMITLV_GET_STRUCT_TLVLEN 663 (wmi_peer_delete_cmd_fixed_param)); 664 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 665 cmd->vdev_id = vdev_id; 666 667 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 668 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 669 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 670 WMI_LOGP("%s: Failed to send peer delete command", __func__); 671 wmi_buf_free(buf); 672 return QDF_STATUS_E_FAILURE; 673 } 674 675 return 0; 676 } 677 678 /** 679 * convert_host_peer_id_to_target_id_tlv - convert host peer param_id 680 * to target id. 681 * @targ_paramid: Target parameter id to hold the result. 682 * @peer_param_id: host param id. 683 * 684 * Return: QDF_STATUS_SUCCESS for success 685 * QDF_STATUS_E_NOSUPPORT when the param_id in not supported in tareget 686 */ 687 #ifdef CONFIG_MCL 688 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 689 uint32_t *targ_paramid, 690 uint32_t peer_param_id) 691 { 692 *targ_paramid = peer_param_id; 693 return QDF_STATUS_SUCCESS; 694 } 695 696 /** 697 * crash_on_send_peer_rx_reorder_queue_remove_cmd() - crash on reorder queue cmd 698 * 699 * On MCL side, we are suspecting this cmd to trigger drop of ARP 700 * response frames from REO by the FW. This function causes a crash if this 701 * command is sent out by the host, so we can track this issue. Ideally no one 702 * should be calling this API from the MCL side 703 * 704 * Return: None 705 */ 706 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 707 { 708 QDF_BUG(0); 709 } 710 #else 711 static QDF_STATUS convert_host_peer_id_to_target_id_tlv( 712 uint32_t *targ_paramid, 713 uint32_t peer_param_id) 714 { 715 switch (peer_param_id) { 716 case WMI_HOST_PEER_MIMO_PS_STATE: 717 *targ_paramid = WMI_PEER_MIMO_PS_STATE; 718 break; 719 case WMI_HOST_PEER_AMPDU: 720 *targ_paramid = WMI_PEER_AMPDU; 721 break; 722 case WMI_HOST_PEER_AUTHORIZE: 723 *targ_paramid = WMI_PEER_AUTHORIZE; 724 break; 725 case WMI_HOST_PEER_CHWIDTH: 726 *targ_paramid = WMI_PEER_CHWIDTH; 727 break; 728 case WMI_HOST_PEER_NSS: 729 *targ_paramid = WMI_PEER_NSS; 730 break; 731 case WMI_HOST_PEER_USE_4ADDR: 732 *targ_paramid = WMI_PEER_USE_4ADDR; 733 break; 734 case WMI_HOST_PEER_MEMBERSHIP: 735 *targ_paramid = WMI_PEER_MEMBERSHIP; 736 break; 737 case WMI_HOST_PEER_USERPOS: 738 *targ_paramid = WMI_PEER_USERPOS; 739 break; 740 case WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED: 741 *targ_paramid = WMI_PEER_CRIT_PROTO_HINT_ENABLED; 742 break; 743 case WMI_HOST_PEER_TX_FAIL_CNT_THR: 744 *targ_paramid = WMI_PEER_TX_FAIL_CNT_THR; 745 break; 746 case WMI_HOST_PEER_SET_HW_RETRY_CTS2S: 747 *targ_paramid = WMI_PEER_SET_HW_RETRY_CTS2S; 748 break; 749 case WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH: 750 *targ_paramid = WMI_PEER_IBSS_ATIM_WINDOW_LENGTH; 751 break; 752 case WMI_HOST_PEER_PHYMODE: 753 *targ_paramid = WMI_PEER_PHYMODE; 754 break; 755 case WMI_HOST_PEER_USE_FIXED_PWR: 756 *targ_paramid = WMI_PEER_USE_FIXED_PWR; 757 break; 758 case WMI_HOST_PEER_PARAM_FIXED_RATE: 759 *targ_paramid = WMI_PEER_PARAM_FIXED_RATE; 760 break; 761 case WMI_HOST_PEER_SET_MU_WHITELIST: 762 *targ_paramid = WMI_PEER_SET_MU_WHITELIST; 763 break; 764 case WMI_HOST_PEER_SET_MAC_TX_RATE: 765 *targ_paramid = WMI_PEER_SET_MAX_TX_RATE; 766 break; 767 case WMI_HOST_PEER_SET_MIN_TX_RATE: 768 *targ_paramid = WMI_PEER_SET_MIN_TX_RATE; 769 break; 770 case WMI_HOST_PEER_SET_DEFAULT_ROUTING: 771 *targ_paramid = WMI_PEER_SET_DEFAULT_ROUTING; 772 break; 773 case WMI_HOST_PEER_NSS_VHT160: 774 *targ_paramid = WMI_PEER_NSS_VHT160; 775 break; 776 case WMI_HOST_PEER_NSS_VHT80_80: 777 *targ_paramid = WMI_PEER_NSS_VHT80_80; 778 break; 779 case WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL: 780 *targ_paramid = WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL; 781 break; 782 case WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL: 783 *targ_paramid = WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL; 784 break; 785 case WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE: 786 *targ_paramid = WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE; 787 break; 788 case WMI_HOST_PEER_PARAM_MU_ENABLE: 789 *targ_paramid = WMI_PEER_PARAM_MU_ENABLE; 790 break; 791 case WMI_HOST_PEER_PARAM_OFDMA_ENABLE: 792 *targ_paramid = WMI_PEER_PARAM_OFDMA_ENABLE; 793 break; 794 default: 795 return QDF_STATUS_E_NOSUPPORT; 796 } 797 798 return QDF_STATUS_SUCCESS; 799 } 800 801 static void crash_on_send_peer_rx_reorder_queue_remove_cmd(void) 802 { 803 /* No-OP */ 804 } 805 806 #endif 807 /** 808 * send_peer_param_cmd_tlv() - set peer parameter in fw 809 * @wmi: wmi handle 810 * @peer_addr: peer mac address 811 * @param : pointer to hold peer set parameter 812 * 813 * Return: QDF_STATUS_SUCCESS for success or error code 814 */ 815 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 816 uint8_t peer_addr[IEEE80211_ADDR_LEN], 817 struct peer_set_params *param) 818 { 819 wmi_peer_set_param_cmd_fixed_param *cmd; 820 wmi_buf_t buf; 821 int32_t err; 822 uint32_t param_id; 823 824 if (convert_host_peer_id_to_target_id_tlv(¶m_id, 825 param->param_id) != QDF_STATUS_SUCCESS) 826 return QDF_STATUS_E_NOSUPPORT; 827 828 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 829 if (!buf) { 830 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 831 return QDF_STATUS_E_NOMEM; 832 } 833 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 834 WMITLV_SET_HDR(&cmd->tlv_header, 835 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 836 WMITLV_GET_STRUCT_TLVLEN 837 (wmi_peer_set_param_cmd_fixed_param)); 838 cmd->vdev_id = param->vdev_id; 839 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 840 cmd->param_id = param_id; 841 cmd->param_value = param->param_value; 842 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 843 err = wmi_unified_cmd_send(wmi, buf, 844 sizeof(wmi_peer_set_param_cmd_fixed_param), 845 WMI_PEER_SET_PARAM_CMDID); 846 if (err) { 847 WMI_LOGE("Failed to send set_param cmd"); 848 wmi_buf_free(buf); 849 return QDF_STATUS_E_FAILURE; 850 } 851 852 return 0; 853 } 854 855 /** 856 * send_vdev_up_cmd_tlv() - send vdev up command in fw 857 * @wmi: wmi handle 858 * @bssid: bssid 859 * @vdev_up_params: pointer to hold vdev up parameter 860 * 861 * Return: QDF_STATUS_SUCCESS for success or error code 862 */ 863 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 864 uint8_t bssid[IEEE80211_ADDR_LEN], 865 struct vdev_up_params *params) 866 { 867 wmi_vdev_up_cmd_fixed_param *cmd; 868 wmi_buf_t buf; 869 int32_t len = sizeof(*cmd); 870 871 WMI_LOGD("%s: VDEV_UP", __func__); 872 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 873 params->vdev_id, params->assoc_id, bssid); 874 buf = wmi_buf_alloc(wmi, len); 875 if (!buf) { 876 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 877 return QDF_STATUS_E_NOMEM; 878 } 879 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 880 WMITLV_SET_HDR(&cmd->tlv_header, 881 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 882 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 883 cmd->vdev_id = params->vdev_id; 884 cmd->vdev_assoc_id = params->assoc_id; 885 cmd->profile_idx = params->profile_idx; 886 cmd->profile_num = params->profile_num; 887 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 888 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 889 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 890 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 891 WMI_LOGP("%s: Failed to send vdev up command", __func__); 892 wmi_buf_free(buf); 893 return QDF_STATUS_E_FAILURE; 894 } 895 896 return 0; 897 } 898 899 /** 900 * send_peer_create_cmd_tlv() - send peer create command to fw 901 * @wmi: wmi handle 902 * @peer_addr: peer mac address 903 * @peer_type: peer type 904 * @vdev_id: vdev id 905 * 906 * Return: QDF_STATUS_SUCCESS for success or error code 907 */ 908 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 909 struct peer_create_params *param) 910 { 911 wmi_peer_create_cmd_fixed_param *cmd; 912 wmi_buf_t buf; 913 int32_t len = sizeof(*cmd); 914 915 buf = wmi_buf_alloc(wmi, len); 916 if (!buf) { 917 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 918 return QDF_STATUS_E_NOMEM; 919 } 920 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 921 WMITLV_SET_HDR(&cmd->tlv_header, 922 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 923 WMITLV_GET_STRUCT_TLVLEN 924 (wmi_peer_create_cmd_fixed_param)); 925 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 926 cmd->peer_type = param->peer_type; 927 cmd->vdev_id = param->vdev_id; 928 929 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 930 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 931 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 932 wmi_buf_free(buf); 933 return QDF_STATUS_E_FAILURE; 934 } 935 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 936 param->vdev_id); 937 938 return 0; 939 } 940 941 /** 942 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 943 * command to fw 944 * @wmi: wmi handle 945 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 946 * 947 * Return: 0 for success or error code 948 */ 949 static 950 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 951 struct rx_reorder_queue_setup_params *param) 952 { 953 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 954 wmi_buf_t buf; 955 int32_t len = sizeof(*cmd); 956 957 buf = wmi_buf_alloc(wmi, len); 958 if (!buf) { 959 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 960 return QDF_STATUS_E_NOMEM; 961 } 962 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 963 WMITLV_SET_HDR(&cmd->tlv_header, 964 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 965 WMITLV_GET_STRUCT_TLVLEN 966 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 967 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 968 cmd->vdev_id = param->vdev_id; 969 cmd->tid = param->tid; 970 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 971 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 972 cmd->queue_no = param->queue_no; 973 cmd->ba_window_size_valid = param->ba_window_size_valid; 974 cmd->ba_window_size = param->ba_window_size; 975 976 977 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 978 if (wmi_unified_cmd_send(wmi, buf, len, 979 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 980 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 981 __func__); 982 wmi_buf_free(buf); 983 return QDF_STATUS_E_FAILURE; 984 } 985 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d\n", __func__, 986 param->peer_macaddr, param->vdev_id, param->tid); 987 988 return QDF_STATUS_SUCCESS; 989 } 990 991 /** 992 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 993 * command to fw 994 * @wmi: wmi handle 995 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 996 * 997 * Return: 0 for success or error code 998 */ 999 static 1000 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1001 struct rx_reorder_queue_remove_params *param) 1002 { 1003 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1004 wmi_buf_t buf; 1005 int32_t len = sizeof(*cmd); 1006 1007 crash_on_send_peer_rx_reorder_queue_remove_cmd(); 1008 1009 buf = wmi_buf_alloc(wmi, len); 1010 if (!buf) { 1011 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 1012 return QDF_STATUS_E_NOMEM; 1013 } 1014 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1015 wmi_buf_data(buf); 1016 WMITLV_SET_HDR(&cmd->tlv_header, 1017 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1018 WMITLV_GET_STRUCT_TLVLEN 1019 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1020 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1021 cmd->vdev_id = param->vdev_id; 1022 cmd->tid_mask = param->peer_tid_bitmap; 1023 1024 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1025 if (wmi_unified_cmd_send(wmi, buf, len, 1026 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1027 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 1028 __func__); 1029 wmi_buf_free(buf); 1030 return QDF_STATUS_E_FAILURE; 1031 } 1032 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 1033 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 1034 1035 return QDF_STATUS_SUCCESS; 1036 } 1037 1038 /** 1039 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 1040 * @wmi_handle: wmi handle 1041 * @param: pointer holding peer details 1042 * 1043 * Return: 0 for success or error code 1044 */ 1045 static QDF_STATUS send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1046 struct peer_add_wds_entry_params *param) 1047 { 1048 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 1049 wmi_buf_t buf; 1050 int len = sizeof(*cmd); 1051 1052 buf = wmi_buf_alloc(wmi_handle, len); 1053 if (!buf) { 1054 qdf_print("%s: wmi_buf_alloc failed", __func__); 1055 return QDF_STATUS_E_FAILURE; 1056 } 1057 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *) wmi_buf_data(buf); 1058 WMITLV_SET_HDR(&cmd->tlv_header, 1059 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 1060 WMITLV_GET_STRUCT_TLVLEN 1061 (wmi_peer_add_wds_entry_cmd_fixed_param)); 1062 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 1063 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1064 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1065 cmd->vdev_id = param->vdev_id; 1066 1067 wmi_mtrace(WMI_PEER_ADD_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 1068 return wmi_unified_cmd_send(wmi_handle, buf, len, 1069 WMI_PEER_ADD_WDS_ENTRY_CMDID); 1070 } 1071 1072 /** 1073 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 1074 * @wmi_handle: wmi handle 1075 * @param: pointer holding peer details 1076 * 1077 * Return: 0 for success or error code 1078 */ 1079 static QDF_STATUS send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1080 struct peer_del_wds_entry_params *param) 1081 { 1082 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 1083 wmi_buf_t buf; 1084 int len = sizeof(*cmd); 1085 1086 buf = wmi_buf_alloc(wmi_handle, len); 1087 if (!buf) { 1088 qdf_print("%s: wmi_buf_alloc failed", __func__); 1089 return QDF_STATUS_E_NOMEM; 1090 } 1091 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1092 WMITLV_SET_HDR(&cmd->tlv_header, 1093 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 1094 WMITLV_GET_STRUCT_TLVLEN 1095 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 1096 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 1097 cmd->vdev_id = param->vdev_id; 1098 wmi_mtrace(WMI_PEER_REMOVE_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 1099 return wmi_unified_cmd_send(wmi_handle, buf, len, 1100 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 1101 } 1102 1103 /** 1104 * send_peer_update_wds_entry_cmd_non_tlv() - send peer update command to fw 1105 * @wmi_handle: wmi handle 1106 * @param: pointer holding peer details 1107 * 1108 * Return: 0 for success or error code 1109 */ 1110 static QDF_STATUS send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 1111 struct peer_update_wds_entry_params *param) 1112 { 1113 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 1114 wmi_buf_t buf; 1115 int len = sizeof(*cmd); 1116 1117 buf = wmi_buf_alloc(wmi_handle, len); 1118 if (!buf) { 1119 qdf_print("%s: wmi_buf_alloc failed", __func__); 1120 return QDF_STATUS_E_NOMEM; 1121 } 1122 1123 /* wmi_buf_alloc returns zeroed command buffer */ 1124 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 1125 WMITLV_SET_HDR(&cmd->tlv_header, 1126 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 1127 WMITLV_GET_STRUCT_TLVLEN 1128 (wmi_peer_update_wds_entry_cmd_fixed_param)); 1129 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? WMI_WDS_FLAG_STATIC : 0; 1130 cmd->vdev_id = param->vdev_id; 1131 if (param->wds_macaddr) 1132 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->wds_macaddr, 1133 &cmd->wds_macaddr); 1134 if (param->peer_macaddr) 1135 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, 1136 &cmd->peer_macaddr); 1137 wmi_mtrace(WMI_PEER_UPDATE_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 1138 return wmi_unified_cmd_send(wmi_handle, buf, len, 1139 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 1140 } 1141 1142 /** 1143 * send_pdev_get_tpc_config_cmd_tlv() - send get tpc config command to fw 1144 * @wmi_handle: wmi handle 1145 * @param: pointer to get tpc config params 1146 * 1147 * Return: 0 for success or error code 1148 */ 1149 static QDF_STATUS 1150 send_pdev_get_tpc_config_cmd_tlv(wmi_unified_t wmi_handle, 1151 uint32_t param) 1152 { 1153 wmi_pdev_get_tpc_config_cmd_fixed_param *cmd; 1154 wmi_buf_t buf; 1155 int32_t len = sizeof(wmi_pdev_get_tpc_config_cmd_fixed_param); 1156 1157 buf = wmi_buf_alloc(wmi_handle, len); 1158 if (!buf) { 1159 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 1160 return QDF_STATUS_E_NOMEM; 1161 } 1162 cmd = (wmi_pdev_get_tpc_config_cmd_fixed_param *)wmi_buf_data(buf); 1163 WMITLV_SET_HDR(&cmd->tlv_header, 1164 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, 1165 WMITLV_GET_STRUCT_TLVLEN 1166 (wmi_pdev_get_tpc_config_cmd_fixed_param)); 1167 1168 cmd->param = param; 1169 wmi_mtrace(WMI_PDEV_GET_TPC_CONFIG_CMDID, NO_SESSION, 0); 1170 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1171 WMI_PDEV_GET_TPC_CONFIG_CMDID)) { 1172 WMI_LOGE("Send pdev get tpc config cmd failed"); 1173 wmi_buf_free(buf); 1174 return QDF_STATUS_E_FAILURE; 1175 1176 } 1177 WMI_LOGD("%s:send success", __func__); 1178 1179 return QDF_STATUS_SUCCESS; 1180 } 1181 1182 #ifdef WLAN_SUPPORT_GREEN_AP 1183 /** 1184 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1185 * @wmi_handle: wmi handle 1186 * @value: value 1187 * @pdev_id: pdev id to have radio context 1188 * 1189 * Return: QDF_STATUS_SUCCESS for success or error code 1190 */ 1191 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1192 uint32_t value, uint8_t pdev_id) 1193 { 1194 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1195 wmi_buf_t buf; 1196 int32_t len = sizeof(*cmd); 1197 1198 WMI_LOGD("Set Green AP PS val %d", value); 1199 1200 buf = wmi_buf_alloc(wmi_handle, len); 1201 if (!buf) { 1202 WMI_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); 1203 return QDF_STATUS_E_NOMEM; 1204 } 1205 1206 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1207 WMITLV_SET_HDR(&cmd->tlv_header, 1208 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1209 WMITLV_GET_STRUCT_TLVLEN 1210 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1211 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 1212 cmd->enable = value; 1213 1214 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1215 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1216 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1217 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1218 wmi_buf_free(buf); 1219 return QDF_STATUS_E_FAILURE; 1220 } 1221 1222 return 0; 1223 } 1224 #endif 1225 1226 /** 1227 * send_pdev_utf_cmd_tlv() - send utf command to fw 1228 * @wmi_handle: wmi handle 1229 * @param: pointer to pdev_utf_params 1230 * @mac_id: mac id to have radio context 1231 * 1232 * Return: QDF_STATUS_SUCCESS for success or error code 1233 */ 1234 static QDF_STATUS 1235 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1236 struct pdev_utf_params *param, 1237 uint8_t mac_id) 1238 { 1239 wmi_buf_t buf; 1240 uint8_t *cmd; 1241 /* if param->len is 0 no data is sent, return error */ 1242 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1243 static uint8_t msgref = 1; 1244 uint8_t segNumber = 0, segInfo, numSegments; 1245 uint16_t chunk_len, total_bytes; 1246 uint8_t *bufpos; 1247 struct seg_hdr_info segHdrInfo; 1248 1249 bufpos = param->utf_payload; 1250 total_bytes = param->len; 1251 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1252 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1253 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1254 1255 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1256 numSegments++; 1257 1258 while (param->len) { 1259 if (param->len > MAX_WMI_UTF_LEN) 1260 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1261 else 1262 chunk_len = param->len; 1263 1264 buf = wmi_buf_alloc(wmi_handle, 1265 (chunk_len + sizeof(segHdrInfo) + 1266 WMI_TLV_HDR_SIZE)); 1267 if (!buf) { 1268 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1269 return QDF_STATUS_E_NOMEM; 1270 } 1271 1272 cmd = (uint8_t *) wmi_buf_data(buf); 1273 1274 segHdrInfo.len = total_bytes; 1275 segHdrInfo.msgref = msgref; 1276 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1277 segHdrInfo.segmentInfo = segInfo; 1278 segHdrInfo.pad = 0; 1279 1280 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1281 " segHdrInfo.segmentInfo = %d", 1282 __func__, segHdrInfo.len, segHdrInfo.msgref, 1283 segHdrInfo.segmentInfo); 1284 1285 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1286 "chunk len %d", __func__, total_bytes, segNumber, 1287 numSegments, chunk_len); 1288 1289 segNumber++; 1290 1291 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1292 (chunk_len + sizeof(segHdrInfo))); 1293 cmd += WMI_TLV_HDR_SIZE; 1294 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1295 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1296 1297 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1298 ret = wmi_unified_cmd_send(wmi_handle, buf, 1299 (chunk_len + sizeof(segHdrInfo) + 1300 WMI_TLV_HDR_SIZE), 1301 WMI_PDEV_UTF_CMDID); 1302 1303 if (QDF_IS_STATUS_ERROR(ret)) { 1304 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1305 wmi_buf_free(buf); 1306 break; 1307 } 1308 1309 param->len -= chunk_len; 1310 bufpos += chunk_len; 1311 } 1312 1313 msgref++; 1314 1315 return ret; 1316 } 1317 #ifdef CONFIG_MCL 1318 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1319 uint32_t host_param) 1320 { 1321 return host_param; 1322 } 1323 #else 1324 static inline uint32_t convert_host_pdev_param_tlv(wmi_unified_t wmi_handle, 1325 uint32_t host_param) 1326 { 1327 if (host_param < wmi_pdev_param_max) 1328 return wmi_handle->pdev_param[host_param]; 1329 1330 return WMI_UNAVAILABLE_PARAM; 1331 } 1332 #endif 1333 /** 1334 * send_pdev_param_cmd_tlv() - set pdev parameters 1335 * @wmi_handle: wmi handle 1336 * @param: pointer to pdev parameter 1337 * @mac_id: radio context 1338 * 1339 * Return: 0 on success, errno on failure 1340 */ 1341 static QDF_STATUS 1342 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1343 struct pdev_params *param, 1344 uint8_t mac_id) 1345 { 1346 QDF_STATUS ret; 1347 wmi_pdev_set_param_cmd_fixed_param *cmd; 1348 wmi_buf_t buf; 1349 uint16_t len = sizeof(*cmd); 1350 uint32_t pdev_param; 1351 1352 pdev_param = convert_host_pdev_param_tlv(wmi_handle, param->param_id); 1353 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1354 WMI_LOGW("%s: Unavailable param %d\n", 1355 __func__, param->param_id); 1356 return QDF_STATUS_E_INVAL; 1357 } 1358 1359 buf = wmi_buf_alloc(wmi_handle, len); 1360 if (!buf) { 1361 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1362 return QDF_STATUS_E_NOMEM; 1363 } 1364 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1365 WMITLV_SET_HDR(&cmd->tlv_header, 1366 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1367 WMITLV_GET_STRUCT_TLVLEN 1368 (wmi_pdev_set_param_cmd_fixed_param)); 1369 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1370 cmd->param_id = pdev_param; 1371 cmd->param_value = param->param_value; 1372 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1373 param->param_value); 1374 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1375 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1376 WMI_PDEV_SET_PARAM_CMDID); 1377 if (QDF_IS_STATUS_ERROR(ret)) { 1378 WMI_LOGE("Failed to send set param command ret = %d", ret); 1379 wmi_buf_free(buf); 1380 } 1381 return ret; 1382 } 1383 1384 /** 1385 * send_suspend_cmd_tlv() - WMI suspend function 1386 * @param wmi_handle : handle to WMI. 1387 * @param param : pointer to hold suspend parameter 1388 * @mac_id: radio context 1389 * 1390 * Return 0 on success and -ve on failure. 1391 */ 1392 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1393 struct suspend_params *param, 1394 uint8_t mac_id) 1395 { 1396 wmi_pdev_suspend_cmd_fixed_param *cmd; 1397 wmi_buf_t wmibuf; 1398 uint32_t len = sizeof(*cmd); 1399 int32_t ret; 1400 1401 /* 1402 * send the command to Target to ignore the 1403 * PCIE reset so as to ensure that Host and target 1404 * states are in sync 1405 */ 1406 wmibuf = wmi_buf_alloc(wmi_handle, len); 1407 if (wmibuf == NULL) 1408 return QDF_STATUS_E_NOMEM; 1409 1410 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1411 WMITLV_SET_HDR(&cmd->tlv_header, 1412 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1413 WMITLV_GET_STRUCT_TLVLEN 1414 (wmi_pdev_suspend_cmd_fixed_param)); 1415 if (param->disable_target_intr) 1416 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1417 else 1418 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1419 1420 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1421 1422 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1423 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1424 WMI_PDEV_SUSPEND_CMDID); 1425 if (ret) { 1426 wmi_buf_free(wmibuf); 1427 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1428 } 1429 1430 return ret; 1431 } 1432 1433 /** 1434 * send_resume_cmd_tlv() - WMI resume function 1435 * @param wmi_handle : handle to WMI. 1436 * @mac_id: radio context 1437 * 1438 * Return: 0 on success and -ve on failure. 1439 */ 1440 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1441 uint8_t mac_id) 1442 { 1443 wmi_buf_t wmibuf; 1444 wmi_pdev_resume_cmd_fixed_param *cmd; 1445 QDF_STATUS ret; 1446 1447 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1448 if (wmibuf == NULL) 1449 return QDF_STATUS_E_NOMEM; 1450 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1451 WMITLV_SET_HDR(&cmd->tlv_header, 1452 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1453 WMITLV_GET_STRUCT_TLVLEN 1454 (wmi_pdev_resume_cmd_fixed_param)); 1455 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 1456 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1457 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1458 WMI_PDEV_RESUME_CMDID); 1459 if (QDF_IS_STATUS_ERROR(ret)) { 1460 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1461 wmi_buf_free(wmibuf); 1462 } 1463 1464 return ret; 1465 } 1466 1467 #ifdef FEATURE_WLAN_D0WOW 1468 /** 1469 * send_d0wow_enable_cmd_tlv() - WMI d0 wow enable function 1470 * @param wmi_handle: handle to WMI. 1471 * @mac_id: radio context 1472 * 1473 * Return: 0 on success and error code on failure. 1474 */ 1475 static QDF_STATUS send_d0wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1476 uint8_t mac_id) 1477 { 1478 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1479 wmi_buf_t buf; 1480 int32_t len; 1481 QDF_STATUS status; 1482 1483 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1484 1485 buf = wmi_buf_alloc(wmi_handle, len); 1486 if (!buf) { 1487 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1488 return QDF_STATUS_E_NOMEM; 1489 } 1490 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1491 WMITLV_SET_HDR(&cmd->tlv_header, 1492 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1493 WMITLV_GET_STRUCT_TLVLEN 1494 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1495 1496 cmd->enable = true; 1497 1498 wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0); 1499 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1500 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1501 if (QDF_IS_STATUS_ERROR(status)) 1502 wmi_buf_free(buf); 1503 1504 return status; 1505 } 1506 1507 /** 1508 * send_d0wow_disable_cmd_tlv() - WMI d0 wow disable function 1509 * @param wmi_handle: handle to WMI. 1510 * @mac_id: radio context 1511 * 1512 * Return: 0 on success and error code on failure. 1513 */ 1514 static QDF_STATUS send_d0wow_disable_cmd_tlv(wmi_unified_t wmi_handle, 1515 uint8_t mac_id) 1516 { 1517 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; 1518 wmi_buf_t buf; 1519 int32_t len; 1520 QDF_STATUS status; 1521 1522 len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); 1523 1524 buf = wmi_buf_alloc(wmi_handle, len); 1525 if (!buf) { 1526 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1527 return QDF_STATUS_E_NOMEM; 1528 } 1529 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); 1530 WMITLV_SET_HDR(&cmd->tlv_header, 1531 WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, 1532 WMITLV_GET_STRUCT_TLVLEN 1533 (wmi_d0_wow_enable_disable_cmd_fixed_param)); 1534 1535 cmd->enable = false; 1536 1537 wmi_mtrace(WMI_D0_WOW_ENABLE_DISABLE_CMDID, NO_SESSION, 0); 1538 status = wmi_unified_cmd_send(wmi_handle, buf, len, 1539 WMI_D0_WOW_ENABLE_DISABLE_CMDID); 1540 if (QDF_IS_STATUS_ERROR(status)) 1541 wmi_buf_free(buf); 1542 1543 return status; 1544 } 1545 #endif 1546 1547 /** 1548 * send_wow_enable_cmd_tlv() - WMI wow enable function 1549 * @param wmi_handle : handle to WMI. 1550 * @param param : pointer to hold wow enable parameter 1551 * @mac_id: radio context 1552 * 1553 * Return: 0 on success and -ve on failure. 1554 */ 1555 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1556 struct wow_cmd_params *param, 1557 uint8_t mac_id) 1558 { 1559 wmi_wow_enable_cmd_fixed_param *cmd; 1560 wmi_buf_t buf; 1561 int32_t len; 1562 int32_t ret; 1563 1564 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1565 1566 buf = wmi_buf_alloc(wmi_handle, len); 1567 if (!buf) { 1568 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 1569 return QDF_STATUS_E_NOMEM; 1570 } 1571 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1572 WMITLV_SET_HDR(&cmd->tlv_header, 1573 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1574 WMITLV_GET_STRUCT_TLVLEN 1575 (wmi_wow_enable_cmd_fixed_param)); 1576 cmd->enable = param->enable; 1577 if (param->can_suspend_link) 1578 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1579 else 1580 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1581 cmd->flags = param->flags; 1582 1583 WMI_LOGI("suspend type: %s", 1584 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1585 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1586 1587 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1588 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1589 WMI_WOW_ENABLE_CMDID); 1590 if (ret) 1591 wmi_buf_free(buf); 1592 1593 return ret; 1594 } 1595 1596 /** 1597 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1598 * @wmi_handle: wmi handle 1599 * @peer_addr: peer mac address 1600 * @param: pointer to ap_ps parameter structure 1601 * 1602 * Return: QDF_STATUS_SUCCESS for success or error code 1603 */ 1604 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1605 uint8_t *peer_addr, 1606 struct ap_ps_params *param) 1607 { 1608 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1609 wmi_buf_t buf; 1610 int32_t err; 1611 1612 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1613 if (!buf) { 1614 WMI_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); 1615 return QDF_STATUS_E_NOMEM; 1616 } 1617 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1618 WMITLV_SET_HDR(&cmd->tlv_header, 1619 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1620 WMITLV_GET_STRUCT_TLVLEN 1621 (wmi_ap_ps_peer_cmd_fixed_param)); 1622 cmd->vdev_id = param->vdev_id; 1623 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1624 cmd->param = param->param; 1625 cmd->value = param->value; 1626 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1627 err = wmi_unified_cmd_send(wmi_handle, buf, 1628 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1629 if (err) { 1630 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1631 wmi_buf_free(buf); 1632 return QDF_STATUS_E_FAILURE; 1633 } 1634 1635 return 0; 1636 } 1637 1638 /** 1639 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1640 * @wmi_handle: wmi handle 1641 * @peer_addr: peer mac address 1642 * @param: pointer to sta_ps parameter structure 1643 * 1644 * Return: QDF_STATUS_SUCCESS for success or error code 1645 */ 1646 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1647 struct sta_ps_params *param) 1648 { 1649 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1650 wmi_buf_t buf; 1651 int32_t len = sizeof(*cmd); 1652 1653 buf = wmi_buf_alloc(wmi_handle, len); 1654 if (!buf) { 1655 WMI_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); 1656 return QDF_STATUS_E_NOMEM; 1657 } 1658 1659 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1660 WMITLV_SET_HDR(&cmd->tlv_header, 1661 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1662 WMITLV_GET_STRUCT_TLVLEN 1663 (wmi_sta_powersave_param_cmd_fixed_param)); 1664 cmd->vdev_id = param->vdev_id; 1665 cmd->param = param->param; 1666 cmd->value = param->value; 1667 1668 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 1669 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1670 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1671 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1672 param->vdev_id, param->param, param->value); 1673 wmi_buf_free(buf); 1674 return QDF_STATUS_E_FAILURE; 1675 } 1676 1677 return 0; 1678 } 1679 1680 /** 1681 * send_crash_inject_cmd_tlv() - inject fw crash 1682 * @wmi_handle: wmi handle 1683 * @param: ponirt to crash inject parameter structure 1684 * 1685 * Return: QDF_STATUS_SUCCESS for success or return error 1686 */ 1687 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1688 struct crash_inject *param) 1689 { 1690 int32_t ret = 0; 1691 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1692 uint16_t len = sizeof(*cmd); 1693 wmi_buf_t buf; 1694 1695 buf = wmi_buf_alloc(wmi_handle, len); 1696 if (!buf) { 1697 WMI_LOGE("%s: wmi_buf_alloc failed!", __func__); 1698 return QDF_STATUS_E_NOMEM; 1699 } 1700 1701 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1702 WMITLV_SET_HDR(&cmd->tlv_header, 1703 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1704 WMITLV_GET_STRUCT_TLVLEN 1705 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1706 cmd->type = param->type; 1707 cmd->delay_time_ms = param->delay_time_ms; 1708 1709 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 1710 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1711 WMI_FORCE_FW_HANG_CMDID); 1712 if (ret) { 1713 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1714 __func__, ret); 1715 wmi_buf_free(buf); 1716 } 1717 1718 return ret; 1719 } 1720 1721 #ifdef FEATURE_FW_LOG_PARSING 1722 /** 1723 * send_dbglog_cmd_tlv() - set debug log level 1724 * @param wmi_handle : handle to WMI. 1725 * @param param : pointer to hold dbglog level parameter 1726 * 1727 * Return: 0 on success and -ve on failure. 1728 */ 1729 static QDF_STATUS 1730 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1731 struct dbglog_params *dbglog_param) 1732 { 1733 wmi_buf_t buf; 1734 wmi_debug_log_config_cmd_fixed_param *configmsg; 1735 QDF_STATUS status; 1736 int32_t i; 1737 int32_t len; 1738 int8_t *buf_ptr; 1739 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1740 1741 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1742 1743 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1744 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1745 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1746 buf = wmi_buf_alloc(wmi_handle, len); 1747 if (buf == NULL) 1748 return QDF_STATUS_E_NOMEM; 1749 1750 configmsg = 1751 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1752 buf_ptr = (int8_t *) configmsg; 1753 WMITLV_SET_HDR(&configmsg->tlv_header, 1754 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1755 WMITLV_GET_STRUCT_TLVLEN 1756 (wmi_debug_log_config_cmd_fixed_param)); 1757 configmsg->dbg_log_param = dbglog_param->param; 1758 configmsg->value = dbglog_param->val; 1759 /* Filling in the data part of second tlv -- should 1760 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1761 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1762 sizeof 1763 (wmi_debug_log_config_cmd_fixed_param) 1764 + WMI_TLV_HDR_SIZE); 1765 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1766 WMITLV_TAG_ARRAY_UINT32, 1767 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1768 if (dbglog_param->module_id_bitmap) { 1769 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 1770 module_id_bitmap_array[i] = 1771 dbglog_param->module_id_bitmap[i]; 1772 } 1773 } 1774 1775 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 1776 status = wmi_unified_cmd_send(wmi_handle, buf, 1777 len, WMI_DBGLOG_CFG_CMDID); 1778 1779 if (status != QDF_STATUS_SUCCESS) 1780 wmi_buf_free(buf); 1781 1782 return status; 1783 } 1784 #endif 1785 1786 #ifdef CONFIG_MCL 1787 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1788 uint32_t host_param) 1789 { 1790 return host_param; 1791 } 1792 #else 1793 static inline uint32_t convert_host_vdev_param_tlv(wmi_unified_t wmi_handle, 1794 uint32_t host_param) 1795 { 1796 if (host_param < wmi_vdev_param_max) 1797 return wmi_handle->vdev_param[host_param]; 1798 1799 return WMI_UNAVAILABLE_PARAM; 1800 } 1801 #endif 1802 /** 1803 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 1804 * @param wmi_handle : handle to WMI. 1805 * @param macaddr : MAC address 1806 * @param param : pointer to hold vdev set parameter 1807 * 1808 * Return: 0 on success and -ve on failure. 1809 */ 1810 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 1811 struct vdev_set_params *param) 1812 { 1813 QDF_STATUS ret; 1814 wmi_vdev_set_param_cmd_fixed_param *cmd; 1815 wmi_buf_t buf; 1816 uint16_t len = sizeof(*cmd); 1817 uint32_t vdev_param; 1818 1819 vdev_param = convert_host_vdev_param_tlv(wmi_handle, param->param_id); 1820 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 1821 WMI_LOGW("%s:Vdev param %d not available", __func__, 1822 param->param_id); 1823 return QDF_STATUS_E_INVAL; 1824 1825 } 1826 1827 buf = wmi_buf_alloc(wmi_handle, len); 1828 if (!buf) { 1829 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 1830 return QDF_STATUS_E_NOMEM; 1831 } 1832 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1833 WMITLV_SET_HDR(&cmd->tlv_header, 1834 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 1835 WMITLV_GET_STRUCT_TLVLEN 1836 (wmi_vdev_set_param_cmd_fixed_param)); 1837 cmd->vdev_id = param->if_id; 1838 cmd->param_id = vdev_param; 1839 cmd->param_value = param->param_value; 1840 WMI_LOGD("Setting vdev %d param = %x, value = %u", 1841 cmd->vdev_id, cmd->param_id, cmd->param_value); 1842 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 1843 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1844 WMI_VDEV_SET_PARAM_CMDID); 1845 if (QDF_IS_STATUS_ERROR(ret)) { 1846 WMI_LOGE("Failed to send set param command ret = %d", ret); 1847 wmi_buf_free(buf); 1848 } 1849 1850 return ret; 1851 } 1852 1853 /** 1854 * send_stats_request_cmd_tlv() - WMI request stats function 1855 * @param wmi_handle : handle to WMI. 1856 * @param macaddr : MAC address 1857 * @param param : pointer to hold stats request parameter 1858 * 1859 * Return: 0 on success and -ve on failure. 1860 */ 1861 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 1862 uint8_t macaddr[IEEE80211_ADDR_LEN], 1863 struct stats_request_params *param) 1864 { 1865 int32_t ret; 1866 wmi_request_stats_cmd_fixed_param *cmd; 1867 wmi_buf_t buf; 1868 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 1869 1870 buf = wmi_buf_alloc(wmi_handle, len); 1871 if (!buf) { 1872 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1873 return -QDF_STATUS_E_NOMEM; 1874 } 1875 1876 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 1877 WMITLV_SET_HDR(&cmd->tlv_header, 1878 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 1879 WMITLV_GET_STRUCT_TLVLEN 1880 (wmi_request_stats_cmd_fixed_param)); 1881 cmd->stats_id = param->stats_id; 1882 cmd->vdev_id = param->vdev_id; 1883 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1884 param->pdev_id); 1885 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 1886 1887 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 1888 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 1889 1890 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 1891 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1892 WMI_REQUEST_STATS_CMDID); 1893 1894 if (ret) { 1895 WMI_LOGE("Failed to send status request to fw =%d", ret); 1896 wmi_buf_free(buf); 1897 } 1898 1899 return ret; 1900 } 1901 1902 #ifdef CONFIG_WIN 1903 /** 1904 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 1905 * @param wmi_handle : handle to WMI. 1906 * @param PKTLOG_EVENT : packet log event 1907 * @mac_id: mac id to have radio context 1908 * 1909 * Return: 0 on success and -ve on failure. 1910 */ 1911 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1912 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 1913 { 1914 int32_t ret; 1915 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 1916 wmi_buf_t buf; 1917 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 1918 1919 buf = wmi_buf_alloc(wmi_handle, len); 1920 if (!buf) { 1921 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1922 return -QDF_STATUS_E_NOMEM; 1923 } 1924 1925 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 1926 WMITLV_SET_HDR(&cmd->tlv_header, 1927 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 1928 WMITLV_GET_STRUCT_TLVLEN 1929 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 1930 cmd->evlist = PKTLOG_EVENT; 1931 cmd->pdev_id = mac_id; 1932 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 1933 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1934 WMI_PDEV_PKTLOG_ENABLE_CMDID); 1935 if (ret) { 1936 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 1937 wmi_buf_free(buf); 1938 } 1939 1940 return ret; 1941 } 1942 1943 /** 1944 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 1945 * @param wmi_handle : handle to WMI. 1946 * @mac_id: mac id to have radio context 1947 * 1948 * Return: 0 on success and -ve on failure. 1949 */ 1950 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 1951 uint8_t mac_id) 1952 { 1953 int32_t ret; 1954 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 1955 wmi_buf_t buf; 1956 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 1957 1958 buf = wmi_buf_alloc(wmi_handle, len); 1959 if (!buf) { 1960 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 1961 return -QDF_STATUS_E_NOMEM; 1962 } 1963 1964 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 1965 WMITLV_SET_HDR(&cmd->tlv_header, 1966 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 1967 WMITLV_GET_STRUCT_TLVLEN 1968 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 1969 cmd->pdev_id = mac_id; 1970 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 1971 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1972 WMI_PDEV_PKTLOG_DISABLE_CMDID); 1973 if (ret) { 1974 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 1975 wmi_buf_free(buf); 1976 } 1977 1978 return ret; 1979 } 1980 #else 1981 /** 1982 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable 1983 * packet-log 1984 * @param wmi_handle : handle to WMI. 1985 * @param macaddr : MAC address 1986 * @param param : pointer to hold stats request parameter 1987 * 1988 * Return: 0 on success and -ve on failure. 1989 */ 1990 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 1991 uint8_t macaddr[IEEE80211_ADDR_LEN], 1992 struct packet_enable_params *param) 1993 { 1994 return 0; 1995 } 1996 /** 1997 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable 1998 * packet-log 1999 * @param wmi_handle : handle to WMI. 2000 * @mac_id: mac id to have radio context 2001 * 2002 * Return: 0 on success and -ve on failure. 2003 */ 2004 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2005 uint8_t mac_id) 2006 { 2007 return 0; 2008 } 2009 #endif 2010 2011 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2012 /** 2013 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2014 * sync time between bwtween host and firmware 2015 * @param wmi_handle : handle to WMI. 2016 * 2017 * Return: None 2018 */ 2019 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2020 { 2021 wmi_buf_t buf; 2022 QDF_STATUS status = QDF_STATUS_SUCCESS; 2023 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2024 int32_t len; 2025 qdf_time_t time_ms; 2026 2027 len = sizeof(*time_stamp); 2028 buf = wmi_buf_alloc(wmi_handle, len); 2029 2030 if (!buf) { 2031 WMI_LOGP(FL("wmi_buf_alloc failed")); 2032 return; 2033 } 2034 time_stamp = 2035 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2036 (wmi_buf_data(buf)); 2037 WMITLV_SET_HDR(&time_stamp->tlv_header, 2038 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2039 WMITLV_GET_STRUCT_TLVLEN( 2040 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2041 2042 time_ms = qdf_get_time_of_the_day_ms(); 2043 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2044 time_stamp->time_stamp_low = time_ms & 2045 WMI_FW_TIME_STAMP_LOW_MASK; 2046 /* 2047 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2048 * wont exceed 27 bit 2049 */ 2050 time_stamp->time_stamp_high = 0; 2051 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 2052 time_stamp->mode, time_stamp->time_stamp_low, 2053 time_stamp->time_stamp_high); 2054 2055 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2056 status = wmi_unified_cmd_send(wmi_handle, buf, 2057 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2058 if (status) { 2059 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2060 wmi_buf_free(buf); 2061 } 2062 2063 } 2064 2065 #ifdef WLAN_SUPPORT_FILS 2066 /** 2067 * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event 2068 * @wmi_handle: wmi handle 2069 * @evt_buf: pointer to event buffer 2070 * @vdev_id: pointer to hold vdev id 2071 * 2072 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 2073 */ 2074 static QDF_STATUS 2075 extract_swfda_vdev_id_tlv(wmi_unified_t wmi_handle, 2076 void *evt_buf, uint32_t *vdev_id) 2077 { 2078 WMI_HOST_SWFDA_EVENTID_param_tlvs *param_buf; 2079 wmi_host_swfda_event_fixed_param *swfda_event; 2080 2081 param_buf = (WMI_HOST_SWFDA_EVENTID_param_tlvs *)evt_buf; 2082 if (!param_buf) { 2083 WMI_LOGE("Invalid swfda event buffer"); 2084 return QDF_STATUS_E_INVAL; 2085 } 2086 swfda_event = param_buf->fixed_param; 2087 *vdev_id = swfda_event->vdev_id; 2088 2089 return QDF_STATUS_SUCCESS; 2090 } 2091 2092 /** 2093 * send_vdev_fils_enable_cmd_tlv() - enable/Disable FD Frame command to fw 2094 * @wmi_handle: wmi handle 2095 * @param: pointer to hold FILS discovery enable param 2096 * 2097 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure 2098 */ 2099 static QDF_STATUS 2100 send_vdev_fils_enable_cmd_tlv(wmi_unified_t wmi_handle, 2101 struct config_fils_params *param) 2102 { 2103 wmi_enable_fils_cmd_fixed_param *cmd; 2104 wmi_buf_t buf; 2105 QDF_STATUS status; 2106 uint32_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 2107 2108 buf = wmi_buf_alloc(wmi_handle, len); 2109 if (!buf) { 2110 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2111 return QDF_STATUS_E_NOMEM; 2112 } 2113 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data(buf); 2114 WMITLV_SET_HDR(&cmd->tlv_header, 2115 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 2116 WMITLV_GET_STRUCT_TLVLEN( 2117 wmi_enable_fils_cmd_fixed_param)); 2118 cmd->vdev_id = param->vdev_id; 2119 cmd->fd_period = param->fd_period; 2120 WMI_LOGI("Setting FD period to %d vdev id : %d\n", 2121 param->fd_period, param->vdev_id); 2122 2123 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, 0); 2124 status = wmi_unified_cmd_send(wmi_handle, buf, len, 2125 WMI_ENABLE_FILS_CMDID); 2126 if (status != QDF_STATUS_SUCCESS) { 2127 wmi_buf_free(buf); 2128 return QDF_STATUS_E_FAILURE; 2129 } 2130 2131 return QDF_STATUS_SUCCESS; 2132 } 2133 2134 /** 2135 * send_fils_discovery_send_cmd_tlv() - WMI FILS Discovery send function 2136 * @wmi_handle: wmi handle 2137 * @param: pointer to hold FD send cmd parameter 2138 * 2139 * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_NOMEM on failure. 2140 */ 2141 static QDF_STATUS 2142 send_fils_discovery_send_cmd_tlv(wmi_unified_t wmi_handle, 2143 struct fd_params *param) 2144 { 2145 QDF_STATUS ret; 2146 wmi_fd_send_from_host_cmd_fixed_param *cmd; 2147 wmi_buf_t wmi_buf; 2148 qdf_dma_addr_t dma_addr; 2149 2150 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2151 if (!wmi_buf) { 2152 WMI_LOGE("%s : wmi_buf_alloc failed\n", __func__); 2153 return QDF_STATUS_E_NOMEM; 2154 } 2155 cmd = (wmi_fd_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf); 2156 WMITLV_SET_HDR(&cmd->tlv_header, 2157 WMITLV_TAG_STRUC_wmi_fd_send_from_host_cmd_fixed_param, 2158 WMITLV_GET_STRUCT_TLVLEN( 2159 wmi_fd_send_from_host_cmd_fixed_param)); 2160 cmd->vdev_id = param->vdev_id; 2161 cmd->data_len = qdf_nbuf_len(param->wbuf); 2162 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2163 qdf_dmaaddr_to_32s(dma_addr, &cmd->frag_ptr_lo, &cmd->frag_ptr_hi); 2164 cmd->frame_ctrl = param->frame_ctrl; 2165 2166 wmi_mtrace(WMI_PDEV_SEND_FD_CMDID, cmd->vdev_id, 0); 2167 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 2168 WMI_PDEV_SEND_FD_CMDID); 2169 if (ret != QDF_STATUS_SUCCESS) { 2170 WMI_LOGE("%s: Failed to send fils discovery frame: %d", 2171 __func__, ret); 2172 wmi_buf_free(wmi_buf); 2173 } 2174 2175 return ret; 2176 } 2177 #endif /* WLAN_SUPPORT_FILS */ 2178 2179 static QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle, 2180 struct beacon_params *param) 2181 { 2182 QDF_STATUS ret; 2183 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 2184 wmi_buf_t wmi_buf; 2185 qdf_dma_addr_t dma_addr; 2186 uint32_t dtim_flag = 0; 2187 2188 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2189 if (!wmi_buf) { 2190 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2191 return QDF_STATUS_E_NOMEM; 2192 } 2193 if (param->is_dtim_count_zero) { 2194 dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; 2195 if (param->is_bitctl_reqd) { 2196 /* deliver CAB traffic in next DTIM beacon */ 2197 dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; 2198 } 2199 } 2200 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2201 WMITLV_SET_HDR(&cmd->tlv_header, 2202 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 2203 WMITLV_GET_STRUCT_TLVLEN 2204 (wmi_bcn_send_from_host_cmd_fixed_param)); 2205 cmd->vdev_id = param->vdev_id; 2206 cmd->data_len = qdf_nbuf_len(param->wbuf); 2207 cmd->frame_ctrl = param->frame_ctrl; 2208 cmd->dtim_flag = dtim_flag; 2209 dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0); 2210 cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr); 2211 #if defined(HTT_PADDR64) 2212 cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F; 2213 #endif 2214 cmd->bcn_antenna = param->bcn_txant; 2215 2216 wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0); 2217 ret = wmi_unified_cmd_send(wmi_handle, 2218 wmi_buf, sizeof(*cmd), WMI_PDEV_SEND_BCN_CMDID); 2219 if (ret != QDF_STATUS_SUCCESS) { 2220 WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret); 2221 wmi_buf_free(wmi_buf); 2222 } 2223 2224 return ret; 2225 } 2226 2227 /** 2228 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2229 * @param wmi_handle : handle to WMI. 2230 * @param param : pointer to hold beacon send cmd parameter 2231 * 2232 * Return: 0 on success and -ve on failure. 2233 */ 2234 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2235 struct beacon_tmpl_params *param) 2236 { 2237 int32_t ret; 2238 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2239 wmi_bcn_prb_info *bcn_prb_info; 2240 wmi_buf_t wmi_buf; 2241 uint8_t *buf_ptr; 2242 uint32_t wmi_buf_len; 2243 2244 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2245 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2246 param->tmpl_len_aligned; 2247 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2248 if (!wmi_buf) { 2249 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 2250 return QDF_STATUS_E_NOMEM; 2251 } 2252 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2253 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2254 WMITLV_SET_HDR(&cmd->tlv_header, 2255 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2256 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2257 cmd->vdev_id = param->vdev_id; 2258 cmd->tim_ie_offset = param->tim_ie_offset; 2259 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2260 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2261 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2262 cmd->esp_ie_offset = param->esp_ie_offset; 2263 cmd->buf_len = param->tmpl_len; 2264 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2265 2266 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2267 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2268 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2269 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2270 bcn_prb_info->caps = 0; 2271 bcn_prb_info->erp = 0; 2272 buf_ptr += sizeof(wmi_bcn_prb_info); 2273 2274 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2275 buf_ptr += WMI_TLV_HDR_SIZE; 2276 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2277 2278 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2279 ret = wmi_unified_cmd_send(wmi_handle, 2280 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2281 if (ret) { 2282 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2283 wmi_buf_free(wmi_buf); 2284 } 2285 2286 return 0; 2287 } 2288 2289 #ifdef CONFIG_MCL 2290 static inline void copy_peer_flags_tlv( 2291 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2292 struct peer_assoc_params *param) 2293 { 2294 cmd->peer_flags = param->peer_flags; 2295 } 2296 #else 2297 static inline void copy_peer_flags_tlv( 2298 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2299 struct peer_assoc_params *param) 2300 { 2301 /* 2302 * The target only needs a subset of the flags maintained in the host. 2303 * Just populate those flags and send it down 2304 */ 2305 cmd->peer_flags = 0; 2306 2307 /* 2308 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2309 */ 2310 if (param->is_wme_set) { 2311 2312 if (param->qos_flag) 2313 cmd->peer_flags |= WMI_PEER_QOS; 2314 if (param->apsd_flag) 2315 cmd->peer_flags |= WMI_PEER_APSD; 2316 if (param->ht_flag) 2317 cmd->peer_flags |= WMI_PEER_HT; 2318 if (param->bw_40) 2319 cmd->peer_flags |= WMI_PEER_40MHZ; 2320 if (param->bw_80) 2321 cmd->peer_flags |= WMI_PEER_80MHZ; 2322 if (param->bw_160) 2323 cmd->peer_flags |= WMI_PEER_160MHZ; 2324 2325 /* Typically if STBC is enabled for VHT it should be enabled 2326 * for HT as well 2327 **/ 2328 if (param->stbc_flag) 2329 cmd->peer_flags |= WMI_PEER_STBC; 2330 2331 /* Typically if LDPC is enabled for VHT it should be enabled 2332 * for HT as well 2333 **/ 2334 if (param->ldpc_flag) 2335 cmd->peer_flags |= WMI_PEER_LDPC; 2336 2337 if (param->static_mimops_flag) 2338 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2339 if (param->dynamic_mimops_flag) 2340 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2341 if (param->spatial_mux_flag) 2342 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2343 if (param->vht_flag) 2344 cmd->peer_flags |= WMI_PEER_VHT; 2345 if (param->he_flag) 2346 cmd->peer_flags |= WMI_PEER_HE; 2347 } 2348 2349 if (param->is_pmf_enabled) 2350 cmd->peer_flags |= WMI_PEER_PMF; 2351 /* 2352 * Suppress authorization for all AUTH modes that need 4-way handshake 2353 * (during re-association). 2354 * Authorization will be done for these modes on key installation. 2355 */ 2356 if (param->auth_flag) 2357 cmd->peer_flags |= WMI_PEER_AUTH; 2358 if (param->need_ptk_4_way) 2359 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2360 else 2361 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2362 if (param->need_gtk_2_way) 2363 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2364 /* safe mode bypass the 4-way handshake */ 2365 if (param->safe_mode_enabled) 2366 cmd->peer_flags &= 2367 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2368 /* Disable AMSDU for station transmit, if user configures it */ 2369 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2370 * it 2371 * if (param->amsdu_disable) Add after FW support 2372 **/ 2373 2374 /* Target asserts if node is marked HT and all MCS is set to 0. 2375 * Mark the node as non-HT if all the mcs rates are disabled through 2376 * iwpriv 2377 **/ 2378 if (param->peer_ht_rates.num_rates == 0) 2379 cmd->peer_flags &= ~WMI_PEER_HT; 2380 2381 if (param->twt_requester) 2382 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2383 2384 if (param->twt_responder) 2385 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2386 } 2387 #endif 2388 2389 #ifdef CONFIG_MCL 2390 static inline void copy_peer_mac_addr_tlv( 2391 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2392 struct peer_assoc_params *param) 2393 { 2394 qdf_mem_copy(&cmd->peer_macaddr, ¶m->peer_macaddr, 2395 sizeof(param->peer_macaddr)); 2396 } 2397 #else 2398 static inline void copy_peer_mac_addr_tlv( 2399 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2400 struct peer_assoc_params *param) 2401 { 2402 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2403 } 2404 #endif 2405 2406 /** 2407 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2408 * @param wmi_handle : handle to WMI. 2409 * @param param : pointer to peer assoc parameter 2410 * 2411 * Return: 0 on success and -ve on failure. 2412 */ 2413 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2414 struct peer_assoc_params *param) 2415 { 2416 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2417 wmi_vht_rate_set *mcs; 2418 wmi_he_rate_set *he_mcs; 2419 wmi_buf_t buf; 2420 int32_t len; 2421 uint8_t *buf_ptr; 2422 QDF_STATUS ret; 2423 uint32_t peer_legacy_rates_align; 2424 uint32_t peer_ht_rates_align; 2425 int32_t i; 2426 2427 2428 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2429 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2430 2431 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2432 (peer_legacy_rates_align * sizeof(uint8_t)) + 2433 WMI_TLV_HDR_SIZE + 2434 (peer_ht_rates_align * sizeof(uint8_t)) + 2435 sizeof(wmi_vht_rate_set) + 2436 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2437 + WMI_TLV_HDR_SIZE); 2438 2439 buf = wmi_buf_alloc(wmi_handle, len); 2440 if (!buf) { 2441 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 2442 return QDF_STATUS_E_NOMEM; 2443 } 2444 2445 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2446 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2447 WMITLV_SET_HDR(&cmd->tlv_header, 2448 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2449 WMITLV_GET_STRUCT_TLVLEN 2450 (wmi_peer_assoc_complete_cmd_fixed_param)); 2451 2452 cmd->vdev_id = param->vdev_id; 2453 2454 cmd->peer_new_assoc = param->peer_new_assoc; 2455 cmd->peer_associd = param->peer_associd; 2456 2457 copy_peer_flags_tlv(cmd, param); 2458 copy_peer_mac_addr_tlv(cmd, param); 2459 2460 cmd->peer_rate_caps = param->peer_rate_caps; 2461 cmd->peer_caps = param->peer_caps; 2462 cmd->peer_listen_intval = param->peer_listen_intval; 2463 cmd->peer_ht_caps = param->peer_ht_caps; 2464 cmd->peer_max_mpdu = param->peer_max_mpdu; 2465 cmd->peer_mpdu_density = param->peer_mpdu_density; 2466 cmd->peer_vht_caps = param->peer_vht_caps; 2467 cmd->peer_phymode = param->peer_phymode; 2468 2469 /* Update 11ax capabilities */ 2470 cmd->peer_he_cap_info = 2471 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2472 cmd->peer_he_cap_info_ext = 2473 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2474 cmd->peer_he_ops = param->peer_he_ops; 2475 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2476 sizeof(param->peer_he_cap_phyinfo)); 2477 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2478 sizeof(param->peer_ppet)); 2479 2480 /* Update peer legacy rate information */ 2481 buf_ptr += sizeof(*cmd); 2482 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2483 peer_legacy_rates_align); 2484 buf_ptr += WMI_TLV_HDR_SIZE; 2485 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2486 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2487 param->peer_legacy_rates.num_rates); 2488 2489 /* Update peer HT rate information */ 2490 buf_ptr += peer_legacy_rates_align; 2491 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2492 peer_ht_rates_align); 2493 buf_ptr += WMI_TLV_HDR_SIZE; 2494 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2495 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2496 param->peer_ht_rates.num_rates); 2497 2498 /* VHT Rates */ 2499 buf_ptr += peer_ht_rates_align; 2500 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2501 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2502 2503 cmd->peer_nss = param->peer_nss; 2504 2505 /* Update bandwidth-NSS mapping */ 2506 cmd->peer_bw_rxnss_override = 0; 2507 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2508 2509 mcs = (wmi_vht_rate_set *) buf_ptr; 2510 if (param->vht_capable) { 2511 mcs->rx_max_rate = param->rx_max_rate; 2512 mcs->rx_mcs_set = param->rx_mcs_set; 2513 mcs->tx_max_rate = param->tx_max_rate; 2514 mcs->tx_mcs_set = param->tx_mcs_set; 2515 } 2516 2517 /* HE Rates */ 2518 cmd->peer_he_mcs = param->peer_he_mcs_count; 2519 buf_ptr += sizeof(wmi_vht_rate_set); 2520 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2521 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2522 buf_ptr += WMI_TLV_HDR_SIZE; 2523 2524 /* Loop through the HE rate set */ 2525 for (i = 0; i < param->peer_he_mcs_count; i++) { 2526 he_mcs = (wmi_he_rate_set *) buf_ptr; 2527 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2528 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2529 2530 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2531 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2532 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2533 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2534 buf_ptr += sizeof(wmi_he_rate_set); 2535 } 2536 2537 2538 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2539 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2540 "nss %d phymode %d peer_mpdu_density %d " 2541 "cmd->peer_vht_caps %x " 2542 "HE cap_info %x ops %x " 2543 "HE cap_info_ext %x " 2544 "HE phy %x %x %x " 2545 "peer_bw_rxnss_override %x", __func__, 2546 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2547 cmd->peer_rate_caps, cmd->peer_caps, 2548 cmd->peer_listen_intval, cmd->peer_ht_caps, 2549 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2550 cmd->peer_mpdu_density, 2551 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2552 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2553 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2554 cmd->peer_he_cap_phy[2], 2555 cmd->peer_bw_rxnss_override); 2556 2557 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2558 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2559 WMI_PEER_ASSOC_CMDID); 2560 if (QDF_IS_STATUS_ERROR(ret)) { 2561 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2562 __func__, ret); 2563 wmi_buf_free(buf); 2564 } 2565 2566 return ret; 2567 } 2568 2569 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2570 */ 2571 static inline void copy_scan_event_cntrl_flags( 2572 wmi_start_scan_cmd_fixed_param * cmd, 2573 struct scan_req_params *param) 2574 { 2575 2576 /* Scan events subscription */ 2577 if (param->scan_ev_started) 2578 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2579 if (param->scan_ev_completed) 2580 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2581 if (param->scan_ev_bss_chan) 2582 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2583 if (param->scan_ev_foreign_chan) 2584 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2585 if (param->scan_ev_dequeued) 2586 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2587 if (param->scan_ev_preempted) 2588 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2589 if (param->scan_ev_start_failed) 2590 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2591 if (param->scan_ev_restarted) 2592 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2593 if (param->scan_ev_foreign_chn_exit) 2594 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2595 if (param->scan_ev_suspended) 2596 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2597 if (param->scan_ev_resumed) 2598 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2599 2600 /** Set scan control flags */ 2601 cmd->scan_ctrl_flags = 0; 2602 if (param->scan_f_passive) 2603 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2604 if (param->scan_f_strict_passive_pch) 2605 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2606 if (param->scan_f_promisc_mode) 2607 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2608 if (param->scan_f_capture_phy_err) 2609 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2610 if (param->scan_f_half_rate) 2611 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2612 if (param->scan_f_quarter_rate) 2613 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2614 if (param->scan_f_cck_rates) 2615 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2616 if (param->scan_f_ofdm_rates) 2617 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2618 if (param->scan_f_chan_stat_evnt) 2619 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2620 if (param->scan_f_filter_prb_req) 2621 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2622 if (param->scan_f_bcast_probe) 2623 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2624 if (param->scan_f_offchan_mgmt_tx) 2625 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2626 if (param->scan_f_offchan_data_tx) 2627 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2628 if (param->scan_f_force_active_dfs_chn) 2629 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2630 if (param->scan_f_add_tpc_ie_in_probe) 2631 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2632 if (param->scan_f_add_ds_ie_in_probe) 2633 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2634 if (param->scan_f_add_spoofed_mac_in_probe) 2635 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2636 if (param->scan_f_add_rand_seq_in_probe) 2637 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2638 if (param->scan_f_en_ie_whitelist_in_probe) 2639 cmd->scan_ctrl_flags |= 2640 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2641 2642 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2643 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2644 param->adaptive_dwell_time_mode); 2645 } 2646 2647 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2648 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2649 struct scan_req_params *params) 2650 { 2651 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2652 } 2653 2654 /** 2655 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2656 * @mac: random mac addr 2657 * @mask: random mac mask 2658 * @mac_addr: wmi random mac 2659 * @mac_mask: wmi random mac mask 2660 * 2661 * Return None. 2662 */ 2663 static inline 2664 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2665 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2666 { 2667 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2668 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2669 } 2670 2671 /* 2672 * wmi_fill_vendor_oui() - fill vendor OUIs 2673 * @buf_ptr: pointer to wmi tlv buffer 2674 * @num_vendor_oui: number of vendor OUIs to be filled 2675 * @param_voui: pointer to OUI buffer 2676 * 2677 * This function populates the wmi tlv buffer when vendor specific OUIs are 2678 * present. 2679 * 2680 * Return: None 2681 */ 2682 static inline 2683 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2684 uint32_t *pvoui) 2685 { 2686 wmi_vendor_oui *voui = NULL; 2687 uint32_t i; 2688 2689 voui = (wmi_vendor_oui *)buf_ptr; 2690 2691 for (i = 0; i < num_vendor_oui; i++) { 2692 WMITLV_SET_HDR(&voui[i].tlv_header, 2693 WMITLV_TAG_STRUC_wmi_vendor_oui, 2694 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2695 voui[i].oui_type_subtype = pvoui[i]; 2696 } 2697 } 2698 2699 /* 2700 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2701 * @ie_bitmap: output pointer to ie bit map in cmd 2702 * @num_vendor_oui: output pointer to num vendor OUIs 2703 * @ie_whitelist: input parameter 2704 * 2705 * This function populates the IE whitelist attrs of scan, pno and 2706 * scan oui commands for ie_whitelist parameter. 2707 * 2708 * Return: None 2709 */ 2710 static inline 2711 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2712 uint32_t *num_vendor_oui, 2713 struct probe_req_whitelist_attr *ie_whitelist) 2714 { 2715 uint32_t i = 0; 2716 2717 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2718 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2719 2720 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2721 } 2722 2723 /** 2724 * send_scan_start_cmd_tlv() - WMI scan start function 2725 * @param wmi_handle : handle to WMI. 2726 * @param param : pointer to hold scan start cmd parameter 2727 * 2728 * Return: 0 on success and -ve on failure. 2729 */ 2730 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2731 struct scan_req_params *params) 2732 { 2733 int32_t ret = 0; 2734 int32_t i; 2735 wmi_buf_t wmi_buf; 2736 wmi_start_scan_cmd_fixed_param *cmd; 2737 uint8_t *buf_ptr; 2738 uint32_t *tmp_ptr; 2739 wmi_ssid *ssid = NULL; 2740 wmi_mac_addr *bssid; 2741 int len = sizeof(*cmd); 2742 uint8_t extraie_len_with_pad = 0; 2743 uint8_t phymode_roundup = 0; 2744 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2745 2746 /* Length TLV placeholder for array of uint32_t */ 2747 len += WMI_TLV_HDR_SIZE; 2748 /* calculate the length of buffer required */ 2749 if (params->chan_list.num_chan) 2750 len += params->chan_list.num_chan * sizeof(uint32_t); 2751 2752 /* Length TLV placeholder for array of wmi_ssid structures */ 2753 len += WMI_TLV_HDR_SIZE; 2754 if (params->num_ssids) 2755 len += params->num_ssids * sizeof(wmi_ssid); 2756 2757 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2758 len += WMI_TLV_HDR_SIZE; 2759 if (params->num_bssid) 2760 len += sizeof(wmi_mac_addr) * params->num_bssid; 2761 2762 /* Length TLV placeholder for array of bytes */ 2763 len += WMI_TLV_HDR_SIZE; 2764 if (params->extraie.len) 2765 extraie_len_with_pad = 2766 roundup(params->extraie.len, sizeof(uint32_t)); 2767 len += extraie_len_with_pad; 2768 2769 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2770 if (ie_whitelist->num_vendor_oui) 2771 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2772 2773 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2774 if (params->scan_f_wide_band) 2775 phymode_roundup = 2776 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2777 sizeof(uint32_t)); 2778 len += phymode_roundup; 2779 2780 /* Allocate the memory */ 2781 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2782 if (!wmi_buf) { 2783 WMI_LOGP("%s: failed to allocate memory for start scan cmd", 2784 __func__); 2785 return QDF_STATUS_E_FAILURE; 2786 } 2787 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2788 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2789 WMITLV_SET_HDR(&cmd->tlv_header, 2790 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2791 WMITLV_GET_STRUCT_TLVLEN 2792 (wmi_start_scan_cmd_fixed_param)); 2793 2794 cmd->scan_id = params->scan_id; 2795 cmd->scan_req_id = params->scan_req_id; 2796 cmd->vdev_id = params->vdev_id; 2797 cmd->scan_priority = params->scan_priority; 2798 2799 copy_scan_event_cntrl_flags(cmd, params); 2800 2801 cmd->dwell_time_active = params->dwell_time_active; 2802 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2803 cmd->dwell_time_passive = params->dwell_time_passive; 2804 cmd->min_rest_time = params->min_rest_time; 2805 cmd->max_rest_time = params->max_rest_time; 2806 cmd->repeat_probe_time = params->repeat_probe_time; 2807 cmd->probe_spacing_time = params->probe_spacing_time; 2808 cmd->idle_time = params->idle_time; 2809 cmd->max_scan_time = params->max_scan_time; 2810 cmd->probe_delay = params->probe_delay; 2811 cmd->burst_duration = params->burst_duration; 2812 cmd->num_chan = params->chan_list.num_chan; 2813 cmd->num_bssid = params->num_bssid; 2814 cmd->num_ssids = params->num_ssids; 2815 cmd->ie_len = params->extraie.len; 2816 cmd->n_probes = params->n_probes; 2817 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2818 2819 WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); 2820 2821 if (params->scan_random.randomize) 2822 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2823 params->scan_random.mac_mask, 2824 &cmd->mac_addr, 2825 &cmd->mac_mask); 2826 2827 if (ie_whitelist->white_list) 2828 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2829 &cmd->num_vendor_oui, 2830 ie_whitelist); 2831 2832 buf_ptr += sizeof(*cmd); 2833 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2834 for (i = 0; i < params->chan_list.num_chan; ++i) 2835 tmp_ptr[i] = params->chan_list.chan[i].freq; 2836 2837 WMITLV_SET_HDR(buf_ptr, 2838 WMITLV_TAG_ARRAY_UINT32, 2839 (params->chan_list.num_chan * sizeof(uint32_t))); 2840 buf_ptr += WMI_TLV_HDR_SIZE + 2841 (params->chan_list.num_chan * sizeof(uint32_t)); 2842 2843 if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { 2844 WMI_LOGE("Invalid value for numSsid"); 2845 goto error; 2846 } 2847 2848 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2849 (params->num_ssids * sizeof(wmi_ssid))); 2850 2851 if (params->num_ssids) { 2852 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 2853 for (i = 0; i < params->num_ssids; ++i) { 2854 ssid->ssid_len = params->ssid[i].length; 2855 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 2856 params->ssid[i].length); 2857 ssid++; 2858 } 2859 } 2860 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 2861 2862 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2863 (params->num_bssid * sizeof(wmi_mac_addr))); 2864 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 2865 2866 if (params->num_bssid) { 2867 for (i = 0; i < params->num_bssid; ++i) { 2868 WMI_CHAR_ARRAY_TO_MAC_ADDR( 2869 ¶ms->bssid_list[i].bytes[0], bssid); 2870 bssid++; 2871 } 2872 } 2873 2874 buf_ptr += WMI_TLV_HDR_SIZE + 2875 (params->num_bssid * sizeof(wmi_mac_addr)); 2876 2877 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 2878 if (params->extraie.len) 2879 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 2880 params); 2881 2882 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 2883 2884 /* probe req ie whitelisting */ 2885 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2886 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 2887 2888 buf_ptr += WMI_TLV_HDR_SIZE; 2889 2890 if (cmd->num_vendor_oui) { 2891 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 2892 ie_whitelist->voui); 2893 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 2894 } 2895 2896 /* Add phy mode TLV if it's a wide band scan */ 2897 if (params->scan_f_wide_band) { 2898 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 2899 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2900 for (i = 0; i < params->chan_list.num_chan; ++i) 2901 buf_ptr[i] = 2902 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 2903 buf_ptr += phymode_roundup; 2904 } else { 2905 /* Add ZERO legth phy mode TLV */ 2906 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 2907 } 2908 2909 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 2910 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2911 len, WMI_START_SCAN_CMDID); 2912 if (ret) { 2913 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 2914 wmi_buf_free(wmi_buf); 2915 } 2916 return ret; 2917 error: 2918 wmi_buf_free(wmi_buf); 2919 return QDF_STATUS_E_FAILURE; 2920 } 2921 2922 /** 2923 * send_scan_stop_cmd_tlv() - WMI scan start function 2924 * @param wmi_handle : handle to WMI. 2925 * @param param : pointer to hold scan cancel cmd parameter 2926 * 2927 * Return: 0 on success and -ve on failure. 2928 */ 2929 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 2930 struct scan_cancel_param *param) 2931 { 2932 wmi_stop_scan_cmd_fixed_param *cmd; 2933 int ret; 2934 int len = sizeof(*cmd); 2935 wmi_buf_t wmi_buf; 2936 2937 /* Allocate the memory */ 2938 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2939 if (!wmi_buf) { 2940 WMI_LOGP("%s: failed to allocate memory for stop scan cmd", 2941 __func__); 2942 ret = QDF_STATUS_E_NOMEM; 2943 goto error; 2944 } 2945 2946 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 2947 WMITLV_SET_HDR(&cmd->tlv_header, 2948 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 2949 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 2950 cmd->vdev_id = param->vdev_id; 2951 cmd->requestor = param->requester; 2952 cmd->scan_id = param->scan_id; 2953 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2954 param->pdev_id); 2955 /* stop the scan with the corresponding scan_id */ 2956 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 2957 /* Cancelling all scans */ 2958 cmd->req_type = WMI_SCAN_STOP_ALL; 2959 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 2960 /* Cancelling VAP scans */ 2961 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 2962 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 2963 /* Cancelling specific scan */ 2964 cmd->req_type = WMI_SCAN_STOP_ONE; 2965 } else { 2966 WMI_LOGE("%s: Invalid Command : ", __func__); 2967 wmi_buf_free(wmi_buf); 2968 return QDF_STATUS_E_INVAL; 2969 } 2970 2971 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 2972 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 2973 len, WMI_STOP_SCAN_CMDID); 2974 if (ret) { 2975 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 2976 wmi_buf_free(wmi_buf); 2977 } 2978 2979 error: 2980 return ret; 2981 } 2982 2983 #ifdef CONFIG_MCL 2984 /** 2985 * send_scan_chan_list_cmd_tlv() - WMI scan channel list function 2986 * @param wmi_handle : handle to WMI. 2987 * @param param : pointer to hold scan channel list parameter 2988 * 2989 * Return: 0 on success and -ve on failure. 2990 */ 2991 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 2992 struct scan_chan_list_params *chan_list) 2993 { 2994 wmi_buf_t buf; 2995 QDF_STATUS qdf_status; 2996 wmi_scan_chan_list_cmd_fixed_param *cmd; 2997 int i; 2998 uint8_t *buf_ptr; 2999 wmi_channel_param *chan_info, *tchan_info; 3000 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3001 3002 len += sizeof(wmi_channel) * chan_list->num_scan_chans; 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->num_scan_chans, len); 3018 3019 cmd->num_scan_chans = chan_list->num_scan_chans; 3020 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3021 WMITLV_TAG_ARRAY_STRUC, 3022 sizeof(wmi_channel) * chan_list->num_scan_chans); 3023 chan_info = (wmi_channel_param *) 3024 (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 3025 tchan_info = chan_list->chan_info; 3026 3027 for (i = 0; i < chan_list->num_scan_chans; ++i) { 3028 WMITLV_SET_HDR(&chan_info->tlv_header, 3029 WMITLV_TAG_STRUC_wmi_channel, 3030 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3031 chan_info->mhz = tchan_info->mhz; 3032 chan_info->band_center_freq1 = 3033 tchan_info->band_center_freq1; 3034 chan_info->band_center_freq2 = 3035 tchan_info->band_center_freq2; 3036 chan_info->info = tchan_info->info; 3037 chan_info->reg_info_1 = tchan_info->reg_info_1; 3038 chan_info->reg_info_2 = tchan_info->reg_info_2; 3039 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 3040 3041 /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ 3042 /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ 3043 /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ 3044 tchan_info++; 3045 chan_info++; 3046 } 3047 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3048 chan_list->pdev_id); 3049 3050 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, NO_SESSION, 0); 3051 qdf_status = wmi_unified_cmd_send(wmi_handle, 3052 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3053 3054 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3055 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3056 wmi_buf_free(buf); 3057 } 3058 3059 end: 3060 return qdf_status; 3061 } 3062 #else 3063 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3064 struct scan_chan_list_params *chan_list) 3065 { 3066 wmi_buf_t buf; 3067 QDF_STATUS qdf_status; 3068 wmi_scan_chan_list_cmd_fixed_param *cmd; 3069 int i; 3070 uint8_t *buf_ptr; 3071 wmi_channel *chan_info; 3072 struct channel_param *tchan_info; 3073 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3074 3075 len += sizeof(wmi_channel) * chan_list->nallchans; 3076 buf = wmi_buf_alloc(wmi_handle, len); 3077 if (!buf) { 3078 WMI_LOGE("Failed to allocate memory"); 3079 qdf_status = QDF_STATUS_E_NOMEM; 3080 goto end; 3081 } 3082 3083 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3084 cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; 3085 WMITLV_SET_HDR(&cmd->tlv_header, 3086 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3087 WMITLV_GET_STRUCT_TLVLEN 3088 (wmi_scan_chan_list_cmd_fixed_param)); 3089 3090 WMI_LOGD("no of channels = %d, len = %d", chan_list->nallchans, len); 3091 3092 if (chan_list->append) 3093 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3094 3095 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3096 chan_list->pdev_id); 3097 cmd->num_scan_chans = chan_list->nallchans; 3098 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3099 WMITLV_TAG_ARRAY_STRUC, 3100 sizeof(wmi_channel) * chan_list->nallchans); 3101 chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); 3102 tchan_info = &(chan_list->ch_param[0]); 3103 3104 for (i = 0; i < chan_list->nallchans; ++i) { 3105 WMITLV_SET_HDR(&chan_info->tlv_header, 3106 WMITLV_TAG_STRUC_wmi_channel, 3107 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3108 chan_info->mhz = tchan_info->mhz; 3109 chan_info->band_center_freq1 = 3110 tchan_info->cfreq1; 3111 chan_info->band_center_freq2 = 3112 tchan_info->cfreq2; 3113 3114 if (tchan_info->is_chan_passive) 3115 WMI_SET_CHANNEL_FLAG(chan_info, 3116 WMI_CHAN_FLAG_PASSIVE); 3117 3118 if (tchan_info->allow_vht) 3119 WMI_SET_CHANNEL_FLAG(chan_info, 3120 WMI_CHAN_FLAG_ALLOW_VHT); 3121 else if (tchan_info->allow_ht) 3122 WMI_SET_CHANNEL_FLAG(chan_info, 3123 WMI_CHAN_FLAG_ALLOW_HT); 3124 WMI_SET_CHANNEL_MODE(chan_info, 3125 tchan_info->phy_mode); 3126 3127 if (tchan_info->half_rate) 3128 WMI_SET_CHANNEL_FLAG(chan_info, 3129 WMI_CHAN_FLAG_HALF_RATE); 3130 3131 if (tchan_info->quarter_rate) 3132 WMI_SET_CHANNEL_FLAG(chan_info, 3133 WMI_CHAN_FLAG_QUARTER_RATE); 3134 3135 /* also fill in power information */ 3136 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3137 tchan_info->minpower); 3138 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3139 tchan_info->maxpower); 3140 WMI_SET_CHANNEL_REG_POWER(chan_info, 3141 tchan_info->maxregpower); 3142 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3143 tchan_info->antennamax); 3144 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3145 tchan_info->reg_class_id); 3146 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3147 tchan_info->maxregpower); 3148 3149 WMI_LOGD("chan[%d] = %u", i, chan_info->mhz); 3150 3151 tchan_info++; 3152 chan_info++; 3153 } 3154 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3155 chan_list->pdev_id); 3156 3157 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3158 qdf_status = wmi_unified_cmd_send( 3159 wmi_handle, 3160 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3161 3162 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3163 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3164 wmi_buf_free(buf); 3165 } 3166 3167 end: 3168 return qdf_status; 3169 } 3170 #endif 3171 3172 /** 3173 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3174 * 3175 * @bufp: Pointer to buffer 3176 * @param: Pointer to tx param 3177 * 3178 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3179 */ 3180 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3181 struct tx_send_params param) 3182 { 3183 wmi_tx_send_params *tx_param; 3184 QDF_STATUS status = QDF_STATUS_SUCCESS; 3185 3186 if (!bufp) { 3187 status = QDF_STATUS_E_FAILURE; 3188 return status; 3189 } 3190 tx_param = (wmi_tx_send_params *)bufp; 3191 WMITLV_SET_HDR(&tx_param->tlv_header, 3192 WMITLV_TAG_STRUC_wmi_tx_send_params, 3193 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3194 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3195 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3196 param.mcs_mask); 3197 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3198 param.nss_mask); 3199 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3200 param.retry_limit); 3201 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3202 param.chain_mask); 3203 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3204 param.bw_mask); 3205 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3206 param.preamble_type); 3207 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3208 param.frame_type); 3209 3210 return status; 3211 } 3212 3213 #ifdef CONFIG_HL_SUPPORT 3214 /** 3215 * send_mgmt_cmd_tlv() - WMI scan start function 3216 * @wmi_handle : handle to WMI. 3217 * @param : pointer to hold mgmt cmd parameter 3218 * 3219 * Return: 0 on success and -ve on failure. 3220 */ 3221 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3222 struct wmi_mgmt_params *param) 3223 { 3224 wmi_buf_t buf; 3225 uint8_t *bufp; 3226 int32_t cmd_len; 3227 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3228 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3229 mgmt_tx_dl_frm_len; 3230 3231 if (param->frm_len > mgmt_tx_dl_frm_len) { 3232 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 3233 __func__, param->frm_len, mgmt_tx_dl_frm_len); 3234 return QDF_STATUS_E_INVAL; 3235 } 3236 3237 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3238 WMI_TLV_HDR_SIZE + 3239 roundup(bufp_len, sizeof(uint32_t)); 3240 3241 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3242 if (!buf) { 3243 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3244 return QDF_STATUS_E_NOMEM; 3245 } 3246 3247 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3248 bufp = (uint8_t *) cmd; 3249 WMITLV_SET_HDR(&cmd->tlv_header, 3250 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3251 WMITLV_GET_STRUCT_TLVLEN 3252 (wmi_mgmt_tx_send_cmd_fixed_param)); 3253 3254 cmd->vdev_id = param->vdev_id; 3255 3256 cmd->desc_id = param->desc_id; 3257 cmd->chanfreq = param->chanfreq; 3258 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3259 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3260 sizeof(uint32_t))); 3261 bufp += WMI_TLV_HDR_SIZE; 3262 qdf_mem_copy(bufp, param->pdata, bufp_len); 3263 3264 cmd->frame_len = param->frm_len; 3265 cmd->buf_len = bufp_len; 3266 cmd->tx_params_valid = param->tx_params_valid; 3267 3268 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3269 bufp, cmd->vdev_id, cmd->chanfreq); 3270 3271 bufp += roundup(bufp_len, sizeof(uint32_t)); 3272 if (param->tx_params_valid) { 3273 if (populate_tx_send_params(bufp, param->tx_param) != 3274 QDF_STATUS_SUCCESS) { 3275 WMI_LOGE("%s: Populate TX send params failed", 3276 __func__); 3277 goto free_buf; 3278 } 3279 cmd_len += sizeof(wmi_tx_send_params); 3280 } 3281 3282 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3283 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3284 WMI_MGMT_TX_SEND_CMDID)) { 3285 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3286 goto free_buf; 3287 } 3288 return QDF_STATUS_SUCCESS; 3289 3290 free_buf: 3291 wmi_buf_free(buf); 3292 return QDF_STATUS_E_FAILURE; 3293 } 3294 #else 3295 /** 3296 * send_mgmt_cmd_tlv() - WMI scan start function 3297 * @wmi_handle : handle to WMI. 3298 * @param : pointer to hold mgmt cmd parameter 3299 * 3300 * Return: 0 on success and -ve on failure. 3301 */ 3302 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3303 struct wmi_mgmt_params *param) 3304 { 3305 wmi_buf_t buf; 3306 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3307 int32_t cmd_len; 3308 uint64_t dma_addr; 3309 void *qdf_ctx = param->qdf_ctx; 3310 uint8_t *bufp; 3311 QDF_STATUS status = QDF_STATUS_SUCCESS; 3312 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3313 mgmt_tx_dl_frm_len; 3314 3315 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3316 WMI_TLV_HDR_SIZE + 3317 roundup(bufp_len, sizeof(uint32_t)); 3318 3319 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3320 if (!buf) { 3321 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3322 return QDF_STATUS_E_NOMEM; 3323 } 3324 3325 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3326 bufp = (uint8_t *) cmd; 3327 WMITLV_SET_HDR(&cmd->tlv_header, 3328 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3329 WMITLV_GET_STRUCT_TLVLEN 3330 (wmi_mgmt_tx_send_cmd_fixed_param)); 3331 3332 cmd->vdev_id = param->vdev_id; 3333 3334 cmd->desc_id = param->desc_id; 3335 cmd->chanfreq = param->chanfreq; 3336 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3337 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3338 sizeof(uint32_t))); 3339 bufp += WMI_TLV_HDR_SIZE; 3340 qdf_mem_copy(bufp, param->pdata, bufp_len); 3341 3342 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3343 QDF_DMA_TO_DEVICE); 3344 if (status != QDF_STATUS_SUCCESS) { 3345 WMI_LOGE("%s: wmi buf map failed", __func__); 3346 goto free_buf; 3347 } 3348 3349 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3350 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3351 #if defined(HTT_PADDR64) 3352 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3353 #endif 3354 cmd->frame_len = param->frm_len; 3355 cmd->buf_len = bufp_len; 3356 cmd->tx_params_valid = param->tx_params_valid; 3357 3358 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3359 bufp, cmd->vdev_id, cmd->chanfreq); 3360 3361 bufp += roundup(bufp_len, sizeof(uint32_t)); 3362 if (param->tx_params_valid) { 3363 status = populate_tx_send_params(bufp, param->tx_param); 3364 if (status != QDF_STATUS_SUCCESS) { 3365 WMI_LOGE("%s: Populate TX send params failed", 3366 __func__); 3367 goto unmap_tx_frame; 3368 } 3369 cmd_len += sizeof(wmi_tx_send_params); 3370 } 3371 3372 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3373 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3374 WMI_MGMT_TX_SEND_CMDID)) { 3375 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3376 goto unmap_tx_frame; 3377 } 3378 return QDF_STATUS_SUCCESS; 3379 3380 unmap_tx_frame: 3381 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3382 QDF_DMA_TO_DEVICE); 3383 free_buf: 3384 wmi_buf_free(buf); 3385 return QDF_STATUS_E_FAILURE; 3386 } 3387 #endif /* CONFIG_HL_SUPPORT */ 3388 3389 /** 3390 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3391 * @wmi_handle : handle to WMI. 3392 * @param : pointer to offchan data tx cmd parameter 3393 * 3394 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3395 */ 3396 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3397 struct wmi_offchan_data_tx_params *param) 3398 { 3399 wmi_buf_t buf; 3400 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3401 int32_t cmd_len; 3402 uint64_t dma_addr; 3403 void *qdf_ctx = param->qdf_ctx; 3404 uint8_t *bufp; 3405 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3406 param->frm_len : mgmt_tx_dl_frm_len; 3407 QDF_STATUS status = QDF_STATUS_SUCCESS; 3408 3409 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3410 WMI_TLV_HDR_SIZE + 3411 roundup(bufp_len, sizeof(uint32_t)); 3412 3413 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3414 if (!buf) { 3415 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3416 return QDF_STATUS_E_NOMEM; 3417 } 3418 3419 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3420 bufp = (uint8_t *) cmd; 3421 WMITLV_SET_HDR(&cmd->tlv_header, 3422 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3423 WMITLV_GET_STRUCT_TLVLEN 3424 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3425 3426 cmd->vdev_id = param->vdev_id; 3427 3428 cmd->desc_id = param->desc_id; 3429 cmd->chanfreq = param->chanfreq; 3430 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3431 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3432 sizeof(uint32_t))); 3433 bufp += WMI_TLV_HDR_SIZE; 3434 qdf_mem_copy(bufp, param->pdata, bufp_len); 3435 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3436 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3437 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3438 #if defined(HTT_PADDR64) 3439 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3440 #endif 3441 cmd->frame_len = param->frm_len; 3442 cmd->buf_len = bufp_len; 3443 cmd->tx_params_valid = param->tx_params_valid; 3444 3445 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3446 bufp, cmd->vdev_id, cmd->chanfreq); 3447 3448 bufp += roundup(bufp_len, sizeof(uint32_t)); 3449 if (param->tx_params_valid) { 3450 status = populate_tx_send_params(bufp, param->tx_param); 3451 if (status != QDF_STATUS_SUCCESS) { 3452 WMI_LOGE("%s: Populate TX send params failed", 3453 __func__); 3454 goto err1; 3455 } 3456 cmd_len += sizeof(wmi_tx_send_params); 3457 } 3458 3459 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3460 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3461 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3462 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3463 goto err1; 3464 } 3465 3466 return QDF_STATUS_SUCCESS; 3467 3468 err1: 3469 wmi_buf_free(buf); 3470 return QDF_STATUS_E_FAILURE; 3471 } 3472 3473 /** 3474 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3475 * @wmi_handle: wmi handle 3476 * @param_value: parameter value 3477 * 3478 * Return: QDF_STATUS_SUCCESS for success or error code 3479 */ 3480 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3481 uint32_t param_value) 3482 { 3483 QDF_STATUS ret; 3484 wmi_modem_power_state_cmd_param *cmd; 3485 wmi_buf_t buf; 3486 uint16_t len = sizeof(*cmd); 3487 3488 buf = wmi_buf_alloc(wmi_handle, len); 3489 if (!buf) { 3490 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3491 return QDF_STATUS_E_NOMEM; 3492 } 3493 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3494 WMITLV_SET_HDR(&cmd->tlv_header, 3495 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3496 WMITLV_GET_STRUCT_TLVLEN 3497 (wmi_modem_power_state_cmd_param)); 3498 cmd->modem_power_state = param_value; 3499 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3500 param_value); 3501 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3502 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3503 WMI_MODEM_POWER_STATE_CMDID); 3504 if (QDF_IS_STATUS_ERROR(ret)) { 3505 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3506 wmi_buf_free(buf); 3507 } 3508 3509 return ret; 3510 } 3511 3512 /** 3513 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3514 * @wmi_handle: wmi handle 3515 * @vdev_id: vdev id 3516 * @val: value 3517 * 3518 * Return: QDF_STATUS_SUCCESS for success or error code. 3519 */ 3520 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3521 uint32_t vdev_id, uint8_t val) 3522 { 3523 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3524 wmi_buf_t buf; 3525 int32_t len = sizeof(*cmd); 3526 3527 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3528 3529 buf = wmi_buf_alloc(wmi_handle, len); 3530 if (!buf) { 3531 WMI_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); 3532 return QDF_STATUS_E_NOMEM; 3533 } 3534 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3535 WMITLV_SET_HDR(&cmd->tlv_header, 3536 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3537 WMITLV_GET_STRUCT_TLVLEN 3538 (wmi_sta_powersave_mode_cmd_fixed_param)); 3539 cmd->vdev_id = vdev_id; 3540 if (val) 3541 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3542 else 3543 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3544 3545 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3546 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3547 WMI_STA_POWERSAVE_MODE_CMDID)) { 3548 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3549 vdev_id, val); 3550 wmi_buf_free(buf); 3551 return QDF_STATUS_E_FAILURE; 3552 } 3553 return 0; 3554 } 3555 3556 /** 3557 * send_set_mimops_cmd_tlv() - set MIMO powersave 3558 * @wmi_handle: wmi handle 3559 * @vdev_id: vdev id 3560 * @value: value 3561 * 3562 * Return: QDF_STATUS_SUCCESS for success or error code. 3563 */ 3564 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3565 uint8_t vdev_id, int value) 3566 { 3567 QDF_STATUS ret; 3568 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3569 wmi_buf_t buf; 3570 uint16_t len = sizeof(*cmd); 3571 3572 buf = wmi_buf_alloc(wmi_handle, len); 3573 if (!buf) { 3574 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3575 return QDF_STATUS_E_NOMEM; 3576 } 3577 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3578 WMITLV_SET_HDR(&cmd->tlv_header, 3579 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3580 WMITLV_GET_STRUCT_TLVLEN 3581 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3582 3583 cmd->vdev_id = vdev_id; 3584 3585 /* WMI_SMPS_FORCED_MODE values do not directly map 3586 * to SM power save values defined in the specification. 3587 * Make sure to send the right mapping. 3588 */ 3589 switch (value) { 3590 case 0: 3591 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3592 break; 3593 case 1: 3594 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3595 break; 3596 case 2: 3597 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3598 break; 3599 case 3: 3600 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3601 break; 3602 default: 3603 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3604 wmi_buf_free(buf); 3605 return QDF_STATUS_E_FAILURE; 3606 } 3607 3608 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3609 3610 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 3611 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3612 WMI_STA_SMPS_FORCE_MODE_CMDID); 3613 if (QDF_IS_STATUS_ERROR(ret)) { 3614 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3615 wmi_buf_free(buf); 3616 } 3617 3618 return ret; 3619 } 3620 3621 /** 3622 * send_set_smps_params_cmd_tlv() - set smps params 3623 * @wmi_handle: wmi handle 3624 * @vdev_id: vdev id 3625 * @value: value 3626 * 3627 * Return: QDF_STATUS_SUCCESS for success or error code. 3628 */ 3629 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3630 int value) 3631 { 3632 QDF_STATUS ret; 3633 wmi_sta_smps_param_cmd_fixed_param *cmd; 3634 wmi_buf_t buf; 3635 uint16_t len = sizeof(*cmd); 3636 3637 buf = wmi_buf_alloc(wmi_handle, len); 3638 if (!buf) { 3639 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 3640 return QDF_STATUS_E_NOMEM; 3641 } 3642 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3643 WMITLV_SET_HDR(&cmd->tlv_header, 3644 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3645 WMITLV_GET_STRUCT_TLVLEN 3646 (wmi_sta_smps_param_cmd_fixed_param)); 3647 3648 cmd->vdev_id = vdev_id; 3649 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3650 cmd->param = 3651 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3652 3653 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3654 cmd->param); 3655 3656 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 3657 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3658 WMI_STA_SMPS_PARAM_CMDID); 3659 if (QDF_IS_STATUS_ERROR(ret)) { 3660 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3661 wmi_buf_free(buf); 3662 } 3663 3664 return ret; 3665 } 3666 3667 /** 3668 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw 3669 * @wmi_handle: wmi handle 3670 * @noa: p2p power save parameters 3671 * 3672 * Return: CDF status 3673 */ 3674 static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle, 3675 struct p2p_ps_params *noa) 3676 { 3677 wmi_p2p_set_noa_cmd_fixed_param *cmd; 3678 wmi_p2p_noa_descriptor *noa_discriptor; 3679 wmi_buf_t buf; 3680 uint8_t *buf_ptr; 3681 uint16_t len; 3682 QDF_STATUS status; 3683 uint32_t duration; 3684 3685 WMI_LOGD("%s: Enter", __func__); 3686 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); 3687 buf = wmi_buf_alloc(wmi_handle, len); 3688 if (!buf) { 3689 WMI_LOGE("Failed to allocate memory"); 3690 status = QDF_STATUS_E_FAILURE; 3691 goto end; 3692 } 3693 3694 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3695 cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; 3696 WMITLV_SET_HDR(&cmd->tlv_header, 3697 WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, 3698 WMITLV_GET_STRUCT_TLVLEN 3699 (wmi_p2p_set_noa_cmd_fixed_param)); 3700 duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration; 3701 cmd->vdev_id = noa->session_id; 3702 cmd->enable = (duration) ? true : false; 3703 cmd->num_noa = 1; 3704 3705 WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), 3706 WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor)); 3707 noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + 3708 sizeof 3709 (wmi_p2p_set_noa_cmd_fixed_param) 3710 + WMI_TLV_HDR_SIZE); 3711 WMITLV_SET_HDR(&noa_discriptor->tlv_header, 3712 WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, 3713 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); 3714 noa_discriptor->type_count = noa->count; 3715 noa_discriptor->duration = duration; 3716 noa_discriptor->interval = noa->interval; 3717 noa_discriptor->start_time = 0; 3718 3719 WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", 3720 cmd->vdev_id, noa->count, noa_discriptor->duration, 3721 noa->interval); 3722 wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0); 3723 status = wmi_unified_cmd_send(wmi_handle, buf, len, 3724 WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); 3725 if (QDF_IS_STATUS_ERROR(status)) { 3726 WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); 3727 wmi_buf_free(buf); 3728 } 3729 3730 end: 3731 WMI_LOGD("%s: Exit", __func__); 3732 return status; 3733 } 3734 3735 3736 /** 3737 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw 3738 * @wmi_handle: wmi handle 3739 * @noa: p2p opp power save parameters 3740 * 3741 * Return: CDF status 3742 */ 3743 static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle, 3744 struct p2p_ps_params *oppps) 3745 { 3746 wmi_p2p_set_oppps_cmd_fixed_param *cmd; 3747 wmi_buf_t buf; 3748 QDF_STATUS status; 3749 3750 WMI_LOGD("%s: Enter", __func__); 3751 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 3752 if (!buf) { 3753 WMI_LOGE("Failed to allocate memory"); 3754 status = QDF_STATUS_E_FAILURE; 3755 goto end; 3756 } 3757 3758 cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); 3759 WMITLV_SET_HDR(&cmd->tlv_header, 3760 WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, 3761 WMITLV_GET_STRUCT_TLVLEN 3762 (wmi_p2p_set_oppps_cmd_fixed_param)); 3763 cmd->vdev_id = oppps->session_id; 3764 if (oppps->ctwindow) 3765 WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); 3766 3767 WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow); 3768 WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", 3769 cmd->vdev_id, oppps->ctwindow); 3770 wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0); 3771 status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 3772 WMI_P2P_SET_OPPPS_PARAM_CMDID); 3773 if (QDF_IS_STATUS_ERROR(status)) { 3774 WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); 3775 wmi_buf_free(buf); 3776 } 3777 3778 end: 3779 WMI_LOGD("%s: Exit", __func__); 3780 return status; 3781 } 3782 3783 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 3784 /** 3785 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw 3786 * @wmi_handle: wmi handle 3787 * @param: p2p listen offload start parameters 3788 * 3789 * Return: QDF status 3790 */ 3791 static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, 3792 struct p2p_lo_start *param) 3793 { 3794 wmi_buf_t buf; 3795 wmi_p2p_lo_start_cmd_fixed_param *cmd; 3796 int32_t len = sizeof(*cmd); 3797 uint8_t *buf_ptr; 3798 QDF_STATUS status; 3799 int device_types_len_aligned; 3800 int probe_resp_len_aligned; 3801 3802 if (!param) { 3803 WMI_LOGE("lo start param is null"); 3804 return QDF_STATUS_E_INVAL; 3805 } 3806 3807 WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); 3808 3809 device_types_len_aligned = 3810 qdf_roundup(param->dev_types_len, 3811 sizeof(uint32_t)); 3812 probe_resp_len_aligned = 3813 qdf_roundup(param->probe_resp_len, 3814 sizeof(uint32_t)); 3815 3816 len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + 3817 probe_resp_len_aligned; 3818 3819 buf = wmi_buf_alloc(wmi_handle, len); 3820 if (!buf) { 3821 WMI_LOGE("%s: Failed to allocate memory for p2p lo start", 3822 __func__); 3823 return QDF_STATUS_E_NOMEM; 3824 } 3825 3826 cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); 3827 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3828 3829 WMITLV_SET_HDR(&cmd->tlv_header, 3830 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, 3831 WMITLV_GET_STRUCT_TLVLEN( 3832 wmi_p2p_lo_start_cmd_fixed_param)); 3833 3834 cmd->vdev_id = param->vdev_id; 3835 cmd->ctl_flags = param->ctl_flags; 3836 cmd->channel = param->freq; 3837 cmd->period = param->period; 3838 cmd->interval = param->interval; 3839 cmd->count = param->count; 3840 cmd->device_types_len = param->dev_types_len; 3841 cmd->prob_resp_len = param->probe_resp_len; 3842 3843 buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); 3844 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3845 device_types_len_aligned); 3846 buf_ptr += WMI_TLV_HDR_SIZE; 3847 qdf_mem_copy(buf_ptr, param->device_types, 3848 param->dev_types_len); 3849 3850 buf_ptr += device_types_len_aligned; 3851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3852 probe_resp_len_aligned); 3853 buf_ptr += WMI_TLV_HDR_SIZE; 3854 qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, 3855 param->probe_resp_len); 3856 3857 WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, 3858 cmd->channel, cmd->period, cmd->interval, cmd->count); 3859 3860 wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0); 3861 status = wmi_unified_cmd_send(wmi_handle, 3862 buf, len, 3863 WMI_P2P_LISTEN_OFFLOAD_START_CMDID); 3864 if (status != QDF_STATUS_SUCCESS) { 3865 WMI_LOGE("%s: Failed to send p2p lo start: %d", 3866 __func__, status); 3867 wmi_buf_free(buf); 3868 return status; 3869 } 3870 3871 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); 3872 3873 return QDF_STATUS_SUCCESS; 3874 } 3875 3876 /** 3877 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw 3878 * @wmi_handle: wmi handle 3879 * @param: p2p listen offload stop parameters 3880 * 3881 * Return: QDF status 3882 */ 3883 static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, 3884 uint8_t vdev_id) 3885 { 3886 wmi_buf_t buf; 3887 wmi_p2p_lo_stop_cmd_fixed_param *cmd; 3888 int32_t len; 3889 QDF_STATUS status; 3890 3891 WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); 3892 3893 len = sizeof(*cmd); 3894 buf = wmi_buf_alloc(wmi_handle, len); 3895 if (!buf) { 3896 qdf_print("%s: Failed to allocate memory for p2p lo stop", 3897 __func__); 3898 return QDF_STATUS_E_NOMEM; 3899 } 3900 cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); 3901 3902 WMITLV_SET_HDR(&cmd->tlv_header, 3903 WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, 3904 WMITLV_GET_STRUCT_TLVLEN( 3905 wmi_p2p_lo_stop_cmd_fixed_param)); 3906 3907 cmd->vdev_id = vdev_id; 3908 3909 WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); 3910 3911 wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0); 3912 status = wmi_unified_cmd_send(wmi_handle, 3913 buf, len, 3914 WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); 3915 if (status != QDF_STATUS_SUCCESS) { 3916 WMI_LOGE("%s: Failed to send p2p lo stop: %d", 3917 __func__, status); 3918 wmi_buf_free(buf); 3919 return status; 3920 } 3921 3922 WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); 3923 3924 return QDF_STATUS_SUCCESS; 3925 } 3926 #endif /* End of FEATURE_P2P_LISTEN_OFFLOAD */ 3927 3928 /** 3929 * send_get_temperature_cmd_tlv() - get pdev temperature req 3930 * @wmi_handle: wmi handle 3931 * 3932 * Return: QDF_STATUS_SUCCESS for success or error code. 3933 */ 3934 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3935 { 3936 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3937 wmi_buf_t wmi_buf; 3938 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3939 uint8_t *buf_ptr; 3940 3941 if (!wmi_handle) { 3942 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3943 return QDF_STATUS_E_INVAL; 3944 } 3945 3946 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3947 if (!wmi_buf) { 3948 WMI_LOGE(FL("wmi_buf_alloc failed")); 3949 return QDF_STATUS_E_NOMEM; 3950 } 3951 3952 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3953 3954 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3955 WMITLV_SET_HDR(&cmd->tlv_header, 3956 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3957 WMITLV_GET_STRUCT_TLVLEN 3958 (wmi_pdev_get_temperature_cmd_fixed_param)); 3959 3960 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 3961 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3962 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3963 WMI_LOGE(FL("failed to send get temperature command")); 3964 wmi_buf_free(wmi_buf); 3965 return QDF_STATUS_E_FAILURE; 3966 } 3967 3968 return QDF_STATUS_SUCCESS; 3969 } 3970 3971 /** 3972 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3973 * @wmi_handle: wmi handle 3974 * @vdevid: vdev id 3975 * @peer_addr: peer mac address 3976 * @auto_triggerparam: auto trigger parameters 3977 * @num_ac: number of access category 3978 * 3979 * This function sets the trigger 3980 * uapsd params such as service interval, delay interval 3981 * and suspend interval which will be used by the firmware 3982 * to send trigger frames periodically when there is no 3983 * traffic on the transmit side. 3984 * 3985 * Return: QDF_STATUS_SUCCESS for success or error code. 3986 */ 3987 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3988 struct sta_uapsd_trig_params *param) 3989 { 3990 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3991 QDF_STATUS ret; 3992 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3993 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3994 uint32_t i; 3995 wmi_buf_t buf; 3996 uint8_t *buf_ptr; 3997 struct sta_uapsd_params *uapsd_param; 3998 wmi_sta_uapsd_auto_trig_param *trig_param; 3999 4000 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4001 if (!buf) { 4002 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 4003 return QDF_STATUS_E_NOMEM; 4004 } 4005 4006 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4007 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4008 WMITLV_SET_HDR(&cmd->tlv_header, 4009 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4010 WMITLV_GET_STRUCT_TLVLEN 4011 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4012 cmd->vdev_id = param->vdevid; 4013 cmd->num_ac = param->num_ac; 4014 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4015 4016 /* TLV indicating array of structures to follow */ 4017 buf_ptr += sizeof(*cmd); 4018 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4019 4020 buf_ptr += WMI_TLV_HDR_SIZE; 4021 4022 /* 4023 * Update tag and length for uapsd auto trigger params (this will take 4024 * care of updating tag and length if it is not pre-filled by caller). 4025 */ 4026 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4027 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4028 for (i = 0; i < param->num_ac; i++) { 4029 WMITLV_SET_HDR((buf_ptr + 4030 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4031 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4032 WMITLV_GET_STRUCT_TLVLEN 4033 (wmi_sta_uapsd_auto_trig_param)); 4034 trig_param->wmm_ac = uapsd_param->wmm_ac; 4035 trig_param->user_priority = uapsd_param->user_priority; 4036 trig_param->service_interval = uapsd_param->service_interval; 4037 trig_param->suspend_interval = uapsd_param->suspend_interval; 4038 trig_param->delay_interval = uapsd_param->delay_interval; 4039 trig_param++; 4040 uapsd_param++; 4041 } 4042 4043 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4044 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4045 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4046 if (QDF_IS_STATUS_ERROR(ret)) { 4047 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 4048 wmi_buf_free(buf); 4049 } 4050 4051 return ret; 4052 } 4053 4054 #ifdef WLAN_FEATURE_DSRC 4055 /** 4056 * send_ocb_set_utc_time_cmd() - send the UTC time to the firmware 4057 * @wmi_handle: pointer to the wmi handle 4058 * @utc: pointer to the UTC time struct 4059 * 4060 * Return: 0 on succes 4061 */ 4062 static QDF_STATUS send_ocb_set_utc_time_cmd_tlv(wmi_unified_t wmi_handle, 4063 struct ocb_utc_param *utc) 4064 { 4065 QDF_STATUS ret; 4066 wmi_ocb_set_utc_time_cmd_fixed_param *cmd; 4067 uint8_t *buf_ptr; 4068 uint32_t len, i; 4069 wmi_buf_t buf; 4070 4071 len = sizeof(*cmd); 4072 buf = wmi_buf_alloc(wmi_handle, len); 4073 if (!buf) { 4074 WMI_LOGE(FL("wmi_buf_alloc failed")); 4075 return QDF_STATUS_E_NOMEM; 4076 } 4077 4078 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4079 cmd = (wmi_ocb_set_utc_time_cmd_fixed_param *)buf_ptr; 4080 WMITLV_SET_HDR(&cmd->tlv_header, 4081 WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, 4082 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_utc_time_cmd_fixed_param)); 4083 cmd->vdev_id = utc->vdev_id; 4084 4085 for (i = 0; i < SIZE_UTC_TIME; i++) 4086 WMI_UTC_TIME_SET(cmd, i, utc->utc_time[i]); 4087 4088 for (i = 0; i < SIZE_UTC_TIME_ERROR; i++) 4089 WMI_TIME_ERROR_SET(cmd, i, utc->time_error[i]); 4090 4091 wmi_mtrace(WMI_OCB_SET_UTC_TIME_CMDID, cmd->vdev_id, 0); 4092 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4093 WMI_OCB_SET_UTC_TIME_CMDID); 4094 if (QDF_IS_STATUS_ERROR(ret)) { 4095 WMI_LOGE(FL("Failed to set OCB UTC time")); 4096 wmi_buf_free(buf); 4097 } 4098 4099 return ret; 4100 } 4101 4102 /** 4103 * send_ocb_start_timing_advert_cmd_tlv() - start sending the timing advertisement 4104 * frames on a channel 4105 * @wmi_handle: pointer to the wmi handle 4106 * @timing_advert: pointer to the timing advertisement struct 4107 * 4108 * Return: 0 on succes 4109 */ 4110 static QDF_STATUS send_ocb_start_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 4111 struct ocb_timing_advert_param *timing_advert) 4112 { 4113 QDF_STATUS ret; 4114 wmi_ocb_start_timing_advert_cmd_fixed_param *cmd; 4115 uint8_t *buf_ptr; 4116 uint32_t len, len_template; 4117 wmi_buf_t buf; 4118 4119 len = sizeof(*cmd) + 4120 WMI_TLV_HDR_SIZE; 4121 4122 len_template = timing_advert->template_length; 4123 /* Add padding to the template if needed */ 4124 if (len_template % 4 != 0) 4125 len_template += 4 - (len_template % 4); 4126 len += len_template; 4127 4128 buf = wmi_buf_alloc(wmi_handle, len); 4129 if (!buf) { 4130 WMI_LOGE(FL("wmi_buf_alloc failed")); 4131 return QDF_STATUS_E_NOMEM; 4132 } 4133 4134 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4135 cmd = (wmi_ocb_start_timing_advert_cmd_fixed_param *)buf_ptr; 4136 WMITLV_SET_HDR(&cmd->tlv_header, 4137 WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, 4138 WMITLV_GET_STRUCT_TLVLEN( 4139 wmi_ocb_start_timing_advert_cmd_fixed_param)); 4140 cmd->vdev_id = timing_advert->vdev_id; 4141 cmd->repeat_rate = timing_advert->repeat_rate; 4142 cmd->channel_freq = timing_advert->chan_freq; 4143 cmd->timestamp_offset = timing_advert->timestamp_offset; 4144 cmd->time_value_offset = timing_advert->time_value_offset; 4145 cmd->timing_advert_template_length = timing_advert->template_length; 4146 buf_ptr += sizeof(*cmd); 4147 4148 /* Add the timing advert template */ 4149 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4150 len_template); 4151 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 4152 (uint8_t *)timing_advert->template_value, 4153 timing_advert->template_length); 4154 4155 wmi_mtrace(WMI_OCB_START_TIMING_ADVERT_CMDID, cmd->vdev_id, 0); 4156 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4157 WMI_OCB_START_TIMING_ADVERT_CMDID); 4158 if (QDF_IS_STATUS_ERROR(ret)) { 4159 WMI_LOGE(FL("Failed to start OCB timing advert")); 4160 wmi_buf_free(buf); 4161 } 4162 4163 return ret; 4164 } 4165 4166 /** 4167 * send_ocb_stop_timing_advert_cmd_tlv() - stop sending the timing advertisement frames 4168 * on a channel 4169 * @wmi_handle: pointer to the wmi handle 4170 * @timing_advert: pointer to the timing advertisement struct 4171 * 4172 * Return: 0 on succes 4173 */ 4174 static QDF_STATUS send_ocb_stop_timing_advert_cmd_tlv(wmi_unified_t wmi_handle, 4175 struct ocb_timing_advert_param *timing_advert) 4176 { 4177 QDF_STATUS ret; 4178 wmi_ocb_stop_timing_advert_cmd_fixed_param *cmd; 4179 uint8_t *buf_ptr; 4180 uint32_t len; 4181 wmi_buf_t buf; 4182 4183 len = sizeof(*cmd); 4184 buf = wmi_buf_alloc(wmi_handle, len); 4185 if (!buf) { 4186 WMI_LOGE(FL("wmi_buf_alloc failed")); 4187 return QDF_STATUS_E_NOMEM; 4188 } 4189 4190 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4191 cmd = (wmi_ocb_stop_timing_advert_cmd_fixed_param *)buf_ptr; 4192 WMITLV_SET_HDR(&cmd->tlv_header, 4193 WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, 4194 WMITLV_GET_STRUCT_TLVLEN( 4195 wmi_ocb_stop_timing_advert_cmd_fixed_param)); 4196 cmd->vdev_id = timing_advert->vdev_id; 4197 cmd->channel_freq = timing_advert->chan_freq; 4198 4199 wmi_mtrace(WMI_OCB_STOP_TIMING_ADVERT_CMDID, cmd->vdev_id, 0); 4200 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4201 WMI_OCB_STOP_TIMING_ADVERT_CMDID); 4202 if (QDF_IS_STATUS_ERROR(ret)) { 4203 WMI_LOGE(FL("Failed to stop OCB timing advert")); 4204 wmi_buf_free(buf); 4205 } 4206 4207 return ret; 4208 } 4209 4210 /** 4211 * send_ocb_get_tsf_timer_cmd_tlv() - get ocb tsf timer val 4212 * @wmi_handle: pointer to the wmi handle 4213 * @request: pointer to the request 4214 * 4215 * Return: 0 on succes 4216 */ 4217 static QDF_STATUS send_ocb_get_tsf_timer_cmd_tlv(wmi_unified_t wmi_handle, 4218 uint8_t vdev_id) 4219 { 4220 QDF_STATUS ret; 4221 wmi_ocb_get_tsf_timer_cmd_fixed_param *cmd; 4222 uint8_t *buf_ptr; 4223 wmi_buf_t buf; 4224 int32_t len; 4225 4226 len = sizeof(*cmd); 4227 buf = wmi_buf_alloc(wmi_handle, len); 4228 if (!buf) { 4229 WMI_LOGE(FL("wmi_buf_alloc failed")); 4230 return QDF_STATUS_E_NOMEM; 4231 } 4232 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4233 4234 cmd = (wmi_ocb_get_tsf_timer_cmd_fixed_param *)buf_ptr; 4235 qdf_mem_zero(cmd, len); 4236 WMITLV_SET_HDR(&cmd->tlv_header, 4237 WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, 4238 WMITLV_GET_STRUCT_TLVLEN( 4239 wmi_ocb_get_tsf_timer_cmd_fixed_param)); 4240 cmd->vdev_id = vdev_id; 4241 4242 /* Send the WMI command */ 4243 wmi_mtrace(WMI_OCB_GET_TSF_TIMER_CMDID, cmd->vdev_id, 0); 4244 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4245 WMI_OCB_GET_TSF_TIMER_CMDID); 4246 /* If there is an error, set the completion event */ 4247 if (QDF_IS_STATUS_ERROR(ret)) { 4248 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4249 wmi_buf_free(buf); 4250 } 4251 4252 return ret; 4253 } 4254 4255 /** 4256 * send_dcc_get_stats_cmd_tlv() - get the DCC channel stats 4257 * @wmi_handle: pointer to the wmi handle 4258 * @get_stats_param: pointer to the dcc stats 4259 * 4260 * Return: 0 on succes 4261 */ 4262 static QDF_STATUS send_dcc_get_stats_cmd_tlv(wmi_unified_t wmi_handle, 4263 struct ocb_dcc_get_stats_param *get_stats_param) 4264 { 4265 QDF_STATUS ret; 4266 wmi_dcc_get_stats_cmd_fixed_param *cmd; 4267 wmi_dcc_channel_stats_request *channel_stats_array; 4268 wmi_buf_t buf; 4269 uint8_t *buf_ptr; 4270 uint32_t len; 4271 uint32_t i; 4272 4273 /* Validate the input */ 4274 if (get_stats_param->request_array_len != 4275 get_stats_param->channel_count * sizeof(*channel_stats_array)) { 4276 WMI_LOGE(FL("Invalid parameter")); 4277 return QDF_STATUS_E_INVAL; 4278 } 4279 4280 /* Allocate memory for the WMI command */ 4281 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4282 get_stats_param->request_array_len; 4283 4284 buf = wmi_buf_alloc(wmi_handle, len); 4285 if (!buf) { 4286 WMI_LOGE(FL("wmi_buf_alloc failed")); 4287 return QDF_STATUS_E_NOMEM; 4288 } 4289 4290 buf_ptr = wmi_buf_data(buf); 4291 qdf_mem_zero(buf_ptr, len); 4292 4293 /* Populate the WMI command */ 4294 cmd = (wmi_dcc_get_stats_cmd_fixed_param *)buf_ptr; 4295 buf_ptr += sizeof(*cmd); 4296 4297 WMITLV_SET_HDR(&cmd->tlv_header, 4298 WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, 4299 WMITLV_GET_STRUCT_TLVLEN( 4300 wmi_dcc_get_stats_cmd_fixed_param)); 4301 cmd->vdev_id = get_stats_param->vdev_id; 4302 cmd->num_channels = get_stats_param->channel_count; 4303 4304 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4305 get_stats_param->request_array_len); 4306 buf_ptr += WMI_TLV_HDR_SIZE; 4307 4308 channel_stats_array = (wmi_dcc_channel_stats_request *)buf_ptr; 4309 qdf_mem_copy(channel_stats_array, get_stats_param->request_array, 4310 get_stats_param->request_array_len); 4311 for (i = 0; i < cmd->num_channels; i++) 4312 WMITLV_SET_HDR(&channel_stats_array[i].tlv_header, 4313 WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, 4314 WMITLV_GET_STRUCT_TLVLEN( 4315 wmi_dcc_channel_stats_request)); 4316 4317 /* Send the WMI command */ 4318 wmi_mtrace(WMI_DCC_GET_STATS_CMDID, cmd->vdev_id, 0); 4319 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4320 WMI_DCC_GET_STATS_CMDID); 4321 4322 if (QDF_IS_STATUS_ERROR(ret)) { 4323 WMI_LOGE(FL("Failed to send WMI message: %d"), ret); 4324 wmi_buf_free(buf); 4325 } 4326 4327 return ret; 4328 } 4329 4330 /** 4331 * send_dcc_clear_stats_cmd_tlv() - command to clear the DCC stats 4332 * @wmi_handle: pointer to the wmi handle 4333 * @vdev_id: vdev id 4334 * @dcc_stats_bitmap: dcc status bitmap 4335 * 4336 * Return: 0 on succes 4337 */ 4338 static QDF_STATUS send_dcc_clear_stats_cmd_tlv(wmi_unified_t wmi_handle, 4339 uint32_t vdev_id, uint32_t dcc_stats_bitmap) 4340 { 4341 QDF_STATUS ret; 4342 wmi_dcc_clear_stats_cmd_fixed_param *cmd; 4343 wmi_buf_t buf; 4344 uint8_t *buf_ptr; 4345 uint32_t len; 4346 4347 /* Allocate memory for the WMI command */ 4348 len = sizeof(*cmd); 4349 4350 buf = wmi_buf_alloc(wmi_handle, len); 4351 if (!buf) { 4352 WMI_LOGE(FL("wmi_buf_alloc failed")); 4353 return QDF_STATUS_E_NOMEM; 4354 } 4355 4356 buf_ptr = wmi_buf_data(buf); 4357 qdf_mem_zero(buf_ptr, len); 4358 4359 /* Populate the WMI command */ 4360 cmd = (wmi_dcc_clear_stats_cmd_fixed_param *)buf_ptr; 4361 4362 WMITLV_SET_HDR(&cmd->tlv_header, 4363 WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, 4364 WMITLV_GET_STRUCT_TLVLEN( 4365 wmi_dcc_clear_stats_cmd_fixed_param)); 4366 cmd->vdev_id = vdev_id; 4367 cmd->dcc_stats_bitmap = dcc_stats_bitmap; 4368 4369 /* Send the WMI command */ 4370 wmi_mtrace(WMI_DCC_CLEAR_STATS_CMDID, cmd->vdev_id, 0); 4371 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4372 WMI_DCC_CLEAR_STATS_CMDID); 4373 if (QDF_IS_STATUS_ERROR(ret)) { 4374 WMI_LOGE(FL("Failed to send the WMI command")); 4375 wmi_buf_free(buf); 4376 } 4377 4378 return ret; 4379 } 4380 4381 /** 4382 * send_dcc_update_ndl_cmd_tlv() - command to update the NDL data 4383 * @wmi_handle: pointer to the wmi handle 4384 * @update_ndl_param: pointer to the request parameters 4385 * 4386 * Return: 0 on success 4387 */ 4388 static QDF_STATUS send_dcc_update_ndl_cmd_tlv(wmi_unified_t wmi_handle, 4389 struct ocb_dcc_update_ndl_param *update_ndl_param) 4390 { 4391 QDF_STATUS qdf_status; 4392 wmi_dcc_update_ndl_cmd_fixed_param *cmd; 4393 wmi_dcc_ndl_chan *ndl_chan_array; 4394 wmi_dcc_ndl_active_state_config *ndl_active_state_array; 4395 uint32_t active_state_count; 4396 wmi_buf_t buf; 4397 uint8_t *buf_ptr; 4398 uint32_t len; 4399 uint32_t i; 4400 4401 /* validate the input */ 4402 if (update_ndl_param->dcc_ndl_chan_list_len != 4403 update_ndl_param->channel_count * sizeof(*ndl_chan_array)) { 4404 WMI_LOGE(FL("Invalid parameter")); 4405 return QDF_STATUS_E_INVAL; 4406 } 4407 active_state_count = 0; 4408 ndl_chan_array = update_ndl_param->dcc_ndl_chan_list; 4409 for (i = 0; i < update_ndl_param->channel_count; i++) 4410 active_state_count += 4411 WMI_NDL_NUM_ACTIVE_STATE_GET(&ndl_chan_array[i]); 4412 if (update_ndl_param->dcc_ndl_active_state_list_len != 4413 active_state_count * sizeof(*ndl_active_state_array)) { 4414 WMI_LOGE(FL("Invalid parameter")); 4415 return QDF_STATUS_E_INVAL; 4416 } 4417 4418 /* Allocate memory for the WMI command */ 4419 len = sizeof(*cmd) + 4420 WMI_TLV_HDR_SIZE + update_ndl_param->dcc_ndl_chan_list_len + 4421 WMI_TLV_HDR_SIZE + 4422 update_ndl_param->dcc_ndl_active_state_list_len; 4423 4424 buf = wmi_buf_alloc(wmi_handle, len); 4425 if (!buf) { 4426 WMI_LOGE(FL("wmi_buf_alloc failed")); 4427 return QDF_STATUS_E_NOMEM; 4428 } 4429 4430 buf_ptr = wmi_buf_data(buf); 4431 qdf_mem_zero(buf_ptr, len); 4432 4433 /* Populate the WMI command */ 4434 cmd = (wmi_dcc_update_ndl_cmd_fixed_param *)buf_ptr; 4435 buf_ptr += sizeof(*cmd); 4436 4437 WMITLV_SET_HDR(&cmd->tlv_header, 4438 WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, 4439 WMITLV_GET_STRUCT_TLVLEN( 4440 wmi_dcc_update_ndl_cmd_fixed_param)); 4441 cmd->vdev_id = update_ndl_param->vdev_id; 4442 cmd->num_channel = update_ndl_param->channel_count; 4443 4444 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4445 update_ndl_param->dcc_ndl_chan_list_len); 4446 buf_ptr += WMI_TLV_HDR_SIZE; 4447 4448 ndl_chan_array = (wmi_dcc_ndl_chan *)buf_ptr; 4449 qdf_mem_copy(ndl_chan_array, update_ndl_param->dcc_ndl_chan_list, 4450 update_ndl_param->dcc_ndl_chan_list_len); 4451 for (i = 0; i < cmd->num_channel; i++) 4452 WMITLV_SET_HDR(&ndl_chan_array[i].tlv_header, 4453 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4454 WMITLV_GET_STRUCT_TLVLEN( 4455 wmi_dcc_ndl_chan)); 4456 buf_ptr += update_ndl_param->dcc_ndl_chan_list_len; 4457 4458 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4459 update_ndl_param->dcc_ndl_active_state_list_len); 4460 buf_ptr += WMI_TLV_HDR_SIZE; 4461 4462 ndl_active_state_array = (wmi_dcc_ndl_active_state_config *) buf_ptr; 4463 qdf_mem_copy(ndl_active_state_array, 4464 update_ndl_param->dcc_ndl_active_state_list, 4465 update_ndl_param->dcc_ndl_active_state_list_len); 4466 for (i = 0; i < active_state_count; i++) { 4467 WMITLV_SET_HDR(&ndl_active_state_array[i].tlv_header, 4468 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4469 WMITLV_GET_STRUCT_TLVLEN( 4470 wmi_dcc_ndl_active_state_config)); 4471 } 4472 buf_ptr += update_ndl_param->dcc_ndl_active_state_list_len; 4473 4474 /* Send the WMI command */ 4475 wmi_mtrace(WMI_DCC_UPDATE_NDL_CMDID, cmd->vdev_id, 0); 4476 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 4477 WMI_DCC_UPDATE_NDL_CMDID); 4478 /* If there is an error, set the completion event */ 4479 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4480 WMI_LOGE(FL("Failed to send WMI message: %d"), qdf_status); 4481 wmi_buf_free(buf); 4482 } 4483 4484 return qdf_status; 4485 } 4486 4487 /** 4488 * send_ocb_set_config_cmd_tlv() - send the OCB config to the FW 4489 * @wmi_handle: pointer to the wmi handle 4490 * @config: the OCB configuration 4491 * 4492 * Return: 0 on success 4493 */ 4494 static QDF_STATUS send_ocb_set_config_cmd_tlv(wmi_unified_t wmi_handle, 4495 struct ocb_config *config) 4496 { 4497 QDF_STATUS ret; 4498 wmi_ocb_set_config_cmd_fixed_param *cmd; 4499 wmi_channel *chan; 4500 wmi_ocb_channel *ocb_chan; 4501 wmi_qos_parameter *qos_param; 4502 wmi_dcc_ndl_chan *ndl_chan; 4503 wmi_dcc_ndl_active_state_config *ndl_active_config; 4504 wmi_ocb_schedule_element *sched_elem; 4505 uint8_t *buf_ptr; 4506 wmi_buf_t buf; 4507 int32_t len; 4508 int32_t i, j, active_state_count; 4509 4510 /* 4511 * Validate the dcc_ndl_chan_list_len and count the number of active 4512 * states. Validate dcc_ndl_active_state_list_len. 4513 */ 4514 active_state_count = 0; 4515 if (config->dcc_ndl_chan_list_len) { 4516 if (!config->dcc_ndl_chan_list || 4517 config->dcc_ndl_chan_list_len != 4518 config->channel_count * sizeof(wmi_dcc_ndl_chan)) { 4519 WMI_LOGE(FL("NDL channel is invalid. List len: %d"), 4520 config->dcc_ndl_chan_list_len); 4521 return QDF_STATUS_E_INVAL; 4522 } 4523 4524 for (i = 0, ndl_chan = config->dcc_ndl_chan_list; 4525 i < config->channel_count; ++i, ++ndl_chan) 4526 active_state_count += 4527 WMI_NDL_NUM_ACTIVE_STATE_GET(ndl_chan); 4528 4529 if (active_state_count) { 4530 if (!config->dcc_ndl_active_state_list || 4531 config->dcc_ndl_active_state_list_len != 4532 active_state_count * 4533 sizeof(wmi_dcc_ndl_active_state_config)) { 4534 WMI_LOGE(FL("NDL active state is invalid.")); 4535 return QDF_STATUS_E_INVAL; 4536 } 4537 } 4538 } 4539 4540 len = sizeof(*cmd) + 4541 WMI_TLV_HDR_SIZE + config->channel_count * 4542 sizeof(wmi_channel) + 4543 WMI_TLV_HDR_SIZE + config->channel_count * 4544 sizeof(wmi_ocb_channel) + 4545 WMI_TLV_HDR_SIZE + config->channel_count * 4546 sizeof(wmi_qos_parameter) * WMI_MAX_NUM_AC + 4547 WMI_TLV_HDR_SIZE + config->dcc_ndl_chan_list_len + 4548 WMI_TLV_HDR_SIZE + active_state_count * 4549 sizeof(wmi_dcc_ndl_active_state_config) + 4550 WMI_TLV_HDR_SIZE + config->schedule_size * 4551 sizeof(wmi_ocb_schedule_element); 4552 buf = wmi_buf_alloc(wmi_handle, len); 4553 if (!buf) { 4554 WMI_LOGE(FL("wmi_buf_alloc failed")); 4555 return QDF_STATUS_E_NOMEM; 4556 } 4557 4558 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4559 cmd = (wmi_ocb_set_config_cmd_fixed_param *)buf_ptr; 4560 WMITLV_SET_HDR(&cmd->tlv_header, 4561 WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, 4562 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_config_cmd_fixed_param)); 4563 cmd->vdev_id = config->vdev_id; 4564 cmd->channel_count = config->channel_count; 4565 cmd->schedule_size = config->schedule_size; 4566 cmd->flags = config->flags; 4567 buf_ptr += sizeof(*cmd); 4568 4569 /* Add the wmi_channel info */ 4570 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4571 config->channel_count*sizeof(wmi_channel)); 4572 buf_ptr += WMI_TLV_HDR_SIZE; 4573 for (i = 0; i < config->channel_count; i++) { 4574 chan = (wmi_channel *)buf_ptr; 4575 WMITLV_SET_HDR(&chan->tlv_header, 4576 WMITLV_TAG_STRUC_wmi_channel, 4577 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4578 chan->mhz = config->channels[i].chan_freq; 4579 chan->band_center_freq1 = config->channels[i].chan_freq; 4580 chan->band_center_freq2 = 0; 4581 chan->info = 0; 4582 4583 WMI_SET_CHANNEL_MODE(chan, config->channels[i].ch_mode); 4584 WMI_SET_CHANNEL_MAX_POWER(chan, config->channels[i].max_pwr); 4585 WMI_SET_CHANNEL_MIN_POWER(chan, config->channels[i].min_pwr); 4586 WMI_SET_CHANNEL_MAX_TX_POWER(chan, config->channels[i].max_pwr); 4587 WMI_SET_CHANNEL_REG_POWER(chan, config->channels[i].reg_pwr); 4588 WMI_SET_CHANNEL_ANTENNA_MAX(chan, 4589 config->channels[i].antenna_max); 4590 4591 if (config->channels[i].bandwidth < 10) 4592 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 4593 else if (config->channels[i].bandwidth < 20) 4594 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 4595 buf_ptr += sizeof(*chan); 4596 } 4597 4598 /* Add the wmi_ocb_channel info */ 4599 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4600 config->channel_count*sizeof(wmi_ocb_channel)); 4601 buf_ptr += WMI_TLV_HDR_SIZE; 4602 for (i = 0; i < config->channel_count; i++) { 4603 ocb_chan = (wmi_ocb_channel *)buf_ptr; 4604 WMITLV_SET_HDR(&ocb_chan->tlv_header, 4605 WMITLV_TAG_STRUC_wmi_ocb_channel, 4606 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_channel)); 4607 ocb_chan->bandwidth = config->channels[i].bandwidth; 4608 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4609 config->channels[i].mac_address.bytes, 4610 &ocb_chan->mac_address); 4611 buf_ptr += sizeof(*ocb_chan); 4612 } 4613 4614 /* Add the wmi_qos_parameter info */ 4615 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4616 config->channel_count * sizeof(wmi_qos_parameter)*WMI_MAX_NUM_AC); 4617 buf_ptr += WMI_TLV_HDR_SIZE; 4618 /* WMI_MAX_NUM_AC parameters for each channel */ 4619 for (i = 0; i < config->channel_count; i++) { 4620 for (j = 0; j < WMI_MAX_NUM_AC; j++) { 4621 qos_param = (wmi_qos_parameter *)buf_ptr; 4622 WMITLV_SET_HDR(&qos_param->tlv_header, 4623 WMITLV_TAG_STRUC_wmi_qos_parameter, 4624 WMITLV_GET_STRUCT_TLVLEN(wmi_qos_parameter)); 4625 qos_param->aifsn = 4626 config->channels[i].qos_params[j].aifsn; 4627 qos_param->cwmin = 4628 config->channels[i].qos_params[j].cwmin; 4629 qos_param->cwmax = 4630 config->channels[i].qos_params[j].cwmax; 4631 buf_ptr += sizeof(*qos_param); 4632 } 4633 } 4634 4635 /* Add the wmi_dcc_ndl_chan (per channel) */ 4636 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4637 config->dcc_ndl_chan_list_len); 4638 buf_ptr += WMI_TLV_HDR_SIZE; 4639 if (config->dcc_ndl_chan_list_len) { 4640 ndl_chan = (wmi_dcc_ndl_chan *)buf_ptr; 4641 qdf_mem_copy(ndl_chan, config->dcc_ndl_chan_list, 4642 config->dcc_ndl_chan_list_len); 4643 for (i = 0; i < config->channel_count; i++) 4644 WMITLV_SET_HDR(&(ndl_chan[i].tlv_header), 4645 WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, 4646 WMITLV_GET_STRUCT_TLVLEN(wmi_dcc_ndl_chan)); 4647 buf_ptr += config->dcc_ndl_chan_list_len; 4648 } 4649 4650 /* Add the wmi_dcc_ndl_active_state_config */ 4651 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, active_state_count * 4652 sizeof(wmi_dcc_ndl_active_state_config)); 4653 buf_ptr += WMI_TLV_HDR_SIZE; 4654 if (active_state_count) { 4655 ndl_active_config = (wmi_dcc_ndl_active_state_config *)buf_ptr; 4656 qdf_mem_copy(ndl_active_config, 4657 config->dcc_ndl_active_state_list, 4658 active_state_count * sizeof(*ndl_active_config)); 4659 for (i = 0; i < active_state_count; ++i) 4660 WMITLV_SET_HDR(&(ndl_active_config[i].tlv_header), 4661 WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, 4662 WMITLV_GET_STRUCT_TLVLEN( 4663 wmi_dcc_ndl_active_state_config)); 4664 buf_ptr += active_state_count * 4665 sizeof(*ndl_active_config); 4666 } 4667 4668 /* Add the wmi_ocb_schedule_element info */ 4669 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4670 config->schedule_size * sizeof(wmi_ocb_schedule_element)); 4671 buf_ptr += WMI_TLV_HDR_SIZE; 4672 for (i = 0; i < config->schedule_size; i++) { 4673 sched_elem = (wmi_ocb_schedule_element *)buf_ptr; 4674 WMITLV_SET_HDR(&sched_elem->tlv_header, 4675 WMITLV_TAG_STRUC_wmi_ocb_schedule_element, 4676 WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_schedule_element)); 4677 sched_elem->channel_freq = config->schedule[i].chan_freq; 4678 sched_elem->total_duration = config->schedule[i].total_duration; 4679 sched_elem->guard_interval = config->schedule[i].guard_interval; 4680 buf_ptr += sizeof(*sched_elem); 4681 } 4682 4683 4684 wmi_mtrace(WMI_OCB_SET_CONFIG_CMDID, cmd->vdev_id, 0); 4685 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4686 WMI_OCB_SET_CONFIG_CMDID); 4687 if (QDF_IS_STATUS_ERROR(ret)) { 4688 WMI_LOGE("Failed to set OCB config"); 4689 wmi_buf_free(buf); 4690 } 4691 4692 return ret; 4693 } 4694 4695 /** 4696 * extract_ocb_channel_config_resp_tlv() - extract ocb channel config resp 4697 * @wmi_handle: wmi handle 4698 * @evt_buf: wmi event buffer 4699 * @status: status buffer 4700 * 4701 * Return: QDF_STATUS_SUCCESS on success 4702 */ 4703 static QDF_STATUS extract_ocb_channel_config_resp_tlv(wmi_unified_t wmi_handle, 4704 void *evt_buf, 4705 uint32_t *status) 4706 { 4707 WMI_OCB_SET_CONFIG_RESP_EVENTID_param_tlvs *param_tlvs; 4708 wmi_ocb_set_config_resp_event_fixed_param *fix_param; 4709 4710 param_tlvs = evt_buf; 4711 fix_param = param_tlvs->fixed_param; 4712 4713 *status = fix_param->status; 4714 return QDF_STATUS_SUCCESS; 4715 } 4716 4717 /** 4718 * extract_ocb_tsf_timer_tlv() - extract TSF timer from event buffer 4719 * @wmi_handle: wmi handle 4720 * @evt_buf: wmi event buffer 4721 * @resp: response buffer 4722 * 4723 * Return: QDF_STATUS_SUCCESS on success 4724 */ 4725 static QDF_STATUS extract_ocb_tsf_timer_tlv(wmi_unified_t wmi_handle, 4726 void *evt_buf, struct ocb_get_tsf_timer_response *resp) 4727 { 4728 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID_param_tlvs *param_tlvs; 4729 wmi_ocb_get_tsf_timer_resp_event_fixed_param *fix_param; 4730 4731 param_tlvs = evt_buf; 4732 fix_param = param_tlvs->fixed_param; 4733 resp->vdev_id = fix_param->vdev_id; 4734 resp->timer_high = fix_param->tsf_timer_high; 4735 resp->timer_low = fix_param->tsf_timer_low; 4736 4737 return QDF_STATUS_SUCCESS; 4738 } 4739 4740 /** 4741 * extract_ocb_ndl_resp_tlv() - extract TSF timer from event buffer 4742 * @wmi_handle: wmi handle 4743 * @evt_buf: wmi event buffer 4744 * @resp: response buffer 4745 * 4746 * Return: QDF_STATUS_SUCCESS on success 4747 */ 4748 static QDF_STATUS extract_ocb_ndl_resp_tlv(wmi_unified_t wmi_handle, 4749 void *evt_buf, struct ocb_dcc_update_ndl_response *resp) 4750 { 4751 WMI_DCC_UPDATE_NDL_RESP_EVENTID_param_tlvs *param_tlvs; 4752 wmi_dcc_update_ndl_resp_event_fixed_param *fix_param; 4753 4754 param_tlvs = evt_buf; 4755 fix_param = param_tlvs->fixed_param; 4756 resp->vdev_id = fix_param->vdev_id; 4757 resp->status = fix_param->status; 4758 return QDF_STATUS_SUCCESS; 4759 } 4760 4761 /** 4762 * extract_ocb_dcc_stats_tlv() - extract DCC stats from event buffer 4763 * @wmi_handle: wmi handle 4764 * @evt_buf: wmi event buffer 4765 * @resp: response buffer 4766 * 4767 * Since length of stats is variable, buffer for DCC stats will be allocated 4768 * in this function. The caller must free the buffer. 4769 * 4770 * Return: QDF_STATUS_SUCCESS on success 4771 */ 4772 static QDF_STATUS extract_ocb_dcc_stats_tlv(wmi_unified_t wmi_handle, 4773 void *evt_buf, struct ocb_dcc_get_stats_response **resp) 4774 { 4775 struct ocb_dcc_get_stats_response *response; 4776 WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *param_tlvs; 4777 wmi_dcc_get_stats_resp_event_fixed_param *fix_param; 4778 4779 param_tlvs = (WMI_DCC_GET_STATS_RESP_EVENTID_param_tlvs *)evt_buf; 4780 fix_param = param_tlvs->fixed_param; 4781 4782 /* Allocate and populate the response */ 4783 if (fix_param->num_channels > ((WMI_SVC_MSG_MAX_SIZE - 4784 sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) { 4785 WMI_LOGE("%s: too many channels:%d", __func__, 4786 fix_param->num_channels); 4787 QDF_ASSERT(0); 4788 *resp = NULL; 4789 return QDF_STATUS_E_INVAL; 4790 } 4791 response = qdf_mem_malloc(sizeof(*response) + fix_param->num_channels * 4792 sizeof(wmi_dcc_ndl_stats_per_channel)); 4793 *resp = response; 4794 if (!response) 4795 return QDF_STATUS_E_NOMEM; 4796 4797 response->vdev_id = fix_param->vdev_id; 4798 response->num_channels = fix_param->num_channels; 4799 response->channel_stats_array_len = 4800 fix_param->num_channels * 4801 sizeof(wmi_dcc_ndl_stats_per_channel); 4802 response->channel_stats_array = ((uint8_t *)response) + 4803 sizeof(*response); 4804 qdf_mem_copy(response->channel_stats_array, 4805 param_tlvs->stats_per_channel_list, 4806 response->channel_stats_array_len); 4807 4808 return QDF_STATUS_SUCCESS; 4809 } 4810 #endif 4811 4812 /** 4813 * send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv() -enable/disable mcc scheduler 4814 * @wmi_handle: wmi handle 4815 * @mcc_adaptive_scheduler: enable/disable 4816 * 4817 * This function enable/disable mcc adaptive scheduler in fw. 4818 * 4819 * Return: QDF_STATUS_SUCCESS for success or error code 4820 */ 4821 static QDF_STATUS send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv( 4822 wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, 4823 uint32_t pdev_id) 4824 { 4825 QDF_STATUS ret; 4826 wmi_buf_t buf = 0; 4827 wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; 4828 uint16_t len = 4829 sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); 4830 4831 buf = wmi_buf_alloc(wmi_handle, len); 4832 if (!buf) { 4833 WMI_LOGP("%s : wmi_buf_alloc failed", __func__); 4834 return QDF_STATUS_E_NOMEM; 4835 } 4836 cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) 4837 wmi_buf_data(buf); 4838 4839 WMITLV_SET_HDR(&cmd->tlv_header, 4840 WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, 4841 WMITLV_GET_STRUCT_TLVLEN 4842 (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); 4843 cmd->enable = mcc_adaptive_scheduler; 4844 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 4845 4846 wmi_mtrace(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID, NO_SESSION, 0); 4847 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4848 WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); 4849 if (QDF_IS_STATUS_ERROR(ret)) { 4850 WMI_LOGP("%s: Failed to send enable/disable MCC" 4851 " adaptive scheduler command", __func__); 4852 wmi_buf_free(buf); 4853 } 4854 4855 return ret; 4856 } 4857 4858 /** 4859 * send_set_mcc_channel_time_latency_cmd_tlv() -set MCC channel time latency 4860 * @wmi: wmi handle 4861 * @mcc_channel: mcc channel 4862 * @mcc_channel_time_latency: MCC channel time latency. 4863 * 4864 * Currently used to set time latency for an MCC vdev/adapter using operating 4865 * channel of it and channel number. The info is provided run time using 4866 * iwpriv command: iwpriv <wlan0 | p2p0> setMccLatency <latency in ms>. 4867 * 4868 * Return: CDF status 4869 */ 4870 static QDF_STATUS send_set_mcc_channel_time_latency_cmd_tlv(wmi_unified_t wmi_handle, 4871 uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency) 4872 { 4873 QDF_STATUS ret; 4874 wmi_buf_t buf = 0; 4875 wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; 4876 uint16_t len = 0; 4877 uint8_t *buf_ptr = NULL; 4878 wmi_resmgr_chan_latency chan_latency; 4879 /* Note: we only support MCC time latency for a single channel */ 4880 uint32_t num_channels = 1; 4881 uint32_t chan1_freq = mcc_channel_freq; 4882 uint32_t latency_chan1 = mcc_channel_time_latency; 4883 4884 4885 /* If 0ms latency is provided, then FW will set to a default. 4886 * Otherwise, latency must be at least 30ms. 4887 */ 4888 if ((latency_chan1 > 0) && 4889 (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { 4890 WMI_LOGE("%s: Invalid time latency for Channel #1 = %dms " 4891 "Minimum is 30ms (or 0 to use default value by " 4892 "firmware)", __func__, latency_chan1); 4893 return QDF_STATUS_E_INVAL; 4894 } 4895 4896 /* Set WMI CMD for channel time latency here */ 4897 len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + 4898 WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array */ 4899 num_channels * sizeof(wmi_resmgr_chan_latency); 4900 buf = wmi_buf_alloc(wmi_handle, len); 4901 if (!buf) { 4902 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4903 return QDF_STATUS_E_NOMEM; 4904 } 4905 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4906 cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) 4907 wmi_buf_data(buf); 4908 WMITLV_SET_HDR(&cmdTL->tlv_header, 4909 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, 4910 WMITLV_GET_STRUCT_TLVLEN 4911 (wmi_resmgr_set_chan_latency_cmd_fixed_param)); 4912 cmdTL->num_chans = num_channels; 4913 /* Update channel time latency information for home channel(s) */ 4914 buf_ptr += sizeof(*cmdTL); 4915 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4916 num_channels * sizeof(wmi_resmgr_chan_latency)); 4917 buf_ptr += WMI_TLV_HDR_SIZE; 4918 chan_latency.chan_mhz = chan1_freq; 4919 chan_latency.latency = latency_chan1; 4920 qdf_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); 4921 wmi_mtrace(WMI_RESMGR_SET_CHAN_LATENCY_CMDID, NO_SESSION, 0); 4922 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4923 WMI_RESMGR_SET_CHAN_LATENCY_CMDID); 4924 if (QDF_IS_STATUS_ERROR(ret)) { 4925 WMI_LOGE("%s: Failed to send MCC Channel Time Latency command", 4926 __func__); 4927 wmi_buf_free(buf); 4928 QDF_ASSERT(0); 4929 } 4930 4931 return ret; 4932 } 4933 4934 /** 4935 * send_set_mcc_channel_time_quota_cmd_tlv() -set MCC channel time quota 4936 * @wmi: wmi handle 4937 * @adapter_1_chan_number: adapter 1 channel number 4938 * @adapter_1_quota: adapter 1 quota 4939 * @adapter_2_chan_number: adapter 2 channel number 4940 * 4941 * Return: CDF status 4942 */ 4943 static QDF_STATUS send_set_mcc_channel_time_quota_cmd_tlv(wmi_unified_t wmi_handle, 4944 uint32_t adapter_1_chan_freq, 4945 uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq) 4946 { 4947 QDF_STATUS ret; 4948 wmi_buf_t buf = 0; 4949 uint16_t len = 0; 4950 uint8_t *buf_ptr = NULL; 4951 wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; 4952 wmi_resmgr_chan_time_quota chan_quota; 4953 uint32_t quota_chan1 = adapter_1_quota; 4954 /* Knowing quota of 1st chan., derive quota for 2nd chan. */ 4955 uint32_t quota_chan2 = 100 - quota_chan1; 4956 /* Note: setting time quota for MCC requires info for 2 channels */ 4957 uint32_t num_channels = 2; 4958 uint32_t chan1_freq = adapter_1_chan_freq; 4959 uint32_t chan2_freq = adapter_2_chan_freq; 4960 4961 WMI_LOGD("%s: freq1:%dMHz, Quota1:%dms, " 4962 "freq2:%dMHz, Quota2:%dms", __func__, 4963 chan1_freq, quota_chan1, chan2_freq, 4964 quota_chan2); 4965 4966 /* 4967 * Perform sanity check on time quota values provided. 4968 */ 4969 if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || 4970 quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { 4971 WMI_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " 4972 "is 20ms & maximum is 80ms", __func__, quota_chan1); 4973 return QDF_STATUS_E_INVAL; 4974 } 4975 /* Set WMI CMD for channel time quota here */ 4976 len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + 4977 WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ 4978 num_channels * sizeof(wmi_resmgr_chan_time_quota); 4979 buf = wmi_buf_alloc(wmi_handle, len); 4980 if (!buf) { 4981 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 4982 QDF_ASSERT(0); 4983 return QDF_STATUS_E_NOMEM; 4984 } 4985 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4986 cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) 4987 wmi_buf_data(buf); 4988 WMITLV_SET_HDR(&cmdTQ->tlv_header, 4989 WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, 4990 WMITLV_GET_STRUCT_TLVLEN 4991 (wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); 4992 cmdTQ->num_chans = num_channels; 4993 4994 /* Update channel time quota information for home channel(s) */ 4995 buf_ptr += sizeof(*cmdTQ); 4996 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4997 num_channels * sizeof(wmi_resmgr_chan_time_quota)); 4998 buf_ptr += WMI_TLV_HDR_SIZE; 4999 chan_quota.chan_mhz = chan1_freq; 5000 chan_quota.channel_time_quota = quota_chan1; 5001 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 5002 /* Construct channel and quota record for the 2nd MCC mode. */ 5003 buf_ptr += sizeof(chan_quota); 5004 chan_quota.chan_mhz = chan2_freq; 5005 chan_quota.channel_time_quota = quota_chan2; 5006 qdf_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); 5007 5008 wmi_mtrace(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, NO_SESSION, 0); 5009 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5010 WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); 5011 if (QDF_IS_STATUS_ERROR(ret)) { 5012 WMI_LOGE("Failed to send MCC Channel Time Quota command"); 5013 wmi_buf_free(buf); 5014 QDF_ASSERT(0); 5015 } 5016 5017 return ret; 5018 } 5019 5020 /** 5021 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5022 * @wmi_handle: Pointer to wmi handle 5023 * @thermal_info: Thermal command information 5024 * 5025 * This function sends the thermal management command 5026 * to the firmware 5027 * 5028 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5029 */ 5030 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5031 struct thermal_cmd_params *thermal_info) 5032 { 5033 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5034 wmi_buf_t buf = NULL; 5035 QDF_STATUS status; 5036 uint32_t len = 0; 5037 5038 len = sizeof(*cmd); 5039 5040 buf = wmi_buf_alloc(wmi_handle, len); 5041 if (!buf) { 5042 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5043 return QDF_STATUS_E_FAILURE; 5044 } 5045 5046 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5047 5048 WMITLV_SET_HDR(&cmd->tlv_header, 5049 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5050 WMITLV_GET_STRUCT_TLVLEN 5051 (wmi_thermal_mgmt_cmd_fixed_param)); 5052 5053 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5054 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5055 cmd->enable = thermal_info->thermal_enable; 5056 5057 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 5058 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 5059 5060 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5061 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5062 WMI_THERMAL_MGMT_CMDID); 5063 if (QDF_IS_STATUS_ERROR(status)) { 5064 wmi_buf_free(buf); 5065 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 5066 } 5067 5068 return status; 5069 } 5070 5071 5072 /** 5073 * send_lro_config_cmd_tlv() - process the LRO config command 5074 * @wmi_handle: Pointer to WMI handle 5075 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5076 * 5077 * This function sends down the LRO configuration parameters to 5078 * the firmware to enable LRO, sets the TCP flags and sets the 5079 * seed values for the toeplitz hash generation 5080 * 5081 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5082 */ 5083 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5084 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5085 { 5086 wmi_lro_info_cmd_fixed_param *cmd; 5087 wmi_buf_t buf; 5088 QDF_STATUS status; 5089 5090 5091 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5092 if (!buf) { 5093 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5094 return QDF_STATUS_E_FAILURE; 5095 } 5096 5097 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5098 5099 WMITLV_SET_HDR(&cmd->tlv_header, 5100 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5101 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5102 5103 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5104 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5105 wmi_lro_cmd->tcp_flag); 5106 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5107 wmi_lro_cmd->tcp_flag_mask); 5108 cmd->toeplitz_hash_ipv4_0_3 = 5109 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5110 cmd->toeplitz_hash_ipv4_4_7 = 5111 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5112 cmd->toeplitz_hash_ipv4_8_11 = 5113 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5114 cmd->toeplitz_hash_ipv4_12_15 = 5115 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5116 cmd->toeplitz_hash_ipv4_16 = 5117 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5118 5119 cmd->toeplitz_hash_ipv6_0_3 = 5120 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5121 cmd->toeplitz_hash_ipv6_4_7 = 5122 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5123 cmd->toeplitz_hash_ipv6_8_11 = 5124 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5125 cmd->toeplitz_hash_ipv6_12_15 = 5126 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5127 cmd->toeplitz_hash_ipv6_16_19 = 5128 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5129 cmd->toeplitz_hash_ipv6_20_23 = 5130 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5131 cmd->toeplitz_hash_ipv6_24_27 = 5132 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5133 cmd->toeplitz_hash_ipv6_28_31 = 5134 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5135 cmd->toeplitz_hash_ipv6_32_35 = 5136 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5137 cmd->toeplitz_hash_ipv6_36_39 = 5138 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5139 cmd->toeplitz_hash_ipv6_40 = 5140 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5141 5142 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x", 5143 cmd->lro_enable, cmd->tcp_flag_u32); 5144 5145 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5146 status = wmi_unified_cmd_send(wmi_handle, buf, 5147 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5148 if (QDF_IS_STATUS_ERROR(status)) { 5149 wmi_buf_free(buf); 5150 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 5151 } 5152 5153 return status; 5154 } 5155 5156 /** 5157 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5158 * @wmi_handle: Pointer to wmi handle 5159 * @rate_report_params: Pointer to peer rate report parameters 5160 * 5161 * 5162 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5163 */ 5164 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5165 struct wmi_peer_rate_report_params *rate_report_params) 5166 { 5167 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5168 wmi_buf_t buf = NULL; 5169 QDF_STATUS status = 0; 5170 uint32_t len = 0; 5171 uint32_t i, j; 5172 5173 len = sizeof(*cmd); 5174 5175 buf = wmi_buf_alloc(wmi_handle, len); 5176 if (!buf) { 5177 WMI_LOGE("Failed to alloc buf to peer_set_condition cmd\n"); 5178 return QDF_STATUS_E_FAILURE; 5179 } 5180 5181 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5182 wmi_buf_data(buf); 5183 5184 WMITLV_SET_HDR( 5185 &cmd->tlv_header, 5186 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5187 WMITLV_GET_STRUCT_TLVLEN( 5188 wmi_peer_set_rate_report_condition_fixed_param)); 5189 5190 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5191 cmd->report_backoff_time = rate_report_params->backoff_time; 5192 cmd->report_timer_period = rate_report_params->timer_period; 5193 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5194 cmd->cond_per_phy[i].val_cond_flags = 5195 rate_report_params->report_per_phy[i].cond_flags; 5196 cmd->cond_per_phy[i].rate_delta.min_delta = 5197 rate_report_params->report_per_phy[i].delta.delta_min; 5198 cmd->cond_per_phy[i].rate_delta.percentage = 5199 rate_report_params->report_per_phy[i].delta.percent; 5200 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5201 cmd->cond_per_phy[i].rate_threshold[j] = 5202 rate_report_params->report_per_phy[i]. 5203 report_rate_threshold[j]; 5204 } 5205 } 5206 5207 WMI_LOGE("%s enable %d backoff_time %d period %d\n", __func__, 5208 cmd->enable_rate_report, 5209 cmd->report_backoff_time, cmd->report_timer_period); 5210 5211 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5212 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5213 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5214 if (QDF_IS_STATUS_ERROR(status)) { 5215 wmi_buf_free(buf); 5216 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 5217 __func__); 5218 } 5219 return status; 5220 } 5221 5222 /** 5223 * send_bcn_buf_ll_cmd_tlv() - prepare and send beacon buffer to fw for LL 5224 * @wmi_handle: wmi handle 5225 * @param: bcn ll cmd parameter 5226 * 5227 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5228 */ 5229 static QDF_STATUS send_bcn_buf_ll_cmd_tlv(wmi_unified_t wmi_handle, 5230 wmi_bcn_send_from_host_cmd_fixed_param *param) 5231 { 5232 wmi_bcn_send_from_host_cmd_fixed_param *cmd; 5233 wmi_buf_t wmi_buf; 5234 QDF_STATUS ret; 5235 5236 wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5237 if (!wmi_buf) { 5238 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5239 return QDF_STATUS_E_FAILURE; 5240 } 5241 5242 cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); 5243 WMITLV_SET_HDR(&cmd->tlv_header, 5244 WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, 5245 WMITLV_GET_STRUCT_TLVLEN 5246 (wmi_bcn_send_from_host_cmd_fixed_param)); 5247 cmd->vdev_id = param->vdev_id; 5248 cmd->data_len = param->data_len; 5249 cmd->frame_ctrl = param->frame_ctrl; 5250 cmd->frag_ptr = param->frag_ptr; 5251 cmd->dtim_flag = param->dtim_flag; 5252 5253 wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0); 5254 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd), 5255 WMI_PDEV_SEND_BCN_CMDID); 5256 5257 if (QDF_IS_STATUS_ERROR(ret)) { 5258 WMI_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); 5259 wmi_buf_free(wmi_buf); 5260 } 5261 5262 return ret; 5263 } 5264 5265 /** 5266 * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters 5267 * @wmi_handle: wmi handle 5268 * @vdev_id: vdev id 5269 * @max_retries: max retries 5270 * @retry_interval: retry interval 5271 * This function sets sta query related parameters in fw. 5272 * 5273 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5274 */ 5275 5276 static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle, 5277 uint8_t vdev_id, uint32_t max_retries, 5278 uint32_t retry_interval) 5279 { 5280 wmi_buf_t buf; 5281 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd; 5282 int len; 5283 5284 len = sizeof(*cmd); 5285 buf = wmi_buf_alloc(wmi_handle, len); 5286 if (!buf) { 5287 WMI_LOGE(FL("wmi_buf_alloc failed")); 5288 return QDF_STATUS_E_FAILURE; 5289 } 5290 5291 cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf); 5292 WMITLV_SET_HDR(&cmd->tlv_header, 5293 WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param, 5294 WMITLV_GET_STRUCT_TLVLEN 5295 (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param)); 5296 5297 5298 cmd->vdev_id = vdev_id; 5299 cmd->sa_query_max_retry_count = max_retries; 5300 cmd->sa_query_retry_interval = retry_interval; 5301 5302 WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"), 5303 vdev_id, retry_interval, max_retries); 5304 5305 wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0); 5306 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5307 WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) { 5308 WMI_LOGE(FL("Failed to offload STA SA Query")); 5309 wmi_buf_free(buf); 5310 return QDF_STATUS_E_FAILURE; 5311 } 5312 5313 WMI_LOGD(FL("Exit :")); 5314 return 0; 5315 } 5316 5317 /** 5318 * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters 5319 * @wmi_handle: wmi handle 5320 * @params: sta keep alive parameter 5321 * 5322 * This function sets keep alive related parameters in fw. 5323 * 5324 * Return: CDF status 5325 */ 5326 static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle, 5327 struct sta_params *params) 5328 { 5329 wmi_buf_t buf; 5330 WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; 5331 WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; 5332 uint8_t *buf_ptr; 5333 int len; 5334 QDF_STATUS ret; 5335 5336 WMI_LOGD("%s: Enter", __func__); 5337 5338 len = sizeof(*cmd) + sizeof(*arp_rsp); 5339 buf = wmi_buf_alloc(wmi_handle, len); 5340 if (!buf) { 5341 WMI_LOGE("wmi_buf_alloc failed"); 5342 return QDF_STATUS_E_FAILURE; 5343 } 5344 5345 cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); 5346 buf_ptr = (uint8_t *) cmd; 5347 WMITLV_SET_HDR(&cmd->tlv_header, 5348 WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, 5349 WMITLV_GET_STRUCT_TLVLEN 5350 (WMI_STA_KEEPALIVE_CMD_fixed_param)); 5351 cmd->interval = params->timeperiod; 5352 cmd->enable = (params->timeperiod) ? 1 : 0; 5353 cmd->vdev_id = params->vdev_id; 5354 WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id, 5355 params->timeperiod, params->method); 5356 arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd)); 5357 WMITLV_SET_HDR(&arp_rsp->tlv_header, 5358 WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, 5359 WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); 5360 5361 if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) || 5362 (params->method == 5363 WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) { 5364 if ((NULL == params->hostv4addr) || 5365 (NULL == params->destv4addr) || 5366 (NULL == params->destmac)) { 5367 WMI_LOGE("%s: received null pointer, hostv4addr:%pK " 5368 "destv4addr:%pK destmac:%pK ", __func__, 5369 params->hostv4addr, params->destv4addr, params->destmac); 5370 wmi_buf_free(buf); 5371 return QDF_STATUS_E_FAILURE; 5372 } 5373 cmd->method = params->method; 5374 qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr, 5375 WMI_IPV4_ADDR_LEN); 5376 qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr, 5377 WMI_IPV4_ADDR_LEN); 5378 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr); 5379 } else { 5380 cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; 5381 } 5382 5383 wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0); 5384 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5385 WMI_STA_KEEPALIVE_CMDID); 5386 if (QDF_IS_STATUS_ERROR(ret)) { 5387 WMI_LOGE("Failed to set KeepAlive"); 5388 wmi_buf_free(buf); 5389 } 5390 5391 WMI_LOGD("%s: Exit", __func__); 5392 return ret; 5393 } 5394 5395 /** 5396 * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params 5397 * @wmi_handle: wmi handle 5398 * @if_id: vdev id 5399 * @gtx_info: GTX config params 5400 * 5401 * This function set GTX related params in firmware. 5402 * 5403 * Return: QDF_STATUS_SUCCESS for success or error code 5404 */ 5405 static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id, 5406 struct wmi_gtx_config *gtx_info) 5407 { 5408 wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; 5409 wmi_buf_t buf; 5410 QDF_STATUS ret; 5411 int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); 5412 5413 buf = wmi_buf_alloc(wmi_handle, len); 5414 if (!buf) { 5415 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 5416 return QDF_STATUS_E_NOMEM; 5417 } 5418 cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf); 5419 WMITLV_SET_HDR(&cmd->tlv_header, 5420 WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, 5421 WMITLV_GET_STRUCT_TLVLEN 5422 (wmi_vdev_set_gtx_params_cmd_fixed_param)); 5423 cmd->vdev_id = if_id; 5424 5425 cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0]; 5426 cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1]; 5427 cmd->userGtxMask = gtx_info->gtx_usrcfg; 5428 cmd->gtxPERThreshold = gtx_info->gtx_threshold; 5429 cmd->gtxPERMargin = gtx_info->gtx_margin; 5430 cmd->gtxTPCstep = gtx_info->gtx_tpcstep; 5431 cmd->gtxTPCMin = gtx_info->gtx_tpcmin; 5432 cmd->gtxBWMask = gtx_info->gtx_bwmask; 5433 5434 WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ 5435 gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ 5436 gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], 5437 cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, 5438 cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); 5439 5440 wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0); 5441 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5442 WMI_VDEV_SET_GTX_PARAMS_CMDID); 5443 if (QDF_IS_STATUS_ERROR(ret)) { 5444 WMI_LOGE("Failed to set GTX PARAMS"); 5445 wmi_buf_free(buf); 5446 } 5447 return ret; 5448 } 5449 5450 /** 5451 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5452 * @wmi_handle: wmi handle 5453 * @vdev_id: vdev id. 5454 * @wmm_vparams: edca parameters 5455 * 5456 * This function updates EDCA parameters to the target 5457 * 5458 * Return: CDF Status 5459 */ 5460 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5461 uint8_t vdev_id, bool mu_edca_param, 5462 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5463 { 5464 uint8_t *buf_ptr; 5465 wmi_buf_t buf; 5466 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5467 wmi_wmm_vparams *wmm_param; 5468 struct wmi_host_wme_vparams *twmm_param; 5469 int len = sizeof(*cmd); 5470 int ac; 5471 5472 buf = wmi_buf_alloc(wmi_handle, len); 5473 5474 if (!buf) { 5475 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 5476 return QDF_STATUS_E_NOMEM; 5477 } 5478 5479 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5480 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5481 WMITLV_SET_HDR(&cmd->tlv_header, 5482 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5483 WMITLV_GET_STRUCT_TLVLEN 5484 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5485 cmd->vdev_id = vdev_id; 5486 cmd->wmm_param_type = mu_edca_param; 5487 5488 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5489 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5490 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5491 WMITLV_SET_HDR(&wmm_param->tlv_header, 5492 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5493 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5494 wmm_param->cwmin = twmm_param->cwmin; 5495 wmm_param->cwmax = twmm_param->cwmax; 5496 wmm_param->aifs = twmm_param->aifs; 5497 if (mu_edca_param) 5498 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5499 else 5500 wmm_param->txoplimit = twmm_param->txoplimit; 5501 wmm_param->acm = twmm_param->acm; 5502 wmm_param->no_ack = twmm_param->noackpolicy; 5503 } 5504 5505 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5506 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5507 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5508 goto fail; 5509 5510 return QDF_STATUS_SUCCESS; 5511 5512 fail: 5513 wmi_buf_free(buf); 5514 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 5515 return QDF_STATUS_E_FAILURE; 5516 } 5517 5518 /** 5519 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5520 * @wmi_handle: wmi handle 5521 * @vdev_id: vdev id 5522 * @probe_rsp_info: probe response info 5523 * 5524 * Return: QDF_STATUS_SUCCESS for success or error code 5525 */ 5526 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5527 uint8_t vdev_id, 5528 struct wmi_probe_resp_params *probe_rsp_info) 5529 { 5530 wmi_prb_tmpl_cmd_fixed_param *cmd; 5531 wmi_bcn_prb_info *bcn_prb_info; 5532 wmi_buf_t wmi_buf; 5533 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5534 uint8_t *buf_ptr; 5535 QDF_STATUS ret; 5536 5537 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 5538 5539 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5540 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5541 5542 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5543 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5544 tmpl_len_aligned; 5545 5546 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5547 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 5548 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5549 return QDF_STATUS_E_INVAL; 5550 } 5551 5552 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5553 if (!wmi_buf) { 5554 WMI_LOGE(FL("wmi_buf_alloc failed")); 5555 return QDF_STATUS_E_NOMEM; 5556 } 5557 5558 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5559 5560 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5561 WMITLV_SET_HDR(&cmd->tlv_header, 5562 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5563 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5564 cmd->vdev_id = vdev_id; 5565 cmd->buf_len = tmpl_len; 5566 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5567 5568 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5569 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5570 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5571 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5572 bcn_prb_info->caps = 0; 5573 bcn_prb_info->erp = 0; 5574 buf_ptr += sizeof(wmi_bcn_prb_info); 5575 5576 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5577 buf_ptr += WMI_TLV_HDR_SIZE; 5578 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5579 5580 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5581 ret = wmi_unified_cmd_send(wmi_handle, 5582 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5583 if (QDF_IS_STATUS_ERROR(ret)) { 5584 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 5585 wmi_buf_free(wmi_buf); 5586 } 5587 5588 return ret; 5589 } 5590 5591 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5592 #define WPI_IV_LEN 16 5593 5594 /** 5595 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5596 * 5597 * @dest_tx: destination address of tsc key counter 5598 * @src_tx: source address of tsc key counter 5599 * @dest_rx: destination address of rsc key counter 5600 * @src_rx: source address of rsc key counter 5601 * 5602 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5603 * 5604 * Return: None 5605 * 5606 */ 5607 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5608 uint8_t *dest_rx, uint8_t *src_rx) 5609 { 5610 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5611 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5612 } 5613 #else 5614 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5615 uint8_t *dest_rx, uint8_t *src_rx) 5616 { 5617 return; 5618 } 5619 #endif 5620 5621 /** 5622 * send_setup_install_key_cmd_tlv() - set key parameters 5623 * @wmi_handle: wmi handle 5624 * @key_params: key parameters 5625 * 5626 * This function fills structure from information 5627 * passed in key_params. 5628 * 5629 * Return: QDF_STATUS_SUCCESS - success 5630 * QDF_STATUS_E_FAILURE - failure 5631 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5632 */ 5633 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5634 struct set_key_params *key_params) 5635 { 5636 wmi_vdev_install_key_cmd_fixed_param *cmd; 5637 wmi_buf_t buf; 5638 uint8_t *buf_ptr; 5639 uint32_t len; 5640 uint8_t *key_data; 5641 QDF_STATUS status; 5642 5643 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5644 WMI_TLV_HDR_SIZE; 5645 5646 buf = wmi_buf_alloc(wmi_handle, len); 5647 if (!buf) { 5648 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 5649 return QDF_STATUS_E_NOMEM; 5650 } 5651 5652 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5653 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5654 WMITLV_SET_HDR(&cmd->tlv_header, 5655 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5656 WMITLV_GET_STRUCT_TLVLEN 5657 (wmi_vdev_install_key_cmd_fixed_param)); 5658 cmd->vdev_id = key_params->vdev_id; 5659 cmd->key_ix = key_params->key_idx; 5660 5661 5662 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5663 cmd->key_flags |= key_params->key_flags; 5664 cmd->key_cipher = key_params->key_cipher; 5665 if ((key_params->key_txmic_len) && 5666 (key_params->key_rxmic_len)) { 5667 cmd->key_txmic_len = key_params->key_txmic_len; 5668 cmd->key_rxmic_len = key_params->key_rxmic_len; 5669 } 5670 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5671 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5672 key_params->tx_iv, 5673 cmd->wpi_key_rsc_counter, 5674 key_params->rx_iv); 5675 #endif 5676 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5677 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5678 roundup(key_params->key_len, sizeof(uint32_t))); 5679 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5680 qdf_mem_copy((void *)key_data, 5681 (const void *)key_params->key_data, key_params->key_len); 5682 if (key_params->key_rsc_counter) 5683 qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, 5684 sizeof(wmi_key_seq_counter)); 5685 cmd->key_len = key_params->key_len; 5686 5687 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5688 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5689 WMI_VDEV_INSTALL_KEY_CMDID); 5690 if (QDF_IS_STATUS_ERROR(status)) 5691 wmi_buf_free(buf); 5692 5693 return status; 5694 } 5695 5696 /** 5697 * send_sar_limit_cmd_tlv() - send sar limit cmd to fw 5698 * @wmi_handle: wmi handle 5699 * @params: sar limit params 5700 * 5701 * Return: QDF_STATUS_SUCCESS for success or error code 5702 */ 5703 static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle, 5704 struct sar_limit_cmd_params *sar_limit_params) 5705 { 5706 wmi_buf_t buf; 5707 QDF_STATUS qdf_status; 5708 wmi_sar_limits_cmd_fixed_param *cmd; 5709 int i; 5710 uint8_t *buf_ptr; 5711 wmi_sar_limit_cmd_row *wmi_sar_rows_list; 5712 struct sar_limit_cmd_row *sar_rows_list; 5713 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 5714 5715 len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows; 5716 buf = wmi_buf_alloc(wmi_handle, len); 5717 if (!buf) { 5718 WMI_LOGE("Failed to allocate memory"); 5719 qdf_status = QDF_STATUS_E_NOMEM; 5720 goto end; 5721 } 5722 5723 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5724 cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr; 5725 WMITLV_SET_HDR(&cmd->tlv_header, 5726 WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param, 5727 WMITLV_GET_STRUCT_TLVLEN 5728 (wmi_sar_limits_cmd_fixed_param)); 5729 cmd->sar_enable = sar_limit_params->sar_enable; 5730 cmd->commit_limits = sar_limit_params->commit_limits; 5731 cmd->num_limit_rows = sar_limit_params->num_limit_rows; 5732 5733 WMI_LOGD("no of sar rows = %d, len = %d", 5734 sar_limit_params->num_limit_rows, len); 5735 buf_ptr += sizeof(*cmd); 5736 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5737 sizeof(wmi_sar_limit_cmd_row) * 5738 sar_limit_params->num_limit_rows); 5739 if (cmd->num_limit_rows == 0) 5740 goto send_sar_limits; 5741 5742 wmi_sar_rows_list = (wmi_sar_limit_cmd_row *) 5743 (buf_ptr + WMI_TLV_HDR_SIZE); 5744 sar_rows_list = sar_limit_params->sar_limit_row_list; 5745 5746 for (i = 0; i < sar_limit_params->num_limit_rows; i++) { 5747 WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header, 5748 WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row, 5749 WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row)); 5750 wmi_sar_rows_list->band_id = sar_rows_list->band_id; 5751 wmi_sar_rows_list->chain_id = sar_rows_list->chain_id; 5752 wmi_sar_rows_list->mod_id = sar_rows_list->mod_id; 5753 wmi_sar_rows_list->limit_value = sar_rows_list->limit_value; 5754 wmi_sar_rows_list->validity_bitmap = 5755 sar_rows_list->validity_bitmap; 5756 WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d", 5757 i, wmi_sar_rows_list->band_id, 5758 wmi_sar_rows_list->chain_id, 5759 wmi_sar_rows_list->mod_id, 5760 wmi_sar_rows_list->limit_value, 5761 wmi_sar_rows_list->validity_bitmap); 5762 sar_rows_list++; 5763 wmi_sar_rows_list++; 5764 } 5765 send_sar_limits: 5766 wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0); 5767 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 5768 WMI_SAR_LIMITS_CMDID); 5769 5770 if (QDF_IS_STATUS_ERROR(qdf_status)) { 5771 WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID"); 5772 wmi_buf_free(buf); 5773 } 5774 5775 end: 5776 return qdf_status; 5777 } 5778 5779 static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle) 5780 { 5781 wmi_sar_get_limits_cmd_fixed_param *cmd; 5782 wmi_buf_t wmi_buf; 5783 uint32_t len; 5784 QDF_STATUS status; 5785 5786 WMI_LOGD(FL("Enter")); 5787 5788 len = sizeof(*cmd); 5789 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5790 if (!wmi_buf) { 5791 WMI_LOGP(FL("failed to allocate memory for msg")); 5792 return QDF_STATUS_E_NOMEM; 5793 } 5794 5795 cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf); 5796 5797 WMITLV_SET_HDR(&cmd->tlv_header, 5798 WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param, 5799 WMITLV_GET_STRUCT_TLVLEN 5800 (wmi_sar_get_limits_cmd_fixed_param)); 5801 5802 cmd->reserved = 0; 5803 5804 wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0); 5805 status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5806 WMI_SAR_GET_LIMITS_CMDID); 5807 if (QDF_IS_STATUS_ERROR(status)) { 5808 WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status); 5809 wmi_buf_free(wmi_buf); 5810 } 5811 5812 WMI_LOGD(FL("Exit")); 5813 5814 return status; 5815 } 5816 5817 /** 5818 * wmi_sar2_result_string() - return string conversion of sar2 result 5819 * @result: sar2 result value 5820 * 5821 * This utility function helps log string conversion of sar2 result. 5822 * 5823 * Return: string conversion of sar 2 result, if match found; 5824 * "Unknown response" otherwise. 5825 */ 5826 static const char *wmi_sar2_result_string(uint32_t result) 5827 { 5828 switch (result) { 5829 CASE_RETURN_STRING(WMI_SAR2_SUCCESS); 5830 CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX); 5831 CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX); 5832 CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR); 5833 CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE); 5834 default: 5835 return "Unknown response"; 5836 } 5837 } 5838 5839 /** 5840 * extract_sar2_result_event_tlv() - process sar response event from FW. 5841 * @handle: wma handle 5842 * @event: event buffer 5843 * @len: buffer length 5844 * 5845 * Return: 0 for success or error code 5846 */ 5847 static QDF_STATUS extract_sar2_result_event_tlv(void *handle, 5848 uint8_t *event, 5849 uint32_t len) 5850 { 5851 wmi_sar2_result_event_fixed_param *sar2_fixed_param; 5852 5853 WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf = 5854 (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event; 5855 5856 if (!param_buf) { 5857 WMI_LOGI("Invalid sar2 result event buffer"); 5858 return QDF_STATUS_E_INVAL; 5859 } 5860 5861 sar2_fixed_param = param_buf->fixed_param; 5862 if (!sar2_fixed_param) { 5863 WMI_LOGI("Invalid sar2 result event fixed param buffer"); 5864 return QDF_STATUS_E_INVAL; 5865 } 5866 5867 WMI_LOGI("SAR2 result: %s", 5868 wmi_sar2_result_string(sar2_fixed_param->result)); 5869 5870 return QDF_STATUS_SUCCESS; 5871 } 5872 5873 static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle, 5874 uint8_t *evt_buf, 5875 struct sar_limit_event *event) 5876 { 5877 wmi_sar_get_limits_event_fixed_param *fixed_param; 5878 WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf; 5879 wmi_sar_get_limit_event_row *row_in; 5880 struct sar_limit_event_row *row_out; 5881 uint32_t row; 5882 5883 if (!evt_buf) { 5884 WMI_LOGE(FL("input event is NULL")); 5885 return QDF_STATUS_E_INVAL; 5886 } 5887 if (!event) { 5888 WMI_LOGE(FL("output event is NULL")); 5889 return QDF_STATUS_E_INVAL; 5890 } 5891 5892 param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf; 5893 5894 fixed_param = param_buf->fixed_param; 5895 if (!fixed_param) { 5896 WMI_LOGE(FL("Invalid fixed param")); 5897 return QDF_STATUS_E_INVAL; 5898 } 5899 5900 event->sar_enable = fixed_param->sar_enable; 5901 event->num_limit_rows = fixed_param->num_limit_rows; 5902 5903 if (event->num_limit_rows > param_buf->num_sar_get_limits) { 5904 WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"), 5905 event->num_limit_rows, param_buf->num_sar_get_limits); 5906 return QDF_STATUS_E_INVAL; 5907 } 5908 5909 if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { 5910 QDF_ASSERT(0); 5911 WMI_LOGE(FL("Num rows %d exceeds max of %d"), 5912 event->num_limit_rows, 5913 MAX_SAR_LIMIT_ROWS_SUPPORTED); 5914 event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED; 5915 } 5916 5917 row_in = param_buf->sar_get_limits; 5918 row_out = &event->sar_limit_row[0]; 5919 for (row = 0; row < event->num_limit_rows; row++) { 5920 row_out->band_id = row_in->band_id; 5921 row_out->chain_id = row_in->chain_id; 5922 row_out->mod_id = row_in->mod_id; 5923 row_out->limit_value = row_in->limit_value; 5924 row_out++; 5925 row_in++; 5926 } 5927 5928 return QDF_STATUS_SUCCESS; 5929 } 5930 5931 #ifdef WLAN_FEATURE_DISA 5932 /** 5933 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 5934 * @wmi_handle: wmi handle 5935 * @params: encrypt/decrypt params 5936 * 5937 * Return: QDF_STATUS_SUCCESS for success or error code 5938 */ 5939 static 5940 QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 5941 struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params) 5942 { 5943 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 5944 wmi_buf_t wmi_buf; 5945 uint8_t *buf_ptr; 5946 QDF_STATUS ret; 5947 uint32_t len; 5948 5949 WMI_LOGD(FL("Send encrypt decrypt cmd")); 5950 5951 len = sizeof(*cmd) + 5952 roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) + 5953 WMI_TLV_HDR_SIZE; 5954 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5955 if (!wmi_buf) { 5956 WMI_LOGP("%s: failed to allocate memory for encrypt/decrypt msg", 5957 __func__); 5958 return QDF_STATUS_E_NOMEM; 5959 } 5960 5961 buf_ptr = wmi_buf_data(wmi_buf); 5962 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 5963 5964 WMITLV_SET_HDR(&cmd->tlv_header, 5965 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 5966 WMITLV_GET_STRUCT_TLVLEN( 5967 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 5968 5969 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 5970 cmd->key_flag = encrypt_decrypt_params->key_flag; 5971 cmd->key_idx = encrypt_decrypt_params->key_idx; 5972 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 5973 cmd->key_len = encrypt_decrypt_params->key_len; 5974 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 5975 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 5976 5977 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 5978 encrypt_decrypt_params->key_len); 5979 5980 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 5981 MAX_MAC_HEADER_LEN); 5982 5983 cmd->data_len = encrypt_decrypt_params->data_len; 5984 5985 if (cmd->data_len) { 5986 buf_ptr += sizeof(*cmd); 5987 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5988 roundup(encrypt_decrypt_params->data_len, 5989 sizeof(uint32_t))); 5990 buf_ptr += WMI_TLV_HDR_SIZE; 5991 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 5992 encrypt_decrypt_params->data_len); 5993 } 5994 5995 /* This conversion is to facilitate data to FW in little endian */ 5996 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 5997 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 5998 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 5999 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 6000 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 6001 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 6002 6003 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 6004 ret = wmi_unified_cmd_send(wmi_handle, 6005 wmi_buf, len, 6006 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 6007 if (QDF_IS_STATUS_ERROR(ret)) { 6008 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 6009 wmi_buf_free(wmi_buf); 6010 } 6011 6012 return ret; 6013 } 6014 6015 /** 6016 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 6017 * params from event 6018 * @wmi_handle: wmi handle 6019 * @evt_buf: pointer to event buffer 6020 * @resp: Pointer to hold resp parameters 6021 * 6022 * Return: QDF_STATUS_SUCCESS for success or error code 6023 */ 6024 static 6025 QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 6026 void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp) 6027 { 6028 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 6029 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 6030 6031 param_buf = evt_buf; 6032 if (!param_buf) { 6033 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 6034 return QDF_STATUS_E_INVAL; 6035 } 6036 6037 data_event = param_buf->fixed_param; 6038 6039 resp->vdev_id = data_event->vdev_id; 6040 resp->status = data_event->status; 6041 6042 if ((data_event->data_length > param_buf->num_enc80211_frame) || 6043 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE - 6044 sizeof(*data_event))) { 6045 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 6046 data_event->data_length, 6047 param_buf->num_enc80211_frame); 6048 return QDF_STATUS_E_INVAL; 6049 } 6050 6051 resp->data_len = data_event->data_length; 6052 6053 if (resp->data_len) 6054 resp->data = (uint8_t *)param_buf->enc80211_frame; 6055 6056 return QDF_STATUS_SUCCESS; 6057 } 6058 #endif 6059 6060 /** 6061 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 6062 * @wmi_handle: wmi handle 6063 * @vdev_id: vdev id 6064 * @p2p_ie: p2p IE 6065 * 6066 * Return: QDF_STATUS_SUCCESS for success or error code 6067 */ 6068 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 6069 uint32_t vdev_id, uint8_t *p2p_ie) 6070 { 6071 QDF_STATUS ret; 6072 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 6073 wmi_buf_t wmi_buf; 6074 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 6075 uint8_t *buf_ptr; 6076 6077 ie_len = (uint32_t) (p2p_ie[1] + 2); 6078 6079 /* More than one P2P IE may be included in a single frame. 6080 If multiple P2P IEs are present, the complete P2P attribute 6081 data consists of the concatenation of the P2P Attribute 6082 fields of the P2P IEs. The P2P Attributes field of each 6083 P2P IE may be any length up to the maximum (251 octets). 6084 In this case host sends one P2P IE to firmware so the length 6085 should not exceed more than 251 bytes 6086 */ 6087 if (ie_len > 251) { 6088 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 6089 return QDF_STATUS_E_INVAL; 6090 } 6091 6092 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 6093 6094 wmi_buf_len = 6095 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 6096 WMI_TLV_HDR_SIZE; 6097 6098 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6099 if (!wmi_buf) { 6100 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6101 return QDF_STATUS_E_NOMEM; 6102 } 6103 6104 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6105 6106 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 6107 WMITLV_SET_HDR(&cmd->tlv_header, 6108 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6109 WMITLV_GET_STRUCT_TLVLEN 6110 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6111 cmd->vdev_id = vdev_id; 6112 cmd->ie_buf_len = ie_len; 6113 6114 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6115 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6116 buf_ptr += WMI_TLV_HDR_SIZE; 6117 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6118 6119 WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 6120 6121 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6122 ret = wmi_unified_cmd_send(wmi_handle, 6123 wmi_buf, wmi_buf_len, 6124 WMI_P2P_GO_SET_BEACON_IE); 6125 if (QDF_IS_STATUS_ERROR(ret)) { 6126 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 6127 wmi_buf_free(wmi_buf); 6128 } 6129 6130 WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 6131 return ret; 6132 } 6133 6134 /** 6135 * send_set_gateway_params_cmd_tlv() - set gateway parameters 6136 * @wmi_handle: wmi handle 6137 * @req: gateway parameter update request structure 6138 * 6139 * This function reads the incoming @req and fill in the destination 6140 * WMI structure and sends down the gateway configs down to the firmware 6141 * 6142 * Return: QDF_STATUS 6143 */ 6144 static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle, 6145 struct gateway_update_req_param *req) 6146 { 6147 wmi_roam_subnet_change_config_fixed_param *cmd; 6148 wmi_buf_t buf; 6149 QDF_STATUS ret; 6150 int len = sizeof(*cmd); 6151 6152 buf = wmi_buf_alloc(wmi_handle, len); 6153 if (!buf) { 6154 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6155 return QDF_STATUS_E_NOMEM; 6156 } 6157 6158 cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf); 6159 WMITLV_SET_HDR(&cmd->tlv_header, 6160 WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, 6161 WMITLV_GET_STRUCT_TLVLEN( 6162 wmi_roam_subnet_change_config_fixed_param)); 6163 6164 cmd->vdev_id = req->session_id; 6165 qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr, 6166 QDF_IPV4_ADDR_SIZE); 6167 qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr, 6168 QDF_IPV6_ADDR_SIZE); 6169 WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes, 6170 &cmd->inet_gw_mac_addr); 6171 cmd->max_retries = req->max_retries; 6172 cmd->timeout = req->timeout; 6173 cmd->num_skip_subnet_change_detection_bssid_list = 0; 6174 cmd->flag = 0; 6175 if (req->ipv4_addr_type) 6176 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag); 6177 6178 if (req->ipv6_addr_type) 6179 WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag); 6180 6181 wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0); 6182 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6183 WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); 6184 if (QDF_IS_STATUS_ERROR(ret)) { 6185 WMI_LOGE("Failed to send gw config parameter to fw, ret: %d", 6186 ret); 6187 wmi_buf_free(buf); 6188 } 6189 6190 return ret; 6191 } 6192 6193 /** 6194 * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring 6195 * @wmi_handle: wmi handle 6196 * @req: rssi monitoring request structure 6197 * 6198 * This function reads the incoming @req and fill in the destination 6199 * WMI structure and send down the rssi monitoring configs down to the firmware 6200 * 6201 * Return: 0 on success; error number otherwise 6202 */ 6203 static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle, 6204 struct rssi_monitor_param *req) 6205 { 6206 wmi_rssi_breach_monitor_config_fixed_param *cmd; 6207 wmi_buf_t buf; 6208 QDF_STATUS ret; 6209 uint32_t len = sizeof(*cmd); 6210 6211 buf = wmi_buf_alloc(wmi_handle, len); 6212 if (!buf) { 6213 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6214 return QDF_STATUS_E_NOMEM; 6215 } 6216 6217 cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf); 6218 WMITLV_SET_HDR(&cmd->tlv_header, 6219 WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, 6220 WMITLV_GET_STRUCT_TLVLEN( 6221 wmi_rssi_breach_monitor_config_fixed_param)); 6222 6223 cmd->vdev_id = req->session_id; 6224 cmd->request_id = req->request_id; 6225 cmd->lo_rssi_reenable_hysteresis = 0; 6226 cmd->hi_rssi_reenable_histeresis = 0; 6227 cmd->min_report_interval = 0; 6228 cmd->max_num_report = 1; 6229 if (req->control) { 6230 /* enable one threshold for each min/max */ 6231 cmd->enabled_bitmap = 0x09; 6232 cmd->low_rssi_breach_threshold[0] = req->min_rssi; 6233 cmd->hi_rssi_breach_threshold[0] = req->max_rssi; 6234 } else { 6235 cmd->enabled_bitmap = 0; 6236 cmd->low_rssi_breach_threshold[0] = 0; 6237 cmd->hi_rssi_breach_threshold[0] = 0; 6238 } 6239 6240 wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0); 6241 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6242 WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); 6243 if (QDF_IS_STATUS_ERROR(ret)) { 6244 WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID"); 6245 wmi_buf_free(buf); 6246 } 6247 6248 WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW"); 6249 6250 return ret; 6251 } 6252 6253 /** 6254 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6255 * @wmi_handle: wmi handle 6256 * @psetoui: OUI parameters 6257 * 6258 * set scan probe OUI parameters in firmware 6259 * 6260 * Return: CDF status 6261 */ 6262 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6263 struct scan_mac_oui *psetoui) 6264 { 6265 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6266 wmi_buf_t wmi_buf; 6267 uint32_t len; 6268 uint8_t *buf_ptr; 6269 uint32_t *oui_buf; 6270 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 6271 6272 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6273 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 6274 6275 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6276 if (!wmi_buf) { 6277 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 6278 return QDF_STATUS_E_NOMEM; 6279 } 6280 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6281 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6282 WMITLV_SET_HDR(&cmd->tlv_header, 6283 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6284 WMITLV_GET_STRUCT_TLVLEN 6285 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6286 6287 oui_buf = &cmd->prob_req_oui; 6288 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6289 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6290 | psetoui->oui[2]; 6291 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 6292 cmd->prob_req_oui); 6293 6294 cmd->vdev_id = psetoui->vdev_id; 6295 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6296 if (psetoui->enb_probe_req_sno_randomization) 6297 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6298 6299 if (ie_whitelist->white_list) { 6300 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 6301 &cmd->num_vendor_oui, 6302 ie_whitelist); 6303 cmd->flags |= 6304 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6305 } 6306 6307 buf_ptr += sizeof(*cmd); 6308 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6309 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6310 buf_ptr += WMI_TLV_HDR_SIZE; 6311 6312 if (cmd->num_vendor_oui != 0) { 6313 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6314 ie_whitelist->voui); 6315 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6316 } 6317 6318 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6319 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6320 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6321 WMI_LOGE("%s: failed to send command", __func__); 6322 wmi_buf_free(wmi_buf); 6323 return QDF_STATUS_E_FAILURE; 6324 } 6325 return QDF_STATUS_SUCCESS; 6326 } 6327 6328 #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 6329 /** 6330 * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command 6331 * @wmi_handle: wmi handle 6332 * @roam_req: Roam scan offload params 6333 * @buf_ptr: command buffer to send 6334 * @fils_tlv_len: fils tlv length 6335 * 6336 * Return: Updated buffer pointer 6337 */ 6338 static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6339 struct roam_offload_scan_params *roam_req, 6340 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6341 { 6342 wmi_roam_fils_offload_tlv_param *fils_tlv; 6343 wmi_erp_info *erp_info; 6344 struct roam_fils_params *roam_fils_params; 6345 6346 if (!roam_req->add_fils_tlv) 6347 return buf_ptr; 6348 6349 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6350 sizeof(*fils_tlv)); 6351 buf_ptr += WMI_TLV_HDR_SIZE; 6352 6353 fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; 6354 WMITLV_SET_HDR(&fils_tlv->tlv_header, 6355 WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, 6356 WMITLV_GET_STRUCT_TLVLEN 6357 (wmi_roam_fils_offload_tlv_param)); 6358 6359 roam_fils_params = &roam_req->roam_fils_params; 6360 erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); 6361 6362 erp_info->username_length = roam_fils_params->username_length; 6363 qdf_mem_copy(erp_info->username, roam_fils_params->username, 6364 erp_info->username_length); 6365 6366 erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; 6367 6368 erp_info->rRk_length = roam_fils_params->rrk_length; 6369 qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, 6370 erp_info->rRk_length); 6371 6372 erp_info->rIk_length = roam_fils_params->rik_length; 6373 qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, 6374 erp_info->rIk_length); 6375 6376 erp_info->realm_len = roam_fils_params->realm_len; 6377 qdf_mem_copy(erp_info->realm, roam_fils_params->realm, 6378 erp_info->realm_len); 6379 6380 buf_ptr += sizeof(*fils_tlv); 6381 return buf_ptr; 6382 } 6383 #else 6384 static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, 6385 struct roam_offload_scan_params *roam_req, 6386 uint8_t *buf_ptr, uint32_t fils_tlv_len) 6387 { 6388 return buf_ptr; 6389 } 6390 #endif 6391 /** 6392 * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw 6393 * @wmi_handle: wmi handle 6394 * @scan_cmd_fp: start scan command ptr 6395 * @roam_req: roam request param 6396 * 6397 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback 6398 * of WMI_ROAM_SCAN_MODE. 6399 * 6400 * Return: QDF status 6401 */ 6402 static QDF_STATUS send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, 6403 wmi_start_scan_cmd_fixed_param * 6404 scan_cmd_fp, 6405 struct roam_offload_scan_params *roam_req) 6406 { 6407 wmi_buf_t buf = NULL; 6408 QDF_STATUS status; 6409 int len; 6410 uint8_t *buf_ptr; 6411 wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; 6412 6413 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6414 int auth_mode = roam_req->auth_mode; 6415 roam_offload_param *req_offload_params = 6416 &roam_req->roam_offload_params; 6417 wmi_roam_offload_tlv_param *roam_offload_params; 6418 wmi_roam_11i_offload_tlv_param *roam_offload_11i; 6419 wmi_roam_11r_offload_tlv_param *roam_offload_11r; 6420 wmi_roam_ese_offload_tlv_param *roam_offload_ese; 6421 wmi_tlv_buf_len_param *assoc_ies; 6422 uint32_t fils_tlv_len = 0; 6423 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6424 /* Need to create a buf with roam_scan command at 6425 * front and piggyback with scan command */ 6426 len = sizeof(wmi_roam_scan_mode_fixed_param) + 6427 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6428 (2 * WMI_TLV_HDR_SIZE) + 6429 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6430 sizeof(wmi_start_scan_cmd_fixed_param); 6431 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6432 WMI_LOGD("auth_mode = %d", auth_mode); 6433 if (roam_req->is_roam_req_valid && 6434 roam_req->roam_offload_enabled) { 6435 len += sizeof(wmi_roam_offload_tlv_param); 6436 len += WMI_TLV_HDR_SIZE; 6437 if ((auth_mode != WMI_AUTH_NONE) && 6438 ((auth_mode != WMI_AUTH_OPEN) || 6439 (auth_mode == WMI_AUTH_OPEN && 6440 roam_req->mdid.mdie_present && 6441 roam_req->is_11r_assoc) || 6442 roam_req->is_ese_assoc)) { 6443 len += WMI_TLV_HDR_SIZE; 6444 if (roam_req->is_ese_assoc) 6445 len += 6446 sizeof(wmi_roam_ese_offload_tlv_param); 6447 else if (auth_mode == WMI_AUTH_FT_RSNA || 6448 auth_mode == WMI_AUTH_FT_RSNA_PSK || 6449 (auth_mode == WMI_AUTH_OPEN && 6450 roam_req->mdid.mdie_present && 6451 roam_req->is_11r_assoc)) 6452 len += 6453 sizeof(wmi_roam_11r_offload_tlv_param); 6454 else 6455 len += 6456 sizeof(wmi_roam_11i_offload_tlv_param); 6457 } else { 6458 len += WMI_TLV_HDR_SIZE; 6459 } 6460 6461 len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE) 6462 + roundup(roam_req->assoc_ie_length, 6463 sizeof(uint32_t))); 6464 6465 if (roam_req->add_fils_tlv) { 6466 fils_tlv_len = sizeof( 6467 wmi_roam_fils_offload_tlv_param); 6468 len += WMI_TLV_HDR_SIZE + fils_tlv_len; 6469 } 6470 } else { 6471 if (roam_req->is_roam_req_valid) 6472 WMI_LOGD("%s : roam offload = %d", 6473 __func__, roam_req->roam_offload_enabled); 6474 else 6475 WMI_LOGD("%s : roam_req is NULL", __func__); 6476 len += (4 * WMI_TLV_HDR_SIZE); 6477 } 6478 if (roam_req->is_roam_req_valid && 6479 roam_req->roam_offload_enabled) { 6480 roam_req->mode = roam_req->mode | 6481 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; 6482 } 6483 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6484 6485 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE 6486 |WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) 6487 len = sizeof(wmi_roam_scan_mode_fixed_param); 6488 6489 buf = wmi_buf_alloc(wmi_handle, len); 6490 if (!buf) { 6491 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6492 return QDF_STATUS_E_NOMEM; 6493 } 6494 6495 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6496 roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; 6497 WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, 6498 WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, 6499 WMITLV_GET_STRUCT_TLVLEN 6500 (wmi_roam_scan_mode_fixed_param)); 6501 6502 roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = 6503 roam_req->roam_trigger_reason_bitmask; 6504 roam_scan_mode_fp->min_delay_btw_scans = 6505 WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans); 6506 roam_scan_mode_fp->roam_scan_mode = roam_req->mode; 6507 roam_scan_mode_fp->vdev_id = roam_req->vdev_id; 6508 if (roam_req->mode == (WMI_ROAM_SCAN_MODE_NONE | 6509 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { 6510 roam_scan_mode_fp->flags |= 6511 WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; 6512 goto send_roam_scan_mode_cmd; 6513 } 6514 6515 /* Fill in scan parameters suitable for roaming scan */ 6516 buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); 6517 6518 qdf_mem_copy(buf_ptr, scan_cmd_fp, 6519 sizeof(wmi_start_scan_cmd_fixed_param)); 6520 /* Ensure there is no additional IEs */ 6521 scan_cmd_fp->ie_len = 0; 6522 WMITLV_SET_HDR(buf_ptr, 6523 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 6524 WMITLV_GET_STRUCT_TLVLEN 6525 (wmi_start_scan_cmd_fixed_param)); 6526 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 6527 buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); 6528 if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) { 6529 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6530 sizeof(wmi_roam_offload_tlv_param)); 6531 buf_ptr += WMI_TLV_HDR_SIZE; 6532 roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; 6533 WMITLV_SET_HDR(buf_ptr, 6534 WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, 6535 WMITLV_GET_STRUCT_TLVLEN 6536 (wmi_roam_offload_tlv_param)); 6537 roam_offload_params->prefer_5g = roam_req->prefer_5ghz; 6538 roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap; 6539 roam_offload_params->select_5g_margin = 6540 roam_req->select_5ghz_margin; 6541 roam_offload_params->handoff_delay_for_rx = 6542 req_offload_params->ho_delay_for_rx; 6543 roam_offload_params->max_mlme_sw_retries = 6544 req_offload_params->roam_preauth_retry_count; 6545 roam_offload_params->no_ack_timeout = 6546 req_offload_params->roam_preauth_no_ack_timeout; 6547 roam_offload_params->reassoc_failure_timeout = 6548 roam_req->reassoc_failure_timeout; 6549 6550 /* Fill the capabilities */ 6551 roam_offload_params->capability = 6552 req_offload_params->capability; 6553 roam_offload_params->ht_caps_info = 6554 req_offload_params->ht_caps_info; 6555 roam_offload_params->ampdu_param = 6556 req_offload_params->ampdu_param; 6557 roam_offload_params->ht_ext_cap = 6558 req_offload_params->ht_ext_cap; 6559 roam_offload_params->ht_txbf = req_offload_params->ht_txbf; 6560 roam_offload_params->asel_cap = req_offload_params->asel_cap; 6561 roam_offload_params->qos_caps = req_offload_params->qos_caps; 6562 roam_offload_params->qos_enabled = 6563 req_offload_params->qos_enabled; 6564 roam_offload_params->wmm_caps = req_offload_params->wmm_caps; 6565 qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, 6566 (uint8_t *)req_offload_params->mcsset, 6567 ROAM_OFFLOAD_NUM_MCS_SET); 6568 6569 buf_ptr += sizeof(wmi_roam_offload_tlv_param); 6570 /* The TLV's are in the order of 11i, 11R, ESE. Hence, 6571 * they are filled in the same order.Depending on the 6572 * authentication type, the other mode TLV's are nullified 6573 * and only headers are filled.*/ 6574 if ((auth_mode != WMI_AUTH_NONE) && 6575 ((auth_mode != WMI_AUTH_OPEN) || 6576 (auth_mode == WMI_AUTH_OPEN 6577 && roam_req->mdid.mdie_present && 6578 roam_req->is_11r_assoc) || 6579 roam_req->is_ese_assoc)) { 6580 if (roam_req->is_ese_assoc) { 6581 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6582 WMITLV_GET_STRUCT_TLVLEN(0)); 6583 buf_ptr += WMI_TLV_HDR_SIZE; 6584 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6585 WMITLV_GET_STRUCT_TLVLEN(0)); 6586 buf_ptr += WMI_TLV_HDR_SIZE; 6587 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6588 sizeof(wmi_roam_ese_offload_tlv_param)); 6589 buf_ptr += WMI_TLV_HDR_SIZE; 6590 roam_offload_ese = 6591 (wmi_roam_ese_offload_tlv_param *) buf_ptr; 6592 qdf_mem_copy(roam_offload_ese->krk, 6593 roam_req->krk, 6594 sizeof(roam_req->krk)); 6595 qdf_mem_copy(roam_offload_ese->btk, 6596 roam_req->btk, 6597 sizeof(roam_req->btk)); 6598 WMITLV_SET_HDR(&roam_offload_ese->tlv_header, 6599 WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, 6600 WMITLV_GET_STRUCT_TLVLEN 6601 (wmi_roam_ese_offload_tlv_param)); 6602 buf_ptr += 6603 sizeof(wmi_roam_ese_offload_tlv_param); 6604 } else if (auth_mode == WMI_AUTH_FT_RSNA 6605 || auth_mode == WMI_AUTH_FT_RSNA_PSK 6606 || (auth_mode == WMI_AUTH_OPEN 6607 && roam_req->mdid.mdie_present && 6608 roam_req->is_11r_assoc)) { 6609 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6610 0); 6611 buf_ptr += WMI_TLV_HDR_SIZE; 6612 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6613 sizeof(wmi_roam_11r_offload_tlv_param)); 6614 buf_ptr += WMI_TLV_HDR_SIZE; 6615 roam_offload_11r = 6616 (wmi_roam_11r_offload_tlv_param *) buf_ptr; 6617 roam_offload_11r->r0kh_id_len = 6618 roam_req->rokh_id_length; 6619 qdf_mem_copy(roam_offload_11r->r0kh_id, 6620 roam_req->rokh_id, 6621 roam_offload_11r->r0kh_id_len); 6622 qdf_mem_copy(roam_offload_11r->psk_msk, 6623 roam_req->psk_pmk, 6624 sizeof(roam_req->psk_pmk)); 6625 roam_offload_11r->psk_msk_len = 6626 roam_req->pmk_len; 6627 roam_offload_11r->mdie_present = 6628 roam_req->mdid.mdie_present; 6629 roam_offload_11r->mdid = 6630 roam_req->mdid.mobility_domain; 6631 if (auth_mode == WMI_AUTH_OPEN) { 6632 /* If FT-Open ensure pmk length 6633 and r0khid len are zero */ 6634 roam_offload_11r->r0kh_id_len = 0; 6635 roam_offload_11r->psk_msk_len = 0; 6636 } 6637 WMITLV_SET_HDR(&roam_offload_11r->tlv_header, 6638 WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, 6639 WMITLV_GET_STRUCT_TLVLEN 6640 (wmi_roam_11r_offload_tlv_param)); 6641 buf_ptr += 6642 sizeof(wmi_roam_11r_offload_tlv_param); 6643 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6644 WMITLV_GET_STRUCT_TLVLEN(0)); 6645 buf_ptr += WMI_TLV_HDR_SIZE; 6646 WMI_LOGD("psk_msk_len = %d", 6647 roam_offload_11r->psk_msk_len); 6648 if (roam_offload_11r->psk_msk_len) 6649 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6650 QDF_TRACE_LEVEL_DEBUG, 6651 roam_offload_11r->psk_msk, 6652 roam_offload_11r->psk_msk_len); 6653 } else { 6654 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6655 sizeof(wmi_roam_11i_offload_tlv_param)); 6656 buf_ptr += WMI_TLV_HDR_SIZE; 6657 roam_offload_11i = 6658 (wmi_roam_11i_offload_tlv_param *) buf_ptr; 6659 6660 if (roam_req->roam_key_mgmt_offload_enabled && 6661 roam_req->fw_okc) { 6662 WMI_SET_ROAM_OFFLOAD_OKC_ENABLED 6663 (roam_offload_11i->flags); 6664 WMI_LOGI("LFR3:OKC enabled"); 6665 } else { 6666 WMI_SET_ROAM_OFFLOAD_OKC_DISABLED 6667 (roam_offload_11i->flags); 6668 WMI_LOGI("LFR3:OKC disabled"); 6669 } 6670 if (roam_req->roam_key_mgmt_offload_enabled && 6671 roam_req->fw_pmksa_cache) { 6672 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED 6673 (roam_offload_11i->flags); 6674 WMI_LOGI("LFR3:PMKSA caching enabled"); 6675 } else { 6676 WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED 6677 (roam_offload_11i->flags); 6678 WMI_LOGI("LFR3:PMKSA caching disabled"); 6679 } 6680 6681 qdf_mem_copy(roam_offload_11i->pmk, 6682 roam_req->psk_pmk, 6683 sizeof(roam_req->psk_pmk)); 6684 roam_offload_11i->pmk_len = roam_req->pmk_len; 6685 WMITLV_SET_HDR(&roam_offload_11i->tlv_header, 6686 WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, 6687 WMITLV_GET_STRUCT_TLVLEN 6688 (wmi_roam_11i_offload_tlv_param)); 6689 buf_ptr += 6690 sizeof(wmi_roam_11i_offload_tlv_param); 6691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6692 0); 6693 buf_ptr += WMI_TLV_HDR_SIZE; 6694 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6695 0); 6696 buf_ptr += WMI_TLV_HDR_SIZE; 6697 WMI_LOGD("pmk_len = %d", 6698 roam_offload_11i->pmk_len); 6699 if (roam_offload_11i->pmk_len) 6700 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, 6701 QDF_TRACE_LEVEL_DEBUG, 6702 roam_offload_11i->pmk, 6703 roam_offload_11i->pmk_len); 6704 } 6705 } else { 6706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6707 WMITLV_GET_STRUCT_TLVLEN(0)); 6708 buf_ptr += WMI_TLV_HDR_SIZE; 6709 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6710 WMITLV_GET_STRUCT_TLVLEN(0)); 6711 buf_ptr += WMI_TLV_HDR_SIZE; 6712 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6713 WMITLV_GET_STRUCT_TLVLEN(0)); 6714 buf_ptr += WMI_TLV_HDR_SIZE; 6715 } 6716 6717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6718 sizeof(*assoc_ies)); 6719 buf_ptr += WMI_TLV_HDR_SIZE; 6720 6721 assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr; 6722 WMITLV_SET_HDR(&assoc_ies->tlv_header, 6723 WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, 6724 WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); 6725 assoc_ies->buf_len = roam_req->assoc_ie_length; 6726 6727 buf_ptr += sizeof(*assoc_ies); 6728 6729 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6730 roundup(assoc_ies->buf_len, sizeof(uint32_t))); 6731 buf_ptr += WMI_TLV_HDR_SIZE; 6732 6733 if (assoc_ies->buf_len != 0) { 6734 qdf_mem_copy(buf_ptr, roam_req->assoc_ie, 6735 assoc_ies->buf_len); 6736 } 6737 buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); 6738 buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req, 6739 buf_ptr, fils_tlv_len); 6740 } else { 6741 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6742 WMITLV_GET_STRUCT_TLVLEN(0)); 6743 buf_ptr += WMI_TLV_HDR_SIZE; 6744 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6745 WMITLV_GET_STRUCT_TLVLEN(0)); 6746 buf_ptr += WMI_TLV_HDR_SIZE; 6747 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6748 WMITLV_GET_STRUCT_TLVLEN(0)); 6749 buf_ptr += WMI_TLV_HDR_SIZE; 6750 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6751 WMITLV_GET_STRUCT_TLVLEN(0)); 6752 buf_ptr += WMI_TLV_HDR_SIZE; 6753 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6754 WMITLV_GET_STRUCT_TLVLEN(0)); 6755 buf_ptr += WMI_TLV_HDR_SIZE; 6756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6757 WMITLV_GET_STRUCT_TLVLEN(0)); 6758 } 6759 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 6760 6761 send_roam_scan_mode_cmd: 6762 wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0); 6763 status = wmi_unified_cmd_send(wmi_handle, buf, 6764 len, WMI_ROAM_SCAN_MODE); 6765 if (QDF_IS_STATUS_ERROR(status)) { 6766 WMI_LOGE( 6767 "wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", 6768 status); 6769 wmi_buf_free(buf); 6770 } 6771 6772 return status; 6773 } 6774 6775 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle, 6776 struct wmi_mawc_roam_params *params) 6777 { 6778 wmi_buf_t buf = NULL; 6779 QDF_STATUS status; 6780 int len; 6781 uint8_t *buf_ptr; 6782 wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params; 6783 6784 len = sizeof(*wmi_roam_mawc_params); 6785 buf = wmi_buf_alloc(wmi_handle, len); 6786 if (!buf) { 6787 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6788 return QDF_STATUS_E_NOMEM; 6789 } 6790 6791 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6792 wmi_roam_mawc_params = 6793 (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr; 6794 WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header, 6795 WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param, 6796 WMITLV_GET_STRUCT_TLVLEN 6797 (wmi_roam_configure_mawc_cmd_fixed_param)); 6798 wmi_roam_mawc_params->vdev_id = params->vdev_id; 6799 if (params->enable) 6800 wmi_roam_mawc_params->enable = 1; 6801 else 6802 wmi_roam_mawc_params->enable = 0; 6803 wmi_roam_mawc_params->traffic_load_threshold = 6804 params->traffic_load_threshold; 6805 wmi_roam_mawc_params->best_ap_rssi_threshold = 6806 params->best_ap_rssi_threshold; 6807 wmi_roam_mawc_params->rssi_stationary_high_adjust = 6808 params->rssi_stationary_high_adjust; 6809 wmi_roam_mawc_params->rssi_stationary_low_adjust = 6810 params->rssi_stationary_low_adjust; 6811 WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"), 6812 wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id, 6813 wmi_roam_mawc_params->traffic_load_threshold, 6814 wmi_roam_mawc_params->best_ap_rssi_threshold, 6815 wmi_roam_mawc_params->rssi_stationary_high_adjust, 6816 wmi_roam_mawc_params->rssi_stationary_low_adjust); 6817 6818 wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6819 status = wmi_unified_cmd_send(wmi_handle, buf, 6820 len, WMI_ROAM_CONFIGURE_MAWC_CMDID); 6821 if (QDF_IS_STATUS_ERROR(status)) { 6822 WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d", 6823 status); 6824 wmi_buf_free(buf); 6825 return status; 6826 } 6827 6828 return QDF_STATUS_SUCCESS; 6829 } 6830 6831 /** 6832 * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload 6833 * rssi threashold 6834 * @wmi_handle: wmi handle 6835 * @roam_req: Roaming request buffer 6836 * 6837 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware 6838 * 6839 * Return: QDF status 6840 */ 6841 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6842 struct roam_offload_scan_rssi_params *roam_req) 6843 { 6844 wmi_buf_t buf = NULL; 6845 QDF_STATUS status; 6846 int len; 6847 uint8_t *buf_ptr; 6848 wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; 6849 wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; 6850 wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL; 6851 wmi_roam_dense_thres_param *dense_thresholds = NULL; 6852 wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL; 6853 6854 len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6855 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6856 len += sizeof(wmi_roam_scan_extended_threshold_param); 6857 len += WMI_TLV_HDR_SIZE; 6858 len += sizeof(wmi_roam_earlystop_rssi_thres_param); 6859 len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/ 6860 len += sizeof(wmi_roam_dense_thres_param); 6861 len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/ 6862 len += sizeof(wmi_roam_bg_scan_roaming_param); 6863 buf = wmi_buf_alloc(wmi_handle, len); 6864 if (!buf) { 6865 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 6866 return QDF_STATUS_E_NOMEM; 6867 } 6868 6869 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6870 rssi_threshold_fp = 6871 (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; 6872 WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, 6873 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, 6874 WMITLV_GET_STRUCT_TLVLEN 6875 (wmi_roam_scan_rssi_threshold_fixed_param)); 6876 /* fill in threshold values */ 6877 rssi_threshold_fp->vdev_id = roam_req->session_id; 6878 rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh; 6879 rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff; 6880 rssi_threshold_fp->hirssi_scan_max_count = 6881 roam_req->hi_rssi_scan_max_count; 6882 rssi_threshold_fp->hirssi_scan_delta = 6883 roam_req->hi_rssi_scan_rssi_delta; 6884 rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub; 6885 rssi_threshold_fp->rssi_thresh_offset_5g = 6886 roam_req->rssi_thresh_offset_5g; 6887 6888 buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); 6889 WMITLV_SET_HDR(buf_ptr, 6890 WMITLV_TAG_ARRAY_STRUC, 6891 sizeof(wmi_roam_scan_extended_threshold_param)); 6892 buf_ptr += WMI_TLV_HDR_SIZE; 6893 ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; 6894 6895 ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g; 6896 if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT) 6897 ext_thresholds->boost_threshold_5g = 6898 roam_req->boost_threshold_5g; 6899 6900 ext_thresholds->boost_algorithm_5g = 6901 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6902 ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g; 6903 ext_thresholds->penalty_algorithm_5g = 6904 WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; 6905 ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g; 6906 ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g; 6907 ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g; 6908 ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold; 6909 6910 WMITLV_SET_HDR(&ext_thresholds->tlv_header, 6911 WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, 6912 WMITLV_GET_STRUCT_TLVLEN 6913 (wmi_roam_scan_extended_threshold_param)); 6914 buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param); 6915 WMITLV_SET_HDR(buf_ptr, 6916 WMITLV_TAG_ARRAY_STRUC, 6917 sizeof(wmi_roam_earlystop_rssi_thres_param)); 6918 buf_ptr += WMI_TLV_HDR_SIZE; 6919 early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr; 6920 early_stop_thresholds->roam_earlystop_thres_min = 6921 roam_req->roam_earlystop_thres_min; 6922 early_stop_thresholds->roam_earlystop_thres_max = 6923 roam_req->roam_earlystop_thres_max; 6924 WMITLV_SET_HDR(&early_stop_thresholds->tlv_header, 6925 WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param, 6926 WMITLV_GET_STRUCT_TLVLEN 6927 (wmi_roam_earlystop_rssi_thres_param)); 6928 6929 buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param); 6930 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6931 sizeof(wmi_roam_dense_thres_param)); 6932 buf_ptr += WMI_TLV_HDR_SIZE; 6933 dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr; 6934 dense_thresholds->roam_dense_rssi_thres_offset = 6935 roam_req->dense_rssi_thresh_offset; 6936 dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt; 6937 dense_thresholds->roam_dense_traffic_thres = 6938 roam_req->traffic_threshold; 6939 dense_thresholds->roam_dense_status = roam_req->initial_dense_status; 6940 WMITLV_SET_HDR(&dense_thresholds->tlv_header, 6941 WMITLV_TAG_STRUC_wmi_roam_dense_thres_param, 6942 WMITLV_GET_STRUCT_TLVLEN 6943 (wmi_roam_dense_thres_param)); 6944 6945 buf_ptr += sizeof(wmi_roam_dense_thres_param); 6946 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6947 sizeof(wmi_roam_bg_scan_roaming_param)); 6948 buf_ptr += WMI_TLV_HDR_SIZE; 6949 bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr; 6950 bg_scan_params->roam_bg_scan_bad_rssi_thresh = 6951 roam_req->bg_scan_bad_rssi_thresh; 6952 bg_scan_params->roam_bg_scan_client_bitmap = 6953 roam_req->bg_scan_client_bitmap; 6954 bg_scan_params->bad_rssi_thresh_offset_2g = 6955 roam_req->roam_bad_rssi_thresh_offset_2g; 6956 bg_scan_params->flags = roam_req->flags; 6957 WMITLV_SET_HDR(&bg_scan_params->tlv_header, 6958 WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param, 6959 WMITLV_GET_STRUCT_TLVLEN 6960 (wmi_roam_bg_scan_roaming_param)); 6961 6962 wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0); 6963 status = wmi_unified_cmd_send(wmi_handle, buf, 6964 len, WMI_ROAM_SCAN_RSSI_THRESHOLD); 6965 if (QDF_IS_STATUS_ERROR(status)) { 6966 WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", 6967 status); 6968 wmi_buf_free(buf); 6969 } 6970 6971 return status; 6972 } 6973 6974 /** 6975 * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime 6976 * configuration params 6977 * @wma_handle: wma handler 6978 * @dwelltime_params: pointer to dwelltime_params 6979 * 6980 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 6981 */ 6982 static 6983 QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, 6984 struct wmi_adaptive_dwelltime_params *dwelltime_params) 6985 { 6986 wmi_scan_adaptive_dwell_config_fixed_param *dwell_param; 6987 wmi_scan_adaptive_dwell_parameters_tlv *cmd; 6988 wmi_buf_t buf; 6989 uint8_t *buf_ptr; 6990 int32_t err; 6991 int len; 6992 6993 len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 6994 len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ 6995 len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv); 6996 buf = wmi_buf_alloc(wmi_handle, len); 6997 if (!buf) { 6998 WMI_LOGE("%s :Failed to allocate buffer to send cmd", 6999 __func__); 7000 return QDF_STATUS_E_NOMEM; 7001 } 7002 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7003 dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr; 7004 WMITLV_SET_HDR(&dwell_param->tlv_header, 7005 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param, 7006 WMITLV_GET_STRUCT_TLVLEN 7007 (wmi_scan_adaptive_dwell_config_fixed_param)); 7008 7009 dwell_param->enable = dwelltime_params->is_enabled; 7010 buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param); 7011 WMITLV_SET_HDR(buf_ptr, 7012 WMITLV_TAG_ARRAY_STRUC, 7013 sizeof(wmi_scan_adaptive_dwell_parameters_tlv)); 7014 buf_ptr += WMI_TLV_HDR_SIZE; 7015 7016 cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr; 7017 WMITLV_SET_HDR(&cmd->tlv_header, 7018 WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv, 7019 WMITLV_GET_STRUCT_TLVLEN( 7020 wmi_scan_adaptive_dwell_parameters_tlv)); 7021 7022 cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode; 7023 cmd->adapative_lpf_weight = dwelltime_params->lpf_weight; 7024 cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval; 7025 cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold; 7026 wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0); 7027 err = wmi_unified_cmd_send(wmi_handle, buf, 7028 len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID); 7029 if (err) { 7030 WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err); 7031 wmi_buf_free(buf); 7032 return QDF_STATUS_E_FAILURE; 7033 } 7034 7035 return QDF_STATUS_SUCCESS; 7036 } 7037 7038 /** 7039 * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection 7040 * configuration params 7041 * @wmi_handle: wmi handler 7042 * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params 7043 * 7044 * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure 7045 */ 7046 static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, 7047 struct wmi_dbs_scan_sel_params *dbs_scan_params) 7048 { 7049 wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; 7050 wmi_scan_dbs_duty_cycle_tlv_param *cmd; 7051 wmi_buf_t buf; 7052 uint8_t *buf_ptr; 7053 QDF_STATUS err; 7054 uint32_t i; 7055 int len; 7056 7057 len = sizeof(*dbs_scan_param); 7058 len += WMI_TLV_HDR_SIZE; 7059 len += dbs_scan_params->num_clients * sizeof(*cmd); 7060 7061 buf = wmi_buf_alloc(wmi_handle, len); 7062 if (!buf) { 7063 WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); 7064 return QDF_STATUS_E_NOMEM; 7065 } 7066 7067 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7068 dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; 7069 WMITLV_SET_HDR(&dbs_scan_param->tlv_header, 7070 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, 7071 WMITLV_GET_STRUCT_TLVLEN 7072 (wmi_scan_dbs_duty_cycle_fixed_param)); 7073 7074 dbs_scan_param->num_clients = dbs_scan_params->num_clients; 7075 dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; 7076 buf_ptr += sizeof(*dbs_scan_param); 7077 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7078 (sizeof(*cmd) * dbs_scan_params->num_clients)); 7079 buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; 7080 7081 for (i = 0; i < dbs_scan_params->num_clients; i++) { 7082 cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; 7083 WMITLV_SET_HDR(&cmd->tlv_header, 7084 WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, 7085 WMITLV_GET_STRUCT_TLVLEN( 7086 wmi_scan_dbs_duty_cycle_tlv_param)); 7087 cmd->module_id = dbs_scan_params->module_id[i]; 7088 cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; 7089 cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; 7090 buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); 7091 } 7092 7093 wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0); 7094 err = wmi_unified_cmd_send(wmi_handle, buf, 7095 len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); 7096 if (QDF_IS_STATUS_ERROR(err)) { 7097 WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); 7098 wmi_buf_free(buf); 7099 return QDF_STATUS_E_FAILURE; 7100 } 7101 7102 return QDF_STATUS_SUCCESS; 7103 } 7104 7105 /** 7106 * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming 7107 * @wmi_handle: wmi handle 7108 * @roam_req: Request which contains the filters 7109 * 7110 * There are filters such as whitelist, blacklist and preferred 7111 * list that need to be applied to the scan results to form the 7112 * probable candidates for roaming. 7113 * 7114 * Return: Return success upon successfully passing the 7115 * parameters to the firmware, otherwise failure. 7116 */ 7117 static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, 7118 struct roam_scan_filter_params *roam_req) 7119 { 7120 wmi_buf_t buf = NULL; 7121 QDF_STATUS status; 7122 uint32_t i; 7123 uint32_t len, blist_len = 0; 7124 uint8_t *buf_ptr; 7125 wmi_roam_filter_fixed_param *roam_filter; 7126 uint8_t *bssid_src_ptr = NULL; 7127 wmi_mac_addr *bssid_dst_ptr = NULL; 7128 wmi_ssid *ssid_ptr = NULL; 7129 uint32_t *bssid_preferred_factor_ptr = NULL; 7130 wmi_roam_lca_disallow_config_tlv_param *blist_param; 7131 wmi_roam_rssi_rejection_oce_config_param *rssi_rej; 7132 7133 len = sizeof(wmi_roam_filter_fixed_param); 7134 7135 len += WMI_TLV_HDR_SIZE; 7136 if (roam_req->num_bssid_black_list) 7137 len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr); 7138 len += WMI_TLV_HDR_SIZE; 7139 if (roam_req->num_ssid_white_list) 7140 len += roam_req->num_ssid_white_list * sizeof(wmi_ssid); 7141 len += 2 * WMI_TLV_HDR_SIZE; 7142 if (roam_req->num_bssid_preferred_list) { 7143 len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr); 7144 len += roam_req->num_bssid_preferred_list * sizeof(uint32_t); 7145 } 7146 len += WMI_TLV_HDR_SIZE; 7147 if (roam_req->lca_disallow_config_present) { 7148 len += sizeof(*blist_param); 7149 blist_len = sizeof(*blist_param); 7150 } 7151 7152 len += WMI_TLV_HDR_SIZE; 7153 if (roam_req->num_rssi_rejection_ap) 7154 len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej); 7155 7156 buf = wmi_buf_alloc(wmi_handle, len); 7157 if (!buf) { 7158 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7159 return QDF_STATUS_E_NOMEM; 7160 } 7161 7162 buf_ptr = (u_int8_t *) wmi_buf_data(buf); 7163 roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; 7164 WMITLV_SET_HDR(&roam_filter->tlv_header, 7165 WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, 7166 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); 7167 /* fill in fixed values */ 7168 roam_filter->vdev_id = roam_req->session_id; 7169 roam_filter->flags = 0; 7170 roam_filter->op_bitmap = roam_req->op_bitmap; 7171 roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list; 7172 roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list; 7173 roam_filter->num_bssid_preferred_list = 7174 roam_req->num_bssid_preferred_list; 7175 roam_filter->num_rssi_rejection_ap = 7176 roam_req->num_rssi_rejection_ap; 7177 buf_ptr += sizeof(wmi_roam_filter_fixed_param); 7178 7179 WMITLV_SET_HDR((buf_ptr), 7180 WMITLV_TAG_ARRAY_FIXED_STRUC, 7181 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr))); 7182 bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list; 7183 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7184 for (i = 0; i < roam_req->num_bssid_black_list; i++) { 7185 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); 7186 bssid_src_ptr += ATH_MAC_LEN; 7187 bssid_dst_ptr++; 7188 } 7189 buf_ptr += WMI_TLV_HDR_SIZE + 7190 (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)); 7191 WMITLV_SET_HDR((buf_ptr), 7192 WMITLV_TAG_ARRAY_FIXED_STRUC, 7193 (roam_req->num_ssid_white_list * sizeof(wmi_ssid))); 7194 ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 7195 for (i = 0; i < roam_req->num_ssid_white_list; i++) { 7196 qdf_mem_copy(&ssid_ptr->ssid, 7197 &roam_req->ssid_allowed_list[i].mac_ssid, 7198 roam_req->ssid_allowed_list[i].length); 7199 ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length; 7200 ssid_ptr++; 7201 } 7202 buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list * 7203 sizeof(wmi_ssid)); 7204 WMITLV_SET_HDR((buf_ptr), 7205 WMITLV_TAG_ARRAY_FIXED_STRUC, 7206 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr))); 7207 bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored; 7208 bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 7209 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7210 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, 7211 (wmi_mac_addr *)bssid_dst_ptr); 7212 bssid_src_ptr += ATH_MAC_LEN; 7213 bssid_dst_ptr++; 7214 } 7215 buf_ptr += WMI_TLV_HDR_SIZE + 7216 (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)); 7217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7218 (roam_req->num_bssid_preferred_list * sizeof(uint32_t))); 7219 bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 7220 for (i = 0; i < roam_req->num_bssid_preferred_list; i++) { 7221 *bssid_preferred_factor_ptr = 7222 roam_req->bssid_favored_factor[i]; 7223 bssid_preferred_factor_ptr++; 7224 } 7225 buf_ptr += WMI_TLV_HDR_SIZE + 7226 (roam_req->num_bssid_preferred_list * sizeof(uint32_t)); 7227 7228 WMITLV_SET_HDR(buf_ptr, 7229 WMITLV_TAG_ARRAY_STRUC, blist_len); 7230 buf_ptr += WMI_TLV_HDR_SIZE; 7231 if (roam_req->lca_disallow_config_present) { 7232 blist_param = 7233 (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr; 7234 WMITLV_SET_HDR(&blist_param->tlv_header, 7235 WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param, 7236 WMITLV_GET_STRUCT_TLVLEN( 7237 wmi_roam_lca_disallow_config_tlv_param)); 7238 7239 blist_param->disallow_duration = roam_req->disallow_duration; 7240 blist_param->rssi_channel_penalization = 7241 roam_req->rssi_channel_penalization; 7242 blist_param->num_disallowed_aps = roam_req->num_disallowed_aps; 7243 blist_param->disallow_lca_enable_source_bitmap = 7244 (WMI_ROAM_LCA_DISALLOW_SOURCE_PER | 7245 WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND); 7246 buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param)); 7247 } 7248 7249 WMITLV_SET_HDR(buf_ptr, 7250 WMITLV_TAG_ARRAY_STRUC, 7251 (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej))); 7252 buf_ptr += WMI_TLV_HDR_SIZE; 7253 for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) { 7254 rssi_rej = 7255 (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr; 7256 WMITLV_SET_HDR(&rssi_rej->tlv_header, 7257 WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param, 7258 WMITLV_GET_STRUCT_TLVLEN( 7259 wmi_roam_rssi_rejection_oce_config_param)); 7260 WMI_CHAR_ARRAY_TO_MAC_ADDR( 7261 roam_req->rssi_rejection_ap[i].bssid.bytes, 7262 &rssi_rej->bssid); 7263 rssi_rej->remaining_disallow_duration = 7264 roam_req->rssi_rejection_ap[i].remaining_duration; 7265 rssi_rej->requested_rssi = 7266 (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; 7267 buf_ptr += 7268 (sizeof(wmi_roam_rssi_rejection_oce_config_param)); 7269 } 7270 7271 wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0); 7272 status = wmi_unified_cmd_send(wmi_handle, buf, 7273 len, WMI_ROAM_FILTER_CMDID); 7274 if (QDF_IS_STATUS_ERROR(status)) { 7275 WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d", 7276 status); 7277 wmi_buf_free(buf); 7278 } 7279 7280 return status; 7281 } 7282 7283 #if defined(WLAN_FEATURE_FILS_SK) 7284 static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle, 7285 struct hlp_params *params) 7286 { 7287 uint32_t len; 7288 uint8_t *buf_ptr; 7289 wmi_buf_t buf = NULL; 7290 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params; 7291 7292 len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param); 7293 len += WMI_TLV_HDR_SIZE; 7294 len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t)); 7295 7296 buf = wmi_buf_alloc(wmi_handle, len); 7297 if (!buf) { 7298 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7299 return QDF_STATUS_E_NOMEM; 7300 } 7301 7302 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7303 hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr; 7304 WMITLV_SET_HDR(&hlp_params->tlv_header, 7305 WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param, 7306 WMITLV_GET_STRUCT_TLVLEN( 7307 wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param)); 7308 7309 hlp_params->vdev_id = params->vdev_id; 7310 hlp_params->size = params->hlp_ie_len; 7311 hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER; 7312 7313 buf_ptr += sizeof(*hlp_params); 7314 7315 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7316 round_up(params->hlp_ie_len, 7317 sizeof(uint32_t))); 7318 buf_ptr += WMI_TLV_HDR_SIZE; 7319 qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len); 7320 7321 WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"), 7322 hlp_params->vdev_id, hlp_params->size); 7323 wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0); 7324 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7325 WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) { 7326 WMI_LOGE(FL("Failed to send FILS HLP pkt cmd")); 7327 wmi_buf_free(buf); 7328 return QDF_STATUS_E_FAILURE; 7329 } 7330 7331 return QDF_STATUS_SUCCESS; 7332 } 7333 #endif 7334 7335 #ifdef IPA_OFFLOAD 7336 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 7337 * @wmi_handle: wmi handle 7338 * @ipa_offload: ipa offload control parameter 7339 * 7340 * Returns: 0 on success, error number otherwise 7341 */ 7342 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 7343 struct ipa_uc_offload_control_params *ipa_offload) 7344 { 7345 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 7346 wmi_buf_t wmi_buf; 7347 uint32_t len; 7348 u_int8_t *buf_ptr; 7349 7350 len = sizeof(*cmd); 7351 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7352 if (!wmi_buf) { 7353 WMI_LOGE("%s: wmi_buf_alloc failed (len=%d)", __func__, len); 7354 return QDF_STATUS_E_NOMEM; 7355 } 7356 7357 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 7358 ipa_offload->offload_type, ipa_offload->enable); 7359 7360 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 7361 7362 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 7363 WMITLV_SET_HDR(&cmd->tlv_header, 7364 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 7365 WMITLV_GET_STRUCT_TLVLEN( 7366 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 7367 7368 cmd->offload_type = ipa_offload->offload_type; 7369 cmd->vdev_id = ipa_offload->vdev_id; 7370 cmd->enable = ipa_offload->enable; 7371 7372 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 7373 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7374 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 7375 WMI_LOGE("%s: failed to command", __func__); 7376 wmi_buf_free(wmi_buf); 7377 return QDF_STATUS_E_FAILURE; 7378 } 7379 7380 return QDF_STATUS_SUCCESS; 7381 } 7382 #endif 7383 7384 /** 7385 * send_plm_stop_cmd_tlv() - plm stop request 7386 * @wmi_handle: wmi handle 7387 * @plm: plm request parameters 7388 * 7389 * This function request FW to stop PLM. 7390 * 7391 * Return: CDF status 7392 */ 7393 static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle, 7394 const struct plm_req_params *plm) 7395 { 7396 wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; 7397 int32_t len; 7398 wmi_buf_t buf; 7399 uint8_t *buf_ptr; 7400 int ret; 7401 7402 len = sizeof(*cmd); 7403 buf = wmi_buf_alloc(wmi_handle, len); 7404 if (!buf) { 7405 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7406 return QDF_STATUS_E_NOMEM; 7407 } 7408 7409 cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); 7410 7411 buf_ptr = (uint8_t *) cmd; 7412 7413 WMITLV_SET_HDR(&cmd->tlv_header, 7414 WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, 7415 WMITLV_GET_STRUCT_TLVLEN 7416 (wmi_vdev_plmreq_stop_cmd_fixed_param)); 7417 7418 cmd->vdev_id = plm->session_id; 7419 7420 cmd->meas_token = plm->meas_token; 7421 WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); 7422 7423 wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0); 7424 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7425 WMI_VDEV_PLMREQ_STOP_CMDID); 7426 if (ret) { 7427 WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__); 7428 wmi_buf_free(buf); 7429 return QDF_STATUS_E_FAILURE; 7430 } 7431 7432 return QDF_STATUS_SUCCESS; 7433 } 7434 7435 /** 7436 * send_plm_start_cmd_tlv() - plm start request 7437 * @wmi_handle: wmi handle 7438 * @plm: plm request parameters 7439 * 7440 * This function request FW to start PLM. 7441 * 7442 * Return: CDF status 7443 */ 7444 static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle, 7445 const struct plm_req_params *plm, 7446 uint32_t *gchannel_list) 7447 { 7448 wmi_vdev_plmreq_start_cmd_fixed_param *cmd; 7449 uint32_t *channel_list; 7450 int32_t len; 7451 wmi_buf_t buf; 7452 uint8_t *buf_ptr; 7453 uint8_t count; 7454 int ret; 7455 7456 /* TLV place holder for channel_list */ 7457 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7458 len += sizeof(uint32_t) * plm->plm_num_ch; 7459 7460 buf = wmi_buf_alloc(wmi_handle, len); 7461 if (!buf) { 7462 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7463 return QDF_STATUS_E_NOMEM; 7464 } 7465 cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); 7466 7467 buf_ptr = (uint8_t *) cmd; 7468 7469 WMITLV_SET_HDR(&cmd->tlv_header, 7470 WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, 7471 WMITLV_GET_STRUCT_TLVLEN 7472 (wmi_vdev_plmreq_start_cmd_fixed_param)); 7473 7474 cmd->vdev_id = plm->session_id; 7475 7476 cmd->meas_token = plm->meas_token; 7477 cmd->dialog_token = plm->diag_token; 7478 cmd->number_bursts = plm->num_bursts; 7479 cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int); 7480 cmd->off_duration = plm->meas_duration; 7481 cmd->burst_cycle = plm->burst_len; 7482 cmd->tx_power = plm->desired_tx_pwr; 7483 WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac); 7484 cmd->num_chans = plm->plm_num_ch; 7485 7486 buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); 7487 7488 WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); 7489 WMI_LOGD("dialog_token: %d", cmd->dialog_token); 7490 WMI_LOGD("number_bursts: %d", cmd->number_bursts); 7491 WMI_LOGD("burst_interval: %d", cmd->burst_interval); 7492 WMI_LOGD("off_duration: %d", cmd->off_duration); 7493 WMI_LOGD("burst_cycle: %d", cmd->burst_cycle); 7494 WMI_LOGD("tx_power: %d", cmd->tx_power); 7495 WMI_LOGD("Number of channels : %d", cmd->num_chans); 7496 7497 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7498 (cmd->num_chans * sizeof(uint32_t))); 7499 7500 buf_ptr += WMI_TLV_HDR_SIZE; 7501 if (cmd->num_chans) { 7502 channel_list = (uint32_t *) buf_ptr; 7503 for (count = 0; count < cmd->num_chans; count++) { 7504 channel_list[count] = plm->plm_ch_list[count]; 7505 if (channel_list[count] < WMI_NLO_FREQ_THRESH) 7506 channel_list[count] = 7507 gchannel_list[count]; 7508 WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); 7509 } 7510 buf_ptr += cmd->num_chans * sizeof(uint32_t); 7511 } 7512 7513 wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0); 7514 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7515 WMI_VDEV_PLMREQ_START_CMDID); 7516 if (ret) { 7517 WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__); 7518 wmi_buf_free(buf); 7519 return QDF_STATUS_E_FAILURE; 7520 } 7521 7522 return QDF_STATUS_SUCCESS; 7523 } 7524 7525 /** 7526 * send_pno_stop_cmd_tlv() - PNO stop request 7527 * @wmi_handle: wmi handle 7528 * @vdev_id: vdev id 7529 * 7530 * This function request FW to stop ongoing PNO operation. 7531 * 7532 * Return: CDF status 7533 */ 7534 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7535 { 7536 wmi_nlo_config_cmd_fixed_param *cmd; 7537 int32_t len = sizeof(*cmd); 7538 wmi_buf_t buf; 7539 uint8_t *buf_ptr; 7540 int ret; 7541 7542 /* 7543 * TLV place holder for array of structures nlo_configured_parameters 7544 * TLV place holder for array of uint32_t channel_list 7545 * TLV place holder for chnl prediction cfg 7546 */ 7547 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7548 buf = wmi_buf_alloc(wmi_handle, len); 7549 if (!buf) { 7550 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7551 return QDF_STATUS_E_NOMEM; 7552 } 7553 7554 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7555 buf_ptr = (uint8_t *) cmd; 7556 7557 WMITLV_SET_HDR(&cmd->tlv_header, 7558 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7559 WMITLV_GET_STRUCT_TLVLEN 7560 (wmi_nlo_config_cmd_fixed_param)); 7561 7562 cmd->vdev_id = vdev_id; 7563 cmd->flags = WMI_NLO_CONFIG_STOP; 7564 buf_ptr += sizeof(*cmd); 7565 7566 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7567 buf_ptr += WMI_TLV_HDR_SIZE; 7568 7569 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 7570 buf_ptr += WMI_TLV_HDR_SIZE; 7571 7572 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7573 buf_ptr += WMI_TLV_HDR_SIZE; 7574 7575 7576 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 7577 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7578 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7579 if (ret) { 7580 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7581 wmi_buf_free(buf); 7582 return QDF_STATUS_E_FAILURE; 7583 } 7584 7585 return QDF_STATUS_SUCCESS; 7586 } 7587 7588 /** 7589 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 7590 * @buf_ptr: Buffer passed by upper layers 7591 * @pno: Buffer to be sent to the firmware 7592 * 7593 * Copy the PNO Channel prediction configuration parameters 7594 * passed by the upper layers to a WMI format TLV and send it 7595 * down to the firmware. 7596 * 7597 * Return: None 7598 */ 7599 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 7600 struct pno_scan_req_params *pno) 7601 { 7602 nlo_channel_prediction_cfg *channel_prediction_cfg = 7603 (nlo_channel_prediction_cfg *) buf_ptr; 7604 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 7605 WMITLV_TAG_ARRAY_BYTE, 7606 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 7607 #ifdef FEATURE_WLAN_SCAN_PNO 7608 channel_prediction_cfg->enable = pno->pno_channel_prediction; 7609 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 7610 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 7611 channel_prediction_cfg->full_scan_period_ms = 7612 pno->channel_prediction_full_scan; 7613 #endif 7614 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7615 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 7616 channel_prediction_cfg->enable, 7617 channel_prediction_cfg->top_k_num, 7618 channel_prediction_cfg->stationary_threshold, 7619 channel_prediction_cfg->full_scan_period_ms); 7620 } 7621 7622 /** 7623 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 7624 * @wmi_handle: wmi handle 7625 * @params: configuration parameters 7626 * 7627 * Return: QDF_STATUS 7628 */ 7629 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 7630 struct nlo_mawc_params *params) 7631 { 7632 wmi_buf_t buf = NULL; 7633 QDF_STATUS status; 7634 int len; 7635 uint8_t *buf_ptr; 7636 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 7637 7638 len = sizeof(*wmi_nlo_mawc_params); 7639 buf = wmi_buf_alloc(wmi_handle, len); 7640 if (!buf) { 7641 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7642 return QDF_STATUS_E_NOMEM; 7643 } 7644 7645 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7646 wmi_nlo_mawc_params = 7647 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 7648 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 7649 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 7650 WMITLV_GET_STRUCT_TLVLEN 7651 (wmi_nlo_configure_mawc_cmd_fixed_param)); 7652 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 7653 if (params->enable) 7654 wmi_nlo_mawc_params->enable = 1; 7655 else 7656 wmi_nlo_mawc_params->enable = 0; 7657 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 7658 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 7659 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 7660 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 7661 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 7662 wmi_nlo_mawc_params->exp_backoff_ratio, 7663 wmi_nlo_mawc_params->init_scan_interval, 7664 wmi_nlo_mawc_params->max_scan_interval); 7665 7666 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 7667 status = wmi_unified_cmd_send(wmi_handle, buf, 7668 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 7669 if (QDF_IS_STATUS_ERROR(status)) { 7670 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 7671 status); 7672 wmi_buf_free(buf); 7673 return QDF_STATUS_E_FAILURE; 7674 } 7675 7676 return QDF_STATUS_SUCCESS; 7677 } 7678 7679 /** 7680 * send_pno_start_cmd_tlv() - PNO start request 7681 * @wmi_handle: wmi handle 7682 * @pno: PNO request 7683 * 7684 * This function request FW to start PNO request. 7685 * Request: CDF status 7686 */ 7687 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 7688 struct pno_scan_req_params *pno) 7689 { 7690 wmi_nlo_config_cmd_fixed_param *cmd; 7691 nlo_configured_parameters *nlo_list; 7692 uint32_t *channel_list; 7693 int32_t len; 7694 wmi_buf_t buf; 7695 uint8_t *buf_ptr; 7696 uint8_t i; 7697 int ret; 7698 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 7699 connected_nlo_rssi_params *nlo_relative_rssi; 7700 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 7701 7702 /* 7703 * TLV place holder for array nlo_configured_parameters(nlo_list) 7704 * TLV place holder for array of uint32_t channel_list 7705 * TLV place holder for chnnl prediction cfg 7706 * TLV place holder for array of wmi_vendor_oui 7707 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 7708 */ 7709 len = sizeof(*cmd) + 7710 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 7711 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 7712 7713 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 7714 WMI_NLO_MAX_CHAN); 7715 len += sizeof(nlo_configured_parameters) * 7716 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7717 len += sizeof(nlo_channel_prediction_cfg); 7718 len += sizeof(enlo_candidate_score_params); 7719 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 7720 len += sizeof(connected_nlo_rssi_params); 7721 len += sizeof(connected_nlo_bss_band_rssi_pref); 7722 7723 buf = wmi_buf_alloc(wmi_handle, len); 7724 if (!buf) { 7725 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 7726 return QDF_STATUS_E_NOMEM; 7727 } 7728 7729 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 7730 7731 buf_ptr = (uint8_t *) cmd; 7732 WMITLV_SET_HDR(&cmd->tlv_header, 7733 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 7734 WMITLV_GET_STRUCT_TLVLEN 7735 (wmi_nlo_config_cmd_fixed_param)); 7736 cmd->vdev_id = pno->vdev_id; 7737 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 7738 7739 #ifdef FEATURE_WLAN_SCAN_PNO 7740 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 7741 pno->adaptive_dwell_mode); 7742 #endif 7743 /* Current FW does not support min-max range for dwell time */ 7744 cmd->active_dwell_time = pno->active_dwell_time; 7745 cmd->passive_dwell_time = pno->passive_dwell_time; 7746 7747 if (pno->do_passive_scan) 7748 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 7749 /* Copy scan interval */ 7750 cmd->fast_scan_period = pno->fast_scan_period; 7751 cmd->slow_scan_period = pno->slow_scan_period; 7752 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 7753 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 7754 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 7755 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 7756 cmd->fast_scan_period, cmd->slow_scan_period); 7757 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 7758 7759 /* mac randomization attributes */ 7760 if (pno->scan_random.randomize) { 7761 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 7762 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 7763 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 7764 pno->scan_random.mac_mask, 7765 &cmd->mac_addr, 7766 &cmd->mac_mask); 7767 } 7768 7769 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 7770 7771 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 7772 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 7773 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7774 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 7775 buf_ptr += WMI_TLV_HDR_SIZE; 7776 7777 nlo_list = (nlo_configured_parameters *) buf_ptr; 7778 for (i = 0; i < cmd->no_of_ssids; i++) { 7779 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 7780 WMITLV_TAG_ARRAY_BYTE, 7781 WMITLV_GET_STRUCT_TLVLEN 7782 (nlo_configured_parameters)); 7783 /* Copy ssid and it's length */ 7784 nlo_list[i].ssid.valid = true; 7785 nlo_list[i].ssid.ssid.ssid_len = 7786 pno->networks_list[i].ssid.length; 7787 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 7788 pno->networks_list[i].ssid.ssid, 7789 nlo_list[i].ssid.ssid.ssid_len); 7790 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 7791 nlo_list[i].ssid.ssid.ssid_len, 7792 (char *)nlo_list[i].ssid.ssid.ssid, 7793 nlo_list[i].ssid.ssid.ssid_len); 7794 7795 /* Copy rssi threshold */ 7796 if (pno->networks_list[i].rssi_thresh && 7797 pno->networks_list[i].rssi_thresh > 7798 WMI_RSSI_THOLD_DEFAULT) { 7799 nlo_list[i].rssi_cond.valid = true; 7800 nlo_list[i].rssi_cond.rssi = 7801 pno->networks_list[i].rssi_thresh; 7802 WMI_LOGD("RSSI threshold : %d dBm", 7803 nlo_list[i].rssi_cond.rssi); 7804 } 7805 nlo_list[i].bcast_nw_type.valid = true; 7806 nlo_list[i].bcast_nw_type.bcast_nw_type = 7807 pno->networks_list[i].bc_new_type; 7808 WMI_LOGD("Broadcast NW type (%u)", 7809 nlo_list[i].bcast_nw_type.bcast_nw_type); 7810 } 7811 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 7812 7813 /* Copy channel info */ 7814 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 7815 WMI_NLO_MAX_CHAN); 7816 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 7817 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7818 (cmd->num_of_channels * sizeof(uint32_t))); 7819 buf_ptr += WMI_TLV_HDR_SIZE; 7820 7821 channel_list = (uint32_t *) buf_ptr; 7822 for (i = 0; i < cmd->num_of_channels; i++) { 7823 channel_list[i] = pno->networks_list[0].channels[i]; 7824 7825 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 7826 channel_list[i] = 7827 wlan_chan_to_freq(pno-> 7828 networks_list[0].channels[i]); 7829 7830 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 7831 } 7832 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 7833 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7834 sizeof(nlo_channel_prediction_cfg)); 7835 buf_ptr += WMI_TLV_HDR_SIZE; 7836 wmi_set_pno_channel_prediction(buf_ptr, pno); 7837 buf_ptr += sizeof(nlo_channel_prediction_cfg); 7838 /** TODO: Discrete firmware doesn't have command/option to configure 7839 * App IE which comes from wpa_supplicant as of part PNO start request. 7840 */ 7841 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 7842 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 7843 buf_ptr += sizeof(enlo_candidate_score_params); 7844 7845 if (ie_whitelist->white_list) { 7846 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 7847 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 7848 &cmd->num_vendor_oui, 7849 ie_whitelist); 7850 } 7851 7852 /* ie white list */ 7853 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7854 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 7855 buf_ptr += WMI_TLV_HDR_SIZE; 7856 if (cmd->num_vendor_oui != 0) { 7857 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 7858 ie_whitelist->voui); 7859 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 7860 } 7861 7862 if (pno->relative_rssi_set) 7863 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 7864 7865 /* 7866 * Firmware calculation using connected PNO params: 7867 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 7868 * deduction of rssi_pref for chosen band_pref and 7869 * addition of rssi_pref for remaining bands (other than chosen band). 7870 */ 7871 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 7872 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 7873 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 7874 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 7875 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 7876 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 7877 buf_ptr += sizeof(*nlo_relative_rssi); 7878 7879 /* 7880 * As of now Kernel and Host supports one band and rssi preference. 7881 * Firmware supports array of band and rssi preferences 7882 */ 7883 cmd->num_cnlo_band_pref = 1; 7884 WMITLV_SET_HDR(buf_ptr, 7885 WMITLV_TAG_ARRAY_STRUC, 7886 cmd->num_cnlo_band_pref * 7887 sizeof(connected_nlo_bss_band_rssi_pref)); 7888 buf_ptr += WMI_TLV_HDR_SIZE; 7889 7890 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 7891 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 7892 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 7893 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 7894 WMITLV_GET_STRUCT_TLVLEN( 7895 connected_nlo_bss_band_rssi_pref)); 7896 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 7897 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 7898 WMI_LOGI("band_pref %d, rssi_pref %d", 7899 nlo_band_rssi[i].band, 7900 nlo_band_rssi[i].rssi_pref); 7901 } 7902 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 7903 7904 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 7905 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7906 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 7907 if (ret) { 7908 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 7909 wmi_buf_free(buf); 7910 return QDF_STATUS_E_FAILURE; 7911 } 7912 7913 return QDF_STATUS_SUCCESS; 7914 } 7915 7916 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7917 /* send_set_ric_req_cmd_tlv() - set ric request element 7918 * @wmi_handle: wmi handle 7919 * @msg: message 7920 * @is_add_ts: is addts required 7921 * 7922 * This function sets ric request element for 11r roaming. 7923 * 7924 * Return: CDF status 7925 */ 7926 static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle, 7927 void *msg, uint8_t is_add_ts) 7928 { 7929 wmi_ric_request_fixed_param *cmd; 7930 wmi_ric_tspec *tspec_param; 7931 wmi_buf_t buf; 7932 uint8_t *buf_ptr; 7933 struct mac_tspec_ie *ptspecIE = NULL; 7934 int32_t len = sizeof(wmi_ric_request_fixed_param) + 7935 WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec); 7936 7937 buf = wmi_buf_alloc(wmi_handle, len); 7938 if (!buf) { 7939 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 7940 return QDF_STATUS_E_NOMEM; 7941 } 7942 7943 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7944 7945 cmd = (wmi_ric_request_fixed_param *) buf_ptr; 7946 WMITLV_SET_HDR(&cmd->tlv_header, 7947 WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, 7948 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); 7949 if (is_add_ts) 7950 cmd->vdev_id = ((struct add_ts_param *) msg)->sme_session_id; 7951 else 7952 cmd->vdev_id = ((struct del_ts_params *) msg)->sessionId; 7953 cmd->num_ric_request = 1; 7954 cmd->is_add_ric = is_add_ts; 7955 7956 buf_ptr += sizeof(wmi_ric_request_fixed_param); 7957 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec)); 7958 7959 buf_ptr += WMI_TLV_HDR_SIZE; 7960 tspec_param = (wmi_ric_tspec *) buf_ptr; 7961 WMITLV_SET_HDR(&tspec_param->tlv_header, 7962 WMITLV_TAG_STRUC_wmi_ric_tspec, 7963 WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); 7964 7965 if (is_add_ts) 7966 ptspecIE = &(((struct add_ts_param *) msg)->tspec); 7967 else 7968 ptspecIE = &(((struct del_ts_params *) msg)->delTsInfo.tspec); 7969 if (ptspecIE) { 7970 /* Fill the tsinfo in the format expected by firmware */ 7971 #ifndef ANI_LITTLE_BIT_ENDIAN 7972 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1, 7973 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7974 #else 7975 qdf_mem_copy(((uint8_t *) &tspec_param->ts_info), 7976 ((uint8_t *) &ptspecIE->tsinfo) + 1, 2); 7977 #endif /* ANI_LITTLE_BIT_ENDIAN */ 7978 7979 tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; 7980 tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; 7981 tspec_param->min_service_interval = ptspecIE->minSvcInterval; 7982 tspec_param->max_service_interval = ptspecIE->maxSvcInterval; 7983 tspec_param->inactivity_interval = ptspecIE->inactInterval; 7984 tspec_param->suspension_interval = ptspecIE->suspendInterval; 7985 tspec_param->svc_start_time = ptspecIE->svcStartTime; 7986 tspec_param->min_data_rate = ptspecIE->minDataRate; 7987 tspec_param->mean_data_rate = ptspecIE->meanDataRate; 7988 tspec_param->peak_data_rate = ptspecIE->peakDataRate; 7989 tspec_param->max_burst_size = ptspecIE->maxBurstSz; 7990 tspec_param->delay_bound = ptspecIE->delayBound; 7991 tspec_param->min_phy_rate = ptspecIE->minPhyRate; 7992 tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; 7993 tspec_param->medium_time = 0; 7994 } 7995 WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); 7996 7997 wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0); 7998 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7999 WMI_ROAM_SET_RIC_REQUEST_CMDID)) { 8000 WMI_LOGP("%s: Failed to send vdev Set RIC Req command", 8001 __func__); 8002 if (is_add_ts) 8003 ((struct add_ts_param *) msg)->status = 8004 QDF_STATUS_E_FAILURE; 8005 wmi_buf_free(buf); 8006 return QDF_STATUS_E_FAILURE; 8007 } 8008 8009 return QDF_STATUS_SUCCESS; 8010 } 8011 8012 /** 8013 * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw. 8014 * @wmi_handle: wmi handle 8015 * @vdev_id: vdev id 8016 * 8017 * This function sends roam synch complete event to fw. 8018 * 8019 * Return: CDF STATUS 8020 */ 8021 static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle, 8022 uint8_t vdev_id) 8023 { 8024 wmi_roam_synch_complete_fixed_param *cmd; 8025 wmi_buf_t wmi_buf; 8026 uint8_t *buf_ptr; 8027 uint16_t len; 8028 len = sizeof(wmi_roam_synch_complete_fixed_param); 8029 8030 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8031 if (!wmi_buf) { 8032 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8033 return QDF_STATUS_E_NOMEM; 8034 } 8035 cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf); 8036 buf_ptr = (uint8_t *) cmd; 8037 WMITLV_SET_HDR(&cmd->tlv_header, 8038 WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, 8039 WMITLV_GET_STRUCT_TLVLEN 8040 (wmi_roam_synch_complete_fixed_param)); 8041 cmd->vdev_id = vdev_id; 8042 wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0); 8043 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8044 WMI_ROAM_SYNCH_COMPLETE)) { 8045 WMI_LOGP("%s: failed to send roam synch confirmation", 8046 __func__); 8047 wmi_buf_free(wmi_buf); 8048 return QDF_STATUS_E_FAILURE; 8049 } 8050 8051 return QDF_STATUS_SUCCESS; 8052 } 8053 #endif 8054 8055 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 8056 /** 8057 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 8058 * @wmi_handle: wmi handle 8059 * @clear_req: ll stats clear request command params 8060 * 8061 * Return: QDF_STATUS_SUCCESS for success or error code 8062 */ 8063 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 8064 const struct ll_stats_clear_params *clear_req, 8065 uint8_t addr[IEEE80211_ADDR_LEN]) 8066 { 8067 wmi_clear_link_stats_cmd_fixed_param *cmd; 8068 int32_t len; 8069 wmi_buf_t buf; 8070 uint8_t *buf_ptr; 8071 int ret; 8072 8073 len = sizeof(*cmd); 8074 buf = wmi_buf_alloc(wmi_handle, len); 8075 8076 if (!buf) { 8077 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8078 return QDF_STATUS_E_NOMEM; 8079 } 8080 8081 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8082 qdf_mem_zero(buf_ptr, len); 8083 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 8084 8085 WMITLV_SET_HDR(&cmd->tlv_header, 8086 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 8087 WMITLV_GET_STRUCT_TLVLEN 8088 (wmi_clear_link_stats_cmd_fixed_param)); 8089 8090 cmd->stop_stats_collection_req = clear_req->stop_req; 8091 cmd->vdev_id = clear_req->sta_id; 8092 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 8093 8094 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8095 &cmd->peer_macaddr); 8096 8097 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 8098 WMI_LOGD("StopReq : %d", cmd->stop_stats_collection_req); 8099 WMI_LOGD("Vdev Id : %d", cmd->vdev_id); 8100 WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); 8101 /* WMI_LOGD("Peer MAC Addr : %pM", 8102 cmd->peer_macaddr); */ 8103 8104 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 8105 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8106 WMI_CLEAR_LINK_STATS_CMDID); 8107 if (ret) { 8108 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 8109 wmi_buf_free(buf); 8110 return QDF_STATUS_E_FAILURE; 8111 } 8112 8113 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 8114 return QDF_STATUS_SUCCESS; 8115 } 8116 8117 /** 8118 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 8119 * @wmi_handle: wmi handle 8120 * @setReq: ll stats set request command params 8121 * 8122 * Return: QDF_STATUS_SUCCESS for success or error code 8123 */ 8124 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 8125 const struct ll_stats_set_params *set_req) 8126 { 8127 wmi_start_link_stats_cmd_fixed_param *cmd; 8128 int32_t len; 8129 wmi_buf_t buf; 8130 uint8_t *buf_ptr; 8131 int ret; 8132 8133 len = sizeof(*cmd); 8134 buf = wmi_buf_alloc(wmi_handle, len); 8135 8136 if (!buf) { 8137 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8138 return QDF_STATUS_E_NOMEM; 8139 } 8140 8141 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8142 qdf_mem_zero(buf_ptr, len); 8143 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 8144 8145 WMITLV_SET_HDR(&cmd->tlv_header, 8146 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 8147 WMITLV_GET_STRUCT_TLVLEN 8148 (wmi_start_link_stats_cmd_fixed_param)); 8149 8150 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 8151 cmd->aggressive_statistics_gathering = 8152 set_req->aggressive_statistics_gathering; 8153 8154 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 8155 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 8156 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 8157 8158 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 8159 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8160 WMI_START_LINK_STATS_CMDID); 8161 if (ret) { 8162 WMI_LOGE("%s: Failed to send set link stats request", __func__); 8163 wmi_buf_free(buf); 8164 return QDF_STATUS_E_FAILURE; 8165 } 8166 8167 return QDF_STATUS_SUCCESS; 8168 } 8169 8170 /** 8171 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 8172 * @wmi_handle:wmi handle 8173 * @get_req:ll stats get request command params 8174 * @addr: mac address 8175 * 8176 * Return: QDF_STATUS_SUCCESS for success or error code 8177 */ 8178 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 8179 const struct ll_stats_get_params *get_req, 8180 uint8_t addr[IEEE80211_ADDR_LEN]) 8181 { 8182 wmi_request_link_stats_cmd_fixed_param *cmd; 8183 int32_t len; 8184 wmi_buf_t buf; 8185 uint8_t *buf_ptr; 8186 int ret; 8187 8188 len = sizeof(*cmd); 8189 buf = wmi_buf_alloc(wmi_handle, len); 8190 8191 if (!buf) { 8192 WMI_LOGE("%s: buf allocation failed", __func__); 8193 return QDF_STATUS_E_NOMEM; 8194 } 8195 8196 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8197 qdf_mem_zero(buf_ptr, len); 8198 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 8199 8200 WMITLV_SET_HDR(&cmd->tlv_header, 8201 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 8202 WMITLV_GET_STRUCT_TLVLEN 8203 (wmi_request_link_stats_cmd_fixed_param)); 8204 8205 cmd->request_id = get_req->req_id; 8206 cmd->stats_type = get_req->param_id_mask; 8207 cmd->vdev_id = get_req->sta_id; 8208 8209 WMI_CHAR_ARRAY_TO_MAC_ADDR(addr, 8210 &cmd->peer_macaddr); 8211 8212 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 8213 WMI_LOGD("Request ID : %u", cmd->request_id); 8214 WMI_LOGD("Stats Type : %0x", cmd->stats_type); 8215 WMI_LOGD("Vdev ID : %d", cmd->vdev_id); 8216 WMI_LOGD("Peer MAC Addr : %pM", addr); 8217 8218 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 8219 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8220 WMI_REQUEST_LINK_STATS_CMDID); 8221 if (ret) { 8222 WMI_LOGE("%s: Failed to send get link stats request", __func__); 8223 wmi_buf_free(buf); 8224 return QDF_STATUS_E_FAILURE; 8225 } 8226 8227 return QDF_STATUS_SUCCESS; 8228 } 8229 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 8230 8231 /** 8232 * send_congestion_cmd_tlv() - send request to fw to get CCA 8233 * @wmi_handle: wmi handle 8234 * @vdev_id: vdev id 8235 * 8236 * Return: CDF status 8237 */ 8238 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 8239 uint8_t vdev_id) 8240 { 8241 wmi_buf_t buf; 8242 wmi_request_stats_cmd_fixed_param *cmd; 8243 uint8_t len; 8244 uint8_t *buf_ptr; 8245 8246 len = sizeof(*cmd); 8247 buf = wmi_buf_alloc(wmi_handle, len); 8248 if (!buf) { 8249 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 8250 return QDF_STATUS_E_FAILURE; 8251 } 8252 8253 buf_ptr = wmi_buf_data(buf); 8254 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 8255 WMITLV_SET_HDR(&cmd->tlv_header, 8256 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8257 WMITLV_GET_STRUCT_TLVLEN 8258 (wmi_request_stats_cmd_fixed_param)); 8259 8260 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 8261 cmd->vdev_id = vdev_id; 8262 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 8263 cmd->vdev_id, cmd->stats_id); 8264 8265 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 8266 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8267 WMI_REQUEST_STATS_CMDID)) { 8268 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 8269 __func__); 8270 wmi_buf_free(buf); 8271 return QDF_STATUS_E_FAILURE; 8272 } 8273 8274 return QDF_STATUS_SUCCESS; 8275 } 8276 8277 /** 8278 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 8279 * @wmi_handle: wmi handle 8280 * @rssi_req: get RSSI request 8281 * 8282 * Return: CDF status 8283 */ 8284 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 8285 { 8286 wmi_buf_t buf; 8287 wmi_request_stats_cmd_fixed_param *cmd; 8288 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8289 8290 buf = wmi_buf_alloc(wmi_handle, len); 8291 if (!buf) { 8292 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8293 return QDF_STATUS_E_FAILURE; 8294 } 8295 8296 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8297 WMITLV_SET_HDR(&cmd->tlv_header, 8298 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8299 WMITLV_GET_STRUCT_TLVLEN 8300 (wmi_request_stats_cmd_fixed_param)); 8301 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8302 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 8303 if (wmi_unified_cmd_send 8304 (wmi_handle, buf, len, WMI_REQUEST_STATS_CMDID)) { 8305 WMI_LOGE("Failed to send host stats request to fw"); 8306 wmi_buf_free(buf); 8307 return QDF_STATUS_E_FAILURE; 8308 } 8309 8310 return QDF_STATUS_SUCCESS; 8311 } 8312 8313 /** 8314 * send_snr_cmd_tlv() - get RSSI from fw 8315 * @wmi_handle: wmi handle 8316 * @vdev_id: vdev id 8317 * 8318 * Return: CDF status 8319 */ 8320 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8321 { 8322 wmi_buf_t buf; 8323 wmi_request_stats_cmd_fixed_param *cmd; 8324 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8325 8326 buf = wmi_buf_alloc(wmi_handle, len); 8327 if (!buf) { 8328 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8329 return QDF_STATUS_E_FAILURE; 8330 } 8331 8332 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8333 cmd->vdev_id = vdev_id; 8334 8335 WMITLV_SET_HDR(&cmd->tlv_header, 8336 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8337 WMITLV_GET_STRUCT_TLVLEN 8338 (wmi_request_stats_cmd_fixed_param)); 8339 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 8340 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 8341 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8342 WMI_REQUEST_STATS_CMDID)) { 8343 WMI_LOGE("Failed to send host stats request to fw"); 8344 wmi_buf_free(buf); 8345 return QDF_STATUS_E_FAILURE; 8346 } 8347 8348 return QDF_STATUS_SUCCESS; 8349 } 8350 8351 /** 8352 * send_link_status_req_cmd_tlv() - process link status request from UMAC 8353 * @wmi_handle: wmi handle 8354 * @link_status: get link params 8355 * 8356 * Return: CDF status 8357 */ 8358 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 8359 struct link_status_params *link_status) 8360 { 8361 wmi_buf_t buf; 8362 wmi_request_stats_cmd_fixed_param *cmd; 8363 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 8364 8365 buf = wmi_buf_alloc(wmi_handle, len); 8366 if (!buf) { 8367 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8368 return QDF_STATUS_E_FAILURE; 8369 } 8370 8371 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 8372 WMITLV_SET_HDR(&cmd->tlv_header, 8373 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 8374 WMITLV_GET_STRUCT_TLVLEN 8375 (wmi_request_stats_cmd_fixed_param)); 8376 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 8377 cmd->vdev_id = link_status->session_id; 8378 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 8379 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8380 WMI_REQUEST_STATS_CMDID)) { 8381 WMI_LOGE("Failed to send WMI link status request to fw"); 8382 wmi_buf_free(buf); 8383 return QDF_STATUS_E_FAILURE; 8384 } 8385 8386 return QDF_STATUS_SUCCESS; 8387 } 8388 8389 /** 8390 * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME 8391 * @wmi_handle: wmi handle 8392 * @ta_dhcp_ind: DHCP indication parameter 8393 * 8394 * Return: CDF Status 8395 */ 8396 static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle, 8397 wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind) 8398 { 8399 QDF_STATUS status; 8400 wmi_buf_t buf = NULL; 8401 uint8_t *buf_ptr; 8402 wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; 8403 int len = sizeof(wmi_peer_set_param_cmd_fixed_param); 8404 8405 8406 buf = wmi_buf_alloc(wmi_handle, len); 8407 if (!buf) { 8408 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8409 return QDF_STATUS_E_NOMEM; 8410 } 8411 8412 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8413 peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; 8414 WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, 8415 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 8416 WMITLV_GET_STRUCT_TLVLEN 8417 (wmi_peer_set_param_cmd_fixed_param)); 8418 8419 /* fill in values */ 8420 peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id; 8421 peer_set_param_fp->param_id = ta_dhcp_ind->param_id; 8422 peer_set_param_fp->param_value = ta_dhcp_ind->param_value; 8423 qdf_mem_copy(&peer_set_param_fp->peer_macaddr, 8424 &ta_dhcp_ind->peer_macaddr, 8425 sizeof(ta_dhcp_ind->peer_macaddr)); 8426 8427 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0); 8428 status = wmi_unified_cmd_send(wmi_handle, buf, 8429 len, WMI_PEER_SET_PARAM_CMDID); 8430 if (QDF_IS_STATUS_ERROR(status)) { 8431 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 8432 " returned Error %d", __func__, status); 8433 wmi_buf_free(buf); 8434 } 8435 8436 return status; 8437 } 8438 8439 /** 8440 * send_get_link_speed_cmd_tlv() -send command to get linkspeed 8441 * @wmi_handle: wmi handle 8442 * @pLinkSpeed: link speed info 8443 * 8444 * Return: CDF status 8445 */ 8446 static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle, 8447 wmi_mac_addr peer_macaddr) 8448 { 8449 wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd; 8450 wmi_buf_t wmi_buf; 8451 uint32_t len; 8452 uint8_t *buf_ptr; 8453 8454 len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); 8455 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8456 if (!wmi_buf) { 8457 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 8458 return QDF_STATUS_E_NOMEM; 8459 } 8460 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 8461 8462 cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr; 8463 WMITLV_SET_HDR(&cmd->tlv_header, 8464 WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, 8465 WMITLV_GET_STRUCT_TLVLEN 8466 (wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); 8467 8468 /* Copy the peer macaddress to the wma buffer */ 8469 qdf_mem_copy(&cmd->peer_macaddr, 8470 &peer_macaddr, 8471 sizeof(peer_macaddr)); 8472 8473 8474 wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0); 8475 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8476 WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { 8477 WMI_LOGE("%s: failed to send link speed command", __func__); 8478 wmi_buf_free(wmi_buf); 8479 return QDF_STATUS_E_FAILURE; 8480 } 8481 return QDF_STATUS_SUCCESS; 8482 } 8483 8484 #ifdef WLAN_SUPPORT_GREEN_AP 8485 /** 8486 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 8487 * @wmi_handle: wmi handler 8488 * @egap_params: pointer to egap_params 8489 * 8490 * Return: 0 for success, otherwise appropriate error code 8491 */ 8492 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 8493 struct wlan_green_ap_egap_params *egap_params) 8494 { 8495 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 8496 wmi_buf_t buf; 8497 int32_t err; 8498 8499 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8500 if (!buf) { 8501 WMI_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); 8502 return QDF_STATUS_E_NOMEM; 8503 } 8504 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 8505 WMITLV_SET_HDR(&cmd->tlv_header, 8506 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 8507 WMITLV_GET_STRUCT_TLVLEN( 8508 wmi_ap_ps_egap_param_cmd_fixed_param)); 8509 8510 cmd->enable = egap_params->host_enable_egap; 8511 cmd->inactivity_time = egap_params->egap_inactivity_time; 8512 cmd->wait_time = egap_params->egap_wait_time; 8513 cmd->flags = egap_params->egap_feature_flags; 8514 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 8515 err = wmi_unified_cmd_send(wmi_handle, buf, 8516 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 8517 if (err) { 8518 WMI_LOGE("Failed to send ap_ps_egap cmd"); 8519 wmi_buf_free(buf); 8520 return QDF_STATUS_E_FAILURE; 8521 } 8522 8523 return QDF_STATUS_SUCCESS; 8524 } 8525 #endif 8526 8527 /** 8528 * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW 8529 * @wmi_handl: wmi handle 8530 * @cmd: Profiling command index 8531 * @value1: parameter1 value 8532 * @value2: parameter2 value 8533 * 8534 * Return: QDF_STATUS_SUCCESS for success else error code 8535 */ 8536 static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle, 8537 uint32_t cmd, uint32_t value1, uint32_t value2) 8538 { 8539 wmi_buf_t buf; 8540 int32_t len = 0; 8541 int ret; 8542 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8543 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8544 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8545 wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd; 8546 8547 switch (cmd) { 8548 case WMI_WLAN_PROFILE_TRIGGER_CMDID: 8549 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8550 buf = wmi_buf_alloc(wmi_handle, len); 8551 if (!buf) { 8552 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8553 return QDF_STATUS_E_NOMEM; 8554 } 8555 prof_trig_cmd = 8556 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8557 wmi_buf_data(buf); 8558 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8559 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8560 WMITLV_GET_STRUCT_TLVLEN 8561 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8562 prof_trig_cmd->enable = value1; 8563 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 8564 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8565 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8566 if (ret) { 8567 WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d", 8568 value1); 8569 wmi_buf_free(buf); 8570 return ret; 8571 } 8572 break; 8573 8574 case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID: 8575 len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param); 8576 buf = wmi_buf_alloc(wmi_handle, len); 8577 if (!buf) { 8578 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8579 return QDF_STATUS_E_NOMEM; 8580 } 8581 profile_getdata_cmd = 8582 (wmi_wlan_profile_get_prof_data_cmd_fixed_param *) 8583 wmi_buf_data(buf); 8584 WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header, 8585 WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, 8586 WMITLV_GET_STRUCT_TLVLEN 8587 (wmi_wlan_profile_get_prof_data_cmd_fixed_param)); 8588 wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, 8589 NO_SESSION, 0); 8590 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8591 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); 8592 if (ret) { 8593 WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d", 8594 value1, value2); 8595 wmi_buf_free(buf); 8596 return ret; 8597 } 8598 break; 8599 8600 case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID: 8601 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8602 buf = wmi_buf_alloc(wmi_handle, len); 8603 if (!buf) { 8604 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8605 return QDF_STATUS_E_NOMEM; 8606 } 8607 hist_intvl_cmd = 8608 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8609 wmi_buf_data(buf); 8610 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8611 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8612 WMITLV_GET_STRUCT_TLVLEN 8613 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8614 hist_intvl_cmd->profile_id = value1; 8615 hist_intvl_cmd->value = value2; 8616 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 8617 NO_SESSION, 0); 8618 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8619 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8620 if (ret) { 8621 WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d", 8622 value1, value2); 8623 wmi_buf_free(buf); 8624 return ret; 8625 } 8626 break; 8627 8628 case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID: 8629 len = 8630 sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8631 buf = wmi_buf_alloc(wmi_handle, len); 8632 if (!buf) { 8633 WMI_LOGP("%s: wmi_buf_alloc Failed", __func__); 8634 return QDF_STATUS_E_NOMEM; 8635 } 8636 profile_enable_cmd = 8637 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8638 wmi_buf_data(buf); 8639 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8640 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8641 WMITLV_GET_STRUCT_TLVLEN 8642 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8643 profile_enable_cmd->profile_id = value1; 8644 profile_enable_cmd->enable = value2; 8645 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 8646 NO_SESSION, 0); 8647 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8648 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8649 if (ret) { 8650 WMI_LOGE("enable cmd Failed for id %d value %d", 8651 value1, value2); 8652 wmi_buf_free(buf); 8653 return ret; 8654 } 8655 break; 8656 8657 default: 8658 WMI_LOGD("%s: invalid profiling command", __func__); 8659 break; 8660 } 8661 8662 return 0; 8663 } 8664 8665 static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle, 8666 struct wlm_latency_level_param *params) 8667 { 8668 wmi_wlm_config_cmd_fixed_param *cmd; 8669 wmi_buf_t buf; 8670 uint32_t len = sizeof(*cmd); 8671 static uint32_t ll[4] = {100, 60, 40, 20}; 8672 8673 buf = wmi_buf_alloc(wmi_handle, len); 8674 if (!buf) { 8675 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8676 return QDF_STATUS_E_NOMEM; 8677 } 8678 cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf); 8679 WMITLV_SET_HDR(&cmd->tlv_header, 8680 WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param, 8681 WMITLV_GET_STRUCT_TLVLEN 8682 (wmi_wlm_config_cmd_fixed_param)); 8683 cmd->vdev_id = params->vdev_id; 8684 cmd->latency_level = params->wlm_latency_level; 8685 cmd->ul_latency = ll[params->wlm_latency_level]; 8686 cmd->dl_latency = ll[params->wlm_latency_level]; 8687 cmd->flags = params->wlm_latency_flags; 8688 wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0); 8689 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8690 WMI_WLM_CONFIG_CMDID)) { 8691 WMI_LOGE("%s: Failed to send setting latency config command", 8692 __func__); 8693 wmi_buf_free(buf); 8694 return QDF_STATUS_E_FAILURE; 8695 } 8696 8697 return 0; 8698 } 8699 /** 8700 * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter 8701 * @wmi_handle: wmi handle 8702 * @vdev_id: vdev id 8703 * 8704 * Return: QDF_STATUS_SUCCESS for success or error code 8705 */ 8706 static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 8707 { 8708 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; 8709 wmi_buf_t buf; 8710 int32_t len = sizeof(*cmd); 8711 8712 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8713 buf = wmi_buf_alloc(wmi_handle, len); 8714 if (!buf) { 8715 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8716 return QDF_STATUS_E_NOMEM; 8717 } 8718 cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) 8719 wmi_buf_data(buf); 8720 WMITLV_SET_HDR(&cmd->tlv_header, 8721 WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, 8722 WMITLV_GET_STRUCT_TLVLEN 8723 (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); 8724 cmd->vdev_id = vdev_id; 8725 cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; 8726 wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0); 8727 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8728 WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { 8729 WMI_LOGP("%s: Failed to send NAT keepalive enable command", 8730 __func__); 8731 wmi_buf_free(buf); 8732 return QDF_STATUS_E_FAILURE; 8733 } 8734 8735 return 0; 8736 } 8737 8738 /** 8739 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 8740 * @wmi_handle: wmi handle 8741 * @vdev_id: vdev id 8742 * 8743 * Return: QDF_STATUS_SUCCESS for success or error code 8744 */ 8745 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 8746 uint8_t vdev_id) 8747 { 8748 wmi_csa_offload_enable_cmd_fixed_param *cmd; 8749 wmi_buf_t buf; 8750 int32_t len = sizeof(*cmd); 8751 8752 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 8753 buf = wmi_buf_alloc(wmi_handle, len); 8754 if (!buf) { 8755 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 8756 return QDF_STATUS_E_NOMEM; 8757 } 8758 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 8759 WMITLV_SET_HDR(&cmd->tlv_header, 8760 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 8761 WMITLV_GET_STRUCT_TLVLEN 8762 (wmi_csa_offload_enable_cmd_fixed_param)); 8763 cmd->vdev_id = vdev_id; 8764 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 8765 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 8766 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8767 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 8768 WMI_LOGP("%s: Failed to send CSA offload enable command", 8769 __func__); 8770 wmi_buf_free(buf); 8771 return QDF_STATUS_E_FAILURE; 8772 } 8773 8774 return 0; 8775 } 8776 8777 #ifdef WLAN_FEATURE_CIF_CFR 8778 /** 8779 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 8780 * @wmi_handle: wmi handle 8781 * @data_len: len of dma cfg req 8782 * @data: dma cfg req 8783 * 8784 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8785 */ 8786 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8787 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 8788 { 8789 wmi_buf_t buf; 8790 uint8_t *cmd; 8791 QDF_STATUS ret; 8792 8793 WMITLV_SET_HDR(cfg, 8794 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 8795 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 8796 8797 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 8798 if (!buf) { 8799 WMI_LOGE(FL("wmi_buf_alloc failed")); 8800 return QDF_STATUS_E_FAILURE; 8801 } 8802 8803 cmd = (uint8_t *) wmi_buf_data(buf); 8804 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 8805 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 8806 sizeof(*cfg)); 8807 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 8808 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 8809 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 8810 if (QDF_IS_STATUS_ERROR(ret)) { 8811 WMI_LOGE(FL(":wmi cmd send failed")); 8812 wmi_buf_free(buf); 8813 } 8814 8815 return ret; 8816 } 8817 #endif 8818 8819 /** 8820 * send_dbr_cfg_cmd_tlv() - configure DMA rings for Direct Buf RX 8821 * @wmi_handle: wmi handle 8822 * @data_len: len of dma cfg req 8823 * @data: dma cfg req 8824 * 8825 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8826 */ 8827 static QDF_STATUS send_dbr_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8828 struct direct_buf_rx_cfg_req *cfg) 8829 { 8830 wmi_buf_t buf; 8831 wmi_dma_ring_cfg_req_fixed_param *cmd; 8832 QDF_STATUS ret; 8833 int32_t len = sizeof(*cmd); 8834 8835 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8836 if (!buf) { 8837 WMI_LOGE(FL("wmi_buf_alloc failed")); 8838 return QDF_STATUS_E_FAILURE; 8839 } 8840 8841 cmd = (wmi_dma_ring_cfg_req_fixed_param *)wmi_buf_data(buf); 8842 8843 WMITLV_SET_HDR(&cmd->tlv_header, 8844 WMITLV_TAG_STRUC_wmi_dma_ring_cfg_req_fixed_param, 8845 WMITLV_GET_STRUCT_TLVLEN(wmi_dma_ring_cfg_req_fixed_param)); 8846 8847 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8848 cfg->pdev_id); 8849 cmd->mod_id = cfg->mod_id; 8850 cmd->base_paddr_lo = cfg->base_paddr_lo; 8851 cmd->base_paddr_hi = cfg->base_paddr_hi; 8852 cmd->head_idx_paddr_lo = cfg->head_idx_paddr_lo; 8853 cmd->head_idx_paddr_hi = cfg->head_idx_paddr_hi; 8854 cmd->tail_idx_paddr_lo = cfg->tail_idx_paddr_lo; 8855 cmd->tail_idx_paddr_hi = cfg->tail_idx_paddr_hi; 8856 cmd->num_elems = cfg->num_elems; 8857 cmd->buf_size = cfg->buf_size; 8858 cmd->num_resp_per_event = cfg->num_resp_per_event; 8859 cmd->event_timeout_ms = cfg->event_timeout_ms; 8860 8861 WMI_LOGD("%s: wmi_dma_ring_cfg_req_fixed_param pdev id %d mod id %d" 8862 "base paddr lo %x base paddr hi %x head idx paddr lo %x" 8863 "head idx paddr hi %x tail idx paddr lo %x" 8864 "tail idx addr hi %x num elems %d buf size %d num resp %d" 8865 "event timeout %d\n", __func__, cmd->pdev_id, 8866 cmd->mod_id, cmd->base_paddr_lo, cmd->base_paddr_hi, 8867 cmd->head_idx_paddr_lo, cmd->head_idx_paddr_hi, 8868 cmd->tail_idx_paddr_lo, cmd->tail_idx_paddr_hi, 8869 cmd->num_elems, cmd->buf_size, cmd->num_resp_per_event, 8870 cmd->event_timeout_ms); 8871 wmi_mtrace(WMI_PDEV_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 8872 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8873 WMI_PDEV_DMA_RING_CFG_REQ_CMDID); 8874 if (QDF_IS_STATUS_ERROR(ret)) { 8875 WMI_LOGE(FL(":wmi cmd send failed")); 8876 wmi_buf_free(buf); 8877 } 8878 8879 return ret; 8880 } 8881 8882 /** 8883 * send_start_11d_scan_cmd_tlv() - start 11d scan request 8884 * @wmi_handle: wmi handle 8885 * @start_11d_scan: 11d scan start request parameters 8886 * 8887 * This function request FW to start 11d scan. 8888 * 8889 * Return: QDF status 8890 */ 8891 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8892 struct reg_start_11d_scan_req *start_11d_scan) 8893 { 8894 wmi_11d_scan_start_cmd_fixed_param *cmd; 8895 int32_t len; 8896 wmi_buf_t buf; 8897 int ret; 8898 8899 len = sizeof(*cmd); 8900 buf = wmi_buf_alloc(wmi_handle, len); 8901 if (!buf) { 8902 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8903 return QDF_STATUS_E_NOMEM; 8904 } 8905 8906 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 8907 8908 WMITLV_SET_HDR(&cmd->tlv_header, 8909 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 8910 WMITLV_GET_STRUCT_TLVLEN 8911 (wmi_11d_scan_start_cmd_fixed_param)); 8912 8913 cmd->vdev_id = start_11d_scan->vdev_id; 8914 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 8915 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 8916 8917 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 8918 8919 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 8920 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8921 WMI_11D_SCAN_START_CMDID); 8922 if (ret) { 8923 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 8924 wmi_buf_free(buf); 8925 return QDF_STATUS_E_FAILURE; 8926 } 8927 8928 return QDF_STATUS_SUCCESS; 8929 } 8930 8931 /** 8932 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 8933 * @wmi_handle: wmi handle 8934 * @start_11d_scan: 11d scan stop request parameters 8935 * 8936 * This function request FW to stop 11d scan. 8937 * 8938 * Return: QDF status 8939 */ 8940 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 8941 struct reg_stop_11d_scan_req *stop_11d_scan) 8942 { 8943 wmi_11d_scan_stop_cmd_fixed_param *cmd; 8944 int32_t len; 8945 wmi_buf_t buf; 8946 int ret; 8947 8948 len = sizeof(*cmd); 8949 buf = wmi_buf_alloc(wmi_handle, len); 8950 if (!buf) { 8951 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 8952 return QDF_STATUS_E_NOMEM; 8953 } 8954 8955 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 8956 8957 WMITLV_SET_HDR(&cmd->tlv_header, 8958 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 8959 WMITLV_GET_STRUCT_TLVLEN 8960 (wmi_11d_scan_stop_cmd_fixed_param)); 8961 8962 cmd->vdev_id = stop_11d_scan->vdev_id; 8963 8964 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 8965 8966 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 8967 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8968 WMI_11D_SCAN_STOP_CMDID); 8969 if (ret) { 8970 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 8971 wmi_buf_free(buf); 8972 return QDF_STATUS_E_FAILURE; 8973 } 8974 8975 return QDF_STATUS_SUCCESS; 8976 } 8977 8978 /** 8979 * send_start_oem_data_cmd_tlv() - start OEM data request to target 8980 * @wmi_handle: wmi handle 8981 * @startOemDataReq: start request params 8982 * 8983 * Return: CDF status 8984 */ 8985 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 8986 uint32_t data_len, 8987 uint8_t *data) 8988 { 8989 wmi_buf_t buf; 8990 uint8_t *cmd; 8991 QDF_STATUS ret; 8992 8993 buf = wmi_buf_alloc(wmi_handle, 8994 (data_len + WMI_TLV_HDR_SIZE)); 8995 if (!buf) { 8996 WMI_LOGE(FL("wmi_buf_alloc failed")); 8997 return QDF_STATUS_E_FAILURE; 8998 } 8999 9000 cmd = (uint8_t *) wmi_buf_data(buf); 9001 9002 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 9003 cmd += WMI_TLV_HDR_SIZE; 9004 qdf_mem_copy(cmd, data, 9005 data_len); 9006 9007 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 9008 data_len); 9009 9010 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 9011 ret = wmi_unified_cmd_send(wmi_handle, buf, 9012 (data_len + 9013 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 9014 9015 if (QDF_IS_STATUS_ERROR(ret)) { 9016 WMI_LOGE(FL(":wmi cmd send failed")); 9017 wmi_buf_free(buf); 9018 } 9019 9020 return ret; 9021 } 9022 9023 /** 9024 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 9025 * @wmi_handle: wmi handle 9026 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 9027 * 9028 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 9029 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 9030 * to firmware based on phyerr filtering 9031 * offload status. 9032 * 9033 * Return: 1 success, 0 failure 9034 */ 9035 static QDF_STATUS 9036 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9037 bool dfs_phyerr_filter_offload) 9038 { 9039 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 9040 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 9041 wmi_buf_t buf; 9042 uint16_t len; 9043 QDF_STATUS ret; 9044 9045 9046 if (false == dfs_phyerr_filter_offload) { 9047 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 9048 __func__); 9049 len = sizeof(*disable_phyerr_offload_cmd); 9050 buf = wmi_buf_alloc(wmi_handle, len); 9051 if (!buf) { 9052 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9053 return 0; 9054 } 9055 disable_phyerr_offload_cmd = 9056 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 9057 wmi_buf_data(buf); 9058 9059 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 9060 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 9061 WMITLV_GET_STRUCT_TLVLEN 9062 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 9063 9064 /* 9065 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 9066 * to the firmware to disable the phyerror 9067 * filtering offload. 9068 */ 9069 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 9070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9071 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 9072 if (QDF_IS_STATUS_ERROR(ret)) { 9073 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 9074 __func__, ret); 9075 wmi_buf_free(buf); 9076 return QDF_STATUS_E_FAILURE; 9077 } 9078 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 9079 __func__); 9080 } else { 9081 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 9082 __func__); 9083 9084 len = sizeof(*enable_phyerr_offload_cmd); 9085 buf = wmi_buf_alloc(wmi_handle, len); 9086 if (!buf) { 9087 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9088 return QDF_STATUS_E_FAILURE; 9089 } 9090 9091 enable_phyerr_offload_cmd = 9092 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 9093 wmi_buf_data(buf); 9094 9095 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 9096 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 9097 WMITLV_GET_STRUCT_TLVLEN 9098 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 9099 9100 /* 9101 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 9102 * to the firmware to enable the phyerror 9103 * filtering offload. 9104 */ 9105 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 9106 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9107 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 9108 9109 if (QDF_IS_STATUS_ERROR(ret)) { 9110 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 9111 __func__, ret); 9112 wmi_buf_free(buf); 9113 return QDF_STATUS_E_FAILURE; 9114 } 9115 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 9116 __func__); 9117 } 9118 9119 return QDF_STATUS_SUCCESS; 9120 } 9121 9122 /** 9123 * send_wow_timer_pattern_cmd_tlv() - set timer pattern tlv, so that firmware 9124 * will wake up host after specified time is elapsed 9125 * @wmi_handle: wmi handle 9126 * @vdev_id: vdev id 9127 * @cookie: value to identify reason why host set up wake call. 9128 * @time: time in ms 9129 * 9130 * Return: QDF status 9131 */ 9132 static QDF_STATUS send_wow_timer_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9133 uint8_t vdev_id, uint32_t cookie, uint32_t time) 9134 { 9135 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 9136 wmi_buf_t buf; 9137 uint8_t *buf_ptr; 9138 int32_t len; 9139 int ret; 9140 9141 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 9142 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_BITMAP_PATTERN_T) + 9143 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 9144 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 9145 WMI_TLV_HDR_SIZE + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 9146 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 9147 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 9148 9149 buf = wmi_buf_alloc(wmi_handle, len); 9150 if (!buf) { 9151 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9152 return QDF_STATUS_E_NOMEM; 9153 } 9154 9155 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9156 buf_ptr = (uint8_t *) cmd; 9157 9158 WMITLV_SET_HDR(&cmd->tlv_header, 9159 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 9160 WMITLV_GET_STRUCT_TLVLEN 9161 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 9162 cmd->vdev_id = vdev_id; 9163 cmd->pattern_id = cookie, 9164 cmd->pattern_type = WOW_TIMER_PATTERN; 9165 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 9166 9167 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 9168 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9169 buf_ptr += WMI_TLV_HDR_SIZE; 9170 9171 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 9172 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9173 buf_ptr += WMI_TLV_HDR_SIZE; 9174 9175 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 9176 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9177 buf_ptr += WMI_TLV_HDR_SIZE; 9178 9179 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 9180 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9181 buf_ptr += WMI_TLV_HDR_SIZE; 9182 9183 /* Fill TLV for pattern_info_timeout, and time value */ 9184 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9185 buf_ptr += WMI_TLV_HDR_SIZE; 9186 *((uint32_t *) buf_ptr) = time; 9187 buf_ptr += sizeof(uint32_t); 9188 9189 /* Fill TLV for ra_ratelimit_interval. with dummy 0 value */ 9190 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 9191 buf_ptr += WMI_TLV_HDR_SIZE; 9192 *((uint32_t *) buf_ptr) = 0; 9193 9194 WMI_LOGD("%s: send wake timer pattern with time[%d] to fw vdev = %d", 9195 __func__, time, vdev_id); 9196 9197 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 9198 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9199 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 9200 if (ret) { 9201 WMI_LOGE("%s: Failed to send wake timer pattern to fw", 9202 __func__); 9203 wmi_buf_free(buf); 9204 return QDF_STATUS_E_FAILURE; 9205 } 9206 9207 return QDF_STATUS_SUCCESS; 9208 } 9209 9210 #if !defined(REMOVE_PKT_LOG) 9211 /** 9212 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 9213 * @wmi_handle: wmi handle 9214 * @pktlog_event: pktlog event 9215 * @cmd_id: pktlog cmd id 9216 * 9217 * Return: CDF status 9218 */ 9219 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 9220 WMI_PKTLOG_EVENT pktlog_event, 9221 WMI_CMD_ID cmd_id, uint8_t user_triggered) 9222 { 9223 WMI_PKTLOG_EVENT PKTLOG_EVENT; 9224 WMI_CMD_ID CMD_ID; 9225 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 9226 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 9227 int len = 0; 9228 wmi_buf_t buf; 9229 9230 PKTLOG_EVENT = pktlog_event; 9231 CMD_ID = cmd_id; 9232 9233 switch (CMD_ID) { 9234 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 9235 len = sizeof(*cmd); 9236 buf = wmi_buf_alloc(wmi_handle, len); 9237 if (!buf) { 9238 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9239 return QDF_STATUS_E_NOMEM; 9240 } 9241 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 9242 wmi_buf_data(buf); 9243 WMITLV_SET_HDR(&cmd->tlv_header, 9244 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 9245 WMITLV_GET_STRUCT_TLVLEN 9246 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 9247 cmd->evlist = PKTLOG_EVENT; 9248 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 9249 : WMI_PKTLOG_ENABLE_AUTO; 9250 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9251 WMI_HOST_PDEV_ID_SOC); 9252 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 9253 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9254 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 9255 WMI_LOGE("failed to send pktlog enable cmdid"); 9256 goto wmi_send_failed; 9257 } 9258 break; 9259 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 9260 len = sizeof(*disable_cmd); 9261 buf = wmi_buf_alloc(wmi_handle, len); 9262 if (!buf) { 9263 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9264 return QDF_STATUS_E_NOMEM; 9265 } 9266 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 9267 wmi_buf_data(buf); 9268 WMITLV_SET_HDR(&disable_cmd->tlv_header, 9269 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 9270 WMITLV_GET_STRUCT_TLVLEN 9271 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 9272 disable_cmd->pdev_id = 9273 wmi_handle->ops->convert_pdev_id_host_to_target( 9274 WMI_HOST_PDEV_ID_SOC); 9275 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 9276 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9277 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 9278 WMI_LOGE("failed to send pktlog disable cmdid"); 9279 goto wmi_send_failed; 9280 } 9281 break; 9282 default: 9283 WMI_LOGD("%s: invalid PKTLOG command", __func__); 9284 break; 9285 } 9286 9287 return QDF_STATUS_SUCCESS; 9288 9289 wmi_send_failed: 9290 wmi_buf_free(buf); 9291 return QDF_STATUS_E_FAILURE; 9292 } 9293 #endif /* REMOVE_PKT_LOG */ 9294 9295 /** 9296 * send_wow_delete_pattern_cmd_tlv() - delete wow pattern in target 9297 * @wmi_handle: wmi handle 9298 * @ptrn_id: pattern id 9299 * @vdev_id: vdev id 9300 * 9301 * Return: CDF status 9302 */ 9303 static QDF_STATUS send_wow_delete_pattern_cmd_tlv(wmi_unified_t wmi_handle, 9304 uint8_t ptrn_id, uint8_t vdev_id) 9305 { 9306 WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; 9307 wmi_buf_t buf; 9308 int32_t len; 9309 int ret; 9310 9311 len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); 9312 9313 9314 buf = wmi_buf_alloc(wmi_handle, len); 9315 if (!buf) { 9316 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9317 return QDF_STATUS_E_NOMEM; 9318 } 9319 9320 cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 9321 9322 WMITLV_SET_HDR(&cmd->tlv_header, 9323 WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, 9324 WMITLV_GET_STRUCT_TLVLEN( 9325 WMI_WOW_DEL_PATTERN_CMD_fixed_param)); 9326 cmd->vdev_id = vdev_id; 9327 cmd->pattern_id = ptrn_id; 9328 cmd->pattern_type = WOW_BITMAP_PATTERN; 9329 9330 WMI_LOGI("Deleting pattern id: %d vdev id %d in fw", 9331 cmd->pattern_id, vdev_id); 9332 9333 wmi_mtrace(WMI_WOW_DEL_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 9334 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9335 WMI_WOW_DEL_WAKE_PATTERN_CMDID); 9336 if (ret) { 9337 WMI_LOGE("%s: Failed to delete wow ptrn from fw", __func__); 9338 wmi_buf_free(buf); 9339 return QDF_STATUS_E_FAILURE; 9340 } 9341 9342 return QDF_STATUS_SUCCESS; 9343 } 9344 9345 /** 9346 * send_host_wakeup_ind_to_fw_cmd_tlv() - send wakeup ind to fw 9347 * @wmi_handle: wmi handle 9348 * 9349 * Sends host wakeup indication to FW. On receiving this indication, 9350 * FW will come out of WOW. 9351 * 9352 * Return: CDF status 9353 */ 9354 static QDF_STATUS send_host_wakeup_ind_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9355 { 9356 wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; 9357 wmi_buf_t buf; 9358 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9359 int32_t len; 9360 int ret; 9361 9362 len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); 9363 9364 buf = wmi_buf_alloc(wmi_handle, len); 9365 if (!buf) { 9366 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9367 return QDF_STATUS_E_NOMEM; 9368 } 9369 9370 cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) 9371 wmi_buf_data(buf); 9372 WMITLV_SET_HDR(&cmd->tlv_header, 9373 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, 9374 WMITLV_GET_STRUCT_TLVLEN 9375 (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); 9376 9377 9378 wmi_mtrace(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, NO_SESSION, 0); 9379 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9380 WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); 9381 if (ret) { 9382 WMI_LOGE("Failed to send host wakeup indication to fw"); 9383 wmi_buf_free(buf); 9384 return QDF_STATUS_E_FAILURE; 9385 } 9386 9387 return qdf_status; 9388 } 9389 9390 /** 9391 * send_del_ts_cmd_tlv() - send DELTS request to fw 9392 * @wmi_handle: wmi handle 9393 * @msg: delts params 9394 * 9395 * Return: CDF status 9396 */ 9397 static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 9398 uint8_t ac) 9399 { 9400 wmi_vdev_wmm_delts_cmd_fixed_param *cmd; 9401 wmi_buf_t buf; 9402 int32_t len = sizeof(*cmd); 9403 9404 buf = wmi_buf_alloc(wmi_handle, len); 9405 if (!buf) { 9406 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9407 return QDF_STATUS_E_NOMEM; 9408 } 9409 cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); 9410 WMITLV_SET_HDR(&cmd->tlv_header, 9411 WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, 9412 WMITLV_GET_STRUCT_TLVLEN 9413 (wmi_vdev_wmm_delts_cmd_fixed_param)); 9414 cmd->vdev_id = vdev_id; 9415 cmd->ac = ac; 9416 9417 WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d", 9418 cmd->vdev_id, cmd->ac, __func__, __LINE__); 9419 wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0); 9420 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9421 WMI_VDEV_WMM_DELTS_CMDID)) { 9422 WMI_LOGP("%s: Failed to send vdev DELTS command", __func__); 9423 wmi_buf_free(buf); 9424 return QDF_STATUS_E_FAILURE; 9425 } 9426 9427 return QDF_STATUS_SUCCESS; 9428 } 9429 9430 /** 9431 * send_aggr_qos_cmd_tlv() - send aggr qos request to fw 9432 * @wmi_handle: handle to wmi 9433 * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests. 9434 * 9435 * A function to handle WMI_AGGR_QOS_REQ. This will send out 9436 * ADD_TS requestes to firmware in loop for all the ACs with 9437 * active flow. 9438 * 9439 * Return: CDF status 9440 */ 9441 static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle, 9442 struct aggr_add_ts_param *aggr_qos_rsp_msg) 9443 { 9444 int i = 0; 9445 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9446 wmi_buf_t buf; 9447 int32_t len = sizeof(*cmd); 9448 9449 for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) { 9450 /* if flow in this AC is active */ 9451 if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) { 9452 /* 9453 * as per implementation of wma_add_ts_req() we 9454 * are not waiting any response from firmware so 9455 * apart from sending ADDTS to firmware just send 9456 * success to upper layers 9457 */ 9458 aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS; 9459 9460 buf = wmi_buf_alloc(wmi_handle, len); 9461 if (!buf) { 9462 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9463 return QDF_STATUS_E_NOMEM; 9464 } 9465 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) 9466 wmi_buf_data(buf); 9467 WMITLV_SET_HDR(&cmd->tlv_header, 9468 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9469 WMITLV_GET_STRUCT_TLVLEN 9470 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9471 cmd->vdev_id = aggr_qos_rsp_msg->vdev_id; 9472 cmd->ac = 9473 WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo. 9474 traffic.userPrio); 9475 cmd->medium_time_us = 9476 aggr_qos_rsp_msg->tspec[i].mediumTime * 32; 9477 cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; 9478 WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", 9479 __func__, __LINE__, cmd->vdev_id, cmd->ac, 9480 cmd->medium_time_us, cmd->downgrade_type); 9481 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0); 9482 if (wmi_unified_cmd_send 9483 (wmi_handle, buf, len, 9484 WMI_VDEV_WMM_ADDTS_CMDID)) { 9485 WMI_LOGP("%s: Failed to send vdev ADDTS command", 9486 __func__); 9487 aggr_qos_rsp_msg->status[i] = 9488 QDF_STATUS_E_FAILURE; 9489 wmi_buf_free(buf); 9490 return QDF_STATUS_E_FAILURE; 9491 } 9492 } 9493 } 9494 9495 return QDF_STATUS_SUCCESS; 9496 } 9497 9498 /** 9499 * send_add_ts_cmd_tlv() - send ADDTS request to fw 9500 * @wmi_handle: wmi handle 9501 * @msg: ADDTS params 9502 * 9503 * Return: CDF status 9504 */ 9505 static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle, 9506 struct add_ts_param *msg) 9507 { 9508 wmi_vdev_wmm_addts_cmd_fixed_param *cmd; 9509 wmi_buf_t buf; 9510 int32_t len = sizeof(*cmd); 9511 9512 msg->status = QDF_STATUS_SUCCESS; 9513 9514 buf = wmi_buf_alloc(wmi_handle, len); 9515 if (!buf) { 9516 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 9517 return QDF_STATUS_E_NOMEM; 9518 } 9519 cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); 9520 WMITLV_SET_HDR(&cmd->tlv_header, 9521 WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, 9522 WMITLV_GET_STRUCT_TLVLEN 9523 (wmi_vdev_wmm_addts_cmd_fixed_param)); 9524 cmd->vdev_id = msg->sme_session_id; 9525 cmd->ac = msg->tspec.tsinfo.traffic.userPrio; 9526 cmd->medium_time_us = msg->tspec.mediumTime * 32; 9527 cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; 9528 WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", 9529 cmd->vdev_id, cmd->ac, cmd->medium_time_us, 9530 cmd->downgrade_type, __func__, __LINE__); 9531 wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0); 9532 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9533 WMI_VDEV_WMM_ADDTS_CMDID)) { 9534 WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__); 9535 msg->status = QDF_STATUS_E_FAILURE; 9536 wmi_buf_free(buf); 9537 return QDF_STATUS_E_FAILURE; 9538 } 9539 9540 return QDF_STATUS_SUCCESS; 9541 } 9542 9543 /** 9544 * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn 9545 * @wmi_handle: wmi handle 9546 * @pAddPeriodicTxPtrnParams: tx ptrn params 9547 * 9548 * Retrun: CDF status 9549 */ 9550 static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9551 struct periodic_tx_pattern * 9552 pAddPeriodicTxPtrnParams, 9553 uint8_t vdev_id) 9554 { 9555 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9556 wmi_buf_t wmi_buf; 9557 uint32_t len; 9558 uint8_t *buf_ptr; 9559 uint32_t ptrn_len, ptrn_len_aligned; 9560 int j; 9561 9562 ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; 9563 ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); 9564 len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + 9565 WMI_TLV_HDR_SIZE + ptrn_len_aligned; 9566 9567 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9568 if (!wmi_buf) { 9569 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9570 return QDF_STATUS_E_NOMEM; 9571 } 9572 9573 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 9574 9575 cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr; 9576 WMITLV_SET_HDR(&cmd->tlv_header, 9577 WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9578 WMITLV_GET_STRUCT_TLVLEN 9579 (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9580 9581 /* Pass the pattern id to delete for the corresponding vdev id */ 9582 cmd->vdev_id = vdev_id; 9583 cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; 9584 cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; 9585 cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; 9586 9587 /* Pattern info */ 9588 buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9589 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); 9590 buf_ptr += WMI_TLV_HDR_SIZE; 9591 qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len); 9592 for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) 9593 WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); 9594 9595 WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d", 9596 __func__, cmd->pattern_id, cmd->vdev_id); 9597 9598 wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0); 9599 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9600 WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9601 WMI_LOGE("%s: failed to add pattern set state command", 9602 __func__); 9603 wmi_buf_free(wmi_buf); 9604 return QDF_STATUS_E_FAILURE; 9605 } 9606 return QDF_STATUS_SUCCESS; 9607 } 9608 9609 /** 9610 * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn 9611 * @wmi_handle: wmi handle 9612 * @vdev_id: vdev id 9613 * @pattern_id: pattern id 9614 * 9615 * Retrun: CDF status 9616 */ 9617 static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle, 9618 uint8_t vdev_id, 9619 uint8_t pattern_id) 9620 { 9621 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd; 9622 wmi_buf_t wmi_buf; 9623 uint32_t len = 9624 sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); 9625 9626 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9627 if (!wmi_buf) { 9628 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 9629 return QDF_STATUS_E_NOMEM; 9630 } 9631 9632 cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) 9633 wmi_buf_data(wmi_buf); 9634 WMITLV_SET_HDR(&cmd->tlv_header, 9635 WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, 9636 WMITLV_GET_STRUCT_TLVLEN 9637 (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); 9638 9639 /* Pass the pattern id to delete for the corresponding vdev id */ 9640 cmd->vdev_id = vdev_id; 9641 cmd->pattern_id = pattern_id; 9642 WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d", 9643 __func__, cmd->pattern_id, cmd->vdev_id); 9644 9645 wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0); 9646 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9647 WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { 9648 WMI_LOGE("%s: failed to send del pattern command", __func__); 9649 wmi_buf_free(wmi_buf); 9650 return QDF_STATUS_E_FAILURE; 9651 } 9652 return QDF_STATUS_SUCCESS; 9653 } 9654 9655 /** 9656 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 9657 * @wmi_handle: wmi handle 9658 * @preq: stats ext params 9659 * 9660 * Return: CDF status 9661 */ 9662 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 9663 struct stats_ext_params *preq) 9664 { 9665 QDF_STATUS ret; 9666 wmi_req_stats_ext_cmd_fixed_param *cmd; 9667 wmi_buf_t buf; 9668 size_t len; 9669 uint8_t *buf_ptr; 9670 9671 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 9672 9673 buf = wmi_buf_alloc(wmi_handle, len); 9674 if (!buf) { 9675 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9676 return QDF_STATUS_E_NOMEM; 9677 } 9678 9679 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9680 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 9681 9682 WMITLV_SET_HDR(&cmd->tlv_header, 9683 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 9684 WMITLV_GET_STRUCT_TLVLEN 9685 (wmi_req_stats_ext_cmd_fixed_param)); 9686 cmd->vdev_id = preq->vdev_id; 9687 cmd->data_len = preq->request_data_len; 9688 9689 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 9690 __func__, preq->request_data_len, preq->vdev_id); 9691 9692 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 9693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 9694 9695 buf_ptr += WMI_TLV_HDR_SIZE; 9696 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 9697 9698 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 9699 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9700 WMI_REQUEST_STATS_EXT_CMDID); 9701 if (QDF_IS_STATUS_ERROR(ret)) { 9702 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 9703 ret); 9704 wmi_buf_free(buf); 9705 } 9706 9707 return ret; 9708 } 9709 9710 /** 9711 * send_enable_ext_wow_cmd_tlv() - enable ext wow in fw 9712 * @wmi_handle: wmi handle 9713 * @params: ext wow params 9714 * 9715 * Return:0 for success or error code 9716 */ 9717 static QDF_STATUS send_enable_ext_wow_cmd_tlv(wmi_unified_t wmi_handle, 9718 struct ext_wow_params *params) 9719 { 9720 wmi_extwow_enable_cmd_fixed_param *cmd; 9721 wmi_buf_t buf; 9722 int32_t len; 9723 int ret; 9724 9725 len = sizeof(wmi_extwow_enable_cmd_fixed_param); 9726 buf = wmi_buf_alloc(wmi_handle, len); 9727 if (!buf) { 9728 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9729 return QDF_STATUS_E_NOMEM; 9730 } 9731 9732 cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); 9733 9734 WMITLV_SET_HDR(&cmd->tlv_header, 9735 WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, 9736 WMITLV_GET_STRUCT_TLVLEN 9737 (wmi_extwow_enable_cmd_fixed_param)); 9738 9739 cmd->vdev_id = params->vdev_id; 9740 cmd->type = params->type; 9741 cmd->wakeup_pin_num = params->wakeup_pin_num; 9742 9743 WMI_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", 9744 __func__, cmd->vdev_id, cmd->type, cmd->wakeup_pin_num); 9745 9746 wmi_mtrace(WMI_EXTWOW_ENABLE_CMDID, cmd->vdev_id, 0); 9747 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9748 WMI_EXTWOW_ENABLE_CMDID); 9749 if (ret) { 9750 WMI_LOGE("%s: Failed to set EXTWOW Enable", __func__); 9751 wmi_buf_free(buf); 9752 return QDF_STATUS_E_FAILURE; 9753 } 9754 9755 return QDF_STATUS_SUCCESS; 9756 9757 } 9758 9759 /** 9760 * send_app_type1_params_in_fw_cmd_tlv() - set app type1 params in fw 9761 * @wmi_handle: wmi handle 9762 * @app_type1_params: app type1 params 9763 * 9764 * Return: CDF status 9765 */ 9766 static QDF_STATUS send_app_type1_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9767 struct app_type1_params *app_type1_params) 9768 { 9769 wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; 9770 wmi_buf_t buf; 9771 int32_t len; 9772 int ret; 9773 9774 len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); 9775 buf = wmi_buf_alloc(wmi_handle, len); 9776 if (!buf) { 9777 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9778 return QDF_STATUS_E_NOMEM; 9779 } 9780 9781 cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) 9782 wmi_buf_data(buf); 9783 9784 WMITLV_SET_HDR(&cmd->tlv_header, 9785 WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, 9786 WMITLV_GET_STRUCT_TLVLEN 9787 (wmi_extwow_set_app_type1_params_cmd_fixed_param)); 9788 9789 cmd->vdev_id = app_type1_params->vdev_id; 9790 WMI_CHAR_ARRAY_TO_MAC_ADDR(app_type1_params->wakee_mac_addr.bytes, 9791 &cmd->wakee_mac); 9792 qdf_mem_copy(cmd->ident, app_type1_params->identification_id, 8); 9793 cmd->ident_len = app_type1_params->id_length; 9794 qdf_mem_copy(cmd->passwd, app_type1_params->password, 16); 9795 cmd->passwd_len = app_type1_params->pass_length; 9796 9797 WMI_LOGD("%s: vdev_id %d wakee_mac_addr %pM " 9798 "identification_id %.8s id_length %u " 9799 "password %.16s pass_length %u", 9800 __func__, cmd->vdev_id, app_type1_params->wakee_mac_addr.bytes, 9801 cmd->ident, cmd->ident_len, cmd->passwd, cmd->passwd_len); 9802 9803 wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, cmd->vdev_id, 0); 9804 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9805 WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); 9806 if (ret) { 9807 WMI_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); 9808 wmi_buf_free(buf); 9809 return QDF_STATUS_E_FAILURE; 9810 } 9811 9812 return QDF_STATUS_SUCCESS; 9813 } 9814 9815 /** 9816 * send_set_app_type2_params_in_fw_cmd_tlv() - set app type2 params in fw 9817 * @wmi_handle: wmi handle 9818 * @appType2Params: app type2 params 9819 * 9820 * Return: CDF status 9821 */ 9822 static QDF_STATUS send_set_app_type2_params_in_fw_cmd_tlv(wmi_unified_t wmi_handle, 9823 struct app_type2_params *appType2Params) 9824 { 9825 wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; 9826 wmi_buf_t buf; 9827 int32_t len; 9828 int ret; 9829 9830 len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); 9831 buf = wmi_buf_alloc(wmi_handle, len); 9832 if (!buf) { 9833 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 9834 return QDF_STATUS_E_NOMEM; 9835 } 9836 9837 cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) 9838 wmi_buf_data(buf); 9839 9840 WMITLV_SET_HDR(&cmd->tlv_header, 9841 WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, 9842 WMITLV_GET_STRUCT_TLVLEN 9843 (wmi_extwow_set_app_type2_params_cmd_fixed_param)); 9844 9845 cmd->vdev_id = appType2Params->vdev_id; 9846 9847 qdf_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); 9848 cmd->rc4_key_len = appType2Params->rc4_key_len; 9849 9850 cmd->ip_id = appType2Params->ip_id; 9851 cmd->ip_device_ip = appType2Params->ip_device_ip; 9852 cmd->ip_server_ip = appType2Params->ip_server_ip; 9853 9854 cmd->tcp_src_port = appType2Params->tcp_src_port; 9855 cmd->tcp_dst_port = appType2Params->tcp_dst_port; 9856 cmd->tcp_seq = appType2Params->tcp_seq; 9857 cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; 9858 9859 cmd->keepalive_init = appType2Params->keepalive_init; 9860 cmd->keepalive_min = appType2Params->keepalive_min; 9861 cmd->keepalive_max = appType2Params->keepalive_max; 9862 cmd->keepalive_inc = appType2Params->keepalive_inc; 9863 9864 WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac.bytes, 9865 &cmd->gateway_mac); 9866 cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; 9867 cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; 9868 9869 WMI_LOGD("%s: vdev_id %d gateway_mac %pM " 9870 "rc4_key %.16s rc4_key_len %u " 9871 "ip_id %x ip_device_ip %x ip_server_ip %x " 9872 "tcp_src_port %u tcp_dst_port %u tcp_seq %u " 9873 "tcp_ack_seq %u keepalive_init %u keepalive_min %u " 9874 "keepalive_max %u keepalive_inc %u " 9875 "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", 9876 __func__, cmd->vdev_id, appType2Params->gateway_mac.bytes, 9877 cmd->rc4_key, cmd->rc4_key_len, 9878 cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, 9879 cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, 9880 cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, 9881 cmd->keepalive_max, cmd->keepalive_inc, 9882 cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); 9883 9884 wmi_mtrace(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, cmd->vdev_id, 0); 9885 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9886 WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); 9887 if (ret) { 9888 WMI_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); 9889 wmi_buf_free(buf); 9890 return QDF_STATUS_E_FAILURE; 9891 } 9892 9893 return QDF_STATUS_SUCCESS; 9894 9895 } 9896 9897 /** 9898 * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware 9899 * @wmi_handle: wmi handle 9900 * @timer_val: auto shutdown timer value 9901 * 9902 * Return: CDF status 9903 */ 9904 static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle, 9905 uint32_t timer_val) 9906 { 9907 QDF_STATUS status; 9908 wmi_buf_t buf = NULL; 9909 uint8_t *buf_ptr; 9910 wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; 9911 int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); 9912 9913 WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", 9914 __func__, timer_val); 9915 9916 buf = wmi_buf_alloc(wmi_handle, len); 9917 if (!buf) { 9918 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 9919 return QDF_STATUS_E_NOMEM; 9920 } 9921 9922 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9923 wmi_auto_sh_cmd = 9924 (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr; 9925 wmi_auto_sh_cmd->timer_value = timer_val; 9926 9927 WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, 9928 WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, 9929 WMITLV_GET_STRUCT_TLVLEN 9930 (wmi_host_auto_shutdown_cfg_cmd_fixed_param)); 9931 9932 wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0); 9933 status = wmi_unified_cmd_send(wmi_handle, buf, 9934 len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); 9935 if (QDF_IS_STATUS_ERROR(status)) { 9936 WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", 9937 __func__, status); 9938 wmi_buf_free(buf); 9939 } 9940 9941 return status; 9942 } 9943 9944 /** 9945 * send_nan_req_cmd_tlv() - to send nan request to target 9946 * @wmi_handle: wmi handle 9947 * @nan_req: request data which will be non-null 9948 * 9949 * Return: CDF status 9950 */ 9951 static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle, 9952 struct nan_req_params *nan_req) 9953 { 9954 QDF_STATUS ret; 9955 wmi_nan_cmd_param *cmd; 9956 wmi_buf_t buf; 9957 uint16_t len = sizeof(*cmd); 9958 uint16_t nan_data_len, nan_data_len_aligned; 9959 uint8_t *buf_ptr; 9960 9961 /* 9962 * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> 9963 * +------------+----------+-----------------------+--------------+ 9964 * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | 9965 * +------------+----------+-----------------------+--------------+ 9966 */ 9967 if (!nan_req) { 9968 WMI_LOGE("%s:nan req is not valid", __func__); 9969 return QDF_STATUS_E_FAILURE; 9970 } 9971 nan_data_len = nan_req->request_data_len; 9972 nan_data_len_aligned = roundup(nan_req->request_data_len, 9973 sizeof(uint32_t)); 9974 if (nan_data_len_aligned < nan_req->request_data_len) { 9975 WMI_LOGE("%s: integer overflow while rounding up data_len", 9976 __func__); 9977 return QDF_STATUS_E_FAILURE; 9978 } 9979 9980 if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 9981 WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen", 9982 __func__); 9983 return QDF_STATUS_E_FAILURE; 9984 } 9985 9986 len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; 9987 buf = wmi_buf_alloc(wmi_handle, len); 9988 if (!buf) { 9989 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 9990 return QDF_STATUS_E_NOMEM; 9991 } 9992 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9993 cmd = (wmi_nan_cmd_param *) buf_ptr; 9994 WMITLV_SET_HDR(&cmd->tlv_header, 9995 WMITLV_TAG_STRUC_wmi_nan_cmd_param, 9996 WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param)); 9997 cmd->data_len = nan_req->request_data_len; 9998 WMI_LOGD("%s: The data len value is %u", 9999 __func__, nan_req->request_data_len); 10000 buf_ptr += sizeof(wmi_nan_cmd_param); 10001 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); 10002 buf_ptr += WMI_TLV_HDR_SIZE; 10003 qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len); 10004 10005 wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0); 10006 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10007 WMI_NAN_CMDID); 10008 if (QDF_IS_STATUS_ERROR(ret)) { 10009 WMI_LOGE("%s Failed to send set param command ret = %d", 10010 __func__, ret); 10011 wmi_buf_free(buf); 10012 } 10013 10014 return ret; 10015 } 10016 10017 /** 10018 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 10019 * @wmi_handle: wmi handle 10020 * @params: DHCP server offload info 10021 * 10022 * Return: QDF_STATUS_SUCCESS for success or error code 10023 */ 10024 static QDF_STATUS 10025 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 10026 struct dhcp_offload_info_params *params) 10027 { 10028 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 10029 wmi_buf_t buf; 10030 QDF_STATUS status; 10031 10032 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 10033 if (!buf) { 10034 WMI_LOGE("Failed to allocate buffer to send " 10035 "set_dhcp_server_offload cmd"); 10036 return QDF_STATUS_E_NOMEM; 10037 } 10038 10039 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 10040 10041 WMITLV_SET_HDR(&cmd->tlv_header, 10042 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 10043 WMITLV_GET_STRUCT_TLVLEN 10044 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 10045 cmd->vdev_id = params->vdev_id; 10046 cmd->enable = params->dhcp_offload_enabled; 10047 cmd->num_client = params->dhcp_client_num; 10048 cmd->srv_ipv4 = params->dhcp_srv_addr; 10049 cmd->start_lsb = 0; 10050 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 10051 status = wmi_unified_cmd_send(wmi_handle, buf, 10052 sizeof(*cmd), 10053 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 10054 if (QDF_IS_STATUS_ERROR(status)) { 10055 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 10056 wmi_buf_free(buf); 10057 return QDF_STATUS_E_FAILURE; 10058 } 10059 WMI_LOGD("Set dhcp server offload to vdevId %d", 10060 params->vdev_id); 10061 10062 return status; 10063 } 10064 10065 /** 10066 * send_set_led_flashing_cmd_tlv() - set led flashing in fw 10067 * @wmi_handle: wmi handle 10068 * @flashing: flashing request 10069 * 10070 * Return: CDF status 10071 */ 10072 static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle, 10073 struct flashing_req_params *flashing) 10074 { 10075 wmi_set_led_flashing_cmd_fixed_param *cmd; 10076 QDF_STATUS status; 10077 wmi_buf_t buf; 10078 uint8_t *buf_ptr; 10079 int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param); 10080 10081 buf = wmi_buf_alloc(wmi_handle, len); 10082 if (!buf) { 10083 WMI_LOGP(FL("wmi_buf_alloc failed")); 10084 return QDF_STATUS_E_NOMEM; 10085 } 10086 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10087 cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr; 10088 WMITLV_SET_HDR(&cmd->tlv_header, 10089 WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, 10090 WMITLV_GET_STRUCT_TLVLEN 10091 (wmi_set_led_flashing_cmd_fixed_param)); 10092 cmd->pattern_id = flashing->pattern_id; 10093 cmd->led_x0 = flashing->led_x0; 10094 cmd->led_x1 = flashing->led_x1; 10095 10096 wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0); 10097 status = wmi_unified_cmd_send(wmi_handle, buf, len, 10098 WMI_PDEV_SET_LED_FLASHING_CMDID); 10099 if (QDF_IS_STATUS_ERROR(status)) { 10100 WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" 10101 " returned Error %d", __func__, status); 10102 wmi_buf_free(buf); 10103 } 10104 10105 return status; 10106 } 10107 10108 /** 10109 * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request 10110 * @wmi_handle: wmi handle 10111 * @ch_avoid_update_req: channel avoid update params 10112 * 10113 * Return: CDF status 10114 */ 10115 static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle) 10116 { 10117 QDF_STATUS status; 10118 wmi_buf_t buf = NULL; 10119 uint8_t *buf_ptr; 10120 wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; 10121 int len = sizeof(wmi_chan_avoid_update_cmd_param); 10122 10123 10124 buf = wmi_buf_alloc(wmi_handle, len); 10125 if (!buf) { 10126 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 10127 return QDF_STATUS_E_NOMEM; 10128 } 10129 10130 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10131 ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; 10132 WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, 10133 WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, 10134 WMITLV_GET_STRUCT_TLVLEN 10135 (wmi_chan_avoid_update_cmd_param)); 10136 10137 wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0); 10138 status = wmi_unified_cmd_send(wmi_handle, buf, 10139 len, WMI_CHAN_AVOID_UPDATE_CMDID); 10140 if (QDF_IS_STATUS_ERROR(status)) { 10141 WMI_LOGE("wmi_unified_cmd_send" 10142 " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" 10143 " returned Error %d", status); 10144 wmi_buf_free(buf); 10145 } 10146 10147 return status; 10148 } 10149 10150 /** 10151 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 10152 * @wmi_handle: wmi handle 10153 * @param: pointer to pdev regdomain params 10154 * 10155 * Return: 0 for success or error code 10156 */ 10157 static QDF_STATUS 10158 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 10159 struct pdev_set_regdomain_params *param) 10160 { 10161 wmi_buf_t buf; 10162 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10163 int32_t len = sizeof(*cmd); 10164 10165 10166 buf = wmi_buf_alloc(wmi_handle, len); 10167 if (!buf) { 10168 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10169 return QDF_STATUS_E_NOMEM; 10170 } 10171 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10172 WMITLV_SET_HDR(&cmd->tlv_header, 10173 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10174 WMITLV_GET_STRUCT_TLVLEN 10175 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10176 10177 cmd->reg_domain = param->currentRDinuse; 10178 cmd->reg_domain_2G = param->currentRD2G; 10179 cmd->reg_domain_5G = param->currentRD5G; 10180 cmd->conformance_test_limit_2G = param->ctl_2G; 10181 cmd->conformance_test_limit_5G = param->ctl_5G; 10182 cmd->dfs_domain = param->dfsDomain; 10183 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10184 param->pdev_id); 10185 10186 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 10187 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10188 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10189 WMI_LOGE("%s: Failed to send pdev set regdomain command", 10190 __func__); 10191 wmi_buf_free(buf); 10192 return QDF_STATUS_E_FAILURE; 10193 } 10194 10195 return QDF_STATUS_SUCCESS; 10196 } 10197 10198 /** 10199 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 10200 * @wmi_handle: wmi handle 10201 * @reg_dmn: reg domain 10202 * @regdmn2G: 2G reg domain 10203 * @regdmn5G: 5G reg domain 10204 * @ctl2G: 2G test limit 10205 * @ctl5G: 5G test limit 10206 * 10207 * Return: none 10208 */ 10209 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 10210 uint32_t reg_dmn, uint16_t regdmn2G, 10211 uint16_t regdmn5G, uint8_t ctl2G, 10212 uint8_t ctl5G) 10213 { 10214 wmi_buf_t buf; 10215 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 10216 int32_t len = sizeof(*cmd); 10217 10218 10219 buf = wmi_buf_alloc(wmi_handle, len); 10220 if (!buf) { 10221 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 10222 return QDF_STATUS_E_NOMEM; 10223 } 10224 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 10225 WMITLV_SET_HDR(&cmd->tlv_header, 10226 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 10227 WMITLV_GET_STRUCT_TLVLEN 10228 (wmi_pdev_set_regdomain_cmd_fixed_param)); 10229 cmd->reg_domain = reg_dmn; 10230 cmd->reg_domain_2G = regdmn2G; 10231 cmd->reg_domain_5G = regdmn5G; 10232 cmd->conformance_test_limit_2G = ctl2G; 10233 cmd->conformance_test_limit_5G = ctl5G; 10234 10235 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 10236 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10237 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 10238 WMI_LOGP("%s: Failed to send pdev set regdomain command", 10239 __func__); 10240 wmi_buf_free(buf); 10241 return QDF_STATUS_E_FAILURE; 10242 } 10243 10244 return QDF_STATUS_SUCCESS; 10245 } 10246 10247 #ifdef FEATURE_WLAN_TDLS 10248 /** 10249 * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode 10250 * @tdls_sw_mode: tdls_sw_mode 10251 * 10252 * This function returns wmi tdls offchannel mode 10253 * 10254 * Return: enum value of wmi tdls offchannel mode 10255 */ 10256 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode) 10257 { 10258 uint8_t off_chan_mode; 10259 10260 switch (tdls_sw_mode) { 10261 case ENABLE_CHANSWITCH: 10262 off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL; 10263 break; 10264 10265 case DISABLE_CHANSWITCH: 10266 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL; 10267 break; 10268 10269 default: 10270 WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode); 10271 off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL; 10272 } 10273 return off_chan_mode; 10274 } 10275 #else 10276 static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode) 10277 { 10278 return WMI_TDLS_DISABLE_OFFCHANNEL; 10279 } 10280 #endif 10281 10282 /** 10283 * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode 10284 * @wmi_handle: wmi handle 10285 * @chan_switch_params: Pointer to tdls channel switch parameter structure 10286 * 10287 * This function sets tdls off channel mode 10288 * 10289 * Return: 0 on success; Negative errno otherwise 10290 */ 10291 static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle, 10292 struct tdls_channel_switch_params *chan_switch_params) 10293 { 10294 wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd; 10295 wmi_buf_t wmi_buf; 10296 u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); 10297 10298 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10299 if (!wmi_buf) { 10300 WMI_LOGE(FL("wmi_buf_alloc failed")); 10301 return QDF_STATUS_E_FAILURE; 10302 } 10303 cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *) 10304 wmi_buf_data(wmi_buf); 10305 WMITLV_SET_HDR(&cmd->tlv_header, 10306 WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, 10307 WMITLV_GET_STRUCT_TLVLEN( 10308 wmi_tdls_set_offchan_mode_cmd_fixed_param)); 10309 10310 WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr, 10311 &cmd->peer_macaddr); 10312 cmd->vdev_id = chan_switch_params->vdev_id; 10313 cmd->offchan_mode = 10314 tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode); 10315 cmd->is_peer_responder = chan_switch_params->is_responder; 10316 cmd->offchan_num = chan_switch_params->tdls_off_ch; 10317 cmd->offchan_bw_bitmap = chan_switch_params->tdls_off_ch_bw_offset; 10318 cmd->offchan_oper_class = chan_switch_params->oper_class; 10319 10320 WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), 10321 cmd->peer_macaddr.mac_addr31to0, 10322 cmd->peer_macaddr.mac_addr47to32); 10323 10324 WMI_LOGD(FL( 10325 "vdev_id: %d, off channel mode: %d, off channel Num: %d, " 10326 "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d" 10327 ), 10328 cmd->vdev_id, 10329 cmd->offchan_mode, 10330 cmd->offchan_num, 10331 cmd->offchan_bw_bitmap, 10332 cmd->is_peer_responder, 10333 cmd->offchan_oper_class); 10334 10335 wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0); 10336 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10337 WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { 10338 WMI_LOGP(FL("failed to send tdls off chan command")); 10339 wmi_buf_free(wmi_buf); 10340 return QDF_STATUS_E_FAILURE; 10341 } 10342 10343 10344 return QDF_STATUS_SUCCESS; 10345 } 10346 10347 /** 10348 * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev 10349 * @wmi_handle: wmi handle 10350 * @pwmaTdlsparams: TDLS params 10351 * 10352 * Return: 0 for success or error code 10353 */ 10354 static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle, 10355 void *tdls_param, uint8_t tdls_state) 10356 { 10357 wmi_tdls_set_state_cmd_fixed_param *cmd; 10358 wmi_buf_t wmi_buf; 10359 10360 struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param; 10361 uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); 10362 10363 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10364 if (!wmi_buf) { 10365 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 10366 return QDF_STATUS_E_FAILURE; 10367 } 10368 cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10369 WMITLV_SET_HDR(&cmd->tlv_header, 10370 WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, 10371 WMITLV_GET_STRUCT_TLVLEN 10372 (wmi_tdls_set_state_cmd_fixed_param)); 10373 cmd->vdev_id = wmi_tdls->vdev_id; 10374 cmd->state = tdls_state; 10375 cmd->notification_interval_ms = wmi_tdls->notification_interval_ms; 10376 cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold; 10377 cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold; 10378 cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold; 10379 cmd->rssi_delta = wmi_tdls->rssi_delta; 10380 cmd->tdls_options = wmi_tdls->tdls_options; 10381 cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window; 10382 cmd->tdls_peer_traffic_response_timeout_ms = 10383 wmi_tdls->peer_traffic_response_timeout; 10384 cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask; 10385 cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time; 10386 cmd->tdls_puapsd_rx_frame_threshold = 10387 wmi_tdls->puapsd_rx_frame_threshold; 10388 cmd->teardown_notification_ms = 10389 wmi_tdls->teardown_notification_ms; 10390 cmd->tdls_peer_kickout_threshold = 10391 wmi_tdls->tdls_peer_kickout_threshold; 10392 10393 WMI_LOGD("%s: tdls_state: %d, state: %d, " 10394 "notification_interval_ms: %d, " 10395 "tx_discovery_threshold: %d, " 10396 "tx_teardown_threshold: %d, " 10397 "rssi_teardown_threshold: %d, " 10398 "rssi_delta: %d, " 10399 "tdls_options: 0x%x, " 10400 "tdls_peer_traffic_ind_window: %d, " 10401 "tdls_peer_traffic_response_timeout: %d, " 10402 "tdls_puapsd_mask: 0x%x, " 10403 "tdls_puapsd_inactivity_time: %d, " 10404 "tdls_puapsd_rx_frame_threshold: %d, " 10405 "teardown_notification_ms: %d, " 10406 "tdls_peer_kickout_threshold: %d", 10407 __func__, tdls_state, cmd->state, 10408 cmd->notification_interval_ms, 10409 cmd->tx_discovery_threshold, 10410 cmd->tx_teardown_threshold, 10411 cmd->rssi_teardown_threshold, 10412 cmd->rssi_delta, 10413 cmd->tdls_options, 10414 cmd->tdls_peer_traffic_ind_window, 10415 cmd->tdls_peer_traffic_response_timeout_ms, 10416 cmd->tdls_puapsd_mask, 10417 cmd->tdls_puapsd_inactivity_time_ms, 10418 cmd->tdls_puapsd_rx_frame_threshold, 10419 cmd->teardown_notification_ms, 10420 cmd->tdls_peer_kickout_threshold); 10421 10422 wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0); 10423 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10424 WMI_TDLS_SET_STATE_CMDID)) { 10425 WMI_LOGP("%s: failed to send tdls set state command", __func__); 10426 wmi_buf_free(wmi_buf); 10427 return QDF_STATUS_E_FAILURE; 10428 } 10429 WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id); 10430 10431 return QDF_STATUS_SUCCESS; 10432 } 10433 10434 /** 10435 * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state 10436 * @wmi_handle: wmi handle 10437 * @peerStateParams: TDLS peer state params 10438 * 10439 * Return: QDF_STATUS_SUCCESS for success or error code 10440 */ 10441 static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle, 10442 struct tdls_peer_state_params *peerStateParams, 10443 uint32_t *ch_mhz) 10444 { 10445 wmi_tdls_peer_update_cmd_fixed_param *cmd; 10446 wmi_tdls_peer_capabilities *peer_cap; 10447 wmi_channel *chan_info; 10448 wmi_buf_t wmi_buf; 10449 uint8_t *buf_ptr; 10450 uint32_t i; 10451 int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + 10452 sizeof(wmi_tdls_peer_capabilities); 10453 10454 10455 len += WMI_TLV_HDR_SIZE + 10456 sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; 10457 10458 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10459 if (!wmi_buf) { 10460 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 10461 return QDF_STATUS_E_FAILURE; 10462 } 10463 10464 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 10465 cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; 10466 WMITLV_SET_HDR(&cmd->tlv_header, 10467 WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, 10468 WMITLV_GET_STRUCT_TLVLEN 10469 (wmi_tdls_peer_update_cmd_fixed_param)); 10470 10471 cmd->vdev_id = peerStateParams->vdevId; 10472 WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, 10473 &cmd->peer_macaddr); 10474 10475 10476 cmd->peer_state = peerStateParams->peerState; 10477 10478 WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " 10479 "peer_macaddr.mac_addr31to0: 0x%x, " 10480 "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", 10481 __func__, cmd->vdev_id, peerStateParams->peerMacAddr, 10482 cmd->peer_macaddr.mac_addr31to0, 10483 cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); 10484 10485 buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); 10486 peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; 10487 WMITLV_SET_HDR(&peer_cap->tlv_header, 10488 WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, 10489 WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); 10490 10491 if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) 10492 WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); 10493 if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) 10494 WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); 10495 if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) 10496 WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); 10497 if (peerStateParams->peerCap.peerUapsdQueue & 0x01) 10498 WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); 10499 10500 /* Ack and More Data Ack are sent as 0, so no need to set 10501 * but fill SP 10502 */ 10503 WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, 10504 peerStateParams->peerCap.peerMaxSp); 10505 10506 peer_cap->buff_sta_support = 10507 peerStateParams->peerCap.peerBuffStaSupport; 10508 peer_cap->off_chan_support = 10509 peerStateParams->peerCap.peerOffChanSupport; 10510 peer_cap->peer_curr_operclass = 10511 peerStateParams->peerCap.peerCurrOperClass; 10512 /* self curr operclass is not being used and so pass op class for 10513 * preferred off chan in it. 10514 */ 10515 peer_cap->self_curr_operclass = 10516 peerStateParams->peerCap.opClassForPrefOffChan; 10517 peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen; 10518 peer_cap->peer_operclass_len = 10519 peerStateParams->peerCap.peerOperClassLen; 10520 10521 WMI_LOGD("%s: peer_operclass_len: %d", 10522 __func__, peer_cap->peer_operclass_len); 10523 for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { 10524 peer_cap->peer_operclass[i] = 10525 peerStateParams->peerCap.peerOperClass[i]; 10526 WMI_LOGD("%s: peer_operclass[%d]: %d", 10527 __func__, i, peer_cap->peer_operclass[i]); 10528 } 10529 10530 peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder; 10531 peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum; 10532 peer_cap->pref_offchan_bw = 10533 peerStateParams->peerCap.prefOffChanBandwidth; 10534 10535 WMI_LOGD 10536 ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, " 10537 "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: " 10538 "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:" 10539 " %d, pref_offchan_bw: %d", 10540 __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, 10541 peer_cap->off_chan_support, peer_cap->peer_curr_operclass, 10542 peer_cap->self_curr_operclass, peer_cap->peer_chan_len, 10543 peer_cap->peer_operclass_len, peer_cap->is_peer_responder, 10544 peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); 10545 10546 /* next fill variable size array of peer chan info */ 10547 buf_ptr += sizeof(wmi_tdls_peer_capabilities); 10548 WMITLV_SET_HDR(buf_ptr, 10549 WMITLV_TAG_ARRAY_STRUC, 10550 sizeof(wmi_channel) * 10551 peerStateParams->peerCap.peerChanLen); 10552 chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); 10553 10554 for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { 10555 WMITLV_SET_HDR(&chan_info->tlv_header, 10556 WMITLV_TAG_STRUC_wmi_channel, 10557 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 10558 chan_info->mhz = ch_mhz[i]; 10559 chan_info->band_center_freq1 = chan_info->mhz; 10560 chan_info->band_center_freq2 = 0; 10561 10562 WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); 10563 10564 if (peerStateParams->peerCap.peerChan[i].dfsSet) { 10565 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); 10566 WMI_LOGI("chan[%d] DFS[%d]\n", 10567 peerStateParams->peerCap.peerChan[i].chanId, 10568 peerStateParams->peerCap.peerChan[i].dfsSet); 10569 } 10570 10571 if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ) 10572 WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); 10573 else 10574 WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); 10575 10576 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 10577 peerStateParams->peerCap. 10578 peerChan[i].pwr); 10579 10580 WMI_SET_CHANNEL_REG_POWER(chan_info, 10581 peerStateParams->peerCap.peerChan[i]. 10582 pwr); 10583 WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, 10584 peerStateParams->peerCap.peerChan[i].pwr); 10585 10586 chan_info++; 10587 } 10588 10589 wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0); 10590 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10591 WMI_TDLS_PEER_UPDATE_CMDID)) { 10592 WMI_LOGE("%s: failed to send tdls peer update state command", 10593 __func__); 10594 wmi_buf_free(wmi_buf); 10595 return QDF_STATUS_E_FAILURE; 10596 } 10597 10598 10599 return QDF_STATUS_SUCCESS; 10600 } 10601 10602 /* 10603 * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware 10604 * @wmi_handle: Pointer to WMi handle 10605 * @ie_data: Pointer for ie data 10606 * 10607 * This function sends IE information to firmware 10608 * 10609 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10610 * 10611 */ 10612 static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle, 10613 struct vdev_ie_info_param *ie_info) 10614 { 10615 wmi_vdev_set_ie_cmd_fixed_param *cmd; 10616 wmi_buf_t buf; 10617 uint8_t *buf_ptr; 10618 uint32_t len, ie_len_aligned; 10619 QDF_STATUS ret; 10620 10621 10622 ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t)); 10623 /* Allocate memory for the WMI command */ 10624 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned; 10625 10626 buf = wmi_buf_alloc(wmi_handle, len); 10627 if (!buf) { 10628 WMI_LOGE(FL("wmi_buf_alloc failed")); 10629 return QDF_STATUS_E_NOMEM; 10630 } 10631 10632 buf_ptr = wmi_buf_data(buf); 10633 qdf_mem_zero(buf_ptr, len); 10634 10635 /* Populate the WMI command */ 10636 cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr; 10637 10638 WMITLV_SET_HDR(&cmd->tlv_header, 10639 WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, 10640 WMITLV_GET_STRUCT_TLVLEN( 10641 wmi_vdev_set_ie_cmd_fixed_param)); 10642 cmd->vdev_id = ie_info->vdev_id; 10643 cmd->ie_id = ie_info->ie_id; 10644 cmd->ie_len = ie_info->length; 10645 cmd->band = ie_info->band; 10646 10647 WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id, 10648 ie_info->length, ie_info->vdev_id); 10649 10650 buf_ptr += sizeof(*cmd); 10651 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 10652 buf_ptr += WMI_TLV_HDR_SIZE; 10653 10654 qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len); 10655 10656 wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0); 10657 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10658 WMI_VDEV_SET_IE_CMDID); 10659 if (QDF_IS_STATUS_ERROR(ret)) { 10660 WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret); 10661 wmi_buf_free(buf); 10662 } 10663 10664 return ret; 10665 } 10666 10667 /** 10668 * send_smart_ant_enable_cmd_tlv() - WMI smart ant enable function 10669 * 10670 * @param wmi_handle : handle to WMI. 10671 * @param param : pointer to antenna param 10672 * 10673 * This function sends smart antenna enable command to FW 10674 * 10675 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10676 */ 10677 static QDF_STATUS send_smart_ant_enable_cmd_tlv(wmi_unified_t wmi_handle, 10678 struct smart_ant_enable_params *param) 10679 { 10680 /* Send WMI COMMAND to Enable */ 10681 wmi_pdev_smart_ant_enable_cmd_fixed_param *cmd; 10682 wmi_pdev_smart_ant_gpio_handle *gpio_param; 10683 wmi_buf_t buf; 10684 uint8_t *buf_ptr; 10685 int len = 0; 10686 QDF_STATUS ret; 10687 int loop = 0; 10688 10689 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 10690 len += WMI_HAL_MAX_SANTENNA * sizeof(wmi_pdev_smart_ant_gpio_handle); 10691 buf = wmi_buf_alloc(wmi_handle, len); 10692 10693 if (!buf) { 10694 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10695 return QDF_STATUS_E_NOMEM; 10696 } 10697 10698 buf_ptr = wmi_buf_data(buf); 10699 qdf_mem_zero(buf_ptr, len); 10700 cmd = (wmi_pdev_smart_ant_enable_cmd_fixed_param *)buf_ptr; 10701 10702 WMITLV_SET_HDR(&cmd->tlv_header, 10703 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_enable_cmd_fixed_param, 10704 WMITLV_GET_STRUCT_TLVLEN( 10705 wmi_pdev_smart_ant_enable_cmd_fixed_param)); 10706 10707 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10708 param->pdev_id); 10709 cmd->enable = param->enable; 10710 cmd->mode = param->mode; 10711 cmd->rx_antenna = param->rx_antenna; 10712 cmd->tx_default_antenna = param->rx_antenna; 10713 10714 /* TLV indicating array of structures to follow */ 10715 buf_ptr += sizeof(wmi_pdev_smart_ant_enable_cmd_fixed_param); 10716 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10717 WMI_HAL_MAX_SANTENNA * 10718 sizeof(wmi_pdev_smart_ant_gpio_handle)); 10719 10720 buf_ptr += WMI_TLV_HDR_SIZE; 10721 gpio_param = (wmi_pdev_smart_ant_gpio_handle *)buf_ptr; 10722 10723 for (loop = 0; loop < WMI_HAL_MAX_SANTENNA; loop++) { 10724 WMITLV_SET_HDR(&gpio_param->tlv_header, 10725 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_gpio_handle, 10726 WMITLV_GET_STRUCT_TLVLEN( 10727 wmi_pdev_smart_ant_gpio_handle)); 10728 if (param->mode == SMART_ANT_MODE_SERIAL) { 10729 if (loop < WMI_HOST_MAX_SERIAL_ANTENNA) { 10730 gpio_param->gpio_pin = param->gpio_pin[loop]; 10731 gpio_param->gpio_func = param->gpio_func[loop]; 10732 } else { 10733 gpio_param->gpio_pin = 0; 10734 gpio_param->gpio_func = 0; 10735 } 10736 } else if (param->mode == SMART_ANT_MODE_PARALLEL) { 10737 gpio_param->gpio_pin = param->gpio_pin[loop]; 10738 gpio_param->gpio_func = param->gpio_func[loop]; 10739 } 10740 /* Setting it to 0 for now */ 10741 gpio_param->pdev_id = 10742 wmi_handle->ops->convert_pdev_id_host_to_target( 10743 param->pdev_id); 10744 gpio_param++; 10745 } 10746 10747 wmi_mtrace(WMI_PDEV_SMART_ANT_ENABLE_CMDID, NO_SESSION, 0); 10748 ret = wmi_unified_cmd_send(wmi_handle, 10749 buf, 10750 len, 10751 WMI_PDEV_SMART_ANT_ENABLE_CMDID); 10752 10753 if (ret != 0) { 10754 WMI_LOGE(" %s :WMI Failed\n", __func__); 10755 WMI_LOGE("enable:%d mode:%d rx_antenna: 0x%08x PINS: [%d %d %d %d] Func[%d %d %d %d] cmdstatus=%d\n", 10756 cmd->enable, 10757 cmd->mode, 10758 cmd->rx_antenna, 10759 param->gpio_pin[0], param->gpio_pin[1], 10760 param->gpio_pin[2], param->gpio_pin[3], 10761 param->gpio_func[0], param->gpio_func[1], 10762 param->gpio_func[2], param->gpio_func[3], 10763 ret); 10764 wmi_buf_free(buf); 10765 } 10766 10767 return ret; 10768 } 10769 10770 /** 10771 * send_smart_ant_set_rx_ant_cmd_tlv() - WMI set rx antenna function 10772 * 10773 * @param wmi_handle : handle to WMI. 10774 * @param param : pointer to rx antenna param 10775 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10776 */ 10777 static QDF_STATUS send_smart_ant_set_rx_ant_cmd_tlv(wmi_unified_t wmi_handle, 10778 struct smart_ant_rx_ant_params *param) 10779 { 10780 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *cmd; 10781 wmi_buf_t buf; 10782 uint8_t *buf_ptr; 10783 uint32_t len; 10784 QDF_STATUS ret; 10785 10786 len = sizeof(*cmd); 10787 buf = wmi_buf_alloc(wmi_handle, len); 10788 WMI_LOGD("%s:\n", __func__); 10789 if (!buf) { 10790 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10791 return QDF_STATUS_E_NOMEM; 10792 } 10793 10794 buf_ptr = wmi_buf_data(buf); 10795 cmd = (wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param *)buf_ptr; 10796 WMITLV_SET_HDR(&cmd->tlv_header, 10797 WMITLV_TAG_STRUC_wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param, 10798 WMITLV_GET_STRUCT_TLVLEN( 10799 wmi_pdev_smart_ant_set_rx_antenna_cmd_fixed_param)); 10800 cmd->rx_antenna = param->antenna; 10801 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10802 param->pdev_id); 10803 10804 wmi_mtrace(WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, NO_SESSION, 0); 10805 ret = wmi_unified_cmd_send(wmi_handle, 10806 buf, 10807 len, 10808 WMI_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID); 10809 10810 if (ret != 0) { 10811 WMI_LOGE(" %s :WMI Failed\n", __func__); 10812 WMI_LOGE("%s: rx_antenna: 0x%08x cmdstatus=%d\n", 10813 __func__, 10814 cmd->rx_antenna, 10815 ret); 10816 wmi_buf_free(buf); 10817 } 10818 10819 return ret; 10820 } 10821 10822 /** 10823 * send_set_ctl_table_cmd_tlv() - send ctl table cmd to fw 10824 * @wmi_handle: wmi handle 10825 * @param: pointer to hold ctl table param 10826 * 10827 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10828 */ 10829 static QDF_STATUS 10830 send_set_ctl_table_cmd_tlv(wmi_unified_t wmi_handle, 10831 struct ctl_table_params *param) 10832 { 10833 uint16_t len, ctl_tlv_len; 10834 uint8_t *buf_ptr; 10835 wmi_buf_t buf; 10836 wmi_pdev_set_ctl_table_cmd_fixed_param *cmd; 10837 uint32_t *ctl_array; 10838 10839 if (!param->ctl_array) 10840 return QDF_STATUS_E_FAILURE; 10841 10842 ctl_tlv_len = WMI_TLV_HDR_SIZE + 10843 roundup(param->ctl_cmd_len, sizeof(uint32_t)); 10844 len = sizeof(*cmd) + ctl_tlv_len; 10845 10846 buf = wmi_buf_alloc(wmi_handle, len); 10847 if (!buf) { 10848 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10849 return QDF_STATUS_E_FAILURE; 10850 } 10851 10852 buf_ptr = wmi_buf_data(buf); 10853 qdf_mem_zero(buf_ptr, len); 10854 10855 cmd = (wmi_pdev_set_ctl_table_cmd_fixed_param *)buf_ptr; 10856 10857 WMITLV_SET_HDR(&cmd->tlv_header, 10858 WMITLV_TAG_STRUC_wmi_pdev_set_ctl_table_cmd_fixed_param, 10859 WMITLV_GET_STRUCT_TLVLEN( 10860 wmi_pdev_set_ctl_table_cmd_fixed_param)); 10861 cmd->ctl_len = param->ctl_cmd_len; 10862 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10863 param->pdev_id); 10864 10865 buf_ptr += sizeof(*cmd); 10866 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10867 (cmd->ctl_len)); 10868 buf_ptr += WMI_TLV_HDR_SIZE; 10869 ctl_array = (uint32_t *)buf_ptr; 10870 10871 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[0], ¶m->ctl_band, 10872 sizeof(param->ctl_band)); 10873 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&ctl_array[1], param->ctl_array, 10874 param->ctl_cmd_len - 10875 sizeof(param->ctl_band)); 10876 10877 wmi_mtrace(WMI_PDEV_SET_CTL_TABLE_CMDID, NO_SESSION, 0); 10878 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10879 WMI_PDEV_SET_CTL_TABLE_CMDID)) { 10880 WMI_LOGE("%s:Failed to send command\n", __func__); 10881 wmi_buf_free(buf); 10882 return QDF_STATUS_E_FAILURE; 10883 } 10884 10885 return QDF_STATUS_SUCCESS; 10886 } 10887 10888 /** 10889 * send_set_mimogain_table_cmd_tlv() - send mimogain table cmd to fw 10890 * @wmi_handle: wmi handle 10891 * @param: pointer to hold mimogain table param 10892 * 10893 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 10894 */ 10895 static QDF_STATUS 10896 send_set_mimogain_table_cmd_tlv(wmi_unified_t wmi_handle, 10897 struct mimogain_table_params *param) 10898 { 10899 uint16_t len, table_tlv_len; 10900 wmi_buf_t buf; 10901 uint8_t *buf_ptr; 10902 wmi_pdev_set_mimogain_table_cmd_fixed_param *cmd; 10903 uint32_t *gain_table; 10904 10905 if (!param->array_gain) 10906 return QDF_STATUS_E_FAILURE; 10907 10908 /* len must be multiple of a single array gain table */ 10909 if (param->tbl_len % 10910 ((WMI_HOST_TX_NUM_CHAIN-1) * WMI_HOST_TPC_REGINDEX_MAX * 10911 WMI_HOST_ARRAY_GAIN_NUM_STREAMS) != 0) { 10912 WMI_LOGE("Array gain table len not correct\n"); 10913 return QDF_STATUS_E_FAILURE; 10914 } 10915 10916 table_tlv_len = WMI_TLV_HDR_SIZE + 10917 roundup(param->tbl_len, sizeof(uint32_t)); 10918 len = sizeof(*cmd) + table_tlv_len; 10919 10920 buf = wmi_buf_alloc(wmi_handle, len); 10921 if (!buf) { 10922 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10923 return QDF_STATUS_E_FAILURE; 10924 } 10925 10926 buf_ptr = wmi_buf_data(buf); 10927 qdf_mem_zero(buf_ptr, len); 10928 10929 cmd = (wmi_pdev_set_mimogain_table_cmd_fixed_param *)buf_ptr; 10930 10931 WMITLV_SET_HDR(&cmd->tlv_header, 10932 WMITLV_TAG_STRUC_wmi_pdev_set_mimogain_table_cmd_fixed_param, 10933 WMITLV_GET_STRUCT_TLVLEN( 10934 wmi_pdev_set_mimogain_table_cmd_fixed_param)); 10935 10936 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10937 param->pdev_id); 10938 WMI_MIMOGAIN_ARRAY_GAIN_LEN_SET(cmd->mimogain_info, param->tbl_len); 10939 WMI_MIMOGAIN_MULTI_CHAIN_BYPASS_SET(cmd->mimogain_info, 10940 param->multichain_gain_bypass); 10941 10942 buf_ptr += sizeof(*cmd); 10943 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10944 (param->tbl_len)); 10945 buf_ptr += WMI_TLV_HDR_SIZE; 10946 gain_table = (uint32_t *)buf_ptr; 10947 10948 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(gain_table, 10949 param->array_gain, 10950 param->tbl_len); 10951 10952 wmi_mtrace(WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID, NO_SESSION, 0); 10953 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10954 WMI_PDEV_SET_MIMOGAIN_TABLE_CMDID)) { 10955 return QDF_STATUS_E_FAILURE; 10956 } 10957 10958 return QDF_STATUS_SUCCESS; 10959 } 10960 10961 /** 10962 * enum packet_power_tlv_flags: target defined 10963 * packet power rate flags for TLV 10964 * @WMI_TLV_FLAG_ONE_CHAIN: one chain 10965 * @WMI_TLV_FLAG_TWO_CHAIN: two chain 10966 * @WMI_TLV_FLAG_THREE_CHAIN: three chain 10967 * @WMI_TLV_FLAG_FOUR_CHAIN: four chain 10968 * @WMI_TLV_FLAG_FIVE_CHAIN: five chain 10969 * @WMI_TLV_FLAG_SIX_CHAIN: six chain 10970 * @WMI_TLV_FLAG_SEVEN_CHAIN: seven chain 10971 * @WMI_TLV_FLAG_EIGHT_CHAIN:eight chain 10972 * @WMI_TLV_FLAG_STBC: STBC is set 10973 * @WMI_TLV_FLAG_40MHZ: 40MHz chan width 10974 * @WMI_TLV_FLAG_80MHZ: 80MHz chan width 10975 * @WMI_TLV_FLAG_160MHZ: 160MHz chan width 10976 * @WMI_TLV_FLAG_TXBF: Tx Bf enabled 10977 * @WMI_TLV_FLAG_RTSENA: RTS enabled 10978 * @WMI_TLV_FLAG_CTSENA: CTS enabled 10979 * @WMI_TLV_FLAG_LDPC: LDPC is set 10980 * @WMI_TLV_FLAG_SGI: Short gaurd interval 10981 * @WMI_TLV_FLAG_SU: SU Data 10982 * @WMI_TLV_FLAG_DL_MU_MIMO_AC: DL AC MU data 10983 * @WMI_TLV_FLAG_DL_MU_MIMO_AX: DL AX MU data 10984 * @WMI_TLV_FLAG_DL_OFDMA: DL OFDMA data 10985 * @WMI_TLV_FLAG_UL_OFDMA: UL OFDMA data 10986 * @WMI_TLV_FLAG_UL_MU_MIMO: UL MU data 10987 * 10988 * @WMI_TLV_FLAG_BW_MASK: bandwidth mask 10989 * @WMI_TLV_FLAG_BW_SHIFT: bandwidth shift 10990 * @WMI_TLV_FLAG_SU_MU_OFDMA_MASK: su/mu/ofdma mask 10991 * @WMI_TLV_FLAG_SU_MU_OFDMA_shift: su/mu/ofdma shift 10992 */ 10993 enum packet_power_tlv_flags { 10994 WMI_TLV_FLAG_ONE_CHAIN = 0x00000001, 10995 WMI_TLV_FLAG_TWO_CHAIN = 0x00000003, 10996 WMI_TLV_FLAG_THREE_CHAIN = 0x00000007, 10997 WMI_TLV_FLAG_FOUR_CHAIN = 0x0000000F, 10998 WMI_TLV_FLAG_FIVE_CHAIN = 0x0000001F, 10999 WMI_TLV_FLAG_SIX_CHAIN = 0x0000003F, 11000 WMI_TLV_FLAG_SEVEN_CHAIN = 0x0000007F, 11001 WMI_TLV_FLAG_EIGHT_CHAIN = 0x0000008F, 11002 WMI_TLV_FLAG_STBC = 0x00000100, 11003 WMI_TLV_FLAG_40MHZ = 0x00000200, 11004 WMI_TLV_FLAG_80MHZ = 0x00000300, 11005 WMI_TLV_FLAG_160MHZ = 0x00000400, 11006 WMI_TLV_FLAG_TXBF = 0x00000800, 11007 WMI_TLV_FLAG_RTSENA = 0x00001000, 11008 WMI_TLV_FLAG_CTSENA = 0x00002000, 11009 WMI_TLV_FLAG_LDPC = 0x00004000, 11010 WMI_TLV_FLAG_SGI = 0x00008000, 11011 WMI_TLV_FLAG_SU = 0x00100000, 11012 WMI_TLV_FLAG_DL_MU_MIMO_AC = 0x00200000, 11013 WMI_TLV_FLAG_DL_MU_MIMO_AX = 0x00300000, 11014 WMI_TLV_FLAG_DL_OFDMA = 0x00400000, 11015 WMI_TLV_FLAG_UL_OFDMA = 0x00500000, 11016 WMI_TLV_FLAG_UL_MU_MIMO = 0x00600000, 11017 11018 WMI_TLV_FLAG_CHAIN_MASK = 0xff, 11019 WMI_TLV_FLAG_BW_MASK = 0x3, 11020 WMI_TLV_FLAG_BW_SHIFT = 9, 11021 WMI_TLV_FLAG_SU_MU_OFDMA_MASK = 0x7, 11022 WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT = 20, 11023 }; 11024 11025 /** 11026 * convert_to_power_info_rate_flags() - convert packet_power_info_params 11027 * to FW understandable format 11028 * @param: pointer to hold packet power info param 11029 * 11030 * @return FW understandable 32 bit rate flags 11031 */ 11032 static uint32_t 11033 convert_to_power_info_rate_flags(struct packet_power_info_params *param) 11034 { 11035 uint32_t rateflags = 0; 11036 11037 if (param->chainmask) 11038 rateflags |= 11039 (param->chainmask & WMI_TLV_FLAG_CHAIN_MASK); 11040 if (param->chan_width) 11041 rateflags |= 11042 ((param->chan_width & WMI_TLV_FLAG_BW_MASK) 11043 << WMI_TLV_FLAG_BW_SHIFT); 11044 if (param->su_mu_ofdma) 11045 rateflags |= 11046 ((param->su_mu_ofdma & WMI_TLV_FLAG_SU_MU_OFDMA_MASK) 11047 << WMI_TLV_FLAG_SU_MU_OFDMA_SHIFT); 11048 if (param->rate_flags & WMI_HOST_FLAG_STBC) 11049 rateflags |= WMI_TLV_FLAG_STBC; 11050 if (param->rate_flags & WMI_HOST_FLAG_LDPC) 11051 rateflags |= WMI_TLV_FLAG_LDPC; 11052 if (param->rate_flags & WMI_HOST_FLAG_TXBF) 11053 rateflags |= WMI_TLV_FLAG_TXBF; 11054 if (param->rate_flags & WMI_HOST_FLAG_RTSENA) 11055 rateflags |= WMI_TLV_FLAG_RTSENA; 11056 if (param->rate_flags & WMI_HOST_FLAG_CTSENA) 11057 rateflags |= WMI_TLV_FLAG_CTSENA; 11058 if (param->rate_flags & WMI_HOST_FLAG_SGI) 11059 rateflags |= WMI_TLV_FLAG_SGI; 11060 11061 return rateflags; 11062 } 11063 11064 /** 11065 * send_packet_power_info_get_cmd_tlv() - send request to get packet power 11066 * info to fw 11067 * @wmi_handle: wmi handle 11068 * @param: pointer to hold packet power info param 11069 * 11070 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11071 */ 11072 static QDF_STATUS 11073 send_packet_power_info_get_cmd_tlv(wmi_unified_t wmi_handle, 11074 struct packet_power_info_params *param) 11075 { 11076 wmi_pdev_get_tpc_cmd_fixed_param *cmd; 11077 wmi_buf_t wmibuf; 11078 uint8_t *buf_ptr; 11079 u_int32_t len = sizeof(wmi_pdev_get_tpc_cmd_fixed_param); 11080 11081 wmibuf = wmi_buf_alloc(wmi_handle, len); 11082 if (wmibuf == NULL) 11083 return QDF_STATUS_E_NOMEM; 11084 11085 buf_ptr = (uint8_t *)wmi_buf_data(wmibuf); 11086 11087 cmd = (wmi_pdev_get_tpc_cmd_fixed_param *)buf_ptr; 11088 WMITLV_SET_HDR(&cmd->tlv_header, 11089 WMITLV_TAG_STRUC_wmi_pdev_get_tpc_cmd_fixed_param, 11090 WMITLV_GET_STRUCT_TLVLEN( 11091 wmi_pdev_get_tpc_cmd_fixed_param)); 11092 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11093 param->pdev_id); 11094 cmd->rate_flags = convert_to_power_info_rate_flags(param); 11095 cmd->nss = param->nss; 11096 cmd->preamble = param->preamble; 11097 cmd->hw_rate = param->hw_rate; 11098 11099 WMI_LOGI("%s[%d] commandID %d, wmi_pdev_get_tpc_cmd=0x%x," 11100 "rate_flags: 0x%x, nss: %d, preamble: %d, hw_rate: %d\n", 11101 __func__, __LINE__, WMI_PDEV_GET_TPC_CMDID, *((u_int32_t *)cmd), 11102 cmd->rate_flags, cmd->nss, cmd->preamble, cmd->hw_rate); 11103 11104 wmi_mtrace(WMI_PDEV_GET_TPC_CMDID, NO_SESSION, 0); 11105 if (wmi_unified_cmd_send(wmi_handle, wmibuf, len, 11106 WMI_PDEV_GET_TPC_CMDID)) { 11107 WMI_LOGE(FL("Failed to get tpc command\n")); 11108 wmi_buf_free(wmibuf); 11109 return QDF_STATUS_E_FAILURE; 11110 } 11111 11112 return QDF_STATUS_SUCCESS; 11113 } 11114 11115 /** 11116 * send_vdev_config_ratemask_cmd_tlv() - config ratemask param in fw 11117 * @wmi_handle: wmi handle 11118 * @param: pointer to hold config ratemask params 11119 * 11120 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11121 */ 11122 static QDF_STATUS send_vdev_config_ratemask_cmd_tlv(wmi_unified_t wmi_handle, 11123 struct config_ratemask_params *param) 11124 { 11125 wmi_vdev_config_ratemask_cmd_fixed_param *cmd; 11126 wmi_buf_t buf; 11127 int32_t len = sizeof(*cmd); 11128 11129 buf = wmi_buf_alloc(wmi_handle, len); 11130 if (!buf) { 11131 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11132 return QDF_STATUS_E_FAILURE; 11133 } 11134 cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf); 11135 WMITLV_SET_HDR(&cmd->tlv_header, 11136 WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param, 11137 WMITLV_GET_STRUCT_TLVLEN( 11138 wmi_vdev_config_ratemask_cmd_fixed_param)); 11139 cmd->vdev_id = param->vdev_id; 11140 cmd->type = param->type; 11141 cmd->mask_lower32 = param->lower32; 11142 cmd->mask_higher32 = param->higher32; 11143 cmd->mask_lower32_2 = param->lower32_2; 11144 WMI_LOGI("Setting vdev ratemask vdev id = 0x%X, type = 0x%X" 11145 "mask_l32 = 0x%X mask_h32 = 0x%X mask_l32_2 = 0x%X\n", 11146 param->vdev_id, param->type, param->lower32, 11147 param->higher32, param->lower32_2); 11148 11149 wmi_mtrace(WMI_VDEV_RATEMASK_CMDID, cmd->vdev_id, 0); 11150 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11151 WMI_VDEV_RATEMASK_CMDID)) { 11152 WMI_LOGE("Seting vdev ratemask failed\n"); 11153 wmi_buf_free(buf); 11154 return QDF_STATUS_E_FAILURE; 11155 } 11156 11157 return QDF_STATUS_SUCCESS; 11158 } 11159 11160 /** 11161 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 11162 * @param: param sent from the host side 11163 * @cmd: param to be sent to the fw side 11164 */ 11165 static inline void copy_custom_aggr_bitmap( 11166 struct set_custom_aggr_size_params *param, 11167 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 11168 { 11169 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 11170 param->ac); 11171 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 11172 param->aggr_type); 11173 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11174 param->tx_aggr_size_disable); 11175 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 11176 param->rx_aggr_size_disable); 11177 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 11178 param->tx_ac_enable); 11179 } 11180 11181 /** 11182 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 11183 * @wmi_handle: wmi handle 11184 * @param: pointer to hold custom aggr size params 11185 * 11186 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11187 */ 11188 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 11189 wmi_unified_t wmi_handle, 11190 struct set_custom_aggr_size_params *param) 11191 { 11192 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 11193 wmi_buf_t buf; 11194 int32_t len = sizeof(*cmd); 11195 11196 buf = wmi_buf_alloc(wmi_handle, len); 11197 if (!buf) { 11198 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11199 return QDF_STATUS_E_FAILURE; 11200 } 11201 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 11202 wmi_buf_data(buf); 11203 WMITLV_SET_HDR(&cmd->tlv_header, 11204 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 11205 WMITLV_GET_STRUCT_TLVLEN( 11206 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 11207 cmd->vdev_id = param->vdev_id; 11208 cmd->tx_aggr_size = param->tx_aggr_size; 11209 cmd->rx_aggr_size = param->rx_aggr_size; 11210 copy_custom_aggr_bitmap(param, cmd); 11211 11212 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 11213 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 11214 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 11215 "tx_ac_enable=0x%X\n", 11216 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 11217 param->ac, param->aggr_type, param->tx_aggr_size_disable, 11218 param->rx_aggr_size_disable, param->tx_ac_enable); 11219 11220 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 11221 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11222 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 11223 WMI_LOGE("Seting custom aggregation size failed\n"); 11224 wmi_buf_free(buf); 11225 return QDF_STATUS_E_FAILURE; 11226 } 11227 11228 return QDF_STATUS_SUCCESS; 11229 } 11230 11231 /** 11232 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 11233 * @param wmi_handle : handle to WMI. 11234 * @param param : pointer to tx antenna param 11235 * 11236 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11237 */ 11238 11239 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 11240 struct set_qdepth_thresh_params *param) 11241 { 11242 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 11243 wmi_msduq_qdepth_thresh_update *cmd_update; 11244 wmi_buf_t buf; 11245 int32_t len = 0; 11246 int i; 11247 uint8_t *buf_ptr; 11248 QDF_STATUS ret; 11249 11250 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 11251 WMI_LOGE("%s: Invalid Update Count!\n", __func__); 11252 return QDF_STATUS_E_INVAL; 11253 } 11254 11255 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11256 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 11257 param->num_of_msduq_updates); 11258 buf = wmi_buf_alloc(wmi_handle, len); 11259 11260 if (!buf) { 11261 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11262 return QDF_STATUS_E_NOMEM; 11263 } 11264 11265 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11266 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 11267 buf_ptr; 11268 11269 WMITLV_SET_HDR(&cmd->tlv_header, 11270 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 11271 , WMITLV_GET_STRUCT_TLVLEN( 11272 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 11273 11274 cmd->pdev_id = 11275 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11276 cmd->vdev_id = param->vdev_id; 11277 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 11278 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 11279 11280 buf_ptr += sizeof( 11281 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 11282 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11283 param->num_of_msduq_updates * 11284 sizeof(wmi_msduq_qdepth_thresh_update)); 11285 buf_ptr += WMI_TLV_HDR_SIZE; 11286 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 11287 11288 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 11289 WMITLV_SET_HDR(&cmd_update->tlv_header, 11290 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 11291 WMITLV_GET_STRUCT_TLVLEN( 11292 wmi_msduq_qdepth_thresh_update)); 11293 cmd_update->tid_num = param->update_params[i].tid_num; 11294 cmd_update->msduq_update_mask = 11295 param->update_params[i].msduq_update_mask; 11296 cmd_update->qdepth_thresh_value = 11297 param->update_params[i].qdepth_thresh_value; 11298 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 11299 "mac_addr_upper4=%X, mac_addr_lower2:%X," 11300 " update mask=0x%X thresh val=0x%X\n", 11301 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 11302 cmd->peer_mac_address.mac_addr31to0, 11303 cmd->peer_mac_address.mac_addr47to32, 11304 cmd_update->msduq_update_mask, 11305 cmd_update->qdepth_thresh_value); 11306 cmd_update++; 11307 } 11308 11309 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 11310 cmd->vdev_id, 0); 11311 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11312 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 11313 11314 if (ret != 0) { 11315 WMI_LOGE(" %s :WMI Failed\n", __func__); 11316 wmi_buf_free(buf); 11317 } 11318 11319 return ret; 11320 } 11321 11322 /** 11323 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 11324 * @wmi_handle: wmi handle 11325 * @param: pointer to hold vap dscp tid map param 11326 * 11327 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11328 */ 11329 static QDF_STATUS 11330 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 11331 struct vap_dscp_tid_map_params *param) 11332 { 11333 wmi_buf_t buf; 11334 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 11335 int32_t len = sizeof(*cmd); 11336 11337 buf = wmi_buf_alloc(wmi_handle, len); 11338 if (!buf) { 11339 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11340 return QDF_STATUS_E_FAILURE; 11341 } 11342 11343 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 11344 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 11345 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 11346 11347 cmd->vdev_id = param->vdev_id; 11348 cmd->enable_override = 0; 11349 11350 WMI_LOGI("Setting dscp for vap id: %d\n", cmd->vdev_id); 11351 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 11352 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11353 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 11354 WMI_LOGE("Failed to set dscp cmd\n"); 11355 wmi_buf_free(buf); 11356 return QDF_STATUS_E_FAILURE; 11357 } 11358 11359 return QDF_STATUS_SUCCESS; 11360 } 11361 11362 /** 11363 * send_vdev_set_neighbour_rx_cmd_tlv() - set neighbour rx param in fw 11364 * @wmi_handle: wmi handle 11365 * @macaddr: vdev mac address 11366 * @param: pointer to hold neigbour rx param 11367 * 11368 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11369 */ 11370 static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle, 11371 uint8_t macaddr[IEEE80211_ADDR_LEN], 11372 struct set_neighbour_rx_params *param) 11373 { 11374 wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd; 11375 wmi_buf_t buf; 11376 int32_t len = sizeof(*cmd); 11377 11378 buf = wmi_buf_alloc(wmi_handle, len); 11379 if (!buf) { 11380 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11381 return QDF_STATUS_E_FAILURE; 11382 } 11383 cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf); 11384 WMITLV_SET_HDR(&cmd->tlv_header, 11385 WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param, 11386 WMITLV_GET_STRUCT_TLVLEN( 11387 wmi_vdev_filter_nrp_config_cmd_fixed_param)); 11388 cmd->vdev_id = param->vdev_id; 11389 cmd->bssid_idx = param->idx; 11390 cmd->action = param->action; 11391 cmd->type = param->type; 11392 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr); 11393 cmd->flag = 0; 11394 11395 wmi_mtrace(WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID, cmd->vdev_id, 0); 11396 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11397 WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) { 11398 WMI_LOGE("Failed to set neighbour rx param\n"); 11399 wmi_buf_free(buf); 11400 return QDF_STATUS_E_FAILURE; 11401 } 11402 11403 return QDF_STATUS_SUCCESS; 11404 } 11405 11406 /** 11407 * send_smart_ant_set_tx_ant_cmd_tlv() - WMI set tx antenna function 11408 * @param wmi_handle : handle to WMI. 11409 * @param macaddr : vdev mac address 11410 * @param param : pointer to tx antenna param 11411 * 11412 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11413 */ 11414 static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle, 11415 uint8_t macaddr[IEEE80211_ADDR_LEN], 11416 struct smart_ant_tx_ant_params *param) 11417 { 11418 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd; 11419 wmi_peer_smart_ant_set_tx_antenna_series *ant_tx_series; 11420 wmi_buf_t buf; 11421 int32_t len = 0; 11422 int i; 11423 uint8_t *buf_ptr; 11424 QDF_STATUS ret; 11425 11426 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11427 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11428 sizeof(wmi_peer_smart_ant_set_tx_antenna_series); 11429 buf = wmi_buf_alloc(wmi_handle, len); 11430 11431 if (!buf) { 11432 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11433 return QDF_STATUS_E_NOMEM; 11434 } 11435 11436 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11437 qdf_mem_zero(buf_ptr, len); 11438 cmd = (wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *)buf_ptr; 11439 11440 WMITLV_SET_HDR(&cmd->tlv_header, 11441 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param, 11442 WMITLV_GET_STRUCT_TLVLEN( 11443 wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param)); 11444 11445 cmd->vdev_id = param->vdev_id; 11446 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11447 11448 buf_ptr += sizeof(wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param); 11449 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11450 sizeof(wmi_peer_smart_ant_set_tx_antenna_series)); 11451 buf_ptr += WMI_TLV_HDR_SIZE; 11452 ant_tx_series = (wmi_peer_smart_ant_set_tx_antenna_series *)buf_ptr; 11453 11454 for (i = 0; i < WMI_SMART_ANT_MAX_RATE_SERIES; i++) { 11455 WMITLV_SET_HDR(&ant_tx_series->tlv_header, 11456 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_tx_antenna_series, 11457 WMITLV_GET_STRUCT_TLVLEN( 11458 wmi_peer_smart_ant_set_tx_antenna_series)); 11459 ant_tx_series->antenna_series = param->antenna_array[i]; 11460 ant_tx_series++; 11461 } 11462 11463 wmi_mtrace(WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, cmd->vdev_id, 0); 11464 ret = wmi_unified_cmd_send(wmi_handle, 11465 buf, 11466 len, 11467 WMI_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID); 11468 11469 if (ret != 0) { 11470 WMI_LOGE(" %s :WMI Failed\n", __func__); 11471 wmi_buf_free(buf); 11472 } 11473 11474 return ret; 11475 } 11476 11477 /** 11478 * send_set_ant_switch_tbl_cmd_tlv() - send ant switch tbl cmd to fw 11479 * @wmi_handle: wmi handle 11480 * @param: pointer to hold ant switch tbl param 11481 * 11482 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11483 */ 11484 static QDF_STATUS 11485 send_set_ant_switch_tbl_cmd_tlv(wmi_unified_t wmi_handle, 11486 struct ant_switch_tbl_params *param) 11487 { 11488 uint8_t len; 11489 wmi_buf_t buf; 11490 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *cmd; 11491 wmi_pdev_set_ant_ctrl_chain *ctrl_chain; 11492 uint8_t *buf_ptr; 11493 11494 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11495 len += sizeof(wmi_pdev_set_ant_ctrl_chain); 11496 buf = wmi_buf_alloc(wmi_handle, len); 11497 11498 if (!buf) { 11499 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11500 return QDF_STATUS_E_NOMEM; 11501 } 11502 11503 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11504 qdf_mem_zero(buf_ptr, len); 11505 cmd = (wmi_pdev_set_ant_switch_tbl_cmd_fixed_param *)buf_ptr; 11506 11507 WMITLV_SET_HDR(&cmd->tlv_header, 11508 WMITLV_TAG_STRUC_wmi_pdev_set_ant_switch_tbl_cmd_fixed_param, 11509 WMITLV_GET_STRUCT_TLVLEN( 11510 wmi_pdev_set_ant_switch_tbl_cmd_fixed_param)); 11511 11512 cmd->antCtrlCommon1 = param->ant_ctrl_common1; 11513 cmd->antCtrlCommon2 = param->ant_ctrl_common2; 11514 cmd->mac_id = 11515 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11516 11517 /* TLV indicating array of structures to follow */ 11518 buf_ptr += sizeof(wmi_pdev_set_ant_switch_tbl_cmd_fixed_param); 11519 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11520 sizeof(wmi_pdev_set_ant_ctrl_chain)); 11521 buf_ptr += WMI_TLV_HDR_SIZE; 11522 ctrl_chain = (wmi_pdev_set_ant_ctrl_chain *)buf_ptr; 11523 11524 ctrl_chain->pdev_id = 11525 wmi_handle->ops->convert_pdev_id_host_to_target(param->pdev_id); 11526 ctrl_chain->antCtrlChain = param->antCtrlChain; 11527 11528 wmi_mtrace(WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, NO_SESSION, 0); 11529 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11530 WMI_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID)) { 11531 wmi_buf_free(buf); 11532 return QDF_STATUS_E_FAILURE; 11533 } 11534 11535 return QDF_STATUS_SUCCESS; 11536 } 11537 11538 /** 11539 * send_smart_ant_set_training_info_cmd_tlv() - WMI set smart antenna 11540 * training information function 11541 * @param wmi_handle : handle to WMI. 11542 * @macaddr : vdev mac address 11543 * @param param : pointer to tx antenna param 11544 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11545 */ 11546 static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv( 11547 wmi_unified_t wmi_handle, 11548 uint8_t macaddr[IEEE80211_ADDR_LEN], 11549 struct smart_ant_training_info_params *param) 11550 { 11551 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd; 11552 wmi_peer_smart_ant_set_train_antenna_param *train_param; 11553 wmi_buf_t buf; 11554 uint8_t *buf_ptr; 11555 int32_t len = 0; 11556 QDF_STATUS ret; 11557 int loop; 11558 11559 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11560 len += (WMI_SMART_ANT_MAX_RATE_SERIES) * 11561 sizeof(wmi_peer_smart_ant_set_train_antenna_param); 11562 buf = wmi_buf_alloc(wmi_handle, len); 11563 11564 if (!buf) { 11565 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11566 return QDF_STATUS_E_NOMEM; 11567 } 11568 11569 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11570 qdf_mem_zero(buf_ptr, len); 11571 cmd = (wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *)buf_ptr; 11572 11573 WMITLV_SET_HDR(&cmd->tlv_header, 11574 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param, 11575 WMITLV_GET_STRUCT_TLVLEN( 11576 wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param)); 11577 11578 cmd->vdev_id = param->vdev_id; 11579 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11580 cmd->num_pkts = param->numpkts; 11581 11582 buf_ptr += sizeof(wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param); 11583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11584 sizeof(wmi_peer_smart_ant_set_train_antenna_param) * 11585 WMI_SMART_ANT_MAX_RATE_SERIES); 11586 11587 buf_ptr += WMI_TLV_HDR_SIZE; 11588 train_param = (wmi_peer_smart_ant_set_train_antenna_param *)buf_ptr; 11589 11590 for (loop = 0; loop < WMI_SMART_ANT_MAX_RATE_SERIES; loop++) { 11591 WMITLV_SET_HDR(&train_param->tlv_header, 11592 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_train_antenna_param, 11593 WMITLV_GET_STRUCT_TLVLEN( 11594 wmi_peer_smart_ant_set_train_antenna_param)); 11595 train_param->train_rate_series = param->rate_array[loop]; 11596 train_param->train_antenna_series = param->antenna_array[loop]; 11597 train_param->rc_flags = 0; 11598 WMI_LOGI(FL("Series number:%d\n"), loop); 11599 WMI_LOGI(FL("Rate [0x%02x] Tx_Antenna [0x%08x]\n"), 11600 train_param->train_rate_series, 11601 train_param->train_antenna_series); 11602 train_param++; 11603 } 11604 11605 wmi_mtrace(WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, cmd->vdev_id, 0); 11606 ret = wmi_unified_cmd_send(wmi_handle, 11607 buf, 11608 len, 11609 WMI_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID); 11610 11611 if (ret != 0) { 11612 WMI_LOGE(" %s :WMI Failed\n", __func__); 11613 wmi_buf_free(buf); 11614 return QDF_STATUS_E_FAILURE; 11615 } 11616 11617 return ret; 11618 } 11619 11620 /** 11621 * send_smart_ant_set_node_config_cmd_tlv() - WMI set node 11622 * configuration function 11623 * @param wmi_handle : handle to WMI. 11624 * @macaddr : vdev mad address 11625 * @param param : pointer to tx antenna param 11626 * 11627 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11628 */ 11629 static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv( 11630 wmi_unified_t wmi_handle, 11631 uint8_t macaddr[IEEE80211_ADDR_LEN], 11632 struct smart_ant_node_config_params *param) 11633 { 11634 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd; 11635 wmi_buf_t buf; 11636 uint8_t *buf_ptr; 11637 int32_t len = 0, args_tlv_len; 11638 int ret; 11639 int i = 0; 11640 uint32_t *node_config_args; 11641 11642 args_tlv_len = WMI_TLV_HDR_SIZE + param->args_count * sizeof(uint32_t); 11643 len = sizeof(*cmd) + args_tlv_len; 11644 11645 if (param->args_count == 0) { 11646 WMI_LOGE("%s: Can't send a command with %d arguments\n", 11647 __func__, param->args_count); 11648 return QDF_STATUS_E_FAILURE; 11649 } 11650 11651 buf = wmi_buf_alloc(wmi_handle, len); 11652 if (!buf) { 11653 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11654 return QDF_STATUS_E_NOMEM; 11655 } 11656 11657 cmd = (wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *) 11658 wmi_buf_data(buf); 11659 buf_ptr = (uint8_t *)cmd; 11660 WMITLV_SET_HDR(&cmd->tlv_header, 11661 WMITLV_TAG_STRUC_wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param, 11662 WMITLV_GET_STRUCT_TLVLEN( 11663 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param)); 11664 cmd->vdev_id = param->vdev_id; 11665 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11666 cmd->cmd_id = param->cmd_id; 11667 cmd->args_count = param->args_count; 11668 buf_ptr += sizeof( 11669 wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param); 11670 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11671 (cmd->args_count * sizeof(uint32_t))); 11672 buf_ptr += WMI_TLV_HDR_SIZE; 11673 node_config_args = (uint32_t *)buf_ptr; 11674 11675 for (i = 0; i < param->args_count; i++) { 11676 node_config_args[i] = param->args_arr[i]; 11677 WMI_LOGI("%d", param->args_arr[i]); 11678 } 11679 11680 wmi_mtrace(WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID, 11681 cmd->vdev_id, 0); 11682 ret = wmi_unified_cmd_send(wmi_handle, 11683 buf, 11684 len, 11685 WMI_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID); 11686 11687 if (ret != 0) { 11688 WMI_LOGE("%s: WMI FAILED:Sent cmd_id: 0x%x\n Node: %02x:%02x:%02x:%02x:%02x:%02x cmdstatus=%d\n", 11689 __func__, param->cmd_id, macaddr[0], 11690 macaddr[1], macaddr[2], macaddr[3], 11691 macaddr[4], macaddr[5], ret); 11692 wmi_buf_free(buf); 11693 } 11694 11695 return ret; 11696 } 11697 11698 #ifdef WLAN_ATF_ENABLE 11699 /** 11700 * send_set_atf_cmd_tlv() - send set atf command to fw 11701 * @wmi_handle: wmi handle 11702 * @param: pointer to set atf param 11703 * 11704 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11705 */ 11706 static QDF_STATUS 11707 send_set_atf_cmd_tlv(wmi_unified_t wmi_handle, 11708 struct set_atf_params *param) 11709 { 11710 wmi_atf_peer_info *peer_info; 11711 wmi_peer_atf_request_fixed_param *cmd; 11712 wmi_buf_t buf; 11713 uint8_t *buf_ptr; 11714 int i; 11715 int32_t len = 0; 11716 QDF_STATUS retval; 11717 11718 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 11719 len += param->num_peers * sizeof(wmi_atf_peer_info); 11720 buf = wmi_buf_alloc(wmi_handle, len); 11721 if (!buf) { 11722 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11723 return QDF_STATUS_E_FAILURE; 11724 } 11725 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11726 cmd = (wmi_peer_atf_request_fixed_param *)buf_ptr; 11727 WMITLV_SET_HDR(&cmd->tlv_header, 11728 WMITLV_TAG_STRUC_wmi_peer_atf_request_fixed_param, 11729 WMITLV_GET_STRUCT_TLVLEN( 11730 wmi_peer_atf_request_fixed_param)); 11731 cmd->num_peers = param->num_peers; 11732 11733 buf_ptr += sizeof(*cmd); 11734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11735 sizeof(wmi_atf_peer_info) * 11736 cmd->num_peers); 11737 buf_ptr += WMI_TLV_HDR_SIZE; 11738 peer_info = (wmi_atf_peer_info *)buf_ptr; 11739 11740 for (i = 0; i < cmd->num_peers; i++) { 11741 WMITLV_SET_HDR(&peer_info->tlv_header, 11742 WMITLV_TAG_STRUC_wmi_atf_peer_info, 11743 WMITLV_GET_STRUCT_TLVLEN( 11744 wmi_atf_peer_info)); 11745 qdf_mem_copy(&(peer_info->peer_macaddr), 11746 &(param->peer_info[i].peer_macaddr), 11747 sizeof(wmi_mac_addr)); 11748 peer_info->atf_units = param->peer_info[i].percentage_peer; 11749 peer_info->vdev_id = param->peer_info[i].vdev_id; 11750 peer_info->pdev_id = 11751 wmi_handle->ops->convert_pdev_id_host_to_target( 11752 param->peer_info[i].pdev_id); 11753 /* 11754 * TLV definition for peer atf request fixed param combines 11755 * extension stats. Legacy FW for WIN (Non-TLV) has peer atf 11756 * stats and atf extension stats as two different 11757 * implementations. 11758 * Need to discuss with FW on this. 11759 * 11760 * peer_info->atf_groupid = param->peer_ext_info[i].group_index; 11761 * peer_info->atf_units_reserved = 11762 * param->peer_ext_info[i].atf_index_reserved; 11763 */ 11764 peer_info++; 11765 } 11766 11767 wmi_mtrace(WMI_PEER_ATF_REQUEST_CMDID, NO_SESSION, 0); 11768 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11769 WMI_PEER_ATF_REQUEST_CMDID); 11770 11771 if (retval != QDF_STATUS_SUCCESS) { 11772 WMI_LOGE("%s : WMI Failed\n", __func__); 11773 wmi_buf_free(buf); 11774 } 11775 11776 return retval; 11777 } 11778 #endif 11779 11780 /** 11781 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 11782 * @wmi_handle: wmi handle 11783 * @param: pointer to hold fwtest param 11784 * 11785 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11786 */ 11787 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 11788 struct set_fwtest_params *param) 11789 { 11790 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11791 wmi_buf_t buf; 11792 int32_t len = sizeof(*cmd); 11793 11794 buf = wmi_buf_alloc(wmi_handle, len); 11795 11796 if (!buf) { 11797 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11798 return QDF_STATUS_E_FAILURE; 11799 } 11800 11801 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 11802 WMITLV_SET_HDR(&cmd->tlv_header, 11803 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11804 WMITLV_GET_STRUCT_TLVLEN( 11805 wmi_fwtest_set_param_cmd_fixed_param)); 11806 cmd->param_id = param->arg; 11807 cmd->param_value = param->value; 11808 11809 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11810 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 11811 WMI_LOGE("Setting FW test param failed\n"); 11812 wmi_buf_free(buf); 11813 return QDF_STATUS_E_FAILURE; 11814 } 11815 11816 return QDF_STATUS_SUCCESS; 11817 } 11818 11819 /** 11820 * send_set_qboost_param_cmd_tlv() - send set qboost command to fw 11821 * @wmi_handle: wmi handle 11822 * @param: pointer to qboost params 11823 * @macaddr: vdev mac address 11824 * 11825 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11826 */ 11827 static QDF_STATUS 11828 send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle, 11829 uint8_t macaddr[IEEE80211_ADDR_LEN], 11830 struct set_qboost_params *param) 11831 { 11832 WMI_QBOOST_CFG_CMD_fixed_param *cmd; 11833 wmi_buf_t buf; 11834 int32_t len; 11835 QDF_STATUS ret; 11836 11837 len = sizeof(*cmd); 11838 11839 buf = wmi_buf_alloc(wmi_handle, len); 11840 if (!buf) { 11841 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11842 return QDF_STATUS_E_FAILURE; 11843 } 11844 11845 cmd = (WMI_QBOOST_CFG_CMD_fixed_param *)wmi_buf_data(buf); 11846 WMITLV_SET_HDR(&cmd->tlv_header, 11847 WMITLV_TAG_STRUC_WMI_QBOOST_CFG_CMD_fixed_param, 11848 WMITLV_GET_STRUCT_TLVLEN( 11849 WMI_QBOOST_CFG_CMD_fixed_param)); 11850 cmd->vdev_id = param->vdev_id; 11851 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11852 cmd->qb_enable = param->value; 11853 11854 wmi_mtrace(WMI_QBOOST_CFG_CMDID, cmd->vdev_id, 0); 11855 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11856 WMI_QBOOST_CFG_CMDID); 11857 11858 if (ret != 0) { 11859 WMI_LOGE("Setting qboost cmd failed\n"); 11860 wmi_buf_free(buf); 11861 } 11862 11863 return ret; 11864 } 11865 11866 /** 11867 * send_gpio_config_cmd_tlv() - send gpio config to fw 11868 * @wmi_handle: wmi handle 11869 * @param: pointer to hold gpio config param 11870 * 11871 * Return: 0 for success or error code 11872 */ 11873 static QDF_STATUS 11874 send_gpio_config_cmd_tlv(wmi_unified_t wmi_handle, 11875 struct gpio_config_params *param) 11876 { 11877 wmi_gpio_config_cmd_fixed_param *cmd; 11878 wmi_buf_t buf; 11879 int32_t len; 11880 QDF_STATUS ret; 11881 11882 len = sizeof(*cmd); 11883 11884 /* Sanity Checks */ 11885 if (param->pull_type > WMI_GPIO_PULL_DOWN || 11886 param->intr_mode > WMI_GPIO_INTTYPE_LEVEL_HIGH) { 11887 return QDF_STATUS_E_FAILURE; 11888 } 11889 11890 buf = wmi_buf_alloc(wmi_handle, len); 11891 if (!buf) { 11892 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11893 return QDF_STATUS_E_FAILURE; 11894 } 11895 11896 cmd = (wmi_gpio_config_cmd_fixed_param *)wmi_buf_data(buf); 11897 WMITLV_SET_HDR(&cmd->tlv_header, 11898 WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, 11899 WMITLV_GET_STRUCT_TLVLEN( 11900 wmi_gpio_config_cmd_fixed_param)); 11901 cmd->gpio_num = param->gpio_num; 11902 cmd->input = param->input; 11903 cmd->pull_type = param->pull_type; 11904 cmd->intr_mode = param->intr_mode; 11905 11906 wmi_mtrace(WMI_GPIO_CONFIG_CMDID, NO_SESSION, 0); 11907 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11908 WMI_GPIO_CONFIG_CMDID); 11909 11910 if (ret != 0) { 11911 WMI_LOGE("Sending GPIO config cmd failed\n"); 11912 wmi_buf_free(buf); 11913 } 11914 11915 return ret; 11916 } 11917 11918 /** 11919 * send_gpio_output_cmd_tlv() - send gpio output to fw 11920 * @wmi_handle: wmi handle 11921 * @param: pointer to hold gpio output param 11922 * 11923 * Return: 0 for success or error code 11924 */ 11925 static QDF_STATUS 11926 send_gpio_output_cmd_tlv(wmi_unified_t wmi_handle, 11927 struct gpio_output_params *param) 11928 { 11929 wmi_gpio_output_cmd_fixed_param *cmd; 11930 wmi_buf_t buf; 11931 int32_t len; 11932 QDF_STATUS ret; 11933 11934 len = sizeof(*cmd); 11935 11936 buf = wmi_buf_alloc(wmi_handle, len); 11937 if (!buf) { 11938 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11939 return QDF_STATUS_E_FAILURE; 11940 } 11941 11942 cmd = (wmi_gpio_output_cmd_fixed_param *)wmi_buf_data(buf); 11943 WMITLV_SET_HDR(&cmd->tlv_header, 11944 WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, 11945 WMITLV_GET_STRUCT_TLVLEN( 11946 wmi_gpio_output_cmd_fixed_param)); 11947 cmd->gpio_num = param->gpio_num; 11948 cmd->set = param->set; 11949 11950 wmi_mtrace(WMI_GPIO_OUTPUT_CMDID, NO_SESSION, 0); 11951 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11952 WMI_GPIO_OUTPUT_CMDID); 11953 11954 if (ret != 0) { 11955 WMI_LOGE("Sending GPIO output cmd failed\n"); 11956 wmi_buf_free(buf); 11957 } 11958 11959 return ret; 11960 11961 } 11962 11963 /** 11964 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 11965 * 11966 * @param wmi_handle : handle to WMI. 11967 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 11968 */ 11969 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 11970 { 11971 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 11972 wmi_buf_t buf; 11973 QDF_STATUS ret; 11974 int32_t len; 11975 11976 len = sizeof(*cmd); 11977 11978 buf = wmi_buf_alloc(wmi_handle, len); 11979 if (!buf) { 11980 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 11981 return QDF_STATUS_E_FAILURE; 11982 } 11983 11984 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 11985 WMITLV_SET_HDR(&cmd->tlv_header, 11986 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 11987 WMITLV_GET_STRUCT_TLVLEN( 11988 wmi_pdev_dfs_disable_cmd_fixed_param)); 11989 /* Filling it with WMI_PDEV_ID_SOC for now */ 11990 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11991 WMI_HOST_PDEV_ID_SOC); 11992 11993 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 11994 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 11995 WMI_PDEV_DFS_DISABLE_CMDID); 11996 11997 if (ret != 0) { 11998 WMI_LOGE("Sending PDEV DFS disable cmd failed\n"); 11999 wmi_buf_free(buf); 12000 } 12001 12002 return ret; 12003 } 12004 12005 /** 12006 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 12007 * 12008 * @param wmi_handle : handle to WMI. 12009 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12010 */ 12011 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 12012 { 12013 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 12014 wmi_buf_t buf; 12015 QDF_STATUS ret; 12016 int32_t len; 12017 12018 len = sizeof(*cmd); 12019 12020 buf = wmi_buf_alloc(wmi_handle, len); 12021 if (!buf) { 12022 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12023 return QDF_STATUS_E_FAILURE; 12024 } 12025 12026 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 12027 WMITLV_SET_HDR(&cmd->tlv_header, 12028 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 12029 WMITLV_GET_STRUCT_TLVLEN( 12030 wmi_pdev_dfs_enable_cmd_fixed_param)); 12031 /* Reserved for future use */ 12032 cmd->reserved0 = 0; 12033 12034 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 12035 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12036 WMI_PDEV_DFS_ENABLE_CMDID); 12037 12038 if (ret != 0) { 12039 WMI_LOGE("Sending PDEV DFS enable cmd failed\n"); 12040 wmi_buf_free(buf); 12041 } 12042 12043 return ret; 12044 } 12045 12046 /** 12047 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 12048 * to fw 12049 * @wmi_handle: wmi handle 12050 * @param: pointer to hold periodic chan stats param 12051 * 12052 * Return: 0 for success or error code 12053 */ 12054 static QDF_STATUS 12055 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 12056 struct periodic_chan_stats_params *param) 12057 { 12058 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 12059 wmi_buf_t buf; 12060 QDF_STATUS ret; 12061 int32_t len; 12062 12063 len = sizeof(*cmd); 12064 12065 buf = wmi_buf_alloc(wmi_handle, len); 12066 if (!buf) { 12067 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12068 return QDF_STATUS_E_FAILURE; 12069 } 12070 12071 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 12072 wmi_buf_data(buf); 12073 WMITLV_SET_HDR(&cmd->tlv_header, 12074 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 12075 WMITLV_GET_STRUCT_TLVLEN( 12076 wmi_set_periodic_channel_stats_config_fixed_param)); 12077 cmd->enable = param->enable; 12078 cmd->stats_period = param->stats_period; 12079 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12080 param->pdev_id); 12081 12082 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 12083 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 12084 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 12085 12086 if (ret != 0) { 12087 WMI_LOGE("Sending periodic chan stats config failed"); 12088 wmi_buf_free(buf); 12089 } 12090 12091 return ret; 12092 } 12093 12094 /** 12095 * send_nf_dbr_dbm_info_get_cmd_tlv() - send request to get nf to fw 12096 * @wmi_handle: wmi handle 12097 * @mac_id: radio context 12098 * 12099 * Return: 0 for success or error code 12100 */ 12101 static QDF_STATUS 12102 send_nf_dbr_dbm_info_get_cmd_tlv(wmi_unified_t wmi_handle, uint8_t mac_id) 12103 { 12104 wmi_buf_t buf; 12105 QDF_STATUS ret; 12106 wmi_pdev_get_nfcal_power_fixed_param *cmd; 12107 int32_t len = sizeof(*cmd); 12108 12109 buf = wmi_buf_alloc(wmi_handle, len); 12110 if (buf == NULL) 12111 return QDF_STATUS_E_NOMEM; 12112 12113 cmd = (wmi_pdev_get_nfcal_power_fixed_param *)wmi_buf_data(buf); 12114 WMITLV_SET_HDR(&cmd->tlv_header, 12115 WMITLV_TAG_STRUC_wmi_pdev_get_nfcal_power_fixed_param, 12116 WMITLV_GET_STRUCT_TLVLEN 12117 (wmi_pdev_get_nfcal_power_fixed_param)); 12118 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(mac_id); 12119 12120 wmi_mtrace(WMI_PDEV_GET_NFCAL_POWER_CMDID, NO_SESSION, 0); 12121 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12122 WMI_PDEV_GET_NFCAL_POWER_CMDID); 12123 if (ret != 0) { 12124 WMI_LOGE("Sending get nfcal power cmd failed\n"); 12125 wmi_buf_free(buf); 12126 } 12127 12128 return ret; 12129 } 12130 12131 /** 12132 * send_set_ht_ie_cmd_tlv() - send ht ie command to fw 12133 * @wmi_handle: wmi handle 12134 * @param: pointer to ht ie param 12135 * 12136 * Return: 0 for success or error code 12137 */ 12138 static QDF_STATUS 12139 send_set_ht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12140 struct ht_ie_params *param) 12141 { 12142 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd; 12143 wmi_buf_t buf; 12144 QDF_STATUS ret; 12145 int32_t len; 12146 uint8_t *buf_ptr; 12147 12148 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12149 roundup(param->ie_len, sizeof(uint32_t)); 12150 12151 buf = wmi_buf_alloc(wmi_handle, len); 12152 if (!buf) { 12153 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12154 return QDF_STATUS_E_FAILURE; 12155 } 12156 12157 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12158 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *)buf_ptr; 12159 WMITLV_SET_HDR(&cmd->tlv_header, 12160 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, 12161 WMITLV_GET_STRUCT_TLVLEN( 12162 wmi_pdev_set_ht_ie_cmd_fixed_param)); 12163 cmd->reserved0 = 0; 12164 cmd->ie_len = param->ie_len; 12165 cmd->tx_streams = param->tx_streams; 12166 cmd->rx_streams = param->rx_streams; 12167 12168 buf_ptr += sizeof(*cmd); 12169 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12170 buf_ptr += WMI_TLV_HDR_SIZE; 12171 if (param->ie_len) 12172 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12173 cmd->ie_len); 12174 12175 wmi_mtrace(WMI_PDEV_SET_HT_CAP_IE_CMDID, NO_SESSION, 0); 12176 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12177 WMI_PDEV_SET_HT_CAP_IE_CMDID); 12178 12179 if (ret != 0) { 12180 WMI_LOGE("Sending set ht ie cmd failed\n"); 12181 wmi_buf_free(buf); 12182 } 12183 12184 return ret; 12185 } 12186 12187 /** 12188 * send_set_vht_ie_cmd_tlv() - send vht ie command to fw 12189 * @wmi_handle: wmi handle 12190 * @param: pointer to vht ie param 12191 * 12192 * Return: 0 for success or error code 12193 */ 12194 static QDF_STATUS 12195 send_set_vht_ie_cmd_tlv(wmi_unified_t wmi_handle, 12196 struct vht_ie_params *param) 12197 { 12198 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd; 12199 wmi_buf_t buf; 12200 QDF_STATUS ret; 12201 int32_t len; 12202 uint8_t *buf_ptr; 12203 12204 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 12205 roundup(param->ie_len, sizeof(uint32_t)); 12206 12207 buf = wmi_buf_alloc(wmi_handle, len); 12208 if (!buf) { 12209 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12210 return QDF_STATUS_E_FAILURE; 12211 } 12212 12213 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12214 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *)buf_ptr; 12215 WMITLV_SET_HDR(&cmd->tlv_header, 12216 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, 12217 WMITLV_GET_STRUCT_TLVLEN( 12218 wmi_pdev_set_vht_ie_cmd_fixed_param)); 12219 cmd->reserved0 = 0; 12220 cmd->ie_len = param->ie_len; 12221 cmd->tx_streams = param->tx_streams; 12222 cmd->rx_streams = param->rx_streams; 12223 12224 buf_ptr += sizeof(*cmd); 12225 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->ie_len); 12226 buf_ptr += WMI_TLV_HDR_SIZE; 12227 if (param->ie_len) 12228 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->ie_data, 12229 cmd->ie_len); 12230 12231 wmi_mtrace(WMI_PDEV_SET_VHT_CAP_IE_CMDID, NO_SESSION, 0); 12232 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12233 WMI_PDEV_SET_VHT_CAP_IE_CMDID); 12234 12235 if (ret != 0) { 12236 WMI_LOGE("Sending set vht ie cmd failed\n"); 12237 wmi_buf_free(buf); 12238 } 12239 12240 return ret; 12241 } 12242 12243 /** 12244 * send_set_quiet_mode_cmd_tlv() - send set quiet mode command to fw 12245 * @wmi_handle: wmi handle 12246 * @param: pointer to quiet mode params 12247 * 12248 * Return: 0 for success or error code 12249 */ 12250 static QDF_STATUS 12251 send_set_quiet_mode_cmd_tlv(wmi_unified_t wmi_handle, 12252 struct set_quiet_mode_params *param) 12253 { 12254 wmi_pdev_set_quiet_cmd_fixed_param *quiet_cmd; 12255 wmi_buf_t buf; 12256 QDF_STATUS ret; 12257 int32_t len; 12258 12259 len = sizeof(*quiet_cmd); 12260 buf = wmi_buf_alloc(wmi_handle, len); 12261 if (!buf) { 12262 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12263 return QDF_STATUS_E_FAILURE; 12264 } 12265 12266 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12267 WMITLV_SET_HDR(&quiet_cmd->tlv_header, 12268 WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, 12269 WMITLV_GET_STRUCT_TLVLEN( 12270 wmi_pdev_set_quiet_cmd_fixed_param)); 12271 quiet_cmd = (wmi_pdev_set_quiet_cmd_fixed_param *)wmi_buf_data(buf); 12272 quiet_cmd->enabled = param->enabled; 12273 quiet_cmd->period = (param->period)*(param->intval); 12274 quiet_cmd->duration = param->duration; 12275 quiet_cmd->next_start = param->offset; 12276 quiet_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12277 WMI_HOST_PDEV_ID_SOC); 12278 12279 wmi_mtrace(WMI_PDEV_SET_QUIET_MODE_CMDID, NO_SESSION, 0); 12280 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12281 WMI_PDEV_SET_QUIET_MODE_CMDID); 12282 12283 if (ret != 0) { 12284 WMI_LOGE("Sending set quiet cmd failed\n"); 12285 wmi_buf_free(buf); 12286 } 12287 12288 return ret; 12289 } 12290 12291 /** 12292 * send_set_bwf_cmd_tlv() - send set bwf command to fw 12293 * @wmi_handle: wmi handle 12294 * @param: pointer to set bwf param 12295 * 12296 * Return: 0 for success or error code 12297 */ 12298 static QDF_STATUS 12299 send_set_bwf_cmd_tlv(wmi_unified_t wmi_handle, 12300 struct set_bwf_params *param) 12301 { 12302 wmi_bwf_peer_info *peer_info; 12303 wmi_peer_bwf_request_fixed_param *cmd; 12304 wmi_buf_t buf; 12305 QDF_STATUS retval; 12306 int32_t len; 12307 uint8_t *buf_ptr; 12308 int i; 12309 12310 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 12311 len += param->num_peers * sizeof(wmi_bwf_peer_info); 12312 buf = wmi_buf_alloc(wmi_handle, len); 12313 if (!buf) { 12314 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 12315 return QDF_STATUS_E_FAILURE; 12316 } 12317 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12318 cmd = (wmi_peer_bwf_request_fixed_param *)buf_ptr; 12319 WMITLV_SET_HDR(&cmd->tlv_header, 12320 WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, 12321 WMITLV_GET_STRUCT_TLVLEN( 12322 wmi_peer_bwf_request_fixed_param)); 12323 cmd->num_peers = param->num_peers; 12324 12325 buf_ptr += sizeof(*cmd); 12326 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12327 sizeof(wmi_bwf_peer_info) * 12328 cmd->num_peers); 12329 buf_ptr += WMI_TLV_HDR_SIZE; 12330 peer_info = (wmi_bwf_peer_info *)buf_ptr; 12331 12332 for (i = 0; i < cmd->num_peers; i++) { 12333 WMITLV_SET_HDR(&peer_info->tlv_header, 12334 WMITLV_TAG_STRUC_wmi_bwf_peer_info, 12335 WMITLV_GET_STRUCT_TLVLEN(wmi_bwf_peer_info)); 12336 peer_info->bwf_guaranteed_bandwidth = 12337 param->peer_info[i].throughput; 12338 peer_info->bwf_max_airtime = 12339 param->peer_info[i].max_airtime; 12340 peer_info->bwf_peer_priority = 12341 param->peer_info[i].priority; 12342 qdf_mem_copy(&peer_info->peer_macaddr, 12343 ¶m->peer_info[i].peer_macaddr, 12344 sizeof(param->peer_info[i].peer_macaddr)); 12345 peer_info->vdev_id = 12346 param->peer_info[i].vdev_id; 12347 peer_info->pdev_id = 12348 wmi_handle->ops->convert_pdev_id_host_to_target( 12349 param->peer_info[i].pdev_id); 12350 peer_info++; 12351 } 12352 12353 wmi_mtrace(WMI_PEER_BWF_REQUEST_CMDID, NO_SESSION, 0); 12354 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 12355 WMI_PEER_BWF_REQUEST_CMDID); 12356 12357 if (retval != QDF_STATUS_SUCCESS) { 12358 WMI_LOGE("%s : WMI Failed\n", __func__); 12359 wmi_buf_free(buf); 12360 } 12361 12362 return retval; 12363 } 12364 12365 /** 12366 * send_mcast_group_update_cmd_tlv() - send mcast group update cmd to fw 12367 * @wmi_handle: wmi handle 12368 * @param: pointer to hold mcast update param 12369 * 12370 * Return: 0 for success or error code 12371 */ 12372 static QDF_STATUS 12373 send_mcast_group_update_cmd_tlv(wmi_unified_t wmi_handle, 12374 struct mcast_group_update_params *param) 12375 { 12376 wmi_peer_mcast_group_cmd_fixed_param *cmd; 12377 wmi_buf_t buf; 12378 QDF_STATUS ret; 12379 int32_t len; 12380 int offset = 0; 12381 static char dummymask[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; 12382 12383 len = sizeof(*cmd); 12384 buf = wmi_buf_alloc(wmi_handle, len); 12385 if (!buf) { 12386 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12387 return QDF_STATUS_E_FAILURE; 12388 } 12389 cmd = (wmi_peer_mcast_group_cmd_fixed_param *)wmi_buf_data(buf); 12390 WMITLV_SET_HDR(&cmd->tlv_header, 12391 WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, 12392 WMITLV_GET_STRUCT_TLVLEN( 12393 wmi_peer_mcast_group_cmd_fixed_param)); 12394 /* confirm the buffer is 4-byte aligned */ 12395 QDF_ASSERT((((size_t) cmd) & 0x3) == 0); 12396 qdf_mem_zero(cmd, sizeof(*cmd)); 12397 12398 cmd->vdev_id = param->vap_id; 12399 /* construct the message assuming our endianness matches the target */ 12400 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_ACTION_M & 12401 (param->action << WMI_PEER_MCAST_GROUP_FLAG_ACTION_S); 12402 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M & 12403 (param->wildcard << WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S); 12404 if (param->is_action_delete) 12405 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_DELETEALL_M; 12406 12407 if (param->is_mcast_addr_len) 12408 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_IPV6_M; 12409 12410 if (param->is_filter_mode_snoop) 12411 cmd->flags |= WMI_PEER_MCAST_GROUP_FLAG_SRC_FILTER_EXCLUDE_M; 12412 12413 /* unicast address spec only applies for non-wildcard cases */ 12414 if (!param->wildcard && param->ucast_mac_addr) { 12415 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->ucast_mac_addr, 12416 &cmd->ucast_mac_addr); 12417 } 12418 12419 if (param->mcast_ip_addr) { 12420 QDF_ASSERT(param->mcast_ip_addr_bytes <= 12421 sizeof(cmd->mcast_ip_addr)); 12422 offset = sizeof(cmd->mcast_ip_addr) - 12423 param->mcast_ip_addr_bytes; 12424 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_addr) + offset, 12425 param->mcast_ip_addr, 12426 param->mcast_ip_addr_bytes); 12427 } 12428 if (!param->mask) 12429 param->mask = &dummymask[0]; 12430 12431 qdf_mem_copy(((uint8_t *)&cmd->mcast_ip_mask) + offset, 12432 param->mask, 12433 param->mcast_ip_addr_bytes); 12434 12435 if (param->srcs && param->nsrcs) { 12436 cmd->num_filter_addr = param->nsrcs; 12437 QDF_ASSERT((param->nsrcs * param->mcast_ip_addr_bytes) <= 12438 sizeof(cmd->filter_addr)); 12439 12440 qdf_mem_copy(((uint8_t *) &cmd->filter_addr), param->srcs, 12441 param->nsrcs * param->mcast_ip_addr_bytes); 12442 } 12443 12444 wmi_mtrace(WMI_PEER_MCAST_GROUP_CMDID, cmd->vdev_id, 0); 12445 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12446 WMI_PEER_MCAST_GROUP_CMDID); 12447 12448 if (ret != QDF_STATUS_SUCCESS) { 12449 WMI_LOGE("%s : WMI Failed\n", __func__); 12450 wmi_buf_free(buf); 12451 } 12452 12453 return ret; 12454 } 12455 12456 /** 12457 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 12458 * command to fw 12459 * @wmi_handle: wmi handle 12460 * @param: pointer to hold spectral config parameter 12461 * 12462 * Return: 0 for success or error code 12463 */ 12464 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 12465 struct vdev_spectral_configure_params *param) 12466 { 12467 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 12468 wmi_buf_t buf; 12469 QDF_STATUS ret; 12470 int32_t len; 12471 12472 len = sizeof(*cmd); 12473 buf = wmi_buf_alloc(wmi_handle, len); 12474 if (!buf) { 12475 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12476 return QDF_STATUS_E_FAILURE; 12477 } 12478 12479 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 12480 WMITLV_SET_HDR(&cmd->tlv_header, 12481 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 12482 WMITLV_GET_STRUCT_TLVLEN( 12483 wmi_vdev_spectral_configure_cmd_fixed_param)); 12484 12485 cmd->vdev_id = param->vdev_id; 12486 cmd->spectral_scan_count = param->count; 12487 cmd->spectral_scan_period = param->period; 12488 cmd->spectral_scan_priority = param->spectral_pri; 12489 cmd->spectral_scan_fft_size = param->fft_size; 12490 cmd->spectral_scan_gc_ena = param->gc_enable; 12491 cmd->spectral_scan_restart_ena = param->restart_enable; 12492 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 12493 cmd->spectral_scan_init_delay = param->init_delay; 12494 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 12495 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 12496 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 12497 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 12498 cmd->spectral_scan_rssi_thr = param->rssi_thr; 12499 cmd->spectral_scan_pwr_format = param->pwr_format; 12500 cmd->spectral_scan_rpt_mode = param->rpt_mode; 12501 cmd->spectral_scan_bin_scale = param->bin_scale; 12502 cmd->spectral_scan_dBm_adj = param->dbm_adj; 12503 cmd->spectral_scan_chn_mask = param->chn_mask; 12504 12505 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 12506 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12507 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 12508 12509 if (ret != 0) { 12510 WMI_LOGE("Sending set quiet cmd failed\n"); 12511 wmi_buf_free(buf); 12512 } 12513 12514 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID\n", 12515 __func__); 12516 12517 WMI_LOGI("vdev_id = %u\n" 12518 "spectral_scan_count = %u\n" 12519 "spectral_scan_period = %u\n" 12520 "spectral_scan_priority = %u\n" 12521 "spectral_scan_fft_size = %u\n" 12522 "spectral_scan_gc_ena = %u\n" 12523 "spectral_scan_restart_ena = %u\n" 12524 "spectral_scan_noise_floor_ref = %u\n" 12525 "spectral_scan_init_delay = %u\n" 12526 "spectral_scan_nb_tone_thr = %u\n" 12527 "spectral_scan_str_bin_thr = %u\n" 12528 "spectral_scan_wb_rpt_mode = %u\n" 12529 "spectral_scan_rssi_rpt_mode = %u\n" 12530 "spectral_scan_rssi_thr = %u\n" 12531 "spectral_scan_pwr_format = %u\n" 12532 "spectral_scan_rpt_mode = %u\n" 12533 "spectral_scan_bin_scale = %u\n" 12534 "spectral_scan_dBm_adj = %u\n" 12535 "spectral_scan_chn_mask = %u\n", 12536 param->vdev_id, 12537 param->count, 12538 param->period, 12539 param->spectral_pri, 12540 param->fft_size, 12541 param->gc_enable, 12542 param->restart_enable, 12543 param->noise_floor_ref, 12544 param->init_delay, 12545 param->nb_tone_thr, 12546 param->str_bin_thr, 12547 param->wb_rpt_mode, 12548 param->rssi_rpt_mode, 12549 param->rssi_thr, 12550 param->pwr_format, 12551 param->rpt_mode, 12552 param->bin_scale, 12553 param->dbm_adj, 12554 param->chn_mask); 12555 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12556 12557 return ret; 12558 } 12559 12560 /** 12561 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 12562 * command to fw 12563 * @wmi_handle: wmi handle 12564 * @param: pointer to hold spectral enable parameter 12565 * 12566 * Return: 0 for success or error code 12567 */ 12568 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 12569 struct vdev_spectral_enable_params *param) 12570 { 12571 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 12572 wmi_buf_t buf; 12573 QDF_STATUS ret; 12574 int32_t len; 12575 12576 len = sizeof(*cmd); 12577 buf = wmi_buf_alloc(wmi_handle, len); 12578 if (!buf) { 12579 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12580 return QDF_STATUS_E_FAILURE; 12581 } 12582 12583 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 12584 WMITLV_SET_HDR(&cmd->tlv_header, 12585 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 12586 WMITLV_GET_STRUCT_TLVLEN( 12587 wmi_vdev_spectral_enable_cmd_fixed_param)); 12588 12589 cmd->vdev_id = param->vdev_id; 12590 12591 if (param->active_valid) { 12592 cmd->trigger_cmd = param->active ? 1 : 2; 12593 /* 1: Trigger, 2: Clear Trigger */ 12594 } else { 12595 cmd->trigger_cmd = 0; /* 0: Ignore */ 12596 } 12597 12598 if (param->enabled_valid) { 12599 cmd->enable_cmd = param->enabled ? 1 : 2; 12600 /* 1: Enable 2: Disable */ 12601 } else { 12602 cmd->enable_cmd = 0; /* 0: Ignore */ 12603 } 12604 12605 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 12606 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12607 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 12608 12609 if (ret != 0) { 12610 WMI_LOGE("Sending scan enable CMD failed\n"); 12611 wmi_buf_free(buf); 12612 } 12613 12614 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID\n", __func__); 12615 12616 WMI_LOGI("vdev_id = %u\n" 12617 "trigger_cmd = %u\n" 12618 "enable_cmd = %u\n", 12619 cmd->vdev_id, 12620 cmd->trigger_cmd, 12621 cmd->enable_cmd); 12622 12623 WMI_LOGI("%s: Status: %d\n\n", __func__, ret); 12624 12625 return ret; 12626 } 12627 12628 /** 12629 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 12630 * @param wmi_handle : handle to WMI. 12631 * @param param : pointer to hold thermal mitigation param 12632 * 12633 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 12634 */ 12635 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 12636 wmi_unified_t wmi_handle, 12637 struct thermal_mitigation_params *param) 12638 { 12639 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 12640 wmi_therm_throt_level_config_info *lvl_conf = NULL; 12641 wmi_buf_t buf = NULL; 12642 uint8_t *buf_ptr = NULL; 12643 int error; 12644 int32_t len; 12645 int i; 12646 12647 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 12648 THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info); 12649 12650 buf = wmi_buf_alloc(wmi_handle, len); 12651 if (!buf) { 12652 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12653 return QDF_STATUS_E_NOMEM; 12654 } 12655 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 12656 12657 /* init fixed params */ 12658 WMITLV_SET_HDR(tt_conf, 12659 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 12660 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 12661 12662 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12663 param->pdev_id); 12664 tt_conf->enable = param->enable; 12665 tt_conf->dc = param->dc; 12666 tt_conf->dc_per_event = param->dc_per_event; 12667 tt_conf->therm_throt_levels = THERMAL_LEVELS; 12668 12669 buf_ptr = (uint8_t *) ++tt_conf; 12670 /* init TLV params */ 12671 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 12672 (THERMAL_LEVELS * sizeof(wmi_therm_throt_level_config_info))); 12673 12674 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 12675 for (i = 0; i < THERMAL_LEVELS; i++) { 12676 WMITLV_SET_HDR(&lvl_conf->tlv_header, 12677 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 12678 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 12679 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 12680 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 12681 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 12682 lvl_conf->prio = param->levelconf[i].priority; 12683 lvl_conf++; 12684 } 12685 12686 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 12687 error = wmi_unified_cmd_send(wmi_handle, buf, len, 12688 WMI_THERM_THROT_SET_CONF_CMDID); 12689 if (QDF_IS_STATUS_ERROR(error)) { 12690 wmi_buf_free(buf); 12691 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 12692 } 12693 12694 return error; 12695 } 12696 12697 /** 12698 * send_pdev_qvit_cmd_tlv() - send qvit command to fw 12699 * @wmi_handle: wmi handle 12700 * @param: pointer to pdev_qvit_params 12701 * 12702 * Return: 0 for success or error code 12703 */ 12704 static QDF_STATUS 12705 send_pdev_qvit_cmd_tlv(wmi_unified_t wmi_handle, 12706 struct pdev_qvit_params *param) 12707 { 12708 wmi_buf_t buf; 12709 QDF_STATUS ret = QDF_STATUS_E_INVAL; 12710 uint8_t *cmd; 12711 static uint8_t msgref = 1; 12712 uint8_t segnumber = 0, seginfo, numsegments; 12713 uint16_t chunk_len, total_bytes; 12714 uint8_t *bufpos; 12715 QVIT_SEG_HDR_INFO_STRUCT seghdrinfo; 12716 12717 bufpos = param->utf_payload; 12718 total_bytes = param->len; 12719 ASSERT(total_bytes / MAX_WMI_QVIT_LEN == 12720 (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN)); 12721 numsegments = (uint8_t) (total_bytes / MAX_WMI_QVIT_LEN); 12722 12723 if (param->len - (numsegments * MAX_WMI_QVIT_LEN)) 12724 numsegments++; 12725 12726 while (param->len) { 12727 if (param->len > MAX_WMI_QVIT_LEN) 12728 chunk_len = MAX_WMI_QVIT_LEN; /* MAX message */ 12729 else 12730 chunk_len = param->len; 12731 12732 buf = wmi_buf_alloc(wmi_handle, 12733 (chunk_len + sizeof(seghdrinfo) + 12734 WMI_TLV_HDR_SIZE)); 12735 if (!buf) { 12736 WMI_LOGE("%s:wmi_buf_alloc failed", __func__); 12737 return QDF_STATUS_E_NOMEM; 12738 } 12739 12740 cmd = (uint8_t *) wmi_buf_data(buf); 12741 12742 seghdrinfo.len = total_bytes; 12743 seghdrinfo.msgref = msgref; 12744 seginfo = ((numsegments << 4) & 0xF0) | (segnumber & 0xF); 12745 seghdrinfo.segmentInfo = seginfo; 12746 12747 segnumber++; 12748 12749 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 12750 (chunk_len + sizeof(seghdrinfo))); 12751 cmd += WMI_TLV_HDR_SIZE; 12752 qdf_mem_copy(cmd, &seghdrinfo, sizeof(seghdrinfo)); 12753 qdf_mem_copy(&cmd[sizeof(seghdrinfo)], bufpos, chunk_len); 12754 12755 wmi_mtrace(WMI_PDEV_QVIT_CMDID, NO_SESSION, 0); 12756 ret = wmi_unified_cmd_send(wmi_handle, buf, 12757 (chunk_len + sizeof(seghdrinfo) + 12758 WMI_TLV_HDR_SIZE), 12759 WMI_PDEV_QVIT_CMDID); 12760 12761 if (ret != 0) { 12762 WMI_LOGE("Failed to send WMI_PDEV_QVIT_CMDID command"); 12763 wmi_buf_free(buf); 12764 break; 12765 } 12766 12767 param->len -= chunk_len; 12768 bufpos += chunk_len; 12769 } 12770 msgref++; 12771 12772 return ret; 12773 } 12774 12775 /** 12776 * send_wmm_update_cmd_tlv() - send wmm update command to fw 12777 * @wmi_handle: wmi handle 12778 * @param: pointer to wmm update param 12779 * 12780 * Return: 0 for success or error code 12781 */ 12782 static QDF_STATUS 12783 send_wmm_update_cmd_tlv(wmi_unified_t wmi_handle, 12784 struct wmm_update_params *param) 12785 { 12786 wmi_pdev_set_wmm_params_cmd_fixed_param *cmd; 12787 wmi_wmm_params *wmm_param; 12788 wmi_buf_t buf; 12789 QDF_STATUS ret; 12790 int32_t len; 12791 int ac = 0; 12792 struct wmi_host_wmeParams *wmep; 12793 uint8_t *buf_ptr; 12794 12795 len = sizeof(*cmd) + (WME_NUM_AC * sizeof(*wmm_param)); 12796 buf = wmi_buf_alloc(wmi_handle, len); 12797 if (!buf) { 12798 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12799 return QDF_STATUS_E_FAILURE; 12800 } 12801 12802 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12803 cmd = (wmi_pdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 12804 WMITLV_SET_HDR(&cmd->tlv_header, 12805 WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, 12806 WMITLV_GET_STRUCT_TLVLEN 12807 (wmi_pdev_set_wmm_params_cmd_fixed_param)); 12808 12809 cmd->reserved0 = WMI_HOST_PDEV_ID_SOC; 12810 12811 buf_ptr += sizeof(wmi_pdev_set_wmm_params_cmd_fixed_param); 12812 12813 for (ac = 0; ac < WME_NUM_AC; ac++) { 12814 wmep = ¶m->wmep_array[ac]; 12815 wmm_param = (wmi_wmm_params *)buf_ptr; 12816 WMITLV_SET_HDR(&wmm_param->tlv_header, 12817 WMITLV_TAG_STRUC_wmi_wmm_params, 12818 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 12819 wmm_param->aifs = wmep->wmep_aifsn; 12820 wmm_param->cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 12821 wmm_param->cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 12822 wmm_param->txoplimit = ATH_TXOP_TO_US(wmep->wmep_txopLimit); 12823 wmm_param->acm = wmep->wmep_acm; 12824 wmm_param->no_ack = wmep->wmep_noackPolicy; 12825 buf_ptr += sizeof(wmi_wmm_params); 12826 } 12827 wmi_mtrace(WMI_PDEV_SET_WMM_PARAMS_CMDID, NO_SESSION, 0); 12828 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12829 WMI_PDEV_SET_WMM_PARAMS_CMDID); 12830 12831 if (ret != 0) { 12832 WMI_LOGE("Sending WMM update CMD failed\n"); 12833 wmi_buf_free(buf); 12834 } 12835 12836 return ret; 12837 } 12838 12839 /** 12840 * send_coex_config_cmd_tlv() - send coex config command to fw 12841 * @wmi_handle: wmi handle 12842 * @param: pointer to coex config param 12843 * 12844 * Return: 0 for success or error code 12845 */ 12846 static QDF_STATUS 12847 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 12848 struct coex_config_params *param) 12849 { 12850 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 12851 wmi_buf_t buf; 12852 QDF_STATUS ret; 12853 int32_t len; 12854 12855 len = sizeof(*cmd); 12856 buf = wmi_buf_alloc(wmi_handle, len); 12857 if (!buf) { 12858 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 12859 return QDF_STATUS_E_FAILURE; 12860 } 12861 12862 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 12863 WMITLV_SET_HDR(&cmd->tlv_header, 12864 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 12865 WMITLV_GET_STRUCT_TLVLEN( 12866 WMI_COEX_CONFIG_CMD_fixed_param)); 12867 12868 cmd->vdev_id = param->vdev_id; 12869 cmd->config_type = param->config_type; 12870 cmd->config_arg1 = param->config_arg1; 12871 cmd->config_arg2 = param->config_arg2; 12872 cmd->config_arg3 = param->config_arg3; 12873 cmd->config_arg4 = param->config_arg4; 12874 cmd->config_arg5 = param->config_arg5; 12875 cmd->config_arg6 = param->config_arg6; 12876 12877 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 12878 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12879 WMI_COEX_CONFIG_CMDID); 12880 12881 if (ret != 0) { 12882 WMI_LOGE("Sending COEX CONFIG CMD failed\n"); 12883 wmi_buf_free(buf); 12884 } 12885 12886 return ret; 12887 } 12888 12889 12890 #ifdef WLAN_SUPPORT_TWT 12891 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12892 target_resource_config *tgt_res_cfg) 12893 { 12894 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 12895 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 12896 } 12897 #else 12898 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 12899 target_resource_config *tgt_res_cfg) 12900 { 12901 resource_cfg->twt_ap_pdev_count = 0; 12902 resource_cfg->twt_ap_sta_count = 0; 12903 } 12904 #endif 12905 12906 static 12907 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 12908 target_resource_config *tgt_res_cfg) 12909 { 12910 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 12911 resource_cfg->num_peers = tgt_res_cfg->num_peers; 12912 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 12913 resource_cfg->num_offload_reorder_buffs = 12914 tgt_res_cfg->num_offload_reorder_buffs; 12915 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 12916 resource_cfg->num_tids = tgt_res_cfg->num_tids; 12917 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 12918 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 12919 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 12920 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 12921 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 12922 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 12923 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 12924 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 12925 resource_cfg->scan_max_pending_req = 12926 tgt_res_cfg->scan_max_pending_req; 12927 resource_cfg->bmiss_offload_max_vdev = 12928 tgt_res_cfg->bmiss_offload_max_vdev; 12929 resource_cfg->roam_offload_max_vdev = 12930 tgt_res_cfg->roam_offload_max_vdev; 12931 resource_cfg->roam_offload_max_ap_profiles = 12932 tgt_res_cfg->roam_offload_max_ap_profiles; 12933 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 12934 resource_cfg->num_mcast_table_elems = 12935 tgt_res_cfg->num_mcast_table_elems; 12936 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 12937 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 12938 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 12939 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 12940 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 12941 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 12942 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 12943 resource_cfg->vow_config = tgt_res_cfg->vow_config; 12944 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 12945 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 12946 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 12947 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 12948 resource_cfg->num_tdls_conn_table_entries = 12949 tgt_res_cfg->num_tdls_conn_table_entries; 12950 resource_cfg->beacon_tx_offload_max_vdev = 12951 tgt_res_cfg->beacon_tx_offload_max_vdev; 12952 resource_cfg->num_multicast_filter_entries = 12953 tgt_res_cfg->num_multicast_filter_entries; 12954 resource_cfg->num_wow_filters = 12955 tgt_res_cfg->num_wow_filters; 12956 resource_cfg->num_keep_alive_pattern = 12957 tgt_res_cfg->num_keep_alive_pattern; 12958 resource_cfg->keep_alive_pattern_size = 12959 tgt_res_cfg->keep_alive_pattern_size; 12960 resource_cfg->max_tdls_concurrent_sleep_sta = 12961 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 12962 resource_cfg->max_tdls_concurrent_buffer_sta = 12963 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 12964 resource_cfg->wmi_send_separate = 12965 tgt_res_cfg->wmi_send_separate; 12966 resource_cfg->num_ocb_vdevs = 12967 tgt_res_cfg->num_ocb_vdevs; 12968 resource_cfg->num_ocb_channels = 12969 tgt_res_cfg->num_ocb_channels; 12970 resource_cfg->num_ocb_schedules = 12971 tgt_res_cfg->num_ocb_schedules; 12972 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 12973 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 12974 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 12975 resource_cfg->max_num_dbs_scan_duty_cycle = 12976 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 12977 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 12978 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 12979 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 12980 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 12981 if (tgt_res_cfg->atf_config) 12982 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 12983 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 12984 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 12985 resource_cfg->flag1, 1); 12986 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 12987 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 12988 resource_cfg->flag1, 1); 12989 if (tgt_res_cfg->cce_disable) 12990 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 12991 12992 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 12993 resource_cfg->peer_map_unmap_v2_support = 12994 tgt_res_cfg->peer_map_unmap_v2; 12995 } 12996 12997 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 12998 * @wmi_handle: pointer to wmi handle 12999 * @buf_ptr: pointer to current position in init command buffer 13000 * @len: pointer to length. This will be updated with current length of cmd 13001 * @param: point host parameters for init command 13002 * 13003 * Return: Updated pointer of buf_ptr. 13004 */ 13005 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 13006 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 13007 { 13008 uint16_t idx; 13009 13010 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 13011 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 13012 wmi_pdev_band_to_mac *band_to_mac; 13013 13014 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 13015 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 13016 sizeof(wmi_resource_config) + 13017 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 13018 sizeof(wlan_host_memory_chunk))); 13019 13020 WMITLV_SET_HDR(&hw_mode->tlv_header, 13021 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13022 (WMITLV_GET_STRUCT_TLVLEN 13023 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 13024 13025 hw_mode->hw_mode_index = param->hw_mode_id; 13026 hw_mode->num_band_to_mac = param->num_band_to_mac; 13027 13028 buf_ptr = (uint8_t *) (hw_mode + 1); 13029 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 13030 WMI_TLV_HDR_SIZE); 13031 for (idx = 0; idx < param->num_band_to_mac; idx++) { 13032 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 13033 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 13034 WMITLV_GET_STRUCT_TLVLEN 13035 (wmi_pdev_band_to_mac)); 13036 band_to_mac[idx].pdev_id = 13037 wmi_handle->ops->convert_pdev_id_host_to_target( 13038 param->band_to_mac[idx].pdev_id); 13039 band_to_mac[idx].start_freq = 13040 param->band_to_mac[idx].start_freq; 13041 band_to_mac[idx].end_freq = 13042 param->band_to_mac[idx].end_freq; 13043 } 13044 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 13045 (param->num_band_to_mac * 13046 sizeof(wmi_pdev_band_to_mac)) + 13047 WMI_TLV_HDR_SIZE; 13048 13049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13050 (param->num_band_to_mac * 13051 sizeof(wmi_pdev_band_to_mac))); 13052 } 13053 13054 return buf_ptr; 13055 } 13056 13057 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 13058 wmi_init_cmd_fixed_param *cmd) 13059 { 13060 int num_whitelist; 13061 wmi_abi_version my_vers; 13062 13063 num_whitelist = sizeof(version_whitelist) / 13064 sizeof(wmi_whitelist_version_info); 13065 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 13066 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 13067 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 13068 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 13069 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 13070 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 13071 13072 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 13073 &my_vers, 13074 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 13075 &cmd->host_abi_vers); 13076 13077 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 13078 __func__, 13079 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 13080 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 13081 cmd->host_abi_vers.abi_version_ns_0, 13082 cmd->host_abi_vers.abi_version_ns_1, 13083 cmd->host_abi_vers.abi_version_ns_2, 13084 cmd->host_abi_vers.abi_version_ns_3); 13085 13086 /* Save version sent from host - 13087 * Will be used to check ready event 13088 */ 13089 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 13090 sizeof(wmi_abi_version)); 13091 } 13092 13093 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13094 { 13095 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13096 wmi_service_ready_event_fixed_param *ev; 13097 13098 13099 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13100 13101 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13102 if (!ev) 13103 return QDF_STATUS_E_FAILURE; 13104 13105 /*Save fw version from service ready message */ 13106 /*This will be used while sending INIT message */ 13107 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13108 sizeof(wmi_handle->fw_abi_version)); 13109 13110 return QDF_STATUS_SUCCESS; 13111 } 13112 13113 /** 13114 * wmi_unified_save_fw_version_cmd() - save fw version 13115 * @wmi_handle: pointer to wmi handle 13116 * @res_cfg: resource config 13117 * @num_mem_chunks: no of mem chunck 13118 * @mem_chunk: pointer to mem chunck structure 13119 * 13120 * This function sends IE information to firmware 13121 * 13122 * Return: QDF_STATUS_SUCCESS for success otherwise failure 13123 * 13124 */ 13125 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 13126 void *evt_buf) 13127 { 13128 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13129 wmi_ready_event_fixed_param *ev = NULL; 13130 13131 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13132 ev = param_buf->fixed_param; 13133 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 13134 &wmi_handle->final_abi_vers, 13135 &ev->fw_abi_vers)) { 13136 /* 13137 * Error: Our host version and the given firmware version 13138 * are incompatible. 13139 **/ 13140 WMI_LOGD("%s: Error: Incompatible WMI version." 13141 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x\n", 13142 __func__, 13143 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 13144 abi_version_0), 13145 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 13146 abi_version_0), 13147 wmi_handle->final_abi_vers.abi_version_ns_0, 13148 wmi_handle->final_abi_vers.abi_version_ns_1, 13149 wmi_handle->final_abi_vers.abi_version_ns_2, 13150 wmi_handle->final_abi_vers.abi_version_ns_3, 13151 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 13152 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 13153 ev->fw_abi_vers.abi_version_ns_0, 13154 ev->fw_abi_vers.abi_version_ns_1, 13155 ev->fw_abi_vers.abi_version_ns_2, 13156 ev->fw_abi_vers.abi_version_ns_3); 13157 13158 return QDF_STATUS_E_FAILURE; 13159 } 13160 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 13161 sizeof(wmi_abi_version)); 13162 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13163 sizeof(wmi_abi_version)); 13164 13165 return QDF_STATUS_SUCCESS; 13166 } 13167 13168 /** 13169 * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw 13170 * @wmi_handle: wmi handle 13171 * @custom_addr: base mac address 13172 * 13173 * Return: QDF_STATUS_SUCCESS for success or error code 13174 */ 13175 static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle, 13176 uint8_t *custom_addr) 13177 { 13178 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; 13179 wmi_buf_t buf; 13180 int err; 13181 13182 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 13183 if (!buf) { 13184 WMI_LOGE("Failed to allocate buffer to send base macaddr cmd"); 13185 return QDF_STATUS_E_NOMEM; 13186 } 13187 13188 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); 13189 qdf_mem_zero(cmd, sizeof(*cmd)); 13190 13191 WMITLV_SET_HDR(&cmd->tlv_header, 13192 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, 13193 WMITLV_GET_STRUCT_TLVLEN 13194 (wmi_pdev_set_base_macaddr_cmd_fixed_param)); 13195 WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr); 13196 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13197 WMI_HOST_PDEV_ID_SOC); 13198 wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0); 13199 err = wmi_unified_cmd_send(wmi_handle, buf, 13200 sizeof(*cmd), 13201 WMI_PDEV_SET_BASE_MACADDR_CMDID); 13202 if (err) { 13203 WMI_LOGE("Failed to send set_base_macaddr cmd"); 13204 wmi_buf_free(buf); 13205 return QDF_STATUS_E_FAILURE; 13206 } 13207 13208 return 0; 13209 } 13210 13211 /** 13212 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 13213 * @handle: wmi handle 13214 * @event: Event received from FW 13215 * @len: Length of the event 13216 * 13217 * Enables the low frequency events and disables the high frequency 13218 * events. Bit 17 indicates if the event if low/high frequency. 13219 * 1 - high frequency, 0 - low frequency 13220 * 13221 * Return: 0 on successfully enabling/disabling the events 13222 */ 13223 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 13224 uint8_t *event, 13225 uint32_t len) 13226 { 13227 uint32_t num_of_diag_events_logs; 13228 wmi_diag_event_log_config_fixed_param *cmd; 13229 wmi_buf_t buf; 13230 uint8_t *buf_ptr; 13231 uint32_t *cmd_args, *evt_args; 13232 uint32_t buf_len, i; 13233 13234 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 13235 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 13236 13237 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 13238 13239 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 13240 if (!param_buf) { 13241 WMI_LOGE("Invalid log supported event buffer"); 13242 return QDF_STATUS_E_INVAL; 13243 } 13244 wmi_event = param_buf->fixed_param; 13245 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 13246 13247 if (num_of_diag_events_logs > 13248 param_buf->num_diag_events_logs_list) { 13249 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 13250 num_of_diag_events_logs, 13251 param_buf->num_diag_events_logs_list); 13252 return QDF_STATUS_E_INVAL; 13253 } 13254 13255 evt_args = param_buf->diag_events_logs_list; 13256 if (!evt_args) { 13257 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 13258 __func__, num_of_diag_events_logs); 13259 return QDF_STATUS_E_INVAL; 13260 } 13261 13262 WMI_LOGD("%s: num_of_diag_events_logs=%d", 13263 __func__, num_of_diag_events_logs); 13264 13265 /* Free any previous allocation */ 13266 if (wmi_handle->events_logs_list) 13267 qdf_mem_free(wmi_handle->events_logs_list); 13268 13269 if (num_of_diag_events_logs > 13270 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 13271 WMI_LOGE("%s: excess num of logs:%d", __func__, 13272 num_of_diag_events_logs); 13273 QDF_ASSERT(0); 13274 return QDF_STATUS_E_INVAL; 13275 } 13276 /* Store the event list for run time enable/disable */ 13277 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 13278 sizeof(uint32_t)); 13279 if (!wmi_handle->events_logs_list) { 13280 WMI_LOGE("%s: event log list memory allocation failed", 13281 __func__); 13282 return QDF_STATUS_E_NOMEM; 13283 } 13284 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 13285 13286 /* Prepare the send buffer */ 13287 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13288 (num_of_diag_events_logs * sizeof(uint32_t)); 13289 13290 buf = wmi_buf_alloc(wmi_handle, buf_len); 13291 if (!buf) { 13292 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13293 qdf_mem_free(wmi_handle->events_logs_list); 13294 wmi_handle->events_logs_list = NULL; 13295 return QDF_STATUS_E_NOMEM; 13296 } 13297 13298 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13299 buf_ptr = (uint8_t *) cmd; 13300 13301 WMITLV_SET_HDR(&cmd->tlv_header, 13302 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13303 WMITLV_GET_STRUCT_TLVLEN( 13304 wmi_diag_event_log_config_fixed_param)); 13305 13306 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 13307 13308 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13309 13310 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13311 (num_of_diag_events_logs * sizeof(uint32_t))); 13312 13313 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13314 13315 /* Populate the events */ 13316 for (i = 0; i < num_of_diag_events_logs; i++) { 13317 /* Low freq (0) - Enable (1) the event 13318 * High freq (1) - Disable (0) the event 13319 */ 13320 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 13321 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 13322 /* Set the event ID */ 13323 WMI_DIAG_ID_SET(cmd_args[i], 13324 WMI_DIAG_ID_GET(evt_args[i])); 13325 /* Set the type */ 13326 WMI_DIAG_TYPE_SET(cmd_args[i], 13327 WMI_DIAG_TYPE_GET(evt_args[i])); 13328 /* Storing the event/log list in WMI */ 13329 wmi_handle->events_logs_list[i] = evt_args[i]; 13330 } 13331 13332 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 13333 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 13334 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13335 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13336 __func__); 13337 wmi_buf_free(buf); 13338 /* Not clearing events_logs_list, though wmi cmd failed. 13339 * Host can still have this list 13340 */ 13341 return QDF_STATUS_E_INVAL; 13342 } 13343 13344 return 0; 13345 } 13346 13347 /** 13348 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 13349 * @wmi_handle: wmi handle 13350 * @start_log: Start logging related parameters 13351 * 13352 * Send the command to the FW based on which specific logging of diag 13353 * event/log id can be started/stopped 13354 * 13355 * Return: None 13356 */ 13357 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 13358 struct wmi_wifi_start_log *start_log) 13359 { 13360 wmi_diag_event_log_config_fixed_param *cmd; 13361 wmi_buf_t buf; 13362 uint8_t *buf_ptr; 13363 uint32_t len, count, log_level, i; 13364 uint32_t *cmd_args; 13365 uint32_t total_len; 13366 count = 0; 13367 13368 if (!wmi_handle->events_logs_list) { 13369 WMI_LOGD("%s: Not received event/log list from FW, yet", 13370 __func__); 13371 return QDF_STATUS_E_NOMEM; 13372 } 13373 /* total_len stores the number of events where BITS 17 and 18 are set. 13374 * i.e., events of high frequency (17) and for extended debugging (18) 13375 */ 13376 total_len = 0; 13377 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13378 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 13379 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 13380 total_len++; 13381 } 13382 13383 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 13384 (total_len * sizeof(uint32_t)); 13385 13386 buf = wmi_buf_alloc(wmi_handle, len); 13387 if (!buf) { 13388 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13389 return QDF_STATUS_E_NOMEM; 13390 } 13391 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 13392 buf_ptr = (uint8_t *) cmd; 13393 13394 WMITLV_SET_HDR(&cmd->tlv_header, 13395 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 13396 WMITLV_GET_STRUCT_TLVLEN( 13397 wmi_diag_event_log_config_fixed_param)); 13398 13399 cmd->num_of_diag_events_logs = total_len; 13400 13401 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 13402 13403 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13404 (total_len * sizeof(uint32_t))); 13405 13406 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13407 13408 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 13409 log_level = 1; 13410 else 13411 log_level = 0; 13412 13413 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 13414 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 13415 uint32_t val = wmi_handle->events_logs_list[i]; 13416 if ((WMI_DIAG_FREQUENCY_GET(val)) && 13417 (WMI_DIAG_EXT_FEATURE_GET(val))) { 13418 13419 WMI_DIAG_ID_SET(cmd_args[count], 13420 WMI_DIAG_ID_GET(val)); 13421 WMI_DIAG_TYPE_SET(cmd_args[count], 13422 WMI_DIAG_TYPE_GET(val)); 13423 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 13424 log_level); 13425 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 13426 count++; 13427 } 13428 } 13429 13430 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 13431 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13432 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 13433 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 13434 __func__); 13435 wmi_buf_free(buf); 13436 return QDF_STATUS_E_INVAL; 13437 } 13438 13439 return QDF_STATUS_SUCCESS; 13440 } 13441 13442 /** 13443 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 13444 * @wmi_handle: WMI handle 13445 * 13446 * This function is used to send the flush command to the FW, 13447 * that will flush the fw logs that are residue in the FW 13448 * 13449 * Return: None 13450 */ 13451 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 13452 { 13453 wmi_debug_mesg_flush_fixed_param *cmd; 13454 wmi_buf_t buf; 13455 int len = sizeof(*cmd); 13456 QDF_STATUS ret; 13457 13458 buf = wmi_buf_alloc(wmi_handle, len); 13459 if (!buf) { 13460 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13461 return QDF_STATUS_E_NOMEM; 13462 } 13463 13464 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 13465 WMITLV_SET_HDR(&cmd->tlv_header, 13466 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 13467 WMITLV_GET_STRUCT_TLVLEN( 13468 wmi_debug_mesg_flush_fixed_param)); 13469 cmd->reserved0 = 0; 13470 13471 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 13472 ret = wmi_unified_cmd_send(wmi_handle, 13473 buf, 13474 len, 13475 WMI_DEBUG_MESG_FLUSH_CMDID); 13476 if (QDF_IS_STATUS_ERROR(ret)) { 13477 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 13478 wmi_buf_free(buf); 13479 return QDF_STATUS_E_INVAL; 13480 } 13481 WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 13482 13483 return ret; 13484 } 13485 13486 /** 13487 * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW 13488 * @wmi_handle: wmi handle 13489 * @msg: PCL structure containing the PCL and the number of channels 13490 * 13491 * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN 13492 * firmware. The DBS Manager is the consumer of this information in the WLAN 13493 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs 13494 * to migrate to a new channel without host driver involvement. An example of 13495 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will 13496 * manage the channel selection without firmware involvement. 13497 * 13498 * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual 13499 * channel list. The weights corresponds to the channels sent in 13500 * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher 13501 * weightage compared to the non PCL channels. 13502 * 13503 * Return: Success if the cmd is sent successfully to the firmware 13504 */ 13505 static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, 13506 struct wmi_pcl_chan_weights *msg) 13507 { 13508 wmi_pdev_set_pcl_cmd_fixed_param *cmd; 13509 wmi_buf_t buf; 13510 uint8_t *buf_ptr; 13511 uint32_t *cmd_args, i, len; 13512 uint32_t chan_len; 13513 13514 chan_len = msg->saved_num_chan; 13515 13516 len = sizeof(*cmd) + 13517 WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t)); 13518 13519 buf = wmi_buf_alloc(wmi_handle, len); 13520 if (!buf) { 13521 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13522 return QDF_STATUS_E_NOMEM; 13523 } 13524 13525 cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf); 13526 buf_ptr = (uint8_t *) cmd; 13527 WMITLV_SET_HDR(&cmd->tlv_header, 13528 WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param, 13529 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param)); 13530 13531 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13532 WMI_HOST_PDEV_ID_SOC); 13533 cmd->num_chan = chan_len; 13534 WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan); 13535 13536 buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param); 13537 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13538 (chan_len * sizeof(uint32_t))); 13539 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 13540 for (i = 0; i < chan_len ; i++) { 13541 cmd_args[i] = msg->weighed_valid_list[i]; 13542 WMI_LOGD("%s: chan:%d weight:%d", __func__, 13543 msg->saved_chan_list[i], cmd_args[i]); 13544 } 13545 wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0); 13546 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13547 WMI_PDEV_SET_PCL_CMDID)) { 13548 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__); 13549 wmi_buf_free(buf); 13550 return QDF_STATUS_E_FAILURE; 13551 } 13552 return QDF_STATUS_SUCCESS; 13553 } 13554 13555 /** 13556 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 13557 * @wmi_handle: wmi handle 13558 * @msg: Structure containing the following parameters 13559 * 13560 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected 13561 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 13562 * 13563 * Provides notification to the WLAN firmware that host driver is requesting a 13564 * HardWare (HW) Mode change. This command is needed to support iHelium in the 13565 * configurations that include the Dual Band Simultaneous (DBS) feature. 13566 * 13567 * Return: Success if the cmd is sent successfully to the firmware 13568 */ 13569 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 13570 uint32_t hw_mode_index) 13571 { 13572 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 13573 wmi_buf_t buf; 13574 uint32_t len; 13575 13576 len = sizeof(*cmd); 13577 13578 buf = wmi_buf_alloc(wmi_handle, len); 13579 if (!buf) { 13580 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13581 return QDF_STATUS_E_NOMEM; 13582 } 13583 13584 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf); 13585 WMITLV_SET_HDR(&cmd->tlv_header, 13586 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 13587 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param)); 13588 13589 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13590 WMI_HOST_PDEV_ID_SOC); 13591 cmd->hw_mode_index = hw_mode_index; 13592 WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 13593 13594 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 13595 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13596 WMI_PDEV_SET_HW_MODE_CMDID)) { 13597 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 13598 __func__); 13599 wmi_buf_free(buf); 13600 return QDF_STATUS_E_FAILURE; 13601 } 13602 13603 return QDF_STATUS_SUCCESS; 13604 } 13605 13606 #ifdef WLAN_POLICY_MGR_ENABLE 13607 /** 13608 * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW 13609 * @wmi_handle: wmi handle 13610 * @msg: Dual MAC config parameters 13611 * 13612 * Configures WLAN firmware with the dual MAC features 13613 * 13614 * Return: QDF_STATUS. 0 on success. 13615 */ 13616 static 13617 QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle, 13618 struct policy_mgr_dual_mac_config *msg) 13619 { 13620 wmi_pdev_set_mac_config_cmd_fixed_param *cmd; 13621 wmi_buf_t buf; 13622 uint32_t len; 13623 13624 len = sizeof(*cmd); 13625 13626 buf = wmi_buf_alloc(wmi_handle, len); 13627 if (!buf) { 13628 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 13629 return QDF_STATUS_E_FAILURE; 13630 } 13631 13632 cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf); 13633 WMITLV_SET_HDR(&cmd->tlv_header, 13634 WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param, 13635 WMITLV_GET_STRUCT_TLVLEN( 13636 wmi_pdev_set_mac_config_cmd_fixed_param)); 13637 13638 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13639 WMI_HOST_PDEV_ID_SOC); 13640 cmd->concurrent_scan_config_bits = msg->scan_config; 13641 cmd->fw_mode_config_bits = msg->fw_mode_config; 13642 WMI_LOGD("%s: scan_config:%x fw_mode_config:%x", 13643 __func__, msg->scan_config, msg->fw_mode_config); 13644 13645 wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0); 13646 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13647 WMI_PDEV_SET_MAC_CONFIG_CMDID)) { 13648 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID", 13649 __func__); 13650 wmi_buf_free(buf); 13651 } 13652 return QDF_STATUS_SUCCESS; 13653 } 13654 #endif 13655 13656 #ifdef BIG_ENDIAN_HOST 13657 /** 13658 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13659 * @param data_len - data length 13660 * @param data - pointer to data 13661 * 13662 * Return: QDF_STATUS - success or error status 13663 */ 13664 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13665 struct fips_params *param) 13666 { 13667 unsigned char *key_unaligned, *data_unaligned; 13668 int c; 13669 u_int8_t *key_aligned = NULL; 13670 u_int8_t *data_aligned = NULL; 13671 13672 /* Assigning unaligned space to copy the key */ 13673 key_unaligned = qdf_mem_malloc( 13674 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 13675 data_unaligned = qdf_mem_malloc( 13676 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 13677 13678 /* Checking if kmalloc is successful to allocate space */ 13679 if (key_unaligned == NULL) 13680 return QDF_STATUS_SUCCESS; 13681 /* Checking if space is aligned */ 13682 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 13683 /* align to 4 */ 13684 key_aligned = 13685 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 13686 FIPS_ALIGN); 13687 } else { 13688 key_aligned = (u_int8_t *)key_unaligned; 13689 } 13690 13691 /* memset and copy content from key to key aligned */ 13692 OS_MEMSET(key_aligned, 0, param->key_len); 13693 OS_MEMCPY(key_aligned, param->key, param->key_len); 13694 13695 /* print a hexdump for host debug */ 13696 print_hex_dump(KERN_DEBUG, 13697 "\t Aligned and Copied Key:@@@@ ", 13698 DUMP_PREFIX_NONE, 13699 16, 1, key_aligned, param->key_len, true); 13700 13701 /* Checking if kmalloc is successful to allocate space */ 13702 if (data_unaligned == NULL) 13703 return QDF_STATUS_SUCCESS; 13704 /* Checking of space is aligned */ 13705 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13706 /* align to 4 */ 13707 data_aligned = 13708 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 13709 FIPS_ALIGN); 13710 } else { 13711 data_aligned = (u_int8_t *)data_unaligned; 13712 } 13713 13714 /* memset and copy content from data to data aligned */ 13715 OS_MEMSET(data_aligned, 0, param->data_len); 13716 OS_MEMCPY(data_aligned, param->data, param->data_len); 13717 13718 /* print a hexdump for host debug */ 13719 print_hex_dump(KERN_DEBUG, 13720 "\t Properly Aligned and Copied Data:@@@@ ", 13721 DUMP_PREFIX_NONE, 13722 16, 1, data_aligned, param->data_len, true); 13723 13724 /* converting to little Endian both key_aligned and 13725 * data_aligned*/ 13726 for (c = 0; c < param->key_len/4; c++) { 13727 *((u_int32_t *)key_aligned+c) = 13728 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 13729 } 13730 for (c = 0; c < param->data_len/4; c++) { 13731 *((u_int32_t *)data_aligned+c) = 13732 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 13733 } 13734 13735 /* update endian data to key and data vectors */ 13736 OS_MEMCPY(param->key, key_aligned, param->key_len); 13737 OS_MEMCPY(param->data, data_aligned, param->data_len); 13738 13739 /* clean up allocated spaces */ 13740 qdf_mem_free(key_unaligned); 13741 key_unaligned = NULL; 13742 key_aligned = NULL; 13743 13744 qdf_mem_free(data_unaligned); 13745 data_unaligned = NULL; 13746 data_aligned = NULL; 13747 13748 return QDF_STATUS_SUCCESS; 13749 } 13750 #else 13751 /** 13752 * fips_align_data_be() - DUMMY for LE platform 13753 * 13754 * Return: QDF_STATUS - success 13755 */ 13756 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 13757 struct fips_params *param) 13758 { 13759 return QDF_STATUS_SUCCESS; 13760 } 13761 #endif 13762 13763 13764 /** 13765 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 13766 * @wmi_handle: wmi handle 13767 * @param: pointer to hold pdev fips param 13768 * 13769 * Return: 0 for success or error code 13770 */ 13771 static QDF_STATUS 13772 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 13773 struct fips_params *param) 13774 { 13775 wmi_pdev_fips_cmd_fixed_param *cmd; 13776 wmi_buf_t buf; 13777 uint8_t *buf_ptr; 13778 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 13779 QDF_STATUS retval = QDF_STATUS_SUCCESS; 13780 13781 /* Length TLV placeholder for array of bytes */ 13782 len += WMI_TLV_HDR_SIZE; 13783 if (param->data_len) 13784 len += (param->data_len*sizeof(uint8_t)); 13785 13786 /* 13787 * Data length must be multiples of 16 bytes - checked against 0xF - 13788 * and must be less than WMI_SVC_MSG_SIZE - static size of 13789 * wmi_pdev_fips_cmd structure 13790 */ 13791 13792 /* do sanity on the input */ 13793 if (!(((param->data_len & 0xF) == 0) && 13794 ((param->data_len > 0) && 13795 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 13796 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 13797 return QDF_STATUS_E_INVAL; 13798 } 13799 13800 buf = wmi_buf_alloc(wmi_handle, len); 13801 if (!buf) { 13802 qdf_print("%s:wmi_buf_alloc failed", __func__); 13803 return QDF_STATUS_E_FAILURE; 13804 } 13805 13806 buf_ptr = (uint8_t *) wmi_buf_data(buf); 13807 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 13808 WMITLV_SET_HDR(&cmd->tlv_header, 13809 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 13810 WMITLV_GET_STRUCT_TLVLEN 13811 (wmi_pdev_fips_cmd_fixed_param)); 13812 13813 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13814 param->pdev_id); 13815 if (param->key != NULL && param->data != NULL) { 13816 cmd->key_len = param->key_len; 13817 cmd->data_len = param->data_len; 13818 cmd->fips_cmd = !!(param->op); 13819 13820 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 13821 return QDF_STATUS_E_FAILURE; 13822 13823 qdf_mem_copy(cmd->key, param->key, param->key_len); 13824 13825 if (param->mode == FIPS_ENGINE_AES_CTR || 13826 param->mode == FIPS_ENGINE_AES_MIC) { 13827 cmd->mode = param->mode; 13828 } else { 13829 cmd->mode = FIPS_ENGINE_AES_CTR; 13830 } 13831 qdf_print("Key len = %d, Data len = %d", 13832 cmd->key_len, cmd->data_len); 13833 13834 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 13835 cmd->key, cmd->key_len, true); 13836 buf_ptr += sizeof(*cmd); 13837 13838 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 13839 13840 buf_ptr += WMI_TLV_HDR_SIZE; 13841 if (param->data_len) 13842 qdf_mem_copy(buf_ptr, 13843 (uint8_t *) param->data, param->data_len); 13844 13845 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 13846 16, 1, buf_ptr, cmd->data_len, true); 13847 13848 buf_ptr += param->data_len; 13849 13850 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 13851 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 13852 WMI_PDEV_FIPS_CMDID); 13853 qdf_print("%s return value %d", __func__, retval); 13854 } else { 13855 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 13856 wmi_buf_free(buf); 13857 retval = -QDF_STATUS_E_BADMSG; 13858 } 13859 13860 return retval; 13861 } 13862 13863 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 13864 /** 13865 * send_add_wow_wakeup_event_cmd_tlv() - Configures wow wakeup events. 13866 * @wmi_handle: wmi handle 13867 * @vdev_id: vdev id 13868 * @bitmap: Event bitmap 13869 * @enable: enable/disable 13870 * 13871 * Return: CDF status 13872 */ 13873 static QDF_STATUS send_add_wow_wakeup_event_cmd_tlv(wmi_unified_t wmi_handle, 13874 uint32_t vdev_id, 13875 uint32_t *bitmap, 13876 bool enable) 13877 { 13878 WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; 13879 uint16_t len; 13880 wmi_buf_t buf; 13881 int ret; 13882 13883 len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); 13884 buf = wmi_buf_alloc(wmi_handle, len); 13885 if (!buf) { 13886 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13887 return QDF_STATUS_E_NOMEM; 13888 } 13889 cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); 13890 WMITLV_SET_HDR(&cmd->tlv_header, 13891 WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, 13892 WMITLV_GET_STRUCT_TLVLEN 13893 (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); 13894 cmd->vdev_id = vdev_id; 13895 cmd->is_add = enable; 13896 qdf_mem_copy(&(cmd->event_bitmaps[0]), bitmap, sizeof(uint32_t) * 13897 WMI_WOW_MAX_EVENT_BM_LEN); 13898 13899 WMI_LOGD("Wakeup pattern 0x%x%x%x%x %s in fw", cmd->event_bitmaps[0], 13900 cmd->event_bitmaps[1], cmd->event_bitmaps[2], 13901 cmd->event_bitmaps[3], enable ? "enabled" : "disabled"); 13902 13903 wmi_mtrace(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, cmd->vdev_id, 0); 13904 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13905 WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); 13906 if (ret) { 13907 WMI_LOGE("Failed to config wow wakeup event"); 13908 wmi_buf_free(buf); 13909 return QDF_STATUS_E_FAILURE; 13910 } 13911 13912 return QDF_STATUS_SUCCESS; 13913 } 13914 13915 /** 13916 * send_wow_patterns_to_fw_cmd_tlv() - Sends WOW patterns to FW. 13917 * @wmi_handle: wmi handle 13918 * @vdev_id: vdev id 13919 * @ptrn_id: pattern id 13920 * @ptrn: pattern 13921 * @ptrn_len: pattern length 13922 * @ptrn_offset: pattern offset 13923 * @mask: mask 13924 * @mask_len: mask length 13925 * @user: true for user configured pattern and false for default pattern 13926 * @default_patterns: default patterns 13927 * 13928 * Return: CDF status 13929 */ 13930 static QDF_STATUS send_wow_patterns_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 13931 uint8_t vdev_id, uint8_t ptrn_id, 13932 const uint8_t *ptrn, uint8_t ptrn_len, 13933 uint8_t ptrn_offset, const uint8_t *mask, 13934 uint8_t mask_len, bool user, 13935 uint8_t default_patterns) 13936 { 13937 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 13938 WOW_BITMAP_PATTERN_T *bitmap_pattern; 13939 wmi_buf_t buf; 13940 uint8_t *buf_ptr; 13941 int32_t len; 13942 int ret; 13943 13944 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 13945 WMI_TLV_HDR_SIZE + 13946 1 * sizeof(WOW_BITMAP_PATTERN_T) + 13947 WMI_TLV_HDR_SIZE + 13948 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 13949 WMI_TLV_HDR_SIZE + 13950 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 13951 WMI_TLV_HDR_SIZE + 13952 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 13953 WMI_TLV_HDR_SIZE + 13954 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 13955 13956 buf = wmi_buf_alloc(wmi_handle, len); 13957 if (!buf) { 13958 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 13959 return QDF_STATUS_E_NOMEM; 13960 } 13961 13962 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 13963 buf_ptr = (uint8_t *) cmd; 13964 13965 WMITLV_SET_HDR(&cmd->tlv_header, 13966 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 13967 WMITLV_GET_STRUCT_TLVLEN 13968 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 13969 cmd->vdev_id = vdev_id; 13970 cmd->pattern_id = ptrn_id; 13971 13972 cmd->pattern_type = WOW_BITMAP_PATTERN; 13973 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 13974 13975 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 13976 sizeof(WOW_BITMAP_PATTERN_T)); 13977 buf_ptr += WMI_TLV_HDR_SIZE; 13978 bitmap_pattern = (WOW_BITMAP_PATTERN_T *) buf_ptr; 13979 13980 WMITLV_SET_HDR(&bitmap_pattern->tlv_header, 13981 WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, 13982 WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); 13983 13984 qdf_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); 13985 qdf_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); 13986 13987 bitmap_pattern->pattern_offset = ptrn_offset; 13988 bitmap_pattern->pattern_len = ptrn_len; 13989 13990 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) 13991 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; 13992 13993 if (bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) 13994 bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; 13995 13996 bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; 13997 bitmap_pattern->pattern_id = ptrn_id; 13998 13999 WMI_LOGD("vdev: %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d user %d", 14000 cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, 14001 bitmap_pattern->pattern_offset, user); 14002 WMI_LOGD("Pattern : "); 14003 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 14004 &bitmap_pattern->patternbuf[0], 14005 bitmap_pattern->pattern_len); 14006 14007 WMI_LOGD("Mask : "); 14008 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 14009 &bitmap_pattern->bitmaskbuf[0], 14010 bitmap_pattern->pattern_len); 14011 14012 buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); 14013 14014 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14015 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14016 buf_ptr += WMI_TLV_HDR_SIZE; 14017 14018 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14019 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14020 buf_ptr += WMI_TLV_HDR_SIZE; 14021 14022 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14023 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14024 buf_ptr += WMI_TLV_HDR_SIZE; 14025 14026 /* Fill TLV for pattern_info_timeout but no data. */ 14027 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14028 buf_ptr += WMI_TLV_HDR_SIZE; 14029 14030 /* Fill TLV for ratelimit_interval with dummy data as this fix elem */ 14031 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(uint32_t)); 14032 buf_ptr += WMI_TLV_HDR_SIZE; 14033 *(uint32_t *) buf_ptr = 0; 14034 14035 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 14036 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14037 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14038 if (ret) { 14039 WMI_LOGE("%s: Failed to send wow ptrn to fw", __func__); 14040 wmi_buf_free(buf); 14041 return QDF_STATUS_E_FAILURE; 14042 } 14043 14044 return QDF_STATUS_SUCCESS; 14045 } 14046 14047 /** 14048 * fill_arp_offload_params_tlv() - Fill ARP offload data 14049 * @wmi_handle: wmi handle 14050 * @offload_req: offload request 14051 * @buf_ptr: buffer pointer 14052 * 14053 * To fill ARP offload data to firmware 14054 * when target goes to wow mode. 14055 * 14056 * Return: None 14057 */ 14058 static void fill_arp_offload_params_tlv(wmi_unified_t wmi_handle, 14059 struct pmo_arp_offload_params *offload_req, uint8_t **buf_ptr) 14060 { 14061 14062 int i; 14063 WMI_ARP_OFFLOAD_TUPLE *arp_tuple; 14064 bool enable_or_disable = offload_req->enable; 14065 14066 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14067 (WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); 14068 *buf_ptr += WMI_TLV_HDR_SIZE; 14069 for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { 14070 arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)*buf_ptr; 14071 WMITLV_SET_HDR(&arp_tuple->tlv_header, 14072 WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, 14073 WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); 14074 14075 /* Fill data for ARP and NS in the first tupple for LA */ 14076 if ((enable_or_disable & PMO_OFFLOAD_ENABLE) && (i == 0)) { 14077 /* Copy the target ip addr and flags */ 14078 arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; 14079 qdf_mem_copy(&arp_tuple->target_ipaddr, 14080 offload_req->host_ipv4_addr, 14081 WMI_IPV4_ADDR_LEN); 14082 WMI_LOGD("ARPOffload IP4 address: %pI4", 14083 offload_req->host_ipv4_addr); 14084 } 14085 *buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); 14086 } 14087 } 14088 14089 #ifdef WLAN_NS_OFFLOAD 14090 /** 14091 * fill_ns_offload_params_tlv() - Fill NS offload data 14092 * @wmi|_handle: wmi handle 14093 * @offload_req: offload request 14094 * @buf_ptr: buffer pointer 14095 * 14096 * To fill NS offload data to firmware 14097 * when target goes to wow mode. 14098 * 14099 * Return: None 14100 */ 14101 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14102 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14103 { 14104 14105 int i; 14106 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14107 14108 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14109 (WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14110 *buf_ptr += WMI_TLV_HDR_SIZE; 14111 for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { 14112 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14113 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14114 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14115 (sizeof(WMI_NS_OFFLOAD_TUPLE) - WMI_TLV_HDR_SIZE)); 14116 14117 /* 14118 * Fill data only for NS offload in the first ARP tuple for LA 14119 */ 14120 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14121 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14122 /* Copy the target/solicitation/remote ip addr */ 14123 if (ns_req->target_ipv6_addr_valid[i]) 14124 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14125 &ns_req->target_ipv6_addr[i], 14126 sizeof(WMI_IPV6_ADDR)); 14127 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14128 &ns_req->self_ipv6_addr[i], 14129 sizeof(WMI_IPV6_ADDR)); 14130 if (ns_req->target_ipv6_addr_ac_type[i]) { 14131 ns_tuple->flags |= 14132 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14133 } 14134 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14135 i, &ns_req->self_ipv6_addr[i], 14136 &ns_req->target_ipv6_addr[i]); 14137 14138 /* target MAC is optional, check if it is valid, 14139 * if this is not valid, the target will use the known 14140 * local MAC address rather than the tuple 14141 */ 14142 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14143 ns_req->self_macaddr.bytes, 14144 &ns_tuple->target_mac); 14145 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14146 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14147 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14148 } 14149 } 14150 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14151 } 14152 } 14153 14154 14155 /** 14156 * fill_nsoffload_ext_tlv() - Fill NS offload ext data 14157 * @wmi: wmi handle 14158 * @offload_req: offload request 14159 * @buf_ptr: buffer pointer 14160 * 14161 * To fill extended NS offload extended data to firmware 14162 * when target goes to wow mode. 14163 * 14164 * Return: None 14165 */ 14166 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14167 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14168 { 14169 int i; 14170 WMI_NS_OFFLOAD_TUPLE *ns_tuple; 14171 uint32_t count, num_ns_ext_tuples; 14172 14173 count = ns_req->num_ns_offload_count; 14174 num_ns_ext_tuples = ns_req->num_ns_offload_count - 14175 WMI_MAX_NS_OFFLOADS; 14176 14177 /* Populate extended NS offload tuples */ 14178 WMITLV_SET_HDR(*buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14179 (num_ns_ext_tuples * sizeof(WMI_NS_OFFLOAD_TUPLE))); 14180 *buf_ptr += WMI_TLV_HDR_SIZE; 14181 for (i = WMI_MAX_NS_OFFLOADS; i < count; i++) { 14182 ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)*buf_ptr; 14183 WMITLV_SET_HDR(&ns_tuple->tlv_header, 14184 WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, 14185 (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); 14186 14187 /* 14188 * Fill data only for NS offload in the first ARP tuple for LA 14189 */ 14190 if ((ns_req->enable & PMO_OFFLOAD_ENABLE)) { 14191 ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; 14192 /* Copy the target/solicitation/remote ip addr */ 14193 if (ns_req->target_ipv6_addr_valid[i]) 14194 qdf_mem_copy(&ns_tuple->target_ipaddr[0], 14195 &ns_req->target_ipv6_addr[i], 14196 sizeof(WMI_IPV6_ADDR)); 14197 qdf_mem_copy(&ns_tuple->solicitation_ipaddr, 14198 &ns_req->self_ipv6_addr[i], 14199 sizeof(WMI_IPV6_ADDR)); 14200 if (ns_req->target_ipv6_addr_ac_type[i]) { 14201 ns_tuple->flags |= 14202 WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; 14203 } 14204 WMI_LOGD("Index %d NS solicitedIp %pI6, targetIp %pI6", 14205 i, &ns_req->self_ipv6_addr[i], 14206 &ns_req->target_ipv6_addr[i]); 14207 14208 /* target MAC is optional, check if it is valid, 14209 * if this is not valid, the target will use the 14210 * known local MAC address rather than the tuple 14211 */ 14212 WMI_CHAR_ARRAY_TO_MAC_ADDR( 14213 ns_req->self_macaddr.bytes, 14214 &ns_tuple->target_mac); 14215 if ((ns_tuple->target_mac.mac_addr31to0 != 0) || 14216 (ns_tuple->target_mac.mac_addr47to32 != 0)) { 14217 ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; 14218 } 14219 } 14220 *buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); 14221 } 14222 } 14223 #else 14224 static void fill_ns_offload_params_tlv(wmi_unified_t wmi_handle, 14225 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14226 { 14227 } 14228 14229 static void fill_nsoffload_ext_tlv(wmi_unified_t wmi_handle, 14230 struct pmo_ns_offload_params *ns_req, uint8_t **buf_ptr) 14231 { 14232 } 14233 #endif 14234 14235 /** 14236 * send_enable_arp_ns_offload_cmd_tlv() - enable ARP NS offload 14237 * @wma: wmi handle 14238 * @arp_offload_req: arp offload request 14239 * @ns_offload_req: ns offload request 14240 * @arp_only: flag 14241 * 14242 * To configure ARP NS off load data to firmware 14243 * when target goes to wow mode. 14244 * 14245 * Return: QDF Status 14246 */ 14247 static QDF_STATUS send_enable_arp_ns_offload_cmd_tlv(wmi_unified_t wmi_handle, 14248 struct pmo_arp_offload_params *arp_offload_req, 14249 struct pmo_ns_offload_params *ns_offload_req, 14250 uint8_t vdev_id) 14251 { 14252 int32_t res; 14253 WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; 14254 uint8_t *buf_ptr; 14255 wmi_buf_t buf; 14256 int32_t len; 14257 uint32_t count = 0, num_ns_ext_tuples = 0; 14258 14259 count = ns_offload_req->num_ns_offload_count; 14260 14261 /* 14262 * TLV place holder size for array of NS tuples 14263 * TLV place holder size for array of ARP tuples 14264 */ 14265 len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + 14266 WMI_TLV_HDR_SIZE + 14267 WMI_MAX_NS_OFFLOADS * sizeof(WMI_NS_OFFLOAD_TUPLE) + 14268 WMI_TLV_HDR_SIZE + 14269 WMI_MAX_ARP_OFFLOADS * sizeof(WMI_ARP_OFFLOAD_TUPLE); 14270 14271 /* 14272 * If there are more than WMI_MAX_NS_OFFLOADS addresses then allocate 14273 * extra length for extended NS offload tuples which follows ARP offload 14274 * tuples. Host needs to fill this structure in following format: 14275 * 2 NS ofload tuples 14276 * 2 ARP offload tuples 14277 * N numbers of extended NS offload tuples if HDD has given more than 14278 * 2 NS offload addresses 14279 */ 14280 if (count > WMI_MAX_NS_OFFLOADS) { 14281 num_ns_ext_tuples = count - WMI_MAX_NS_OFFLOADS; 14282 len += WMI_TLV_HDR_SIZE + num_ns_ext_tuples 14283 * sizeof(WMI_NS_OFFLOAD_TUPLE); 14284 } 14285 14286 buf = wmi_buf_alloc(wmi_handle, len); 14287 if (!buf) { 14288 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 14289 return QDF_STATUS_E_NOMEM; 14290 } 14291 14292 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14293 cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *) buf_ptr; 14294 WMITLV_SET_HDR(&cmd->tlv_header, 14295 WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, 14296 WMITLV_GET_STRUCT_TLVLEN 14297 (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); 14298 cmd->flags = 0; 14299 cmd->vdev_id = vdev_id; 14300 cmd->num_ns_ext_tuples = num_ns_ext_tuples; 14301 14302 WMI_LOGD("ARP NS Offload vdev_id: %d", cmd->vdev_id); 14303 14304 buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); 14305 fill_ns_offload_params_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14306 fill_arp_offload_params_tlv(wmi_handle, arp_offload_req, &buf_ptr); 14307 if (num_ns_ext_tuples) 14308 fill_nsoffload_ext_tlv(wmi_handle, ns_offload_req, &buf_ptr); 14309 14310 wmi_mtrace(WMI_SET_ARP_NS_OFFLOAD_CMDID, cmd->vdev_id, 0); 14311 res = wmi_unified_cmd_send(wmi_handle, buf, len, 14312 WMI_SET_ARP_NS_OFFLOAD_CMDID); 14313 if (res) { 14314 WMI_LOGE("Failed to enable ARP NDP/NSffload"); 14315 wmi_buf_free(buf); 14316 return QDF_STATUS_E_FAILURE; 14317 } 14318 14319 return QDF_STATUS_SUCCESS; 14320 } 14321 14322 /** 14323 * send_enable_enhance_multicast_offload_tlv() - send enhance multicast offload 14324 * @wmi_handle: wmi handle 14325 * @vdev_id: vdev id 14326 * @action: true for enable else false 14327 * 14328 * To enable enhance multicast offload to firmware 14329 * when target goes to wow mode. 14330 * 14331 * Return: QDF Status 14332 */ 14333 14334 static 14335 QDF_STATUS send_enable_enhance_multicast_offload_tlv( 14336 wmi_unified_t wmi_handle, 14337 uint8_t vdev_id, bool action) 14338 { 14339 QDF_STATUS status; 14340 wmi_buf_t buf; 14341 wmi_config_enhanced_mcast_filter_cmd_fixed_param *cmd; 14342 14343 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14344 if (!buf) { 14345 WMI_LOGE("Failed to allocate buffer to send set key cmd"); 14346 return QDF_STATUS_E_NOMEM; 14347 } 14348 14349 cmd = (wmi_config_enhanced_mcast_filter_cmd_fixed_param *) 14350 wmi_buf_data(buf); 14351 14352 WMITLV_SET_HDR(&cmd->tlv_header, 14353 WMITLV_TAG_STRUC_wmi_config_enhanced_mcast_filter_fixed_param, 14354 WMITLV_GET_STRUCT_TLVLEN( 14355 wmi_config_enhanced_mcast_filter_cmd_fixed_param)); 14356 14357 cmd->vdev_id = vdev_id; 14358 cmd->enable = ((action == 0) ? ENHANCED_MCAST_FILTER_DISABLED : 14359 ENHANCED_MCAST_FILTER_ENABLED); 14360 WMI_LOGD("%s: config enhance multicast offload action %d for vdev %d", 14361 __func__, action, vdev_id); 14362 wmi_mtrace(WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID, cmd->vdev_id, 0); 14363 status = wmi_unified_cmd_send(wmi_handle, buf, 14364 sizeof(*cmd), WMI_CONFIG_ENHANCED_MCAST_FILTER_CMDID); 14365 if (status != QDF_STATUS_SUCCESS) { 14366 wmi_buf_free(buf); 14367 WMI_LOGE("%s:Failed to send ENHANCED_MCAST_FILTER_CMDID", 14368 __func__); 14369 } 14370 14371 return status; 14372 } 14373 14374 /** 14375 * extract_gtk_rsp_event_tlv() - extract gtk rsp params from event 14376 * @wmi_handle: wmi handle 14377 * @param evt_buf: pointer to event buffer 14378 * @param hdr: Pointer to hold header 14379 * @param bufp: Pointer to hold pointer to rx param buffer 14380 * 14381 * Return: QDF_STATUS_SUCCESS for success or error code 14382 */ 14383 static QDF_STATUS extract_gtk_rsp_event_tlv(wmi_unified_t wmi_handle, 14384 void *evt_buf, struct pmo_gtk_rsp_params *gtk_rsp_param, uint32_t len) 14385 { 14386 WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *fixed_param; 14387 WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; 14388 14389 param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)evt_buf; 14390 if (!param_buf) { 14391 WMI_LOGE("gtk param_buf is NULL"); 14392 return QDF_STATUS_E_INVAL; 14393 } 14394 14395 if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { 14396 WMI_LOGE("Invalid length for GTK status"); 14397 return QDF_STATUS_E_INVAL; 14398 } 14399 14400 fixed_param = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *) 14401 param_buf->fixed_param; 14402 gtk_rsp_param->vdev_id = fixed_param->vdev_id; 14403 gtk_rsp_param->status_flag = QDF_STATUS_SUCCESS; 14404 gtk_rsp_param->refresh_cnt = fixed_param->refresh_cnt; 14405 qdf_mem_copy(>k_rsp_param->replay_counter, 14406 &fixed_param->replay_counter, 14407 GTK_REPLAY_COUNTER_BYTES); 14408 14409 return QDF_STATUS_SUCCESS; 14410 14411 } 14412 14413 #ifdef FEATURE_WLAN_RA_FILTERING 14414 /** 14415 * send_wow_sta_ra_filter_cmd_tlv() - set RA filter pattern in fw 14416 * @wmi_handle: wmi handle 14417 * @vdev_id: vdev id 14418 * 14419 * Return: CDF status 14420 */ 14421 static QDF_STATUS send_wow_sta_ra_filter_cmd_tlv(wmi_unified_t wmi_handle, 14422 uint8_t vdev_id, uint8_t default_pattern, 14423 uint16_t rate_limit_interval) 14424 { 14425 14426 WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; 14427 wmi_buf_t buf; 14428 uint8_t *buf_ptr; 14429 int32_t len; 14430 int ret; 14431 14432 len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + 14433 WMI_TLV_HDR_SIZE + 14434 0 * sizeof(WOW_BITMAP_PATTERN_T) + 14435 WMI_TLV_HDR_SIZE + 14436 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + 14437 WMI_TLV_HDR_SIZE + 14438 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + 14439 WMI_TLV_HDR_SIZE + 14440 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + 14441 WMI_TLV_HDR_SIZE + 14442 0 * sizeof(uint32_t) + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t); 14443 14444 buf = wmi_buf_alloc(wmi_handle, len); 14445 if (!buf) { 14446 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 14447 return QDF_STATUS_E_NOMEM; 14448 } 14449 14450 cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); 14451 buf_ptr = (uint8_t *) cmd; 14452 14453 WMITLV_SET_HDR(&cmd->tlv_header, 14454 WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, 14455 WMITLV_GET_STRUCT_TLVLEN 14456 (WMI_WOW_ADD_PATTERN_CMD_fixed_param)); 14457 cmd->vdev_id = vdev_id; 14458 cmd->pattern_id = default_pattern, 14459 cmd->pattern_type = WOW_IPV6_RA_PATTERN; 14460 buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); 14461 14462 /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ 14463 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14464 buf_ptr += WMI_TLV_HDR_SIZE; 14465 14466 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ 14467 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14468 buf_ptr += WMI_TLV_HDR_SIZE; 14469 14470 /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ 14471 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14472 buf_ptr += WMI_TLV_HDR_SIZE; 14473 14474 /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ 14475 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 14476 buf_ptr += WMI_TLV_HDR_SIZE; 14477 14478 /* Fill TLV for pattern_info_timeout but no data. */ 14479 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 14480 buf_ptr += WMI_TLV_HDR_SIZE; 14481 14482 /* Fill TLV for ra_ratelimit_interval. */ 14483 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 14484 buf_ptr += WMI_TLV_HDR_SIZE; 14485 14486 *((uint32_t *) buf_ptr) = rate_limit_interval; 14487 14488 WMI_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, 14489 rate_limit_interval, vdev_id); 14490 14491 wmi_mtrace(WMI_WOW_ADD_WAKE_PATTERN_CMDID, cmd->vdev_id, 0); 14492 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14493 WMI_WOW_ADD_WAKE_PATTERN_CMDID); 14494 if (ret) { 14495 WMI_LOGE("%s: Failed to send RA rate limit to fw", __func__); 14496 wmi_buf_free(buf); 14497 return QDF_STATUS_E_FAILURE; 14498 } 14499 14500 return QDF_STATUS_SUCCESS; 14501 14502 } 14503 #endif /* FEATURE_WLAN_RA_FILTERING */ 14504 14505 /** 14506 * send_add_clear_mcbc_filter_cmd_tlv() - set mcast filter command to fw 14507 * @wmi_handle: wmi handle 14508 * @vdev_id: vdev id 14509 * @multicastAddr: mcast address 14510 * @clearList: clear list flag 14511 * 14512 * Return: QDF_STATUS_SUCCESS for success or error code 14513 */ 14514 static QDF_STATUS send_add_clear_mcbc_filter_cmd_tlv(wmi_unified_t wmi_handle, 14515 uint8_t vdev_id, 14516 struct qdf_mac_addr multicast_addr, 14517 bool clearList) 14518 { 14519 WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; 14520 wmi_buf_t buf; 14521 int err; 14522 14523 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 14524 if (!buf) { 14525 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 14526 return QDF_STATUS_E_NOMEM; 14527 } 14528 14529 cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); 14530 qdf_mem_zero(cmd, sizeof(*cmd)); 14531 14532 WMITLV_SET_HDR(&cmd->tlv_header, 14533 WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, 14534 WMITLV_GET_STRUCT_TLVLEN 14535 (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); 14536 cmd->action = 14537 (clearList ? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); 14538 cmd->vdev_id = vdev_id; 14539 WMI_CHAR_ARRAY_TO_MAC_ADDR(multicast_addr.bytes, &cmd->mcastbdcastaddr); 14540 14541 WMI_LOGD("Action:%d; vdev_id:%d; clearList:%d; MCBC MAC Addr: %pM", 14542 cmd->action, vdev_id, clearList, multicast_addr.bytes); 14543 14544 wmi_mtrace(WMI_SET_MCASTBCAST_FILTER_CMDID, cmd->vdev_id, 0); 14545 err = wmi_unified_cmd_send(wmi_handle, buf, 14546 sizeof(*cmd), 14547 WMI_SET_MCASTBCAST_FILTER_CMDID); 14548 if (err) { 14549 WMI_LOGE("Failed to send set_param cmd"); 14550 wmi_buf_free(buf); 14551 return QDF_STATUS_E_FAILURE; 14552 } 14553 14554 return QDF_STATUS_SUCCESS; 14555 } 14556 14557 /** 14558 * send_multiple_add_clear_mcbc_filter_cmd_tlv() - send multiple mcast filter 14559 * command to fw 14560 * @wmi_handle: wmi handle 14561 * @vdev_id: vdev id 14562 * @mcast_filter_params: mcast filter params 14563 * 14564 * Return: QDF_STATUS_SUCCESS for success or error code 14565 */ 14566 static QDF_STATUS send_multiple_add_clear_mcbc_filter_cmd_tlv( 14567 wmi_unified_t wmi_handle, 14568 uint8_t vdev_id, 14569 struct pmo_mcast_filter_params *filter_param) 14570 14571 { 14572 WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *cmd; 14573 uint8_t *buf_ptr; 14574 wmi_buf_t buf; 14575 int err; 14576 int i; 14577 uint8_t *mac_addr_src_ptr = NULL; 14578 wmi_mac_addr *mac_addr_dst_ptr; 14579 uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 14580 sizeof(wmi_mac_addr) * filter_param->multicast_addr_cnt; 14581 14582 buf = wmi_buf_alloc(wmi_handle, len); 14583 if (!buf) { 14584 WMI_LOGE("Failed to allocate memory"); 14585 return QDF_STATUS_E_NOMEM; 14586 } 14587 14588 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14589 cmd = (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param *) 14590 wmi_buf_data(buf); 14591 qdf_mem_zero(cmd, sizeof(*cmd)); 14592 14593 WMITLV_SET_HDR(&cmd->tlv_header, 14594 WMITLV_TAG_STRUC_wmi_set_multiple_mcast_filter_cmd_fixed_param, 14595 WMITLV_GET_STRUCT_TLVLEN 14596 (WMI_SET_MULTIPLE_MCAST_FILTER_CMD_fixed_param)); 14597 cmd->operation = 14598 ((filter_param->action == 0) ? WMI_MULTIPLE_MCAST_FILTER_DELETE 14599 : WMI_MULTIPLE_MCAST_FILTER_ADD); 14600 cmd->vdev_id = vdev_id; 14601 cmd->num_mcastaddrs = filter_param->multicast_addr_cnt; 14602 14603 buf_ptr += sizeof(*cmd); 14604 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 14605 sizeof(wmi_mac_addr) * 14606 filter_param->multicast_addr_cnt); 14607 14608 if (filter_param->multicast_addr_cnt == 0) 14609 goto send_cmd; 14610 14611 mac_addr_src_ptr = (uint8_t *)&filter_param->multicast_addr; 14612 mac_addr_dst_ptr = (wmi_mac_addr *) 14613 (buf_ptr + WMI_TLV_HDR_SIZE); 14614 14615 for (i = 0; i < filter_param->multicast_addr_cnt; i++) { 14616 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac_addr_src_ptr, mac_addr_dst_ptr); 14617 mac_addr_src_ptr += ATH_MAC_LEN; 14618 mac_addr_dst_ptr++; 14619 } 14620 14621 send_cmd: 14622 wmi_mtrace(WMI_SET_MULTIPLE_MCAST_FILTER_CMDID, cmd->vdev_id, 0); 14623 err = wmi_unified_cmd_send(wmi_handle, buf, 14624 len, 14625 WMI_SET_MULTIPLE_MCAST_FILTER_CMDID); 14626 if (err) { 14627 WMI_LOGE("Failed to send set_param cmd"); 14628 wmi_buf_free(buf); 14629 return QDF_STATUS_E_FAILURE; 14630 } 14631 14632 return QDF_STATUS_SUCCESS; 14633 } 14634 14635 static void 14636 fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd, 14637 uint8_t vdev_id, 14638 struct pmo_gtk_req *params) 14639 { 14640 uint8_t *buf_ptr; 14641 wmi_gtk_offload_fils_tlv_param *ext_param; 14642 14643 buf_ptr = (uint8_t *) cmd + sizeof(*cmd); 14644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 14645 sizeof(*ext_param)); 14646 buf_ptr += WMI_TLV_HDR_SIZE; 14647 14648 ext_param = (wmi_gtk_offload_fils_tlv_param *)buf_ptr; 14649 WMITLV_SET_HDR(&ext_param->tlv_header, 14650 WMITLV_TAG_STRUC_wmi_gtk_offload_extended_tlv_param, 14651 WMITLV_GET_STRUCT_TLVLEN( 14652 wmi_gtk_offload_fils_tlv_param)); 14653 ext_param->vdev_id = vdev_id; 14654 ext_param->flags = cmd->flags; 14655 ext_param->kek_len = params->kek_len; 14656 qdf_mem_copy(ext_param->KEK, params->kek, params->kek_len); 14657 qdf_mem_copy(ext_param->KCK, params->kck, 14658 WMI_GTK_OFFLOAD_KCK_BYTES); 14659 qdf_mem_copy(ext_param->replay_counter, ¶ms->replay_counter, 14660 GTK_REPLAY_COUNTER_BYTES); 14661 } 14662 14663 /** 14664 * send_gtk_offload_cmd_tlv() - send GTK offload command to fw 14665 * @wmi_handle: wmi handle 14666 * @vdev_id: vdev id 14667 * @params: GTK offload parameters 14668 * 14669 * Return: CDF status 14670 */ 14671 static 14672 QDF_STATUS send_gtk_offload_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 14673 struct pmo_gtk_req *params, 14674 bool enable_offload, 14675 uint32_t gtk_offload_opcode) 14676 { 14677 int len; 14678 wmi_buf_t buf; 14679 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14680 QDF_STATUS status = QDF_STATUS_SUCCESS; 14681 14682 WMI_LOGD("%s Enter", __func__); 14683 14684 len = sizeof(*cmd); 14685 14686 if (params->is_fils_connection) 14687 len += WMI_TLV_HDR_SIZE + 14688 sizeof(wmi_gtk_offload_fils_tlv_param); 14689 14690 /* alloc wmi buffer */ 14691 buf = wmi_buf_alloc(wmi_handle, len); 14692 if (!buf) { 14693 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14694 status = QDF_STATUS_E_NOMEM; 14695 goto out; 14696 } 14697 14698 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14699 WMITLV_SET_HDR(&cmd->tlv_header, 14700 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14701 WMITLV_GET_STRUCT_TLVLEN 14702 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14703 14704 cmd->vdev_id = vdev_id; 14705 14706 /* Request target to enable GTK offload */ 14707 if (enable_offload == PMO_GTK_OFFLOAD_ENABLE) { 14708 cmd->flags = gtk_offload_opcode; 14709 14710 /* Copy the keys and replay counter */ 14711 qdf_mem_copy(cmd->KCK, params->kck, PMO_KCK_LEN); 14712 qdf_mem_copy(cmd->KEK, params->kek, PMO_KEK_LEN_LEGACY); 14713 qdf_mem_copy(cmd->replay_counter, ¶ms->replay_counter, 14714 GTK_REPLAY_COUNTER_BYTES); 14715 } else { 14716 cmd->flags = gtk_offload_opcode; 14717 } 14718 if (params->is_fils_connection) 14719 fill_fils_tlv_params(cmd, vdev_id, params); 14720 14721 WMI_LOGD("VDEVID: %d, GTK_FLAGS: x%x kek len %d", vdev_id, cmd->flags, params->kek_len); 14722 /* send the wmi command */ 14723 wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0); 14724 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14725 WMI_GTK_OFFLOAD_CMDID)) { 14726 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); 14727 wmi_buf_free(buf); 14728 status = QDF_STATUS_E_FAILURE; 14729 } 14730 14731 out: 14732 WMI_LOGD("%s Exit", __func__); 14733 return status; 14734 } 14735 14736 /** 14737 * send_process_gtk_offload_getinfo_cmd_tlv() - send GTK offload cmd to fw 14738 * @wmi_handle: wmi handle 14739 * @params: GTK offload params 14740 * 14741 * Return: CDF status 14742 */ 14743 static QDF_STATUS send_process_gtk_offload_getinfo_cmd_tlv( 14744 wmi_unified_t wmi_handle, 14745 uint8_t vdev_id, 14746 uint64_t offload_req_opcode) 14747 { 14748 int len; 14749 wmi_buf_t buf; 14750 WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; 14751 QDF_STATUS status = QDF_STATUS_SUCCESS; 14752 14753 len = sizeof(*cmd); 14754 14755 /* alloc wmi buffer */ 14756 buf = wmi_buf_alloc(wmi_handle, len); 14757 if (!buf) { 14758 WMI_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); 14759 status = QDF_STATUS_E_NOMEM; 14760 goto out; 14761 } 14762 14763 cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *) wmi_buf_data(buf); 14764 WMITLV_SET_HDR(&cmd->tlv_header, 14765 WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, 14766 WMITLV_GET_STRUCT_TLVLEN 14767 (WMI_GTK_OFFLOAD_CMD_fixed_param)); 14768 14769 /* Request for GTK offload status */ 14770 cmd->flags = offload_req_opcode; 14771 cmd->vdev_id = vdev_id; 14772 14773 /* send the wmi command */ 14774 wmi_mtrace(WMI_GTK_OFFLOAD_CMDID, cmd->vdev_id, 0); 14775 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14776 WMI_GTK_OFFLOAD_CMDID)) { 14777 WMI_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); 14778 wmi_buf_free(buf); 14779 status = QDF_STATUS_E_FAILURE; 14780 } 14781 14782 out: 14783 return status; 14784 } 14785 14786 /** 14787 * send_action_frame_patterns_cmd_tlv() - send wmi cmd of action filter params 14788 * @wmi_handle: wmi handler 14789 * @action_params: pointer to action_params 14790 * 14791 * Return: 0 for success, otherwise appropriate error code 14792 */ 14793 static QDF_STATUS send_action_frame_patterns_cmd_tlv(wmi_unified_t wmi_handle, 14794 struct pmo_action_wakeup_set_params *action_params) 14795 { 14796 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *cmd; 14797 wmi_buf_t buf; 14798 int i; 14799 int32_t err; 14800 uint32_t len = 0, *cmd_args; 14801 uint8_t *buf_ptr; 14802 14803 len = (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t)) 14804 + WMI_TLV_HDR_SIZE + sizeof(*cmd); 14805 buf = wmi_buf_alloc(wmi_handle, len); 14806 if (!buf) { 14807 WMI_LOGE("Failed to allocate buffer to send action filter cmd"); 14808 return QDF_STATUS_E_NOMEM; 14809 } 14810 cmd = (WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param *) wmi_buf_data(buf); 14811 buf_ptr = (uint8_t *)cmd; 14812 WMITLV_SET_HDR(&cmd->tlv_header, 14813 WMITLV_TAG_STRUC_wmi_wow_set_action_wake_up_cmd_fixed_param, 14814 WMITLV_GET_STRUCT_TLVLEN( 14815 WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param)); 14816 14817 cmd->vdev_id = action_params->vdev_id; 14818 cmd->operation = action_params->operation; 14819 14820 for (i = 0; i < MAX_SUPPORTED_ACTION_CATEGORY_ELE_LIST; i++) 14821 cmd->action_category_map[i] = 14822 action_params->action_category_map[i]; 14823 14824 buf_ptr += sizeof(WMI_WOW_SET_ACTION_WAKE_UP_CMD_fixed_param); 14825 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14826 (PMO_SUPPORTED_ACTION_CATE * sizeof(uint32_t))); 14827 buf_ptr += WMI_TLV_HDR_SIZE; 14828 cmd_args = (uint32_t *) buf_ptr; 14829 for (i = 0; i < PMO_SUPPORTED_ACTION_CATE; i++) 14830 cmd_args[i] = action_params->action_per_category[i]; 14831 14832 wmi_mtrace(WMI_WOW_SET_ACTION_WAKE_UP_CMDID, cmd->vdev_id, 0); 14833 err = wmi_unified_cmd_send(wmi_handle, buf, 14834 len, WMI_WOW_SET_ACTION_WAKE_UP_CMDID); 14835 if (err) { 14836 WMI_LOGE("Failed to send ap_ps_egap cmd"); 14837 wmi_buf_free(buf); 14838 return QDF_STATUS_E_FAILURE; 14839 } 14840 14841 return QDF_STATUS_SUCCESS; 14842 } 14843 14844 #ifdef FEATURE_WLAN_LPHB 14845 14846 /** 14847 * send_lphb_config_hbenable_cmd_tlv() - enable command of LPHB configuration 14848 * @wmi_handle: wmi handle 14849 * @lphb_conf_req: configuration info 14850 * 14851 * Return: CDF status 14852 */ 14853 static QDF_STATUS send_lphb_config_hbenable_cmd_tlv(wmi_unified_t wmi_handle, 14854 wmi_hb_set_enable_cmd_fixed_param *params) 14855 { 14856 QDF_STATUS status; 14857 wmi_buf_t buf = NULL; 14858 uint8_t *buf_ptr; 14859 wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; 14860 int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); 14861 14862 14863 buf = wmi_buf_alloc(wmi_handle, len); 14864 if (!buf) { 14865 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14866 return QDF_STATUS_E_NOMEM; 14867 } 14868 14869 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14870 hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; 14871 WMITLV_SET_HDR(&hb_enable_fp->tlv_header, 14872 WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, 14873 WMITLV_GET_STRUCT_TLVLEN 14874 (wmi_hb_set_enable_cmd_fixed_param)); 14875 14876 /* fill in values */ 14877 hb_enable_fp->vdev_id = params->session; 14878 hb_enable_fp->enable = params->enable; 14879 hb_enable_fp->item = params->item; 14880 hb_enable_fp->session = params->session; 14881 14882 wmi_mtrace(WMI_HB_SET_ENABLE_CMDID, NO_SESSION, 0); 14883 status = wmi_unified_cmd_send(wmi_handle, buf, 14884 len, WMI_HB_SET_ENABLE_CMDID); 14885 if (QDF_IS_STATUS_ERROR(status)) { 14886 WMI_LOGE("cmd_send WMI_HB_SET_ENABLE returned Error %d", 14887 status); 14888 wmi_buf_free(buf); 14889 } 14890 14891 return status; 14892 } 14893 14894 /** 14895 * send_lphb_config_tcp_params_cmd_tlv() - set tcp params of LPHB configuration 14896 * @wmi_handle: wmi handle 14897 * @lphb_conf_req: lphb config request 14898 * 14899 * Return: CDF status 14900 */ 14901 static QDF_STATUS send_lphb_config_tcp_params_cmd_tlv(wmi_unified_t wmi_handle, 14902 wmi_hb_set_tcp_params_cmd_fixed_param *lphb_conf_req) 14903 { 14904 QDF_STATUS status; 14905 wmi_buf_t buf = NULL; 14906 uint8_t *buf_ptr; 14907 wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; 14908 int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); 14909 14910 buf = wmi_buf_alloc(wmi_handle, len); 14911 if (!buf) { 14912 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14913 return QDF_STATUS_E_NOMEM; 14914 } 14915 14916 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14917 hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; 14918 WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, 14919 WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, 14920 WMITLV_GET_STRUCT_TLVLEN 14921 (wmi_hb_set_tcp_params_cmd_fixed_param)); 14922 14923 /* fill in values */ 14924 hb_tcp_params_fp->vdev_id = lphb_conf_req->vdev_id; 14925 hb_tcp_params_fp->srv_ip = lphb_conf_req->srv_ip; 14926 hb_tcp_params_fp->dev_ip = lphb_conf_req->dev_ip; 14927 hb_tcp_params_fp->seq = lphb_conf_req->seq; 14928 hb_tcp_params_fp->src_port = lphb_conf_req->src_port; 14929 hb_tcp_params_fp->dst_port = lphb_conf_req->dst_port; 14930 hb_tcp_params_fp->interval = lphb_conf_req->interval; 14931 hb_tcp_params_fp->timeout = lphb_conf_req->timeout; 14932 hb_tcp_params_fp->session = lphb_conf_req->session; 14933 qdf_mem_copy(&hb_tcp_params_fp->gateway_mac, 14934 &lphb_conf_req->gateway_mac, 14935 sizeof(hb_tcp_params_fp->gateway_mac)); 14936 14937 wmi_mtrace(WMI_HB_SET_TCP_PARAMS_CMDID, NO_SESSION, 0); 14938 status = wmi_unified_cmd_send(wmi_handle, buf, 14939 len, WMI_HB_SET_TCP_PARAMS_CMDID); 14940 if (QDF_IS_STATUS_ERROR(status)) { 14941 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", 14942 status); 14943 wmi_buf_free(buf); 14944 } 14945 14946 return status; 14947 } 14948 14949 /** 14950 * send_lphb_config_tcp_pkt_filter_cmd_tlv() - configure tcp packet filter cmd 14951 * @wmi_handle: wmi handle 14952 * @lphb_conf_req: lphb config request 14953 * 14954 * Return: CDF status 14955 */ 14956 static 14957 QDF_STATUS send_lphb_config_tcp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 14958 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *g_hb_tcp_filter_fp) 14959 { 14960 QDF_STATUS status; 14961 wmi_buf_t buf = NULL; 14962 uint8_t *buf_ptr; 14963 wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; 14964 int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); 14965 14966 buf = wmi_buf_alloc(wmi_handle, len); 14967 if (!buf) { 14968 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 14969 return QDF_STATUS_E_NOMEM; 14970 } 14971 14972 buf_ptr = (uint8_t *) wmi_buf_data(buf); 14973 hb_tcp_filter_fp = 14974 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; 14975 WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, 14976 WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, 14977 WMITLV_GET_STRUCT_TLVLEN 14978 (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); 14979 14980 /* fill in values */ 14981 hb_tcp_filter_fp->vdev_id = g_hb_tcp_filter_fp->vdev_id; 14982 hb_tcp_filter_fp->length = g_hb_tcp_filter_fp->length; 14983 hb_tcp_filter_fp->offset = g_hb_tcp_filter_fp->offset; 14984 hb_tcp_filter_fp->session = g_hb_tcp_filter_fp->session; 14985 memcpy((void *)&hb_tcp_filter_fp->filter, 14986 (void *)&g_hb_tcp_filter_fp->filter, 14987 WMI_WLAN_HB_MAX_FILTER_SIZE); 14988 14989 wmi_mtrace(WMI_HB_SET_TCP_PKT_FILTER_CMDID, NO_SESSION, 0); 14990 status = wmi_unified_cmd_send(wmi_handle, buf, 14991 len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); 14992 if (QDF_IS_STATUS_ERROR(status)) { 14993 WMI_LOGE("cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", 14994 status); 14995 wmi_buf_free(buf); 14996 } 14997 14998 return status; 14999 } 15000 15001 /** 15002 * send_lphb_config_udp_params_cmd_tlv() - configure udp param command of LPHB 15003 * @wmi_handle: wmi handle 15004 * @lphb_conf_req: lphb config request 15005 * 15006 * Return: CDF status 15007 */ 15008 static QDF_STATUS send_lphb_config_udp_params_cmd_tlv(wmi_unified_t wmi_handle, 15009 wmi_hb_set_udp_params_cmd_fixed_param *lphb_conf_req) 15010 { 15011 QDF_STATUS status; 15012 wmi_buf_t buf = NULL; 15013 uint8_t *buf_ptr; 15014 wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; 15015 int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); 15016 15017 buf = wmi_buf_alloc(wmi_handle, len); 15018 if (!buf) { 15019 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15020 return QDF_STATUS_E_NOMEM; 15021 } 15022 15023 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15024 hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; 15025 WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, 15026 WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, 15027 WMITLV_GET_STRUCT_TLVLEN 15028 (wmi_hb_set_udp_params_cmd_fixed_param)); 15029 15030 /* fill in values */ 15031 hb_udp_params_fp->vdev_id = lphb_conf_req->vdev_id; 15032 hb_udp_params_fp->srv_ip = lphb_conf_req->srv_ip; 15033 hb_udp_params_fp->dev_ip = lphb_conf_req->dev_ip; 15034 hb_udp_params_fp->src_port = lphb_conf_req->src_port; 15035 hb_udp_params_fp->dst_port = lphb_conf_req->dst_port; 15036 hb_udp_params_fp->interval = lphb_conf_req->interval; 15037 hb_udp_params_fp->timeout = lphb_conf_req->timeout; 15038 hb_udp_params_fp->session = lphb_conf_req->session; 15039 qdf_mem_copy(&hb_udp_params_fp->gateway_mac, 15040 &lphb_conf_req->gateway_mac, 15041 sizeof(lphb_conf_req->gateway_mac)); 15042 15043 wmi_mtrace(WMI_HB_SET_UDP_PARAMS_CMDID, NO_SESSION, 0); 15044 status = wmi_unified_cmd_send(wmi_handle, buf, 15045 len, WMI_HB_SET_UDP_PARAMS_CMDID); 15046 if (QDF_IS_STATUS_ERROR(status)) { 15047 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", 15048 status); 15049 wmi_buf_free(buf); 15050 } 15051 15052 return status; 15053 } 15054 15055 /** 15056 * send_lphb_config_udp_pkt_filter_cmd_tlv() - configure udp pkt filter command 15057 * @wmi_handle: wmi handle 15058 * @lphb_conf_req: lphb config request 15059 * 15060 * Return: CDF status 15061 */ 15062 static 15063 QDF_STATUS send_lphb_config_udp_pkt_filter_cmd_tlv(wmi_unified_t wmi_handle, 15064 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *lphb_conf_req) 15065 { 15066 QDF_STATUS status; 15067 wmi_buf_t buf = NULL; 15068 uint8_t *buf_ptr; 15069 wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; 15070 int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); 15071 15072 buf = wmi_buf_alloc(wmi_handle, len); 15073 if (!buf) { 15074 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15075 return QDF_STATUS_E_NOMEM; 15076 } 15077 15078 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15079 hb_udp_filter_fp = 15080 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; 15081 WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, 15082 WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, 15083 WMITLV_GET_STRUCT_TLVLEN 15084 (wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); 15085 15086 /* fill in values */ 15087 hb_udp_filter_fp->vdev_id = lphb_conf_req->vdev_id; 15088 hb_udp_filter_fp->length = lphb_conf_req->length; 15089 hb_udp_filter_fp->offset = lphb_conf_req->offset; 15090 hb_udp_filter_fp->session = lphb_conf_req->session; 15091 memcpy((void *)&hb_udp_filter_fp->filter, 15092 (void *)&lphb_conf_req->filter, 15093 WMI_WLAN_HB_MAX_FILTER_SIZE); 15094 15095 wmi_mtrace(WMI_HB_SET_UDP_PKT_FILTER_CMDID, NO_SESSION, 0); 15096 status = wmi_unified_cmd_send(wmi_handle, buf, 15097 len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); 15098 if (QDF_IS_STATUS_ERROR(status)) { 15099 WMI_LOGE("cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", 15100 status); 15101 wmi_buf_free(buf); 15102 } 15103 15104 return status; 15105 } 15106 #endif /* FEATURE_WLAN_LPHB */ 15107 15108 static QDF_STATUS send_conf_hw_filter_cmd_tlv(wmi_unified_t wmi, 15109 struct pmo_hw_filter_params *req) 15110 { 15111 QDF_STATUS status; 15112 wmi_hw_data_filter_cmd_fixed_param *cmd; 15113 wmi_buf_t wmi_buf; 15114 15115 if (!req) { 15116 WMI_LOGE("req is null"); 15117 return QDF_STATUS_E_INVAL; 15118 } 15119 15120 wmi_buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 15121 if (!wmi_buf) { 15122 WMI_LOGE(FL("Out of memory")); 15123 return QDF_STATUS_E_NOMEM; 15124 } 15125 15126 cmd = (wmi_hw_data_filter_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15127 WMITLV_SET_HDR(&cmd->tlv_header, 15128 WMITLV_TAG_STRUC_wmi_hw_data_filter_cmd_fixed_param, 15129 WMITLV_GET_STRUCT_TLVLEN(wmi_hw_data_filter_cmd_fixed_param)); 15130 cmd->vdev_id = req->vdev_id; 15131 cmd->enable = req->enable; 15132 /* Set all modes in case of disable */ 15133 if (!cmd->enable) 15134 cmd->hw_filter_bitmap = ((uint32_t)~0U); 15135 else 15136 cmd->hw_filter_bitmap = req->mode_bitmap; 15137 15138 WMI_LOGD("Send %s hw filter mode: 0x%X for vdev id %d", 15139 req->enable ? "enable" : "disable", req->mode_bitmap, 15140 req->vdev_id); 15141 15142 wmi_mtrace(WMI_HW_DATA_FILTER_CMDID, cmd->vdev_id, 0); 15143 status = wmi_unified_cmd_send(wmi, wmi_buf, sizeof(*cmd), 15144 WMI_HW_DATA_FILTER_CMDID); 15145 if (QDF_IS_STATUS_ERROR(status)) { 15146 WMI_LOGE("Failed to configure hw filter"); 15147 wmi_buf_free(wmi_buf); 15148 } 15149 15150 return status; 15151 } 15152 15153 #ifdef WLAN_FEATURE_PACKET_FILTERING 15154 /** 15155 * send_enable_disable_packet_filter_cmd_tlv() - enable/disable packet filter 15156 * @wmi_handle: wmi handle 15157 * @vdev_id: vdev id 15158 * @enable: Flag to enable/disable packet filter 15159 * 15160 * Return: QDF_STATUS_SUCCESS for success or error code 15161 */ 15162 static QDF_STATUS send_enable_disable_packet_filter_cmd_tlv( 15163 wmi_unified_t wmi_handle, uint8_t vdev_id, bool enable) 15164 { 15165 int32_t len; 15166 int ret = 0; 15167 wmi_buf_t buf; 15168 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *cmd; 15169 15170 len = sizeof(WMI_PACKET_FILTER_ENABLE_CMD_fixed_param); 15171 15172 buf = wmi_buf_alloc(wmi_handle, len); 15173 if (!buf) { 15174 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 15175 return QDF_STATUS_E_NOMEM; 15176 } 15177 15178 cmd = (WMI_PACKET_FILTER_ENABLE_CMD_fixed_param *) wmi_buf_data(buf); 15179 WMITLV_SET_HDR(&cmd->tlv_header, 15180 WMITLV_TAG_STRUC_wmi_packet_filter_enable_fixed_param, 15181 WMITLV_GET_STRUCT_TLVLEN( 15182 WMI_PACKET_FILTER_ENABLE_CMD_fixed_param)); 15183 15184 cmd->vdev_id = vdev_id; 15185 if (enable) 15186 cmd->enable = PACKET_FILTER_SET_ENABLE; 15187 else 15188 cmd->enable = PACKET_FILTER_SET_DISABLE; 15189 15190 WMI_LOGE("%s: Packet filter enable %d for vdev_id %d", 15191 __func__, cmd->enable, vdev_id); 15192 15193 wmi_mtrace(WMI_PACKET_FILTER_ENABLE_CMDID, cmd->vdev_id, 0); 15194 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15195 WMI_PACKET_FILTER_ENABLE_CMDID); 15196 if (ret) { 15197 WMI_LOGE("Failed to send packet filter wmi cmd to fw"); 15198 wmi_buf_free(buf); 15199 } 15200 15201 return ret; 15202 } 15203 15204 /** 15205 * send_config_packet_filter_cmd_tlv() - configure packet filter in target 15206 * @wmi_handle: wmi handle 15207 * @vdev_id: vdev id 15208 * @rcv_filter_param: Packet filter parameters 15209 * @filter_id: Filter id 15210 * @enable: Flag to add/delete packet filter configuration 15211 * 15212 * Return: QDF_STATUS_SUCCESS for success or error code 15213 */ 15214 static QDF_STATUS send_config_packet_filter_cmd_tlv(wmi_unified_t wmi_handle, 15215 uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, 15216 uint8_t filter_id, bool enable) 15217 { 15218 int len, i; 15219 int err = 0; 15220 wmi_buf_t buf; 15221 WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *cmd; 15222 15223 15224 /* allocate the memory */ 15225 len = sizeof(*cmd); 15226 buf = wmi_buf_alloc(wmi_handle, len); 15227 if (!buf) { 15228 WMI_LOGE("Failed to allocate buffer to send set_param cmd"); 15229 return QDF_STATUS_E_NOMEM; 15230 } 15231 15232 cmd = (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 15233 WMITLV_SET_HDR(&cmd->tlv_header, 15234 WMITLV_TAG_STRUC_wmi_packet_filter_config_fixed_param, 15235 WMITLV_GET_STRUCT_TLVLEN 15236 (WMI_PACKET_FILTER_CONFIG_CMD_fixed_param)); 15237 15238 cmd->vdev_id = vdev_id; 15239 cmd->filter_id = filter_id; 15240 if (enable) 15241 cmd->filter_action = PACKET_FILTER_SET_ACTIVE; 15242 else 15243 cmd->filter_action = PACKET_FILTER_SET_INACTIVE; 15244 15245 if (enable) { 15246 cmd->num_params = QDF_MIN( 15247 WMI_PACKET_FILTER_MAX_CMP_PER_PACKET_FILTER, 15248 rcv_filter_param->num_params); 15249 cmd->filter_type = rcv_filter_param->filter_type; 15250 cmd->coalesce_time = rcv_filter_param->coalesce_time; 15251 15252 for (i = 0; i < cmd->num_params; i++) { 15253 cmd->paramsData[i].proto_type = 15254 rcv_filter_param->params_data[i].protocol_layer; 15255 cmd->paramsData[i].cmp_type = 15256 rcv_filter_param->params_data[i].compare_flag; 15257 cmd->paramsData[i].data_length = 15258 rcv_filter_param->params_data[i].data_length; 15259 cmd->paramsData[i].data_offset = 15260 rcv_filter_param->params_data[i].data_offset; 15261 memcpy(&cmd->paramsData[i].compareData, 15262 rcv_filter_param->params_data[i].compare_data, 15263 sizeof(cmd->paramsData[i].compareData)); 15264 memcpy(&cmd->paramsData[i].dataMask, 15265 rcv_filter_param->params_data[i].data_mask, 15266 sizeof(cmd->paramsData[i].dataMask)); 15267 } 15268 } 15269 15270 WMI_LOGE("Packet filter action %d filter with id: %d, num_params=%d", 15271 cmd->filter_action, cmd->filter_id, cmd->num_params); 15272 /* send the command along with data */ 15273 wmi_mtrace(WMI_PACKET_FILTER_CONFIG_CMDID, cmd->vdev_id, 0); 15274 err = wmi_unified_cmd_send(wmi_handle, buf, len, 15275 WMI_PACKET_FILTER_CONFIG_CMDID); 15276 if (err) { 15277 WMI_LOGE("Failed to send pkt_filter cmd"); 15278 wmi_buf_free(buf); 15279 return QDF_STATUS_E_FAILURE; 15280 } 15281 15282 return QDF_STATUS_SUCCESS; 15283 } 15284 #endif /* End of WLAN_FEATURE_PACKET_FILTERING */ 15285 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 15286 15287 /** 15288 * send_set_ssid_hotlist_cmd_tlv() - Handle an SSID hotlist set request 15289 * @wmi_handle: wmi handle 15290 * @request: SSID hotlist set request 15291 * 15292 * Return: QDF_STATUS enumeration 15293 */ 15294 static QDF_STATUS 15295 send_set_ssid_hotlist_cmd_tlv(wmi_unified_t wmi_handle, 15296 struct ssid_hotlist_request_params *request) 15297 { 15298 wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *cmd; 15299 wmi_buf_t wmi_buf; 15300 uint32_t len; 15301 uint32_t array_size; 15302 uint8_t *buf_ptr; 15303 15304 /* length of fixed portion */ 15305 len = sizeof(*cmd); 15306 15307 /* length of variable portion */ 15308 array_size = 15309 request->ssid_count * sizeof(wmi_extscan_hotlist_ssid_entry); 15310 len += WMI_TLV_HDR_SIZE + array_size; 15311 15312 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15313 if (!wmi_buf) { 15314 WMI_LOGE("%s: wmi_buf_alloc failed", __func__); 15315 return QDF_STATUS_E_NOMEM; 15316 } 15317 15318 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 15319 cmd = (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param *) 15320 buf_ptr; 15321 WMITLV_SET_HDR 15322 (&cmd->tlv_header, 15323 WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, 15324 WMITLV_GET_STRUCT_TLVLEN 15325 (wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param)); 15326 15327 cmd->request_id = request->request_id; 15328 cmd->requestor_id = 0; 15329 cmd->vdev_id = request->session_id; 15330 cmd->table_id = 0; 15331 cmd->lost_ap_scan_count = request->lost_ssid_sample_size; 15332 cmd->total_entries = request->ssid_count; 15333 cmd->num_entries_in_page = request->ssid_count; 15334 cmd->first_entry_index = 0; 15335 15336 buf_ptr += sizeof(*cmd); 15337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, array_size); 15338 15339 if (request->ssid_count) { 15340 wmi_extscan_hotlist_ssid_entry *entry; 15341 int i; 15342 15343 buf_ptr += WMI_TLV_HDR_SIZE; 15344 entry = (wmi_extscan_hotlist_ssid_entry *)buf_ptr; 15345 for (i = 0; i < request->ssid_count; i++) { 15346 WMITLV_SET_HDR 15347 (entry, 15348 WMITLV_TAG_ARRAY_STRUC, 15349 WMITLV_GET_STRUCT_TLVLEN 15350 (wmi_extscan_hotlist_ssid_entry)); 15351 entry->ssid.ssid_len = request->ssids[i].ssid.length; 15352 qdf_mem_copy(entry->ssid.ssid, 15353 request->ssids[i].ssid.mac_ssid, 15354 request->ssids[i].ssid.length); 15355 entry->band = request->ssids[i].band; 15356 entry->min_rssi = request->ssids[i].rssi_low; 15357 entry->max_rssi = request->ssids[i].rssi_high; 15358 entry++; 15359 } 15360 cmd->mode = WMI_EXTSCAN_MODE_START; 15361 } else { 15362 cmd->mode = WMI_EXTSCAN_MODE_STOP; 15363 } 15364 15365 wmi_mtrace(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID, 15366 cmd->vdev_id, 0); 15367 if (wmi_unified_cmd_send 15368 (wmi_handle, wmi_buf, len, 15369 WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID)) { 15370 WMI_LOGE("%s: failed to send command", __func__); 15371 wmi_buf_free(wmi_buf); 15372 return QDF_STATUS_E_FAILURE; 15373 } 15374 15375 return QDF_STATUS_SUCCESS; 15376 } 15377 15378 /** 15379 * send_fw_test_cmd_tlv() - send fw test command to fw. 15380 * @wmi_handle: wmi handle 15381 * @wmi_fwtest: fw test command 15382 * 15383 * This function sends fw test command to fw. 15384 * 15385 * Return: CDF STATUS 15386 */ 15387 static 15388 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 15389 struct set_fwtest_params *wmi_fwtest) 15390 { 15391 wmi_fwtest_set_param_cmd_fixed_param *cmd; 15392 wmi_buf_t wmi_buf; 15393 uint16_t len; 15394 15395 len = sizeof(*cmd); 15396 15397 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15398 if (!wmi_buf) { 15399 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15400 return QDF_STATUS_E_NOMEM; 15401 } 15402 15403 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15404 WMITLV_SET_HDR(&cmd->tlv_header, 15405 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 15406 WMITLV_GET_STRUCT_TLVLEN( 15407 wmi_fwtest_set_param_cmd_fixed_param)); 15408 cmd->param_id = wmi_fwtest->arg; 15409 cmd->param_value = wmi_fwtest->value; 15410 15411 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 15412 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15413 WMI_FWTEST_CMDID)) { 15414 WMI_LOGP("%s: failed to send fw test command", __func__); 15415 wmi_buf_free(wmi_buf); 15416 return QDF_STATUS_E_FAILURE; 15417 } 15418 15419 return QDF_STATUS_SUCCESS; 15420 } 15421 15422 /** 15423 * send_unit_test_cmd_tlv() - send unit test command to fw. 15424 * @wmi_handle: wmi handle 15425 * @wmi_utest: unit test command 15426 * 15427 * This function send unit test command to fw. 15428 * 15429 * Return: CDF STATUS 15430 */ 15431 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 15432 struct wmi_unit_test_cmd *wmi_utest) 15433 { 15434 wmi_unit_test_cmd_fixed_param *cmd; 15435 wmi_buf_t wmi_buf; 15436 uint8_t *buf_ptr; 15437 int i; 15438 uint16_t len, args_tlv_len; 15439 uint32_t *unit_test_cmd_args; 15440 15441 args_tlv_len = 15442 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 15443 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 15444 15445 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15446 if (!wmi_buf) { 15447 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15448 return QDF_STATUS_E_NOMEM; 15449 } 15450 15451 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 15452 buf_ptr = (uint8_t *) cmd; 15453 WMITLV_SET_HDR(&cmd->tlv_header, 15454 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 15455 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 15456 cmd->vdev_id = wmi_utest->vdev_id; 15457 cmd->module_id = wmi_utest->module_id; 15458 cmd->num_args = wmi_utest->num_args; 15459 cmd->diag_token = wmi_utest->diag_token; 15460 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 15461 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15462 (wmi_utest->num_args * sizeof(uint32_t))); 15463 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15464 WMI_LOGI("%s: VDEV ID: %d\n", __func__, cmd->vdev_id); 15465 WMI_LOGI("%s: MODULE ID: %d\n", __func__, cmd->module_id); 15466 WMI_LOGI("%s: TOKEN: %d\n", __func__, cmd->diag_token); 15467 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 15468 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 15469 unit_test_cmd_args[i] = wmi_utest->args[i]; 15470 WMI_LOGI("%d,", wmi_utest->args[i]); 15471 } 15472 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 15473 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15474 WMI_UNIT_TEST_CMDID)) { 15475 WMI_LOGP("%s: failed to send unit test command", __func__); 15476 wmi_buf_free(wmi_buf); 15477 return QDF_STATUS_E_FAILURE; 15478 } 15479 15480 return QDF_STATUS_SUCCESS; 15481 } 15482 15483 /** 15484 * send_roam_invoke_cmd_tlv() - send roam invoke command to fw. 15485 * @wmi_handle: wma handle 15486 * @roaminvoke: roam invoke command 15487 * 15488 * Send roam invoke command to fw for fastreassoc. 15489 * 15490 * Return: CDF STATUS 15491 */ 15492 static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, 15493 struct wmi_roam_invoke_cmd *roaminvoke, 15494 uint32_t ch_hz) 15495 { 15496 wmi_roam_invoke_cmd_fixed_param *cmd; 15497 wmi_buf_t wmi_buf; 15498 u_int8_t *buf_ptr; 15499 u_int16_t len, args_tlv_len; 15500 uint32_t *channel_list; 15501 wmi_mac_addr *bssid_list; 15502 wmi_tlv_buf_len_param *buf_len_tlv; 15503 15504 /* Host sends only one channel and one bssid */ 15505 args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + 15506 sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + 15507 roundup(roaminvoke->frame_len, sizeof(uint32_t)); 15508 len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; 15509 wmi_buf = wmi_buf_alloc(wmi_handle, len); 15510 if (!wmi_buf) { 15511 WMI_LOGE("%s: wmai_buf_alloc failed", __func__); 15512 return QDF_STATUS_E_NOMEM; 15513 } 15514 15515 cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); 15516 buf_ptr = (u_int8_t *) cmd; 15517 WMITLV_SET_HDR(&cmd->tlv_header, 15518 WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, 15519 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); 15520 cmd->vdev_id = roaminvoke->vdev_id; 15521 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE); 15522 if (roaminvoke->is_same_bssid) 15523 cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP); 15524 WMI_LOGD(FL("is_same_bssid flag: %d"), roaminvoke->is_same_bssid); 15525 15526 if (roaminvoke->frame_len) { 15527 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP; 15528 /* packing 1 beacon/probe_rsp frame with WMI cmd */ 15529 cmd->num_buf = 1; 15530 } else { 15531 cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH; 15532 cmd->num_buf = 0; 15533 } 15534 15535 cmd->roam_ap_sel_mode = 0; 15536 cmd->roam_delay = 0; 15537 cmd->num_chan = 1; 15538 cmd->num_bssid = 1; 15539 15540 buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); 15541 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15542 (sizeof(u_int32_t))); 15543 channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 15544 *channel_list = ch_hz; 15545 buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE; 15546 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15547 (sizeof(wmi_mac_addr))); 15548 bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); 15549 WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); 15550 15551 /* move to next tlv i.e. bcn_prb_buf_list */ 15552 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr); 15553 15554 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 15555 sizeof(wmi_tlv_buf_len_param)); 15556 15557 buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE); 15558 buf_len_tlv->buf_len = roaminvoke->frame_len; 15559 15560 /* move to next tlv i.e. bcn_prb_frm */ 15561 buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param); 15562 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 15563 roundup(roaminvoke->frame_len, sizeof(uint32_t))); 15564 15565 /* copy frame after the header */ 15566 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, 15567 roaminvoke->frame_buf, 15568 roaminvoke->frame_len); 15569 15570 WMI_LOGD(FL("bcn/prb_rsp frame, length: %d"), roaminvoke->frame_len); 15571 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 15572 buf_ptr + WMI_TLV_HDR_SIZE, 15573 roaminvoke->frame_len); 15574 WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d"), 15575 cmd->flags, cmd->roam_scan_mode, 15576 cmd->roam_ap_sel_mode, cmd->roam_delay, 15577 cmd->num_chan, cmd->num_bssid); 15578 WMI_LOGD(FL("BSSID: %pM, channel: %d"), roaminvoke->bssid, ch_hz); 15579 15580 wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0); 15581 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 15582 WMI_ROAM_INVOKE_CMDID)) { 15583 WMI_LOGP("%s: failed to send roam invoke command", __func__); 15584 wmi_buf_free(wmi_buf); 15585 return QDF_STATUS_E_FAILURE; 15586 } 15587 15588 return QDF_STATUS_SUCCESS; 15589 } 15590 15591 /** 15592 * send_roam_scan_offload_cmd_tlv() - set roam offload command 15593 * @wmi_handle: wmi handle 15594 * @command: command 15595 * @vdev_id: vdev id 15596 * 15597 * This function set roam offload command to fw. 15598 * 15599 * Return: CDF status 15600 */ 15601 static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle, 15602 uint32_t command, uint32_t vdev_id) 15603 { 15604 QDF_STATUS status; 15605 wmi_roam_scan_cmd_fixed_param *cmd_fp; 15606 wmi_buf_t buf = NULL; 15607 int len; 15608 uint8_t *buf_ptr; 15609 15610 len = sizeof(wmi_roam_scan_cmd_fixed_param); 15611 buf = wmi_buf_alloc(wmi_handle, len); 15612 if (!buf) { 15613 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15614 return QDF_STATUS_E_NOMEM; 15615 } 15616 15617 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15618 15619 cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; 15620 WMITLV_SET_HDR(&cmd_fp->tlv_header, 15621 WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, 15622 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); 15623 cmd_fp->vdev_id = vdev_id; 15624 cmd_fp->command_arg = command; 15625 15626 wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0); 15627 status = wmi_unified_cmd_send(wmi_handle, buf, 15628 len, WMI_ROAM_SCAN_CMD); 15629 if (QDF_IS_STATUS_ERROR(status)) { 15630 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", 15631 status); 15632 goto error; 15633 } 15634 15635 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__); 15636 return QDF_STATUS_SUCCESS; 15637 15638 error: 15639 wmi_buf_free(buf); 15640 15641 return status; 15642 } 15643 15644 /** 15645 * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw 15646 * @wmi_handle: wmi handle 15647 * @ap_profile_p: ap profile 15648 * @vdev_id: vdev id 15649 * 15650 * Send WMI_ROAM_AP_PROFILE to firmware 15651 * 15652 * Return: CDF status 15653 */ 15654 static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, 15655 struct ap_profile_params *ap_profile) 15656 { 15657 wmi_buf_t buf = NULL; 15658 QDF_STATUS status; 15659 int len; 15660 uint8_t *buf_ptr; 15661 wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; 15662 wmi_roam_cnd_scoring_param *score_param; 15663 wmi_ap_profile *profile; 15664 15665 len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); 15666 len += sizeof(*score_param); 15667 buf = wmi_buf_alloc(wmi_handle, len); 15668 if (!buf) { 15669 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15670 return QDF_STATUS_E_NOMEM; 15671 } 15672 15673 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15674 roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; 15675 WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, 15676 WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, 15677 WMITLV_GET_STRUCT_TLVLEN 15678 (wmi_roam_ap_profile_fixed_param)); 15679 /* fill in threshold values */ 15680 roam_ap_profile_fp->vdev_id = ap_profile->vdev_id; 15681 roam_ap_profile_fp->id = 0; 15682 buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); 15683 15684 profile = (wmi_ap_profile *)buf_ptr; 15685 WMITLV_SET_HDR(&profile->tlv_header, 15686 WMITLV_TAG_STRUC_wmi_ap_profile, 15687 WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile)); 15688 profile->flags = ap_profile->profile.flags; 15689 profile->rssi_threshold = ap_profile->profile.rssi_threshold; 15690 profile->ssid.ssid_len = ap_profile->profile.ssid.length; 15691 qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid, 15692 profile->ssid.ssid_len); 15693 profile->rsn_authmode = ap_profile->profile.rsn_authmode; 15694 profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset; 15695 profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset; 15696 profile->rsn_mcastmgmtcipherset = 15697 ap_profile->profile.rsn_mcastmgmtcipherset; 15698 profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh; 15699 15700 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", 15701 profile->flags, profile->rssi_threshold, 15702 profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid, 15703 profile->rsn_authmode, profile->rsn_ucastcipherset, 15704 profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset, 15705 profile->rssi_abs_thresh); 15706 15707 buf_ptr += sizeof(wmi_ap_profile); 15708 15709 score_param = (wmi_roam_cnd_scoring_param *)buf_ptr; 15710 WMITLV_SET_HDR(&score_param->tlv_header, 15711 WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param, 15712 WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param)); 15713 score_param->disable_bitmap = ap_profile->param.disable_bitmap; 15714 score_param->rssi_weightage_pcnt = 15715 ap_profile->param.rssi_weightage; 15716 score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage; 15717 score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage; 15718 score_param->he_weightage_pcnt = ap_profile->param.he_weightage; 15719 score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage; 15720 score_param->band_weightage_pcnt = ap_profile->param.band_weightage; 15721 score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage; 15722 score_param->esp_qbss_weightage_pcnt = 15723 ap_profile->param.esp_qbss_weightage; 15724 score_param->beamforming_weightage_pcnt = 15725 ap_profile->param.beamforming_weightage; 15726 score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage; 15727 score_param->oce_wan_weightage_pcnt = 15728 ap_profile->param.oce_wan_weightage; 15729 15730 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", 15731 score_param->disable_bitmap, score_param->rssi_weightage_pcnt, 15732 score_param->ht_weightage_pcnt, 15733 score_param->vht_weightage_pcnt, 15734 score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt, 15735 score_param->band_weightage_pcnt, 15736 score_param->nss_weightage_pcnt, 15737 score_param->esp_qbss_weightage_pcnt, 15738 score_param->beamforming_weightage_pcnt, 15739 score_param->pcl_weightage_pcnt, 15740 score_param->oce_wan_weightage_pcnt); 15741 15742 score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score; 15743 score_param->band_scoring.score_pcnt = 15744 ap_profile->param.band_index_score; 15745 score_param->nss_scoring.score_pcnt = 15746 ap_profile->param.nss_index_score; 15747 15748 WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x", 15749 score_param->bw_scoring.score_pcnt, 15750 score_param->band_scoring.score_pcnt, 15751 score_param->nss_scoring.score_pcnt); 15752 15753 score_param->rssi_scoring.best_rssi_threshold = 15754 (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold; 15755 score_param->rssi_scoring.good_rssi_threshold = 15756 (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold; 15757 score_param->rssi_scoring.bad_rssi_threshold = 15758 (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold; 15759 score_param->rssi_scoring.good_rssi_pcnt = 15760 ap_profile->param.rssi_scoring.good_rssi_pcnt; 15761 score_param->rssi_scoring.bad_rssi_pcnt = 15762 ap_profile->param.rssi_scoring.bad_rssi_pcnt; 15763 score_param->rssi_scoring.good_bucket_size = 15764 ap_profile->param.rssi_scoring.good_bucket_size; 15765 score_param->rssi_scoring.bad_bucket_size = 15766 ap_profile->param.rssi_scoring.bad_bucket_size; 15767 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh = 15768 (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh; 15769 15770 WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d", 15771 score_param->rssi_scoring.best_rssi_threshold, 15772 score_param->rssi_scoring.good_rssi_threshold, 15773 score_param->rssi_scoring.bad_rssi_threshold, 15774 score_param->rssi_scoring.rssi_pref_5g_rssi_thresh); 15775 WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d", 15776 score_param->rssi_scoring.good_rssi_pcnt, 15777 score_param->rssi_scoring.bad_rssi_pcnt, 15778 score_param->rssi_scoring.good_bucket_size, 15779 score_param->rssi_scoring.bad_bucket_size); 15780 15781 score_param->esp_qbss_scoring.num_slot = 15782 ap_profile->param.esp_qbss_scoring.num_slot; 15783 score_param->esp_qbss_scoring.score_pcnt3_to_0 = 15784 ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0; 15785 score_param->esp_qbss_scoring.score_pcnt7_to_4 = 15786 ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4; 15787 score_param->esp_qbss_scoring.score_pcnt11_to_8 = 15788 ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8; 15789 score_param->esp_qbss_scoring.score_pcnt15_to_12 = 15790 ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12; 15791 15792 WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15793 score_param->esp_qbss_scoring.num_slot, 15794 score_param->esp_qbss_scoring.score_pcnt3_to_0, 15795 score_param->esp_qbss_scoring.score_pcnt7_to_4, 15796 score_param->esp_qbss_scoring.score_pcnt11_to_8, 15797 score_param->esp_qbss_scoring.score_pcnt15_to_12); 15798 15799 score_param->oce_wan_scoring.num_slot = 15800 ap_profile->param.oce_wan_scoring.num_slot; 15801 score_param->oce_wan_scoring.score_pcnt3_to_0 = 15802 ap_profile->param.oce_wan_scoring.score_pcnt3_to_0; 15803 score_param->oce_wan_scoring.score_pcnt7_to_4 = 15804 ap_profile->param.oce_wan_scoring.score_pcnt7_to_4; 15805 score_param->oce_wan_scoring.score_pcnt11_to_8 = 15806 ap_profile->param.oce_wan_scoring.score_pcnt11_to_8; 15807 score_param->oce_wan_scoring.score_pcnt15_to_12 = 15808 ap_profile->param.oce_wan_scoring.score_pcnt15_to_12; 15809 15810 WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x", 15811 score_param->oce_wan_scoring.num_slot, 15812 score_param->oce_wan_scoring.score_pcnt3_to_0, 15813 score_param->oce_wan_scoring.score_pcnt7_to_4, 15814 score_param->oce_wan_scoring.score_pcnt11_to_8, 15815 score_param->oce_wan_scoring.score_pcnt15_to_12); 15816 15817 wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0); 15818 status = wmi_unified_cmd_send(wmi_handle, buf, 15819 len, WMI_ROAM_AP_PROFILE); 15820 if (QDF_IS_STATUS_ERROR(status)) { 15821 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", 15822 status); 15823 wmi_buf_free(buf); 15824 } 15825 15826 WMI_LOGD("WMI --> WMI_ROAM_AP_PROFILE and other parameters"); 15827 15828 return status; 15829 } 15830 15831 /** 15832 * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period 15833 * @wmi_handle: wmi handle 15834 * @scan_period: scan period 15835 * @scan_age: scan age 15836 * @vdev_id: vdev id 15837 * 15838 * Send WMI_ROAM_SCAN_PERIOD parameters to fw. 15839 * 15840 * Return: CDF status 15841 */ 15842 static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, 15843 uint32_t scan_period, 15844 uint32_t scan_age, 15845 uint32_t vdev_id) 15846 { 15847 QDF_STATUS status; 15848 wmi_buf_t buf = NULL; 15849 int len; 15850 uint8_t *buf_ptr; 15851 wmi_roam_scan_period_fixed_param *scan_period_fp; 15852 15853 /* Send scan period values */ 15854 len = sizeof(wmi_roam_scan_period_fixed_param); 15855 buf = wmi_buf_alloc(wmi_handle, len); 15856 if (!buf) { 15857 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15858 return QDF_STATUS_E_NOMEM; 15859 } 15860 15861 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15862 scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; 15863 WMITLV_SET_HDR(&scan_period_fp->tlv_header, 15864 WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, 15865 WMITLV_GET_STRUCT_TLVLEN 15866 (wmi_roam_scan_period_fixed_param)); 15867 /* fill in scan period values */ 15868 scan_period_fp->vdev_id = vdev_id; 15869 scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ 15870 scan_period_fp->roam_scan_age = scan_age; 15871 15872 wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0); 15873 status = wmi_unified_cmd_send(wmi_handle, buf, 15874 len, WMI_ROAM_SCAN_PERIOD); 15875 if (QDF_IS_STATUS_ERROR(status)) { 15876 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", 15877 status); 15878 goto error; 15879 } 15880 15881 WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", 15882 __func__, scan_period, scan_age); 15883 return QDF_STATUS_SUCCESS; 15884 error: 15885 wmi_buf_free(buf); 15886 15887 return status; 15888 } 15889 15890 /** 15891 * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list 15892 * @wmi_handle: wmi handle 15893 * @chan_count: channel count 15894 * @chan_list: channel list 15895 * @list_type: list type 15896 * @vdev_id: vdev id 15897 * 15898 * Set roam offload channel list. 15899 * 15900 * Return: CDF status 15901 */ 15902 static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 15903 uint8_t chan_count, 15904 uint32_t *chan_list, 15905 uint8_t list_type, uint32_t vdev_id) 15906 { 15907 wmi_buf_t buf = NULL; 15908 QDF_STATUS status; 15909 int len, list_tlv_len; 15910 int i; 15911 uint8_t *buf_ptr; 15912 wmi_roam_chan_list_fixed_param *chan_list_fp; 15913 uint32_t *roam_chan_list_array; 15914 15915 if (chan_count == 0) { 15916 WMI_LOGD("%s : invalid number of channels %d", __func__, 15917 chan_count); 15918 return QDF_STATUS_E_EMPTY; 15919 } 15920 /* Channel list is a table of 2 TLV's */ 15921 list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); 15922 len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; 15923 buf = wmi_buf_alloc(wmi_handle, len); 15924 if (!buf) { 15925 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15926 return QDF_STATUS_E_NOMEM; 15927 } 15928 15929 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15930 chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; 15931 WMITLV_SET_HDR(&chan_list_fp->tlv_header, 15932 WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, 15933 WMITLV_GET_STRUCT_TLVLEN 15934 (wmi_roam_chan_list_fixed_param)); 15935 chan_list_fp->vdev_id = vdev_id; 15936 chan_list_fp->num_chan = chan_count; 15937 if (chan_count > 0 && list_type == WMI_CHANNEL_LIST_STATIC) { 15938 /* external app is controlling channel list */ 15939 chan_list_fp->chan_list_type = 15940 WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; 15941 } else { 15942 /* umac supplied occupied channel list in LFR */ 15943 chan_list_fp->chan_list_type = 15944 WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; 15945 } 15946 15947 buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); 15948 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15949 (chan_list_fp->num_chan * sizeof(uint32_t))); 15950 roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 15951 WMI_LOGD("%s: %d channels = ", __func__, chan_list_fp->num_chan); 15952 for (i = 0; ((i < chan_list_fp->num_chan) && 15953 (i < WMI_ROAM_MAX_CHANNELS)); i++) { 15954 roam_chan_list_array[i] = chan_list[i]; 15955 WMI_LOGD("%d,", roam_chan_list_array[i]); 15956 } 15957 15958 wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0); 15959 status = wmi_unified_cmd_send(wmi_handle, buf, 15960 len, WMI_ROAM_CHAN_LIST); 15961 if (QDF_IS_STATUS_ERROR(status)) { 15962 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", 15963 status); 15964 goto error; 15965 } 15966 15967 WMI_LOGD("%s: WMI --> WMI_ROAM_SCAN_CHAN_LIST", __func__); 15968 return QDF_STATUS_SUCCESS; 15969 error: 15970 wmi_buf_free(buf); 15971 15972 return status; 15973 } 15974 15975 /** 15976 * send_per_roam_config_cmd_tlv() - set per roaming config to FW 15977 * @wmi_handle: wmi handle 15978 * @req_buf: per roam config buffer 15979 * 15980 * Return: QDF status 15981 */ 15982 static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle, 15983 struct wmi_per_roam_config_req *req_buf) 15984 { 15985 wmi_buf_t buf = NULL; 15986 QDF_STATUS status; 15987 int len; 15988 uint8_t *buf_ptr; 15989 wmi_roam_per_config_fixed_param *wmi_per_config; 15990 15991 len = sizeof(wmi_roam_per_config_fixed_param); 15992 buf = wmi_buf_alloc(wmi_handle, len); 15993 if (!buf) { 15994 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 15995 return QDF_STATUS_E_NOMEM; 15996 } 15997 15998 buf_ptr = (uint8_t *) wmi_buf_data(buf); 15999 wmi_per_config = 16000 (wmi_roam_per_config_fixed_param *) buf_ptr; 16001 WMITLV_SET_HDR(&wmi_per_config->tlv_header, 16002 WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param, 16003 WMITLV_GET_STRUCT_TLVLEN 16004 (wmi_roam_per_config_fixed_param)); 16005 16006 /* fill in per roam config values */ 16007 wmi_per_config->vdev_id = req_buf->vdev_id; 16008 16009 wmi_per_config->enable = req_buf->per_config.enable; 16010 wmi_per_config->high_rate_thresh = 16011 (req_buf->per_config.tx_high_rate_thresh << 16) | 16012 (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff); 16013 wmi_per_config->low_rate_thresh = 16014 (req_buf->per_config.tx_low_rate_thresh << 16) | 16015 (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff); 16016 wmi_per_config->pkt_err_rate_thresh_pct = 16017 (req_buf->per_config.tx_rate_thresh_percnt << 16) | 16018 (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff); 16019 wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time; 16020 wmi_per_config->pkt_err_rate_mon_time = 16021 (req_buf->per_config.tx_per_mon_time << 16) | 16022 (req_buf->per_config.rx_per_mon_time & 0x0000ffff); 16023 wmi_per_config->min_candidate_rssi = 16024 req_buf->per_config.min_candidate_rssi; 16025 16026 /* Send per roam config parameters */ 16027 wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0); 16028 status = wmi_unified_cmd_send(wmi_handle, buf, 16029 len, WMI_ROAM_PER_CONFIG_CMDID); 16030 if (QDF_IS_STATUS_ERROR(status)) { 16031 WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d", 16032 status); 16033 wmi_buf_free(buf); 16034 return status; 16035 } 16036 WMI_LOGD(FL("per roam enable=%d, vdev=%d"), 16037 req_buf->per_config.enable, req_buf->vdev_id); 16038 16039 return QDF_STATUS_SUCCESS; 16040 } 16041 16042 /** 16043 * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th 16044 * @wmi_handle: wmi handle 16045 * @rssi_change_thresh: RSSI Change threshold 16046 * @bcn_rssi_weight: beacon RSSI weight 16047 * @vdev_id: vdev id 16048 * 16049 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw. 16050 * 16051 * Return: CDF status 16052 */ 16053 static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle, 16054 uint32_t vdev_id, 16055 int32_t rssi_change_thresh, 16056 uint32_t bcn_rssi_weight, 16057 uint32_t hirssi_delay_btw_scans) 16058 { 16059 wmi_buf_t buf = NULL; 16060 QDF_STATUS status; 16061 int len; 16062 uint8_t *buf_ptr; 16063 wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; 16064 16065 /* Send rssi change parameters */ 16066 len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); 16067 buf = wmi_buf_alloc(wmi_handle, len); 16068 if (!buf) { 16069 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16070 return QDF_STATUS_E_NOMEM; 16071 } 16072 16073 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16074 rssi_change_fp = 16075 (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; 16076 WMITLV_SET_HDR(&rssi_change_fp->tlv_header, 16077 WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, 16078 WMITLV_GET_STRUCT_TLVLEN 16079 (wmi_roam_scan_rssi_change_threshold_fixed_param)); 16080 /* fill in rssi change threshold (hysteresis) values */ 16081 rssi_change_fp->vdev_id = vdev_id; 16082 rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; 16083 rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; 16084 rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans; 16085 16086 wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0); 16087 status = wmi_unified_cmd_send(wmi_handle, buf, 16088 len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); 16089 if (QDF_IS_STATUS_ERROR(status)) { 16090 WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", 16091 status); 16092 goto error; 16093 } 16094 16095 WMI_LOGD(FL("roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d"), 16096 rssi_change_thresh, bcn_rssi_weight); 16097 WMI_LOGD(FL("hirssi_delay_btw_scans=%d"), hirssi_delay_btw_scans); 16098 return QDF_STATUS_SUCCESS; 16099 error: 16100 wmi_buf_free(buf); 16101 16102 return status; 16103 } 16104 16105 /** 16106 * send_power_dbg_cmd_tlv() - send power debug commands 16107 * @wmi_handle: wmi handle 16108 * @param: wmi power debug parameter 16109 * 16110 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 16111 * 16112 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16113 */ 16114 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 16115 struct wmi_power_dbg_params *param) 16116 { 16117 wmi_buf_t buf = NULL; 16118 QDF_STATUS status; 16119 int len, args_tlv_len; 16120 uint8_t *buf_ptr; 16121 uint8_t i; 16122 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 16123 uint32_t *cmd_args; 16124 16125 /* Prepare and send power debug cmd parameters */ 16126 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 16127 len = sizeof(*cmd) + args_tlv_len; 16128 buf = wmi_buf_alloc(wmi_handle, len); 16129 if (!buf) { 16130 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16131 return QDF_STATUS_E_NOMEM; 16132 } 16133 16134 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16135 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 16136 WMITLV_SET_HDR(&cmd->tlv_header, 16137 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 16138 WMITLV_GET_STRUCT_TLVLEN 16139 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 16140 16141 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16142 param->pdev_id); 16143 cmd->module_id = param->module_id; 16144 cmd->num_args = param->num_args; 16145 buf_ptr += sizeof(*cmd); 16146 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16147 (param->num_args * sizeof(uint32_t))); 16148 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 16149 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 16150 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 16151 cmd_args[i] = param->args[i]; 16152 WMI_LOGI("%d,", param->args[i]); 16153 } 16154 16155 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 16156 status = wmi_unified_cmd_send(wmi_handle, buf, 16157 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 16158 if (QDF_IS_STATUS_ERROR(status)) { 16159 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 16160 status); 16161 goto error; 16162 } 16163 16164 return QDF_STATUS_SUCCESS; 16165 error: 16166 wmi_buf_free(buf); 16167 16168 return status; 16169 } 16170 16171 /** 16172 * send_multiple_vdev_restart_req_cmd_tlv() - send multiple vdev restart req 16173 * @wmi_handle: wmi handle 16174 * @param: wmi multiple vdev restart req param 16175 * 16176 * Send WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID parameters to fw. 16177 * 16178 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16179 */ 16180 static QDF_STATUS send_multiple_vdev_restart_req_cmd_tlv( 16181 wmi_unified_t wmi_handle, 16182 struct multiple_vdev_restart_params *param) 16183 { 16184 wmi_buf_t buf; 16185 QDF_STATUS qdf_status; 16186 wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *cmd; 16187 int i; 16188 uint8_t *buf_ptr; 16189 uint32_t *vdev_ids; 16190 wmi_channel *chan_info; 16191 struct channel_param *tchan_info; 16192 uint16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 16193 16194 len += sizeof(wmi_channel); 16195 if (param->num_vdevs) 16196 len += sizeof(uint32_t) * param->num_vdevs; 16197 16198 buf = wmi_buf_alloc(wmi_handle, len); 16199 if (!buf) { 16200 WMI_LOGE("Failed to allocate memory\n"); 16201 qdf_status = QDF_STATUS_E_NOMEM; 16202 goto end; 16203 } 16204 16205 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16206 cmd = (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param *) 16207 buf_ptr; 16208 16209 WMITLV_SET_HDR(&cmd->tlv_header, 16210 WMITLV_TAG_STRUC_wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param, 16211 WMITLV_GET_STRUCT_TLVLEN 16212 (wmi_pdev_multiple_vdev_restart_request_cmd_fixed_param)); 16213 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16214 param->pdev_id); 16215 cmd->requestor_id = param->requestor_id; 16216 cmd->disable_hw_ack = param->disable_hw_ack; 16217 cmd->cac_duration_ms = param->cac_duration_ms; 16218 cmd->num_vdevs = param->num_vdevs; 16219 16220 WMI_LOGI("%s:cmd->pdev_id: %d ,cmd->requestor_id: %d ," 16221 "cmd->disable_hw_ack: %d , cmd->cac_duration_ms:%d ," 16222 " cmd->num_vdevs: %d ", 16223 __func__, cmd->pdev_id, cmd->requestor_id, 16224 cmd->disable_hw_ack, cmd->cac_duration_ms, cmd->num_vdevs); 16225 buf_ptr += sizeof(*cmd); 16226 16227 WMITLV_SET_HDR(buf_ptr, 16228 WMITLV_TAG_ARRAY_UINT32, 16229 sizeof(uint32_t) * param->num_vdevs); 16230 vdev_ids = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 16231 for (i = 0; i < param->num_vdevs; i++) { 16232 vdev_ids[i] = param->vdev_ids[i]; 16233 } 16234 16235 buf_ptr += (sizeof(uint32_t) * param->num_vdevs) + WMI_TLV_HDR_SIZE; 16236 16237 WMITLV_SET_HDR(buf_ptr, 16238 WMITLV_TAG_STRUC_wmi_channel, 16239 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16240 chan_info = (wmi_channel *)buf_ptr; 16241 tchan_info = &(param->ch_param); 16242 chan_info->mhz = tchan_info->mhz; 16243 chan_info->band_center_freq1 = tchan_info->cfreq1; 16244 chan_info->band_center_freq2 = tchan_info->cfreq2; 16245 if (tchan_info->is_chan_passive) 16246 WMI_SET_CHANNEL_FLAG(chan_info, 16247 WMI_CHAN_FLAG_PASSIVE); 16248 if (tchan_info->dfs_set) 16249 WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); 16250 16251 if (tchan_info->allow_vht) 16252 WMI_SET_CHANNEL_FLAG(chan_info, 16253 WMI_CHAN_FLAG_ALLOW_VHT); 16254 else if (tchan_info->allow_ht) 16255 WMI_SET_CHANNEL_FLAG(chan_info, 16256 WMI_CHAN_FLAG_ALLOW_HT); 16257 WMI_SET_CHANNEL_MODE(chan_info, tchan_info->phy_mode); 16258 WMI_SET_CHANNEL_MIN_POWER(chan_info, tchan_info->minpower); 16259 WMI_SET_CHANNEL_MAX_POWER(chan_info, tchan_info->maxpower); 16260 WMI_SET_CHANNEL_REG_POWER(chan_info, tchan_info->maxregpower); 16261 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, tchan_info->antennamax); 16262 WMI_SET_CHANNEL_REG_CLASSID(chan_info, tchan_info->reg_class_id); 16263 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, tchan_info->maxregpower); 16264 16265 WMI_LOGI("%s:tchan_info->is_chan_passive: %d ," 16266 "tchan_info->dfs_set : %d ,tchan_info->allow_vht:%d ," 16267 "tchan_info->allow_ht: %d ,tchan_info->antennamax: %d ," 16268 "tchan_info->phy_mode: %d ,tchan_info->minpower: %d," 16269 "tchan_info->maxpower: %d ,tchan_info->maxregpower: %d ," 16270 "tchan_info->reg_class_id: %d ," 16271 "tchan_info->maxregpower : %d ", __func__, 16272 tchan_info->is_chan_passive, tchan_info->dfs_set, 16273 tchan_info->allow_vht, tchan_info->allow_ht, 16274 tchan_info->antennamax, tchan_info->phy_mode, 16275 tchan_info->minpower, tchan_info->maxpower, 16276 tchan_info->maxregpower, tchan_info->reg_class_id, 16277 tchan_info->maxregpower); 16278 16279 wmi_mtrace(WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID, NO_SESSION, 0); 16280 qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len, 16281 WMI_PDEV_MULTIPLE_VDEV_RESTART_REQUEST_CMDID); 16282 16283 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16284 WMI_LOGE("%s: Failed to send\n", __func__); 16285 wmi_buf_free(buf); 16286 } 16287 16288 end: 16289 return qdf_status; 16290 } 16291 16292 /** 16293 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 16294 * @wmi_handle: wmi handle 16295 * @pdev_id: pdev id 16296 * 16297 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 16298 * 16299 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16300 */ 16301 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 16302 uint32_t pdev_id) 16303 { 16304 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 16305 wmi_buf_t buf; 16306 uint16_t len; 16307 QDF_STATUS ret; 16308 16309 len = sizeof(*cmd); 16310 buf = wmi_buf_alloc(wmi_handle, len); 16311 16312 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16313 16314 if (!buf) { 16315 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16316 return QDF_STATUS_E_NOMEM; 16317 } 16318 16319 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 16320 wmi_buf_data(buf); 16321 16322 WMITLV_SET_HDR(&cmd->tlv_header, 16323 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 16324 WMITLV_GET_STRUCT_TLVLEN( 16325 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 16326 16327 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16328 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 16329 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16330 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 16331 if (QDF_IS_STATUS_ERROR(ret)) { 16332 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16333 __func__, ret, pdev_id); 16334 wmi_buf_free(buf); 16335 return QDF_STATUS_E_FAILURE; 16336 } 16337 16338 return QDF_STATUS_SUCCESS; 16339 } 16340 16341 /** 16342 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 16343 * @wmi_handle: wmi handle 16344 * @pdev_id: pdev id 16345 * 16346 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 16347 * 16348 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 16349 */ 16350 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 16351 uint32_t pdev_id) 16352 { 16353 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 16354 wmi_buf_t buf; 16355 uint16_t len; 16356 QDF_STATUS ret; 16357 16358 len = sizeof(*cmd); 16359 buf = wmi_buf_alloc(wmi_handle, len); 16360 16361 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 16362 16363 if (!buf) { 16364 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16365 return QDF_STATUS_E_NOMEM; 16366 } 16367 16368 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 16369 wmi_buf_data(buf); 16370 16371 WMITLV_SET_HDR(&cmd->tlv_header, 16372 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 16373 WMITLV_GET_STRUCT_TLVLEN( 16374 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 16375 16376 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 16377 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 16378 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16379 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 16380 if (QDF_IS_STATUS_ERROR(ret)) { 16381 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 16382 __func__, ret, pdev_id); 16383 wmi_buf_free(buf); 16384 return QDF_STATUS_E_FAILURE; 16385 } 16386 16387 return QDF_STATUS_SUCCESS; 16388 } 16389 16390 /** 16391 * init_cmd_send_tlv() - send initialization cmd to fw 16392 * @wmi_handle: wmi handle 16393 * @param param: pointer to wmi init param 16394 * 16395 * Return: QDF_STATUS_SUCCESS for success or error code 16396 */ 16397 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 16398 struct wmi_init_cmd_param *param) 16399 { 16400 wmi_buf_t buf; 16401 wmi_init_cmd_fixed_param *cmd; 16402 uint8_t *buf_ptr; 16403 wmi_resource_config *resource_cfg; 16404 wlan_host_memory_chunk *host_mem_chunks; 16405 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 16406 uint16_t idx; 16407 int len; 16408 QDF_STATUS ret; 16409 16410 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 16411 WMI_TLV_HDR_SIZE; 16412 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 16413 16414 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 16415 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 16416 WMI_TLV_HDR_SIZE + 16417 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 16418 16419 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 16420 if (!buf) { 16421 qdf_print("%s: wmi_buf_alloc failed", __func__); 16422 return QDF_STATUS_E_FAILURE; 16423 } 16424 16425 buf_ptr = (uint8_t *) wmi_buf_data(buf); 16426 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 16427 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 16428 16429 host_mem_chunks = (wlan_host_memory_chunk *) 16430 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 16431 + WMI_TLV_HDR_SIZE); 16432 16433 WMITLV_SET_HDR(&cmd->tlv_header, 16434 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 16435 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 16436 16437 wmi_copy_resource_config(resource_cfg, param->res_cfg); 16438 WMITLV_SET_HDR(&resource_cfg->tlv_header, 16439 WMITLV_TAG_STRUC_wmi_resource_config, 16440 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 16441 16442 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 16443 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 16444 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 16445 WMITLV_GET_STRUCT_TLVLEN 16446 (wlan_host_memory_chunk)); 16447 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 16448 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 16449 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 16450 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 16451 "chunk %d len %d requested ,ptr 0x%x ", 16452 idx, host_mem_chunks[idx].size, 16453 host_mem_chunks[idx].ptr); 16454 } 16455 cmd->num_host_mem_chunks = param->num_mem_chunks; 16456 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 16457 16458 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 16459 WMITLV_TAG_ARRAY_STRUC, 16460 (sizeof(wlan_host_memory_chunk) * 16461 param->num_mem_chunks)); 16462 16463 /* Fill hw mode id config */ 16464 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 16465 16466 /* Fill fw_abi_vers */ 16467 copy_fw_abi_version_tlv(wmi_handle, cmd); 16468 16469 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 16470 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 16471 if (QDF_IS_STATUS_ERROR(ret)) { 16472 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 16473 ret); 16474 wmi_buf_free(buf); 16475 } 16476 16477 return ret; 16478 16479 } 16480 16481 /** 16482 * send_addba_send_cmd_tlv() - send addba send command to fw 16483 * @wmi_handle: wmi handle 16484 * @param: pointer to delba send params 16485 * @macaddr: peer mac address 16486 * 16487 * Send WMI_ADDBA_SEND_CMDID command to firmware 16488 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16489 */ 16490 static QDF_STATUS 16491 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 16492 uint8_t macaddr[IEEE80211_ADDR_LEN], 16493 struct addba_send_params *param) 16494 { 16495 wmi_addba_send_cmd_fixed_param *cmd; 16496 wmi_buf_t buf; 16497 uint16_t len; 16498 QDF_STATUS ret; 16499 16500 len = sizeof(*cmd); 16501 16502 buf = wmi_buf_alloc(wmi_handle, len); 16503 if (!buf) { 16504 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16505 return QDF_STATUS_E_NOMEM; 16506 } 16507 16508 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 16509 16510 WMITLV_SET_HDR(&cmd->tlv_header, 16511 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 16512 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 16513 16514 cmd->vdev_id = param->vdev_id; 16515 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16516 cmd->tid = param->tidno; 16517 cmd->buffersize = param->buffersize; 16518 16519 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 16520 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 16521 if (QDF_IS_STATUS_ERROR(ret)) { 16522 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16523 wmi_buf_free(buf); 16524 return QDF_STATUS_E_FAILURE; 16525 } 16526 16527 return QDF_STATUS_SUCCESS; 16528 } 16529 16530 /** 16531 * send_delba_send_cmd_tlv() - send delba send command to fw 16532 * @wmi_handle: wmi handle 16533 * @param: pointer to delba send params 16534 * @macaddr: peer mac address 16535 * 16536 * Send WMI_DELBA_SEND_CMDID command to firmware 16537 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 16538 */ 16539 static QDF_STATUS 16540 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 16541 uint8_t macaddr[IEEE80211_ADDR_LEN], 16542 struct delba_send_params *param) 16543 { 16544 wmi_delba_send_cmd_fixed_param *cmd; 16545 wmi_buf_t buf; 16546 uint16_t len; 16547 QDF_STATUS ret; 16548 16549 len = sizeof(*cmd); 16550 16551 buf = wmi_buf_alloc(wmi_handle, len); 16552 if (!buf) { 16553 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 16554 return QDF_STATUS_E_NOMEM; 16555 } 16556 16557 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 16558 16559 WMITLV_SET_HDR(&cmd->tlv_header, 16560 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 16561 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 16562 16563 cmd->vdev_id = param->vdev_id; 16564 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16565 cmd->tid = param->tidno; 16566 cmd->initiator = param->initiator; 16567 cmd->reasoncode = param->reasoncode; 16568 16569 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 16570 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 16571 if (QDF_IS_STATUS_ERROR(ret)) { 16572 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16573 wmi_buf_free(buf); 16574 return QDF_STATUS_E_FAILURE; 16575 } 16576 16577 return QDF_STATUS_SUCCESS; 16578 } 16579 16580 /** 16581 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 16582 * to fw 16583 * @wmi_handle: wmi handle 16584 * @param: pointer to addba clearresp params 16585 * @macaddr: peer mac address 16586 * Return: 0 for success or error code 16587 */ 16588 static QDF_STATUS 16589 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 16590 uint8_t macaddr[IEEE80211_ADDR_LEN], 16591 struct addba_clearresponse_params *param) 16592 { 16593 wmi_addba_clear_resp_cmd_fixed_param *cmd; 16594 wmi_buf_t buf; 16595 uint16_t len; 16596 QDF_STATUS ret; 16597 16598 len = sizeof(*cmd); 16599 16600 buf = wmi_buf_alloc(wmi_handle, len); 16601 if (!buf) { 16602 WMI_LOGE("%s: wmi_buf_alloc failed\n", __func__); 16603 return QDF_STATUS_E_FAILURE; 16604 } 16605 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 16606 16607 WMITLV_SET_HDR(&cmd->tlv_header, 16608 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 16609 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 16610 16611 cmd->vdev_id = param->vdev_id; 16612 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 16613 16614 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 16615 ret = wmi_unified_cmd_send(wmi_handle, 16616 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 16617 if (QDF_IS_STATUS_ERROR(ret)) { 16618 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 16619 wmi_buf_free(buf); 16620 return QDF_STATUS_E_FAILURE; 16621 } 16622 16623 return QDF_STATUS_SUCCESS; 16624 } 16625 16626 /** 16627 * send_bcn_offload_control_cmd_tlv - send beacon ofload control cmd to fw 16628 * @wmi_handle: wmi handle 16629 * @bcn_ctrl_param: pointer to bcn_offload_control param 16630 * 16631 * Return: QDF_STATUS_SUCCESS for success or error code 16632 */ 16633 static 16634 QDF_STATUS send_bcn_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 16635 struct bcn_offload_control *bcn_ctrl_param) 16636 { 16637 wmi_buf_t buf; 16638 wmi_bcn_offload_ctrl_cmd_fixed_param *cmd; 16639 QDF_STATUS ret; 16640 uint32_t len; 16641 16642 len = sizeof(*cmd); 16643 16644 buf = wmi_buf_alloc(wmi_handle, len); 16645 if (!buf) { 16646 qdf_print("%s: wmi_buf_alloc failed", __func__); 16647 return QDF_STATUS_E_FAILURE; 16648 } 16649 16650 cmd = (wmi_bcn_offload_ctrl_cmd_fixed_param *) wmi_buf_data(buf); 16651 WMITLV_SET_HDR(&cmd->tlv_header, 16652 WMITLV_TAG_STRUC_wmi_bcn_offload_ctrl_cmd_fixed_param, 16653 WMITLV_GET_STRUCT_TLVLEN 16654 (wmi_bcn_offload_ctrl_cmd_fixed_param)); 16655 cmd->vdev_id = bcn_ctrl_param->vdev_id; 16656 switch (bcn_ctrl_param->bcn_ctrl_op) { 16657 case BCN_OFFLD_CTRL_TX_DISABLE: 16658 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_DISABLE; 16659 break; 16660 case BCN_OFFLD_CTRL_TX_ENABLE: 16661 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_TX_ENABLE; 16662 break; 16663 case BCN_OFFLD_CTRL_SWBA_DISABLE: 16664 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_DISABLE; 16665 break; 16666 case BCN_OFFLD_CTRL_SWBA_ENABLE: 16667 cmd->bcn_ctrl_op = WMI_BEACON_CTRL_SWBA_EVENT_ENABLE; 16668 break; 16669 default: 16670 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID unknown CTRL Operation %d", 16671 bcn_ctrl_param->bcn_ctrl_op); 16672 wmi_buf_free(buf); 16673 return QDF_STATUS_E_FAILURE; 16674 break; 16675 } 16676 wmi_mtrace(WMI_BCN_OFFLOAD_CTRL_CMDID, cmd->vdev_id, 0); 16677 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16678 WMI_BCN_OFFLOAD_CTRL_CMDID); 16679 16680 if (QDF_IS_STATUS_ERROR(ret)) { 16681 WMI_LOGE("WMI_BCN_OFFLOAD_CTRL_CMDID send returned Error %d", 16682 ret); 16683 wmi_buf_free(buf); 16684 } 16685 16686 return ret; 16687 } 16688 16689 #ifdef OBSS_PD 16690 /** 16691 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 16692 * @wmi_handle: wmi handle 16693 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 16694 * 16695 * Return: QDF_STATUS_SUCCESS for success or error code 16696 */ 16697 static 16698 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 16699 struct wmi_host_obss_spatial_reuse_set_param 16700 *obss_spatial_reuse_param) 16701 { 16702 wmi_buf_t buf; 16703 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 16704 QDF_STATUS ret; 16705 uint32_t len; 16706 16707 len = sizeof(*cmd); 16708 16709 buf = wmi_buf_alloc(wmi_handle, len); 16710 if (!buf) { 16711 qdf_print("%s: wmi_buf_alloc failed\n", __func__); 16712 return QDF_STATUS_E_FAILURE; 16713 } 16714 16715 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 16716 WMITLV_SET_HDR(&cmd->tlv_header, 16717 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 16718 WMITLV_GET_STRUCT_TLVLEN 16719 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 16720 16721 cmd->enable = obss_spatial_reuse_param->enable; 16722 cmd->obss_min = obss_spatial_reuse_param->obss_min; 16723 cmd->obss_max = obss_spatial_reuse_param->obss_max; 16724 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 16725 16726 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16727 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 16728 16729 if (QDF_IS_STATUS_ERROR(ret)) { 16730 WMI_LOGE( 16731 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 16732 ret); 16733 wmi_buf_free(buf); 16734 } 16735 16736 return ret; 16737 } 16738 #endif 16739 16740 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 16741 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle, 16742 struct nan_datapath_initiator_req *ndp_req) 16743 { 16744 uint16_t len; 16745 wmi_buf_t buf; 16746 uint8_t *tlv_ptr; 16747 QDF_STATUS status; 16748 wmi_channel *ch_tlv; 16749 wmi_ndp_initiator_req_fixed_param *cmd; 16750 uint32_t passphrase_len, service_name_len; 16751 uint32_t ndp_cfg_len, ndp_app_info_len, pmk_len; 16752 wmi_ndp_transport_ip_param *tcp_ip_param; 16753 16754 /* 16755 * WMI command expects 4 byte alligned len: 16756 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16757 */ 16758 ndp_cfg_len = qdf_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); 16759 ndp_app_info_len = qdf_roundup(ndp_req->ndp_info.ndp_app_info_len, 4); 16760 pmk_len = qdf_roundup(ndp_req->pmk.pmk_len, 4); 16761 passphrase_len = qdf_roundup(ndp_req->passphrase.passphrase_len, 4); 16762 service_name_len = 16763 qdf_roundup(ndp_req->service_name.service_name_len, 4); 16764 /* allocated memory for fixed params as well as variable size data */ 16765 len = sizeof(*cmd) + sizeof(*ch_tlv) + (5 * WMI_TLV_HDR_SIZE) 16766 + ndp_cfg_len + ndp_app_info_len + pmk_len 16767 + passphrase_len + service_name_len; 16768 16769 if (ndp_req->is_ipv6_addr_present) 16770 len += sizeof(*tcp_ip_param); 16771 16772 buf = wmi_buf_alloc(wmi_handle, len); 16773 if (!buf) { 16774 WMI_LOGE("wmi_buf_alloc failed"); 16775 return QDF_STATUS_E_NOMEM; 16776 } 16777 16778 cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); 16779 WMITLV_SET_HDR(&cmd->tlv_header, 16780 WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, 16781 WMITLV_GET_STRUCT_TLVLEN( 16782 wmi_ndp_initiator_req_fixed_param)); 16783 cmd->vdev_id = wlan_vdev_get_id(ndp_req->vdev); 16784 cmd->transaction_id = ndp_req->transaction_id; 16785 cmd->service_instance_id = ndp_req->service_instance_id; 16786 WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, 16787 &cmd->peer_discovery_mac_addr); 16788 16789 cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; 16790 cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; 16791 cmd->ndp_channel_cfg = ndp_req->channel_cfg; 16792 cmd->nan_pmk_len = ndp_req->pmk.pmk_len; 16793 cmd->nan_csid = ndp_req->ncs_sk_type; 16794 cmd->nan_passphrase_len = ndp_req->passphrase.passphrase_len; 16795 cmd->nan_servicename_len = ndp_req->service_name.service_name_len; 16796 16797 ch_tlv = (wmi_channel *)&cmd[1]; 16798 WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, 16799 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 16800 ch_tlv->mhz = ndp_req->channel; 16801 tlv_ptr = (uint8_t *)&ch_tlv[1]; 16802 16803 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16804 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16805 ndp_req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16806 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16807 16808 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16809 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16810 ndp_req->ndp_info.ndp_app_info, cmd->ndp_app_info_len); 16811 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16812 16813 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16814 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->pmk.pmk, 16815 cmd->nan_pmk_len); 16816 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16817 16818 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16819 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], ndp_req->passphrase.passphrase, 16820 cmd->nan_passphrase_len); 16821 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16822 16823 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16824 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16825 ndp_req->service_name.service_name, 16826 cmd->nan_servicename_len); 16827 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16828 16829 if (ndp_req->is_ipv6_addr_present) { 16830 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16831 WMITLV_SET_HDR(tcp_ip_param, 16832 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16833 WMITLV_GET_STRUCT_TLVLEN( 16834 wmi_ndp_transport_ip_param)); 16835 tcp_ip_param->ipv6_addr_present = true; 16836 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16837 ndp_req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16838 } 16839 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16840 ndp_req->is_ipv6_addr_present, ndp_req->ipv6_addr); 16841 16842 WMI_LOGD("vdev_id = %d, transaction_id: %d, service_instance_id: %d, ch: %d, ch_cfg: %d, csid: %d", 16843 cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, 16844 ch_tlv->mhz, cmd->ndp_channel_cfg, cmd->nan_csid); 16845 WMI_LOGD("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", 16846 cmd->peer_discovery_mac_addr.mac_addr31to0, 16847 cmd->peer_discovery_mac_addr.mac_addr47to32); 16848 16849 WMI_LOGD("ndp_config len: %d", cmd->ndp_cfg_len); 16850 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16851 ndp_req->ndp_config.ndp_cfg, 16852 ndp_req->ndp_config.ndp_cfg_len); 16853 16854 WMI_LOGD("ndp_app_info len: %d", cmd->ndp_app_info_len); 16855 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16856 ndp_req->ndp_info.ndp_app_info, 16857 ndp_req->ndp_info.ndp_app_info_len); 16858 16859 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 16860 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16861 ndp_req->pmk.pmk, cmd->nan_pmk_len); 16862 16863 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 16864 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16865 ndp_req->passphrase.passphrase, 16866 cmd->nan_passphrase_len); 16867 16868 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 16869 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 16870 ndp_req->service_name.service_name, 16871 cmd->nan_servicename_len); 16872 16873 WMI_LOGD("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)", 16874 WMI_NDP_INITIATOR_REQ_CMDID); 16875 16876 wmi_mtrace(WMI_NDP_INITIATOR_REQ_CMDID, cmd->vdev_id, 0); 16877 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16878 WMI_NDP_INITIATOR_REQ_CMDID); 16879 if (QDF_IS_STATUS_ERROR(status)) { 16880 WMI_LOGE("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d", status); 16881 wmi_buf_free(buf); 16882 } 16883 16884 return status; 16885 } 16886 16887 static QDF_STATUS nan_ndp_responder_req_tlv(wmi_unified_t wmi_handle, 16888 struct nan_datapath_responder_req *req) 16889 { 16890 uint16_t len; 16891 wmi_buf_t buf; 16892 uint8_t *tlv_ptr; 16893 QDF_STATUS status; 16894 wmi_ndp_responder_req_fixed_param *cmd; 16895 wmi_ndp_transport_ip_param *tcp_ip_param; 16896 uint32_t passphrase_len, service_name_len; 16897 uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len, pmk_len; 16898 16899 vdev_id = wlan_vdev_get_id(req->vdev); 16900 WMI_LOGD("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d", 16901 vdev_id, req->transaction_id, 16902 req->ndp_rsp, 16903 req->ndp_instance_id, 16904 req->ndp_info.ndp_app_info_len); 16905 16906 /* 16907 * WMI command expects 4 byte alligned len: 16908 * round up ndp_cfg_len and ndp_app_info_len to 4 bytes 16909 */ 16910 ndp_cfg_len = qdf_roundup(req->ndp_config.ndp_cfg_len, 4); 16911 ndp_app_info_len = qdf_roundup(req->ndp_info.ndp_app_info_len, 4); 16912 pmk_len = qdf_roundup(req->pmk.pmk_len, 4); 16913 passphrase_len = qdf_roundup(req->passphrase.passphrase_len, 4); 16914 service_name_len = 16915 qdf_roundup(req->service_name.service_name_len, 4); 16916 16917 /* allocated memory for fixed params as well as variable size data */ 16918 len = sizeof(*cmd) + 5*WMI_TLV_HDR_SIZE + ndp_cfg_len + ndp_app_info_len 16919 + pmk_len + passphrase_len + service_name_len; 16920 16921 if (req->is_ipv6_addr_present || req->is_port_present || 16922 req->is_protocol_present) 16923 len += sizeof(*tcp_ip_param); 16924 16925 buf = wmi_buf_alloc(wmi_handle, len); 16926 if (!buf) { 16927 WMI_LOGE("wmi_buf_alloc failed"); 16928 return QDF_STATUS_E_NOMEM; 16929 } 16930 cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); 16931 WMITLV_SET_HDR(&cmd->tlv_header, 16932 WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, 16933 WMITLV_GET_STRUCT_TLVLEN( 16934 wmi_ndp_responder_req_fixed_param)); 16935 cmd->vdev_id = vdev_id; 16936 cmd->transaction_id = req->transaction_id; 16937 cmd->ndp_instance_id = req->ndp_instance_id; 16938 cmd->rsp_code = req->ndp_rsp; 16939 cmd->ndp_cfg_len = req->ndp_config.ndp_cfg_len; 16940 cmd->ndp_app_info_len = req->ndp_info.ndp_app_info_len; 16941 cmd->nan_pmk_len = req->pmk.pmk_len; 16942 cmd->nan_csid = req->ncs_sk_type; 16943 cmd->nan_passphrase_len = req->passphrase.passphrase_len; 16944 cmd->nan_servicename_len = req->service_name.service_name_len; 16945 16946 tlv_ptr = (uint8_t *)&cmd[1]; 16947 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); 16948 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16949 req->ndp_config.ndp_cfg, cmd->ndp_cfg_len); 16950 16951 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_cfg_len; 16952 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); 16953 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16954 req->ndp_info.ndp_app_info, 16955 req->ndp_info.ndp_app_info_len); 16956 16957 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + ndp_app_info_len; 16958 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, pmk_len); 16959 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], req->pmk.pmk, 16960 cmd->nan_pmk_len); 16961 16962 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + pmk_len; 16963 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, passphrase_len); 16964 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16965 req->passphrase.passphrase, 16966 cmd->nan_passphrase_len); 16967 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + passphrase_len; 16968 16969 WMITLV_SET_HDR(tlv_ptr, WMITLV_TAG_ARRAY_BYTE, service_name_len); 16970 qdf_mem_copy(&tlv_ptr[WMI_TLV_HDR_SIZE], 16971 req->service_name.service_name, 16972 cmd->nan_servicename_len); 16973 16974 tlv_ptr = tlv_ptr + WMI_TLV_HDR_SIZE + service_name_len; 16975 16976 if (req->is_ipv6_addr_present || req->is_port_present || 16977 req->is_protocol_present) { 16978 tcp_ip_param = (wmi_ndp_transport_ip_param *)tlv_ptr; 16979 WMITLV_SET_HDR(tcp_ip_param, 16980 WMITLV_TAG_STRUC_wmi_ndp_transport_ip_param, 16981 WMITLV_GET_STRUCT_TLVLEN( 16982 wmi_ndp_transport_ip_param)); 16983 tcp_ip_param->ipv6_addr_present = req->is_ipv6_addr_present; 16984 qdf_mem_copy(tcp_ip_param->ipv6_intf_addr, 16985 req->ipv6_addr, WMI_NDP_IPV6_INTF_ADDR_LEN); 16986 16987 tcp_ip_param->trans_port_present = req->is_port_present; 16988 tcp_ip_param->transport_port = req->port; 16989 16990 tcp_ip_param->trans_proto_present = req->is_protocol_present; 16991 tcp_ip_param->transport_protocol = req->protocol; 16992 } 16993 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 16994 req->is_ipv6_addr_present, req->ipv6_addr); 16995 WMI_LOGD(FL("port: %d present: %d"), req->is_port_present, req->port); 16996 WMI_LOGD(FL("protocol: %d present: %d"), 16997 req->is_protocol_present, req->protocol); 16998 16999 WMI_LOGD("vdev_id = %d, transaction_id: %d, csid: %d", 17000 cmd->vdev_id, cmd->transaction_id, cmd->nan_csid); 17001 17002 WMI_LOGD("ndp_config len: %d", 17003 req->ndp_config.ndp_cfg_len); 17004 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17005 req->ndp_config.ndp_cfg, 17006 req->ndp_config.ndp_cfg_len); 17007 17008 WMI_LOGD("ndp_app_info len: %d", 17009 req->ndp_info.ndp_app_info_len); 17010 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17011 req->ndp_info.ndp_app_info, 17012 req->ndp_info.ndp_app_info_len); 17013 17014 WMI_LOGD("pmk len: %d", cmd->nan_pmk_len); 17015 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17016 req->pmk.pmk, cmd->nan_pmk_len); 17017 17018 WMI_LOGD("pass phrase len: %d", cmd->nan_passphrase_len); 17019 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17020 req->passphrase.passphrase, 17021 cmd->nan_passphrase_len); 17022 17023 WMI_LOGD("service name len: %d", cmd->nan_servicename_len); 17024 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17025 req->service_name.service_name, 17026 cmd->nan_servicename_len); 17027 17028 WMI_LOGD("sending WMI_NDP_RESPONDER_REQ_CMDID(0x%X)", 17029 WMI_NDP_RESPONDER_REQ_CMDID); 17030 wmi_mtrace(WMI_NDP_RESPONDER_REQ_CMDID, cmd->vdev_id, 0); 17031 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17032 WMI_NDP_RESPONDER_REQ_CMDID); 17033 if (QDF_IS_STATUS_ERROR(status)) { 17034 WMI_LOGE("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d", status); 17035 wmi_buf_free(buf); 17036 } 17037 return status; 17038 } 17039 17040 static QDF_STATUS nan_ndp_end_req_tlv(wmi_unified_t wmi_handle, 17041 struct nan_datapath_end_req *req) 17042 { 17043 uint16_t len; 17044 wmi_buf_t buf; 17045 QDF_STATUS status; 17046 uint32_t ndp_end_req_len, i; 17047 wmi_ndp_end_req *ndp_end_req_lst; 17048 wmi_ndp_end_req_fixed_param *cmd; 17049 17050 /* len of tlv following fixed param */ 17051 ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; 17052 /* above comes out to 4 byte alligned already, no need of padding */ 17053 len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; 17054 buf = wmi_buf_alloc(wmi_handle, len); 17055 if (!buf) { 17056 WMI_LOGE("Malloc failed"); 17057 return QDF_STATUS_E_NOMEM; 17058 } 17059 17060 cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); 17061 WMITLV_SET_HDR(&cmd->tlv_header, 17062 WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, 17063 WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); 17064 17065 cmd->transaction_id = req->transaction_id; 17066 17067 /* set tlv pointer to end of fixed param */ 17068 WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, 17069 ndp_end_req_len); 17070 17071 ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + 17072 WMI_TLV_HDR_SIZE); 17073 for (i = 0; i < req->num_ndp_instances; i++) { 17074 WMITLV_SET_HDR(&ndp_end_req_lst[i], 17075 WMITLV_TAG_ARRAY_FIXED_STRUC, 17076 (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); 17077 17078 ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; 17079 } 17080 17081 WMI_LOGD("Sending WMI_NDP_END_REQ_CMDID to FW"); 17082 wmi_mtrace(WMI_NDP_END_REQ_CMDID, NO_SESSION, 0); 17083 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17084 WMI_NDP_END_REQ_CMDID); 17085 if (QDF_IS_STATUS_ERROR(status)) { 17086 WMI_LOGE("WMI_NDP_END_REQ_CMDID failed, ret: %d", status); 17087 wmi_buf_free(buf); 17088 } 17089 17090 return status; 17091 } 17092 17093 static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle, 17094 uint8_t *data, struct nan_datapath_initiator_rsp *rsp) 17095 { 17096 WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; 17097 wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; 17098 17099 event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)data; 17100 fixed_params = event->fixed_param; 17101 17102 rsp->vdev = 17103 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17104 fixed_params->vdev_id, 17105 WLAN_NAN_ID); 17106 if (!rsp->vdev) { 17107 WMI_LOGE("vdev is null"); 17108 return QDF_STATUS_E_INVAL; 17109 } 17110 17111 rsp->transaction_id = fixed_params->transaction_id; 17112 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17113 rsp->status = fixed_params->rsp_status; 17114 rsp->reason = fixed_params->reason_code; 17115 17116 return QDF_STATUS_SUCCESS; 17117 } 17118 17119 static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle, 17120 uint8_t *data, struct nan_datapath_indication_event *rsp) 17121 { 17122 WMI_NDP_INDICATION_EVENTID_param_tlvs *event; 17123 wmi_ndp_indication_event_fixed_param *fixed_params; 17124 size_t total_array_len; 17125 17126 event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)data; 17127 fixed_params = 17128 (wmi_ndp_indication_event_fixed_param *)event->fixed_param; 17129 17130 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17131 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17132 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17133 return QDF_STATUS_E_INVAL; 17134 } 17135 17136 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17137 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17138 fixed_params->ndp_app_info_len, 17139 event->num_ndp_app_info); 17140 return QDF_STATUS_E_INVAL; 17141 } 17142 17143 if (fixed_params->ndp_cfg_len > 17144 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 17145 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 17146 __func__, fixed_params->ndp_cfg_len); 17147 return QDF_STATUS_E_INVAL; 17148 } 17149 17150 total_array_len = fixed_params->ndp_cfg_len + 17151 sizeof(*fixed_params); 17152 17153 if (fixed_params->ndp_app_info_len > 17154 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 17155 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 17156 __func__, fixed_params->ndp_app_info_len); 17157 return QDF_STATUS_E_INVAL; 17158 } 17159 total_array_len += fixed_params->ndp_app_info_len; 17160 17161 if (fixed_params->nan_scid_len > 17162 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 17163 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 17164 __func__, fixed_params->nan_scid_len); 17165 return QDF_STATUS_E_INVAL; 17166 } 17167 17168 rsp->vdev = 17169 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17170 fixed_params->vdev_id, 17171 WLAN_NAN_ID); 17172 if (!rsp->vdev) { 17173 WMI_LOGE("vdev is null"); 17174 return QDF_STATUS_E_INVAL; 17175 } 17176 rsp->service_instance_id = fixed_params->service_instance_id; 17177 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17178 rsp->role = fixed_params->self_ndp_role; 17179 rsp->policy = fixed_params->accept_policy; 17180 17181 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17182 rsp->peer_mac_addr.bytes); 17183 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, 17184 rsp->peer_discovery_mac_addr.bytes); 17185 17186 WMI_LOGD("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d,\n" 17187 "service_instance %d, ndp_instance %d, role %d, policy %d,\n" 17188 "csid: %d, scid_len: %d, peer_addr: %pM, peer_disc_addr: %pM", 17189 WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, 17190 fixed_params->service_instance_id, 17191 fixed_params->ndp_instance_id, fixed_params->self_ndp_role, 17192 fixed_params->accept_policy, 17193 fixed_params->nan_csid, fixed_params->nan_scid_len, 17194 rsp->peer_mac_addr.bytes, 17195 rsp->peer_discovery_mac_addr.bytes); 17196 17197 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17198 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17199 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17200 17201 WMI_LOGD("ndp_app_info - %d bytes", 17202 fixed_params->ndp_app_info_len); 17203 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17204 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17205 17206 rsp->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; 17207 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17208 rsp->ncs_sk_type = fixed_params->nan_csid; 17209 rsp->scid.scid_len = fixed_params->nan_scid_len; 17210 17211 if (rsp->ndp_config.ndp_cfg_len > NDP_QOS_INFO_LEN) 17212 rsp->ndp_config.ndp_cfg_len = NDP_QOS_INFO_LEN; 17213 qdf_mem_copy(rsp->ndp_config.ndp_cfg, event->ndp_cfg, 17214 rsp->ndp_config.ndp_cfg_len); 17215 17216 if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN) 17217 rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN; 17218 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17219 rsp->ndp_info.ndp_app_info_len); 17220 17221 if (rsp->scid.scid_len > NDP_SCID_BUF_LEN) 17222 rsp->scid.scid_len = NDP_SCID_BUF_LEN; 17223 qdf_mem_copy(rsp->scid.scid, event->ndp_scid, rsp->scid.scid_len); 17224 17225 if (event->ndp_transport_ip_param && 17226 event->num_ndp_transport_ip_param) { 17227 if (event->ndp_transport_ip_param->ipv6_addr_present) { 17228 rsp->is_ipv6_addr_present = true; 17229 qdf_mem_copy(rsp->ipv6_addr, 17230 event->ndp_transport_ip_param->ipv6_intf_addr, 17231 WMI_NDP_IPV6_INTF_ADDR_LEN); 17232 } 17233 } 17234 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 17235 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 17236 17237 WMI_LOGD("scid hex dump:"); 17238 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17239 rsp->scid.scid, rsp->scid.scid_len); 17240 17241 return QDF_STATUS_SUCCESS; 17242 } 17243 17244 static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle, 17245 uint8_t *data, struct nan_datapath_confirm_event *rsp) 17246 { 17247 uint8_t i; 17248 WMI_HOST_WLAN_PHY_MODE ch_mode; 17249 WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; 17250 wmi_ndp_confirm_event_fixed_param *fixed_params; 17251 size_t total_array_len; 17252 17253 event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) data; 17254 fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; 17255 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", 17256 WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, 17257 fixed_params->ndp_instance_id, fixed_params->rsp_code, 17258 fixed_params->reason_code, 17259 fixed_params->num_active_ndps_on_peer); 17260 WMI_LOGE("num_ch: %d", fixed_params->num_ndp_channels); 17261 17262 if (fixed_params->ndp_cfg_len > event->num_ndp_cfg) { 17263 WMI_LOGE("FW message ndp cfg length %d larger than TLV hdr %d", 17264 fixed_params->ndp_cfg_len, event->num_ndp_cfg); 17265 return QDF_STATUS_E_INVAL; 17266 } 17267 17268 WMI_LOGD("ndp_cfg - %d bytes", fixed_params->ndp_cfg_len); 17269 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17270 &event->ndp_cfg, fixed_params->ndp_cfg_len); 17271 17272 if (fixed_params->ndp_app_info_len > event->num_ndp_app_info) { 17273 WMI_LOGE("FW message ndp app info length %d more than TLV hdr %d", 17274 fixed_params->ndp_app_info_len, 17275 event->num_ndp_app_info); 17276 return QDF_STATUS_E_INVAL; 17277 } 17278 17279 WMI_LOGD("ndp_app_info - %d bytes", 17280 fixed_params->ndp_app_info_len); 17281 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 17282 &event->ndp_app_info, fixed_params->ndp_app_info_len); 17283 17284 if (fixed_params->ndp_cfg_len > 17285 (WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) { 17286 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 17287 __func__, fixed_params->ndp_cfg_len); 17288 return QDF_STATUS_E_INVAL; 17289 } 17290 17291 total_array_len = fixed_params->ndp_cfg_len + 17292 sizeof(*fixed_params); 17293 17294 if (fixed_params->ndp_app_info_len > 17295 (WMI_SVC_MSG_MAX_SIZE - total_array_len)) { 17296 WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d", 17297 __func__, fixed_params->ndp_app_info_len); 17298 return QDF_STATUS_E_INVAL; 17299 } 17300 17301 rsp->vdev = 17302 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17303 fixed_params->vdev_id, 17304 WLAN_NAN_ID); 17305 if (!rsp->vdev) { 17306 WMI_LOGE("vdev is null"); 17307 return QDF_STATUS_E_INVAL; 17308 } 17309 rsp->ndp_instance_id = fixed_params->ndp_instance_id; 17310 rsp->rsp_code = fixed_params->rsp_code; 17311 rsp->reason_code = fixed_params->reason_code; 17312 rsp->num_active_ndps_on_peer = fixed_params->num_active_ndps_on_peer; 17313 rsp->num_channels = fixed_params->num_ndp_channels; 17314 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17315 rsp->peer_ndi_mac_addr.bytes); 17316 rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; 17317 qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info, 17318 rsp->ndp_info.ndp_app_info_len); 17319 17320 if (rsp->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 17321 WMI_LOGE(FL("too many channels")); 17322 rsp->num_channels = NAN_CH_INFO_MAX_CHANNELS; 17323 } 17324 17325 for (i = 0; i < rsp->num_channels; i++) { 17326 rsp->ch[i].channel = event->ndp_channel_list[i].mhz; 17327 rsp->ch[i].nss = event->nss_list[i]; 17328 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndp_channel_list[i]); 17329 rsp->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 17330 ch_mode); 17331 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 17332 rsp->ch[i].channel, 17333 rsp->ch[i].ch_width, 17334 rsp->ch[i].nss); 17335 } 17336 17337 if (event->ndp_transport_ip_param && 17338 event->num_ndp_transport_ip_param) { 17339 if (event->ndp_transport_ip_param->ipv6_addr_present) { 17340 rsp->is_ipv6_addr_present = true; 17341 qdf_mem_copy(rsp->ipv6_addr, 17342 event->ndp_transport_ip_param->ipv6_intf_addr, 17343 WMI_NDP_IPV6_INTF_ADDR_LEN); 17344 } 17345 17346 if (event->ndp_transport_ip_param->trans_port_present) { 17347 rsp->is_port_present = true; 17348 rsp->port = 17349 event->ndp_transport_ip_param->transport_port; 17350 } 17351 17352 if (event->ndp_transport_ip_param->trans_proto_present) { 17353 rsp->is_protocol_present = true; 17354 rsp->protocol = 17355 event->ndp_transport_ip_param->transport_protocol; 17356 } 17357 } 17358 WMI_LOGD(FL("IPv6 addr present: %d, addr: %pI6"), 17359 rsp->is_ipv6_addr_present, rsp->ipv6_addr); 17360 WMI_LOGD(FL("port: %d present: %d"), rsp->port, rsp->is_port_present); 17361 WMI_LOGD(FL("protocol: %d present: %d"), 17362 rsp->protocol, rsp->is_protocol_present); 17363 17364 return QDF_STATUS_SUCCESS; 17365 } 17366 17367 static QDF_STATUS extract_ndp_responder_rsp_tlv(wmi_unified_t wmi_handle, 17368 uint8_t *data, struct nan_datapath_responder_rsp *rsp) 17369 { 17370 WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; 17371 wmi_ndp_responder_rsp_event_fixed_param *fixed_params; 17372 17373 event = (WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *)data; 17374 fixed_params = event->fixed_param; 17375 17376 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", 17377 WMI_NDP_RESPONDER_RSP_EVENTID, fixed_params->vdev_id, 17378 rsp->peer_mac_addr.bytes, rsp->transaction_id, 17379 rsp->status, rsp->reason, rsp->create_peer); 17380 17381 rsp->vdev = 17382 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17383 fixed_params->vdev_id, 17384 WLAN_NAN_ID); 17385 if (!rsp->vdev) { 17386 WMI_LOGE("vdev is null"); 17387 return QDF_STATUS_E_INVAL; 17388 } 17389 rsp->transaction_id = fixed_params->transaction_id; 17390 rsp->reason = fixed_params->reason_code; 17391 rsp->status = fixed_params->rsp_status; 17392 rsp->create_peer = fixed_params->create_peer; 17393 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, 17394 rsp->peer_mac_addr.bytes); 17395 17396 return QDF_STATUS_SUCCESS; 17397 } 17398 17399 static QDF_STATUS extract_ndp_end_rsp_tlv(wmi_unified_t wmi_handle, 17400 uint8_t *data, struct nan_datapath_end_rsp_event *rsp) 17401 { 17402 WMI_NDP_END_RSP_EVENTID_param_tlvs *event; 17403 wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; 17404 17405 event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data; 17406 fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; 17407 WMI_LOGD("WMI_NDP_END_RSP_EVENTID(0x%X) received. transaction_id: %d, rsp_status: %d, reason_code: %d", 17408 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, 17409 fixed_params->rsp_status, fixed_params->reason_code); 17410 17411 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17412 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17413 if (!rsp->vdev) { 17414 WMI_LOGE("vdev is null"); 17415 return QDF_STATUS_E_INVAL; 17416 } 17417 rsp->transaction_id = fixed_params->transaction_id; 17418 rsp->reason = fixed_params->reason_code; 17419 rsp->status = fixed_params->rsp_status; 17420 17421 return QDF_STATUS_SUCCESS; 17422 } 17423 17424 static QDF_STATUS extract_ndp_end_ind_tlv(wmi_unified_t wmi_handle, 17425 uint8_t *data, struct nan_datapath_end_indication_event **rsp) 17426 { 17427 uint32_t i, buf_size; 17428 wmi_ndp_end_indication *ind; 17429 struct qdf_mac_addr peer_addr; 17430 WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; 17431 17432 event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data; 17433 ind = event->ndp_end_indication_list; 17434 17435 if (event->num_ndp_end_indication_list == 0) { 17436 WMI_LOGE("Error: Event ignored, 0 ndp instances"); 17437 return QDF_STATUS_E_INVAL; 17438 } 17439 17440 WMI_LOGD("number of ndp instances = %d", 17441 event->num_ndp_end_indication_list); 17442 17443 if (event->num_ndp_end_indication_list > ((UINT_MAX - sizeof(**rsp))/ 17444 sizeof((*rsp)->ndp_map[0]))) { 17445 WMI_LOGE("num_ndp_end_ind_list %d too large", 17446 event->num_ndp_end_indication_list); 17447 return QDF_STATUS_E_INVAL; 17448 } 17449 17450 buf_size = sizeof(**rsp) + event->num_ndp_end_indication_list * 17451 sizeof((*rsp)->ndp_map[0]); 17452 *rsp = qdf_mem_malloc(buf_size); 17453 if (!(*rsp)) { 17454 WMI_LOGE("Failed to allocate memory"); 17455 return QDF_STATUS_E_NOMEM; 17456 } 17457 17458 (*rsp)->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( 17459 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID); 17460 if (!(*rsp)->vdev) { 17461 WMI_LOGE("vdev is null"); 17462 qdf_mem_free(*rsp); 17463 *rsp = NULL; 17464 return QDF_STATUS_E_INVAL; 17465 } 17466 17467 (*rsp)->num_ndp_ids = event->num_ndp_end_indication_list; 17468 for (i = 0; i < (*rsp)->num_ndp_ids; i++) { 17469 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17470 peer_addr.bytes); 17471 WMI_LOGD("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ", 17472 i, ind[i].type, ind[i].reason_code, 17473 ind[i].ndp_instance_id, 17474 ind[i].num_active_ndps_on_peer); 17475 /* Add each instance entry to the list */ 17476 (*rsp)->ndp_map[i].ndp_instance_id = ind[i].ndp_instance_id; 17477 (*rsp)->ndp_map[i].vdev_id = ind[i].vdev_id; 17478 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, 17479 (*rsp)->ndp_map[i].peer_ndi_mac_addr.bytes); 17480 (*rsp)->ndp_map[i].num_active_ndp_sessions = 17481 ind[i].num_active_ndps_on_peer; 17482 (*rsp)->ndp_map[i].type = ind[i].type; 17483 (*rsp)->ndp_map[i].reason_code = ind[i].reason_code; 17484 } 17485 17486 return QDF_STATUS_SUCCESS; 17487 } 17488 17489 static QDF_STATUS extract_ndp_sch_update_tlv(wmi_unified_t wmi_handle, 17490 uint8_t *data, struct nan_datapath_sch_update_event *ind) 17491 { 17492 uint8_t i; 17493 WMI_HOST_WLAN_PHY_MODE ch_mode; 17494 WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *event; 17495 wmi_ndl_schedule_update_fixed_param *fixed_params; 17496 17497 event = (WMI_NDL_SCHEDULE_UPDATE_EVENTID_param_tlvs *)data; 17498 fixed_params = event->fixed_param; 17499 17500 WMI_LOGD(FL("flags: %d, num_ch: %d, num_ndp_instances: %d"), 17501 fixed_params->flags, fixed_params->num_channels, 17502 fixed_params->num_ndp_instances); 17503 17504 ind->vdev = 17505 wlan_objmgr_get_vdev_by_id_from_psoc(wmi_handle->soc->wmi_psoc, 17506 fixed_params->vdev_id, 17507 WLAN_NAN_ID); 17508 if (!ind->vdev) { 17509 WMI_LOGE("vdev is null"); 17510 return QDF_STATUS_E_INVAL; 17511 } 17512 17513 ind->flags = fixed_params->flags; 17514 ind->num_channels = fixed_params->num_channels; 17515 ind->num_ndp_instances = fixed_params->num_ndp_instances; 17516 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_macaddr, 17517 ind->peer_addr.bytes); 17518 17519 if (ind->num_ndp_instances > NDP_NUM_INSTANCE_ID) { 17520 WMI_LOGE(FL("uint32 overflow")); 17521 wlan_objmgr_vdev_release_ref(ind->vdev, WLAN_NAN_ID); 17522 return QDF_STATUS_E_INVAL; 17523 } 17524 17525 qdf_mem_copy(ind->ndp_instances, event->ndp_instance_list, 17526 sizeof(uint32_t) * ind->num_ndp_instances); 17527 17528 if (ind->num_channels > NAN_CH_INFO_MAX_CHANNELS) { 17529 WMI_LOGE(FL("too many channels")); 17530 ind->num_channels = NAN_CH_INFO_MAX_CHANNELS; 17531 } 17532 for (i = 0; i < ind->num_channels; i++) { 17533 ind->ch[i].channel = event->ndl_channel_list[i].mhz; 17534 ind->ch[i].nss = event->nss_list[i]; 17535 ch_mode = WMI_GET_CHANNEL_MODE(&event->ndl_channel_list[i]); 17536 ind->ch[i].ch_width = wmi_get_ch_width_from_phy_mode(wmi_handle, 17537 ch_mode); 17538 WMI_LOGD(FL("ch: %d, ch_mode: %d, nss: %d"), 17539 ind->ch[i].channel, 17540 ind->ch[i].ch_width, 17541 ind->ch[i].nss); 17542 } 17543 17544 for (i = 0; i < fixed_params->num_ndp_instances; i++) 17545 WMI_LOGD(FL("instance_id[%d]: %d"), 17546 i, event->ndp_instance_list[i]); 17547 17548 return QDF_STATUS_SUCCESS; 17549 } 17550 17551 #endif 17552 17553 #ifdef QCA_SUPPORT_CP_STATS 17554 /** 17555 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 17556 * @wmi_handle: wma handle 17557 * @evt_buf: event buffer 17558 * @out_buff: buffer to populated after stats extraction 17559 * 17560 * Return: status of operation 17561 */ 17562 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 17563 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 17564 { 17565 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 17566 wmi_congestion_stats *congestion_stats; 17567 17568 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 17569 congestion_stats = param_buf->congestion_stats; 17570 if (!congestion_stats) { 17571 WMI_LOGD("%s: no cca stats in event buffer", __func__); 17572 return QDF_STATUS_E_INVAL; 17573 } 17574 17575 out_buff->vdev_id = congestion_stats->vdev_id; 17576 out_buff->congestion = congestion_stats->congestion; 17577 17578 WMI_LOGD("%s: cca stats event processed", __func__); 17579 return QDF_STATUS_SUCCESS; 17580 } 17581 #endif /* QCA_SUPPORT_CP_STATS */ 17582 17583 /** 17584 * save_service_bitmap_tlv() - save service bitmap 17585 * @wmi_handle: wmi handle 17586 * @param evt_buf: pointer to event buffer 17587 * @param bitmap_buf: bitmap buffer, for converged legacy support 17588 * 17589 * Return: QDF_STATUS 17590 */ 17591 static 17592 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17593 void *bitmap_buf) 17594 { 17595 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17596 struct wmi_soc *soc = wmi_handle->soc; 17597 17598 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17599 17600 /* If it is already allocated, use that buffer. This can happen 17601 * during target stop/start scenarios where host allocation is skipped. 17602 */ 17603 if (!soc->wmi_service_bitmap) { 17604 soc->wmi_service_bitmap = 17605 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 17606 if (!soc->wmi_service_bitmap) { 17607 WMI_LOGE("Failed memory allocation for service bitmap"); 17608 return QDF_STATUS_E_NOMEM; 17609 } 17610 } 17611 17612 qdf_mem_copy(soc->wmi_service_bitmap, 17613 param_buf->wmi_service_bitmap, 17614 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17615 17616 if (bitmap_buf) 17617 qdf_mem_copy(bitmap_buf, 17618 param_buf->wmi_service_bitmap, 17619 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 17620 17621 return QDF_STATUS_SUCCESS; 17622 } 17623 17624 /** 17625 * save_ext_service_bitmap_tlv() - save extendend service bitmap 17626 * @wmi_handle: wmi handle 17627 * @param evt_buf: pointer to event buffer 17628 * @param bitmap_buf: bitmap buffer, for converged legacy support 17629 * 17630 * Return: QDF_STATUS 17631 */ 17632 static 17633 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17634 void *bitmap_buf) 17635 { 17636 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 17637 wmi_service_available_event_fixed_param *ev; 17638 struct wmi_soc *soc = wmi_handle->soc; 17639 17640 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 17641 17642 ev = param_buf->fixed_param; 17643 17644 /* If it is already allocated, use that buffer. This can happen 17645 * during target stop/start scenarios where host allocation is skipped. 17646 */ 17647 if (!soc->wmi_ext_service_bitmap) { 17648 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 17649 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 17650 if (!soc->wmi_ext_service_bitmap) { 17651 WMI_LOGE("Failed memory allocation for service bitmap"); 17652 return QDF_STATUS_E_NOMEM; 17653 } 17654 } 17655 17656 qdf_mem_copy(soc->wmi_ext_service_bitmap, 17657 ev->wmi_service_segment_bitmap, 17658 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17659 17660 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n", 17661 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 17662 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 17663 17664 if (bitmap_buf) 17665 qdf_mem_copy(bitmap_buf, 17666 soc->wmi_ext_service_bitmap, 17667 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 17668 17669 return QDF_STATUS_SUCCESS; 17670 } 17671 /** 17672 * is_service_enabled_tlv() - Check if service enabled 17673 * @param wmi_handle: wmi handle 17674 * @param service_id: service identifier 17675 * 17676 * Return: 1 enabled, 0 disabled 17677 */ 17678 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 17679 uint32_t service_id) 17680 { 17681 struct wmi_soc *soc = wmi_handle->soc; 17682 17683 if (!soc->wmi_service_bitmap) { 17684 WMI_LOGE("WMI service bit map is not saved yet\n"); 17685 return false; 17686 } 17687 17688 /* if wmi_service_enabled was received with extended bitmap, 17689 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 17690 */ 17691 if (soc->wmi_ext_service_bitmap) 17692 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 17693 soc->wmi_ext_service_bitmap, 17694 service_id); 17695 17696 if (service_id >= WMI_MAX_SERVICE) { 17697 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 17698 service_id); 17699 return false; 17700 } 17701 17702 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 17703 service_id); 17704 } 17705 17706 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 17707 struct wlan_psoc_target_capability_info *cap) 17708 { 17709 /* except LDPC all flags are common betwen legacy and here 17710 * also IBFEER is not defined for TLV 17711 */ 17712 cap->ht_cap_info |= ev_target_cap & ( 17713 WMI_HT_CAP_ENABLED 17714 | WMI_HT_CAP_HT20_SGI 17715 | WMI_HT_CAP_DYNAMIC_SMPS 17716 | WMI_HT_CAP_TX_STBC 17717 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 17718 | WMI_HT_CAP_RX_STBC 17719 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 17720 | WMI_HT_CAP_LDPC 17721 | WMI_HT_CAP_L_SIG_TXOP_PROT 17722 | WMI_HT_CAP_MPDU_DENSITY 17723 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 17724 | WMI_HT_CAP_HT40_SGI); 17725 if (ev_target_cap & WMI_HT_CAP_LDPC) 17726 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 17727 WMI_HOST_HT_CAP_TX_LDPC; 17728 } 17729 /** 17730 * extract_service_ready_tlv() - extract service ready event 17731 * @wmi_handle: wmi handle 17732 * @param evt_buf: pointer to received event buffer 17733 * @param cap: pointer to hold target capability information extracted from even 17734 * 17735 * Return: QDF_STATUS_SUCCESS for success or error code 17736 */ 17737 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 17738 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 17739 { 17740 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17741 wmi_service_ready_event_fixed_param *ev; 17742 17743 17744 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17745 17746 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17747 if (!ev) { 17748 qdf_print("%s: wmi_buf_alloc failed", __func__); 17749 return QDF_STATUS_E_FAILURE; 17750 } 17751 17752 cap->phy_capability = ev->phy_capability; 17753 cap->max_frag_entry = ev->max_frag_entry; 17754 cap->num_rf_chains = ev->num_rf_chains; 17755 copy_ht_cap_info(ev->ht_cap_info, cap); 17756 cap->vht_cap_info = ev->vht_cap_info; 17757 cap->vht_supp_mcs = ev->vht_supp_mcs; 17758 cap->hw_min_tx_power = ev->hw_min_tx_power; 17759 cap->hw_max_tx_power = ev->hw_max_tx_power; 17760 cap->sys_cap_info = ev->sys_cap_info; 17761 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 17762 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 17763 cap->max_num_scan_channels = ev->max_num_scan_channels; 17764 cap->max_supported_macs = ev->max_supported_macs; 17765 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 17766 cap->txrx_chainmask = ev->txrx_chainmask; 17767 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 17768 cap->num_msdu_desc = ev->num_msdu_desc; 17769 cap->fw_version = ev->fw_build_vers; 17770 /* fw_version_1 is not available in TLV. */ 17771 cap->fw_version_1 = 0; 17772 17773 return QDF_STATUS_SUCCESS; 17774 } 17775 17776 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 17777 * to host internal WMI_HOST_REGDMN_MODE values. 17778 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 17779 * host currently. Add this in the future if required. 17780 * 11AX (Phase II) : 11ax related values are not currently 17781 * advertised separately by FW. As part of phase II regulatory bring-up, 17782 * finalize the advertisement mechanism. 17783 * @target_wireless_mode: target wireless mode received in message 17784 * 17785 * Return: returns the host internal wireless mode. 17786 */ 17787 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 17788 { 17789 17790 uint32_t wireless_modes = 0; 17791 17792 if (target_wireless_mode & REGDMN_MODE_11A) 17793 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 17794 17795 if (target_wireless_mode & REGDMN_MODE_TURBO) 17796 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 17797 17798 if (target_wireless_mode & REGDMN_MODE_11B) 17799 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 17800 17801 if (target_wireless_mode & REGDMN_MODE_PUREG) 17802 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 17803 17804 if (target_wireless_mode & REGDMN_MODE_11G) 17805 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 17806 17807 if (target_wireless_mode & REGDMN_MODE_108G) 17808 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 17809 17810 if (target_wireless_mode & REGDMN_MODE_108A) 17811 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 17812 17813 if (target_wireless_mode & REGDMN_MODE_XR) 17814 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 17815 17816 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 17817 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 17818 17819 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 17820 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 17821 17822 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 17823 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 17824 17825 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 17826 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 17827 17828 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 17829 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 17830 17831 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 17832 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 17833 17834 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 17835 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 17836 17837 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 17838 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 17839 17840 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 17841 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 17842 17843 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 17844 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 17845 17846 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 17847 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 17848 17849 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 17850 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 17851 17852 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 17853 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 17854 17855 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 17856 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 17857 17858 return wireless_modes; 17859 } 17860 17861 /** 17862 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 17863 * @wmi_handle: wmi handle 17864 * @param evt_buf: Pointer to event buffer 17865 * @param cap: pointer to hold HAL reg capabilities 17866 * 17867 * Return: QDF_STATUS_SUCCESS for success or error code 17868 */ 17869 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 17870 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 17871 { 17872 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17873 17874 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17875 17876 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 17877 sizeof(uint32_t)), 17878 sizeof(struct wlan_psoc_hal_reg_capability)); 17879 17880 cap->wireless_modes = convert_wireless_modes_tlv( 17881 param_buf->hal_reg_capabilities->wireless_modes); 17882 17883 return QDF_STATUS_SUCCESS; 17884 } 17885 17886 /** 17887 * extract_host_mem_req_tlv() - Extract host memory request event 17888 * @wmi_handle: wmi handle 17889 * @param evt_buf: pointer to event buffer 17890 * @param num_entries: pointer to hold number of entries requested 17891 * 17892 * Return: Number of entries requested 17893 */ 17894 static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 17895 void *evt_buf, uint8_t *num_entries) 17896 { 17897 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17898 wmi_service_ready_event_fixed_param *ev; 17899 17900 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17901 17902 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17903 if (!ev) { 17904 qdf_print("%s: wmi_buf_alloc failed", __func__); 17905 return NULL; 17906 } 17907 17908 *num_entries = ev->num_mem_reqs; 17909 17910 return (host_mem_req *)param_buf->mem_reqs; 17911 } 17912 17913 /** 17914 * save_fw_version_in_service_ready_tlv() - Save fw version in service 17915 * ready function 17916 * @wmi_handle: wmi handle 17917 * @param evt_buf: pointer to event buffer 17918 * 17919 * Return: QDF_STATUS_SUCCESS for success or error code 17920 */ 17921 static QDF_STATUS 17922 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 17923 { 17924 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 17925 wmi_service_ready_event_fixed_param *ev; 17926 17927 17928 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 17929 17930 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 17931 if (!ev) { 17932 qdf_print("%s: wmi_buf_alloc failed", __func__); 17933 return QDF_STATUS_E_FAILURE; 17934 } 17935 17936 /*Save fw version from service ready message */ 17937 /*This will be used while sending INIT message */ 17938 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 17939 sizeof(wmi_handle->fw_abi_version)); 17940 17941 return QDF_STATUS_SUCCESS; 17942 } 17943 17944 /** 17945 * ready_extract_init_status_tlv() - Extract init status from ready event 17946 * @wmi_handle: wmi handle 17947 * @param evt_buf: Pointer to event buffer 17948 * 17949 * Return: ready status 17950 */ 17951 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 17952 void *evt_buf) 17953 { 17954 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17955 wmi_ready_event_fixed_param *ev = NULL; 17956 17957 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17958 ev = param_buf->fixed_param; 17959 17960 qdf_print("%s:%d", __func__, ev->status); 17961 17962 return ev->status; 17963 } 17964 17965 /** 17966 * ready_extract_mac_addr_tlv() - extract mac address from ready event 17967 * @wmi_handle: wmi handle 17968 * @param evt_buf: pointer to event buffer 17969 * @param macaddr: Pointer to hold MAC address 17970 * 17971 * Return: QDF_STATUS_SUCCESS for success or error code 17972 */ 17973 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 17974 void *evt_buf, uint8_t *macaddr) 17975 { 17976 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 17977 wmi_ready_event_fixed_param *ev = NULL; 17978 17979 17980 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 17981 ev = param_buf->fixed_param; 17982 17983 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 17984 17985 return QDF_STATUS_SUCCESS; 17986 } 17987 17988 /** 17989 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 17990 * @wmi_handle: wmi handle 17991 * @param evt_buf: pointer to event buffer 17992 * @param macaddr: Pointer to hold number of MAC addresses 17993 * 17994 * Return: Pointer to addr list 17995 */ 17996 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 17997 void *evt_buf, uint8_t *num_mac) 17998 { 17999 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18000 wmi_ready_event_fixed_param *ev = NULL; 18001 18002 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18003 ev = param_buf->fixed_param; 18004 18005 *num_mac = ev->num_extra_mac_addr; 18006 18007 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 18008 } 18009 18010 /** 18011 * extract_ready_params_tlv() - Extract data from ready event apart from 18012 * status, macaddr and version. 18013 * @wmi_handle: Pointer to WMI handle. 18014 * @evt_buf: Pointer to Ready event buffer. 18015 * @ev_param: Pointer to host defined struct to copy the data from event. 18016 * 18017 * Return: QDF_STATUS_SUCCESS on success. 18018 */ 18019 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 18020 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 18021 { 18022 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 18023 wmi_ready_event_fixed_param *ev = NULL; 18024 18025 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 18026 ev = param_buf->fixed_param; 18027 18028 ev_param->status = ev->status; 18029 ev_param->num_dscp_table = ev->num_dscp_table; 18030 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 18031 ev_param->num_total_peer = ev->num_total_peers; 18032 ev_param->num_extra_peer = ev->num_extra_peers; 18033 /* Agile_cap in ready event is not supported in TLV target */ 18034 ev_param->agile_capability = false; 18035 18036 return QDF_STATUS_SUCCESS; 18037 } 18038 18039 /** 18040 * extract_dbglog_data_len_tlv() - extract debuglog data length 18041 * @wmi_handle: wmi handle 18042 * @param evt_buf: pointer to event buffer 18043 * 18044 * Return: length 18045 */ 18046 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 18047 void *evt_buf, uint32_t *len) 18048 { 18049 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 18050 18051 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 18052 18053 *len = param_buf->num_bufp; 18054 18055 return param_buf->bufp; 18056 } 18057 18058 /** 18059 * extract_vdev_start_resp_tlv() - extract vdev start response 18060 * @wmi_handle: wmi handle 18061 * @param evt_buf: pointer to event buffer 18062 * @param vdev_rsp: Pointer to hold vdev response 18063 * 18064 * Return: QDF_STATUS_SUCCESS for success or error code 18065 */ 18066 static QDF_STATUS extract_vdev_start_resp_tlv(wmi_unified_t wmi_handle, 18067 void *evt_buf, wmi_host_vdev_start_resp *vdev_rsp) 18068 { 18069 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; 18070 wmi_vdev_start_response_event_fixed_param *ev; 18071 18072 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) evt_buf; 18073 if (!param_buf) { 18074 qdf_print("Invalid start response event buffer"); 18075 return QDF_STATUS_E_INVAL; 18076 } 18077 18078 ev = param_buf->fixed_param; 18079 if (!ev) { 18080 qdf_print("Invalid start response event buffer"); 18081 return QDF_STATUS_E_INVAL; 18082 } 18083 18084 qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp)); 18085 18086 vdev_rsp->vdev_id = ev->vdev_id; 18087 vdev_rsp->requestor_id = ev->requestor_id; 18088 switch (ev->resp_type) { 18089 case WMI_VDEV_START_RESP_EVENT: 18090 vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT; 18091 break; 18092 case WMI_VDEV_RESTART_RESP_EVENT: 18093 vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT; 18094 break; 18095 default: 18096 qdf_print("Invalid start response event buffer"); 18097 break; 18098 }; 18099 vdev_rsp->status = ev->status; 18100 vdev_rsp->chain_mask = ev->chain_mask; 18101 vdev_rsp->smps_mode = ev->smps_mode; 18102 vdev_rsp->mac_id = ev->mac_id; 18103 vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; 18104 vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; 18105 18106 return QDF_STATUS_SUCCESS; 18107 } 18108 18109 /** 18110 * extract_vdev_delete_resp_tlv() - extract vdev delete response 18111 * @wmi_handle: wmi handle 18112 * @param evt_buf: pointer to event buffer 18113 * @param delete_rsp: Pointer to hold vdev delete response 18114 * 18115 * Return: QDF_STATUS_SUCCESS for success or error code 18116 */ 18117 static QDF_STATUS extract_vdev_delete_resp_tlv(wmi_unified_t wmi_handle, 18118 void *evt_buf, struct wmi_host_vdev_delete_resp *delete_rsp) 18119 { 18120 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; 18121 wmi_vdev_delete_resp_event_fixed_param *ev; 18122 18123 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *) evt_buf; 18124 if (!param_buf) { 18125 WMI_LOGE("Invalid vdev delete response event buffer\n"); 18126 return QDF_STATUS_E_INVAL; 18127 } 18128 18129 ev = param_buf->fixed_param; 18130 if (!ev) { 18131 WMI_LOGE("Invalid vdev delete response event\n"); 18132 return QDF_STATUS_E_INVAL; 18133 } 18134 18135 qdf_mem_zero(delete_rsp, sizeof(*delete_rsp)); 18136 delete_rsp->vdev_id = ev->vdev_id; 18137 18138 return QDF_STATUS_SUCCESS; 18139 } 18140 18141 18142 /** 18143 * extract_tbttoffset_num_vdevs_tlv() - extract tbtt offset num vdev 18144 * @wmi_handle: wmi handle 18145 * @param evt_buf: pointer to event buffer 18146 * @param num_vdevs: Pointer to hold num vdev 18147 * 18148 * Return: QDF_STATUS_SUCCESS for success or error code 18149 */ 18150 static QDF_STATUS extract_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18151 void *evt_buf, uint32_t *num_vdevs) 18152 { 18153 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18154 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18155 uint32_t vdev_map; 18156 18157 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf; 18158 if (!param_buf) { 18159 qdf_print("Invalid tbtt update ext event buffer"); 18160 return QDF_STATUS_E_INVAL; 18161 } 18162 tbtt_offset_event = param_buf->fixed_param; 18163 vdev_map = tbtt_offset_event->vdev_map; 18164 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18165 18166 return QDF_STATUS_SUCCESS; 18167 } 18168 18169 /** 18170 * extract_ext_tbttoffset_num_vdevs_tlv() - extract ext tbtt offset num vdev 18171 * @wmi_handle: wmi handle 18172 * @param evt_buf: pointer to event buffer 18173 * @param num_vdevs: Pointer to hold num vdev 18174 * 18175 * Return: QDF_STATUS_SUCCESS for success or error code 18176 */ 18177 static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(void *wmi_hdl, 18178 void *evt_buf, uint32_t *num_vdevs) 18179 { 18180 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18181 wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event; 18182 18183 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18184 if (!param_buf) { 18185 qdf_print("Invalid tbtt update ext event buffer"); 18186 return QDF_STATUS_E_INVAL; 18187 } 18188 tbtt_offset_ext_event = param_buf->fixed_param; 18189 18190 *num_vdevs = tbtt_offset_ext_event->num_vdevs; 18191 18192 return QDF_STATUS_SUCCESS; 18193 } 18194 18195 /** 18196 * extract_tbttoffset_update_params_tlv() - extract tbtt offset param 18197 * @wmi_handle: wmi handle 18198 * @param evt_buf: pointer to event buffer 18199 * @param idx: Index referring to a vdev 18200 * @param tbtt_param: Pointer to tbttoffset event param 18201 * 18202 * Return: QDF_STATUS_SUCCESS for success or error code 18203 */ 18204 static QDF_STATUS extract_tbttoffset_update_params_tlv(void *wmi_hdl, 18205 void *evt_buf, uint8_t idx, 18206 struct tbttoffset_params *tbtt_param) 18207 { 18208 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; 18209 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; 18210 uint32_t vdev_map; 18211 18212 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) evt_buf; 18213 if (!param_buf) { 18214 qdf_print("Invalid tbtt update event buffer"); 18215 return QDF_STATUS_E_INVAL; 18216 } 18217 18218 tbtt_offset_event = param_buf->fixed_param; 18219 vdev_map = tbtt_offset_event->vdev_map; 18220 tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx); 18221 if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID) 18222 return QDF_STATUS_E_INVAL; 18223 tbtt_param->tbttoffset = 18224 param_buf->tbttoffset_list[tbtt_param->vdev_id]; 18225 18226 return QDF_STATUS_SUCCESS; 18227 } 18228 18229 /** 18230 * extract_ext_tbttoffset_update_params_tlv() - extract ext tbtt offset param 18231 * @wmi_handle: wmi handle 18232 * @param evt_buf: pointer to event buffer 18233 * @param idx: Index referring to a vdev 18234 * @param tbtt_param: Pointer to tbttoffset event param 18235 * 18236 * Return: QDF_STATUS_SUCCESS for success or error code 18237 */ 18238 static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(void *wmi_hdl, 18239 void *evt_buf, uint8_t idx, 18240 struct tbttoffset_params *tbtt_param) 18241 { 18242 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf; 18243 wmi_tbtt_offset_info *tbtt_offset_info; 18244 18245 param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf; 18246 if (!param_buf) { 18247 qdf_print("Invalid tbtt update event buffer"); 18248 return QDF_STATUS_E_INVAL; 18249 } 18250 tbtt_offset_info = ¶m_buf->tbtt_offset_info[idx]; 18251 18252 tbtt_param->vdev_id = tbtt_offset_info->vdev_id; 18253 tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset; 18254 18255 return QDF_STATUS_SUCCESS; 18256 } 18257 18258 #ifdef CONFIG_MCL 18259 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 18260 ((_status) & WMI_RXERR_DECRYPT) 18261 #else 18262 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 18263 #endif 18264 18265 /** 18266 * extract_mgmt_rx_params_tlv() - extract management rx params from event 18267 * @wmi_handle: wmi handle 18268 * @param evt_buf: pointer to event buffer 18269 * @param hdr: Pointer to hold header 18270 * @param bufp: Pointer to hold pointer to rx param buffer 18271 * 18272 * Return: QDF_STATUS_SUCCESS for success or error code 18273 */ 18274 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 18275 void *evt_buf, struct mgmt_rx_event_params *hdr, 18276 uint8_t **bufp) 18277 { 18278 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 18279 wmi_mgmt_rx_hdr *ev_hdr = NULL; 18280 int i; 18281 18282 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 18283 if (!param_tlvs) { 18284 WMI_LOGE("Get NULL point message from FW"); 18285 return QDF_STATUS_E_INVAL; 18286 } 18287 18288 ev_hdr = param_tlvs->hdr; 18289 if (!hdr) { 18290 WMI_LOGE("Rx event is NULL"); 18291 return QDF_STATUS_E_INVAL; 18292 } 18293 18294 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 18295 WMI_LOGE("%s: RX mgmt frame decrypt error, discard it", 18296 __func__); 18297 return QDF_STATUS_E_INVAL; 18298 } 18299 18300 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18301 ev_hdr->pdev_id); 18302 18303 hdr->channel = ev_hdr->channel; 18304 hdr->snr = ev_hdr->snr; 18305 hdr->rate = ev_hdr->rate; 18306 hdr->phy_mode = ev_hdr->phy_mode; 18307 hdr->buf_len = ev_hdr->buf_len; 18308 hdr->status = ev_hdr->status; 18309 hdr->flags = ev_hdr->flags; 18310 hdr->rssi = ev_hdr->rssi; 18311 hdr->tsf_delta = ev_hdr->tsf_delta; 18312 for (i = 0; i < ATH_MAX_ANTENNA; i++) 18313 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 18314 18315 *bufp = param_tlvs->bufp; 18316 18317 return QDF_STATUS_SUCCESS; 18318 } 18319 18320 /** 18321 * extract_vdev_stopped_param_tlv() - extract vdev stop param from event 18322 * @wmi_handle: wmi handle 18323 * @param evt_buf: pointer to event buffer 18324 * @param vdev_id: Pointer to hold vdev identifier 18325 * 18326 * Return: QDF_STATUS_SUCCESS for success or error code 18327 */ 18328 static QDF_STATUS extract_vdev_stopped_param_tlv(wmi_unified_t wmi_handle, 18329 void *evt_buf, uint32_t *vdev_id) 18330 { 18331 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; 18332 wmi_vdev_stopped_event_fixed_param *resp_event; 18333 18334 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) evt_buf; 18335 if (!param_buf) { 18336 WMI_LOGE("Invalid event buffer"); 18337 return QDF_STATUS_E_INVAL; 18338 } 18339 resp_event = param_buf->fixed_param; 18340 *vdev_id = resp_event->vdev_id; 18341 18342 return QDF_STATUS_SUCCESS; 18343 } 18344 18345 /** 18346 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 18347 * @wmi_handle: wmi handle 18348 * @param evt_buf: pointer to event buffer 18349 * @param param: Pointer to hold roam param 18350 * 18351 * Return: QDF_STATUS_SUCCESS for success or error code 18352 */ 18353 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 18354 void *evt_buf, wmi_host_roam_event *param) 18355 { 18356 WMI_ROAM_EVENTID_param_tlvs *param_buf; 18357 wmi_roam_event_fixed_param *evt; 18358 18359 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 18360 if (!param_buf) { 18361 WMI_LOGE("Invalid roam event buffer"); 18362 return QDF_STATUS_E_INVAL; 18363 } 18364 18365 evt = param_buf->fixed_param; 18366 qdf_mem_zero(param, sizeof(*param)); 18367 18368 param->vdev_id = evt->vdev_id; 18369 param->reason = evt->reason; 18370 param->rssi = evt->rssi; 18371 18372 return QDF_STATUS_SUCCESS; 18373 } 18374 18375 /** 18376 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 18377 * @wmi_handle: wmi handle 18378 * @param evt_buf: pointer to event buffer 18379 * @param param: Pointer to hold vdev scan param 18380 * 18381 * Return: QDF_STATUS_SUCCESS for success or error code 18382 */ 18383 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 18384 void *evt_buf, struct scan_event *param) 18385 { 18386 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 18387 wmi_scan_event_fixed_param *evt = NULL; 18388 18389 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 18390 evt = param_buf->fixed_param; 18391 18392 qdf_mem_zero(param, sizeof(*param)); 18393 18394 switch (evt->event) { 18395 case WMI_SCAN_EVENT_STARTED: 18396 param->type = SCAN_EVENT_TYPE_STARTED; 18397 break; 18398 case WMI_SCAN_EVENT_COMPLETED: 18399 param->type = SCAN_EVENT_TYPE_COMPLETED; 18400 break; 18401 case WMI_SCAN_EVENT_BSS_CHANNEL: 18402 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 18403 break; 18404 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 18405 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 18406 break; 18407 case WMI_SCAN_EVENT_DEQUEUED: 18408 param->type = SCAN_EVENT_TYPE_DEQUEUED; 18409 break; 18410 case WMI_SCAN_EVENT_PREEMPTED: 18411 param->type = SCAN_EVENT_TYPE_PREEMPTED; 18412 break; 18413 case WMI_SCAN_EVENT_START_FAILED: 18414 param->type = SCAN_EVENT_TYPE_START_FAILED; 18415 break; 18416 case WMI_SCAN_EVENT_RESTARTED: 18417 param->type = SCAN_EVENT_TYPE_RESTARTED; 18418 break; 18419 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 18420 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 18421 break; 18422 case WMI_SCAN_EVENT_MAX: 18423 default: 18424 param->type = SCAN_EVENT_TYPE_MAX; 18425 break; 18426 }; 18427 18428 switch (evt->reason) { 18429 case WMI_SCAN_REASON_NONE: 18430 param->reason = SCAN_REASON_NONE; 18431 break; 18432 case WMI_SCAN_REASON_COMPLETED: 18433 param->reason = SCAN_REASON_COMPLETED; 18434 break; 18435 case WMI_SCAN_REASON_CANCELLED: 18436 param->reason = SCAN_REASON_CANCELLED; 18437 break; 18438 case WMI_SCAN_REASON_PREEMPTED: 18439 param->reason = SCAN_REASON_PREEMPTED; 18440 break; 18441 case WMI_SCAN_REASON_TIMEDOUT: 18442 param->reason = SCAN_REASON_TIMEDOUT; 18443 break; 18444 case WMI_SCAN_REASON_INTERNAL_FAILURE: 18445 param->reason = SCAN_REASON_INTERNAL_FAILURE; 18446 break; 18447 case WMI_SCAN_REASON_SUSPENDED: 18448 param->reason = SCAN_REASON_SUSPENDED; 18449 break; 18450 case WMI_SCAN_REASON_MAX: 18451 param->reason = SCAN_REASON_MAX; 18452 break; 18453 default: 18454 param->reason = SCAN_REASON_MAX; 18455 break; 18456 }; 18457 18458 param->chan_freq = evt->channel_freq; 18459 param->requester = evt->requestor; 18460 param->scan_id = evt->scan_id; 18461 param->vdev_id = evt->vdev_id; 18462 param->timestamp = evt->tsf_timestamp; 18463 18464 return QDF_STATUS_SUCCESS; 18465 } 18466 18467 #ifdef CONVERGED_TDLS_ENABLE 18468 /** 18469 * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event 18470 * @wmi_handle: wmi handle 18471 * @param evt_buf: pointer to event buffer 18472 * @param param: Pointer to hold vdev tdls param 18473 * 18474 * Return: QDF_STATUS_SUCCESS for success or error code 18475 */ 18476 static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle, 18477 void *evt_buf, struct tdls_event_info *param) 18478 { 18479 WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf; 18480 wmi_tdls_peer_event_fixed_param *evt; 18481 18482 param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf; 18483 if (!param_buf) { 18484 WMI_LOGE("%s: NULL param_buf", __func__); 18485 return QDF_STATUS_E_NULL_VALUE; 18486 } 18487 18488 evt = param_buf->fixed_param; 18489 18490 qdf_mem_zero(param, sizeof(*param)); 18491 18492 param->vdev_id = evt->vdev_id; 18493 WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr, 18494 param->peermac.bytes); 18495 switch (evt->peer_status) { 18496 case WMI_TDLS_SHOULD_DISCOVER: 18497 param->message_type = TDLS_SHOULD_DISCOVER; 18498 break; 18499 case WMI_TDLS_SHOULD_TEARDOWN: 18500 param->message_type = TDLS_SHOULD_TEARDOWN; 18501 break; 18502 case WMI_TDLS_PEER_DISCONNECTED: 18503 param->message_type = TDLS_PEER_DISCONNECTED; 18504 break; 18505 case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION: 18506 param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY; 18507 break; 18508 default: 18509 WMI_LOGE("%s: Discarding unknown tdls event %d from target", 18510 __func__, evt->peer_status); 18511 return QDF_STATUS_E_INVAL; 18512 }; 18513 18514 switch (evt->peer_reason) { 18515 case WMI_TDLS_TEARDOWN_REASON_TX: 18516 param->peer_reason = TDLS_TEARDOWN_TX; 18517 break; 18518 case WMI_TDLS_TEARDOWN_REASON_RSSI: 18519 param->peer_reason = TDLS_TEARDOWN_RSSI; 18520 break; 18521 case WMI_TDLS_TEARDOWN_REASON_SCAN: 18522 param->peer_reason = TDLS_TEARDOWN_SCAN; 18523 break; 18524 case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: 18525 param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE; 18526 break; 18527 case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: 18528 param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT; 18529 break; 18530 case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: 18531 param->peer_reason = TDLS_TEARDOWN_BAD_PTR; 18532 break; 18533 case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: 18534 param->peer_reason = TDLS_TEARDOWN_NO_RSP; 18535 break; 18536 case WMI_TDLS_ENTER_BUF_STA: 18537 param->peer_reason = TDLS_PEER_ENTER_BUF_STA; 18538 break; 18539 case WMI_TDLS_EXIT_BUF_STA: 18540 param->peer_reason = TDLS_PEER_EXIT_BUF_STA; 18541 break; 18542 case WMI_TDLS_ENTER_BT_BUSY_MODE: 18543 param->peer_reason = TDLS_ENTER_BT_BUSY; 18544 break; 18545 case WMI_TDLS_EXIT_BT_BUSY_MODE: 18546 param->peer_reason = TDLS_EXIT_BT_BUSY; 18547 break; 18548 case WMI_TDLS_SCAN_STARTED_EVENT: 18549 param->peer_reason = TDLS_SCAN_STARTED; 18550 break; 18551 case WMI_TDLS_SCAN_COMPLETED_EVENT: 18552 param->peer_reason = TDLS_SCAN_COMPLETED; 18553 break; 18554 18555 default: 18556 WMI_LOGE("%s: unknown reason %d in tdls event %d from target", 18557 __func__, evt->peer_reason, evt->peer_status); 18558 return QDF_STATUS_E_INVAL; 18559 }; 18560 18561 WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d", 18562 __func__, param->peermac.bytes, param->message_type, 18563 param->peer_reason, param->vdev_id); 18564 18565 return QDF_STATUS_SUCCESS; 18566 } 18567 #endif 18568 18569 /** 18570 * extract_mgmt_tx_compl_param_tlv() - extract MGMT tx completion event params 18571 * @wmi_handle: wmi handle 18572 * @param evt_buf: pointer to event buffer 18573 * @param param: Pointer to hold MGMT TX completion params 18574 * 18575 * Return: QDF_STATUS_SUCCESS for success or error code 18576 */ 18577 static QDF_STATUS extract_mgmt_tx_compl_param_tlv(wmi_unified_t wmi_handle, 18578 void *evt_buf, wmi_host_mgmt_tx_compl_event *param) 18579 { 18580 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18581 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; 18582 18583 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) 18584 evt_buf; 18585 if (!param_buf) { 18586 WMI_LOGE("%s: Invalid mgmt Tx completion event", __func__); 18587 return QDF_STATUS_E_INVAL; 18588 } 18589 cmpl_params = param_buf->fixed_param; 18590 18591 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18592 cmpl_params->pdev_id); 18593 param->desc_id = cmpl_params->desc_id; 18594 param->status = cmpl_params->status; 18595 param->ppdu_id = cmpl_params->ppdu_id; 18596 18597 return QDF_STATUS_SUCCESS; 18598 } 18599 18600 /** 18601 * extract_offchan_data_tx_compl_param_tlv() - 18602 * extract Offchan data tx completion event params 18603 * @wmi_handle: wmi handle 18604 * @param evt_buf: pointer to event buffer 18605 * @param param: Pointer to hold offchan data TX completion params 18606 * 18607 * Return: QDF_STATUS_SUCCESS for success or error code 18608 */ 18609 static QDF_STATUS extract_offchan_data_tx_compl_param_tlv( 18610 wmi_unified_t wmi_handle, void *evt_buf, 18611 struct wmi_host_offchan_data_tx_compl_event *param) 18612 { 18613 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *param_buf; 18614 wmi_offchan_data_tx_compl_event_fixed_param *cmpl_params; 18615 18616 param_buf = (WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID_param_tlvs *) 18617 evt_buf; 18618 if (!param_buf) { 18619 WMI_LOGE("%s: Invalid offchan data Tx compl event", __func__); 18620 return QDF_STATUS_E_INVAL; 18621 } 18622 cmpl_params = param_buf->fixed_param; 18623 18624 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18625 cmpl_params->pdev_id); 18626 param->desc_id = cmpl_params->desc_id; 18627 param->status = cmpl_params->status; 18628 18629 return QDF_STATUS_SUCCESS; 18630 } 18631 18632 /** 18633 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18634 * status tlv 18635 * @wmi_handle: wmi handle 18636 * @param evt_buf: pointer to event buffer 18637 * @param param: Pointer to hold csa switch count status event param 18638 * 18639 * Return: QDF_STATUS_SUCCESS for success or error code 18640 */ 18641 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18642 wmi_unified_t wmi_handle, 18643 void *evt_buf, 18644 struct pdev_csa_switch_count_status *param) 18645 { 18646 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18647 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18648 18649 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18650 evt_buf; 18651 if (!param_buf) { 18652 WMI_LOGE("%s: Invalid CSA status event\n", __func__); 18653 return QDF_STATUS_E_INVAL; 18654 } 18655 18656 csa_status = param_buf->fixed_param; 18657 18658 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18659 csa_status->pdev_id); 18660 param->current_switch_count = csa_status->current_switch_count; 18661 param->num_vdevs = csa_status->num_vdevs; 18662 param->vdev_ids = param_buf->vdev_ids; 18663 18664 return QDF_STATUS_SUCCESS; 18665 } 18666 18667 /** 18668 * extract_pdev_tpc_config_ev_param_tlv() - extract pdev tpc configuration 18669 * param from event 18670 * @wmi_handle: wmi handle 18671 * @param evt_buf: pointer to event buffer 18672 * @param param: Pointer to hold tpc configuration 18673 * 18674 * Return: 0 for success or error code 18675 */ 18676 static QDF_STATUS extract_pdev_tpc_config_ev_param_tlv(wmi_unified_t wmi_handle, 18677 void *evt_buf, 18678 wmi_host_pdev_tpc_config_event *param) 18679 { 18680 wmi_pdev_tpc_config_event_fixed_param *event = 18681 (wmi_pdev_tpc_config_event_fixed_param *)evt_buf; 18682 18683 if (!event) { 18684 WMI_LOGE("Invalid event buffer"); 18685 return QDF_STATUS_E_INVAL; 18686 } 18687 18688 param->pdev_id = event->pdev_id; 18689 param->regDomain = event->regDomain; 18690 param->chanFreq = event->chanFreq; 18691 param->phyMode = event->phyMode; 18692 param->twiceAntennaReduction = event->twiceAntennaReduction; 18693 param->twiceAntennaGain = event->twiceAntennaGain; 18694 param->twiceMaxRDPower = event->twiceMaxRDPower; 18695 param->powerLimit = event->powerLimit; 18696 param->rateMax = event->rateMax; 18697 param->numTxChain = event->numTxChain; 18698 param->ctl = event->ctl; 18699 param->flags = event->flags; 18700 18701 qdf_mem_copy(param->maxRegAllowedPower, event->maxRegAllowedPower, 18702 sizeof(param->maxRegAllowedPower)); 18703 qdf_mem_copy(param->maxRegAllowedPowerAGCDD, 18704 event->maxRegAllowedPowerAGCDD, 18705 sizeof(param->maxRegAllowedPowerAGCDD)); 18706 qdf_mem_copy(param->maxRegAllowedPowerAGSTBC, 18707 event->maxRegAllowedPowerAGSTBC, 18708 sizeof(param->maxRegAllowedPowerAGSTBC)); 18709 qdf_mem_copy(param->maxRegAllowedPowerAGTXBF, 18710 event->maxRegAllowedPowerAGTXBF, 18711 sizeof(param->maxRegAllowedPowerAGTXBF)); 18712 WMI_LOGD("%s:extract success", __func__); 18713 18714 return QDF_STATUS_SUCCESS; 18715 } 18716 18717 /** 18718 * extract_swba_num_vdevs_tlv() - extract swba num vdevs from event 18719 * @wmi_handle: wmi handle 18720 * @param evt_buf: pointer to event buffer 18721 * @param num_vdevs: Pointer to hold num vdevs 18722 * 18723 * Return: QDF_STATUS_SUCCESS for success or error code 18724 */ 18725 static QDF_STATUS extract_swba_num_vdevs_tlv(wmi_unified_t wmi_handle, 18726 void *evt_buf, uint32_t *num_vdevs) 18727 { 18728 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18729 wmi_host_swba_event_fixed_param *swba_event; 18730 uint32_t vdev_map; 18731 18732 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18733 if (!param_buf) { 18734 WMI_LOGE("Invalid swba event buffer"); 18735 return QDF_STATUS_E_INVAL; 18736 } 18737 18738 swba_event = param_buf->fixed_param; 18739 *num_vdevs = swba_event->num_vdevs; 18740 if (!(*num_vdevs)) { 18741 vdev_map = swba_event->vdev_map; 18742 *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map); 18743 } 18744 18745 return QDF_STATUS_SUCCESS; 18746 } 18747 18748 /** 18749 * extract_swba_tim_info_tlv() - extract swba tim info from event 18750 * @wmi_handle: wmi handle 18751 * @param evt_buf: pointer to event buffer 18752 * @param idx: Index to bcn info 18753 * @param tim_info: Pointer to hold tim info 18754 * 18755 * Return: QDF_STATUS_SUCCESS for success or error code 18756 */ 18757 static QDF_STATUS extract_swba_tim_info_tlv(wmi_unified_t wmi_handle, 18758 void *evt_buf, uint32_t idx, wmi_host_tim_info *tim_info) 18759 { 18760 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18761 wmi_tim_info *tim_info_ev; 18762 18763 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18764 if (!param_buf) { 18765 WMI_LOGE("Invalid swba event buffer"); 18766 return QDF_STATUS_E_INVAL; 18767 } 18768 18769 tim_info_ev = ¶m_buf->tim_info[idx]; 18770 18771 tim_info->tim_len = tim_info_ev->tim_len; 18772 tim_info->tim_mcast = tim_info_ev->tim_mcast; 18773 qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap, 18774 (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE)); 18775 tim_info->tim_changed = tim_info_ev->tim_changed; 18776 tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending; 18777 tim_info->vdev_id = tim_info_ev->vdev_id; 18778 18779 return QDF_STATUS_SUCCESS; 18780 } 18781 18782 /** 18783 * extract_swba_noa_info_tlv() - extract swba NoA information from event 18784 * @wmi_handle: wmi handle 18785 * @param evt_buf: pointer to event buffer 18786 * @param idx: Index to bcn info 18787 * @param p2p_desc: Pointer to hold p2p NoA info 18788 * 18789 * Return: QDF_STATUS_SUCCESS for success or error code 18790 */ 18791 static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, 18792 void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc) 18793 { 18794 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; 18795 wmi_p2p_noa_info *p2p_noa_info; 18796 uint8_t i = 0; 18797 18798 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) evt_buf; 18799 if (!param_buf) { 18800 WMI_LOGE("Invalid swba event buffer"); 18801 return QDF_STATUS_E_INVAL; 18802 } 18803 18804 p2p_noa_info = ¶m_buf->p2p_noa_info[idx]; 18805 18806 p2p_desc->modified = false; 18807 p2p_desc->num_descriptors = 0; 18808 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { 18809 p2p_desc->modified = true; 18810 p2p_desc->index = 18811 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); 18812 p2p_desc->oppPS = 18813 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); 18814 p2p_desc->ctwindow = 18815 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); 18816 p2p_desc->num_descriptors = 18817 (uint8_t) WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET 18818 (p2p_noa_info); 18819 for (i = 0; i < p2p_desc->num_descriptors; i++) { 18820 p2p_desc->noa_descriptors[i].type_count = 18821 (uint8_t) p2p_noa_info->noa_descriptors[i]. 18822 type_count; 18823 p2p_desc->noa_descriptors[i].duration = 18824 p2p_noa_info->noa_descriptors[i].duration; 18825 p2p_desc->noa_descriptors[i].interval = 18826 p2p_noa_info->noa_descriptors[i].interval; 18827 p2p_desc->noa_descriptors[i].start_time = 18828 p2p_noa_info->noa_descriptors[i].start_time; 18829 } 18830 p2p_desc->vdev_id = p2p_noa_info->vdev_id; 18831 } 18832 18833 return QDF_STATUS_SUCCESS; 18834 } 18835 18836 #ifdef CONVERGED_P2P_ENABLE 18837 /** 18838 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event 18839 * @wmi_handle: wmi handle 18840 * @param evt_buf: pointer to event buffer 18841 * @param param: Pointer to hold p2p noa info 18842 * 18843 * Return: QDF_STATUS_SUCCESS for success or error code 18844 */ 18845 static QDF_STATUS extract_p2p_noa_ev_param_tlv( 18846 wmi_unified_t wmi_handle, void *evt_buf, 18847 struct p2p_noa_info *param) 18848 { 18849 WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; 18850 wmi_p2p_noa_event_fixed_param *fixed_param; 18851 uint8_t i; 18852 wmi_p2p_noa_info *wmi_noa_info; 18853 uint8_t *buf_ptr; 18854 uint32_t descriptors; 18855 18856 param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; 18857 if (!param_tlvs) { 18858 WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); 18859 return QDF_STATUS_E_INVAL; 18860 } 18861 18862 if (!param) { 18863 WMI_LOGE("noa information param is null"); 18864 return QDF_STATUS_E_INVAL; 18865 } 18866 18867 fixed_param = param_tlvs->fixed_param; 18868 buf_ptr = (uint8_t *) fixed_param; 18869 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); 18870 wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); 18871 18872 if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { 18873 WMI_LOGE("%s: noa attr is not modified", __func__); 18874 return QDF_STATUS_E_INVAL; 18875 } 18876 18877 param->vdev_id = fixed_param->vdev_id; 18878 param->index = 18879 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); 18880 param->opps_ps = 18881 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); 18882 param->ct_window = 18883 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); 18884 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); 18885 param->num_desc = (uint8_t) descriptors; 18886 if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) { 18887 WMI_LOGE("%s: invalid num desc:%d", __func__, 18888 param->num_desc); 18889 return QDF_STATUS_E_INVAL; 18890 } 18891 18892 WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, 18893 param->index, param->opps_ps, param->ct_window, 18894 param->num_desc); 18895 for (i = 0; i < param->num_desc; i++) { 18896 param->noa_desc[i].type_count = 18897 (uint8_t) wmi_noa_info->noa_descriptors[i]. 18898 type_count; 18899 param->noa_desc[i].duration = 18900 wmi_noa_info->noa_descriptors[i].duration; 18901 param->noa_desc[i].interval = 18902 wmi_noa_info->noa_descriptors[i].interval; 18903 param->noa_desc[i].start_time = 18904 wmi_noa_info->noa_descriptors[i].start_time; 18905 WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", 18906 __func__, i, param->noa_desc[i].type_count, 18907 param->noa_desc[i].duration, 18908 param->noa_desc[i].interval, 18909 param->noa_desc[i].start_time); 18910 } 18911 18912 return QDF_STATUS_SUCCESS; 18913 } 18914 18915 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 18916 /** 18917 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop 18918 * information from event 18919 * @wmi_handle: wmi handle 18920 * @param evt_buf: pointer to event buffer 18921 * @param param: Pointer to hold p2p lo stop event information 18922 * 18923 * Return: QDF_STATUS_SUCCESS for success or error code 18924 */ 18925 static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( 18926 wmi_unified_t wmi_handle, void *evt_buf, 18927 struct p2p_lo_event *param) 18928 { 18929 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; 18930 wmi_p2p_lo_stopped_event_fixed_param *lo_param; 18931 18932 param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) 18933 evt_buf; 18934 if (!param_tlvs) { 18935 WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); 18936 return QDF_STATUS_E_INVAL; 18937 } 18938 18939 if (!param) { 18940 WMI_LOGE("lo stop event param is null"); 18941 return QDF_STATUS_E_INVAL; 18942 } 18943 18944 lo_param = param_tlvs->fixed_param; 18945 param->vdev_id = lo_param->vdev_id; 18946 param->reason_code = lo_param->reason; 18947 WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, 18948 param->vdev_id, param->reason_code); 18949 18950 return QDF_STATUS_SUCCESS; 18951 } 18952 #endif 18953 #endif /* End of CONVERGED_P2P_ENABLE */ 18954 18955 /** 18956 * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event 18957 * @wmi_handle: wmi handle 18958 * @param evt_buf: pointer to event buffer 18959 * @param ev: Pointer to hold peer param 18960 * 18961 * Return: QDF_STATUS_SUCCESS for success or error code 18962 */ 18963 static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle, 18964 void *evt_buf, wmi_host_peer_sta_kickout_event *ev) 18965 { 18966 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; 18967 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; 18968 18969 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) evt_buf; 18970 kickout_event = param_buf->fixed_param; 18971 18972 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, 18973 ev->peer_macaddr); 18974 18975 ev->reason = kickout_event->reason; 18976 ev->rssi = kickout_event->rssi; 18977 18978 return QDF_STATUS_SUCCESS; 18979 } 18980 18981 /** 18982 * extract_all_stats_counts_tlv() - extract all stats count from event 18983 * @wmi_handle: wmi handle 18984 * @param evt_buf: pointer to event buffer 18985 * @param stats_param: Pointer to hold stats count 18986 * 18987 * Return: QDF_STATUS_SUCCESS for success or error code 18988 */ 18989 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 18990 void *evt_buf, wmi_host_stats_event *stats_param) 18991 { 18992 wmi_stats_event_fixed_param *ev; 18993 wmi_per_chain_rssi_stats *rssi_event; 18994 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18995 uint64_t min_data_len; 18996 18997 qdf_mem_zero(stats_param, sizeof(*stats_param)); 18998 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 18999 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19000 rssi_event = param_buf->chain_stats; 19001 if (!ev) { 19002 WMI_LOGE("%s: event fixed param NULL\n", __func__); 19003 return QDF_STATUS_E_FAILURE; 19004 } 19005 19006 if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) { 19007 WMI_LOGE("num_data : %u is invalid", param_buf->num_data); 19008 return QDF_STATUS_E_FAULT; 19009 } 19010 19011 switch (ev->stats_id) { 19012 case WMI_REQUEST_PEER_STAT: 19013 stats_param->stats_id = WMI_HOST_REQUEST_PEER_STAT; 19014 break; 19015 19016 case WMI_REQUEST_AP_STAT: 19017 stats_param->stats_id = WMI_HOST_REQUEST_AP_STAT; 19018 break; 19019 19020 case WMI_REQUEST_PDEV_STAT: 19021 stats_param->stats_id = WMI_HOST_REQUEST_PDEV_STAT; 19022 break; 19023 19024 case WMI_REQUEST_VDEV_STAT: 19025 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_STAT; 19026 break; 19027 19028 case WMI_REQUEST_BCNFLT_STAT: 19029 stats_param->stats_id = WMI_HOST_REQUEST_BCNFLT_STAT; 19030 break; 19031 19032 case WMI_REQUEST_VDEV_RATE_STAT: 19033 stats_param->stats_id = WMI_HOST_REQUEST_VDEV_RATE_STAT; 19034 break; 19035 19036 case WMI_REQUEST_BCN_STAT: 19037 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 19038 break; 19039 19040 default: 19041 stats_param->stats_id = 0; 19042 break; 19043 19044 } 19045 19046 /* ev->num_*_stats may cause uint32_t overflow, so use uint64_t 19047 * to save total length calculated 19048 */ 19049 min_data_len = 19050 (((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19051 (((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19052 (((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) + 19053 (((uint64_t)ev->num_bcnflt_stats) * 19054 sizeof(wmi_bcnfilter_stats_t)) + 19055 (((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) + 19056 (((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) + 19057 (((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) + 19058 (((uint64_t)ev->num_peer_extd_stats) * 19059 sizeof(wmi_peer_extd_stats)); 19060 if (param_buf->num_data != min_data_len) { 19061 WMI_LOGE("data len: %u isn't same as calculated: %llu", 19062 param_buf->num_data, min_data_len); 19063 return QDF_STATUS_E_FAULT; 19064 } 19065 19066 stats_param->num_pdev_stats = ev->num_pdev_stats; 19067 stats_param->num_pdev_ext_stats = 0; 19068 stats_param->num_vdev_stats = ev->num_vdev_stats; 19069 stats_param->num_peer_stats = ev->num_peer_stats; 19070 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 19071 stats_param->num_chan_stats = ev->num_chan_stats; 19072 stats_param->num_bcn_stats = ev->num_bcn_stats; 19073 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19074 ev->pdev_id); 19075 19076 /* if chain_stats is not populated */ 19077 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 19078 return QDF_STATUS_SUCCESS; 19079 19080 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 19081 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 19082 return QDF_STATUS_SUCCESS; 19083 19084 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 19085 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 19086 return QDF_STATUS_SUCCESS; 19087 19088 if (rssi_event->num_per_chain_rssi_stats >= 19089 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) { 19090 WMI_LOGE("num_per_chain_rssi_stats:%u is out of bounds", 19091 rssi_event->num_per_chain_rssi_stats); 19092 return QDF_STATUS_E_INVAL; 19093 } 19094 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 19095 19096 return QDF_STATUS_SUCCESS; 19097 } 19098 19099 /** 19100 * extract_pdev_tx_stats() - extract pdev tx stats from event 19101 */ 19102 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, struct wlan_dbg_tx_stats *tx_stats) 19103 { 19104 /* Tx Stats */ 19105 tx->comp_queued = tx_stats->comp_queued; 19106 tx->comp_delivered = tx_stats->comp_delivered; 19107 tx->msdu_enqued = tx_stats->msdu_enqued; 19108 tx->mpdu_enqued = tx_stats->mpdu_enqued; 19109 tx->wmm_drop = tx_stats->wmm_drop; 19110 tx->local_enqued = tx_stats->local_enqued; 19111 tx->local_freed = tx_stats->local_freed; 19112 tx->hw_queued = tx_stats->hw_queued; 19113 tx->hw_reaped = tx_stats->hw_reaped; 19114 tx->underrun = tx_stats->underrun; 19115 tx->tx_abort = tx_stats->tx_abort; 19116 tx->mpdus_requed = tx_stats->mpdus_requed; 19117 tx->data_rc = tx_stats->data_rc; 19118 tx->self_triggers = tx_stats->self_triggers; 19119 tx->sw_retry_failure = tx_stats->sw_retry_failure; 19120 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 19121 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 19122 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 19123 tx->pdev_resets = tx_stats->pdev_resets; 19124 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 19125 tx->phy_underrun = tx_stats->phy_underrun; 19126 tx->txop_ovf = tx_stats->txop_ovf; 19127 19128 return; 19129 } 19130 19131 19132 /** 19133 * extract_pdev_rx_stats() - extract pdev rx stats from event 19134 */ 19135 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, struct wlan_dbg_rx_stats *rx_stats) 19136 { 19137 /* Rx Stats */ 19138 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 19139 rx->status_rcvd = rx_stats->status_rcvd; 19140 rx->r0_frags = rx_stats->r0_frags; 19141 rx->r1_frags = rx_stats->r1_frags; 19142 rx->r2_frags = rx_stats->r2_frags; 19143 /* Only TLV */ 19144 rx->r3_frags = 0; 19145 rx->htt_msdus = rx_stats->htt_msdus; 19146 rx->htt_mpdus = rx_stats->htt_mpdus; 19147 rx->loc_msdus = rx_stats->loc_msdus; 19148 rx->loc_mpdus = rx_stats->loc_mpdus; 19149 rx->oversize_amsdu = rx_stats->oversize_amsdu; 19150 rx->phy_errs = rx_stats->phy_errs; 19151 rx->phy_err_drop = rx_stats->phy_err_drop; 19152 rx->mpdu_errs = rx_stats->mpdu_errs; 19153 19154 return; 19155 } 19156 19157 /** 19158 * extract_pdev_stats_tlv() - extract pdev stats from event 19159 * @wmi_handle: wmi handle 19160 * @param evt_buf: pointer to event buffer 19161 * @param index: Index into pdev stats 19162 * @param pdev_stats: Pointer to hold pdev stats 19163 * 19164 * Return: QDF_STATUS_SUCCESS for success or error code 19165 */ 19166 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 19167 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 19168 { 19169 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19170 wmi_stats_event_fixed_param *ev_param; 19171 uint8_t *data; 19172 19173 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19174 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19175 19176 data = param_buf->data; 19177 19178 if (index < ev_param->num_pdev_stats) { 19179 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 19180 (index * sizeof(wmi_pdev_stats))); 19181 19182 pdev_stats->chan_nf = ev->chan_nf; 19183 pdev_stats->tx_frame_count = ev->tx_frame_count; 19184 pdev_stats->rx_frame_count = ev->rx_frame_count; 19185 pdev_stats->rx_clear_count = ev->rx_clear_count; 19186 pdev_stats->cycle_count = ev->cycle_count; 19187 pdev_stats->phy_err_count = ev->phy_err_count; 19188 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 19189 19190 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 19191 &(ev->pdev_stats.tx)); 19192 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 19193 &(ev->pdev_stats.rx)); 19194 } 19195 19196 return QDF_STATUS_SUCCESS; 19197 } 19198 19199 /** 19200 * extract_unit_test_tlv() - extract unit test data 19201 * @wmi_handle: wmi handle 19202 * @param evt_buf: pointer to event buffer 19203 * @param unit_test: pointer to hold unit test data 19204 * @param maxspace: Amount of space in evt_buf 19205 * 19206 * Return: QDF_STATUS_SUCCESS for success or error code 19207 */ 19208 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 19209 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 19210 { 19211 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 19212 wmi_unit_test_event_fixed_param *ev_param; 19213 uint32_t num_bufp; 19214 uint32_t copy_size; 19215 uint8_t *bufp; 19216 19217 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 19218 ev_param = param_buf->fixed_param; 19219 bufp = param_buf->bufp; 19220 num_bufp = param_buf->num_bufp; 19221 unit_test->vdev_id = ev_param->vdev_id; 19222 unit_test->module_id = ev_param->module_id; 19223 unit_test->diag_token = ev_param->diag_token; 19224 unit_test->flag = ev_param->flag; 19225 unit_test->payload_len = ev_param->payload_len; 19226 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d\n", __func__, 19227 ev_param->vdev_id, 19228 ev_param->module_id, 19229 ev_param->diag_token, 19230 ev_param->flag); 19231 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 19232 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 19233 bufp, num_bufp); 19234 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 19235 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 19236 unit_test->buffer_len = copy_size; 19237 19238 return QDF_STATUS_SUCCESS; 19239 } 19240 19241 /** 19242 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 19243 * @wmi_handle: wmi handle 19244 * @param evt_buf: pointer to event buffer 19245 * @param index: Index into extended pdev stats 19246 * @param pdev_ext_stats: Pointer to hold extended pdev stats 19247 * 19248 * Return: QDF_STATUS_SUCCESS for success or error code 19249 */ 19250 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 19251 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 19252 { 19253 return QDF_STATUS_SUCCESS; 19254 } 19255 19256 /** 19257 * extract_vdev_stats_tlv() - extract vdev stats from event 19258 * @wmi_handle: wmi handle 19259 * @param evt_buf: pointer to event buffer 19260 * @param index: Index into vdev stats 19261 * @param vdev_stats: Pointer to hold vdev stats 19262 * 19263 * Return: QDF_STATUS_SUCCESS for success or error code 19264 */ 19265 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 19266 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 19267 { 19268 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19269 wmi_stats_event_fixed_param *ev_param; 19270 uint8_t *data; 19271 19272 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19273 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19274 data = (uint8_t *) param_buf->data; 19275 19276 if (index < ev_param->num_vdev_stats) { 19277 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 19278 ((ev_param->num_pdev_stats) * 19279 sizeof(wmi_pdev_stats)) + 19280 (index * sizeof(wmi_vdev_stats))); 19281 19282 vdev_stats->vdev_id = ev->vdev_id; 19283 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 19284 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 19285 19286 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 19287 sizeof(ev->tx_frm_cnt)); 19288 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 19289 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 19290 ev->multiple_retry_cnt, 19291 sizeof(ev->multiple_retry_cnt)); 19292 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 19293 sizeof(ev->fail_cnt)); 19294 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 19295 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 19296 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 19297 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 19298 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 19299 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 19300 sizeof(ev->tx_rate_history)); 19301 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 19302 sizeof(ev->bcn_rssi_history)); 19303 19304 } 19305 19306 return QDF_STATUS_SUCCESS; 19307 } 19308 19309 /** 19310 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 19311 * buffer 19312 * @wmi_handle: wmi handle 19313 * @evt_buf: pointer to event buffer 19314 * @index: Index into vdev stats 19315 * @rssi_stats: Pointer to hold rssi stats 19316 * 19317 * Return: QDF_STATUS_SUCCESS for success or error code 19318 */ 19319 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 19320 void *evt_buf, uint32_t index, 19321 struct wmi_host_per_chain_rssi_stats *rssi_stats) 19322 { 19323 uint8_t *data; 19324 wmi_rssi_stats *fw_rssi_stats; 19325 wmi_per_chain_rssi_stats *rssi_event; 19326 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19327 19328 if (!evt_buf) { 19329 WMI_LOGE("evt_buf is null"); 19330 return QDF_STATUS_E_NULL_VALUE; 19331 } 19332 19333 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19334 rssi_event = param_buf->chain_stats; 19335 19336 if (index >= rssi_event->num_per_chain_rssi_stats) { 19337 WMI_LOGE("invalid index"); 19338 return QDF_STATUS_E_INVAL; 19339 } 19340 19341 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 19342 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 19343 19344 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 19345 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 19346 fw_rssi_stats->rssi_avg_beacon, 19347 sizeof(fw_rssi_stats->rssi_avg_beacon)); 19348 qdf_mem_copy(rssi_stats->rssi_avg_data, 19349 fw_rssi_stats->rssi_avg_data, 19350 sizeof(fw_rssi_stats->rssi_avg_data)); 19351 qdf_mem_copy(&rssi_stats->peer_macaddr, 19352 &fw_rssi_stats->peer_macaddr, 19353 sizeof(fw_rssi_stats->peer_macaddr)); 19354 19355 return QDF_STATUS_SUCCESS; 19356 } 19357 19358 19359 19360 /** 19361 * extract_bcn_stats_tlv() - extract bcn stats from event 19362 * @wmi_handle: wmi handle 19363 * @param evt_buf: pointer to event buffer 19364 * @param index: Index into vdev stats 19365 * @param bcn_stats: Pointer to hold bcn stats 19366 * 19367 * Return: QDF_STATUS_SUCCESS for success or error code 19368 */ 19369 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 19370 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 19371 { 19372 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19373 wmi_stats_event_fixed_param *ev_param; 19374 uint8_t *data; 19375 19376 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19377 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19378 data = (uint8_t *) param_buf->data; 19379 19380 if (index < ev_param->num_bcn_stats) { 19381 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 19382 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19383 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19384 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19385 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 19386 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 19387 (index * sizeof(wmi_bcn_stats))); 19388 19389 bcn_stats->vdev_id = ev->vdev_id; 19390 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 19391 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 19392 } 19393 19394 return QDF_STATUS_SUCCESS; 19395 } 19396 19397 /** 19398 * extract_peer_stats_tlv() - extract peer stats from event 19399 * @wmi_handle: wmi handle 19400 * @param evt_buf: pointer to event buffer 19401 * @param index: Index into peer stats 19402 * @param peer_stats: Pointer to hold peer stats 19403 * 19404 * Return: QDF_STATUS_SUCCESS for success or error code 19405 */ 19406 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 19407 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 19408 { 19409 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19410 wmi_stats_event_fixed_param *ev_param; 19411 uint8_t *data; 19412 19413 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19414 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19415 data = (uint8_t *) param_buf->data; 19416 19417 if (index < ev_param->num_peer_stats) { 19418 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 19419 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19420 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19421 (index * sizeof(wmi_peer_stats))); 19422 19423 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 19424 19425 OS_MEMCPY(&(peer_stats->peer_macaddr), 19426 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 19427 19428 peer_stats->peer_rssi = ev->peer_rssi; 19429 peer_stats->peer_tx_rate = ev->peer_tx_rate; 19430 peer_stats->peer_rx_rate = ev->peer_rx_rate; 19431 } 19432 19433 return QDF_STATUS_SUCCESS; 19434 } 19435 19436 /** 19437 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 19438 * @wmi_handle: wmi handle 19439 * @param evt_buf: pointer to event buffer 19440 * @param index: Index into bcn fault stats 19441 * @param bcnflt_stats: Pointer to hold bcn fault stats 19442 * 19443 * Return: QDF_STATUS_SUCCESS for success or error code 19444 */ 19445 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 19446 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 19447 { 19448 return QDF_STATUS_SUCCESS; 19449 } 19450 19451 /** 19452 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 19453 * @wmi_handle: wmi handle 19454 * @param evt_buf: pointer to event buffer 19455 * @param index: Index into extended peer stats 19456 * @param peer_extd_stats: Pointer to hold extended peer stats 19457 * 19458 * Return: QDF_STATUS_SUCCESS for success or error code 19459 */ 19460 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 19461 void *evt_buf, uint32_t index, 19462 wmi_host_peer_extd_stats *peer_extd_stats) 19463 { 19464 return QDF_STATUS_SUCCESS; 19465 } 19466 19467 /** 19468 * extract_chan_stats_tlv() - extract chan stats from event 19469 * @wmi_handle: wmi handle 19470 * @param evt_buf: pointer to event buffer 19471 * @param index: Index into chan stats 19472 * @param vdev_extd_stats: Pointer to hold chan stats 19473 * 19474 * Return: QDF_STATUS_SUCCESS for success or error code 19475 */ 19476 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 19477 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 19478 { 19479 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19480 wmi_stats_event_fixed_param *ev_param; 19481 uint8_t *data; 19482 19483 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 19484 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 19485 data = (uint8_t *) param_buf->data; 19486 19487 if (index < ev_param->num_chan_stats) { 19488 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 19489 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 19490 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 19491 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 19492 (index * sizeof(wmi_chan_stats))); 19493 19494 19495 /* Non-TLV doesn't have num_chan_stats */ 19496 chan_stats->chan_mhz = ev->chan_mhz; 19497 chan_stats->sampling_period_us = ev->sampling_period_us; 19498 chan_stats->rx_clear_count = ev->rx_clear_count; 19499 chan_stats->tx_duration_us = ev->tx_duration_us; 19500 chan_stats->rx_duration_us = ev->rx_duration_us; 19501 } 19502 19503 return QDF_STATUS_SUCCESS; 19504 } 19505 19506 /** 19507 * extract_profile_ctx_tlv() - extract profile context from event 19508 * @wmi_handle: wmi handle 19509 * @param evt_buf: pointer to event buffer 19510 * @idx: profile stats index to extract 19511 * @param profile_ctx: Pointer to hold profile context 19512 * 19513 * Return: QDF_STATUS_SUCCESS for success or error code 19514 */ 19515 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 19516 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 19517 { 19518 return QDF_STATUS_SUCCESS; 19519 } 19520 19521 /** 19522 * extract_profile_data_tlv() - extract profile data from event 19523 * @wmi_handle: wmi handle 19524 * @param evt_buf: pointer to event buffer 19525 * @param profile_data: Pointer to hold profile data 19526 * 19527 * Return: QDF_STATUS_SUCCESS for success or error code 19528 */ 19529 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 19530 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 19531 { 19532 19533 return QDF_STATUS_SUCCESS; 19534 } 19535 19536 /** 19537 * extract_chan_info_event_tlv() - extract chan information from event 19538 * @wmi_handle: wmi handle 19539 * @param evt_buf: pointer to event buffer 19540 * @param chan_info: Pointer to hold chan information 19541 * 19542 * Return: QDF_STATUS_SUCCESS for success or error code 19543 */ 19544 static QDF_STATUS extract_chan_info_event_tlv(wmi_unified_t wmi_handle, 19545 void *evt_buf, wmi_host_chan_info_event *chan_info) 19546 { 19547 WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; 19548 wmi_chan_info_event_fixed_param *ev; 19549 19550 param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) evt_buf; 19551 19552 ev = (wmi_chan_info_event_fixed_param *) param_buf->fixed_param; 19553 if (!ev) { 19554 WMI_LOGE("%s: Failed to allocmemory\n", __func__); 19555 return QDF_STATUS_E_FAILURE; 19556 } 19557 19558 chan_info->err_code = ev->err_code; 19559 chan_info->freq = ev->freq; 19560 chan_info->cmd_flags = ev->cmd_flags; 19561 chan_info->noise_floor = ev->noise_floor; 19562 chan_info->rx_clear_count = ev->rx_clear_count; 19563 chan_info->cycle_count = ev->cycle_count; 19564 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19565 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19566 chan_info->pdev_id = wlan_get_pdev_id_from_vdev_id( 19567 (struct wlan_objmgr_psoc *)wmi_handle->soc->wmi_psoc, 19568 ev->vdev_id, WLAN_SCAN_ID); 19569 chan_info->chan_tx_pwr_range = ev->chan_tx_pwr_range; 19570 chan_info->chan_tx_pwr_tp = ev->chan_tx_pwr_tp; 19571 chan_info->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 19572 chan_info->rx_11b_mode_data_duration = ev->rx_11b_mode_data_duration; 19573 chan_info->tx_frame_cnt = ev->tx_frame_cnt; 19574 chan_info->rx_frame_count = ev->rx_frame_count; 19575 chan_info->mac_clk_mhz = ev->mac_clk_mhz; 19576 chan_info->vdev_id = ev->vdev_id; 19577 19578 return QDF_STATUS_SUCCESS; 19579 } 19580 19581 /** 19582 * extract_pdev_utf_event_tlv() - extract UTF data info from event 19583 * @wmi_handle: WMI handle 19584 * @param evt_buf: Pointer to event buffer 19585 * @param param: Pointer to hold data 19586 * 19587 * Return : QDF_STATUS_SUCCESS for success or error code 19588 */ 19589 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 19590 uint8_t *evt_buf, 19591 struct wmi_host_pdev_utf_event *event) 19592 { 19593 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 19594 struct wmi_host_utf_seg_header_info *seg_hdr; 19595 19596 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 19597 event->data = param_buf->data; 19598 event->datalen = param_buf->num_data; 19599 19600 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 19601 WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen); 19602 return QDF_STATUS_E_INVAL; 19603 } 19604 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 19605 /* Set pdev_id=1 until FW adds support to include pdev_id */ 19606 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19607 seg_hdr->pdev_id); 19608 19609 return QDF_STATUS_SUCCESS; 19610 } 19611 19612 /** 19613 * extract_chainmask_tables_tlv() - extract chain mask tables from event 19614 * @wmi_handle: wmi handle 19615 * @param evt_buf: pointer to event buffer 19616 * @param param: Pointer to hold evt buf 19617 * 19618 * Return: QDF_STATUS_SUCCESS for success or error code 19619 */ 19620 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 19621 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 19622 { 19623 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19624 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 19625 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19626 uint8_t i = 0, j = 0; 19627 19628 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19629 if (!param_buf) 19630 return QDF_STATUS_E_INVAL; 19631 19632 hw_caps = param_buf->soc_hw_mode_caps; 19633 if (!hw_caps) 19634 return QDF_STATUS_E_INVAL; 19635 19636 if (!hw_caps->num_chainmask_tables) 19637 return QDF_STATUS_E_INVAL; 19638 19639 chainmask_caps = param_buf->mac_phy_chainmask_caps; 19640 19641 if (chainmask_caps == NULL) 19642 return QDF_STATUS_E_INVAL; 19643 19644 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 19645 19646 qdf_print("Dumping chain mask combo data for table : %d", i); 19647 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 19648 19649 chainmask_table[i].cap_list[j].chainmask = 19650 chainmask_caps->chainmask; 19651 19652 chainmask_table[i].cap_list[j].supports_chan_width_20 = 19653 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 19654 19655 chainmask_table[i].cap_list[j].supports_chan_width_40 = 19656 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 19657 19658 chainmask_table[i].cap_list[j].supports_chan_width_80 = 19659 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 19660 19661 chainmask_table[i].cap_list[j].supports_chan_width_160 = 19662 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 19663 19664 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 19665 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 19666 19667 chainmask_table[i].cap_list[j].chain_mask_2G = 19668 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 19669 19670 chainmask_table[i].cap_list[j].chain_mask_5G = 19671 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 19672 19673 chainmask_table[i].cap_list[j].chain_mask_tx = 19674 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 19675 19676 chainmask_table[i].cap_list[j].chain_mask_rx = 19677 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 19678 19679 chainmask_table[i].cap_list[j].supports_aDFS = 19680 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 19681 19682 qdf_print("supported_flags: 0x%08x chainmasks: 0x%08x", 19683 chainmask_caps->supported_flags, 19684 chainmask_caps->chainmask 19685 ); 19686 chainmask_caps++; 19687 } 19688 } 19689 19690 return QDF_STATUS_SUCCESS; 19691 } 19692 19693 /** 19694 * extract_service_ready_ext_tlv() - extract basic extended service ready params 19695 * from event 19696 * @wmi_handle: wmi handle 19697 * @param evt_buf: pointer to event buffer 19698 * @param param: Pointer to hold evt buf 19699 * 19700 * Return: QDF_STATUS_SUCCESS for success or error code 19701 */ 19702 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 19703 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 19704 { 19705 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19706 wmi_service_ready_ext_event_fixed_param *ev; 19707 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19708 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19709 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 19710 uint8_t i = 0; 19711 19712 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19713 if (!param_buf) 19714 return QDF_STATUS_E_INVAL; 19715 19716 ev = param_buf->fixed_param; 19717 if (!ev) 19718 return QDF_STATUS_E_INVAL; 19719 19720 /* Move this to host based bitmap */ 19721 param->default_conc_scan_config_bits = 19722 ev->default_conc_scan_config_bits; 19723 param->default_fw_config_bits = ev->default_fw_config_bits; 19724 param->he_cap_info = ev->he_cap_info; 19725 param->mpdu_density = ev->mpdu_density; 19726 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 19727 param->fw_build_vers_ext = ev->fw_build_vers_ext; 19728 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 19729 param->max_bssid_indicator = ev->max_bssid_indicator; 19730 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 19731 19732 hw_caps = param_buf->soc_hw_mode_caps; 19733 if (hw_caps) 19734 param->num_hw_modes = hw_caps->num_hw_modes; 19735 else 19736 param->num_hw_modes = 0; 19737 19738 reg_caps = param_buf->soc_hal_reg_caps; 19739 if (reg_caps) 19740 param->num_phy = reg_caps->num_phy; 19741 else 19742 param->num_phy = 0; 19743 19744 if (hw_caps) { 19745 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 19746 qdf_print("Num chain mask tables: %d", hw_caps->num_chainmask_tables); 19747 } else 19748 param->num_chainmask_tables = 0; 19749 19750 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 19751 19752 if (chain_mask_combo == NULL) 19753 return QDF_STATUS_SUCCESS; 19754 19755 qdf_print("Dumping chain mask combo data"); 19756 19757 for (i = 0; i < param->num_chainmask_tables; i++) { 19758 19759 qdf_print("table_id : %d Num valid chainmasks: %d", 19760 chain_mask_combo->chainmask_table_id, 19761 chain_mask_combo->num_valid_chainmask 19762 ); 19763 19764 param->chainmask_table[i].table_id = 19765 chain_mask_combo->chainmask_table_id; 19766 param->chainmask_table[i].num_valid_chainmasks = 19767 chain_mask_combo->num_valid_chainmask; 19768 chain_mask_combo++; 19769 } 19770 qdf_print("chain mask combo end"); 19771 19772 return QDF_STATUS_SUCCESS; 19773 } 19774 19775 /** 19776 * extract_sar_cap_service_ready_ext_tlv() - 19777 * extract SAR cap from service ready event 19778 * @wmi_handle: wmi handle 19779 * @event: pointer to event buffer 19780 * @ext_param: extended target info 19781 * 19782 * Return: QDF_STATUS_SUCCESS for success or error code 19783 */ 19784 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 19785 wmi_unified_t wmi_handle, 19786 uint8_t *event, 19787 struct wlan_psoc_host_service_ext_param *ext_param) 19788 { 19789 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19790 WMI_SAR_CAPABILITIES *sar_caps; 19791 19792 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 19793 19794 if (!param_buf) 19795 return QDF_STATUS_E_INVAL; 19796 19797 sar_caps = param_buf->sar_caps; 19798 if (sar_caps) 19799 ext_param->sar_version = sar_caps->active_version; 19800 else 19801 ext_param->sar_version = 0; 19802 19803 return QDF_STATUS_SUCCESS; 19804 } 19805 19806 /** 19807 * extract_hw_mode_cap_service_ready_ext_tlv() - 19808 * extract HW mode cap from service ready event 19809 * @wmi_handle: wmi handle 19810 * @param evt_buf: pointer to event buffer 19811 * @param param: Pointer to hold evt buf 19812 * @param hw_mode_idx: hw mode idx should be less than num_mode 19813 * 19814 * Return: QDF_STATUS_SUCCESS for success or error code 19815 */ 19816 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 19817 wmi_unified_t wmi_handle, 19818 uint8_t *event, uint8_t hw_mode_idx, 19819 struct wlan_psoc_host_hw_mode_caps *param) 19820 { 19821 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19822 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19823 19824 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19825 if (!param_buf) 19826 return QDF_STATUS_E_INVAL; 19827 19828 hw_caps = param_buf->soc_hw_mode_caps; 19829 if (!hw_caps) 19830 return QDF_STATUS_E_INVAL; 19831 19832 if (hw_mode_idx >= hw_caps->num_hw_modes) 19833 return QDF_STATUS_E_INVAL; 19834 19835 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 19836 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 19837 19838 param->hw_mode_config_type = 19839 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 19840 19841 return QDF_STATUS_SUCCESS; 19842 } 19843 19844 /** 19845 * extract_mac_phy_cap_service_ready_ext_tlv() - 19846 * extract MAC phy cap from service ready event 19847 * @wmi_handle: wmi handle 19848 * @param evt_buf: pointer to event buffer 19849 * @param param: Pointer to hold evt buf 19850 * @param hw_mode_idx: hw mode idx should be less than num_mode 19851 * @param phy_id: phy id within hw_mode 19852 * 19853 * Return: QDF_STATUS_SUCCESS for success or error code 19854 */ 19855 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 19856 wmi_unified_t wmi_handle, 19857 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 19858 struct wlan_psoc_host_mac_phy_caps *param) 19859 { 19860 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19861 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 19862 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 19863 uint32_t phy_map; 19864 uint8_t hw_idx, phy_idx = 0; 19865 19866 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19867 if (!param_buf) 19868 return QDF_STATUS_E_INVAL; 19869 19870 hw_caps = param_buf->soc_hw_mode_caps; 19871 if (!hw_caps) 19872 return QDF_STATUS_E_INVAL; 19873 19874 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 19875 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 19876 break; 19877 19878 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 19879 while (phy_map) { 19880 phy_map >>= 1; 19881 phy_idx++; 19882 } 19883 } 19884 19885 if (hw_idx == hw_caps->num_hw_modes) 19886 return QDF_STATUS_E_INVAL; 19887 19888 phy_idx += phy_id; 19889 if (phy_idx >= param_buf->num_mac_phy_caps) 19890 return QDF_STATUS_E_INVAL; 19891 19892 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 19893 19894 param->hw_mode_id = mac_phy_caps->hw_mode_id; 19895 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 19896 mac_phy_caps->pdev_id); 19897 param->phy_id = mac_phy_caps->phy_id; 19898 param->supports_11b = 19899 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 19900 param->supports_11g = 19901 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 19902 param->supports_11a = 19903 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 19904 param->supports_11n = 19905 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 19906 param->supports_11ac = 19907 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 19908 param->supports_11ax = 19909 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 19910 19911 param->supported_bands = mac_phy_caps->supported_bands; 19912 param->ampdu_density = mac_phy_caps->ampdu_density; 19913 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 19914 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 19915 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 19916 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 19917 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 19918 mac_phy_caps->he_cap_info_2G; 19919 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 19920 mac_phy_caps->he_cap_info_2G_ext; 19921 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 19922 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 19923 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 19924 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 19925 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 19926 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 19927 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 19928 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 19929 mac_phy_caps->he_cap_info_5G; 19930 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 19931 mac_phy_caps->he_cap_info_5G_ext; 19932 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 19933 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 19934 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 19935 qdf_mem_copy(¶m->he_cap_phy_info_2G, 19936 &mac_phy_caps->he_cap_phy_info_2G, 19937 sizeof(param->he_cap_phy_info_2G)); 19938 qdf_mem_copy(¶m->he_cap_phy_info_5G, 19939 &mac_phy_caps->he_cap_phy_info_5G, 19940 sizeof(param->he_cap_phy_info_5G)); 19941 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 19942 sizeof(param->he_ppet2G)); 19943 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 19944 sizeof(param->he_ppet5G)); 19945 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 19946 19947 return QDF_STATUS_SUCCESS; 19948 } 19949 19950 /** 19951 * extract_reg_cap_service_ready_ext_tlv() - 19952 * extract REG cap from service ready event 19953 * @wmi_handle: wmi handle 19954 * @param evt_buf: pointer to event buffer 19955 * @param param: Pointer to hold evt buf 19956 * @param phy_idx: phy idx should be less than num_mode 19957 * 19958 * Return: QDF_STATUS_SUCCESS for success or error code 19959 */ 19960 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 19961 wmi_unified_t wmi_handle, 19962 uint8_t *event, uint8_t phy_idx, 19963 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 19964 { 19965 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 19966 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 19967 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 19968 19969 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 19970 if (!param_buf) 19971 return QDF_STATUS_E_INVAL; 19972 19973 reg_caps = param_buf->soc_hal_reg_caps; 19974 if (!reg_caps) 19975 return QDF_STATUS_E_INVAL; 19976 19977 if (phy_idx >= reg_caps->num_phy) 19978 return QDF_STATUS_E_INVAL; 19979 19980 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 19981 19982 param->phy_id = ext_reg_cap->phy_id; 19983 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 19984 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 19985 param->regcap1 = ext_reg_cap->regcap1; 19986 param->regcap2 = ext_reg_cap->regcap2; 19987 param->wireless_modes = convert_wireless_modes_tlv( 19988 ext_reg_cap->wireless_modes); 19989 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 19990 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 19991 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 19992 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 19993 19994 return QDF_STATUS_SUCCESS; 19995 } 19996 19997 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 19998 wmi_unified_t wmi_handle, 19999 uint8_t *event, uint8_t idx, 20000 struct wlan_psoc_host_dbr_ring_caps *param) 20001 { 20002 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 20003 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps; 20004 20005 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 20006 if (!param_buf) 20007 return QDF_STATUS_E_INVAL; 20008 20009 dbr_ring_caps = ¶m_buf->dma_ring_caps[idx]; 20010 20011 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20012 dbr_ring_caps->pdev_id); 20013 param->mod_id = dbr_ring_caps->mod_id; 20014 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 20015 param->min_buf_size = dbr_ring_caps->min_buf_size; 20016 param->min_buf_align = dbr_ring_caps->min_buf_align; 20017 20018 return QDF_STATUS_SUCCESS; 20019 } 20020 20021 static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, 20022 uint8_t *event, struct direct_buf_rx_rsp *param) 20023 { 20024 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20025 wmi_dma_buf_release_fixed_param *ev; 20026 20027 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20028 if (!param_buf) 20029 return QDF_STATUS_E_INVAL; 20030 20031 ev = param_buf->fixed_param; 20032 if (!ev) 20033 return QDF_STATUS_E_INVAL; 20034 20035 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20036 ev->pdev_id); 20037 param->mod_id = ev->mod_id; 20038 param->num_buf_release_entry = ev->num_buf_release_entry; 20039 param->num_meta_data_entry = ev->num_meta_data_entry; 20040 WMI_LOGD("%s:pdev id %d mod id %d num buf release entry %d\n", __func__, 20041 param->pdev_id, param->mod_id, param->num_buf_release_entry); 20042 20043 return QDF_STATUS_SUCCESS; 20044 } 20045 20046 static QDF_STATUS extract_dbr_buf_release_entry_tlv(wmi_unified_t wmi_handle, 20047 uint8_t *event, uint8_t idx, struct direct_buf_rx_entry *param) 20048 { 20049 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20050 wmi_dma_buf_release_entry *entry; 20051 20052 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20053 if (!param_buf) 20054 return QDF_STATUS_E_INVAL; 20055 20056 entry = ¶m_buf->entries[idx]; 20057 20058 if (!entry) { 20059 WMI_LOGE("%s: Entry is NULL\n", __func__); 20060 return QDF_STATUS_E_FAILURE; 20061 } 20062 20063 WMI_LOGD("%s: paddr_lo[%d] = %x\n", __func__, idx, entry->paddr_lo); 20064 20065 param->paddr_lo = entry->paddr_lo; 20066 param->paddr_hi = entry->paddr_hi; 20067 20068 return QDF_STATUS_SUCCESS; 20069 } 20070 20071 static QDF_STATUS extract_dbr_buf_metadata_tlv( 20072 wmi_unified_t wmi_handle, uint8_t *event, 20073 uint8_t idx, struct direct_buf_rx_metadata *param) 20074 { 20075 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; 20076 wmi_dma_buf_release_spectral_meta_data *entry; 20077 20078 param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; 20079 if (!param_buf) 20080 return QDF_STATUS_E_INVAL; 20081 20082 entry = ¶m_buf->meta_data[idx]; 20083 20084 if (!entry) { 20085 WMI_LOGE("%s: Entry is NULL\n", __func__); 20086 return QDF_STATUS_E_FAILURE; 20087 } 20088 20089 qdf_mem_copy(param->noisefloor, entry->noise_floor, 20090 sizeof(entry->noise_floor)); 20091 return QDF_STATUS_SUCCESS; 20092 } 20093 20094 /** 20095 * extract_dcs_interference_type_tlv() - extract dcs interference type 20096 * from event 20097 * @wmi_handle: wmi handle 20098 * @param evt_buf: pointer to event buffer 20099 * @param param: Pointer to hold dcs interference param 20100 * 20101 * Return: 0 for success or error code 20102 */ 20103 static QDF_STATUS extract_dcs_interference_type_tlv( 20104 wmi_unified_t wmi_handle, 20105 void *evt_buf, struct wmi_host_dcs_interference_param *param) 20106 { 20107 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20108 20109 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20110 if (!param_buf) 20111 return QDF_STATUS_E_INVAL; 20112 20113 param->interference_type = param_buf->fixed_param->interference_type; 20114 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20115 param_buf->fixed_param->pdev_id); 20116 20117 return QDF_STATUS_SUCCESS; 20118 } 20119 20120 /* 20121 * extract_dcs_cw_int_tlv() - extract dcs cw interference from event 20122 * @wmi_handle: wmi handle 20123 * @param evt_buf: pointer to event buffer 20124 * @param cw_int: Pointer to hold cw interference 20125 * 20126 * Return: 0 for success or error code 20127 */ 20128 static QDF_STATUS extract_dcs_cw_int_tlv(wmi_unified_t wmi_handle, 20129 void *evt_buf, 20130 wmi_host_ath_dcs_cw_int *cw_int) 20131 { 20132 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20133 wlan_dcs_cw_int *ev; 20134 20135 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20136 if (!param_buf) 20137 return QDF_STATUS_E_INVAL; 20138 20139 ev = param_buf->cw_int; 20140 20141 cw_int->channel = ev->channel; 20142 20143 return QDF_STATUS_SUCCESS; 20144 } 20145 20146 /** 20147 * extract_dcs_im_tgt_stats_tlv() - extract dcs im target stats from event 20148 * @wmi_handle: wmi handle 20149 * @param evt_buf: pointer to event buffer 20150 * @param wlan_stat: Pointer to hold wlan stats 20151 * 20152 * Return: 0 for success or error code 20153 */ 20154 static QDF_STATUS extract_dcs_im_tgt_stats_tlv(wmi_unified_t wmi_handle, 20155 void *evt_buf, 20156 wmi_host_dcs_im_tgt_stats_t *wlan_stat) 20157 { 20158 WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *param_buf; 20159 wlan_dcs_im_tgt_stats_t *ev; 20160 20161 param_buf = (WMI_DCS_INTERFERENCE_EVENTID_param_tlvs *) evt_buf; 20162 if (!param_buf) 20163 return QDF_STATUS_E_INVAL; 20164 20165 ev = param_buf->wlan_stat; 20166 wlan_stat->reg_tsf32 = ev->reg_tsf32; 20167 wlan_stat->last_ack_rssi = ev->last_ack_rssi; 20168 wlan_stat->tx_waste_time = ev->tx_waste_time; 20169 wlan_stat->rx_time = ev->rx_time; 20170 wlan_stat->phyerr_cnt = ev->phyerr_cnt; 20171 wlan_stat->mib_stats.listen_time = ev->listen_time; 20172 wlan_stat->mib_stats.reg_tx_frame_cnt = ev->reg_tx_frame_cnt; 20173 wlan_stat->mib_stats.reg_rx_frame_cnt = ev->reg_rx_frame_cnt; 20174 wlan_stat->mib_stats.reg_rxclr_cnt = ev->reg_rxclr_cnt; 20175 wlan_stat->mib_stats.reg_cycle_cnt = ev->reg_cycle_cnt; 20176 wlan_stat->mib_stats.reg_rxclr_ext_cnt = ev->reg_rxclr_ext_cnt; 20177 wlan_stat->mib_stats.reg_ofdm_phyerr_cnt = ev->reg_ofdm_phyerr_cnt; 20178 wlan_stat->mib_stats.reg_cck_phyerr_cnt = ev->reg_cck_phyerr_cnt; 20179 wlan_stat->chan_nf = ev->chan_nf; 20180 wlan_stat->my_bss_rx_cycle_count = ev->my_bss_rx_cycle_count; 20181 20182 return QDF_STATUS_SUCCESS; 20183 } 20184 20185 /** 20186 * extract_thermal_stats_tlv() - extract thermal stats from event 20187 * @wmi_handle: wmi handle 20188 * @param evt_buf: Pointer to event buffer 20189 * @param temp: Pointer to hold extracted temperature 20190 * @param level: Pointer to hold extracted level 20191 * 20192 * Return: 0 for success or error code 20193 */ 20194 static QDF_STATUS 20195 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 20196 void *evt_buf, uint32_t *temp, 20197 uint32_t *level, uint32_t *pdev_id) 20198 { 20199 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20200 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 20201 20202 param_buf = 20203 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20204 if (!param_buf) 20205 return QDF_STATUS_E_INVAL; 20206 20207 tt_stats_event = param_buf->fixed_param; 20208 20209 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20210 tt_stats_event->pdev_id); 20211 *temp = tt_stats_event->temp; 20212 *level = tt_stats_event->level; 20213 20214 return QDF_STATUS_SUCCESS; 20215 } 20216 20217 /** 20218 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 20219 * @wmi_handle: wmi handle 20220 * @param evt_buf: pointer to event buffer 20221 * @param idx: Index to level stats 20222 * @param levelcount: Pointer to hold levelcount 20223 * @param dccount: Pointer to hold dccount 20224 * 20225 * Return: 0 for success or error code 20226 */ 20227 static QDF_STATUS 20228 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 20229 void *evt_buf, uint8_t idx, uint32_t *levelcount, 20230 uint32_t *dccount) 20231 { 20232 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 20233 wmi_therm_throt_level_stats_info *tt_level_info; 20234 20235 param_buf = 20236 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 20237 if (!param_buf) 20238 return QDF_STATUS_E_INVAL; 20239 20240 tt_level_info = param_buf->therm_throt_level_stats_info; 20241 20242 if (idx < THERMAL_LEVELS) { 20243 *levelcount = tt_level_info[idx].level_count; 20244 *dccount = tt_level_info[idx].dc_count; 20245 return QDF_STATUS_SUCCESS; 20246 } 20247 20248 return QDF_STATUS_E_FAILURE; 20249 } 20250 #ifdef BIG_ENDIAN_HOST 20251 /** 20252 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 20253 * @param data_len - data length 20254 * @param data - pointer to data 20255 * 20256 * Return: QDF_STATUS - success or error status 20257 */ 20258 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20259 { 20260 uint8_t *data_aligned = NULL; 20261 int c; 20262 unsigned char *data_unaligned; 20263 20264 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 20265 FIPS_ALIGN)); 20266 /* Assigning unaligned space to copy the data */ 20267 /* Checking if kmalloc does successful allocation */ 20268 if (data_unaligned == NULL) 20269 return QDF_STATUS_E_FAILURE; 20270 20271 /* Checking if space is alligned */ 20272 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 20273 /* align the data space */ 20274 data_aligned = 20275 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 20276 } else { 20277 data_aligned = (u_int8_t *)data_unaligned; 20278 } 20279 20280 /* memset and copy content from data to data aligned */ 20281 OS_MEMSET(data_aligned, 0, data_len); 20282 OS_MEMCPY(data_aligned, data, data_len); 20283 /* Endianness to LE */ 20284 for (c = 0; c < data_len/4; c++) { 20285 *((u_int32_t *)data_aligned + c) = 20286 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 20287 } 20288 20289 /* Copy content to event->data */ 20290 OS_MEMCPY(data, data_aligned, data_len); 20291 20292 /* clean up allocated space */ 20293 qdf_mem_free(data_unaligned); 20294 data_aligned = NULL; 20295 data_unaligned = NULL; 20296 20297 /*************************************************************/ 20298 20299 return QDF_STATUS_SUCCESS; 20300 } 20301 #else 20302 /** 20303 * fips_conv_data_be() - DUMMY for LE platform 20304 * 20305 * Return: QDF_STATUS - success 20306 */ 20307 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 20308 { 20309 return QDF_STATUS_SUCCESS; 20310 } 20311 #endif 20312 20313 /** 20314 * extract_fips_event_data_tlv() - extract fips event data 20315 * @wmi_handle: wmi handle 20316 * @param evt_buf: pointer to event buffer 20317 * @param param: pointer FIPS event params 20318 * 20319 * Return: 0 for success or error code 20320 */ 20321 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 20322 void *evt_buf, struct wmi_host_fips_event_param *param) 20323 { 20324 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 20325 wmi_pdev_fips_event_fixed_param *event; 20326 20327 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 20328 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 20329 20330 if (fips_conv_data_be(event->data_len, param_buf->data) != 20331 QDF_STATUS_SUCCESS) 20332 return QDF_STATUS_E_FAILURE; 20333 20334 param->data = (uint32_t *)param_buf->data; 20335 param->data_len = event->data_len; 20336 param->error_status = event->error_status; 20337 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20338 event->pdev_id); 20339 20340 return QDF_STATUS_SUCCESS; 20341 } 20342 20343 /* 20344 * extract_peer_delete_response_event_tlv() - extract peer delete response event 20345 * @wmi_handle: wmi handle 20346 * @param evt_buf: pointer to event buffer 20347 * @param vdev_id: Pointer to hold vdev_id 20348 * @param mac_addr: Pointer to hold peer mac address 20349 * 20350 * Return: QDF_STATUS_SUCCESS for success or error code 20351 */ 20352 static QDF_STATUS extract_peer_delete_response_event_tlv(wmi_unified_t wmi_hdl, 20353 void *evt_buf, struct wmi_host_peer_delete_response_event *param) 20354 { 20355 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf; 20356 wmi_peer_delete_resp_event_fixed_param *ev; 20357 20358 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)evt_buf; 20359 20360 ev = (wmi_peer_delete_resp_event_fixed_param *) param_buf->fixed_param; 20361 if (!ev) { 20362 WMI_LOGE("%s: Invalid peer_delete response\n", __func__); 20363 return QDF_STATUS_E_FAILURE; 20364 } 20365 20366 param->vdev_id = ev->vdev_id; 20367 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 20368 ¶m->mac_address.bytes[0]); 20369 20370 return QDF_STATUS_SUCCESS; 20371 } 20372 20373 static bool is_management_record_tlv(uint32_t cmd_id) 20374 { 20375 switch (cmd_id) { 20376 case WMI_MGMT_TX_SEND_CMDID: 20377 case WMI_MGMT_TX_COMPLETION_EVENTID: 20378 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 20379 case WMI_MGMT_RX_EVENTID: 20380 return true; 20381 default: 20382 return false; 20383 } 20384 } 20385 20386 static bool is_diag_event_tlv(uint32_t event_id) 20387 { 20388 if (WMI_DIAG_EVENTID == event_id) 20389 return true; 20390 20391 return false; 20392 } 20393 20394 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20395 { 20396 wmi_vdev_set_param_cmd_fixed_param *set_cmd; 20397 20398 set_cmd = (wmi_vdev_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20399 20400 switch (set_cmd->param_id) { 20401 case WMI_VDEV_PARAM_LISTEN_INTERVAL: 20402 case WMI_VDEV_PARAM_DTIM_POLICY: 20403 return HTC_TX_PACKET_TAG_AUTO_PM; 20404 default: 20405 break; 20406 } 20407 20408 return 0; 20409 } 20410 20411 static uint16_t wmi_tag_sta_powersave_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf) 20412 { 20413 wmi_sta_powersave_param_cmd_fixed_param *ps_cmd; 20414 20415 ps_cmd = (wmi_sta_powersave_param_cmd_fixed_param *)wmi_buf_data(buf); 20416 20417 switch (ps_cmd->param) { 20418 case WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD: 20419 case WMI_STA_PS_PARAM_INACTIVITY_TIME: 20420 case WMI_STA_PS_ENABLE_QPOWER: 20421 return HTC_TX_PACKET_TAG_AUTO_PM; 20422 default: 20423 break; 20424 } 20425 20426 return 0; 20427 } 20428 20429 static uint16_t wmi_tag_common_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf, 20430 uint32_t cmd_id) 20431 { 20432 if (qdf_atomic_read(&wmi_hdl->is_wow_bus_suspended)) 20433 return 0; 20434 20435 switch (cmd_id) { 20436 case WMI_VDEV_SET_PARAM_CMDID: 20437 return wmi_tag_vdev_set_cmd(wmi_hdl, buf); 20438 case WMI_STA_POWERSAVE_PARAM_CMDID: 20439 return wmi_tag_sta_powersave_cmd(wmi_hdl, buf); 20440 default: 20441 break; 20442 } 20443 20444 return 0; 20445 } 20446 20447 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 20448 { 20449 uint16_t tag = 0; 20450 20451 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 20452 pr_err("%s: Target is already suspended, Ignore FW Hang Command\n", 20453 __func__); 20454 return tag; 20455 } 20456 20457 if (wmi_handle->tag_crash_inject) 20458 tag = HTC_TX_PACKET_TAG_AUTO_PM; 20459 20460 wmi_handle->tag_crash_inject = false; 20461 return tag; 20462 } 20463 20464 /** 20465 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 20466 * @wmi_handle: WMI handle 20467 * @buf: WMI buffer 20468 * @cmd_id: WMI command Id 20469 * 20470 * Return htc_tx_tag 20471 */ 20472 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 20473 wmi_buf_t buf, 20474 uint32_t cmd_id) 20475 { 20476 uint16_t htc_tx_tag = 0; 20477 20478 switch (cmd_id) { 20479 case WMI_WOW_ENABLE_CMDID: 20480 case WMI_PDEV_SUSPEND_CMDID: 20481 case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: 20482 case WMI_WOW_ADD_WAKE_PATTERN_CMDID: 20483 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 20484 case WMI_PDEV_RESUME_CMDID: 20485 case WMI_WOW_DEL_WAKE_PATTERN_CMDID: 20486 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 20487 #ifdef FEATURE_WLAN_D0WOW 20488 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 20489 #endif 20490 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 20491 break; 20492 case WMI_FORCE_FW_HANG_CMDID: 20493 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 20494 break; 20495 case WMI_VDEV_SET_PARAM_CMDID: 20496 case WMI_STA_POWERSAVE_PARAM_CMDID: 20497 htc_tx_tag = wmi_tag_common_cmd(wmi_handle, buf, cmd_id); 20498 default: 20499 break; 20500 } 20501 20502 return htc_tx_tag; 20503 } 20504 20505 /** 20506 * extract_channel_hopping_event_tlv() - extract channel hopping param 20507 * from event 20508 * @wmi_handle: wmi handle 20509 * @param evt_buf: pointer to event buffer 20510 * @param ch_hopping: Pointer to hold channel hopping param 20511 * 20512 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20513 */ 20514 static QDF_STATUS extract_channel_hopping_event_tlv( 20515 wmi_unified_t wmi_handle, void *evt_buf, 20516 wmi_host_pdev_channel_hopping_event *ch_hopping) 20517 { 20518 WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *param_buf; 20519 wmi_pdev_channel_hopping_event_fixed_param *event; 20520 20521 param_buf = (WMI_PDEV_CHANNEL_HOPPING_EVENTID_param_tlvs *)evt_buf; 20522 event = (wmi_pdev_channel_hopping_event_fixed_param *) 20523 param_buf->fixed_param; 20524 20525 ch_hopping->noise_floor_report_iter = event->noise_floor_report_iter; 20526 ch_hopping->noise_floor_total_iter = event->noise_floor_total_iter; 20527 ch_hopping->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20528 event->pdev_id); 20529 20530 return QDF_STATUS_SUCCESS; 20531 } 20532 20533 /** 20534 * extract_pdev_tpc_ev_param_tlv() - extract tpc param from event 20535 * @wmi_handle: wmi handle 20536 * @param evt_buf: pointer to event buffer 20537 * @param param: Pointer to hold tpc param 20538 * 20539 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20540 */ 20541 static QDF_STATUS extract_pdev_tpc_ev_param_tlv(wmi_unified_t wmi_handle, 20542 void *evt_buf, 20543 wmi_host_pdev_tpc_event *param) 20544 { 20545 WMI_PDEV_TPC_EVENTID_param_tlvs *param_buf; 20546 wmi_pdev_tpc_event_fixed_param *event; 20547 20548 param_buf = (WMI_PDEV_TPC_EVENTID_param_tlvs *)evt_buf; 20549 event = (wmi_pdev_tpc_event_fixed_param *)param_buf->fixed_param; 20550 20551 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20552 event->pdev_id); 20553 qdf_mem_copy(param->tpc, param_buf->tpc, sizeof(param->tpc)); 20554 20555 return QDF_STATUS_SUCCESS; 20556 } 20557 20558 /** 20559 * extract_nfcal_power_ev_param_tlv() - extract noise floor calibration 20560 * power param from event 20561 * @wmi_handle: wmi handle 20562 * @param evt_buf: pointer to event buffer 20563 * @param param: Pointer to hold nf cal power param 20564 * 20565 * Return: 0 for success or error code 20566 */ 20567 static QDF_STATUS 20568 extract_nfcal_power_ev_param_tlv(wmi_unified_t wmi_handle, 20569 void *evt_buf, 20570 wmi_host_pdev_nfcal_power_all_channels_event *param) 20571 { 20572 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *param_buf; 20573 wmi_pdev_nfcal_power_all_channels_event_fixed_param *event; 20574 wmi_pdev_nfcal_power_all_channels_nfdBr *ch_nfdbr; 20575 wmi_pdev_nfcal_power_all_channels_nfdBm *ch_nfdbm; 20576 wmi_pdev_nfcal_power_all_channels_freqNum *ch_freqnum; 20577 uint32_t i; 20578 20579 param_buf = 20580 (WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID_param_tlvs *)evt_buf; 20581 event = param_buf->fixed_param; 20582 ch_nfdbr = param_buf->nfdbr; 20583 ch_nfdbm = param_buf->nfdbm; 20584 ch_freqnum = param_buf->freqnum; 20585 20586 WMI_LOGD("pdev_id[%x], num_nfdbr[%d], num_nfdbm[%d] num_freqnum[%d]\n", 20587 event->pdev_id, param_buf->num_nfdbr, 20588 param_buf->num_nfdbm, param_buf->num_freqnum); 20589 20590 if (param_buf->num_nfdbr > 20591 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20592 WMI_LOGE("invalid number of nfdBr"); 20593 return QDF_STATUS_E_FAILURE; 20594 } 20595 20596 if (param_buf->num_nfdbm > 20597 WMI_HOST_RXG_CAL_CHAN_MAX * WMI_HOST_MAX_NUM_CHAINS) { 20598 WMI_LOGE("invalid number of nfdBm"); 20599 return QDF_STATUS_E_FAILURE; 20600 } 20601 20602 if (param_buf->num_freqnum > WMI_HOST_RXG_CAL_CHAN_MAX) { 20603 WMI_LOGE("invalid number of freqNum"); 20604 return QDF_STATUS_E_FAILURE; 20605 } 20606 20607 for (i = 0; i < param_buf->num_nfdbr; i++) { 20608 param->nfdbr[i] = (int8_t)ch_nfdbr->nfdBr; 20609 param->nfdbm[i] = (int8_t)ch_nfdbm->nfdBm; 20610 ch_nfdbr++; 20611 ch_nfdbm++; 20612 } 20613 20614 for (i = 0; i < param_buf->num_freqnum; i++) { 20615 param->freqnum[i] = ch_freqnum->freqNum; 20616 ch_freqnum++; 20617 } 20618 20619 param->pdev_id = wmi_handle->ops-> 20620 convert_pdev_id_target_to_host(event->pdev_id); 20621 20622 return QDF_STATUS_SUCCESS; 20623 } 20624 20625 20626 #ifdef BIG_ENDIAN_HOST 20627 /** 20628 * wds_addr_ev_conv_data_be() - LE to BE conversion of wds addr event 20629 * @param data_len - data length 20630 * @param data - pointer to data 20631 * 20632 * Return: QDF_STATUS - success or error status 20633 */ 20634 static QDF_STATUS wds_addr_ev_conv_data_be(uint16_t data_len, uint8_t *ev) 20635 { 20636 uint8_t *datap = (uint8_t *)ev; 20637 int i; 20638 /* Skip swapping the first word */ 20639 datap += sizeof(uint32_t); 20640 for (i = 0; i < ((data_len / sizeof(uint32_t))-1); 20641 i++, datap += sizeof(uint32_t)) { 20642 *(uint32_t *)datap = qdf_le32_to_cpu(*(uint32_t *)datap); 20643 } 20644 20645 return QDF_STATUS_SUCCESS; 20646 } 20647 #else 20648 /** 20649 * wds_addr_ev_conv_data_be() - Dummy operation for LE platforms 20650 * @param data_len - data length 20651 * @param data - pointer to data 20652 * 20653 * Return: QDF_STATUS - success or error status 20654 */ 20655 static QDF_STATUS wds_addr_ev_conv_data_be(uint32_t data_len, uint8_t *ev) 20656 { 20657 return QDF_STATUS_SUCCESS; 20658 } 20659 #endif 20660 20661 /** 20662 * extract_wds_addr_event_tlv() - extract wds address from event 20663 * @wmi_handle: wmi handle 20664 * @param evt_buf: pointer to event buffer 20665 * @param wds_ev: Pointer to hold wds address 20666 * 20667 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20668 */ 20669 static QDF_STATUS extract_wds_addr_event_tlv(wmi_unified_t wmi_handle, 20670 void *evt_buf, 20671 uint16_t len, wds_addr_event_t *wds_ev) 20672 { 20673 WMI_WDS_PEER_EVENTID_param_tlvs *param_buf; 20674 wmi_wds_addr_event_fixed_param *ev; 20675 int i; 20676 20677 param_buf = (WMI_WDS_PEER_EVENTID_param_tlvs *)evt_buf; 20678 ev = (wmi_wds_addr_event_fixed_param *)param_buf->fixed_param; 20679 20680 if (wds_addr_ev_conv_data_be(len, (uint8_t *)ev) != QDF_STATUS_SUCCESS) 20681 return QDF_STATUS_E_FAILURE; 20682 20683 qdf_mem_copy(wds_ev->event_type, ev->event_type, 20684 sizeof(wds_ev->event_type)); 20685 for (i = 0; i < 4; i++) { 20686 wds_ev->peer_mac[i] = 20687 ((u_int8_t *)&(ev->peer_mac.mac_addr31to0))[i]; 20688 wds_ev->dest_mac[i] = 20689 ((u_int8_t *)&(ev->dest_mac.mac_addr31to0))[i]; 20690 } 20691 for (i = 0; i < 2; i++) { 20692 wds_ev->peer_mac[4+i] = 20693 ((u_int8_t *)&(ev->peer_mac.mac_addr47to32))[i]; 20694 wds_ev->dest_mac[4+i] = 20695 ((u_int8_t *)&(ev->dest_mac.mac_addr47to32))[i]; 20696 } 20697 wds_ev->vdev_id = ev->vdev_id; 20698 20699 return QDF_STATUS_SUCCESS; 20700 } 20701 20702 /** 20703 * extract_peer_sta_ps_statechange_ev_tlv() - extract peer sta ps state 20704 * from event 20705 * @wmi_handle: wmi handle 20706 * @param evt_buf: pointer to event buffer 20707 * @param ev: Pointer to hold peer param and ps state 20708 * 20709 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20710 */ 20711 static QDF_STATUS extract_peer_sta_ps_statechange_ev_tlv(wmi_unified_t wmi_handle, 20712 void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev) 20713 { 20714 WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf; 20715 wmi_peer_sta_ps_statechange_event_fixed_param *event; 20716 20717 param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)evt_buf; 20718 event = (wmi_peer_sta_ps_statechange_event_fixed_param *) 20719 param_buf->fixed_param; 20720 20721 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, ev->peer_macaddr); 20722 ev->peer_ps_state = event->peer_ps_state; 20723 20724 return QDF_STATUS_SUCCESS; 20725 } 20726 20727 /** 20728 * extract_inst_rssi_stats_event_tlv() - extract inst rssi stats from event 20729 * @wmi_handle: wmi handle 20730 * @param evt_buf: pointer to event buffer 20731 * @param inst_rssi_resp: Pointer to hold inst rssi response 20732 * 20733 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 20734 */ 20735 static QDF_STATUS extract_inst_rssi_stats_event_tlv( 20736 wmi_unified_t wmi_handle, void *evt_buf, 20737 wmi_host_inst_stats_resp *inst_rssi_resp) 20738 { 20739 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 20740 wmi_inst_rssi_stats_resp_fixed_param *event; 20741 20742 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 20743 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 20744 20745 qdf_mem_copy(&(inst_rssi_resp->peer_macaddr), 20746 &(event->peer_macaddr), sizeof(wmi_mac_addr)); 20747 inst_rssi_resp->iRSSI = event->iRSSI; 20748 20749 return QDF_STATUS_SUCCESS; 20750 } 20751 20752 static struct cur_reg_rule 20753 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 20754 wmi_regulatory_rule_struct *wmi_reg_rule) 20755 { 20756 struct cur_reg_rule *reg_rule_ptr; 20757 uint32_t count; 20758 20759 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 20760 20761 if (NULL == reg_rule_ptr) { 20762 WMI_LOGE("memory allocation failure"); 20763 return NULL; 20764 } 20765 20766 for (count = 0; count < num_reg_rules; count++) { 20767 reg_rule_ptr[count].start_freq = 20768 WMI_REG_RULE_START_FREQ_GET( 20769 wmi_reg_rule[count].freq_info); 20770 reg_rule_ptr[count].end_freq = 20771 WMI_REG_RULE_END_FREQ_GET( 20772 wmi_reg_rule[count].freq_info); 20773 reg_rule_ptr[count].max_bw = 20774 WMI_REG_RULE_MAX_BW_GET( 20775 wmi_reg_rule[count].bw_pwr_info); 20776 reg_rule_ptr[count].reg_power = 20777 WMI_REG_RULE_REG_POWER_GET( 20778 wmi_reg_rule[count].bw_pwr_info); 20779 reg_rule_ptr[count].ant_gain = 20780 WMI_REG_RULE_ANTENNA_GAIN_GET( 20781 wmi_reg_rule[count].bw_pwr_info); 20782 reg_rule_ptr[count].flags = 20783 WMI_REG_RULE_FLAGS_GET( 20784 wmi_reg_rule[count].flag_info); 20785 } 20786 20787 return reg_rule_ptr; 20788 } 20789 20790 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 20791 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20792 struct cur_regulatory_info *reg_info, uint32_t len) 20793 { 20794 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 20795 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 20796 wmi_regulatory_rule_struct *wmi_reg_rule; 20797 uint32_t num_2g_reg_rules, num_5g_reg_rules; 20798 20799 WMI_LOGD("processing regulatory channel list"); 20800 20801 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 20802 if (!param_buf) { 20803 WMI_LOGE("invalid channel list event buf"); 20804 return QDF_STATUS_E_FAILURE; 20805 } 20806 20807 chan_list_event_hdr = param_buf->fixed_param; 20808 20809 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 20810 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 20811 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 20812 REG_ALPHA2_LEN); 20813 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 20814 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 20815 reg_info->offload_enabled = true; 20816 reg_info->num_phy = chan_list_event_hdr->num_phy; 20817 reg_info->phy_id = chan_list_event_hdr->phy_id; 20818 reg_info->ctry_code = chan_list_event_hdr->country_id; 20819 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 20820 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 20821 reg_info->status_code = REG_SET_CC_STATUS_PASS; 20822 else if (chan_list_event_hdr->status_code == 20823 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 20824 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 20825 else if (chan_list_event_hdr->status_code == 20826 WMI_REG_INIT_ALPHA2_NOT_FOUND) 20827 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 20828 else if (chan_list_event_hdr->status_code == 20829 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 20830 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 20831 else if (chan_list_event_hdr->status_code == 20832 WMI_REG_SET_CC_STATUS_NO_MEMORY) 20833 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 20834 else if (chan_list_event_hdr->status_code == 20835 WMI_REG_SET_CC_STATUS_FAIL) 20836 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 20837 20838 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 20839 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 20840 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 20841 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 20842 20843 num_2g_reg_rules = reg_info->num_2g_reg_rules; 20844 num_5g_reg_rules = reg_info->num_5g_reg_rules; 20845 20846 WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 20847 __func__, reg_info->alpha2, reg_info->dfs_region, 20848 reg_info->min_bw_2g, reg_info->max_bw_2g, 20849 reg_info->min_bw_5g, reg_info->max_bw_5g); 20850 20851 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 20852 num_2g_reg_rules, num_5g_reg_rules); 20853 wmi_reg_rule = 20854 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 20855 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 20856 + WMI_TLV_HDR_SIZE); 20857 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 20858 wmi_reg_rule); 20859 wmi_reg_rule += num_2g_reg_rules; 20860 20861 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 20862 wmi_reg_rule); 20863 20864 WMI_LOGD("processed regulatory channel list"); 20865 20866 return QDF_STATUS_SUCCESS; 20867 } 20868 20869 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 20870 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20871 struct reg_11d_new_country *reg_11d_country, uint32_t len) 20872 { 20873 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 20874 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 20875 20876 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 20877 if (!param_buf) { 20878 WMI_LOGE("invalid 11d country event buf"); 20879 return QDF_STATUS_E_FAILURE; 20880 } 20881 20882 reg_11d_country_event = param_buf->fixed_param; 20883 20884 qdf_mem_copy(reg_11d_country->alpha2, 20885 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 20886 20887 WMI_LOGD("processed 11d country event, new cc %s", 20888 reg_11d_country->alpha2); 20889 20890 return QDF_STATUS_SUCCESS; 20891 } 20892 20893 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 20894 wmi_unified_t wmi_handle, uint8_t *evt_buf, 20895 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 20896 { 20897 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 20898 wmi_avoid_freq_range_desc *afr_desc; 20899 uint32_t num_freq_ranges, freq_range_idx; 20900 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 20901 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 20902 20903 if (!param_buf) { 20904 WMI_LOGE("Invalid channel avoid event buffer"); 20905 return QDF_STATUS_E_INVAL; 20906 } 20907 20908 afr_fixed_param = param_buf->fixed_param; 20909 if (!afr_fixed_param) { 20910 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 20911 return QDF_STATUS_E_INVAL; 20912 } 20913 20914 if (!ch_avoid_ind) { 20915 WMI_LOGE("Invalid channel avoid indication buffer"); 20916 return QDF_STATUS_E_INVAL; 20917 } 20918 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 20919 WMI_LOGE(FL("no.of freq ranges exceeded the limit")); 20920 return QDF_STATUS_E_INVAL; 20921 } 20922 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 20923 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 20924 afr_fixed_param->num_freq_ranges; 20925 20926 WMI_LOGD("Channel avoid event received with %d ranges", 20927 num_freq_ranges); 20928 20929 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 20930 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 20931 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 20932 freq_range_idx++) { 20933 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 20934 afr_desc->start_freq; 20935 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 20936 afr_desc->end_freq; 20937 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 20938 freq_range_idx, afr_desc->tlv_header, 20939 afr_desc->start_freq, afr_desc->end_freq); 20940 afr_desc++; 20941 } 20942 20943 return QDF_STATUS_SUCCESS; 20944 } 20945 #ifdef DFS_COMPONENT_ENABLE 20946 /** 20947 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 20948 * @wmi_handle: wma handle 20949 * @evt_buf: event buffer 20950 * @vdev_id: vdev id 20951 * @len: length of buffer 20952 * 20953 * Return: 0 for success or error code 20954 */ 20955 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 20956 uint8_t *evt_buf, 20957 uint32_t *vdev_id, 20958 uint32_t len) 20959 { 20960 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 20961 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 20962 20963 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 20964 if (!param_tlvs) { 20965 WMI_LOGE("invalid cac complete event buf"); 20966 return QDF_STATUS_E_FAILURE; 20967 } 20968 20969 cac_event = param_tlvs->fixed_param; 20970 *vdev_id = cac_event->vdev_id; 20971 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 20972 20973 return QDF_STATUS_SUCCESS; 20974 } 20975 20976 /** 20977 * extract_dfs_radar_detection_event_tlv() - extract radar found event 20978 * @wmi_handle: wma handle 20979 * @evt_buf: event buffer 20980 * @radar_found: radar found event info 20981 * @len: length of buffer 20982 * 20983 * Return: 0 for success or error code 20984 */ 20985 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 20986 wmi_unified_t wmi_handle, 20987 uint8_t *evt_buf, 20988 struct radar_found_info *radar_found, 20989 uint32_t len) 20990 { 20991 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 20992 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 20993 20994 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 20995 if (!param_tlv) { 20996 WMI_LOGE("invalid radar detection event buf"); 20997 return QDF_STATUS_E_FAILURE; 20998 } 20999 21000 radar_event = param_tlv->fixed_param; 21001 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 21002 radar_event->pdev_id); 21003 radar_found->detection_mode = radar_event->detection_mode; 21004 radar_found->chan_freq = radar_event->chan_freq; 21005 radar_found->chan_width = radar_event->chan_width; 21006 radar_found->detector_id = radar_event->detector_id; 21007 radar_found->segment_id = radar_event->segment_id; 21008 radar_found->timestamp = radar_event->timestamp; 21009 radar_found->is_chirp = radar_event->is_chirp; 21010 radar_found->freq_offset = radar_event->freq_offset; 21011 radar_found->sidx = radar_event->sidx; 21012 21013 WMI_LOGI("processed radar found event pdev %d," 21014 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 21015 "chan_width (RSSI) %d,detector_id (false_radar) %d," 21016 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 21017 "is_chirp %d,detection mode %d\n", 21018 radar_event->pdev_id, radar_found->pdev_id, 21019 radar_event->timestamp, radar_event->chan_freq, 21020 radar_event->chan_width, radar_event->detector_id, 21021 radar_event->freq_offset, radar_event->segment_id, 21022 radar_event->sidx, radar_event->is_chirp, 21023 radar_event->detection_mode); 21024 21025 return QDF_STATUS_SUCCESS; 21026 } 21027 21028 #ifdef QCA_MCL_DFS_SUPPORT 21029 /** 21030 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 21031 * @wmi_handle: wma handle 21032 * @evt_buf: event buffer 21033 * @wlan_radar_event: Pointer to struct radar_event_info 21034 * @len: length of buffer 21035 * 21036 * Return: QDF_STATUS 21037 */ 21038 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21039 wmi_unified_t wmi_handle, 21040 uint8_t *evt_buf, 21041 struct radar_event_info *wlan_radar_event, 21042 uint32_t len) 21043 { 21044 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 21045 wmi_dfs_radar_event_fixed_param *radar_event; 21046 21047 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 21048 if (!param_tlv) { 21049 WMI_LOGE("invalid wlan radar event buf"); 21050 return QDF_STATUS_E_FAILURE; 21051 } 21052 21053 radar_event = param_tlv->fixed_param; 21054 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 21055 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 21056 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 21057 wlan_radar_event->rssi = radar_event->rssi; 21058 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 21059 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 21060 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 21061 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 21062 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 21063 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 21064 if (radar_event->pulse_flags & 21065 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 21066 wlan_radar_event->is_psidx_diff_valid = true; 21067 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 21068 } else { 21069 wlan_radar_event->is_psidx_diff_valid = false; 21070 } 21071 21072 wlan_radar_event->pdev_id = radar_event->pdev_id; 21073 21074 return QDF_STATUS_SUCCESS; 21075 } 21076 #else 21077 static QDF_STATUS extract_wlan_radar_event_info_tlv( 21078 wmi_unified_t wmi_handle, 21079 uint8_t *evt_buf, 21080 struct radar_event_info *wlan_radar_event, 21081 uint32_t len) 21082 { 21083 return QDF_STATUS_SUCCESS; 21084 } 21085 #endif 21086 #endif 21087 21088 /** 21089 * send_get_rcpi_cmd_tlv() - send request for rcpi value 21090 * @wmi_handle: wmi handle 21091 * @get_rcpi_param: rcpi params 21092 * 21093 * Return: QDF status 21094 */ 21095 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 21096 struct rcpi_req *get_rcpi_param) 21097 { 21098 wmi_buf_t buf; 21099 wmi_request_rcpi_cmd_fixed_param *cmd; 21100 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 21101 21102 buf = wmi_buf_alloc(wmi_handle, len); 21103 if (!buf) { 21104 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21105 return QDF_STATUS_E_NOMEM; 21106 } 21107 21108 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 21109 WMITLV_SET_HDR(&cmd->tlv_header, 21110 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 21111 WMITLV_GET_STRUCT_TLVLEN 21112 (wmi_request_rcpi_cmd_fixed_param)); 21113 21114 cmd->vdev_id = get_rcpi_param->vdev_id; 21115 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 21116 &cmd->peer_macaddr); 21117 21118 switch (get_rcpi_param->measurement_type) { 21119 21120 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21121 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21122 break; 21123 21124 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 21125 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 21126 break; 21127 21128 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21129 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21130 break; 21131 21132 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 21133 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 21134 break; 21135 21136 default: 21137 /* 21138 * invalid rcpi measurement type, fall back to 21139 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 21140 */ 21141 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21142 break; 21143 } 21144 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 21145 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 21146 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21147 WMI_REQUEST_RCPI_CMDID)) { 21148 21149 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 21150 __func__); 21151 wmi_buf_free(buf); 21152 return QDF_STATUS_E_FAILURE; 21153 } 21154 21155 return QDF_STATUS_SUCCESS; 21156 } 21157 21158 /** 21159 * extract_rcpi_response_event_tlv() - Extract RCPI event params 21160 * @wmi_handle: wmi handle 21161 * @evt_buf: pointer to event buffer 21162 * @res: pointer to hold rcpi response from firmware 21163 * 21164 * Return: QDF_STATUS_SUCCESS for successful event parse 21165 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 21166 */ 21167 static QDF_STATUS 21168 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 21169 void *evt_buf, struct rcpi_res *res) 21170 { 21171 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 21172 wmi_update_rcpi_event_fixed_param *event; 21173 21174 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 21175 if (!param_buf) { 21176 WMI_LOGE(FL("Invalid rcpi event")); 21177 return QDF_STATUS_E_INVAL; 21178 } 21179 21180 event = param_buf->fixed_param; 21181 res->vdev_id = event->vdev_id; 21182 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 21183 21184 switch (event->measurement_type) { 21185 21186 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 21187 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 21188 break; 21189 21190 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 21191 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 21192 break; 21193 21194 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 21195 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 21196 break; 21197 21198 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 21199 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 21200 break; 21201 21202 default: 21203 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 21204 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 21205 return QDF_STATUS_E_FAILURE; 21206 } 21207 21208 if (event->status) 21209 return QDF_STATUS_E_FAILURE; 21210 else 21211 return QDF_STATUS_SUCCESS; 21212 } 21213 21214 /** 21215 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 21216 * host to target defines. For legacy there is not conversion 21217 * required. Just return pdev_id as it is. 21218 * @param pdev_id: host pdev_id to be converted. 21219 * Return: target pdev_id after conversion. 21220 */ 21221 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 21222 uint32_t pdev_id) 21223 { 21224 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 21225 return WMI_PDEV_ID_SOC; 21226 21227 /*No conversion required*/ 21228 return pdev_id; 21229 } 21230 21231 /** 21232 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 21233 * target to host defines. For legacy there is not conversion 21234 * required. Just return pdev_id as it is. 21235 * @param pdev_id: target pdev_id to be converted. 21236 * Return: host pdev_id after conversion. 21237 */ 21238 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 21239 uint32_t pdev_id) 21240 { 21241 /*No conversion required*/ 21242 return pdev_id; 21243 } 21244 21245 /** 21246 * send_set_country_cmd_tlv() - WMI scan channel list function 21247 * @param wmi_handle : handle to WMI. 21248 * @param param : pointer to hold scan channel list parameter 21249 * 21250 * Return: 0 on success and -ve on failure. 21251 */ 21252 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 21253 struct set_country *params) 21254 { 21255 wmi_buf_t buf; 21256 QDF_STATUS qdf_status; 21257 wmi_set_current_country_cmd_fixed_param *cmd; 21258 uint16_t len = sizeof(*cmd); 21259 21260 buf = wmi_buf_alloc(wmi_handle, len); 21261 if (!buf) { 21262 WMI_LOGE("Failed to allocate memory"); 21263 qdf_status = QDF_STATUS_E_NOMEM; 21264 goto end; 21265 } 21266 21267 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 21268 WMITLV_SET_HDR(&cmd->tlv_header, 21269 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 21270 WMITLV_GET_STRUCT_TLVLEN 21271 (wmi_set_current_country_cmd_fixed_param)); 21272 21273 WMI_LOGD("setting cuurnet country to %s", params->country); 21274 21275 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 21276 21277 cmd->pdev_id = params->pdev_id; 21278 21279 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 21280 qdf_status = wmi_unified_cmd_send(wmi_handle, 21281 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 21282 21283 if (QDF_IS_STATUS_ERROR(qdf_status)) { 21284 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 21285 wmi_buf_free(buf); 21286 } 21287 21288 end: 21289 return qdf_status; 21290 } 21291 21292 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 21293 WMI_SET_BITS(alpha, 0, 8, val0); \ 21294 WMI_SET_BITS(alpha, 8, 8, val1); \ 21295 WMI_SET_BITS(alpha, 16, 8, val2); \ 21296 } while (0) 21297 21298 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 21299 uint8_t pdev_id, struct cc_regdmn_s *rd) 21300 { 21301 wmi_set_init_country_cmd_fixed_param *cmd; 21302 uint16_t len; 21303 wmi_buf_t buf; 21304 int ret; 21305 21306 len = sizeof(wmi_set_init_country_cmd_fixed_param); 21307 buf = wmi_buf_alloc(wmi_handle, len); 21308 if (!buf) { 21309 WMI_LOGE("%s: Failed allocate wmi buffer", __func__); 21310 return QDF_STATUS_E_NOMEM; 21311 } 21312 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 21313 WMITLV_SET_HDR(&cmd->tlv_header, 21314 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 21315 WMITLV_GET_STRUCT_TLVLEN 21316 (wmi_set_init_country_cmd_fixed_param)); 21317 21318 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(pdev_id); 21319 21320 if (rd->flags == CC_IS_SET) { 21321 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 21322 cmd->country_code.country_id = rd->cc.country_code; 21323 } else if (rd->flags == ALPHA_IS_SET) { 21324 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 21325 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 21326 rd->cc.alpha[0], 21327 rd->cc.alpha[1], 21328 rd->cc.alpha[2]); 21329 } else if (rd->flags == REGDMN_IS_SET) { 21330 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 21331 cmd->country_code.domain_code = rd->cc.regdmn_id; 21332 } 21333 21334 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 21335 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21336 WMI_SET_INIT_COUNTRY_CMDID); 21337 if (ret) { 21338 WMI_LOGE("Failed to config wow wakeup event"); 21339 wmi_buf_free(buf); 21340 return QDF_STATUS_E_FAILURE; 21341 } 21342 21343 return QDF_STATUS_SUCCESS; 21344 } 21345 21346 /** 21347 * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan 21348 * configuration params 21349 * @wmi_handle: wmi handler 21350 * @limit_off_chan_param: pointer to wmi_off_chan_param 21351 * 21352 * Return: 0 for success and non zero for failure 21353 */ 21354 static 21355 QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle, 21356 struct wmi_limit_off_chan_param *limit_off_chan_param) 21357 { 21358 wmi_vdev_limit_offchan_cmd_fixed_param *cmd; 21359 wmi_buf_t buf; 21360 uint32_t len = sizeof(*cmd); 21361 int err; 21362 21363 buf = wmi_buf_alloc(wmi_handle, len); 21364 if (!buf) { 21365 WMI_LOGP("%s: failed to allocate memory for limit off chan cmd", 21366 __func__); 21367 return QDF_STATUS_E_NOMEM; 21368 } 21369 21370 cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf); 21371 21372 WMITLV_SET_HDR(&cmd->tlv_header, 21373 WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param, 21374 WMITLV_GET_STRUCT_TLVLEN( 21375 wmi_vdev_limit_offchan_cmd_fixed_param)); 21376 21377 cmd->vdev_id = limit_off_chan_param->vdev_id; 21378 21379 cmd->flags &= 0; 21380 if (limit_off_chan_param->status) 21381 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE; 21382 if (limit_off_chan_param->skip_dfs_chans) 21383 cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS; 21384 21385 cmd->max_offchan_time = limit_off_chan_param->max_offchan_time; 21386 cmd->rest_time = limit_off_chan_param->rest_time; 21387 21388 WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d", 21389 __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time, 21390 cmd->rest_time); 21391 21392 wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0); 21393 err = wmi_unified_cmd_send(wmi_handle, buf, 21394 len, WMI_VDEV_LIMIT_OFFCHAN_CMDID); 21395 if (QDF_IS_STATUS_ERROR(err)) { 21396 WMI_LOGE("Failed to send limit off chan cmd err=%d", err); 21397 wmi_buf_free(buf); 21398 return QDF_STATUS_E_FAILURE; 21399 } 21400 21401 return QDF_STATUS_SUCCESS; 21402 } 21403 21404 /** 21405 * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request 21406 * @wmi_handle: wmi handler 21407 * @req_buf: set arp stats request buffer 21408 * 21409 * Return: 0 for success and non zero for failure 21410 */ 21411 static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21412 struct set_arp_stats *req_buf) 21413 { 21414 wmi_buf_t buf = NULL; 21415 QDF_STATUS status; 21416 int len; 21417 uint8_t *buf_ptr; 21418 wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp; 21419 21420 len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21421 if (req_buf->pkt_type_bitmap) { 21422 len += WMI_TLV_HDR_SIZE; 21423 len += sizeof(wmi_vdev_set_connectivity_check_stats); 21424 } 21425 buf = wmi_buf_alloc(wmi_handle, len); 21426 if (!buf) { 21427 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21428 return QDF_STATUS_E_NOMEM; 21429 } 21430 21431 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21432 wmi_set_arp = 21433 (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr; 21434 WMITLV_SET_HDR(&wmi_set_arp->tlv_header, 21435 WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param, 21436 WMITLV_GET_STRUCT_TLVLEN 21437 (wmi_vdev_set_arp_stats_cmd_fixed_param)); 21438 21439 /* fill in per roam config values */ 21440 wmi_set_arp->vdev_id = req_buf->vdev_id; 21441 21442 wmi_set_arp->set_clr = req_buf->flag; 21443 wmi_set_arp->pkt_type = req_buf->pkt_type; 21444 wmi_set_arp->ipv4 = req_buf->ip_addr; 21445 21446 WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u", 21447 wmi_set_arp->vdev_id, wmi_set_arp->set_clr, 21448 wmi_set_arp->pkt_type, wmi_set_arp->ipv4); 21449 21450 /* 21451 * pkt_type_bitmap should be non-zero to ensure 21452 * presence of additional stats. 21453 */ 21454 if (req_buf->pkt_type_bitmap) { 21455 wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats; 21456 21457 buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param); 21458 WMITLV_SET_HDR(buf_ptr, 21459 WMITLV_TAG_ARRAY_STRUC, 21460 sizeof(wmi_vdev_set_connectivity_check_stats)); 21461 buf_ptr += WMI_TLV_HDR_SIZE; 21462 wmi_set_connect_stats = 21463 (wmi_vdev_set_connectivity_check_stats *)buf_ptr; 21464 WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header, 21465 WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats, 21466 WMITLV_GET_STRUCT_TLVLEN( 21467 wmi_vdev_set_connectivity_check_stats)); 21468 wmi_set_connect_stats->pkt_type_bitmap = 21469 req_buf->pkt_type_bitmap; 21470 wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port; 21471 wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port; 21472 wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4; 21473 21474 WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u", 21475 wmi_set_connect_stats->pkt_type_bitmap, 21476 wmi_set_connect_stats->tcp_src_port, 21477 wmi_set_connect_stats->tcp_dst_port, 21478 wmi_set_connect_stats->icmp_ipv4); 21479 } 21480 21481 /* Send per roam config parameters */ 21482 wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0); 21483 status = wmi_unified_cmd_send(wmi_handle, buf, 21484 len, WMI_VDEV_SET_ARP_STAT_CMDID); 21485 if (QDF_IS_STATUS_ERROR(status)) { 21486 WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d", 21487 status); 21488 goto error; 21489 } 21490 21491 WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"), 21492 req_buf->flag, req_buf->vdev_id); 21493 return QDF_STATUS_SUCCESS; 21494 error: 21495 wmi_buf_free(buf); 21496 21497 return status; 21498 } 21499 21500 /** 21501 * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request 21502 * @wmi_handle: wmi handler 21503 * @req_buf: get arp stats request buffer 21504 * 21505 * Return: 0 for success and non zero for failure 21506 */ 21507 static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle, 21508 struct get_arp_stats *req_buf) 21509 { 21510 wmi_buf_t buf = NULL; 21511 QDF_STATUS status; 21512 int len; 21513 uint8_t *buf_ptr; 21514 wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats; 21515 21516 len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param); 21517 buf = wmi_buf_alloc(wmi_handle, len); 21518 if (!buf) { 21519 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 21520 return QDF_STATUS_E_NOMEM; 21521 } 21522 21523 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21524 get_arp_stats = 21525 (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr; 21526 WMITLV_SET_HDR(&get_arp_stats->tlv_header, 21527 WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param, 21528 WMITLV_GET_STRUCT_TLVLEN 21529 (wmi_vdev_get_arp_stats_cmd_fixed_param)); 21530 21531 /* fill in arp stats req cmd values */ 21532 get_arp_stats->vdev_id = req_buf->vdev_id; 21533 21534 WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id); 21535 /* Send per roam config parameters */ 21536 wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0); 21537 status = wmi_unified_cmd_send(wmi_handle, buf, 21538 len, WMI_VDEV_GET_ARP_STAT_CMDID); 21539 if (QDF_IS_STATUS_ERROR(status)) { 21540 WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d", 21541 status); 21542 goto error; 21543 } 21544 21545 return QDF_STATUS_SUCCESS; 21546 error: 21547 wmi_buf_free(buf); 21548 21549 return status; 21550 } 21551 21552 /** 21553 * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid 21554 * @wmi_handle: wmi handler 21555 * @pmk_info: pointer to PMK cache entry 21556 * @vdev_id: vdev id 21557 * 21558 * Return: 0 for success and non zero for failure 21559 */ 21560 static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle, 21561 struct wmi_unified_pmk_cache *pmk_info) 21562 { 21563 wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd; 21564 wmi_buf_t buf; 21565 QDF_STATUS status; 21566 uint8_t *buf_ptr; 21567 wmi_pmk_cache *pmksa; 21568 uint32_t len = sizeof(*cmd); 21569 21570 if (pmk_info->pmk_len) 21571 len += WMI_TLV_HDR_SIZE + sizeof(*pmksa); 21572 21573 buf = wmi_buf_alloc(wmi_handle, len); 21574 if (!buf) { 21575 WMI_LOGP("%s: failed to allocate memory for set del pmkid cache", 21576 __func__); 21577 return QDF_STATUS_E_NOMEM; 21578 } 21579 21580 buf_ptr = (uint8_t *) wmi_buf_data(buf); 21581 cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr; 21582 21583 WMITLV_SET_HDR(&cmd->tlv_header, 21584 WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param, 21585 WMITLV_GET_STRUCT_TLVLEN( 21586 wmi_pdev_update_pmk_cache_cmd_fixed_param)); 21587 21588 cmd->vdev_id = pmk_info->session_id; 21589 21590 /* If pmk_info->pmk_len is 0, this is a flush request */ 21591 if (!pmk_info->pmk_len) { 21592 cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL; 21593 cmd->num_cache = 0; 21594 goto send_cmd; 21595 } 21596 21597 cmd->num_cache = 1; 21598 buf_ptr += sizeof(*cmd); 21599 21600 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 21601 sizeof(*pmksa)); 21602 buf_ptr += WMI_TLV_HDR_SIZE; 21603 21604 pmksa = (wmi_pmk_cache *)buf_ptr; 21605 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache, 21606 WMITLV_GET_STRUCT_TLVLEN 21607 (wmi_pmk_cache)); 21608 pmksa->pmk_len = pmk_info->pmk_len; 21609 qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len); 21610 pmksa->pmkid_len = pmk_info->pmkid_len; 21611 qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len); 21612 qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr)); 21613 pmksa->ssid.ssid_len = pmk_info->ssid.length; 21614 qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid), 21615 pmksa->ssid.ssid_len); 21616 pmksa->cache_id = pmk_info->cache_id; 21617 pmksa->cat_flag = pmk_info->cat_flag; 21618 pmksa->action_flag = pmk_info->action_flag; 21619 21620 send_cmd: 21621 wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0); 21622 status = wmi_unified_cmd_send(wmi_handle, buf, len, 21623 WMI_PDEV_UPDATE_PMK_CACHE_CMDID); 21624 if (status != QDF_STATUS_SUCCESS) { 21625 WMI_LOGE("%s: failed to send set del pmkid cache command %d", 21626 __func__, status); 21627 wmi_buf_free(buf); 21628 } 21629 21630 return status; 21631 } 21632 21633 /** 21634 * send_pdev_caldata_version_check_cmd_tlv() - send caldata check cmd to fw 21635 * @wmi_handle: wmi handle 21636 * @param: reserved param 21637 * 21638 * Return: 0 for success or error code 21639 */ 21640 static QDF_STATUS 21641 send_pdev_caldata_version_check_cmd_tlv(wmi_unified_t wmi_handle, 21642 uint32_t param) 21643 { 21644 wmi_pdev_check_cal_version_cmd_fixed_param *cmd; 21645 wmi_buf_t buf; 21646 int32_t len = sizeof(wmi_pdev_check_cal_version_cmd_fixed_param); 21647 21648 buf = wmi_buf_alloc(wmi_handle, len); 21649 if (!buf) { 21650 qdf_print("%s:wmi_buf_alloc failed", __func__); 21651 return QDF_STATUS_E_FAILURE; 21652 } 21653 cmd = (wmi_pdev_check_cal_version_cmd_fixed_param *)wmi_buf_data(buf); 21654 WMITLV_SET_HDR(&cmd->tlv_header, 21655 WMITLV_TAG_STRUC_wmi_pdev_check_cal_version_cmd_fixed_param, 21656 WMITLV_GET_STRUCT_TLVLEN 21657 (wmi_pdev_check_cal_version_cmd_fixed_param)); 21658 cmd->pdev_id = param; /* set to 0x0 as expected from FW */ 21659 wmi_mtrace(WMI_PDEV_CHECK_CAL_VERSION_CMDID, NO_SESSION, 0); 21660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21661 WMI_PDEV_CHECK_CAL_VERSION_CMDID)) { 21662 wmi_buf_free(buf); 21663 return QDF_STATUS_E_FAILURE; 21664 } 21665 21666 return QDF_STATUS_SUCCESS; 21667 } 21668 21669 /** 21670 * extract_pdev_caldata_version_check_ev_param_tlv() - extract caldata from event 21671 * @wmi_handle: wmi handle 21672 * @param evt_buf: pointer to event buffer 21673 * @param param: Pointer to hold peer caldata version data 21674 * 21675 * Return: 0 for success or error code 21676 */ 21677 static QDF_STATUS extract_pdev_caldata_version_check_ev_param_tlv( 21678 wmi_unified_t wmi_handle, 21679 void *evt_buf, 21680 wmi_host_pdev_check_cal_version_event *param) 21681 { 21682 WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *param_tlvs; 21683 wmi_pdev_check_cal_version_event_fixed_param *event; 21684 21685 param_tlvs = (WMI_PDEV_CHECK_CAL_VERSION_EVENTID_param_tlvs *) evt_buf; 21686 if (!param_tlvs) { 21687 WMI_LOGE("invalid cal version event buf"); 21688 return QDF_STATUS_E_FAILURE; 21689 } 21690 event = param_tlvs->fixed_param; 21691 if (event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] != '\0') 21692 event->board_mcn_detail[WMI_BOARD_MCN_STRING_MAX_SIZE] = '\0'; 21693 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(param->board_mcn_detail, 21694 event->board_mcn_detail, WMI_BOARD_MCN_STRING_BUF_SIZE); 21695 21696 param->software_cal_version = event->software_cal_version; 21697 param->board_cal_version = event->board_cal_version; 21698 param->cal_ok = event->cal_status; 21699 21700 return QDF_STATUS_SUCCESS; 21701 } 21702 21703 /* 21704 * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config 21705 * @wmi_handle: wmi handle 21706 * @params: pointer to wmi_btm_config 21707 * 21708 * Return: QDF_STATUS 21709 */ 21710 static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, 21711 struct wmi_btm_config *params) 21712 { 21713 21714 wmi_btm_config_fixed_param *cmd; 21715 wmi_buf_t buf; 21716 uint32_t len; 21717 21718 len = sizeof(*cmd); 21719 buf = wmi_buf_alloc(wmi_handle, len); 21720 if (!buf) { 21721 qdf_print("%s:wmi_buf_alloc failed", __func__); 21722 return QDF_STATUS_E_NOMEM; 21723 } 21724 21725 cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf); 21726 WMITLV_SET_HDR(&cmd->tlv_header, 21727 WMITLV_TAG_STRUC_wmi_btm_config_fixed_param, 21728 WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param)); 21729 cmd->vdev_id = params->vdev_id; 21730 cmd->flags = params->btm_offload_config; 21731 cmd->max_attempt_cnt = params->btm_max_attempt_cnt; 21732 cmd->solicited_timeout_ms = params->btm_solicited_timeout; 21733 cmd->stick_time_seconds = params->btm_sticky_time; 21734 21735 wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0); 21736 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21737 WMI_ROAM_BTM_CONFIG_CMDID)) { 21738 WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID", 21739 __func__); 21740 wmi_buf_free(buf); 21741 return QDF_STATUS_E_FAILURE; 21742 } 21743 21744 return QDF_STATUS_SUCCESS; 21745 } 21746 21747 /** 21748 * send_obss_detection_cfg_cmd_tlv() - send obss detection 21749 * configurations to firmware. 21750 * @wmi_handle: wmi handle 21751 * @obss_cfg_param: obss detection configurations 21752 * 21753 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 21754 * 21755 * Return: QDF_STATUS 21756 */ 21757 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 21758 struct wmi_obss_detection_cfg_param *obss_cfg_param) 21759 { 21760 wmi_buf_t buf; 21761 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 21762 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 21763 21764 buf = wmi_buf_alloc(wmi_handle, len); 21765 if (!buf) { 21766 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 21767 return QDF_STATUS_E_NOMEM; 21768 } 21769 21770 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 21771 WMITLV_SET_HDR(&cmd->tlv_header, 21772 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 21773 WMITLV_GET_STRUCT_TLVLEN 21774 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 21775 21776 cmd->vdev_id = obss_cfg_param->vdev_id; 21777 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 21778 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 21779 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 21780 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 21781 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 21782 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 21783 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 21784 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 21785 21786 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 21787 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21788 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 21789 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 21790 wmi_buf_free(buf); 21791 return QDF_STATUS_E_FAILURE; 21792 } 21793 21794 return QDF_STATUS_SUCCESS; 21795 } 21796 21797 /** 21798 * extract_obss_detection_info_tlv() - Extract obss detection info 21799 * received from firmware. 21800 * @evt_buf: pointer to event buffer 21801 * @obss_detection: Pointer to hold obss detection info 21802 * 21803 * Return: QDF_STATUS 21804 */ 21805 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 21806 struct wmi_obss_detect_info 21807 *obss_detection) 21808 { 21809 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 21810 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 21811 21812 if (!obss_detection) { 21813 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 21814 return QDF_STATUS_E_INVAL; 21815 } 21816 21817 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 21818 if (!param_buf) { 21819 WMI_LOGE("%s: Invalid evt_buf", __func__); 21820 return QDF_STATUS_E_INVAL; 21821 } 21822 21823 fix_param = param_buf->fixed_param; 21824 obss_detection->vdev_id = fix_param->vdev_id; 21825 obss_detection->matched_detection_masks = 21826 fix_param->matched_detection_masks; 21827 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 21828 &obss_detection->matched_bssid_addr[0]); 21829 switch (fix_param->reason) { 21830 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 21831 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 21832 break; 21833 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 21834 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 21835 break; 21836 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 21837 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 21838 break; 21839 default: 21840 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 21841 return QDF_STATUS_E_INVAL; 21842 } 21843 21844 return QDF_STATUS_SUCCESS; 21845 } 21846 21847 /** 21848 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 21849 * @wmi_handle: wmi handle 21850 * @params: pointer to request structure 21851 * 21852 * Return: QDF_STATUS 21853 */ 21854 static QDF_STATUS 21855 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 21856 struct wmi_roam_scan_stats_req *params) 21857 { 21858 wmi_buf_t buf; 21859 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 21860 WMITLV_TAG_ID tag; 21861 uint32_t size; 21862 uint32_t len = sizeof(*cmd); 21863 21864 buf = wmi_buf_alloc(wmi_handle, len); 21865 if (!buf) { 21866 WMI_LOGE(FL("Failed to allocate wmi buffer")); 21867 return QDF_STATUS_E_FAILURE; 21868 } 21869 21870 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 21871 21872 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 21873 size = WMITLV_GET_STRUCT_TLVLEN( 21874 wmi_request_roam_scan_stats_cmd_fixed_param); 21875 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 21876 21877 cmd->vdev_id = params->vdev_id; 21878 21879 WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id); 21880 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21881 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 21882 WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID", 21883 __func__); 21884 wmi_buf_free(buf); 21885 return QDF_STATUS_E_FAILURE; 21886 } 21887 21888 return QDF_STATUS_SUCCESS; 21889 } 21890 21891 /** 21892 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 21893 * @wmi_handle: wmi handle 21894 * @evt_buf: pointer to event buffer 21895 * @vdev_id: output pointer to hold vdev id 21896 * @res_param: output pointer to hold the allocated response 21897 * 21898 * Return: QDF_STATUS 21899 */ 21900 static QDF_STATUS 21901 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21902 uint32_t *vdev_id, 21903 struct wmi_roam_scan_stats_res **res_param) 21904 { 21905 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 21906 wmi_roam_scan_stats_event_fixed_param *fixed_param; 21907 uint32_t *client_id = NULL; 21908 wmi_roaming_timestamp *timestamp = NULL; 21909 uint32_t *num_channels = NULL; 21910 uint32_t *chan_info = NULL; 21911 wmi_mac_addr *old_bssid = NULL; 21912 uint32_t *is_roaming_success = NULL; 21913 wmi_mac_addr *new_bssid = NULL; 21914 uint32_t *num_roam_candidates = NULL; 21915 wmi_roam_scan_trigger_reason *roam_reason = NULL; 21916 wmi_mac_addr *bssid = NULL; 21917 uint32_t *score = NULL; 21918 uint32_t *channel = NULL; 21919 uint32_t *rssi = NULL; 21920 int chan_idx = 0, cand_idx = 0; 21921 uint32_t total_len; 21922 struct wmi_roam_scan_stats_res *res; 21923 uint32_t i, j; 21924 uint32_t num_scans; 21925 21926 *res_param = NULL; 21927 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 21928 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 21929 if (!param_buf) { 21930 WMI_LOGE(FL("Invalid roam scan stats event")); 21931 return QDF_STATUS_E_INVAL; 21932 } 21933 21934 fixed_param = param_buf->fixed_param; 21935 total_len = sizeof(*res) + fixed_param->num_roam_scans * 21936 sizeof(struct wmi_roam_scan_stats_params); 21937 21938 *vdev_id = fixed_param->vdev_id; 21939 num_scans = fixed_param->num_roam_scans; 21940 21941 res = qdf_mem_malloc(total_len); 21942 if (!res) { 21943 WMI_LOGE("Failed to allocate roam scan stats response memory"); 21944 return QDF_STATUS_E_NOMEM; 21945 } 21946 21947 if (!num_scans) { 21948 *res_param = res; 21949 return QDF_STATUS_SUCCESS; 21950 } 21951 21952 if (param_buf->client_id && 21953 param_buf->num_client_id == num_scans) 21954 client_id = param_buf->client_id; 21955 21956 if (param_buf->timestamp && 21957 param_buf->num_timestamp == num_scans) 21958 timestamp = param_buf->timestamp; 21959 21960 if (param_buf->old_bssid && 21961 param_buf->num_old_bssid == num_scans) 21962 old_bssid = param_buf->old_bssid; 21963 21964 if (param_buf->new_bssid && 21965 param_buf->num_new_bssid == num_scans) 21966 new_bssid = param_buf->new_bssid; 21967 21968 if (param_buf->is_roaming_success && 21969 param_buf->num_is_roaming_success == num_scans) 21970 is_roaming_success = param_buf->is_roaming_success; 21971 21972 if (param_buf->roam_reason && 21973 param_buf->num_roam_reason == num_scans) 21974 roam_reason = param_buf->roam_reason; 21975 21976 if (param_buf->num_channels && 21977 param_buf->num_num_channels == num_scans) { 21978 uint32_t count, chan_info_sum = 0; 21979 21980 num_channels = param_buf->num_channels; 21981 for (count = 0; count < param_buf->num_num_channels; count++) 21982 chan_info_sum += param_buf->num_channels[count]; 21983 21984 if (param_buf->chan_info && 21985 param_buf->num_chan_info == chan_info_sum) 21986 chan_info = param_buf->chan_info; 21987 } 21988 21989 if (param_buf->num_roam_candidates && 21990 param_buf->num_num_roam_candidates == num_scans) { 21991 uint32_t count, roam_cand_sum = 0; 21992 21993 num_roam_candidates = param_buf->num_roam_candidates; 21994 for (count = 0; count < param_buf->num_num_roam_candidates; 21995 count++) 21996 roam_cand_sum += param_buf->num_roam_candidates[count]; 21997 21998 if (param_buf->bssid && 21999 param_buf->num_bssid == roam_cand_sum) 22000 bssid = param_buf->bssid; 22001 22002 if (param_buf->score && 22003 param_buf->num_score == roam_cand_sum) 22004 score = param_buf->score; 22005 22006 if (param_buf->channel && 22007 param_buf->num_channel == roam_cand_sum) 22008 channel = param_buf->channel; 22009 22010 if (param_buf->rssi && 22011 param_buf->num_rssi == roam_cand_sum) 22012 rssi = param_buf->rssi; 22013 } 22014 22015 res->num_roam_scans = num_scans; 22016 for (i = 0; i < num_scans; i++) { 22017 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 22018 22019 if (timestamp) 22020 roam->time_stamp = timestamp[i].lower32bit | 22021 (timestamp[i].upper32bit << 31); 22022 22023 if (client_id) 22024 roam->client_id = client_id[i]; 22025 22026 if (num_channels) { 22027 roam->num_scan_chans = num_channels[i]; 22028 if (chan_info) { 22029 for (j = 0; j < num_channels[i]; j++) 22030 roam->scan_freqs[j] = 22031 chan_info[chan_idx++]; 22032 } 22033 } 22034 22035 if (is_roaming_success) 22036 roam->is_roam_successful = is_roaming_success[i]; 22037 22038 if (roam_reason) { 22039 roam->trigger_id = roam_reason[i].trigger_id; 22040 roam->trigger_value = roam_reason[i].trigger_value; 22041 } 22042 22043 if (num_roam_candidates) { 22044 roam->num_roam_candidates = num_roam_candidates[i]; 22045 22046 for (j = 0; j < num_roam_candidates[i]; j++) { 22047 if (score) 22048 roam->cand[j].score = score[cand_idx]; 22049 if (rssi) 22050 roam->cand[j].rssi = rssi[cand_idx]; 22051 if (channel) 22052 roam->cand[j].freq = 22053 channel[cand_idx]; 22054 22055 if (bssid) 22056 WMI_MAC_ADDR_TO_CHAR_ARRAY( 22057 &bssid[cand_idx], 22058 roam->cand[j].bssid); 22059 22060 cand_idx++; 22061 } 22062 } 22063 22064 if (old_bssid) 22065 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 22066 roam->old_bssid); 22067 22068 if (new_bssid) 22069 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 22070 roam->new_bssid); 22071 } 22072 22073 *res_param = res; 22074 22075 return QDF_STATUS_SUCCESS; 22076 } 22077 22078 /** 22079 * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params 22080 * @wmi_handle: wmi handler 22081 * @params: pointer to 11k offload params 22082 * 22083 * Return: 0 for success and non zero for failure 22084 */ 22085 static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle, 22086 struct wmi_11k_offload_params *params) 22087 { 22088 wmi_11k_offload_report_fixed_param *cmd; 22089 wmi_buf_t buf; 22090 QDF_STATUS status; 22091 uint8_t *buf_ptr; 22092 wmi_neighbor_report_11k_offload_tlv_param 22093 *neighbor_report_offload_params; 22094 wmi_neighbor_report_offload *neighbor_report_offload; 22095 22096 uint32_t len = sizeof(*cmd); 22097 22098 if (params->offload_11k_bitmask & 22099 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) 22100 len += WMI_TLV_HDR_SIZE + 22101 sizeof(wmi_neighbor_report_11k_offload_tlv_param); 22102 22103 buf = wmi_buf_alloc(wmi_handle, len); 22104 if (!buf) { 22105 WMI_LOGP("%s: failed to allocate memory for 11k offload params", 22106 __func__); 22107 return QDF_STATUS_E_NOMEM; 22108 } 22109 22110 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22111 cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr; 22112 22113 WMITLV_SET_HDR(&cmd->tlv_header, 22114 WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param, 22115 WMITLV_GET_STRUCT_TLVLEN( 22116 wmi_11k_offload_report_fixed_param)); 22117 22118 cmd->vdev_id = params->vdev_id; 22119 cmd->offload_11k = params->offload_11k_bitmask; 22120 22121 if (params->offload_11k_bitmask & 22122 WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) { 22123 buf_ptr += sizeof(wmi_11k_offload_report_fixed_param); 22124 22125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 22126 sizeof(wmi_neighbor_report_11k_offload_tlv_param)); 22127 buf_ptr += WMI_TLV_HDR_SIZE; 22128 22129 neighbor_report_offload_params = 22130 (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr; 22131 WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header, 22132 WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param, 22133 WMITLV_GET_STRUCT_TLVLEN( 22134 wmi_neighbor_report_11k_offload_tlv_param)); 22135 22136 neighbor_report_offload = &neighbor_report_offload_params-> 22137 neighbor_rep_ofld_params; 22138 22139 neighbor_report_offload->time_offset = 22140 params->neighbor_report_params.time_offset; 22141 neighbor_report_offload->low_rssi_offset = 22142 params->neighbor_report_params.low_rssi_offset; 22143 neighbor_report_offload->bmiss_count_trigger = 22144 params->neighbor_report_params.bmiss_count_trigger; 22145 neighbor_report_offload->per_threshold_offset = 22146 params->neighbor_report_params.per_threshold_offset; 22147 neighbor_report_offload->neighbor_report_cache_timeout = 22148 params->neighbor_report_params. 22149 neighbor_report_cache_timeout; 22150 neighbor_report_offload->max_neighbor_report_req_cap = 22151 params->neighbor_report_params. 22152 max_neighbor_report_req_cap; 22153 neighbor_report_offload->ssid.ssid_len = 22154 params->neighbor_report_params.ssid.length; 22155 qdf_mem_copy(neighbor_report_offload->ssid.ssid, 22156 ¶ms->neighbor_report_params.ssid.mac_ssid, 22157 neighbor_report_offload->ssid.ssid_len); 22158 } 22159 22160 wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0); 22161 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22162 WMI_11K_OFFLOAD_REPORT_CMDID); 22163 if (status != QDF_STATUS_SUCCESS) { 22164 WMI_LOGE("%s: failed to send 11k offload command %d", 22165 __func__, status); 22166 wmi_buf_free(buf); 22167 } 22168 22169 return status; 22170 } 22171 22172 /** 22173 * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report 22174 * command 22175 * @wmi_handle: wmi handler 22176 * @params: pointer to neighbor report invoke params 22177 * 22178 * Return: 0 for success and non zero for failure 22179 */ 22180 static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle, 22181 struct wmi_invoke_neighbor_report_params *params) 22182 { 22183 wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd; 22184 wmi_buf_t buf; 22185 QDF_STATUS status; 22186 uint8_t *buf_ptr; 22187 uint32_t len = sizeof(*cmd); 22188 22189 buf = wmi_buf_alloc(wmi_handle, len); 22190 if (!buf) { 22191 WMI_LOGP("%s:failed to allocate memory for neighbor invoke cmd", 22192 __func__); 22193 return QDF_STATUS_E_NOMEM; 22194 } 22195 22196 buf_ptr = (uint8_t *) wmi_buf_data(buf); 22197 cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr; 22198 22199 WMITLV_SET_HDR(&cmd->tlv_header, 22200 WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param, 22201 WMITLV_GET_STRUCT_TLVLEN( 22202 wmi_11k_offload_invoke_neighbor_report_fixed_param)); 22203 22204 cmd->vdev_id = params->vdev_id; 22205 cmd->flags = params->send_resp_to_host; 22206 22207 cmd->ssid.ssid_len = params->ssid.length; 22208 qdf_mem_copy(cmd->ssid.ssid, 22209 ¶ms->ssid.mac_ssid, 22210 cmd->ssid.ssid_len); 22211 22212 wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0); 22213 status = wmi_unified_cmd_send(wmi_handle, buf, len, 22214 WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID); 22215 if (status != QDF_STATUS_SUCCESS) { 22216 WMI_LOGE("%s: failed to send invoke neighbor report command %d", 22217 __func__, status); 22218 wmi_buf_free(buf); 22219 } 22220 22221 return status; 22222 } 22223 22224 #ifdef WLAN_SUPPORT_GREEN_AP 22225 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 22226 uint8_t *evt_buf, 22227 struct wlan_green_ap_egap_status_info *egap_status_info_params) 22228 { 22229 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 22230 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 22231 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 22232 22233 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 22234 if (!param_buf) { 22235 WMI_LOGE("Invalid EGAP Info status event buffer"); 22236 return QDF_STATUS_E_INVAL; 22237 } 22238 22239 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 22240 param_buf->fixed_param; 22241 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 22242 param_buf->chainmask_list; 22243 22244 egap_status_info_params->status = egap_info_event->status; 22245 egap_status_info_params->mac_id = chainmask_event->mac_id; 22246 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 22247 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 22248 22249 return QDF_STATUS_SUCCESS; 22250 } 22251 #endif 22252 22253 /* 22254 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 22255 * updating bss color change within firmware when AP announces bss color change. 22256 * @wmi_handle: wmi handle 22257 * @vdev_id: vdev ID 22258 * @enable: enable bss color change within firmware 22259 * 22260 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 22261 * 22262 * Return: QDF_STATUS 22263 */ 22264 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 22265 uint32_t vdev_id, 22266 bool enable) 22267 { 22268 wmi_buf_t buf; 22269 wmi_bss_color_change_enable_fixed_param *cmd; 22270 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 22271 22272 buf = wmi_buf_alloc(wmi_handle, len); 22273 if (!buf) { 22274 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22275 return QDF_STATUS_E_NOMEM; 22276 } 22277 22278 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 22279 WMITLV_SET_HDR(&cmd->tlv_header, 22280 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 22281 WMITLV_GET_STRUCT_TLVLEN 22282 (wmi_bss_color_change_enable_fixed_param)); 22283 cmd->vdev_id = vdev_id; 22284 cmd->enable = enable; 22285 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 22286 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22287 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 22288 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 22289 wmi_buf_free(buf); 22290 return QDF_STATUS_E_FAILURE; 22291 } 22292 22293 return QDF_STATUS_SUCCESS; 22294 } 22295 22296 /** 22297 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 22298 * configurations to firmware. 22299 * @wmi_handle: wmi handle 22300 * @cfg_param: obss detection configurations 22301 * 22302 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 22303 * 22304 * Return: QDF_STATUS 22305 */ 22306 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 22307 wmi_unified_t wmi_handle, 22308 struct wmi_obss_color_collision_cfg_param *cfg_param) 22309 { 22310 wmi_buf_t buf; 22311 wmi_obss_color_collision_det_config_fixed_param *cmd; 22312 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 22313 22314 buf = wmi_buf_alloc(wmi_handle, len); 22315 if (!buf) { 22316 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 22317 return QDF_STATUS_E_NOMEM; 22318 } 22319 22320 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 22321 buf); 22322 WMITLV_SET_HDR(&cmd->tlv_header, 22323 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 22324 WMITLV_GET_STRUCT_TLVLEN 22325 (wmi_obss_color_collision_det_config_fixed_param)); 22326 cmd->vdev_id = cfg_param->vdev_id; 22327 cmd->flags = cfg_param->flags; 22328 cmd->current_bss_color = cfg_param->current_bss_color; 22329 cmd->detection_period_ms = cfg_param->detection_period_ms; 22330 cmd->scan_period_ms = cfg_param->scan_period_ms; 22331 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 22332 22333 switch (cfg_param->evt_type) { 22334 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 22335 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 22336 break; 22337 case OBSS_COLOR_COLLISION_DETECTION: 22338 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 22339 break; 22340 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22341 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22342 break; 22343 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 22344 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 22345 break; 22346 default: 22347 WMI_LOGE("%s: invalid event type: %d", 22348 __func__, cfg_param->evt_type); 22349 wmi_buf_free(buf); 22350 return QDF_STATUS_E_FAILURE; 22351 } 22352 22353 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 22354 if (wmi_unified_cmd_send(wmi_handle, buf, len, 22355 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 22356 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 22357 __func__, cfg_param->vdev_id); 22358 wmi_buf_free(buf); 22359 return QDF_STATUS_E_FAILURE; 22360 } 22361 22362 return QDF_STATUS_SUCCESS; 22363 } 22364 22365 /** 22366 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 22367 * received from firmware. 22368 * @evt_buf: pointer to event buffer 22369 * @info: Pointer to hold bss collision info 22370 * 22371 * Return: QDF_STATUS 22372 */ 22373 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 22374 struct wmi_obss_color_collision_info *info) 22375 { 22376 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 22377 wmi_obss_color_collision_evt_fixed_param *fix_param; 22378 22379 if (!info) { 22380 WMI_LOGE("%s: Invalid obss color buffer", __func__); 22381 return QDF_STATUS_E_INVAL; 22382 } 22383 22384 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 22385 evt_buf; 22386 if (!param_buf) { 22387 WMI_LOGE("%s: Invalid evt_buf", __func__); 22388 return QDF_STATUS_E_INVAL; 22389 } 22390 22391 fix_param = param_buf->fixed_param; 22392 info->vdev_id = fix_param->vdev_id; 22393 info->obss_color_bitmap_bit0to31 = fix_param->bss_color_bitmap_bit0to31; 22394 info->obss_color_bitmap_bit32to63 = 22395 fix_param->bss_color_bitmap_bit32to63; 22396 22397 switch (fix_param->evt_type) { 22398 case WMI_BSS_COLOR_COLLISION_DISABLE: 22399 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 22400 break; 22401 case WMI_BSS_COLOR_COLLISION_DETECTION: 22402 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 22403 break; 22404 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 22405 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 22406 break; 22407 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 22408 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 22409 break; 22410 default: 22411 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 22412 __func__, fix_param->evt_type, fix_param->vdev_id); 22413 return QDF_STATUS_E_FAILURE; 22414 } 22415 22416 return QDF_STATUS_SUCCESS; 22417 } 22418 22419 /* 22420 * extract_comb_phyerr_tlv() - extract comb phy error from event 22421 * @wmi_handle: wmi handle 22422 * @evt_buf: pointer to event buffer 22423 * @datalen: data length of event buffer 22424 * @buf_offset: Pointer to hold value of current event buffer offset 22425 * post extraction 22426 * @phyerr: Pointer to hold phyerr 22427 * 22428 * Return: QDF_STATUS 22429 */ 22430 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 22431 void *evt_buf, 22432 uint16_t datalen, 22433 uint16_t *buf_offset, 22434 wmi_host_phyerr_t *phyerr) 22435 { 22436 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 22437 wmi_comb_phyerr_rx_hdr *pe_hdr; 22438 22439 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 22440 if (!param_tlvs) { 22441 WMI_LOGD("%s: Received null data from FW", __func__); 22442 return QDF_STATUS_E_FAILURE; 22443 } 22444 22445 pe_hdr = param_tlvs->hdr; 22446 if (!pe_hdr) { 22447 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 22448 return QDF_STATUS_E_FAILURE; 22449 } 22450 22451 /* Ensure it's at least the size of the header */ 22452 if (datalen < sizeof(*pe_hdr)) { 22453 WMI_LOGD("%s: Expected minimum size %zu, received %d", 22454 __func__, sizeof(*pe_hdr), datalen); 22455 return QDF_STATUS_E_FAILURE; 22456 } 22457 22458 phyerr->pdev_id = wmi_handle->ops-> 22459 convert_pdev_id_target_to_host(pe_hdr->pdev_id); 22460 phyerr->tsf64 = pe_hdr->tsf_l32; 22461 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 22462 phyerr->bufp = param_tlvs->bufp; 22463 phyerr->buf_len = pe_hdr->buf_len; 22464 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 22465 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 22466 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 22467 22468 return QDF_STATUS_SUCCESS; 22469 } 22470 22471 /** 22472 * extract_single_phyerr_tlv() - extract single phy error from event 22473 * @wmi_handle: wmi handle 22474 * @evt_buf: pointer to event buffer 22475 * @datalen: data length of event buffer 22476 * @buf_offset: Pointer to hold value of current event buffer offset 22477 * post extraction 22478 * @phyerr: Pointer to hold phyerr 22479 * 22480 * Return: QDF_STATUS 22481 */ 22482 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 22483 void *evt_buf, 22484 uint16_t datalen, 22485 uint16_t *buf_offset, 22486 wmi_host_phyerr_t *phyerr) 22487 { 22488 wmi_single_phyerr_rx_event *ev; 22489 uint16_t n = *buf_offset; 22490 uint8_t *data = (uint8_t *)evt_buf; 22491 22492 if (n < datalen) { 22493 if ((datalen - n) < sizeof(ev->hdr)) { 22494 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 22495 __func__, datalen, n, sizeof(ev->hdr)); 22496 return QDF_STATUS_E_FAILURE; 22497 } 22498 22499 /* 22500 * Obtain a pointer to the beginning of the current event. 22501 * data[0] is the beginning of the WMI payload. 22502 */ 22503 ev = (wmi_single_phyerr_rx_event *)&data[n]; 22504 22505 /* 22506 * Sanity check the buffer length of the event against 22507 * what we currently have. 22508 * 22509 * Since buf_len is 32 bits, we check if it overflows 22510 * a large 32 bit value. It's not 0x7fffffff because 22511 * we increase n by (buf_len + sizeof(hdr)), which would 22512 * in itself cause n to overflow. 22513 * 22514 * If "int" is 64 bits then this becomes a moot point. 22515 */ 22516 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 22517 WMI_LOGD("%s: buf_len is garbage 0x%x", 22518 __func__, ev->hdr.buf_len); 22519 return QDF_STATUS_E_FAILURE; 22520 } 22521 22522 if ((n + ev->hdr.buf_len) > datalen) { 22523 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 22524 __func__, n, ev->hdr.buf_len, datalen); 22525 return QDF_STATUS_E_FAILURE; 22526 } 22527 22528 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 22529 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 22530 phyerr->bufp = &ev->bufp[0]; 22531 phyerr->buf_len = ev->hdr.buf_len; 22532 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 22533 22534 /* 22535 * Advance the buffer pointer to the next PHY error. 22536 * buflen is the length of this payload, so we need to 22537 * advance past the current header _AND_ the payload. 22538 */ 22539 n += sizeof(*ev) + ev->hdr.buf_len; 22540 } 22541 *buf_offset = n; 22542 22543 return QDF_STATUS_SUCCESS; 22544 } 22545 22546 /** 22547 * extract_esp_estimation_ev_param_tlv() - extract air time from event 22548 * @wmi_handle: wmi handle 22549 * @evt_buf: pointer to event buffer 22550 * @param: Pointer to hold esp event 22551 * 22552 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 22553 */ 22554 static QDF_STATUS 22555 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 22556 void *evt_buf, 22557 struct esp_estimation_event *param) 22558 { 22559 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 22560 wmi_esp_estimate_event_fixed_param *esp_event; 22561 22562 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 22563 if (!param_buf) { 22564 WMI_LOGE("Invalid ESP Estimate Event buffer"); 22565 return QDF_STATUS_E_INVAL; 22566 } 22567 esp_event = param_buf->fixed_param; 22568 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 22569 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 22570 esp_event->pdev_id); 22571 22572 return QDF_STATUS_SUCCESS; 22573 } 22574 22575 struct wmi_ops tlv_ops = { 22576 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 22577 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 22578 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 22579 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 22580 .send_hidden_ssid_vdev_restart_cmd = 22581 send_hidden_ssid_vdev_restart_cmd_tlv, 22582 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 22583 .send_peer_param_cmd = send_peer_param_cmd_tlv, 22584 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 22585 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 22586 .send_peer_create_cmd = send_peer_create_cmd_tlv, 22587 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 22588 .send_peer_rx_reorder_queue_setup_cmd = 22589 send_peer_rx_reorder_queue_setup_cmd_tlv, 22590 .send_peer_rx_reorder_queue_remove_cmd = 22591 send_peer_rx_reorder_queue_remove_cmd_tlv, 22592 .send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv, 22593 .send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv, 22594 .send_peer_update_wds_entry_cmd = send_peer_update_wds_entry_cmd_tlv, 22595 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 22596 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 22597 .send_pdev_get_tpc_config_cmd = send_pdev_get_tpc_config_cmd_tlv, 22598 .send_suspend_cmd = send_suspend_cmd_tlv, 22599 .send_resume_cmd = send_resume_cmd_tlv, 22600 #ifdef FEATURE_WLAN_D0WOW 22601 .send_d0wow_enable_cmd = send_d0wow_enable_cmd_tlv, 22602 .send_d0wow_disable_cmd = send_d0wow_disable_cmd_tlv, 22603 #endif 22604 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 22605 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 22606 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 22607 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 22608 #ifdef FEATURE_FW_LOG_PARSING 22609 .send_dbglog_cmd = send_dbglog_cmd_tlv, 22610 #endif 22611 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 22612 .send_stats_request_cmd = send_stats_request_cmd_tlv, 22613 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 22614 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 22615 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 22616 .send_beacon_send_cmd = send_beacon_send_cmd_tlv, 22617 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 22618 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 22619 .send_scan_start_cmd = send_scan_start_cmd_tlv, 22620 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 22621 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 22622 .send_mgmt_cmd = send_mgmt_cmd_tlv, 22623 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 22624 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 22625 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 22626 .send_set_sta_uapsd_auto_trig_cmd = 22627 send_set_sta_uapsd_auto_trig_cmd_tlv, 22628 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 22629 .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, 22630 .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, 22631 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 22632 .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, 22633 .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, 22634 #endif 22635 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 22636 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 22637 #ifdef WLAN_FEATURE_DSRC 22638 .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, 22639 .send_ocb_get_tsf_timer_cmd = send_ocb_get_tsf_timer_cmd_tlv, 22640 .send_dcc_clear_stats_cmd = send_dcc_clear_stats_cmd_tlv, 22641 .send_dcc_get_stats_cmd = send_dcc_get_stats_cmd_tlv, 22642 .send_dcc_update_ndl_cmd = send_dcc_update_ndl_cmd_tlv, 22643 .send_ocb_set_config_cmd = send_ocb_set_config_cmd_tlv, 22644 .send_ocb_stop_timing_advert_cmd = send_ocb_stop_timing_advert_cmd_tlv, 22645 .send_ocb_start_timing_advert_cmd = 22646 send_ocb_start_timing_advert_cmd_tlv, 22647 .extract_ocb_chan_config_resp = extract_ocb_channel_config_resp_tlv, 22648 .extract_ocb_tsf_timer = extract_ocb_tsf_timer_tlv, 22649 .extract_dcc_update_ndl_resp = extract_ocb_ndl_resp_tlv, 22650 .extract_dcc_stats = extract_ocb_dcc_stats_tlv, 22651 #endif 22652 .send_set_enable_disable_mcc_adaptive_scheduler_cmd = 22653 send_set_enable_disable_mcc_adaptive_scheduler_cmd_tlv, 22654 .send_set_mcc_channel_time_latency_cmd = 22655 send_set_mcc_channel_time_latency_cmd_tlv, 22656 .send_set_mcc_channel_time_quota_cmd = 22657 send_set_mcc_channel_time_quota_cmd_tlv, 22658 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 22659 .send_lro_config_cmd = send_lro_config_cmd_tlv, 22660 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 22661 .send_set_sta_sa_query_param_cmd = send_set_sta_sa_query_param_cmd_tlv, 22662 .send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv, 22663 .send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv, 22664 .send_probe_rsp_tmpl_send_cmd = 22665 send_probe_rsp_tmpl_send_cmd_tlv, 22666 .send_p2p_go_set_beacon_ie_cmd = 22667 send_p2p_go_set_beacon_ie_cmd_tlv, 22668 .send_setup_install_key_cmd = 22669 send_setup_install_key_cmd_tlv, 22670 .send_set_gateway_params_cmd = 22671 send_set_gateway_params_cmd_tlv, 22672 .send_set_rssi_monitoring_cmd = 22673 send_set_rssi_monitoring_cmd_tlv, 22674 .send_scan_probe_setoui_cmd = 22675 send_scan_probe_setoui_cmd_tlv, 22676 .send_roam_scan_offload_rssi_thresh_cmd = 22677 send_roam_scan_offload_rssi_thresh_cmd_tlv, 22678 .send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv, 22679 .send_roam_scan_filter_cmd = 22680 send_roam_scan_filter_cmd_tlv, 22681 #ifdef IPA_OFFLOAD 22682 .send_ipa_offload_control_cmd = 22683 send_ipa_offload_control_cmd_tlv, 22684 #endif 22685 .send_plm_stop_cmd = send_plm_stop_cmd_tlv, 22686 .send_plm_start_cmd = send_plm_start_cmd_tlv, 22687 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 22688 .send_pno_start_cmd = send_pno_start_cmd_tlv, 22689 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 22690 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 22691 .send_set_ric_req_cmd = send_set_ric_req_cmd_tlv, 22692 .send_process_roam_synch_complete_cmd = 22693 send_process_roam_synch_complete_cmd_tlv, 22694 #endif 22695 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22696 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 22697 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 22698 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 22699 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 22700 .send_congestion_cmd = send_congestion_cmd_tlv, 22701 .send_snr_request_cmd = send_snr_request_cmd_tlv, 22702 .send_snr_cmd = send_snr_cmd_tlv, 22703 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 22704 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 22705 .send_add_wow_wakeup_event_cmd = send_add_wow_wakeup_event_cmd_tlv, 22706 .send_wow_patterns_to_fw_cmd = send_wow_patterns_to_fw_cmd_tlv, 22707 .send_enable_arp_ns_offload_cmd = send_enable_arp_ns_offload_cmd_tlv, 22708 .send_add_clear_mcbc_filter_cmd = send_add_clear_mcbc_filter_cmd_tlv, 22709 .send_multiple_add_clear_mcbc_filter_cmd = 22710 send_multiple_add_clear_mcbc_filter_cmd_tlv, 22711 .send_conf_hw_filter_cmd = send_conf_hw_filter_cmd_tlv, 22712 .send_gtk_offload_cmd = send_gtk_offload_cmd_tlv, 22713 .send_process_gtk_offload_getinfo_cmd = 22714 send_process_gtk_offload_getinfo_cmd_tlv, 22715 .send_enable_enhance_multicast_offload_cmd = 22716 send_enable_enhance_multicast_offload_tlv, 22717 .extract_gtk_rsp_event = extract_gtk_rsp_event_tlv, 22718 #ifdef FEATURE_WLAN_RA_FILTERING 22719 .send_wow_sta_ra_filter_cmd = send_wow_sta_ra_filter_cmd_tlv, 22720 #endif 22721 .send_action_frame_patterns_cmd = send_action_frame_patterns_cmd_tlv, 22722 .send_lphb_config_hbenable_cmd = send_lphb_config_hbenable_cmd_tlv, 22723 .send_lphb_config_tcp_params_cmd = send_lphb_config_tcp_params_cmd_tlv, 22724 .send_lphb_config_tcp_pkt_filter_cmd = 22725 send_lphb_config_tcp_pkt_filter_cmd_tlv, 22726 .send_lphb_config_udp_params_cmd = send_lphb_config_udp_params_cmd_tlv, 22727 .send_lphb_config_udp_pkt_filter_cmd = 22728 send_lphb_config_udp_pkt_filter_cmd_tlv, 22729 #ifdef WLAN_FEATURE_PACKET_FILTERING 22730 .send_enable_disable_packet_filter_cmd = 22731 send_enable_disable_packet_filter_cmd_tlv, 22732 .send_config_packet_filter_cmd = send_config_packet_filter_cmd_tlv, 22733 #endif 22734 #endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ 22735 #ifdef CONFIG_MCL 22736 .send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv, 22737 .send_get_link_speed_cmd = send_get_link_speed_cmd_tlv, 22738 .send_bcn_buf_ll_cmd = send_bcn_buf_ll_cmd_tlv, 22739 .send_roam_scan_offload_mode_cmd = 22740 send_roam_scan_offload_mode_cmd_tlv, 22741 #ifndef REMOVE_PKT_LOG 22742 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 22743 #endif 22744 .send_roam_scan_offload_ap_profile_cmd = 22745 send_roam_scan_offload_ap_profile_cmd_tlv, 22746 #endif 22747 #ifdef WLAN_SUPPORT_GREEN_AP 22748 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 22749 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 22750 .extract_green_ap_egap_status_info = 22751 extract_green_ap_egap_status_info_tlv, 22752 #endif 22753 .send_fw_profiling_cmd = send_fw_profiling_cmd_tlv, 22754 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 22755 .send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv, 22756 .send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv, 22757 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 22758 #ifdef WLAN_FEATURE_CIF_CFR 22759 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 22760 #endif 22761 .send_dbr_cfg_cmd = send_dbr_cfg_cmd_tlv, 22762 .send_dfs_phyerr_filter_offload_en_cmd = 22763 send_dfs_phyerr_filter_offload_en_cmd_tlv, 22764 .send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv, 22765 .send_host_wakeup_ind_to_fw_cmd = send_host_wakeup_ind_to_fw_cmd_tlv, 22766 .send_del_ts_cmd = send_del_ts_cmd_tlv, 22767 .send_aggr_qos_cmd = send_aggr_qos_cmd_tlv, 22768 .send_add_ts_cmd = send_add_ts_cmd_tlv, 22769 .send_process_add_periodic_tx_ptrn_cmd = 22770 send_process_add_periodic_tx_ptrn_cmd_tlv, 22771 .send_process_del_periodic_tx_ptrn_cmd = 22772 send_process_del_periodic_tx_ptrn_cmd_tlv, 22773 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 22774 .send_enable_ext_wow_cmd = send_enable_ext_wow_cmd_tlv, 22775 .send_set_app_type2_params_in_fw_cmd = 22776 send_set_app_type2_params_in_fw_cmd_tlv, 22777 .send_set_auto_shutdown_timer_cmd = 22778 send_set_auto_shutdown_timer_cmd_tlv, 22779 .send_nan_req_cmd = send_nan_req_cmd_tlv, 22780 .send_process_dhcpserver_offload_cmd = 22781 send_process_dhcpserver_offload_cmd_tlv, 22782 .send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv, 22783 .send_process_ch_avoid_update_cmd = 22784 send_process_ch_avoid_update_cmd_tlv, 22785 .send_pdev_set_regdomain_cmd = 22786 send_pdev_set_regdomain_cmd_tlv, 22787 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 22788 .send_set_tdls_offchan_mode_cmd = send_set_tdls_offchan_mode_cmd_tlv, 22789 .send_update_fw_tdls_state_cmd = send_update_fw_tdls_state_cmd_tlv, 22790 .send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv, 22791 .send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv, 22792 .save_fw_version_cmd = save_fw_version_cmd_tlv, 22793 .check_and_update_fw_version = 22794 check_and_update_fw_version_cmd_tlv, 22795 .send_set_base_macaddr_indicate_cmd = 22796 send_set_base_macaddr_indicate_cmd_tlv, 22797 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 22798 .send_enable_specific_fw_logs_cmd = 22799 send_enable_specific_fw_logs_cmd_tlv, 22800 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 22801 .send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv, 22802 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 22803 #ifdef WLAN_POLICY_MGR_ENABLE 22804 .send_pdev_set_dual_mac_config_cmd = 22805 send_pdev_set_dual_mac_config_cmd_tlv, 22806 #endif 22807 .send_app_type1_params_in_fw_cmd = 22808 send_app_type1_params_in_fw_cmd_tlv, 22809 .send_set_ssid_hotlist_cmd = send_set_ssid_hotlist_cmd_tlv, 22810 .send_unit_test_cmd = send_unit_test_cmd_tlv, 22811 .send_roam_invoke_cmd = send_roam_invoke_cmd_tlv, 22812 .send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv, 22813 .send_roam_scan_offload_scan_period_cmd = 22814 send_roam_scan_offload_scan_period_cmd_tlv, 22815 .send_roam_scan_offload_chan_list_cmd = 22816 send_roam_scan_offload_chan_list_cmd_tlv, 22817 .send_roam_scan_offload_rssi_change_cmd = 22818 send_roam_scan_offload_rssi_change_cmd_tlv, 22819 #ifdef FEATURE_WLAN_APF 22820 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 22821 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 22822 .send_apf_write_work_memory_cmd = 22823 wmi_send_apf_write_work_memory_cmd_tlv, 22824 .send_apf_read_work_memory_cmd = 22825 wmi_send_apf_read_work_memory_cmd_tlv, 22826 .extract_apf_read_memory_resp_event = 22827 wmi_extract_apf_read_memory_resp_event_tlv, 22828 #endif /* FEATURE_WLAN_APF */ 22829 .send_adapt_dwelltime_params_cmd = 22830 send_adapt_dwelltime_params_cmd_tlv, 22831 .send_dbs_scan_sel_params_cmd = 22832 send_dbs_scan_sel_params_cmd_tlv, 22833 .init_cmd_send = init_cmd_send_tlv, 22834 .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, 22835 .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, 22836 .send_set_ctl_table_cmd = send_set_ctl_table_cmd_tlv, 22837 .send_set_mimogain_table_cmd = send_set_mimogain_table_cmd_tlv, 22838 .send_packet_power_info_get_cmd = send_packet_power_info_get_cmd_tlv, 22839 .send_vdev_config_ratemask_cmd = send_vdev_config_ratemask_cmd_tlv, 22840 .send_vdev_set_custom_aggr_size_cmd = 22841 send_vdev_set_custom_aggr_size_cmd_tlv, 22842 .send_vdev_set_qdepth_thresh_cmd = 22843 send_vdev_set_qdepth_thresh_cmd_tlv, 22844 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 22845 .send_vdev_set_neighbour_rx_cmd = send_vdev_set_neighbour_rx_cmd_tlv, 22846 .send_smart_ant_set_tx_ant_cmd = send_smart_ant_set_tx_ant_cmd_tlv, 22847 .send_set_ant_switch_tbl_cmd = send_set_ant_switch_tbl_cmd_tlv, 22848 .send_smart_ant_set_training_info_cmd = 22849 send_smart_ant_set_training_info_cmd_tlv, 22850 .send_smart_ant_set_node_config_cmd = 22851 send_smart_ant_set_node_config_cmd_tlv, 22852 #ifdef WLAN_ATF_ENABLE 22853 .send_set_atf_cmd = send_set_atf_cmd_tlv, 22854 #endif 22855 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 22856 .send_set_qboost_param_cmd = send_set_qboost_param_cmd_tlv, 22857 .send_gpio_config_cmd = send_gpio_config_cmd_tlv, 22858 .send_gpio_output_cmd = send_gpio_output_cmd_tlv, 22859 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 22860 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 22861 .send_periodic_chan_stats_config_cmd = 22862 send_periodic_chan_stats_config_cmd_tlv, 22863 .send_nf_dbr_dbm_info_get_cmd = send_nf_dbr_dbm_info_get_cmd_tlv, 22864 .send_set_ht_ie_cmd = send_set_ht_ie_cmd_tlv, 22865 .send_set_vht_ie_cmd = send_set_vht_ie_cmd_tlv, 22866 .send_set_quiet_mode_cmd = send_set_quiet_mode_cmd_tlv, 22867 .send_set_bwf_cmd = send_set_bwf_cmd_tlv, 22868 .send_mcast_group_update_cmd = send_mcast_group_update_cmd_tlv, 22869 .send_vdev_spectral_configure_cmd = 22870 send_vdev_spectral_configure_cmd_tlv, 22871 .send_vdev_spectral_enable_cmd = 22872 send_vdev_spectral_enable_cmd_tlv, 22873 .send_thermal_mitigation_param_cmd = 22874 send_thermal_mitigation_param_cmd_tlv, 22875 .send_pdev_qvit_cmd = send_pdev_qvit_cmd_tlv, 22876 .send_wmm_update_cmd = send_wmm_update_cmd_tlv, 22877 .send_process_update_edca_param_cmd = 22878 send_process_update_edca_param_cmd_tlv, 22879 .send_coex_config_cmd = send_coex_config_cmd_tlv, 22880 .send_set_country_cmd = send_set_country_cmd_tlv, 22881 .send_bcn_offload_control_cmd = send_bcn_offload_control_cmd_tlv, 22882 .send_addba_send_cmd = send_addba_send_cmd_tlv, 22883 .send_delba_send_cmd = send_delba_send_cmd_tlv, 22884 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 22885 .get_target_cap_from_service_ready = extract_service_ready_tlv, 22886 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 22887 .extract_host_mem_req = extract_host_mem_req_tlv, 22888 .save_service_bitmap = save_service_bitmap_tlv, 22889 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 22890 .is_service_enabled = is_service_enabled_tlv, 22891 .save_fw_version = save_fw_version_in_service_ready_tlv, 22892 .ready_extract_init_status = ready_extract_init_status_tlv, 22893 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 22894 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 22895 .extract_ready_event_params = extract_ready_event_params_tlv, 22896 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 22897 .extract_vdev_start_resp = extract_vdev_start_resp_tlv, 22898 .extract_vdev_delete_resp = extract_vdev_delete_resp_tlv, 22899 .extract_tbttoffset_update_params = 22900 extract_tbttoffset_update_params_tlv, 22901 .extract_ext_tbttoffset_update_params = 22902 extract_ext_tbttoffset_update_params_tlv, 22903 .extract_tbttoffset_num_vdevs = 22904 extract_tbttoffset_num_vdevs_tlv, 22905 .extract_ext_tbttoffset_num_vdevs = 22906 extract_ext_tbttoffset_num_vdevs_tlv, 22907 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 22908 .extract_vdev_stopped_param = extract_vdev_stopped_param_tlv, 22909 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 22910 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 22911 #ifdef CONVERGED_TDLS_ENABLE 22912 .extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv, 22913 #endif 22914 .extract_mgmt_tx_compl_param = extract_mgmt_tx_compl_param_tlv, 22915 .extract_swba_num_vdevs = extract_swba_num_vdevs_tlv, 22916 .extract_swba_tim_info = extract_swba_tim_info_tlv, 22917 .extract_swba_noa_info = extract_swba_noa_info_tlv, 22918 #ifdef CONVERGED_P2P_ENABLE 22919 .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, 22920 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 22921 .extract_p2p_lo_stop_ev_param = 22922 extract_p2p_lo_stop_ev_param_tlv, 22923 #endif 22924 #endif 22925 .extract_offchan_data_tx_compl_param = 22926 extract_offchan_data_tx_compl_param_tlv, 22927 .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, 22928 .extract_all_stats_count = extract_all_stats_counts_tlv, 22929 .extract_pdev_stats = extract_pdev_stats_tlv, 22930 .extract_unit_test = extract_unit_test_tlv, 22931 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 22932 .extract_vdev_stats = extract_vdev_stats_tlv, 22933 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 22934 .extract_peer_stats = extract_peer_stats_tlv, 22935 .extract_bcn_stats = extract_bcn_stats_tlv, 22936 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 22937 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 22938 .extract_chan_stats = extract_chan_stats_tlv, 22939 .extract_profile_ctx = extract_profile_ctx_tlv, 22940 .extract_profile_data = extract_profile_data_tlv, 22941 .extract_chan_info_event = extract_chan_info_event_tlv, 22942 .extract_channel_hopping_event = extract_channel_hopping_event_tlv, 22943 .send_fw_test_cmd = send_fw_test_cmd_tlv, 22944 #ifdef WLAN_FEATURE_DISA 22945 .send_encrypt_decrypt_send_cmd = 22946 send_encrypt_decrypt_send_cmd_tlv, 22947 .extract_encrypt_decrypt_resp_event = 22948 extract_encrypt_decrypt_resp_event_tlv, 22949 #endif 22950 .send_sar_limit_cmd = send_sar_limit_cmd_tlv, 22951 .get_sar_limit_cmd = get_sar_limit_cmd_tlv, 22952 .extract_sar_limit_event = extract_sar_limit_event_tlv, 22953 .extract_sar2_result_event = extract_sar2_result_event_tlv, 22954 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 22955 .send_multiple_vdev_restart_req_cmd = 22956 send_multiple_vdev_restart_req_cmd_tlv, 22957 .extract_service_ready_ext = extract_service_ready_ext_tlv, 22958 .extract_hw_mode_cap_service_ready_ext = 22959 extract_hw_mode_cap_service_ready_ext_tlv, 22960 .extract_mac_phy_cap_service_ready_ext = 22961 extract_mac_phy_cap_service_ready_ext_tlv, 22962 .extract_reg_cap_service_ready_ext = 22963 extract_reg_cap_service_ready_ext_tlv, 22964 .extract_dbr_ring_cap_service_ready_ext = 22965 extract_dbr_ring_cap_service_ready_ext_tlv, 22966 .extract_sar_cap_service_ready_ext = 22967 extract_sar_cap_service_ready_ext_tlv, 22968 .extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv, 22969 .extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv, 22970 .extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv, 22971 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 22972 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 22973 .extract_dcs_interference_type = extract_dcs_interference_type_tlv, 22974 .extract_dcs_cw_int = extract_dcs_cw_int_tlv, 22975 .extract_dcs_im_tgt_stats = extract_dcs_im_tgt_stats_tlv, 22976 .extract_fips_event_data = extract_fips_event_data_tlv, 22977 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 22978 .extract_peer_delete_response_event = 22979 extract_peer_delete_response_event_tlv, 22980 .is_management_record = is_management_record_tlv, 22981 .is_diag_event = is_diag_event_tlv, 22982 .extract_pdev_csa_switch_count_status = 22983 extract_pdev_csa_switch_count_status_tlv, 22984 .extract_pdev_tpc_ev_param = extract_pdev_tpc_ev_param_tlv, 22985 .extract_pdev_tpc_config_ev_param = 22986 extract_pdev_tpc_config_ev_param_tlv, 22987 .extract_nfcal_power_ev_param = extract_nfcal_power_ev_param_tlv, 22988 .extract_wds_addr_event = extract_wds_addr_event_tlv, 22989 .extract_peer_sta_ps_statechange_ev = 22990 extract_peer_sta_ps_statechange_ev_tlv, 22991 .extract_inst_rssi_stats_event = extract_inst_rssi_stats_event_tlv, 22992 .send_per_roam_config_cmd = send_per_roam_config_cmd_tlv, 22993 #ifdef WLAN_FEATURE_ACTION_OUI 22994 .send_action_oui_cmd = send_action_oui_cmd_tlv, 22995 #endif 22996 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 22997 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 22998 .extract_reg_chan_list_update_event = 22999 extract_reg_chan_list_update_event_tlv, 23000 .extract_chainmask_tables = 23001 extract_chainmask_tables_tlv, 23002 .extract_thermal_stats = extract_thermal_stats_tlv, 23003 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 23004 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 23005 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 23006 #ifdef DFS_COMPONENT_ENABLE 23007 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 23008 .extract_dfs_radar_detection_event = 23009 extract_dfs_radar_detection_event_tlv, 23010 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 23011 #endif 23012 .convert_pdev_id_host_to_target = 23013 convert_host_pdev_id_to_target_pdev_id_legacy, 23014 .convert_pdev_id_target_to_host = 23015 convert_target_pdev_id_to_host_pdev_id_legacy, 23016 23017 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 23018 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 23019 .extract_reg_11d_new_country_event = 23020 extract_reg_11d_new_country_event_tlv, 23021 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 23022 .send_limit_off_chan_cmd = 23023 send_limit_off_chan_cmd_tlv, 23024 .extract_reg_ch_avoid_event = 23025 extract_reg_ch_avoid_event_tlv, 23026 .send_pdev_caldata_version_check_cmd = 23027 send_pdev_caldata_version_check_cmd_tlv, 23028 .extract_pdev_caldata_version_check_ev_param = 23029 extract_pdev_caldata_version_check_ev_param_tlv, 23030 .send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv, 23031 .send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv, 23032 .send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv, 23033 #if defined(WLAN_FEATURE_FILS_SK) 23034 .send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv, 23035 #endif 23036 .send_wow_timer_pattern_cmd = send_wow_timer_pattern_cmd_tlv, 23037 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 23038 .send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv, 23039 .send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv, 23040 .send_ndp_end_req_cmd = nan_ndp_end_req_tlv, 23041 .extract_ndp_initiator_rsp = extract_ndp_initiator_rsp_tlv, 23042 .extract_ndp_ind = extract_ndp_ind_tlv, 23043 .extract_ndp_confirm = extract_ndp_confirm_tlv, 23044 .extract_ndp_responder_rsp = extract_ndp_responder_rsp_tlv, 23045 .extract_ndp_end_rsp = extract_ndp_end_rsp_tlv, 23046 .extract_ndp_end_ind = extract_ndp_end_ind_tlv, 23047 .extract_ndp_sch_update = extract_ndp_sch_update_tlv, 23048 #endif 23049 .send_btm_config = send_btm_config_cmd_tlv, 23050 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 23051 .extract_obss_detection_info = extract_obss_detection_info_tlv, 23052 #ifdef WLAN_SUPPORT_FILS 23053 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_tlv, 23054 .extract_swfda_vdev_id = extract_swfda_vdev_id_tlv, 23055 .send_fils_discovery_send_cmd = send_fils_discovery_send_cmd_tlv, 23056 #endif /* WLAN_SUPPORT_FILS */ 23057 .send_offload_11k_cmd = send_offload_11k_cmd_tlv, 23058 .send_invoke_neighbor_report_cmd = send_invoke_neighbor_report_cmd_tlv, 23059 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 23060 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 23061 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 23062 .wmi_check_command_params = wmitlv_check_command_tlv_params, 23063 .send_bss_color_change_enable_cmd = 23064 send_bss_color_change_enable_cmd_tlv, 23065 .send_obss_color_collision_cfg_cmd = 23066 send_obss_color_collision_cfg_cmd_tlv, 23067 .extract_obss_color_collision_info = 23068 extract_obss_color_collision_info_tlv, 23069 .extract_comb_phyerr = extract_comb_phyerr_tlv, 23070 .extract_single_phyerr = extract_single_phyerr_tlv, 23071 #ifdef QCA_SUPPORT_CP_STATS 23072 .extract_cca_stats = extract_cca_stats_tlv, 23073 #endif 23074 .extract_esp_estimation_ev_param = 23075 extract_esp_estimation_ev_param_tlv, 23076 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 23077 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 23078 #ifdef OBSS_PD 23079 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 23080 #endif 23081 }; 23082 23083 /** 23084 * populate_tlv_event_id() - populates wmi event ids 23085 * 23086 * @param event_ids: Pointer to hold event ids 23087 * Return: None 23088 */ 23089 static void populate_tlv_events_id(uint32_t *event_ids) 23090 { 23091 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 23092 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 23093 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 23094 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23095 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 23096 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 23097 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 23098 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 23099 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 23100 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 23101 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 23102 event_ids[wmi_service_ready_ext_event_id] = 23103 WMI_SERVICE_READY_EXT_EVENTID; 23104 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 23105 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 23106 event_ids[wmi_vdev_install_key_complete_event_id] = 23107 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 23108 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 23109 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 23110 23111 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 23112 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 23113 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 23114 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 23115 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 23116 event_ids[wmi_peer_estimated_linkspeed_event_id] = 23117 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 23118 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 23119 event_ids[wmi_peer_delete_response_event_id] = 23120 WMI_PEER_DELETE_RESP_EVENTID; 23121 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 23122 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 23123 event_ids[wmi_tbttoffset_update_event_id] = 23124 WMI_TBTTOFFSET_UPDATE_EVENTID; 23125 event_ids[wmi_ext_tbttoffset_update_event_id] = 23126 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 23127 event_ids[wmi_offload_bcn_tx_status_event_id] = 23128 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 23129 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 23130 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 23131 event_ids[wmi_mgmt_tx_completion_event_id] = 23132 WMI_MGMT_TX_COMPLETION_EVENTID; 23133 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 23134 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 23135 event_ids[wmi_tx_delba_complete_event_id] = 23136 WMI_TX_DELBA_COMPLETE_EVENTID; 23137 event_ids[wmi_tx_addba_complete_event_id] = 23138 WMI_TX_ADDBA_COMPLETE_EVENTID; 23139 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 23140 23141 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 23142 23143 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 23144 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 23145 23146 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 23147 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 23148 23149 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 23150 23151 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 23152 event_ids[wmi_p2p_lo_stop_event_id] = 23153 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 23154 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 23155 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 23156 event_ids[wmi_d0_wow_disable_ack_event_id] = 23157 WMI_D0_WOW_DISABLE_ACK_EVENTID; 23158 event_ids[wmi_wow_initial_wakeup_event_id] = 23159 WMI_WOW_INITIAL_WAKEUP_EVENTID; 23160 23161 event_ids[wmi_rtt_meas_report_event_id] = 23162 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 23163 event_ids[wmi_tsf_meas_report_event_id] = 23164 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 23165 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 23166 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 23167 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 23168 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 23169 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 23170 event_ids[wmi_diag_event_id_log_supported_event_id] = 23171 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 23172 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 23173 event_ids[wmi_nlo_scan_complete_event_id] = 23174 WMI_NLO_SCAN_COMPLETE_EVENTID; 23175 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 23176 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 23177 23178 event_ids[wmi_gtk_offload_status_event_id] = 23179 WMI_GTK_OFFLOAD_STATUS_EVENTID; 23180 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 23181 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 23182 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 23183 23184 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 23185 23186 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 23187 23188 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 23189 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 23190 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 23191 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 23192 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 23193 event_ids[wmi_wlan_profile_data_event_id] = 23194 WMI_WLAN_PROFILE_DATA_EVENTID; 23195 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 23196 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 23197 event_ids[wmi_vdev_get_keepalive_event_id] = 23198 WMI_VDEV_GET_KEEPALIVE_EVENTID; 23199 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 23200 23201 event_ids[wmi_diag_container_event_id] = 23202 WMI_DIAG_DATA_CONTAINER_EVENTID; 23203 23204 event_ids[wmi_host_auto_shutdown_event_id] = 23205 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 23206 23207 event_ids[wmi_update_whal_mib_stats_event_id] = 23208 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 23209 23210 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 23211 event_ids[wmi_update_vdev_rate_stats_event_id] = 23212 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 23213 23214 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 23215 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 23216 23217 /** Set OCB Sched Response, deprecated */ 23218 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 23219 23220 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 23221 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 23222 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 23223 23224 /* GPIO Event */ 23225 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 23226 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 23227 23228 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 23229 event_ids[wmi_rfkill_state_change_event_id] = 23230 WMI_RFKILL_STATE_CHANGE_EVENTID; 23231 23232 /* TDLS Event */ 23233 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 23234 23235 event_ids[wmi_batch_scan_enabled_event_id] = 23236 WMI_BATCH_SCAN_ENABLED_EVENTID; 23237 event_ids[wmi_batch_scan_result_event_id] = 23238 WMI_BATCH_SCAN_RESULT_EVENTID; 23239 /* OEM Event */ 23240 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 23241 event_ids[wmi_oem_meas_report_event_id] = 23242 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 23243 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 23244 23245 /* NAN Event */ 23246 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 23247 23248 /* LPI Event */ 23249 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 23250 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 23251 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 23252 23253 /* ExtScan events */ 23254 event_ids[wmi_extscan_start_stop_event_id] = 23255 WMI_EXTSCAN_START_STOP_EVENTID; 23256 event_ids[wmi_extscan_operation_event_id] = 23257 WMI_EXTSCAN_OPERATION_EVENTID; 23258 event_ids[wmi_extscan_table_usage_event_id] = 23259 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 23260 event_ids[wmi_extscan_cached_results_event_id] = 23261 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 23262 event_ids[wmi_extscan_wlan_change_results_event_id] = 23263 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 23264 event_ids[wmi_extscan_hotlist_match_event_id] = 23265 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 23266 event_ids[wmi_extscan_capabilities_event_id] = 23267 WMI_EXTSCAN_CAPABILITIES_EVENTID; 23268 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 23269 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 23270 23271 /* mDNS offload events */ 23272 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 23273 23274 /* SAP Authentication offload events */ 23275 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 23276 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 23277 23278 /** Out-of-context-of-bss (OCB) events */ 23279 event_ids[wmi_ocb_set_config_resp_event_id] = 23280 WMI_OCB_SET_CONFIG_RESP_EVENTID; 23281 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 23282 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 23283 event_ids[wmi_dcc_get_stats_resp_event_id] = 23284 WMI_DCC_GET_STATS_RESP_EVENTID; 23285 event_ids[wmi_dcc_update_ndl_resp_event_id] = 23286 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 23287 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 23288 /* System-On-Chip events */ 23289 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 23290 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 23291 event_ids[wmi_soc_hw_mode_transition_event_id] = 23292 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 23293 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 23294 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 23295 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 23296 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 23297 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 23298 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 23299 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 23300 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 23301 event_ids[wmi_peer_sta_ps_statechg_event_id] = 23302 WMI_PEER_STA_PS_STATECHG_EVENTID; 23303 event_ids[wmi_pdev_channel_hopping_event_id] = 23304 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 23305 event_ids[wmi_offchan_data_tx_completion_event] = 23306 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 23307 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 23308 event_ids[wmi_dfs_radar_detection_event_id] = 23309 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 23310 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 23311 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 23312 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 23313 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 23314 event_ids[wmi_service_available_event_id] = 23315 WMI_SERVICE_AVAILABLE_EVENTID; 23316 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 23317 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 23318 /* NDP events */ 23319 event_ids[wmi_ndp_initiator_rsp_event_id] = 23320 WMI_NDP_INITIATOR_RSP_EVENTID; 23321 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 23322 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 23323 event_ids[wmi_ndp_responder_rsp_event_id] = 23324 WMI_NDP_RESPONDER_RSP_EVENTID; 23325 event_ids[wmi_ndp_end_indication_event_id] = 23326 WMI_NDP_END_INDICATION_EVENTID; 23327 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 23328 event_ids[wmi_ndl_schedule_update_event_id] = 23329 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 23330 23331 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 23332 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 23333 event_ids[wmi_pdev_chip_power_stats_event_id] = 23334 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 23335 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 23336 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 23337 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 23338 event_ids[wmi_apf_capability_info_event_id] = 23339 WMI_BPF_CAPABILIY_INFO_EVENTID; 23340 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 23341 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 23342 event_ids[wmi_report_rx_aggr_failure_event_id] = 23343 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 23344 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 23345 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 23346 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 23347 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 23348 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 23349 event_ids[wmi_pdev_hw_mode_transition_event_id] = 23350 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 23351 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 23352 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 23353 event_ids[wmi_coex_bt_activity_event_id] = 23354 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 23355 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 23356 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 23357 event_ids[wmi_radio_tx_power_level_stats_event_id] = 23358 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 23359 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 23360 event_ids[wmi_dma_buf_release_event_id] = 23361 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 23362 event_ids[wmi_sap_obss_detection_report_event_id] = 23363 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 23364 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 23365 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 23366 event_ids[wmi_obss_color_collision_report_event_id] = 23367 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 23368 event_ids[wmi_pdev_div_rssi_antid_event_id] = 23369 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 23370 event_ids[wmi_twt_enable_complete_event_id] = 23371 WMI_TWT_ENABLE_COMPLETE_EVENTID; 23372 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 23373 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 23374 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 23375 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 23376 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 23377 #ifdef AST_HKV1_WORKAROUND 23378 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 23379 #endif 23380 } 23381 23382 /** 23383 * populate_tlv_service() - populates wmi services 23384 * 23385 * @param wmi_service: Pointer to hold wmi_service 23386 * Return: None 23387 */ 23388 static void populate_tlv_service(uint32_t *wmi_service) 23389 { 23390 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 23391 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 23392 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 23393 wmi_service[wmi_service_roam_scan_offload] = 23394 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 23395 wmi_service[wmi_service_bcn_miss_offload] = 23396 WMI_SERVICE_BCN_MISS_OFFLOAD; 23397 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 23398 wmi_service[wmi_service_sta_advanced_pwrsave] = 23399 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 23400 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 23401 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 23402 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 23403 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 23404 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 23405 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 23406 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 23407 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 23408 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 23409 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 23410 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 23411 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 23412 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 23413 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 23414 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 23415 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 23416 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 23417 wmi_service[wmi_service_packet_power_save] = 23418 WMI_SERVICE_PACKET_POWER_SAVE; 23419 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 23420 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 23421 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 23422 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 23423 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 23424 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 23425 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 23426 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 23427 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 23428 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 23429 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 23430 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 23431 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 23432 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 23433 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 23434 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 23435 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 23436 wmi_service[wmi_service_mcc_bcn_interval_change] = 23437 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 23438 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 23439 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 23440 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 23441 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 23442 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 23443 wmi_service[wmi_service_lte_ant_share_support] = 23444 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 23445 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 23446 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 23447 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 23448 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 23449 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 23450 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 23451 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 23452 wmi_service[wmi_service_bcn_txrate_override] = 23453 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 23454 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 23455 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 23456 wmi_service[wmi_service_estimate_linkspeed] = 23457 WMI_SERVICE_ESTIMATE_LINKSPEED; 23458 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 23459 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 23460 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 23461 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 23462 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 23463 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 23464 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 23465 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 23466 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 23467 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 23468 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 23469 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 23470 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 23471 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 23472 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 23473 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 23474 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 23475 wmi_service[wmi_service_sap_auth_offload] = 23476 WMI_SERVICE_SAP_AUTH_OFFLOAD; 23477 wmi_service[wmi_service_dual_band_simultaneous_support] = 23478 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 23479 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 23480 wmi_service[wmi_service_ap_arpns_offload] = 23481 WMI_SERVICE_AP_ARPNS_OFFLOAD; 23482 wmi_service[wmi_service_per_band_chainmask_support] = 23483 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 23484 wmi_service[wmi_service_packet_filter_offload] = 23485 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 23486 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 23487 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 23488 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 23489 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 23490 wmi_service[wmi_service_multiple_vdev_restart] = 23491 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 23492 23493 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 23494 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 23495 wmi_service[wmi_service_smart_antenna_sw_support] = 23496 WMI_SERVICE_UNAVAILABLE; 23497 wmi_service[wmi_service_smart_antenna_hw_support] = 23498 WMI_SERVICE_UNAVAILABLE; 23499 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 23500 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 23501 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 23502 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 23503 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 23504 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 23505 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 23506 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 23507 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 23508 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 23509 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 23510 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 23511 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 23512 wmi_service[wmi_service_periodic_chan_stat_support] = 23513 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 23514 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 23515 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 23516 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 23517 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 23518 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 23519 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23520 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 23521 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 23522 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 23523 wmi_service[wmi_service_unified_wow_capability] = 23524 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 23525 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 23526 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 23527 wmi_service[wmi_service_sync_delete_cmds] = 23528 WMI_SERVICE_SYNC_DELETE_CMDS; 23529 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 23530 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 23531 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 23532 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 23533 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 23534 wmi_service[wmi_service_deprecated_replace] = 23535 WMI_SERVICE_DEPRECATED_REPLACE; 23536 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 23537 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 23538 wmi_service[wmi_service_enhanced_mcast_filter] = 23539 WMI_SERVICE_ENHANCED_MCAST_FILTER; 23540 wmi_service[wmi_service_half_rate_quarter_rate_support] = 23541 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 23542 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 23543 wmi_service[wmi_service_p2p_listen_offload_support] = 23544 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 23545 wmi_service[wmi_service_mark_first_wakeup_packet] = 23546 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 23547 wmi_service[wmi_service_multiple_mcast_filter_set] = 23548 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 23549 wmi_service[wmi_service_host_managed_rx_reorder] = 23550 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 23551 wmi_service[wmi_service_flash_rdwr_support] = 23552 WMI_SERVICE_FLASH_RDWR_SUPPORT; 23553 wmi_service[wmi_service_wlan_stats_report] = 23554 WMI_SERVICE_WLAN_STATS_REPORT; 23555 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 23556 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 23557 wmi_service[wmi_service_dfs_phyerr_offload] = 23558 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 23559 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 23560 wmi_service[wmi_service_fw_mem_dump_support] = 23561 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 23562 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 23563 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 23564 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 23565 wmi_service[wmi_service_hw_data_filtering] = 23566 WMI_SERVICE_HW_DATA_FILTERING; 23567 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 23568 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 23569 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 23570 wmi_service[wmi_service_extended_nss_support] = 23571 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 23572 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 23573 wmi_service[wmi_service_bcn_offload_start_stop_support] = 23574 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 23575 wmi_service[wmi_service_offchan_data_tid_support] = 23576 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 23577 wmi_service[wmi_service_support_dma] = 23578 WMI_SERVICE_SUPPORT_DIRECT_DMA; 23579 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 23580 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 23581 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 23582 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 23583 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 23584 wmi_service[wmi_service_11k_neighbour_report_support] = 23585 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 23586 wmi_service[wmi_service_ap_obss_detection_offload] = 23587 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 23588 wmi_service[wmi_service_bss_color_offload] = 23589 WMI_SERVICE_BSS_COLOR_OFFLOAD; 23590 wmi_service[wmi_service_gmac_offload_support] = 23591 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 23592 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 23593 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 23594 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 23595 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 23596 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 23597 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 23598 wmi_service[wmi_service_listen_interval_offload_support] = 23599 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 23600 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 23601 wmi_service[wmi_service_obss_spatial_reuse] = 23602 WMI_SERVICE_OBSS_SPATIAL_REUSE; 23603 23604 } 23605 23606 #ifndef CONFIG_MCL 23607 23608 /** 23609 * populate_pdev_param_tlv() - populates pdev params 23610 * 23611 * @param pdev_param: Pointer to hold pdev params 23612 * Return: None 23613 */ 23614 static void populate_pdev_param_tlv(uint32_t *pdev_param) 23615 { 23616 pdev_param[wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK; 23617 pdev_param[wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK; 23618 pdev_param[wmi_pdev_param_txpower_limit2g] = 23619 WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 23620 pdev_param[wmi_pdev_param_txpower_limit5g] = 23621 WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 23622 pdev_param[wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE; 23623 pdev_param[wmi_pdev_param_beacon_gen_mode] = 23624 WMI_PDEV_PARAM_BEACON_GEN_MODE; 23625 pdev_param[wmi_pdev_param_beacon_tx_mode] = 23626 WMI_PDEV_PARAM_BEACON_TX_MODE; 23627 pdev_param[wmi_pdev_param_resmgr_offchan_mode] = 23628 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE; 23629 pdev_param[wmi_pdev_param_protection_mode] = 23630 WMI_PDEV_PARAM_PROTECTION_MODE; 23631 pdev_param[wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW; 23632 pdev_param[wmi_pdev_param_non_agg_sw_retry_th] = 23633 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH; 23634 pdev_param[wmi_pdev_param_agg_sw_retry_th] = 23635 WMI_PDEV_PARAM_AGG_SW_RETRY_TH; 23636 pdev_param[wmi_pdev_param_sta_kickout_th] = 23637 WMI_PDEV_PARAM_STA_KICKOUT_TH; 23638 pdev_param[wmi_pdev_param_ac_aggrsize_scaling] = 23639 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING; 23640 pdev_param[wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE; 23641 pdev_param[wmi_pdev_param_ltr_ac_latency_be] = 23642 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE; 23643 pdev_param[wmi_pdev_param_ltr_ac_latency_bk] = 23644 WMI_PDEV_PARAM_LTR_AC_LATENCY_BK; 23645 pdev_param[wmi_pdev_param_ltr_ac_latency_vi] = 23646 WMI_PDEV_PARAM_LTR_AC_LATENCY_VI; 23647 pdev_param[wmi_pdev_param_ltr_ac_latency_vo] = 23648 WMI_PDEV_PARAM_LTR_AC_LATENCY_VO; 23649 pdev_param[wmi_pdev_param_ltr_ac_latency_timeout] = 23650 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT; 23651 pdev_param[wmi_pdev_param_ltr_sleep_override] = 23652 WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE; 23653 pdev_param[wmi_pdev_param_ltr_rx_override] = 23654 WMI_PDEV_PARAM_LTR_RX_OVERRIDE; 23655 pdev_param[wmi_pdev_param_ltr_tx_activity_timeout] = 23656 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT; 23657 pdev_param[wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE; 23658 pdev_param[wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE; 23659 pdev_param[wmi_pdev_param_pcielp_txbuf_flush] = 23660 WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH; 23661 pdev_param[wmi_pdev_param_pcielp_txbuf_watermark] = 23662 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK; 23663 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_en] = 23664 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN; 23665 pdev_param[wmi_pdev_param_pcielp_txbuf_tmo_value] = 23666 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE; 23667 pdev_param[wmi_pdev_param_pdev_stats_update_period] = 23668 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD; 23669 pdev_param[wmi_pdev_param_vdev_stats_update_period] = 23670 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD; 23671 pdev_param[wmi_pdev_param_peer_stats_update_period] = 23672 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD; 23673 pdev_param[wmi_pdev_param_bcnflt_stats_update_period] = 23674 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD; 23675 pdev_param[wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS; 23676 pdev_param[wmi_pdev_param_arp_ac_override] = 23677 WMI_PDEV_PARAM_ARP_AC_OVERRIDE; 23678 pdev_param[wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS; 23679 pdev_param[wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE; 23680 pdev_param[wmi_pdev_param_ani_poll_period] = 23681 WMI_PDEV_PARAM_ANI_POLL_PERIOD; 23682 pdev_param[wmi_pdev_param_ani_listen_period] = 23683 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD; 23684 pdev_param[wmi_pdev_param_ani_ofdm_level] = 23685 WMI_PDEV_PARAM_ANI_OFDM_LEVEL; 23686 pdev_param[wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL; 23687 pdev_param[wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN; 23688 pdev_param[wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA; 23689 pdev_param[wmi_pdev_param_idle_ps_config] = 23690 WMI_PDEV_PARAM_IDLE_PS_CONFIG; 23691 pdev_param[wmi_pdev_param_power_gating_sleep] = 23692 WMI_PDEV_PARAM_POWER_GATING_SLEEP; 23693 pdev_param[wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE; 23694 pdev_param[wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR; 23695 pdev_param[wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE; 23696 pdev_param[wmi_pdev_param_hw_rfkill_config] = 23697 WMI_PDEV_PARAM_HW_RFKILL_CONFIG; 23698 pdev_param[wmi_pdev_param_low_power_rf_enable] = 23699 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE; 23700 pdev_param[wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK; 23701 pdev_param[wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN; 23702 pdev_param[wmi_pdev_param_power_collapse_enable] = 23703 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE; 23704 pdev_param[wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE; 23705 pdev_param[wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE; 23706 pdev_param[wmi_pdev_param_audio_over_wlan_latency] = 23707 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY; 23708 pdev_param[wmi_pdev_param_audio_over_wlan_enable] = 23709 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE; 23710 pdev_param[wmi_pdev_param_whal_mib_stats_update_enable] = 23711 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE; 23712 pdev_param[wmi_pdev_param_vdev_rate_stats_update_period] = 23713 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD; 23714 pdev_param[wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW; 23715 pdev_param[wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG; 23716 pdev_param[wmi_pdev_param_adaptive_early_rx_enable] = 23717 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE; 23718 pdev_param[wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 23719 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP; 23720 pdev_param[wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 23721 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP; 23722 pdev_param[wmi_pdev_param_early_rx_fix_sleep_slop] = 23723 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP; 23724 pdev_param[wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 23725 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE; 23726 pdev_param[wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 23727 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT; 23728 pdev_param[wmi_pdev_param_bmiss_bto_inc_dec_step] = 23729 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP; 23730 pdev_param[wmi_pdev_param_bto_fix_bcn_timeout] = 23731 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT; 23732 pdev_param[wmi_pdev_param_ce_based_adaptive_bto_enable] = 23733 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE; 23734 pdev_param[wmi_pdev_param_ce_bto_combo_ce_value] = 23735 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE; 23736 pdev_param[wmi_pdev_param_tx_chain_mask_2g] = 23737 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G; 23738 pdev_param[wmi_pdev_param_rx_chain_mask_2g] = 23739 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G; 23740 pdev_param[wmi_pdev_param_tx_chain_mask_5g] = 23741 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G; 23742 pdev_param[wmi_pdev_param_rx_chain_mask_5g] = 23743 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G; 23744 pdev_param[wmi_pdev_param_tx_chain_mask_cck] = 23745 WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK; 23746 pdev_param[wmi_pdev_param_tx_chain_mask_1ss] = 23747 WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS; 23748 pdev_param[wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER; 23749 pdev_param[wmi_pdev_set_mcast_to_ucast_tid] = 23750 WMI_PDEV_SET_MCAST_TO_UCAST_TID; 23751 pdev_param[wmi_pdev_param_mgmt_retry_limit] = 23752 WMI_PDEV_PARAM_MGMT_RETRY_LIMIT; 23753 pdev_param[wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST; 23754 pdev_param[wmi_pdev_peer_sta_ps_statechg_enable] = 23755 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE; 23756 pdev_param[wmi_pdev_param_proxy_sta_mode] = 23757 WMI_PDEV_PARAM_PROXY_STA_MODE; 23758 pdev_param[wmi_pdev_param_mu_group_policy] = 23759 WMI_PDEV_PARAM_MU_GROUP_POLICY; 23760 pdev_param[wmi_pdev_param_noise_detection] = 23761 WMI_PDEV_PARAM_NOISE_DETECTION; 23762 pdev_param[wmi_pdev_param_noise_threshold] = 23763 WMI_PDEV_PARAM_NOISE_THRESHOLD; 23764 pdev_param[wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE; 23765 pdev_param[wmi_pdev_param_set_mcast_bcast_echo] = 23766 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO; 23767 pdev_param[wmi_pdev_param_atf_strict_sch] = 23768 WMI_PDEV_PARAM_ATF_STRICT_SCH; 23769 pdev_param[wmi_pdev_param_atf_sched_duration] = 23770 WMI_PDEV_PARAM_ATF_SCHED_DURATION; 23771 pdev_param[wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN; 23772 pdev_param[wmi_pdev_param_sensitivity_level] = 23773 WMI_PDEV_PARAM_SENSITIVITY_LEVEL; 23774 pdev_param[wmi_pdev_param_signed_txpower_2g] = 23775 WMI_PDEV_PARAM_SIGNED_TXPOWER_2G; 23776 pdev_param[wmi_pdev_param_signed_txpower_5g] = 23777 WMI_PDEV_PARAM_SIGNED_TXPOWER_5G; 23778 pdev_param[wmi_pdev_param_enable_per_tid_amsdu] = 23779 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU; 23780 pdev_param[wmi_pdev_param_enable_per_tid_ampdu] = 23781 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU; 23782 pdev_param[wmi_pdev_param_cca_threshold] = 23783 WMI_PDEV_PARAM_CCA_THRESHOLD; 23784 pdev_param[wmi_pdev_param_rts_fixed_rate] = 23785 WMI_PDEV_PARAM_RTS_FIXED_RATE; 23786 pdev_param[wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM; 23787 pdev_param[wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET; 23788 pdev_param[wmi_pdev_param_wapi_mbssid_offset] = 23789 WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET; 23790 pdev_param[wmi_pdev_param_arp_srcaddr] = 23791 WMI_PDEV_PARAM_ARP_DBG_SRCADDR; 23792 pdev_param[wmi_pdev_param_arp_dstaddr] = 23793 WMI_PDEV_PARAM_ARP_DBG_DSTADDR; 23794 pdev_param[wmi_pdev_param_txpower_decr_db] = 23795 WMI_PDEV_PARAM_TXPOWER_DECR_DB; 23796 pdev_param[wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM; 23797 pdev_param[wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM; 23798 pdev_param[wmi_pdev_param_atf_obss_noise_sch] = 23799 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH; 23800 pdev_param[wmi_pdev_param_atf_obss_noise_scaling_factor] = 23801 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR; 23802 pdev_param[wmi_pdev_param_cust_txpower_scale] = 23803 WMI_PDEV_PARAM_CUST_TXPOWER_SCALE; 23804 pdev_param[wmi_pdev_param_atf_dynamic_enable] = 23805 WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE; 23806 pdev_param[wmi_pdev_param_atf_ssid_group_policy] = 23807 WMI_UNAVAILABLE_PARAM; 23808 pdev_param[wmi_pdev_param_igmpmld_override] = 23809 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23810 pdev_param[wmi_pdev_param_igmpmld_tid] = 23811 WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE; 23812 pdev_param[wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN; 23813 pdev_param[wmi_pdev_param_block_interbss] = 23814 WMI_PDEV_PARAM_BLOCK_INTERBSS; 23815 pdev_param[wmi_pdev_param_set_disable_reset_cmdid] = 23816 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID; 23817 pdev_param[wmi_pdev_param_set_msdu_ttl_cmdid] = 23818 WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID; 23819 pdev_param[wmi_pdev_param_txbf_sound_period_cmdid] = 23820 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID; 23821 pdev_param[wmi_pdev_param_set_burst_mode_cmdid] = 23822 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID; 23823 pdev_param[wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS; 23824 pdev_param[wmi_pdev_param_mesh_mcast_enable] = 23825 WMI_PDEV_PARAM_MESH_MCAST_ENABLE; 23826 pdev_param[wmi_pdev_param_set_promisc_mode_cmdid] = 23827 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID; 23828 pdev_param[wmi_pdev_param_set_ppdu_duration_cmdid] = 23829 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID; 23830 pdev_param[wmi_pdev_param_remove_mcast2ucast_buffer] = 23831 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER; 23832 pdev_param[wmi_pdev_param_set_mcast2ucast_buffer] = 23833 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER; 23834 pdev_param[wmi_pdev_param_set_mcast2ucast_mode] = 23835 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE; 23836 pdev_param[wmi_pdev_param_smart_antenna_default_antenna] = 23837 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA; 23838 pdev_param[wmi_pdev_param_fast_channel_reset] = 23839 WMI_PDEV_PARAM_FAST_CHANNEL_RESET; 23840 pdev_param[wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE; 23841 pdev_param[wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT; 23842 pdev_param[wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE; 23843 pdev_param[wmi_pdev_param_antenna_gain_half_db] = 23844 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB; 23845 pdev_param[wmi_pdev_param_esp_indication_period] = 23846 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD; 23847 pdev_param[wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW; 23848 pdev_param[wmi_pdev_param_esp_airtime_fraction] = 23849 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION; 23850 pdev_param[wmi_pdev_param_esp_ppdu_duration] = 23851 WMI_PDEV_PARAM_ESP_PPDU_DURATION; 23852 #ifdef WLAN_RU26_SUPPORT 23853 pdev_param[wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_RU26_ALLOWED; 23854 #endif 23855 } 23856 23857 /** 23858 * populate_vdev_param_tlv() - populates vdev params 23859 * 23860 * @param vdev_param: Pointer to hold vdev params 23861 * Return: None 23862 */ 23863 static void populate_vdev_param_tlv(uint32_t *vdev_param) 23864 { 23865 vdev_param[wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD; 23866 vdev_param[wmi_vdev_param_fragmentation_threshold] = 23867 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; 23868 vdev_param[wmi_vdev_param_beacon_interval] = 23869 WMI_VDEV_PARAM_BEACON_INTERVAL; 23870 vdev_param[wmi_vdev_param_listen_interval] = 23871 WMI_VDEV_PARAM_LISTEN_INTERVAL; 23872 vdev_param[wmi_vdev_param_multicast_rate] = 23873 WMI_VDEV_PARAM_MULTICAST_RATE; 23874 vdev_param[wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE; 23875 vdev_param[wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME; 23876 vdev_param[wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE; 23877 vdev_param[wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME; 23878 vdev_param[wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD; 23879 vdev_param[wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME; 23880 vdev_param[wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL; 23881 vdev_param[wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD; 23882 vdev_param[wmi_vdev_oc_scheduler_air_time_limit] = 23883 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT; 23884 vdev_param[wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS; 23885 vdev_param[wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW; 23886 vdev_param[wmi_vdev_param_bmiss_count_max] = 23887 WMI_VDEV_PARAM_BMISS_COUNT_MAX; 23888 vdev_param[wmi_vdev_param_bmiss_first_bcnt] = 23889 WMI_VDEV_PARAM_BMISS_FIRST_BCNT; 23890 vdev_param[wmi_vdev_param_bmiss_final_bcnt] = 23891 WMI_VDEV_PARAM_BMISS_FINAL_BCNT; 23892 vdev_param[wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM; 23893 vdev_param[wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH; 23894 vdev_param[wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET; 23895 vdev_param[wmi_vdev_param_disable_htprotection] = 23896 WMI_VDEV_PARAM_DISABLE_HTPROTECTION; 23897 vdev_param[wmi_vdev_param_sta_quickkickout] = 23898 WMI_VDEV_PARAM_STA_QUICKKICKOUT; 23899 vdev_param[wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE; 23900 vdev_param[wmi_vdev_param_protection_mode] = 23901 WMI_VDEV_PARAM_PROTECTION_MODE; 23902 vdev_param[wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE; 23903 vdev_param[wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI; 23904 vdev_param[wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC; 23905 vdev_param[wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC; 23906 vdev_param[wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC; 23907 vdev_param[wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD; 23908 vdev_param[wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID; 23909 vdev_param[wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS; 23910 vdev_param[wmi_vdev_param_bcast_data_rate] = 23911 WMI_VDEV_PARAM_BCAST_DATA_RATE; 23912 vdev_param[wmi_vdev_param_mcast_data_rate] = 23913 WMI_VDEV_PARAM_MCAST_DATA_RATE; 23914 vdev_param[wmi_vdev_param_mcast_indicate] = 23915 WMI_VDEV_PARAM_MCAST_INDICATE; 23916 vdev_param[wmi_vdev_param_dhcp_indicate] = 23917 WMI_VDEV_PARAM_DHCP_INDICATE; 23918 vdev_param[wmi_vdev_param_unknown_dest_indicate] = 23919 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE; 23920 vdev_param[wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 23921 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 23922 vdev_param[wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 23923 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 23924 vdev_param[wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 23925 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 23926 vdev_param[wmi_vdev_param_ap_enable_nawds] = 23927 WMI_VDEV_PARAM_AP_ENABLE_NAWDS; 23928 vdev_param[wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS; 23929 vdev_param[wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF; 23930 vdev_param[wmi_vdev_param_packet_powersave] = 23931 WMI_VDEV_PARAM_PACKET_POWERSAVE; 23932 vdev_param[wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY; 23933 vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 23934 vdev_param[wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 23935 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS; 23936 vdev_param[wmi_vdev_param_early_rx_adjust_enable] = 23937 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE; 23938 vdev_param[wmi_vdev_param_early_rx_tgt_bmiss_num] = 23939 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM; 23940 vdev_param[wmi_vdev_param_early_rx_bmiss_sample_cycle] = 23941 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE; 23942 vdev_param[wmi_vdev_param_early_rx_slop_step] = 23943 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP; 23944 vdev_param[wmi_vdev_param_early_rx_init_slop] = 23945 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP; 23946 vdev_param[wmi_vdev_param_early_rx_adjust_pause] = 23947 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE; 23948 vdev_param[wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT; 23949 vdev_param[wmi_vdev_param_snr_num_for_cal] = 23950 WMI_VDEV_PARAM_SNR_NUM_FOR_CAL; 23951 vdev_param[wmi_vdev_param_roam_fw_offload] = 23952 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD; 23953 vdev_param[wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC; 23954 vdev_param[wmi_vdev_param_ibss_max_bcn_lost_ms] = 23955 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS; 23956 vdev_param[wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE; 23957 vdev_param[wmi_vdev_param_early_rx_drift_sample] = 23958 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE; 23959 vdev_param[wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 23960 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR; 23961 vdev_param[wmi_vdev_param_ebt_resync_timeout] = 23962 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT; 23963 vdev_param[wmi_vdev_param_aggr_trig_event_enable] = 23964 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE; 23965 vdev_param[wmi_vdev_param_is_ibss_power_save_allowed] = 23966 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED; 23967 vdev_param[wmi_vdev_param_is_power_collapse_allowed] = 23968 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED; 23969 vdev_param[wmi_vdev_param_is_awake_on_txrx_enabled] = 23970 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED; 23971 vdev_param[wmi_vdev_param_inactivity_cnt] = 23972 WMI_VDEV_PARAM_INACTIVITY_CNT; 23973 vdev_param[wmi_vdev_param_txsp_end_inactivity_time_ms] = 23974 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS; 23975 vdev_param[wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY; 23976 vdev_param[wmi_vdev_param_ibss_ps_warmup_time_secs] = 23977 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS; 23978 vdev_param[wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 23979 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE; 23980 vdev_param[wmi_vdev_param_rx_leak_window] = 23981 WMI_VDEV_PARAM_RX_LEAK_WINDOW; 23982 vdev_param[wmi_vdev_param_stats_avg_factor] = 23983 WMI_VDEV_PARAM_STATS_AVG_FACTOR; 23984 vdev_param[wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH; 23985 vdev_param[wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE; 23986 vdev_param[wmi_vdev_param_mcc_rtscts_protection_enable] = 23987 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE; 23988 vdev_param[wmi_vdev_param_mcc_broadcast_probe_enable] = 23989 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; 23990 vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; 23991 vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; 23992 vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; 23993 vdev_param[wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM; 23994 vdev_param[wmi_vdev_param_he_range_ext_enable] = 23995 WMI_VDEV_PARAM_HE_RANGE_EXT; 23996 vdev_param[wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR; 23997 vdev_param[wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE; 23998 vdev_param[wmi_vdev_param_set_he_sounding_mode] 23999 = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 24000 vdev_param[wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31; 24001 vdev_param[wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP; 24002 vdev_param[wmi_vdev_param_dtim_enable_cts] = 24003 WMI_VDEV_PARAM_DTIM_ENABLE_CTS; 24004 vdev_param[wmi_vdev_param_atf_ssid_sched_policy] = 24005 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY; 24006 vdev_param[wmi_vdev_param_disable_dyn_bw_rts] = 24007 WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS; 24008 vdev_param[wmi_vdev_param_mcast2ucast_set] = 24009 WMI_VDEV_PARAM_MCAST2UCAST_SET; 24010 vdev_param[wmi_vdev_param_rc_num_retries] = 24011 WMI_VDEV_PARAM_RC_NUM_RETRIES; 24012 vdev_param[wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR; 24013 vdev_param[wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET; 24014 vdev_param[wmi_vdev_param_rts_fixed_rate] = 24015 WMI_VDEV_PARAM_RTS_FIXED_RATE; 24016 vdev_param[wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK; 24017 vdev_param[wmi_vdev_param_vht80_ratemask] = 24018 WMI_VDEV_PARAM_VHT80_RATEMASK; 24019 vdev_param[wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA; 24020 vdev_param[wmi_vdev_param_bw_nss_ratemask] = 24021 WMI_VDEV_PARAM_BW_NSS_RATEMASK; 24022 vdev_param[wmi_vdev_param_set_he_ltf] = 24023 WMI_VDEV_PARAM_HE_LTF; 24024 vdev_param[wmi_vdev_param_disable_cabq] = 24025 WMI_VDEV_PARAM_DISABLE_CABQ; 24026 vdev_param[wmi_vdev_param_rate_dropdown_bmap] = 24027 WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP; 24028 vdev_param[wmi_vdev_param_set_ba_mode] = 24029 WMI_VDEV_PARAM_BA_MODE; 24030 vdev_param[wmi_vdev_param_capabilities] = 24031 WMI_VDEV_PARAM_CAPABILITIES; 24032 vdev_param[wmi_vdev_param_autorate_misc_cfg] = 24033 WMI_VDEV_PARAM_AUTORATE_MISC_CFG; 24034 } 24035 #endif 24036 24037 /** 24038 * populate_target_defines_tlv() - Populate target defines and params 24039 * @wmi_handle: pointer to wmi handle 24040 * 24041 * Return: None 24042 */ 24043 #ifndef CONFIG_MCL 24044 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 24045 { 24046 populate_pdev_param_tlv(wmi_handle->pdev_param); 24047 populate_vdev_param_tlv(wmi_handle->vdev_param); 24048 } 24049 #else 24050 static void populate_target_defines_tlv(struct wmi_unified *wmi_handle) 24051 { } 24052 #endif 24053 24054 /** 24055 * wmi_ocb_ut_attach() - Attach OCB test framework 24056 * @wmi_handle: wmi handle 24057 * 24058 * Return: None 24059 */ 24060 #ifdef WLAN_OCB_UT 24061 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 24062 #else 24063 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 24064 { 24065 return; 24066 } 24067 #endif 24068 24069 /** 24070 * wmi_tlv_attach() - Attach TLV APIs 24071 * 24072 * Return: None 24073 */ 24074 void wmi_tlv_attach(wmi_unified_t wmi_handle) 24075 { 24076 wmi_handle->ops = &tlv_ops; 24077 wmi_ocb_ut_attach(wmi_handle); 24078 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 24079 #ifdef WMI_INTERFACE_EVENT_LOGGING 24080 /* Skip saving WMI_CMD_HDR and TLV HDR */ 24081 wmi_handle->log_info.buf_offset_command = 8; 24082 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 24083 wmi_handle->log_info.buf_offset_event = 4; 24084 #endif 24085 populate_tlv_events_id(wmi_handle->wmi_events); 24086 populate_tlv_service(wmi_handle->services); 24087 populate_target_defines_tlv(wmi_handle); 24088 wmi_twt_attach_tlv(wmi_handle); 24089 wmi_extscan_attach_tlv(wmi_handle); 24090 } 24091 qdf_export_symbol(wmi_tlv_attach); 24092 24093 /** 24094 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 24095 * 24096 * Return: None 24097 */ 24098 void wmi_tlv_init(void) 24099 { 24100 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 24101 } 24102