1 /* 2 * Copyright (c) 2016-2020 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 <wlan_cmn.h> 27 #include <htc_services.h> 28 #ifdef FEATURE_WLAN_APF 29 #include "wmi_unified_apf_tlv.h" 30 #endif 31 #ifdef WLAN_FEATURE_ACTION_OUI 32 #include "wmi_unified_action_oui_tlv.h" 33 #endif 34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 35 #include "wlan_pmo_hw_filter_public_struct.h" 36 #endif 37 #include <wlan_utility.h> 38 #ifdef WLAN_SUPPORT_GREEN_AP 39 #include "wlan_green_ap_api.h" 40 #endif 41 42 #include "wmi_unified_twt_api.h" 43 44 #ifdef WLAN_POLICY_MGR_ENABLE 45 #include "wlan_policy_mgr_public_struct.h" 46 #endif 47 48 #ifdef WMI_SMART_ANT_SUPPORT 49 #include "wmi_unified_smart_ant_api.h" 50 #endif 51 52 #ifdef WMI_DBR_SUPPORT 53 #include "wmi_unified_dbr_api.h" 54 #endif 55 56 #ifdef WMI_ATF_SUPPORT 57 #include "wmi_unified_atf_api.h" 58 #endif 59 60 #ifdef WMI_AP_SUPPORT 61 #include "wmi_unified_ap_api.h" 62 #endif 63 64 #ifdef WLAN_CFR_ENABLE 65 #include "wmi_unified_cfr_api.h" 66 #endif 67 68 #include <wmi_unified_vdev_api.h> 69 #include <wmi_unified_vdev_tlv.h> 70 71 /* HTC service ids for WMI for multi-radio */ 72 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 73 WMI_CONTROL_SVC_WMAC1, 74 WMI_CONTROL_SVC_WMAC2}; 75 76 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 77 /*Populate peer_param array whose index as host id and 78 *value as target id 79 */ 80 static const uint32_t peer_param_tlv[] = { 81 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 82 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 83 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 84 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 85 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 86 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 87 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 88 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 89 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 90 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 91 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 92 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 93 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 94 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 95 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 96 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 97 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 98 [WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST, 99 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 100 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 101 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 102 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 103 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 104 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 105 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 106 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 107 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 108 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 109 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 110 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 111 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 112 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 113 }; 114 115 /** 116 * Populate pdev_param_value whose index is host param and value is target 117 * param 118 */ 119 static const uint32_t pdev_param_tlv[] = { 120 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 121 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 122 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 123 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 124 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 125 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 126 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 127 [wmi_pdev_param_resmgr_offchan_mode] = 128 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 129 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 130 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 131 [wmi_pdev_param_non_agg_sw_retry_th] = 132 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 133 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 134 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 135 [wmi_pdev_param_ac_aggrsize_scaling] = 136 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 137 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 138 [wmi_pdev_param_ltr_ac_latency_be] = 139 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 140 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 141 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 142 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 143 [wmi_pdev_param_ltr_ac_latency_timeout] = 144 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 145 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 146 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 147 [wmi_pdev_param_ltr_tx_activity_timeout] = 148 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 149 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 150 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 151 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 152 [wmi_pdev_param_pcielp_txbuf_watermark] = 153 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 154 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 155 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 156 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 157 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 158 [wmi_pdev_param_pdev_stats_update_period] = 159 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 160 [wmi_pdev_param_vdev_stats_update_period] = 161 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 162 [wmi_pdev_param_peer_stats_update_period] = 163 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 164 [wmi_pdev_param_bcnflt_stats_update_period] = 165 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 166 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 167 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 168 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 169 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 170 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 171 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 172 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 173 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 174 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 175 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 176 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 177 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 178 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 179 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 180 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 181 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 182 [wmi_pdev_param_low_power_rf_enable] = 183 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 184 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 185 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 186 [wmi_pdev_param_power_collapse_enable] = 187 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 188 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 189 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 190 [wmi_pdev_param_audio_over_wlan_latency] = 191 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 192 [wmi_pdev_param_audio_over_wlan_enable] = 193 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 194 [wmi_pdev_param_whal_mib_stats_update_enable] = 195 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 196 [wmi_pdev_param_vdev_rate_stats_update_period] = 197 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 198 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 199 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 200 [wmi_pdev_param_adaptive_early_rx_enable] = 201 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 202 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 203 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 204 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 205 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 206 [wmi_pdev_param_early_rx_fix_sleep_slop] = 207 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 208 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 209 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 210 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 211 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 212 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 213 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 214 [wmi_pdev_param_bto_fix_bcn_timeout] = 215 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 216 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 217 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 218 [wmi_pdev_param_ce_bto_combo_ce_value] = 219 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 220 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 221 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 222 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 223 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 224 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 225 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 226 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 227 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 228 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 229 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 230 [wmi_pdev_peer_sta_ps_statechg_enable] = 231 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 232 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 233 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 234 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 235 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 236 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 237 [wmi_pdev_param_set_mcast_bcast_echo] = 238 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 239 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 240 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 241 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 242 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 243 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 244 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 245 [wmi_pdev_param_enable_per_tid_amsdu] = 246 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 247 [wmi_pdev_param_enable_per_tid_ampdu] = 248 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 249 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 250 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 251 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 252 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 253 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 254 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 255 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 256 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 257 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 258 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 259 [wmi_pdev_param_atf_obss_noise_sch] = 260 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 261 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 262 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 263 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 264 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 265 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 266 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 267 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 268 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 269 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 270 [wmi_pdev_param_set_disable_reset_cmdid] = 271 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 272 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 273 [wmi_pdev_param_txbf_sound_period_cmdid] = 274 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 275 [wmi_pdev_param_set_burst_mode_cmdid] = 276 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 277 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 278 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 279 [wmi_pdev_param_set_promisc_mode_cmdid] = 280 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 281 [wmi_pdev_param_set_ppdu_duration_cmdid] = 282 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 283 [wmi_pdev_param_remove_mcast2ucast_buffer] = 284 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 285 [wmi_pdev_param_set_mcast2ucast_buffer] = 286 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 287 [wmi_pdev_param_set_mcast2ucast_mode] = 288 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 289 [wmi_pdev_param_smart_antenna_default_antenna] = 290 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 291 [wmi_pdev_param_fast_channel_reset] = 292 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 293 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 294 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 295 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 296 [wmi_pdev_param_antenna_gain_half_db] = 297 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 298 [wmi_pdev_param_esp_indication_period] = 299 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 300 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 301 [wmi_pdev_param_esp_airtime_fraction] = 302 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 303 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 304 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 305 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 306 /* Trigger interval for all trigger types. */ 307 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 308 [wmi_pdev_param_sub_channel_marking] = 309 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 310 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 311 [wmi_pdev_param_equal_ru_allocation_enable] = 312 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 313 [wmi_pdev_param_per_peer_prd_cfr_enable] = 314 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 315 [wmi_pdev_param_nav_override_config] = 316 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 317 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 318 [wmi_pdev_param_set_prb_rsp_ttl] = 319 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 320 [wmi_pdev_param_set_mu_ppdu_duration] = 321 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 322 [wmi_pdev_param_set_tbtt_ctrl] = 323 WMI_PDEV_PARAM_SET_TBTT_CTRL, 324 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 325 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 326 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 327 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 328 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 329 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 330 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 331 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 332 }; 333 334 /** 335 * Populate vdev_param_value_tlv array whose index is host param 336 * and value is target param 337 */ 338 static const uint32_t vdev_param_tlv[] = { 339 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 340 [wmi_vdev_param_fragmentation_threshold] = 341 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 342 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 343 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 344 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 345 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 346 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 347 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 348 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 349 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 350 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 351 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 352 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 353 [wmi_vdev_oc_scheduler_air_time_limit] = 354 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 355 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 356 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 357 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 358 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 359 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 360 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 361 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 362 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 363 [wmi_vdev_param_disable_htprotection] = 364 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 365 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 366 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 367 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 368 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 369 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 370 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 371 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 372 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 373 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 374 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 375 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 376 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 377 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 378 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 379 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 380 [wmi_vdev_param_unknown_dest_indicate] = 381 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 382 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 383 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 384 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 385 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 386 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 387 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 388 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 389 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 390 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 391 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 392 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 393 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 394 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 395 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 396 [wmi_vdev_param_early_rx_adjust_enable] = 397 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 398 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 399 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 400 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 401 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 402 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 403 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 404 [wmi_vdev_param_early_rx_adjust_pause] = 405 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 406 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 407 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 408 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 409 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 410 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 411 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 412 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 413 [wmi_vdev_param_early_rx_drift_sample] = 414 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 415 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 416 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 417 [wmi_vdev_param_ebt_resync_timeout] = 418 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 419 [wmi_vdev_param_aggr_trig_event_enable] = 420 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 421 [wmi_vdev_param_is_ibss_power_save_allowed] = 422 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 423 [wmi_vdev_param_is_power_collapse_allowed] = 424 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 425 [wmi_vdev_param_is_awake_on_txrx_enabled] = 426 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 427 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 428 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 429 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 430 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 431 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 432 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 433 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 434 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 435 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 436 [wmi_vdev_param_stats_avg_factor] = 437 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 438 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 439 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 440 [wmi_vdev_param_mcc_rtscts_protection_enable] = 441 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 442 [wmi_vdev_param_mcc_broadcast_probe_enable] = 443 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 444 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 445 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 446 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 447 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 448 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 449 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 450 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 451 [wmi_vdev_param_set_he_sounding_mode] = 452 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 453 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 454 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 455 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 456 [wmi_vdev_param_atf_ssid_sched_policy] = 457 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 458 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 459 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 460 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 461 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 462 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 463 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 464 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 465 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 466 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 467 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 468 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 469 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 470 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 471 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 472 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 473 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 474 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 475 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 476 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 477 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 478 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 479 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 480 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 481 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 482 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 483 [wmi_vdev_param_mcast_rc_stale_period] = 484 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 485 [wmi_vdev_param_enable_multi_group_key] = 486 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 487 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 488 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 489 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 490 }; 491 #endif 492 493 /** 494 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 495 * host to target defines. 496 * @wmi_handle: pointer to wmi_handle 497 * @param pdev_id: host pdev_id to be converted. 498 * Return: target pdev_id after conversion. 499 */ 500 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 501 uint32_t pdev_id) 502 { 503 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 504 if (!wmi_handle->soc->is_pdev_is_map_enable) { 505 switch (pdev_id) { 506 case WMI_HOST_PDEV_ID_0: 507 return WMI_PDEV_ID_1ST; 508 case WMI_HOST_PDEV_ID_1: 509 return WMI_PDEV_ID_2ND; 510 case WMI_HOST_PDEV_ID_2: 511 return WMI_PDEV_ID_3RD; 512 } 513 } else { 514 return wmi_handle->cmd_pdev_id_map[pdev_id]; 515 } 516 } else { 517 return WMI_PDEV_ID_SOC; 518 } 519 520 QDF_ASSERT(0); 521 522 return WMI_PDEV_ID_SOC; 523 } 524 525 /** 526 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 527 * target to host defines. 528 * @wmi_handle: pointer to wmi_handle 529 * @param pdev_id: target pdev_id to be converted. 530 * Return: host pdev_id after conversion. 531 */ 532 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 533 uint32_t pdev_id) 534 { 535 536 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 537 if (!wmi_handle->soc->is_pdev_is_map_enable) { 538 switch (pdev_id) { 539 case WMI_PDEV_ID_1ST: 540 return WMI_HOST_PDEV_ID_0; 541 case WMI_PDEV_ID_2ND: 542 return WMI_HOST_PDEV_ID_1; 543 case WMI_PDEV_ID_3RD: 544 return WMI_HOST_PDEV_ID_2; 545 } 546 } else { 547 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 548 } 549 } else if (pdev_id == WMI_PDEV_ID_SOC) { 550 return WMI_HOST_PDEV_ID_SOC; 551 } else { 552 WMI_LOGE("Invalid pdev_id"); 553 } 554 555 return WMI_HOST_PDEV_ID_INVALID; 556 } 557 558 /** 559 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 560 * host to target defines. 561 * @wmi_handle: pointer to wmi_handle 562 * @param phy_id: host pdev_id to be converted. 563 * Return: target phy_id after conversion. 564 */ 565 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 566 uint32_t phy_id) 567 { 568 if (!wmi_handle->soc->is_phy_id_map_enable || 569 phy_id >= WMI_MAX_RADIOS) { 570 return phy_id; 571 } 572 573 return wmi_handle->cmd_phy_id_map[phy_id]; 574 } 575 576 /** 577 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 578 * target to host defines. 579 * @wmi_handle: pointer to wmi_handle 580 * @param phy_id: target phy_id to be converted. 581 * Return: host phy_id after conversion. 582 */ 583 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 584 uint32_t phy_id) 585 { 586 if (!wmi_handle->soc->is_phy_id_map_enable || 587 phy_id >= WMI_MAX_RADIOS) { 588 return phy_id; 589 } 590 591 return wmi_handle->evt_phy_id_map[phy_id]; 592 } 593 594 /** 595 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 596 * 597 * Return None. 598 */ 599 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 600 uint32_t *pdev_id_map, 601 uint8_t size) 602 { 603 int i = 0; 604 605 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 606 for (i = 0; i < size; i++) { 607 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 608 wmi_handle->evt_pdev_id_map[i] = 609 WMI_HOST_PDEV_ID_INVALID; 610 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 611 wmi_handle->evt_phy_id_map[i] = 612 WMI_HOST_PDEV_ID_INVALID; 613 } 614 615 for (i = 0; i < size; i++) { 616 if (wmi_handle->cmd_pdev_id_map[i] != 617 WMI_HOST_PDEV_ID_INVALID) { 618 wmi_handle->evt_pdev_id_map 619 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 620 } 621 if (wmi_handle->cmd_phy_id_map[i] != 622 WMI_HOST_PDEV_ID_INVALID) { 623 wmi_handle->evt_phy_id_map 624 [wmi_handle->cmd_phy_id_map[i]] = i; 625 } 626 } 627 wmi_handle->soc->is_pdev_is_map_enable = true; 628 wmi_handle->soc->is_phy_id_map_enable = true; 629 } else { 630 wmi_handle->soc->is_pdev_is_map_enable = false; 631 wmi_handle->soc->is_phy_id_map_enable = false; 632 } 633 634 wmi_handle->ops->convert_pdev_id_host_to_target = 635 convert_host_pdev_id_to_target_pdev_id; 636 wmi_handle->ops->convert_pdev_id_target_to_host = 637 convert_target_pdev_id_to_host_pdev_id; 638 639 /* phy_id convert function assignments */ 640 wmi_handle->ops->convert_phy_id_host_to_target = 641 convert_host_phy_id_to_target_phy_id; 642 wmi_handle->ops->convert_phy_id_target_to_host = 643 convert_target_phy_id_to_host_phy_id; 644 } 645 646 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 647 * buffer. 648 * @wmi_handle: pointer to wmi_handle 649 * @cmd: pointer target vdev create command buffer 650 * @param: pointer host params for vdev create 651 * 652 * Return: None 653 */ 654 static inline void copy_vdev_create_pdev_id( 655 struct wmi_unified *wmi_handle, 656 wmi_vdev_create_cmd_fixed_param * cmd, 657 struct vdev_create_params *param) 658 { 659 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 660 wmi_handle, 661 param->pdev_id); 662 } 663 664 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 665 { 666 uint16_t mtrace_message_id; 667 668 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 669 (QDF_WMI_MTRACE_GRP_ID(message_id) << 670 QDF_WMI_MTRACE_CMD_NUM_BITS); 671 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 672 mtrace_message_id, vdev_id, data); 673 } 674 qdf_export_symbol(wmi_mtrace); 675 676 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 677 static QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 678 wmi_buf_t buf, 679 uint32_t buflen, uint32_t cmd_id) 680 { 681 if (wmi_is_target_suspended(wmi_handle)) { 682 if (QDF_IS_STATUS_SUCCESS( 683 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 684 buflen, cmd_id))) 685 return QDF_STATUS_SUCCESS; 686 } 687 688 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 689 690 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 691 } 692 #else 693 static inline 694 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 695 wmi_buf_t buf, 696 uint32_t buflen, uint32_t cmd_id) 697 { 698 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 699 } 700 #endif 701 702 /** 703 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 704 * @wmi_handle: wmi handle 705 * @param: pointer to hold vdev create parameter 706 * @macaddr: vdev mac address 707 * 708 * Return: QDF_STATUS_SUCCESS for success or error code 709 */ 710 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 711 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 712 struct vdev_create_params *param) 713 { 714 wmi_vdev_create_cmd_fixed_param *cmd; 715 wmi_buf_t buf; 716 int32_t len = sizeof(*cmd); 717 QDF_STATUS ret; 718 int num_bands = 2; 719 uint8_t *buf_ptr; 720 wmi_vdev_txrx_streams *txrx_streams; 721 722 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 723 buf = wmi_buf_alloc(wmi_handle, len); 724 if (!buf) 725 return QDF_STATUS_E_NOMEM; 726 727 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 728 WMITLV_SET_HDR(&cmd->tlv_header, 729 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 730 WMITLV_GET_STRUCT_TLVLEN 731 (wmi_vdev_create_cmd_fixed_param)); 732 cmd->vdev_id = param->vdev_id; 733 cmd->vdev_type = param->type; 734 cmd->vdev_subtype = param->subtype; 735 cmd->flags = param->mbssid_flags; 736 cmd->vdevid_trans = param->vdevid_trans; 737 cmd->num_cfg_txrx_streams = num_bands; 738 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 739 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 740 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 741 __func__, param->vdev_id, cmd->pdev_id, 742 macaddr[0], macaddr[1], macaddr[2], 743 macaddr[3], macaddr[4], macaddr[5]); 744 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 745 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 746 (num_bands * sizeof(wmi_vdev_txrx_streams))); 747 buf_ptr += WMI_TLV_HDR_SIZE; 748 749 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 750 param->type, param->subtype, 751 param->nss_2g, param->nss_5g); 752 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 753 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 754 txrx_streams->supported_tx_streams = param->nss_2g; 755 txrx_streams->supported_rx_streams = param->nss_2g; 756 WMITLV_SET_HDR(&txrx_streams->tlv_header, 757 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 758 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 759 760 txrx_streams++; 761 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 762 txrx_streams->supported_tx_streams = param->nss_5g; 763 txrx_streams->supported_rx_streams = param->nss_5g; 764 WMITLV_SET_HDR(&txrx_streams->tlv_header, 765 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 766 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 767 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 768 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 769 if (QDF_IS_STATUS_ERROR(ret)) { 770 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 771 wmi_buf_free(buf); 772 } 773 774 return ret; 775 } 776 777 /** 778 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 779 * @wmi_handle: wmi handle 780 * @if_id: vdev id 781 * 782 * Return: QDF_STATUS_SUCCESS for success or error code 783 */ 784 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 785 uint8_t if_id) 786 { 787 wmi_vdev_delete_cmd_fixed_param *cmd; 788 wmi_buf_t buf; 789 QDF_STATUS ret; 790 791 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 792 if (!buf) 793 return QDF_STATUS_E_NOMEM; 794 795 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 796 WMITLV_SET_HDR(&cmd->tlv_header, 797 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 798 WMITLV_GET_STRUCT_TLVLEN 799 (wmi_vdev_delete_cmd_fixed_param)); 800 cmd->vdev_id = if_id; 801 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 802 ret = wmi_unified_cmd_send(wmi_handle, buf, 803 sizeof(wmi_vdev_delete_cmd_fixed_param), 804 WMI_VDEV_DELETE_CMDID); 805 if (QDF_IS_STATUS_ERROR(ret)) { 806 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 807 wmi_buf_free(buf); 808 } 809 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 810 811 return ret; 812 } 813 814 /** 815 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 816 * @wmi_handle: wmi handle 817 * @vdev_id: vdev id 818 * @nss_chains_user_cfg: user configured nss chain params 819 * 820 * Return: QDF_STATUS_SUCCESS for success or error code 821 */ 822 static QDF_STATUS 823 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 824 uint8_t vdev_id, 825 struct vdev_nss_chains *user_cfg) 826 { 827 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 828 wmi_buf_t buf; 829 QDF_STATUS ret; 830 831 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 832 if (!buf) 833 return QDF_STATUS_E_NOMEM; 834 835 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 836 WMITLV_SET_HDR(&cmd->tlv_header, 837 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 838 WMITLV_GET_STRUCT_TLVLEN 839 (wmi_vdev_chainmask_config_cmd_fixed_param)); 840 cmd->vdev_id = vdev_id; 841 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 842 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 843 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 844 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 845 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 846 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 847 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 848 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 849 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 850 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 851 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 852 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 853 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 854 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 855 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 856 857 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 858 ret = wmi_unified_cmd_send(wmi_handle, buf, 859 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 860 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 861 if (QDF_IS_STATUS_ERROR(ret)) { 862 WMI_LOGE("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 863 wmi_buf_free(buf); 864 } 865 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 866 867 return ret; 868 } 869 870 /** 871 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 872 * @wmi: wmi handle 873 * @vdev_id: vdev id 874 * 875 * Return: QDF_STATUS_SUCCESS for success or erro code 876 */ 877 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 878 uint8_t vdev_id) 879 { 880 wmi_vdev_stop_cmd_fixed_param *cmd; 881 wmi_buf_t buf; 882 int32_t len = sizeof(*cmd); 883 884 buf = wmi_buf_alloc(wmi, len); 885 if (!buf) 886 return QDF_STATUS_E_NOMEM; 887 888 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 889 WMITLV_SET_HDR(&cmd->tlv_header, 890 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 891 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 892 cmd->vdev_id = vdev_id; 893 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 894 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 895 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 896 wmi_buf_free(buf); 897 return QDF_STATUS_E_FAILURE; 898 } 899 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 900 901 return 0; 902 } 903 904 /** 905 * send_vdev_down_cmd_tlv() - send vdev down command to fw 906 * @wmi: wmi handle 907 * @vdev_id: vdev id 908 * 909 * Return: QDF_STATUS_SUCCESS for success or error code 910 */ 911 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 912 { 913 wmi_vdev_down_cmd_fixed_param *cmd; 914 wmi_buf_t buf; 915 int32_t len = sizeof(*cmd); 916 917 buf = wmi_buf_alloc(wmi, len); 918 if (!buf) 919 return QDF_STATUS_E_NOMEM; 920 921 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 922 WMITLV_SET_HDR(&cmd->tlv_header, 923 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 924 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 925 cmd->vdev_id = vdev_id; 926 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 927 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 928 WMI_LOGP("%s: Failed to send vdev down", __func__); 929 wmi_buf_free(buf); 930 return QDF_STATUS_E_FAILURE; 931 } 932 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 933 934 return 0; 935 } 936 937 static inline void copy_channel_info( 938 wmi_vdev_start_request_cmd_fixed_param * cmd, 939 wmi_channel *chan, 940 struct vdev_start_params *req) 941 { 942 chan->mhz = req->channel.mhz; 943 944 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 945 946 chan->band_center_freq1 = req->channel.cfreq1; 947 chan->band_center_freq2 = req->channel.cfreq2; 948 949 if (req->channel.half_rate) 950 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 951 else if (req->channel.quarter_rate) 952 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 953 954 if (req->channel.dfs_set) { 955 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 956 cmd->disable_hw_ack = req->disable_hw_ack; 957 } 958 959 if (req->channel.dfs_set_cfreq2) 960 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 961 962 /* According to firmware both reg power and max tx power 963 * on set channel power is used and set it to max reg 964 * power from regulatory. 965 */ 966 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 967 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 968 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 969 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 970 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 971 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 972 973 } 974 975 /** 976 * send_vdev_start_cmd_tlv() - send vdev start request to fw 977 * @wmi_handle: wmi handle 978 * @req: vdev start params 979 * 980 * Return: QDF status 981 */ 982 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 983 struct vdev_start_params *req) 984 { 985 wmi_vdev_start_request_cmd_fixed_param *cmd; 986 wmi_buf_t buf; 987 wmi_channel *chan; 988 int32_t len, ret; 989 uint8_t *buf_ptr; 990 991 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 992 buf = wmi_buf_alloc(wmi_handle, len); 993 if (!buf) 994 return QDF_STATUS_E_NOMEM; 995 996 buf_ptr = (uint8_t *) wmi_buf_data(buf); 997 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 998 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 999 WMITLV_SET_HDR(&cmd->tlv_header, 1000 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1001 WMITLV_GET_STRUCT_TLVLEN 1002 (wmi_vdev_start_request_cmd_fixed_param)); 1003 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1004 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1005 cmd->vdev_id = req->vdev_id; 1006 1007 /* Fill channel info */ 1008 copy_channel_info(cmd, chan, req); 1009 cmd->beacon_interval = req->beacon_interval; 1010 cmd->dtim_period = req->dtim_period; 1011 1012 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1013 if (req->bcn_tx_rate_code) 1014 wmi_enable_bcn_ratecode(cmd->flags); 1015 1016 if (!req->is_restart) { 1017 if (req->pmf_enabled) 1018 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1019 } 1020 1021 /* Copy the SSID */ 1022 if (req->ssid.length) { 1023 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1024 cmd->ssid.ssid_len = req->ssid.length; 1025 else 1026 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1027 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 1028 cmd->ssid.ssid_len); 1029 } 1030 1031 if (req->hidden_ssid) 1032 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1033 1034 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1035 cmd->num_noa_descriptors = req->num_noa_descriptors; 1036 cmd->preferred_rx_streams = req->preferred_rx_streams; 1037 cmd->preferred_tx_streams = req->preferred_tx_streams; 1038 cmd->cac_duration_ms = req->cac_duration_ms; 1039 cmd->regdomain = req->regdomain; 1040 cmd->he_ops = req->he_ops; 1041 1042 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1043 sizeof(wmi_channel)); 1044 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1045 cmd->num_noa_descriptors * 1046 sizeof(wmi_p2p_noa_descriptor)); 1047 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1048 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1049 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1050 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1051 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 1052 chan->mhz, req->channel.phy_mode, chan->info, 1053 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1054 chan->band_center_freq1, chan->band_center_freq2, 1055 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1056 req->preferred_tx_streams, req->preferred_rx_streams, 1057 req->ldpc_rx_enabled, req->cac_duration_ms, 1058 req->regdomain, req->he_ops, 1059 req->disable_hw_ack); 1060 1061 if (req->is_restart) { 1062 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1063 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1064 WMI_VDEV_RESTART_REQUEST_CMDID); 1065 } else { 1066 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1067 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1068 WMI_VDEV_START_REQUEST_CMDID); 1069 } 1070 if (ret) { 1071 WMI_LOGP("%s: Failed to send vdev start command", __func__); 1072 wmi_buf_free(buf); 1073 return QDF_STATUS_E_FAILURE; 1074 } 1075 1076 return QDF_STATUS_SUCCESS; 1077 } 1078 1079 /** 1080 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1081 * @wmi: wmi handle 1082 * @peer_addr: peer mac address 1083 * @param: pointer to hold peer flush tid parameter 1084 * 1085 * Return: 0 for success or error code 1086 */ 1087 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1088 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1089 struct peer_flush_params *param) 1090 { 1091 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1092 wmi_buf_t buf; 1093 int32_t len = sizeof(*cmd); 1094 1095 buf = wmi_buf_alloc(wmi, len); 1096 if (!buf) 1097 return QDF_STATUS_E_NOMEM; 1098 1099 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1100 WMITLV_SET_HDR(&cmd->tlv_header, 1101 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1102 WMITLV_GET_STRUCT_TLVLEN 1103 (wmi_peer_flush_tids_cmd_fixed_param)); 1104 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1105 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1106 cmd->vdev_id = param->vdev_id; 1107 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 1108 peer_addr, param->vdev_id, 1109 param->peer_tid_bitmap); 1110 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1111 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1112 WMI_LOGP("%s: Failed to send flush tid command", __func__); 1113 wmi_buf_free(buf); 1114 return QDF_STATUS_E_FAILURE; 1115 } 1116 1117 return 0; 1118 } 1119 1120 /** 1121 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1122 * @wmi: wmi handle 1123 * @peer_addr: peer mac addr 1124 * @vdev_id: vdev id 1125 * 1126 * Return: QDF_STATUS_SUCCESS for success or error code 1127 */ 1128 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1129 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1130 uint8_t vdev_id) 1131 { 1132 wmi_peer_delete_cmd_fixed_param *cmd; 1133 wmi_buf_t buf; 1134 int32_t len = sizeof(*cmd); 1135 buf = wmi_buf_alloc(wmi, len); 1136 if (!buf) 1137 return QDF_STATUS_E_NOMEM; 1138 1139 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 1140 WMITLV_SET_HDR(&cmd->tlv_header, 1141 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1142 WMITLV_GET_STRUCT_TLVLEN 1143 (wmi_peer_delete_cmd_fixed_param)); 1144 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1145 cmd->vdev_id = vdev_id; 1146 1147 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 1148 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1149 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1150 WMI_LOGP("%s: Failed to send peer delete command", __func__); 1151 wmi_buf_free(buf); 1152 return QDF_STATUS_E_FAILURE; 1153 } 1154 1155 return 0; 1156 } 1157 1158 /** 1159 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1160 * @wmi: wmi handle 1161 * @param: pointer to hold peer delete all parameter 1162 * 1163 * Return: QDF_STATUS_SUCCESS for success or error code 1164 */ 1165 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1166 wmi_unified_t wmi, 1167 struct peer_delete_all_params *param) 1168 { 1169 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1170 wmi_buf_t buf; 1171 int32_t len = sizeof(*cmd); 1172 1173 buf = wmi_buf_alloc(wmi, len); 1174 if (!buf) 1175 return QDF_STATUS_E_NOMEM; 1176 1177 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1178 WMITLV_SET_HDR( 1179 &cmd->tlv_header, 1180 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1181 WMITLV_GET_STRUCT_TLVLEN 1182 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1183 cmd->vdev_id = param->vdev_id; 1184 1185 WMI_LOGD("%s: vdev_id %d", __func__, cmd->vdev_id); 1186 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1187 if (wmi_unified_cmd_send(wmi, buf, len, 1188 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1189 WMI_LOGP("%s: Failed to send peer del all command", __func__); 1190 wmi_buf_free(buf); 1191 return QDF_STATUS_E_FAILURE; 1192 } 1193 1194 return QDF_STATUS_SUCCESS; 1195 } 1196 1197 /** 1198 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1199 * to target id. 1200 * @peer_param_id: host param id. 1201 * 1202 * Return: Target param id. 1203 */ 1204 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1205 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1206 uint32_t peer_param_id) 1207 { 1208 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1209 return peer_param_tlv[peer_param_id]; 1210 return WMI_UNAVAILABLE_PARAM; 1211 } 1212 #else 1213 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1214 uint32_t peer_param_id) 1215 { 1216 return peer_param_id; 1217 } 1218 #endif 1219 1220 /** 1221 * send_peer_param_cmd_tlv() - set peer parameter in fw 1222 * @wmi: wmi handle 1223 * @peer_addr: peer mac address 1224 * @param : pointer to hold peer set parameter 1225 * 1226 * Return: QDF_STATUS_SUCCESS for success or error code 1227 */ 1228 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1229 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1230 struct peer_set_params *param) 1231 { 1232 wmi_peer_set_param_cmd_fixed_param *cmd; 1233 wmi_buf_t buf; 1234 int32_t err; 1235 uint32_t param_id; 1236 1237 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1238 if (param_id == WMI_UNAVAILABLE_PARAM) { 1239 WMI_LOGW("%s: Unavailable param %d", __func__, param->param_id); 1240 return QDF_STATUS_E_NOSUPPORT; 1241 } 1242 1243 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1244 if (!buf) 1245 return QDF_STATUS_E_NOMEM; 1246 1247 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1248 WMITLV_SET_HDR(&cmd->tlv_header, 1249 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1250 WMITLV_GET_STRUCT_TLVLEN 1251 (wmi_peer_set_param_cmd_fixed_param)); 1252 cmd->vdev_id = param->vdev_id; 1253 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1254 cmd->param_id = param_id; 1255 cmd->param_value = param->param_value; 1256 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1257 err = wmi_unified_cmd_send(wmi, buf, 1258 sizeof(wmi_peer_set_param_cmd_fixed_param), 1259 WMI_PEER_SET_PARAM_CMDID); 1260 if (err) { 1261 WMI_LOGE("Failed to send set_param cmd"); 1262 wmi_buf_free(buf); 1263 return QDF_STATUS_E_FAILURE; 1264 } 1265 1266 return 0; 1267 } 1268 1269 /** 1270 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1271 * @wmi: wmi handle 1272 * @bssid: bssid 1273 * @vdev_up_params: pointer to hold vdev up parameter 1274 * 1275 * Return: QDF_STATUS_SUCCESS for success or error code 1276 */ 1277 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1278 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1279 struct vdev_up_params *params) 1280 { 1281 wmi_vdev_up_cmd_fixed_param *cmd; 1282 wmi_buf_t buf; 1283 int32_t len = sizeof(*cmd); 1284 1285 WMI_LOGD("%s: VDEV_UP", __func__); 1286 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 1287 params->vdev_id, params->assoc_id, bssid); 1288 buf = wmi_buf_alloc(wmi, len); 1289 if (!buf) 1290 return QDF_STATUS_E_NOMEM; 1291 1292 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1293 WMITLV_SET_HDR(&cmd->tlv_header, 1294 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1295 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1296 cmd->vdev_id = params->vdev_id; 1297 cmd->vdev_assoc_id = params->assoc_id; 1298 cmd->profile_idx = params->profile_idx; 1299 cmd->profile_num = params->profile_num; 1300 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1301 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1302 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1303 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1304 WMI_LOGP("%s: Failed to send vdev up command", __func__); 1305 wmi_buf_free(buf); 1306 return QDF_STATUS_E_FAILURE; 1307 } 1308 1309 return 0; 1310 } 1311 1312 /** 1313 * send_peer_create_cmd_tlv() - send peer create command to fw 1314 * @wmi: wmi handle 1315 * @peer_addr: peer mac address 1316 * @peer_type: peer type 1317 * @vdev_id: vdev id 1318 * 1319 * Return: QDF_STATUS_SUCCESS for success or error code 1320 */ 1321 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1322 struct peer_create_params *param) 1323 { 1324 wmi_peer_create_cmd_fixed_param *cmd; 1325 wmi_buf_t buf; 1326 int32_t len = sizeof(*cmd); 1327 1328 buf = wmi_buf_alloc(wmi, len); 1329 if (!buf) 1330 return QDF_STATUS_E_NOMEM; 1331 1332 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1333 WMITLV_SET_HDR(&cmd->tlv_header, 1334 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1335 WMITLV_GET_STRUCT_TLVLEN 1336 (wmi_peer_create_cmd_fixed_param)); 1337 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1338 cmd->peer_type = param->peer_type; 1339 cmd->vdev_id = param->vdev_id; 1340 1341 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1342 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1343 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 1344 wmi_buf_free(buf); 1345 return QDF_STATUS_E_FAILURE; 1346 } 1347 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 1348 param->vdev_id); 1349 1350 return 0; 1351 } 1352 1353 /** 1354 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1355 * command to fw 1356 * @wmi: wmi handle 1357 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1358 * 1359 * Return: 0 for success or error code 1360 */ 1361 static 1362 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1363 struct rx_reorder_queue_setup_params *param) 1364 { 1365 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1366 wmi_buf_t buf; 1367 int32_t len = sizeof(*cmd); 1368 1369 buf = wmi_buf_alloc(wmi, len); 1370 if (!buf) 1371 return QDF_STATUS_E_NOMEM; 1372 1373 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1374 WMITLV_SET_HDR(&cmd->tlv_header, 1375 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1376 WMITLV_GET_STRUCT_TLVLEN 1377 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1378 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1379 cmd->vdev_id = param->vdev_id; 1380 cmd->tid = param->tid; 1381 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1382 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1383 cmd->queue_no = param->queue_no; 1384 cmd->ba_window_size_valid = param->ba_window_size_valid; 1385 cmd->ba_window_size = param->ba_window_size; 1386 1387 1388 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1389 if (wmi_unified_cmd_send(wmi, buf, len, 1390 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1391 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 1392 __func__); 1393 wmi_buf_free(buf); 1394 return QDF_STATUS_E_FAILURE; 1395 } 1396 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d", __func__, 1397 param->peer_macaddr, param->vdev_id, param->tid); 1398 1399 return QDF_STATUS_SUCCESS; 1400 } 1401 1402 /** 1403 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1404 * command to fw 1405 * @wmi: wmi handle 1406 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1407 * 1408 * Return: 0 for success or error code 1409 */ 1410 static 1411 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1412 struct rx_reorder_queue_remove_params *param) 1413 { 1414 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1415 wmi_buf_t buf; 1416 int32_t len = sizeof(*cmd); 1417 1418 buf = wmi_buf_alloc(wmi, len); 1419 if (!buf) 1420 return QDF_STATUS_E_NOMEM; 1421 1422 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1423 wmi_buf_data(buf); 1424 WMITLV_SET_HDR(&cmd->tlv_header, 1425 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1426 WMITLV_GET_STRUCT_TLVLEN 1427 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1428 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1429 cmd->vdev_id = param->vdev_id; 1430 cmd->tid_mask = param->peer_tid_bitmap; 1431 1432 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1433 if (wmi_unified_cmd_send(wmi, buf, len, 1434 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1435 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 1436 __func__); 1437 wmi_buf_free(buf); 1438 return QDF_STATUS_E_FAILURE; 1439 } 1440 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 1441 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 1442 1443 return QDF_STATUS_SUCCESS; 1444 } 1445 1446 #ifdef WLAN_SUPPORT_GREEN_AP 1447 /** 1448 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1449 * @wmi_handle: wmi handle 1450 * @value: value 1451 * @pdev_id: pdev id to have radio context 1452 * 1453 * Return: QDF_STATUS_SUCCESS for success or error code 1454 */ 1455 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1456 uint32_t value, uint8_t pdev_id) 1457 { 1458 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1459 wmi_buf_t buf; 1460 int32_t len = sizeof(*cmd); 1461 1462 WMI_LOGD("Set Green AP PS val %d", value); 1463 1464 buf = wmi_buf_alloc(wmi_handle, len); 1465 if (!buf) 1466 return QDF_STATUS_E_NOMEM; 1467 1468 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1469 WMITLV_SET_HDR(&cmd->tlv_header, 1470 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1471 WMITLV_GET_STRUCT_TLVLEN 1472 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1473 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1474 wmi_handle, 1475 pdev_id); 1476 cmd->enable = value; 1477 1478 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1479 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1480 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1481 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1482 wmi_buf_free(buf); 1483 return QDF_STATUS_E_FAILURE; 1484 } 1485 1486 return 0; 1487 } 1488 #endif 1489 1490 /** 1491 * send_pdev_utf_cmd_tlv() - send utf command to fw 1492 * @wmi_handle: wmi handle 1493 * @param: pointer to pdev_utf_params 1494 * @mac_id: mac id to have radio context 1495 * 1496 * Return: QDF_STATUS_SUCCESS for success or error code 1497 */ 1498 static QDF_STATUS 1499 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1500 struct pdev_utf_params *param, 1501 uint8_t mac_id) 1502 { 1503 wmi_buf_t buf; 1504 uint8_t *cmd; 1505 /* if param->len is 0 no data is sent, return error */ 1506 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1507 static uint8_t msgref = 1; 1508 uint8_t segNumber = 0, segInfo, numSegments; 1509 uint16_t chunk_len, total_bytes; 1510 uint8_t *bufpos; 1511 struct seg_hdr_info segHdrInfo; 1512 1513 bufpos = param->utf_payload; 1514 total_bytes = param->len; 1515 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1516 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1517 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1518 1519 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1520 numSegments++; 1521 1522 while (param->len) { 1523 if (param->len > MAX_WMI_UTF_LEN) 1524 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1525 else 1526 chunk_len = param->len; 1527 1528 buf = wmi_buf_alloc(wmi_handle, 1529 (chunk_len + sizeof(segHdrInfo) + 1530 WMI_TLV_HDR_SIZE)); 1531 if (!buf) 1532 return QDF_STATUS_E_NOMEM; 1533 1534 cmd = (uint8_t *) wmi_buf_data(buf); 1535 1536 segHdrInfo.len = total_bytes; 1537 segHdrInfo.msgref = msgref; 1538 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1539 segHdrInfo.segmentInfo = segInfo; 1540 segHdrInfo.pad = 0; 1541 1542 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1543 " segHdrInfo.segmentInfo = %d", 1544 __func__, segHdrInfo.len, segHdrInfo.msgref, 1545 segHdrInfo.segmentInfo); 1546 1547 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1548 "chunk len %d", __func__, total_bytes, segNumber, 1549 numSegments, chunk_len); 1550 1551 segNumber++; 1552 1553 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1554 (chunk_len + sizeof(segHdrInfo))); 1555 cmd += WMI_TLV_HDR_SIZE; 1556 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1557 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1558 1559 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1560 ret = wmi_unified_cmd_send(wmi_handle, buf, 1561 (chunk_len + sizeof(segHdrInfo) + 1562 WMI_TLV_HDR_SIZE), 1563 WMI_PDEV_UTF_CMDID); 1564 1565 if (QDF_IS_STATUS_ERROR(ret)) { 1566 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1567 wmi_buf_free(buf); 1568 break; 1569 } 1570 1571 param->len -= chunk_len; 1572 bufpos += chunk_len; 1573 } 1574 1575 msgref++; 1576 1577 return ret; 1578 } 1579 1580 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1581 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1582 { 1583 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1584 return pdev_param_tlv[host_param]; 1585 return WMI_UNAVAILABLE_PARAM; 1586 } 1587 #else 1588 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1589 { 1590 return host_param; 1591 } 1592 #endif 1593 1594 /** 1595 * send_pdev_param_cmd_tlv() - set pdev parameters 1596 * @wmi_handle: wmi handle 1597 * @param: pointer to pdev parameter 1598 * @mac_id: radio context 1599 * 1600 * Return: 0 on success, errno on failure 1601 */ 1602 static QDF_STATUS 1603 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1604 struct pdev_params *param, 1605 uint8_t mac_id) 1606 { 1607 QDF_STATUS ret; 1608 wmi_pdev_set_param_cmd_fixed_param *cmd; 1609 wmi_buf_t buf; 1610 uint16_t len = sizeof(*cmd); 1611 uint32_t pdev_param; 1612 1613 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1614 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1615 WMI_LOGW("%s: Unavailable param %d", 1616 __func__, param->param_id); 1617 return QDF_STATUS_E_INVAL; 1618 } 1619 1620 buf = wmi_buf_alloc(wmi_handle, len); 1621 if (!buf) 1622 return QDF_STATUS_E_NOMEM; 1623 1624 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1625 WMITLV_SET_HDR(&cmd->tlv_header, 1626 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1627 WMITLV_GET_STRUCT_TLVLEN 1628 (wmi_pdev_set_param_cmd_fixed_param)); 1629 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1630 wmi_handle, 1631 mac_id); 1632 cmd->param_id = pdev_param; 1633 cmd->param_value = param->param_value; 1634 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1635 param->param_value); 1636 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1637 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1638 WMI_PDEV_SET_PARAM_CMDID); 1639 if (QDF_IS_STATUS_ERROR(ret)) { 1640 WMI_LOGE("Failed to send set param command ret = %d", ret); 1641 wmi_buf_free(buf); 1642 } 1643 return ret; 1644 } 1645 1646 /** 1647 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1648 * @wmi_handle: wmi handle 1649 * @msg: Structure containing the following parameters 1650 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1651 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 1652 * 1653 * Provides notification to the WLAN firmware that host driver is requesting a 1654 * HardWare (HW) Mode change. This command is needed to support iHelium in the 1655 * configurations that include the Dual Band Simultaneous (DBS) feature. 1656 * 1657 * Return: Success if the cmd is sent successfully to the firmware 1658 */ 1659 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 1660 uint32_t hw_mode_index) 1661 { 1662 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 1663 wmi_buf_t buf; 1664 uint32_t len; 1665 1666 len = sizeof(*cmd); 1667 1668 buf = wmi_buf_alloc(wmi_handle, len); 1669 if (!buf) 1670 return QDF_STATUS_E_NOMEM; 1671 1672 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 1673 WMITLV_SET_HDR(&cmd->tlv_header, 1674 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 1675 WMITLV_GET_STRUCT_TLVLEN( 1676 wmi_pdev_set_hw_mode_cmd_fixed_param)); 1677 1678 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1679 wmi_handle, 1680 WMI_HOST_PDEV_ID_SOC); 1681 cmd->hw_mode_index = hw_mode_index; 1682 WMI_LOGD("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 1683 1684 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 1685 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1686 WMI_PDEV_SET_HW_MODE_CMDID)) { 1687 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 1688 __func__); 1689 wmi_buf_free(buf); 1690 return QDF_STATUS_E_FAILURE; 1691 } 1692 1693 return QDF_STATUS_SUCCESS; 1694 } 1695 1696 /** 1697 * send_suspend_cmd_tlv() - WMI suspend function 1698 * @param wmi_handle : handle to WMI. 1699 * @param param : pointer to hold suspend parameter 1700 * @mac_id: radio context 1701 * 1702 * Return 0 on success and -ve on failure. 1703 */ 1704 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1705 struct suspend_params *param, 1706 uint8_t mac_id) 1707 { 1708 wmi_pdev_suspend_cmd_fixed_param *cmd; 1709 wmi_buf_t wmibuf; 1710 uint32_t len = sizeof(*cmd); 1711 int32_t ret; 1712 1713 /* 1714 * send the command to Target to ignore the 1715 * PCIE reset so as to ensure that Host and target 1716 * states are in sync 1717 */ 1718 wmibuf = wmi_buf_alloc(wmi_handle, len); 1719 if (!wmibuf) 1720 return QDF_STATUS_E_NOMEM; 1721 1722 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1723 WMITLV_SET_HDR(&cmd->tlv_header, 1724 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1725 WMITLV_GET_STRUCT_TLVLEN 1726 (wmi_pdev_suspend_cmd_fixed_param)); 1727 if (param->disable_target_intr) 1728 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1729 else 1730 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1731 1732 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1733 wmi_handle, 1734 mac_id); 1735 1736 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1737 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1738 WMI_PDEV_SUSPEND_CMDID); 1739 if (ret) { 1740 wmi_buf_free(wmibuf); 1741 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1742 } 1743 1744 return ret; 1745 } 1746 1747 /** 1748 * send_resume_cmd_tlv() - WMI resume function 1749 * @param wmi_handle : handle to WMI. 1750 * @mac_id: radio context 1751 * 1752 * Return: 0 on success and -ve on failure. 1753 */ 1754 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1755 uint8_t mac_id) 1756 { 1757 wmi_buf_t wmibuf; 1758 wmi_pdev_resume_cmd_fixed_param *cmd; 1759 QDF_STATUS ret; 1760 1761 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1762 if (!wmibuf) 1763 return QDF_STATUS_E_NOMEM; 1764 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1765 WMITLV_SET_HDR(&cmd->tlv_header, 1766 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1767 WMITLV_GET_STRUCT_TLVLEN 1768 (wmi_pdev_resume_cmd_fixed_param)); 1769 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1770 wmi_handle, 1771 mac_id); 1772 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1773 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1774 WMI_PDEV_RESUME_CMDID); 1775 if (QDF_IS_STATUS_ERROR(ret)) { 1776 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1777 wmi_buf_free(wmibuf); 1778 } 1779 1780 return ret; 1781 } 1782 1783 /** 1784 * send_wow_enable_cmd_tlv() - WMI wow enable function 1785 * @param wmi_handle : handle to WMI. 1786 * @param param : pointer to hold wow enable parameter 1787 * @mac_id: radio context 1788 * 1789 * Return: 0 on success and -ve on failure. 1790 */ 1791 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1792 struct wow_cmd_params *param, 1793 uint8_t mac_id) 1794 { 1795 wmi_wow_enable_cmd_fixed_param *cmd; 1796 wmi_buf_t buf; 1797 int32_t len; 1798 int32_t ret; 1799 1800 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1801 1802 buf = wmi_buf_alloc(wmi_handle, len); 1803 if (!buf) 1804 return QDF_STATUS_E_NOMEM; 1805 1806 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1807 WMITLV_SET_HDR(&cmd->tlv_header, 1808 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1809 WMITLV_GET_STRUCT_TLVLEN 1810 (wmi_wow_enable_cmd_fixed_param)); 1811 cmd->enable = param->enable; 1812 if (param->can_suspend_link) 1813 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1814 else 1815 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1816 cmd->flags = param->flags; 1817 1818 WMI_LOGI("suspend type: %s", 1819 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1820 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1821 1822 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1823 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1824 WMI_WOW_ENABLE_CMDID); 1825 if (ret) 1826 wmi_buf_free(buf); 1827 1828 return ret; 1829 } 1830 1831 /** 1832 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1833 * @wmi_handle: wmi handle 1834 * @peer_addr: peer mac address 1835 * @param: pointer to ap_ps parameter structure 1836 * 1837 * Return: QDF_STATUS_SUCCESS for success or error code 1838 */ 1839 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1840 uint8_t *peer_addr, 1841 struct ap_ps_params *param) 1842 { 1843 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1844 wmi_buf_t buf; 1845 int32_t err; 1846 1847 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1848 if (!buf) 1849 return QDF_STATUS_E_NOMEM; 1850 1851 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1852 WMITLV_SET_HDR(&cmd->tlv_header, 1853 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1854 WMITLV_GET_STRUCT_TLVLEN 1855 (wmi_ap_ps_peer_cmd_fixed_param)); 1856 cmd->vdev_id = param->vdev_id; 1857 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1858 cmd->param = param->param; 1859 cmd->value = param->value; 1860 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1861 err = wmi_unified_cmd_send(wmi_handle, buf, 1862 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1863 if (err) { 1864 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1865 wmi_buf_free(buf); 1866 return QDF_STATUS_E_FAILURE; 1867 } 1868 1869 return 0; 1870 } 1871 1872 /** 1873 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1874 * @wmi_handle: wmi handle 1875 * @peer_addr: peer mac address 1876 * @param: pointer to sta_ps parameter structure 1877 * 1878 * Return: QDF_STATUS_SUCCESS for success or error code 1879 */ 1880 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1881 struct sta_ps_params *param) 1882 { 1883 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1884 wmi_buf_t buf; 1885 int32_t len = sizeof(*cmd); 1886 1887 buf = wmi_buf_alloc(wmi_handle, len); 1888 if (!buf) 1889 return QDF_STATUS_E_NOMEM; 1890 1891 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1892 WMITLV_SET_HDR(&cmd->tlv_header, 1893 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1894 WMITLV_GET_STRUCT_TLVLEN 1895 (wmi_sta_powersave_param_cmd_fixed_param)); 1896 cmd->vdev_id = param->vdev_id; 1897 cmd->param = param->param_id; 1898 cmd->value = param->value; 1899 1900 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 1901 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1902 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1903 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1904 param->vdev_id, param->param_id, param->value); 1905 wmi_buf_free(buf); 1906 return QDF_STATUS_E_FAILURE; 1907 } 1908 1909 return 0; 1910 } 1911 1912 /** 1913 * send_crash_inject_cmd_tlv() - inject fw crash 1914 * @wmi_handle: wmi handle 1915 * @param: ponirt to crash inject parameter structure 1916 * 1917 * Return: QDF_STATUS_SUCCESS for success or return error 1918 */ 1919 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1920 struct crash_inject *param) 1921 { 1922 int32_t ret = 0; 1923 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1924 uint16_t len = sizeof(*cmd); 1925 wmi_buf_t buf; 1926 1927 buf = wmi_buf_alloc(wmi_handle, len); 1928 if (!buf) 1929 return QDF_STATUS_E_NOMEM; 1930 1931 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1932 WMITLV_SET_HDR(&cmd->tlv_header, 1933 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1934 WMITLV_GET_STRUCT_TLVLEN 1935 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1936 cmd->type = param->type; 1937 cmd->delay_time_ms = param->delay_time_ms; 1938 1939 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 1940 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1941 WMI_FORCE_FW_HANG_CMDID); 1942 if (ret) { 1943 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1944 __func__, ret); 1945 wmi_buf_free(buf); 1946 } 1947 1948 return ret; 1949 } 1950 1951 #ifdef FEATURE_FW_LOG_PARSING 1952 /** 1953 * send_dbglog_cmd_tlv() - set debug log level 1954 * @param wmi_handle : handle to WMI. 1955 * @param param : pointer to hold dbglog level parameter 1956 * 1957 * Return: 0 on success and -ve on failure. 1958 */ 1959 static QDF_STATUS 1960 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1961 struct dbglog_params *dbglog_param) 1962 { 1963 wmi_buf_t buf; 1964 wmi_debug_log_config_cmd_fixed_param *configmsg; 1965 QDF_STATUS status; 1966 int32_t i; 1967 int32_t len; 1968 int8_t *buf_ptr; 1969 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 1970 1971 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 1972 1973 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 1974 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 1975 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1976 buf = wmi_buf_alloc(wmi_handle, len); 1977 if (!buf) 1978 return QDF_STATUS_E_NOMEM; 1979 1980 configmsg = 1981 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 1982 buf_ptr = (int8_t *) configmsg; 1983 WMITLV_SET_HDR(&configmsg->tlv_header, 1984 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 1985 WMITLV_GET_STRUCT_TLVLEN 1986 (wmi_debug_log_config_cmd_fixed_param)); 1987 configmsg->dbg_log_param = dbglog_param->param; 1988 configmsg->value = dbglog_param->val; 1989 /* Filling in the data part of second tlv -- should 1990 * follow first tlv _ WMI_TLV_HDR_SIZE */ 1991 module_id_bitmap_array = (uint32_t *) (buf_ptr + 1992 sizeof 1993 (wmi_debug_log_config_cmd_fixed_param) 1994 + WMI_TLV_HDR_SIZE); 1995 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 1996 WMITLV_TAG_ARRAY_UINT32, 1997 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 1998 if (dbglog_param->module_id_bitmap) { 1999 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2000 module_id_bitmap_array[i] = 2001 dbglog_param->module_id_bitmap[i]; 2002 } 2003 } 2004 2005 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2006 status = wmi_unified_cmd_send(wmi_handle, buf, 2007 len, WMI_DBGLOG_CFG_CMDID); 2008 2009 if (status != QDF_STATUS_SUCCESS) 2010 wmi_buf_free(buf); 2011 2012 return status; 2013 } 2014 #endif 2015 2016 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2017 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2018 { 2019 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2020 return vdev_param_tlv[host_param]; 2021 return WMI_UNAVAILABLE_PARAM; 2022 } 2023 #else 2024 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2025 { 2026 return host_param; 2027 } 2028 #endif 2029 2030 /** 2031 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2032 * @param wmi_handle : handle to WMI. 2033 * @param macaddr : MAC address 2034 * @param param : pointer to hold vdev set parameter 2035 * 2036 * Return: 0 on success and -ve on failure. 2037 */ 2038 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2039 struct vdev_set_params *param) 2040 { 2041 QDF_STATUS ret; 2042 wmi_vdev_set_param_cmd_fixed_param *cmd; 2043 wmi_buf_t buf; 2044 uint16_t len = sizeof(*cmd); 2045 uint32_t vdev_param; 2046 2047 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2048 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2049 WMI_LOGW("%s:Vdev param %d not available", __func__, 2050 param->param_id); 2051 return QDF_STATUS_E_INVAL; 2052 2053 } 2054 2055 buf = wmi_buf_alloc(wmi_handle, len); 2056 if (!buf) 2057 return QDF_STATUS_E_NOMEM; 2058 2059 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2060 WMITLV_SET_HDR(&cmd->tlv_header, 2061 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2062 WMITLV_GET_STRUCT_TLVLEN 2063 (wmi_vdev_set_param_cmd_fixed_param)); 2064 cmd->vdev_id = param->vdev_id; 2065 cmd->param_id = vdev_param; 2066 cmd->param_value = param->param_value; 2067 WMI_LOGD("Setting vdev %d param = %x, value = %u", 2068 cmd->vdev_id, cmd->param_id, cmd->param_value); 2069 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2071 WMI_VDEV_SET_PARAM_CMDID); 2072 if (QDF_IS_STATUS_ERROR(ret)) { 2073 WMI_LOGE("Failed to send set param command ret = %d", ret); 2074 wmi_buf_free(buf); 2075 } 2076 2077 return ret; 2078 } 2079 2080 /** 2081 * send_stats_request_cmd_tlv() - WMI request stats function 2082 * @param wmi_handle : handle to WMI. 2083 * @param macaddr : MAC address 2084 * @param param : pointer to hold stats request parameter 2085 * 2086 * Return: 0 on success and -ve on failure. 2087 */ 2088 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 2089 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 2090 struct stats_request_params *param) 2091 { 2092 int32_t ret; 2093 wmi_request_stats_cmd_fixed_param *cmd; 2094 wmi_buf_t buf; 2095 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 2096 2097 buf = wmi_buf_alloc(wmi_handle, len); 2098 if (!buf) 2099 return -QDF_STATUS_E_NOMEM; 2100 2101 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 2102 WMITLV_SET_HDR(&cmd->tlv_header, 2103 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 2104 WMITLV_GET_STRUCT_TLVLEN 2105 (wmi_request_stats_cmd_fixed_param)); 2106 cmd->stats_id = param->stats_id; 2107 cmd->vdev_id = param->vdev_id; 2108 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2109 wmi_handle, 2110 param->pdev_id); 2111 2112 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 2113 2114 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 2115 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 2116 2117 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 2118 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 2119 WMI_REQUEST_STATS_CMDID); 2120 2121 if (ret) { 2122 WMI_LOGE("Failed to send status request to fw =%d", ret); 2123 wmi_buf_free(buf); 2124 } 2125 2126 return ret; 2127 } 2128 2129 /** 2130 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2131 * @wmi_handle: handle to WMI. 2132 * @macaddr: Peer mac address to be filter 2133 * @mac_id: mac id to have radio context 2134 * @enb_dsb: Enable MAC based filtering or Disable 2135 * 2136 * Return: QDF_STATUS 2137 */ 2138 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2139 uint8_t *macaddr, 2140 uint8_t mac_id, 2141 uint8_t enb_dsb) 2142 { 2143 int32_t ret; 2144 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2145 wmi_pdev_pktlog_filter_info *mac_info; 2146 wmi_buf_t buf; 2147 uint8_t *buf_ptr; 2148 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2149 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2150 2151 buf = wmi_buf_alloc(wmi_handle, len); 2152 if (!buf) 2153 return QDF_STATUS_E_NOMEM; 2154 2155 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2156 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2157 WMITLV_SET_HDR(&cmd->tlv_header, 2158 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2159 WMITLV_GET_STRUCT_TLVLEN 2160 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2161 cmd->pdev_id = mac_id; 2162 cmd->enable = enb_dsb; 2163 cmd->num_of_mac_addresses = 1; 2164 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2165 2166 buf_ptr += sizeof(*cmd); 2167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2168 sizeof(wmi_pdev_pktlog_filter_info)); 2169 buf_ptr += WMI_TLV_HDR_SIZE; 2170 2171 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2172 2173 WMITLV_SET_HDR(&mac_info->tlv_header, 2174 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2175 WMITLV_GET_STRUCT_TLVLEN 2176 (wmi_pdev_pktlog_filter_info)); 2177 2178 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2179 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2180 WMI_PDEV_PKTLOG_FILTER_CMDID); 2181 if (ret) { 2182 WMI_LOGE("Failed to send peer based pktlog command to FW =%d" 2183 , ret); 2184 wmi_buf_free(buf); 2185 } 2186 2187 return ret; 2188 } 2189 2190 /** 2191 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2192 * @param wmi_handle : handle to WMI. 2193 * @param PKTLOG_EVENT : packet log event 2194 * @mac_id: mac id to have radio context 2195 * 2196 * Return: 0 on success and -ve on failure. 2197 */ 2198 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2199 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2200 { 2201 int32_t ret; 2202 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2203 wmi_buf_t buf; 2204 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2205 2206 buf = wmi_buf_alloc(wmi_handle, len); 2207 if (!buf) 2208 return -QDF_STATUS_E_NOMEM; 2209 2210 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2211 WMITLV_SET_HDR(&cmd->tlv_header, 2212 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2213 WMITLV_GET_STRUCT_TLVLEN 2214 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2215 cmd->evlist = PKTLOG_EVENT; 2216 cmd->pdev_id = mac_id; 2217 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2218 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2219 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2220 if (ret) { 2221 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 2222 wmi_buf_free(buf); 2223 } 2224 2225 return ret; 2226 } 2227 2228 /** 2229 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2230 * @param wmi_handle : handle to WMI. 2231 * @mac_id: mac id to have radio context 2232 * 2233 * Return: 0 on success and -ve on failure. 2234 */ 2235 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2236 uint8_t mac_id) 2237 { 2238 int32_t ret; 2239 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2240 wmi_buf_t buf; 2241 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2242 2243 buf = wmi_buf_alloc(wmi_handle, len); 2244 if (!buf) 2245 return -QDF_STATUS_E_NOMEM; 2246 2247 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2248 WMITLV_SET_HDR(&cmd->tlv_header, 2249 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2250 WMITLV_GET_STRUCT_TLVLEN 2251 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2252 cmd->pdev_id = mac_id; 2253 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2254 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2255 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2256 if (ret) { 2257 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 2258 wmi_buf_free(buf); 2259 } 2260 2261 return ret; 2262 } 2263 2264 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2265 /** 2266 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2267 * sync time between bwtween host and firmware 2268 * @param wmi_handle : handle to WMI. 2269 * 2270 * Return: None 2271 */ 2272 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2273 { 2274 wmi_buf_t buf; 2275 QDF_STATUS status = QDF_STATUS_SUCCESS; 2276 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2277 int32_t len; 2278 qdf_time_t time_ms; 2279 2280 len = sizeof(*time_stamp); 2281 buf = wmi_buf_alloc(wmi_handle, len); 2282 2283 if (!buf) 2284 return; 2285 2286 time_stamp = 2287 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2288 (wmi_buf_data(buf)); 2289 WMITLV_SET_HDR(&time_stamp->tlv_header, 2290 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2291 WMITLV_GET_STRUCT_TLVLEN( 2292 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2293 2294 time_ms = qdf_get_time_of_the_day_ms(); 2295 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2296 time_stamp->time_stamp_low = time_ms & 2297 WMI_FW_TIME_STAMP_LOW_MASK; 2298 /* 2299 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2300 * wont exceed 27 bit 2301 */ 2302 time_stamp->time_stamp_high = 0; 2303 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 2304 time_stamp->mode, time_stamp->time_stamp_low, 2305 time_stamp->time_stamp_high); 2306 2307 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2308 status = wmi_unified_cmd_send(wmi_handle, buf, 2309 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2310 if (status) { 2311 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2312 wmi_buf_free(buf); 2313 } 2314 2315 } 2316 2317 /** 2318 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2319 * @param wmi_handle : handle to WMI. 2320 * @param param : pointer to hold FILS Discovery send cmd parameter 2321 * 2322 * Return: 0 on success and -ve on failure. 2323 */ 2324 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2325 struct fils_discovery_tmpl_params *param) 2326 { 2327 int32_t ret; 2328 wmi_fd_tmpl_cmd_fixed_param *cmd; 2329 wmi_buf_t wmi_buf; 2330 uint8_t *buf_ptr; 2331 uint32_t wmi_buf_len; 2332 2333 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2334 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2335 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2336 if (!wmi_buf) 2337 return QDF_STATUS_E_NOMEM; 2338 2339 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2340 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2341 WMITLV_SET_HDR(&cmd->tlv_header, 2342 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2343 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2344 cmd->vdev_id = param->vdev_id; 2345 cmd->buf_len = param->tmpl_len; 2346 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2347 2348 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2349 buf_ptr += WMI_TLV_HDR_SIZE; 2350 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2351 2352 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2353 ret = wmi_unified_cmd_send(wmi_handle, 2354 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2355 2356 if (ret) { 2357 WMI_LOGE("%s: Failed to send fd tmpl: %d", __func__, ret); 2358 wmi_buf_free(wmi_buf); 2359 return ret; 2360 } 2361 2362 return 0; 2363 } 2364 2365 /** 2366 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2367 * @param wmi_handle : handle to WMI. 2368 * @param param : pointer to hold beacon send cmd parameter 2369 * 2370 * Return: 0 on success and -ve on failure. 2371 */ 2372 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2373 struct beacon_tmpl_params *param) 2374 { 2375 int32_t ret; 2376 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2377 wmi_bcn_prb_info *bcn_prb_info; 2378 wmi_buf_t wmi_buf; 2379 uint8_t *buf_ptr; 2380 uint32_t wmi_buf_len; 2381 2382 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2383 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2384 param->tmpl_len_aligned; 2385 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2386 if (!wmi_buf) 2387 return QDF_STATUS_E_NOMEM; 2388 2389 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2390 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2391 WMITLV_SET_HDR(&cmd->tlv_header, 2392 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2393 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2394 cmd->vdev_id = param->vdev_id; 2395 cmd->tim_ie_offset = param->tim_ie_offset; 2396 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2397 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2398 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2399 cmd->esp_ie_offset = param->esp_ie_offset; 2400 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2401 cmd->buf_len = param->tmpl_len; 2402 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2403 2404 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2405 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2406 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2407 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2408 bcn_prb_info->caps = 0; 2409 bcn_prb_info->erp = 0; 2410 buf_ptr += sizeof(wmi_bcn_prb_info); 2411 2412 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2413 buf_ptr += WMI_TLV_HDR_SIZE; 2414 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2415 2416 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2417 ret = wmi_unified_cmd_send(wmi_handle, 2418 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2419 if (ret) { 2420 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2421 wmi_buf_free(wmi_buf); 2422 } 2423 2424 return 0; 2425 } 2426 2427 static inline void copy_peer_flags_tlv( 2428 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2429 struct peer_assoc_params *param) 2430 { 2431 /* 2432 * The target only needs a subset of the flags maintained in the host. 2433 * Just populate those flags and send it down 2434 */ 2435 cmd->peer_flags = 0; 2436 2437 /* 2438 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2439 */ 2440 if (param->is_wme_set) { 2441 2442 if (param->qos_flag) 2443 cmd->peer_flags |= WMI_PEER_QOS; 2444 if (param->apsd_flag) 2445 cmd->peer_flags |= WMI_PEER_APSD; 2446 if (param->ht_flag) 2447 cmd->peer_flags |= WMI_PEER_HT; 2448 if (param->bw_40) 2449 cmd->peer_flags |= WMI_PEER_40MHZ; 2450 if (param->bw_80) 2451 cmd->peer_flags |= WMI_PEER_80MHZ; 2452 if (param->bw_160) 2453 cmd->peer_flags |= WMI_PEER_160MHZ; 2454 2455 /* Typically if STBC is enabled for VHT it should be enabled 2456 * for HT as well 2457 **/ 2458 if (param->stbc_flag) 2459 cmd->peer_flags |= WMI_PEER_STBC; 2460 2461 /* Typically if LDPC is enabled for VHT it should be enabled 2462 * for HT as well 2463 **/ 2464 if (param->ldpc_flag) 2465 cmd->peer_flags |= WMI_PEER_LDPC; 2466 2467 if (param->static_mimops_flag) 2468 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2469 if (param->dynamic_mimops_flag) 2470 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2471 if (param->spatial_mux_flag) 2472 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2473 if (param->vht_flag) 2474 cmd->peer_flags |= WMI_PEER_VHT; 2475 if (param->he_flag) 2476 cmd->peer_flags |= WMI_PEER_HE; 2477 if (param->p2p_capable_sta) 2478 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2479 } 2480 2481 if (param->is_pmf_enabled) 2482 cmd->peer_flags |= WMI_PEER_PMF; 2483 /* 2484 * Suppress authorization for all AUTH modes that need 4-way handshake 2485 * (during re-association). 2486 * Authorization will be done for these modes on key installation. 2487 */ 2488 if (param->auth_flag) 2489 cmd->peer_flags |= WMI_PEER_AUTH; 2490 if (param->need_ptk_4_way) 2491 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2492 else 2493 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2494 if (param->need_gtk_2_way) 2495 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2496 /* safe mode bypass the 4-way handshake */ 2497 if (param->safe_mode_enabled) 2498 cmd->peer_flags &= 2499 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2500 /* inter BSS peer */ 2501 if (param->inter_bss_peer) 2502 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2503 /* Disable AMSDU for station transmit, if user configures it */ 2504 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2505 * it 2506 * if (param->amsdu_disable) Add after FW support 2507 **/ 2508 2509 /* Target asserts if node is marked HT and all MCS is set to 0. 2510 * Mark the node as non-HT if all the mcs rates are disabled through 2511 * iwpriv 2512 **/ 2513 if (param->peer_ht_rates.num_rates == 0) 2514 cmd->peer_flags &= ~WMI_PEER_HT; 2515 2516 if (param->twt_requester) 2517 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2518 2519 if (param->twt_responder) 2520 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2521 } 2522 2523 static inline void copy_peer_mac_addr_tlv( 2524 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2525 struct peer_assoc_params *param) 2526 { 2527 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2528 } 2529 2530 /** 2531 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2532 * @param wmi_handle : handle to WMI. 2533 * @param param : pointer to peer assoc parameter 2534 * 2535 * Return: 0 on success and -ve on failure. 2536 */ 2537 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2538 struct peer_assoc_params *param) 2539 { 2540 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2541 wmi_vht_rate_set *mcs; 2542 wmi_he_rate_set *he_mcs; 2543 wmi_buf_t buf; 2544 int32_t len; 2545 uint8_t *buf_ptr; 2546 QDF_STATUS ret; 2547 uint32_t peer_legacy_rates_align; 2548 uint32_t peer_ht_rates_align; 2549 int32_t i; 2550 2551 2552 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2553 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2554 2555 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2556 (peer_legacy_rates_align * sizeof(uint8_t)) + 2557 WMI_TLV_HDR_SIZE + 2558 (peer_ht_rates_align * sizeof(uint8_t)) + 2559 sizeof(wmi_vht_rate_set) + 2560 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2561 + WMI_TLV_HDR_SIZE); 2562 2563 buf = wmi_buf_alloc(wmi_handle, len); 2564 if (!buf) 2565 return QDF_STATUS_E_NOMEM; 2566 2567 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2568 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2569 WMITLV_SET_HDR(&cmd->tlv_header, 2570 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2571 WMITLV_GET_STRUCT_TLVLEN 2572 (wmi_peer_assoc_complete_cmd_fixed_param)); 2573 2574 cmd->vdev_id = param->vdev_id; 2575 2576 cmd->peer_new_assoc = param->peer_new_assoc; 2577 cmd->peer_associd = param->peer_associd; 2578 2579 copy_peer_flags_tlv(cmd, param); 2580 copy_peer_mac_addr_tlv(cmd, param); 2581 2582 cmd->peer_rate_caps = param->peer_rate_caps; 2583 cmd->peer_caps = param->peer_caps; 2584 cmd->peer_listen_intval = param->peer_listen_intval; 2585 cmd->peer_ht_caps = param->peer_ht_caps; 2586 cmd->peer_max_mpdu = param->peer_max_mpdu; 2587 cmd->peer_mpdu_density = param->peer_mpdu_density; 2588 cmd->peer_vht_caps = param->peer_vht_caps; 2589 cmd->peer_phymode = param->peer_phymode; 2590 2591 /* Update 11ax capabilities */ 2592 cmd->peer_he_cap_info = 2593 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2594 cmd->peer_he_cap_info_ext = 2595 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2596 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 2597 cmd->peer_he_ops = param->peer_he_ops; 2598 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2599 sizeof(param->peer_he_cap_phyinfo)); 2600 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2601 sizeof(param->peer_ppet)); 2602 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 2603 2604 /* Update peer legacy rate information */ 2605 buf_ptr += sizeof(*cmd); 2606 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2607 peer_legacy_rates_align); 2608 buf_ptr += WMI_TLV_HDR_SIZE; 2609 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2610 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2611 param->peer_legacy_rates.num_rates); 2612 2613 /* Update peer HT rate information */ 2614 buf_ptr += peer_legacy_rates_align; 2615 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2616 peer_ht_rates_align); 2617 buf_ptr += WMI_TLV_HDR_SIZE; 2618 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2619 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2620 param->peer_ht_rates.num_rates); 2621 2622 /* VHT Rates */ 2623 buf_ptr += peer_ht_rates_align; 2624 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2625 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2626 2627 cmd->peer_nss = param->peer_nss; 2628 2629 /* Update bandwidth-NSS mapping */ 2630 cmd->peer_bw_rxnss_override = 0; 2631 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2632 2633 mcs = (wmi_vht_rate_set *) buf_ptr; 2634 if (param->vht_capable) { 2635 mcs->rx_max_rate = param->rx_max_rate; 2636 mcs->rx_mcs_set = param->rx_mcs_set; 2637 mcs->tx_max_rate = param->tx_max_rate; 2638 mcs->tx_mcs_set = param->tx_mcs_set; 2639 } 2640 2641 /* HE Rates */ 2642 cmd->min_data_rate = param->min_data_rate; 2643 cmd->peer_he_mcs = param->peer_he_mcs_count; 2644 buf_ptr += sizeof(wmi_vht_rate_set); 2645 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2646 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2647 buf_ptr += WMI_TLV_HDR_SIZE; 2648 2649 /* Loop through the HE rate set */ 2650 for (i = 0; i < param->peer_he_mcs_count; i++) { 2651 he_mcs = (wmi_he_rate_set *) buf_ptr; 2652 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2653 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2654 2655 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2656 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2657 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2658 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2659 buf_ptr += sizeof(wmi_he_rate_set); 2660 } 2661 2662 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 2663 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2664 == WMI_HOST_HE_INVALID_MCSNSSMAP || 2665 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2666 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2667 WMI_LOGD("param->peer_he_tx_mcs_set[160MHz]=%x", 2668 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2669 WMI_LOGD("param->peer_he_rx_mcs_set[160MHz]=%x", 2670 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2671 WMI_LOGD("peer_mac=%02x:%02x:%02x:%02x:%02x:%02x", 2672 param->peer_mac[0], param->peer_mac[1], 2673 param->peer_mac[2], param->peer_mac[3], 2674 param->peer_mac[4], param->peer_mac[5]); 2675 } 2676 2677 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2678 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2679 "nss %d phymode %d peer_mpdu_density %d " 2680 "cmd->peer_vht_caps %x " 2681 "HE cap_info %x ops %x " 2682 "HE cap_info_ext %x " 2683 "HE phy %x %x %x " 2684 "peer_bw_rxnss_override %x", __func__, 2685 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2686 cmd->peer_rate_caps, cmd->peer_caps, 2687 cmd->peer_listen_intval, cmd->peer_ht_caps, 2688 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2689 cmd->peer_mpdu_density, 2690 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2691 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2692 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2693 cmd->peer_he_cap_phy[2], 2694 cmd->peer_bw_rxnss_override); 2695 2696 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2697 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2698 WMI_PEER_ASSOC_CMDID); 2699 if (QDF_IS_STATUS_ERROR(ret)) { 2700 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2701 __func__, ret); 2702 wmi_buf_free(buf); 2703 } 2704 2705 return ret; 2706 } 2707 2708 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2709 */ 2710 static inline void copy_scan_event_cntrl_flags( 2711 wmi_start_scan_cmd_fixed_param * cmd, 2712 struct scan_req_params *param) 2713 { 2714 2715 /* Scan events subscription */ 2716 if (param->scan_ev_started) 2717 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2718 if (param->scan_ev_completed) 2719 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2720 if (param->scan_ev_bss_chan) 2721 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2722 if (param->scan_ev_foreign_chan) 2723 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2724 if (param->scan_ev_dequeued) 2725 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2726 if (param->scan_ev_preempted) 2727 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2728 if (param->scan_ev_start_failed) 2729 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2730 if (param->scan_ev_restarted) 2731 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2732 if (param->scan_ev_foreign_chn_exit) 2733 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2734 if (param->scan_ev_suspended) 2735 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2736 if (param->scan_ev_resumed) 2737 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2738 2739 /** Set scan control flags */ 2740 cmd->scan_ctrl_flags = 0; 2741 if (param->scan_f_passive) 2742 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2743 if (param->scan_f_strict_passive_pch) 2744 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2745 if (param->scan_f_promisc_mode) 2746 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2747 if (param->scan_f_capture_phy_err) 2748 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2749 if (param->scan_f_half_rate) 2750 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2751 if (param->scan_f_quarter_rate) 2752 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2753 if (param->scan_f_cck_rates) 2754 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2755 if (param->scan_f_ofdm_rates) 2756 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2757 if (param->scan_f_chan_stat_evnt) 2758 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2759 if (param->scan_f_filter_prb_req) 2760 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2761 if (param->scan_f_bcast_probe) 2762 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2763 if (param->scan_f_offchan_mgmt_tx) 2764 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2765 if (param->scan_f_offchan_data_tx) 2766 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2767 if (param->scan_f_force_active_dfs_chn) 2768 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2769 if (param->scan_f_add_tpc_ie_in_probe) 2770 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2771 if (param->scan_f_add_ds_ie_in_probe) 2772 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2773 if (param->scan_f_add_spoofed_mac_in_probe) 2774 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2775 if (param->scan_f_add_rand_seq_in_probe) 2776 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2777 if (param->scan_f_en_ie_whitelist_in_probe) 2778 cmd->scan_ctrl_flags |= 2779 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2780 2781 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2782 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2783 param->adaptive_dwell_time_mode); 2784 } 2785 2786 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2787 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2788 struct scan_req_params *params) 2789 { 2790 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2791 } 2792 2793 /** 2794 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2795 * @mac: random mac addr 2796 * @mask: random mac mask 2797 * @mac_addr: wmi random mac 2798 * @mac_mask: wmi random mac mask 2799 * 2800 * Return None. 2801 */ 2802 static inline 2803 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2804 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2805 { 2806 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2807 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2808 } 2809 2810 /* 2811 * wmi_fill_vendor_oui() - fill vendor OUIs 2812 * @buf_ptr: pointer to wmi tlv buffer 2813 * @num_vendor_oui: number of vendor OUIs to be filled 2814 * @param_voui: pointer to OUI buffer 2815 * 2816 * This function populates the wmi tlv buffer when vendor specific OUIs are 2817 * present. 2818 * 2819 * Return: None 2820 */ 2821 static inline 2822 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2823 uint32_t *pvoui) 2824 { 2825 wmi_vendor_oui *voui = NULL; 2826 uint32_t i; 2827 2828 voui = (wmi_vendor_oui *)buf_ptr; 2829 2830 for (i = 0; i < num_vendor_oui; i++) { 2831 WMITLV_SET_HDR(&voui[i].tlv_header, 2832 WMITLV_TAG_STRUC_wmi_vendor_oui, 2833 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2834 voui[i].oui_type_subtype = pvoui[i]; 2835 } 2836 } 2837 2838 /* 2839 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2840 * @ie_bitmap: output pointer to ie bit map in cmd 2841 * @num_vendor_oui: output pointer to num vendor OUIs 2842 * @ie_whitelist: input parameter 2843 * 2844 * This function populates the IE whitelist attrs of scan, pno and 2845 * scan oui commands for ie_whitelist parameter. 2846 * 2847 * Return: None 2848 */ 2849 static inline 2850 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2851 uint32_t *num_vendor_oui, 2852 struct probe_req_whitelist_attr *ie_whitelist) 2853 { 2854 uint32_t i = 0; 2855 2856 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2857 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2858 2859 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2860 } 2861 2862 /** 2863 * send_scan_start_cmd_tlv() - WMI scan start function 2864 * @param wmi_handle : handle to WMI. 2865 * @param param : pointer to hold scan start cmd parameter 2866 * 2867 * Return: 0 on success and -ve on failure. 2868 */ 2869 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2870 struct scan_req_params *params) 2871 { 2872 int32_t ret = 0; 2873 int32_t i; 2874 wmi_buf_t wmi_buf; 2875 wmi_start_scan_cmd_fixed_param *cmd; 2876 uint8_t *buf_ptr; 2877 uint32_t *tmp_ptr; 2878 wmi_ssid *ssid = NULL; 2879 wmi_mac_addr *bssid; 2880 size_t len = sizeof(*cmd); 2881 uint16_t extraie_len_with_pad = 0; 2882 uint8_t phymode_roundup = 0; 2883 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2884 wmi_hint_freq_short_ssid *s_ssid = NULL; 2885 wmi_hint_freq_bssid *hint_bssid = NULL; 2886 2887 /* Length TLV placeholder for array of uint32_t */ 2888 len += WMI_TLV_HDR_SIZE; 2889 /* calculate the length of buffer required */ 2890 if (params->chan_list.num_chan) 2891 len += params->chan_list.num_chan * sizeof(uint32_t); 2892 2893 /* Length TLV placeholder for array of wmi_ssid structures */ 2894 len += WMI_TLV_HDR_SIZE; 2895 if (params->num_ssids) 2896 len += params->num_ssids * sizeof(wmi_ssid); 2897 2898 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2899 len += WMI_TLV_HDR_SIZE; 2900 if (params->num_bssid) 2901 len += sizeof(wmi_mac_addr) * params->num_bssid; 2902 2903 /* Length TLV placeholder for array of bytes */ 2904 len += WMI_TLV_HDR_SIZE; 2905 if (params->extraie.len) 2906 extraie_len_with_pad = 2907 roundup(params->extraie.len, sizeof(uint32_t)); 2908 len += extraie_len_with_pad; 2909 2910 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2911 if (ie_whitelist->num_vendor_oui) 2912 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2913 2914 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2915 if (params->scan_f_wide_band) 2916 phymode_roundup = 2917 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2918 sizeof(uint32_t)); 2919 len += phymode_roundup; 2920 2921 len += WMI_TLV_HDR_SIZE; 2922 if (params->num_hint_bssid) 2923 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 2924 2925 len += WMI_TLV_HDR_SIZE; 2926 if (params->num_hint_s_ssid) 2927 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 2928 2929 /* Allocate the memory */ 2930 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2931 if (!wmi_buf) 2932 return QDF_STATUS_E_FAILURE; 2933 2934 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2935 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2936 WMITLV_SET_HDR(&cmd->tlv_header, 2937 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2938 WMITLV_GET_STRUCT_TLVLEN 2939 (wmi_start_scan_cmd_fixed_param)); 2940 2941 cmd->scan_id = params->scan_id; 2942 cmd->scan_req_id = params->scan_req_id; 2943 cmd->vdev_id = params->vdev_id; 2944 cmd->scan_priority = params->scan_priority; 2945 2946 copy_scan_event_cntrl_flags(cmd, params); 2947 2948 cmd->dwell_time_active = params->dwell_time_active; 2949 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2950 cmd->dwell_time_passive = params->dwell_time_passive; 2951 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 2952 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 2953 cmd->scan_start_offset = params->scan_offset_time; 2954 cmd->min_rest_time = params->min_rest_time; 2955 cmd->max_rest_time = params->max_rest_time; 2956 cmd->repeat_probe_time = params->repeat_probe_time; 2957 cmd->probe_spacing_time = params->probe_spacing_time; 2958 cmd->idle_time = params->idle_time; 2959 cmd->max_scan_time = params->max_scan_time; 2960 cmd->probe_delay = params->probe_delay; 2961 cmd->burst_duration = params->burst_duration; 2962 cmd->num_chan = params->chan_list.num_chan; 2963 cmd->num_bssid = params->num_bssid; 2964 cmd->num_ssids = params->num_ssids; 2965 cmd->ie_len = params->extraie.len; 2966 cmd->n_probes = params->n_probes; 2967 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 2968 2969 if (params->scan_random.randomize) 2970 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 2971 params->scan_random.mac_mask, 2972 &cmd->mac_addr, 2973 &cmd->mac_mask); 2974 2975 if (ie_whitelist->white_list) 2976 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 2977 &cmd->num_vendor_oui, 2978 ie_whitelist); 2979 2980 buf_ptr += sizeof(*cmd); 2981 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 2982 for (i = 0; i < params->chan_list.num_chan; ++i) 2983 tmp_ptr[i] = params->chan_list.chan[i].freq; 2984 2985 WMITLV_SET_HDR(buf_ptr, 2986 WMITLV_TAG_ARRAY_UINT32, 2987 (params->chan_list.num_chan * sizeof(uint32_t))); 2988 buf_ptr += WMI_TLV_HDR_SIZE + 2989 (params->chan_list.num_chan * sizeof(uint32_t)); 2990 2991 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 2992 WMI_LOGE("Invalid value for num_ssids %d", params->num_ssids); 2993 goto error; 2994 } 2995 2996 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 2997 (params->num_ssids * sizeof(wmi_ssid))); 2998 2999 if (params->num_ssids) { 3000 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3001 for (i = 0; i < params->num_ssids; ++i) { 3002 ssid->ssid_len = params->ssid[i].length; 3003 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3004 params->ssid[i].length); 3005 ssid++; 3006 } 3007 } 3008 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3009 3010 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3011 (params->num_bssid * sizeof(wmi_mac_addr))); 3012 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3013 3014 if (params->num_bssid) { 3015 for (i = 0; i < params->num_bssid; ++i) { 3016 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3017 ¶ms->bssid_list[i].bytes[0], bssid); 3018 bssid++; 3019 } 3020 } 3021 3022 buf_ptr += WMI_TLV_HDR_SIZE + 3023 (params->num_bssid * sizeof(wmi_mac_addr)); 3024 3025 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3026 if (params->extraie.len) 3027 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3028 params); 3029 3030 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3031 3032 /* probe req ie whitelisting */ 3033 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3034 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3035 3036 buf_ptr += WMI_TLV_HDR_SIZE; 3037 3038 if (cmd->num_vendor_oui) { 3039 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3040 ie_whitelist->voui); 3041 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3042 } 3043 3044 /* Add phy mode TLV if it's a wide band scan */ 3045 if (params->scan_f_wide_band) { 3046 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3047 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3048 for (i = 0; i < params->chan_list.num_chan; ++i) 3049 buf_ptr[i] = 3050 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3051 buf_ptr += phymode_roundup; 3052 } else { 3053 /* Add ZERO legth phy mode TLV */ 3054 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3055 buf_ptr += WMI_TLV_HDR_SIZE; 3056 } 3057 3058 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3059 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3060 if (params->num_hint_s_ssid) { 3061 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3062 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3063 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3064 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3065 s_ssid++; 3066 } 3067 } 3068 buf_ptr += WMI_TLV_HDR_SIZE + 3069 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3070 3071 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3072 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3073 if (params->num_hint_bssid) { 3074 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3075 for (i = 0; i < params->num_hint_bssid; ++i) { 3076 hint_bssid->freq_flags = 3077 params->hint_bssid[i].freq_flags; 3078 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3079 &hint_bssid->bssid); 3080 hint_bssid++; 3081 } 3082 } 3083 3084 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3085 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3086 len, WMI_START_SCAN_CMDID); 3087 if (ret) { 3088 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 3089 wmi_buf_free(wmi_buf); 3090 } 3091 return ret; 3092 error: 3093 wmi_buf_free(wmi_buf); 3094 return QDF_STATUS_E_FAILURE; 3095 } 3096 3097 /** 3098 * send_scan_stop_cmd_tlv() - WMI scan start function 3099 * @param wmi_handle : handle to WMI. 3100 * @param param : pointer to hold scan cancel cmd parameter 3101 * 3102 * Return: 0 on success and -ve on failure. 3103 */ 3104 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3105 struct scan_cancel_param *param) 3106 { 3107 wmi_stop_scan_cmd_fixed_param *cmd; 3108 int ret; 3109 int len = sizeof(*cmd); 3110 wmi_buf_t wmi_buf; 3111 3112 /* Allocate the memory */ 3113 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3114 if (!wmi_buf) { 3115 ret = QDF_STATUS_E_NOMEM; 3116 goto error; 3117 } 3118 3119 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3120 WMITLV_SET_HDR(&cmd->tlv_header, 3121 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3122 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3123 cmd->vdev_id = param->vdev_id; 3124 cmd->requestor = param->requester; 3125 cmd->scan_id = param->scan_id; 3126 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3127 wmi_handle, 3128 param->pdev_id); 3129 /* stop the scan with the corresponding scan_id */ 3130 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3131 /* Cancelling all scans */ 3132 cmd->req_type = WMI_SCAN_STOP_ALL; 3133 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3134 /* Cancelling VAP scans */ 3135 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3136 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3137 /* Cancelling specific scan */ 3138 cmd->req_type = WMI_SCAN_STOP_ONE; 3139 } else { 3140 WMI_LOGE("%s: Invalid Command : ", __func__); 3141 wmi_buf_free(wmi_buf); 3142 return QDF_STATUS_E_INVAL; 3143 } 3144 3145 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3146 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3147 len, WMI_STOP_SCAN_CMDID); 3148 if (ret) { 3149 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 3150 wmi_buf_free(wmi_buf); 3151 } 3152 3153 error: 3154 return ret; 3155 } 3156 3157 #define WMI_MAX_CHAN_INFO_LOG 192 3158 3159 /** 3160 * wmi_scan_chanlist_dump() - Dump scan channel list info 3161 * @scan_chan_list: scan channel list 3162 * 3163 * Return: void 3164 */ 3165 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3166 { 3167 uint32_t i; 3168 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3169 int len = 0; 3170 struct channel_param *chan; 3171 int ret; 3172 3173 WMI_LOGD(FL("start (freq MHz, tx power dBm):")); 3174 for (i = 0; i < scan_chan_list->nallchans; i++) { 3175 chan = &scan_chan_list->ch_param[i]; 3176 ret = scnprintf(info + len, sizeof(info) - len, "%d %d ", 3177 chan->mhz, chan->maxregpower); 3178 if (ret <= 0) 3179 break; 3180 len += ret; 3181 if (len >= (sizeof(info) - 20)) { 3182 WMI_LOGD(FL("%s"), info); 3183 len = 0; 3184 } 3185 } 3186 if (len > 0) 3187 WMI_LOGD(FL("%s"), info); 3188 WMI_LOGD(FL("end total_count %d"), scan_chan_list->nallchans); 3189 } 3190 3191 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3192 struct scan_chan_list_params *chan_list) 3193 { 3194 wmi_buf_t buf; 3195 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3196 wmi_scan_chan_list_cmd_fixed_param *cmd; 3197 int i; 3198 uint8_t *buf_ptr; 3199 wmi_channel *chan_info; 3200 struct channel_param *tchan_info; 3201 uint16_t len; 3202 uint16_t num_send_chans, num_sends = 0; 3203 3204 wmi_scan_chanlist_dump(chan_list); 3205 tchan_info = &chan_list->ch_param[0]; 3206 while (chan_list->nallchans) { 3207 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3208 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3209 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3210 else 3211 num_send_chans = chan_list->nallchans; 3212 3213 chan_list->nallchans -= num_send_chans; 3214 len += sizeof(wmi_channel) * num_send_chans; 3215 buf = wmi_buf_alloc(wmi_handle, len); 3216 if (!buf) { 3217 qdf_status = QDF_STATUS_E_NOMEM; 3218 goto end; 3219 } 3220 3221 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3222 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3223 WMITLV_SET_HDR(&cmd->tlv_header, 3224 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3225 WMITLV_GET_STRUCT_TLVLEN 3226 (wmi_scan_chan_list_cmd_fixed_param)); 3227 3228 WMI_LOGD("no of channels = %d, len = %d", num_send_chans, len); 3229 3230 if (num_sends) 3231 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3232 3233 if (chan_list->max_bw_support_present) 3234 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3235 3236 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3237 wmi_handle, 3238 chan_list->pdev_id); 3239 3240 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3241 3242 cmd->num_scan_chans = num_send_chans; 3243 WMITLV_SET_HDR((buf_ptr + 3244 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3245 WMITLV_TAG_ARRAY_STRUC, 3246 sizeof(wmi_channel) * num_send_chans); 3247 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3248 WMI_TLV_HDR_SIZE); 3249 3250 for (i = 0; i < num_send_chans; ++i) { 3251 WMITLV_SET_HDR(&chan_info->tlv_header, 3252 WMITLV_TAG_STRUC_wmi_channel, 3253 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3254 chan_info->mhz = tchan_info->mhz; 3255 chan_info->band_center_freq1 = 3256 tchan_info->cfreq1; 3257 chan_info->band_center_freq2 = 3258 tchan_info->cfreq2; 3259 3260 if (tchan_info->is_chan_passive) 3261 WMI_SET_CHANNEL_FLAG(chan_info, 3262 WMI_CHAN_FLAG_PASSIVE); 3263 if (tchan_info->dfs_set) 3264 WMI_SET_CHANNEL_FLAG(chan_info, 3265 WMI_CHAN_FLAG_DFS); 3266 3267 if (tchan_info->dfs_set_cfreq2) 3268 WMI_SET_CHANNEL_FLAG(chan_info, 3269 WMI_CHAN_FLAG_DFS_CFREQ2); 3270 3271 if (tchan_info->allow_he) 3272 WMI_SET_CHANNEL_FLAG(chan_info, 3273 WMI_CHAN_FLAG_ALLOW_HE); 3274 3275 if (tchan_info->allow_vht) 3276 WMI_SET_CHANNEL_FLAG(chan_info, 3277 WMI_CHAN_FLAG_ALLOW_VHT); 3278 3279 if (tchan_info->allow_ht) 3280 WMI_SET_CHANNEL_FLAG(chan_info, 3281 WMI_CHAN_FLAG_ALLOW_HT); 3282 WMI_SET_CHANNEL_MODE(chan_info, 3283 tchan_info->phy_mode); 3284 3285 if (tchan_info->half_rate) 3286 WMI_SET_CHANNEL_FLAG(chan_info, 3287 WMI_CHAN_FLAG_HALF_RATE); 3288 3289 if (tchan_info->quarter_rate) 3290 WMI_SET_CHANNEL_FLAG(chan_info, 3291 WMI_CHAN_FLAG_QUARTER_RATE); 3292 3293 if (tchan_info->psc_channel) 3294 WMI_SET_CHANNEL_FLAG(chan_info, 3295 WMI_CHAN_FLAG_PSC); 3296 3297 /* also fill in power information */ 3298 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3299 tchan_info->minpower); 3300 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3301 tchan_info->maxpower); 3302 WMI_SET_CHANNEL_REG_POWER(chan_info, 3303 tchan_info->maxregpower); 3304 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3305 tchan_info->antennamax); 3306 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3307 tchan_info->reg_class_id); 3308 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3309 tchan_info->maxregpower); 3310 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3311 tchan_info->max_bw_supported); 3312 3313 tchan_info++; 3314 chan_info++; 3315 } 3316 3317 qdf_status = wmi_unified_cmd_send( 3318 wmi_handle, 3319 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3320 3321 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3322 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3323 wmi_buf_free(buf); 3324 goto end; 3325 } 3326 num_sends++; 3327 } 3328 3329 end: 3330 return qdf_status; 3331 } 3332 3333 /** 3334 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3335 * 3336 * @bufp: Pointer to buffer 3337 * @param: Pointer to tx param 3338 * 3339 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3340 */ 3341 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3342 struct tx_send_params param) 3343 { 3344 wmi_tx_send_params *tx_param; 3345 QDF_STATUS status = QDF_STATUS_SUCCESS; 3346 3347 if (!bufp) { 3348 status = QDF_STATUS_E_FAILURE; 3349 return status; 3350 } 3351 tx_param = (wmi_tx_send_params *)bufp; 3352 WMITLV_SET_HDR(&tx_param->tlv_header, 3353 WMITLV_TAG_STRUC_wmi_tx_send_params, 3354 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3355 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3356 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3357 param.mcs_mask); 3358 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3359 param.nss_mask); 3360 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3361 param.retry_limit); 3362 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3363 param.chain_mask); 3364 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3365 param.bw_mask); 3366 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3367 param.preamble_type); 3368 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3369 param.frame_type); 3370 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3371 param.cfr_enable); 3372 3373 return status; 3374 } 3375 3376 #ifdef CONFIG_HL_SUPPORT 3377 /** 3378 * send_mgmt_cmd_tlv() - WMI scan start function 3379 * @wmi_handle : handle to WMI. 3380 * @param : pointer to hold mgmt cmd parameter 3381 * 3382 * Return: 0 on success and -ve on failure. 3383 */ 3384 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3385 struct wmi_mgmt_params *param) 3386 { 3387 wmi_buf_t buf; 3388 uint8_t *bufp; 3389 int32_t cmd_len; 3390 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3391 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3392 mgmt_tx_dl_frm_len; 3393 3394 if (param->frm_len > mgmt_tx_dl_frm_len) { 3395 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 3396 __func__, param->frm_len, mgmt_tx_dl_frm_len); 3397 return QDF_STATUS_E_INVAL; 3398 } 3399 3400 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3401 WMI_TLV_HDR_SIZE + 3402 roundup(bufp_len, sizeof(uint32_t)); 3403 3404 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3405 if (!buf) 3406 return QDF_STATUS_E_NOMEM; 3407 3408 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3409 bufp = (uint8_t *) cmd; 3410 WMITLV_SET_HDR(&cmd->tlv_header, 3411 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3412 WMITLV_GET_STRUCT_TLVLEN 3413 (wmi_mgmt_tx_send_cmd_fixed_param)); 3414 3415 cmd->vdev_id = param->vdev_id; 3416 3417 cmd->desc_id = param->desc_id; 3418 cmd->chanfreq = param->chanfreq; 3419 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3420 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3421 sizeof(uint32_t))); 3422 bufp += WMI_TLV_HDR_SIZE; 3423 qdf_mem_copy(bufp, param->pdata, bufp_len); 3424 3425 cmd->frame_len = param->frm_len; 3426 cmd->buf_len = bufp_len; 3427 cmd->tx_params_valid = param->tx_params_valid; 3428 3429 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3430 bufp, cmd->vdev_id, cmd->chanfreq); 3431 3432 bufp += roundup(bufp_len, sizeof(uint32_t)); 3433 if (param->tx_params_valid) { 3434 if (populate_tx_send_params(bufp, param->tx_param) != 3435 QDF_STATUS_SUCCESS) { 3436 WMI_LOGE("%s: Populate TX send params failed", 3437 __func__); 3438 goto free_buf; 3439 } 3440 cmd_len += sizeof(wmi_tx_send_params); 3441 } 3442 3443 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3444 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3445 WMI_MGMT_TX_SEND_CMDID)) { 3446 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3447 goto free_buf; 3448 } 3449 return QDF_STATUS_SUCCESS; 3450 3451 free_buf: 3452 wmi_buf_free(buf); 3453 return QDF_STATUS_E_FAILURE; 3454 } 3455 #else 3456 /** 3457 * send_mgmt_cmd_tlv() - WMI scan start function 3458 * @wmi_handle : handle to WMI. 3459 * @param : pointer to hold mgmt cmd parameter 3460 * 3461 * Return: 0 on success and -ve on failure. 3462 */ 3463 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3464 struct wmi_mgmt_params *param) 3465 { 3466 wmi_buf_t buf; 3467 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3468 int32_t cmd_len; 3469 uint64_t dma_addr; 3470 void *qdf_ctx = param->qdf_ctx; 3471 uint8_t *bufp; 3472 QDF_STATUS status = QDF_STATUS_SUCCESS; 3473 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3474 mgmt_tx_dl_frm_len; 3475 3476 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3477 WMI_TLV_HDR_SIZE + 3478 roundup(bufp_len, sizeof(uint32_t)); 3479 3480 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3481 if (!buf) 3482 return QDF_STATUS_E_NOMEM; 3483 3484 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3485 bufp = (uint8_t *) cmd; 3486 WMITLV_SET_HDR(&cmd->tlv_header, 3487 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3488 WMITLV_GET_STRUCT_TLVLEN 3489 (wmi_mgmt_tx_send_cmd_fixed_param)); 3490 3491 cmd->vdev_id = param->vdev_id; 3492 3493 cmd->desc_id = param->desc_id; 3494 cmd->chanfreq = param->chanfreq; 3495 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3496 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3497 sizeof(uint32_t))); 3498 bufp += WMI_TLV_HDR_SIZE; 3499 qdf_mem_copy(bufp, param->pdata, bufp_len); 3500 3501 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3502 QDF_DMA_TO_DEVICE); 3503 if (status != QDF_STATUS_SUCCESS) { 3504 WMI_LOGE("%s: wmi buf map failed", __func__); 3505 goto free_buf; 3506 } 3507 3508 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3509 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3510 #if defined(HTT_PADDR64) 3511 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3512 #endif 3513 cmd->frame_len = param->frm_len; 3514 cmd->buf_len = bufp_len; 3515 cmd->tx_params_valid = param->tx_params_valid; 3516 3517 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3518 bufp, cmd->vdev_id, cmd->chanfreq); 3519 3520 bufp += roundup(bufp_len, sizeof(uint32_t)); 3521 if (param->tx_params_valid) { 3522 status = populate_tx_send_params(bufp, param->tx_param); 3523 if (status != QDF_STATUS_SUCCESS) { 3524 WMI_LOGE("%s: Populate TX send params failed", 3525 __func__); 3526 goto unmap_tx_frame; 3527 } 3528 cmd_len += sizeof(wmi_tx_send_params); 3529 } 3530 3531 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3532 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3533 WMI_MGMT_TX_SEND_CMDID)) { 3534 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3535 goto unmap_tx_frame; 3536 } 3537 return QDF_STATUS_SUCCESS; 3538 3539 unmap_tx_frame: 3540 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3541 QDF_DMA_TO_DEVICE); 3542 free_buf: 3543 wmi_buf_free(buf); 3544 return QDF_STATUS_E_FAILURE; 3545 } 3546 #endif /* CONFIG_HL_SUPPORT */ 3547 3548 /** 3549 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3550 * @wmi_handle : handle to WMI. 3551 * @param : pointer to offchan data tx cmd parameter 3552 * 3553 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3554 */ 3555 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3556 struct wmi_offchan_data_tx_params *param) 3557 { 3558 wmi_buf_t buf; 3559 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3560 int32_t cmd_len; 3561 uint64_t dma_addr; 3562 void *qdf_ctx = param->qdf_ctx; 3563 uint8_t *bufp; 3564 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3565 param->frm_len : mgmt_tx_dl_frm_len; 3566 QDF_STATUS status = QDF_STATUS_SUCCESS; 3567 3568 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3569 WMI_TLV_HDR_SIZE + 3570 roundup(bufp_len, sizeof(uint32_t)); 3571 3572 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3573 if (!buf) 3574 return QDF_STATUS_E_NOMEM; 3575 3576 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3577 bufp = (uint8_t *) cmd; 3578 WMITLV_SET_HDR(&cmd->tlv_header, 3579 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3580 WMITLV_GET_STRUCT_TLVLEN 3581 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3582 3583 cmd->vdev_id = param->vdev_id; 3584 3585 cmd->desc_id = param->desc_id; 3586 cmd->chanfreq = param->chanfreq; 3587 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3588 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3589 sizeof(uint32_t))); 3590 bufp += WMI_TLV_HDR_SIZE; 3591 qdf_mem_copy(bufp, param->pdata, bufp_len); 3592 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3593 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3594 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3595 #if defined(HTT_PADDR64) 3596 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3597 #endif 3598 cmd->frame_len = param->frm_len; 3599 cmd->buf_len = bufp_len; 3600 cmd->tx_params_valid = param->tx_params_valid; 3601 3602 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3603 bufp, cmd->vdev_id, cmd->chanfreq); 3604 3605 bufp += roundup(bufp_len, sizeof(uint32_t)); 3606 if (param->tx_params_valid) { 3607 status = populate_tx_send_params(bufp, param->tx_param); 3608 if (status != QDF_STATUS_SUCCESS) { 3609 WMI_LOGE("%s: Populate TX send params failed", 3610 __func__); 3611 goto err1; 3612 } 3613 cmd_len += sizeof(wmi_tx_send_params); 3614 } 3615 3616 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3617 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3618 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3619 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3620 goto err1; 3621 } 3622 3623 return QDF_STATUS_SUCCESS; 3624 3625 err1: 3626 wmi_buf_free(buf); 3627 return QDF_STATUS_E_FAILURE; 3628 } 3629 3630 /** 3631 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3632 * @wmi_handle: wmi handle 3633 * @param_value: parameter value 3634 * 3635 * Return: QDF_STATUS_SUCCESS for success or error code 3636 */ 3637 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3638 uint32_t param_value) 3639 { 3640 QDF_STATUS ret; 3641 wmi_modem_power_state_cmd_param *cmd; 3642 wmi_buf_t buf; 3643 uint16_t len = sizeof(*cmd); 3644 3645 buf = wmi_buf_alloc(wmi_handle, len); 3646 if (!buf) 3647 return QDF_STATUS_E_NOMEM; 3648 3649 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3650 WMITLV_SET_HDR(&cmd->tlv_header, 3651 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3652 WMITLV_GET_STRUCT_TLVLEN 3653 (wmi_modem_power_state_cmd_param)); 3654 cmd->modem_power_state = param_value; 3655 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3656 param_value); 3657 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3658 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3659 WMI_MODEM_POWER_STATE_CMDID); 3660 if (QDF_IS_STATUS_ERROR(ret)) { 3661 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3662 wmi_buf_free(buf); 3663 } 3664 3665 return ret; 3666 } 3667 3668 /** 3669 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3670 * @wmi_handle: wmi handle 3671 * @vdev_id: vdev id 3672 * @val: value 3673 * 3674 * Return: QDF_STATUS_SUCCESS for success or error code. 3675 */ 3676 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3677 uint32_t vdev_id, uint8_t val) 3678 { 3679 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3680 wmi_buf_t buf; 3681 int32_t len = sizeof(*cmd); 3682 3683 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3684 3685 buf = wmi_buf_alloc(wmi_handle, len); 3686 if (!buf) 3687 return QDF_STATUS_E_NOMEM; 3688 3689 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3690 WMITLV_SET_HDR(&cmd->tlv_header, 3691 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3692 WMITLV_GET_STRUCT_TLVLEN 3693 (wmi_sta_powersave_mode_cmd_fixed_param)); 3694 cmd->vdev_id = vdev_id; 3695 if (val) 3696 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3697 else 3698 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3699 3700 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3701 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3702 WMI_STA_POWERSAVE_MODE_CMDID)) { 3703 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3704 vdev_id, val); 3705 wmi_buf_free(buf); 3706 return QDF_STATUS_E_FAILURE; 3707 } 3708 return QDF_STATUS_SUCCESS; 3709 } 3710 3711 /** 3712 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 3713 * @wmi_handle: wmi handle 3714 * @vdev_id: vdev id 3715 * 3716 * Return: QDF_STATUS_SUCCESS for success or error code. 3717 */ 3718 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 3719 uint8_t val) 3720 { 3721 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 3722 wmi_buf_t buf; 3723 size_t len = sizeof(*cmd); 3724 3725 buf = wmi_buf_alloc(wmi_handle, len); 3726 if (!buf) 3727 return QDF_STATUS_E_NOMEM; 3728 3729 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 3730 WMITLV_SET_HDR(&cmd->tlv_header, 3731 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 3732 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 3733 3734 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 3735 WMI_IDLE_TRIGGER_MONITOR_OFF); 3736 3737 WMI_LOGD("val:%d", cmd->idle_trigger_monitor); 3738 3739 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3740 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 3741 wmi_buf_free(buf); 3742 return QDF_STATUS_E_FAILURE; 3743 } 3744 return QDF_STATUS_SUCCESS; 3745 } 3746 3747 /** 3748 * send_set_mimops_cmd_tlv() - set MIMO powersave 3749 * @wmi_handle: wmi handle 3750 * @vdev_id: vdev id 3751 * @value: value 3752 * 3753 * Return: QDF_STATUS_SUCCESS for success or error code. 3754 */ 3755 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3756 uint8_t vdev_id, int value) 3757 { 3758 QDF_STATUS ret; 3759 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3760 wmi_buf_t buf; 3761 uint16_t len = sizeof(*cmd); 3762 3763 buf = wmi_buf_alloc(wmi_handle, len); 3764 if (!buf) 3765 return QDF_STATUS_E_NOMEM; 3766 3767 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3768 WMITLV_SET_HDR(&cmd->tlv_header, 3769 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3770 WMITLV_GET_STRUCT_TLVLEN 3771 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3772 3773 cmd->vdev_id = vdev_id; 3774 3775 /* WMI_SMPS_FORCED_MODE values do not directly map 3776 * to SM power save values defined in the specification. 3777 * Make sure to send the right mapping. 3778 */ 3779 switch (value) { 3780 case 0: 3781 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3782 break; 3783 case 1: 3784 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3785 break; 3786 case 2: 3787 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3788 break; 3789 case 3: 3790 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3791 break; 3792 default: 3793 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3794 wmi_buf_free(buf); 3795 return QDF_STATUS_E_FAILURE; 3796 } 3797 3798 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3799 3800 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 3801 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3802 WMI_STA_SMPS_FORCE_MODE_CMDID); 3803 if (QDF_IS_STATUS_ERROR(ret)) { 3804 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3805 wmi_buf_free(buf); 3806 } 3807 3808 return ret; 3809 } 3810 3811 /** 3812 * send_set_smps_params_cmd_tlv() - set smps params 3813 * @wmi_handle: wmi handle 3814 * @vdev_id: vdev id 3815 * @value: value 3816 * 3817 * Return: QDF_STATUS_SUCCESS for success or error code. 3818 */ 3819 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3820 int value) 3821 { 3822 QDF_STATUS ret; 3823 wmi_sta_smps_param_cmd_fixed_param *cmd; 3824 wmi_buf_t buf; 3825 uint16_t len = sizeof(*cmd); 3826 3827 buf = wmi_buf_alloc(wmi_handle, len); 3828 if (!buf) 3829 return QDF_STATUS_E_NOMEM; 3830 3831 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3832 WMITLV_SET_HDR(&cmd->tlv_header, 3833 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3834 WMITLV_GET_STRUCT_TLVLEN 3835 (wmi_sta_smps_param_cmd_fixed_param)); 3836 3837 cmd->vdev_id = vdev_id; 3838 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3839 cmd->param = 3840 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3841 3842 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3843 cmd->param); 3844 3845 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 3846 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3847 WMI_STA_SMPS_PARAM_CMDID); 3848 if (QDF_IS_STATUS_ERROR(ret)) { 3849 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3850 wmi_buf_free(buf); 3851 } 3852 3853 return ret; 3854 } 3855 3856 /** 3857 * send_get_temperature_cmd_tlv() - get pdev temperature req 3858 * @wmi_handle: wmi handle 3859 * 3860 * Return: QDF_STATUS_SUCCESS for success or error code. 3861 */ 3862 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3863 { 3864 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3865 wmi_buf_t wmi_buf; 3866 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3867 uint8_t *buf_ptr; 3868 3869 if (!wmi_handle) { 3870 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3871 return QDF_STATUS_E_INVAL; 3872 } 3873 3874 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3875 if (!wmi_buf) 3876 return QDF_STATUS_E_NOMEM; 3877 3878 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3879 3880 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3881 WMITLV_SET_HDR(&cmd->tlv_header, 3882 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3883 WMITLV_GET_STRUCT_TLVLEN 3884 (wmi_pdev_get_temperature_cmd_fixed_param)); 3885 3886 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 3887 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3888 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3889 WMI_LOGE(FL("failed to send get temperature command")); 3890 wmi_buf_free(wmi_buf); 3891 return QDF_STATUS_E_FAILURE; 3892 } 3893 3894 return QDF_STATUS_SUCCESS; 3895 } 3896 3897 /** 3898 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3899 * @wmi_handle: wmi handle 3900 * @vdevid: vdev id 3901 * @peer_addr: peer mac address 3902 * @auto_triggerparam: auto trigger parameters 3903 * @num_ac: number of access category 3904 * 3905 * This function sets the trigger 3906 * uapsd params such as service interval, delay interval 3907 * and suspend interval which will be used by the firmware 3908 * to send trigger frames periodically when there is no 3909 * traffic on the transmit side. 3910 * 3911 * Return: QDF_STATUS_SUCCESS for success or error code. 3912 */ 3913 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3914 struct sta_uapsd_trig_params *param) 3915 { 3916 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3917 QDF_STATUS ret; 3918 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3919 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3920 uint32_t i; 3921 wmi_buf_t buf; 3922 uint8_t *buf_ptr; 3923 struct sta_uapsd_params *uapsd_param; 3924 wmi_sta_uapsd_auto_trig_param *trig_param; 3925 3926 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3927 if (!buf) 3928 return QDF_STATUS_E_NOMEM; 3929 3930 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3931 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3932 WMITLV_SET_HDR(&cmd->tlv_header, 3933 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3934 WMITLV_GET_STRUCT_TLVLEN 3935 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3936 cmd->vdev_id = param->vdevid; 3937 cmd->num_ac = param->num_ac; 3938 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3939 3940 /* TLV indicating array of structures to follow */ 3941 buf_ptr += sizeof(*cmd); 3942 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3943 3944 buf_ptr += WMI_TLV_HDR_SIZE; 3945 3946 /* 3947 * Update tag and length for uapsd auto trigger params (this will take 3948 * care of updating tag and length if it is not pre-filled by caller). 3949 */ 3950 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3951 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3952 for (i = 0; i < param->num_ac; i++) { 3953 WMITLV_SET_HDR((buf_ptr + 3954 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3955 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3956 WMITLV_GET_STRUCT_TLVLEN 3957 (wmi_sta_uapsd_auto_trig_param)); 3958 trig_param->wmm_ac = uapsd_param->wmm_ac; 3959 trig_param->user_priority = uapsd_param->user_priority; 3960 trig_param->service_interval = uapsd_param->service_interval; 3961 trig_param->suspend_interval = uapsd_param->suspend_interval; 3962 trig_param->delay_interval = uapsd_param->delay_interval; 3963 trig_param++; 3964 uapsd_param++; 3965 } 3966 3967 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 3968 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3969 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 3970 if (QDF_IS_STATUS_ERROR(ret)) { 3971 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 3972 wmi_buf_free(buf); 3973 } 3974 3975 return ret; 3976 } 3977 3978 /** 3979 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 3980 * @wmi_handle: Pointer to wmi handle 3981 * @thermal_info: Thermal command information 3982 * 3983 * This function sends the thermal management command 3984 * to the firmware 3985 * 3986 * Return: QDF_STATUS_SUCCESS for success otherwise failure 3987 */ 3988 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3989 struct thermal_cmd_params *thermal_info) 3990 { 3991 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 3992 wmi_buf_t buf = NULL; 3993 QDF_STATUS status; 3994 uint32_t len = 0; 3995 3996 len = sizeof(*cmd); 3997 3998 buf = wmi_buf_alloc(wmi_handle, len); 3999 if (!buf) 4000 return QDF_STATUS_E_FAILURE; 4001 4002 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4003 4004 WMITLV_SET_HDR(&cmd->tlv_header, 4005 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4006 WMITLV_GET_STRUCT_TLVLEN 4007 (wmi_thermal_mgmt_cmd_fixed_param)); 4008 4009 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4010 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4011 cmd->enable = thermal_info->thermal_enable; 4012 4013 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4014 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4015 4016 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4017 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4018 WMI_THERMAL_MGMT_CMDID); 4019 if (QDF_IS_STATUS_ERROR(status)) { 4020 wmi_buf_free(buf); 4021 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4022 } 4023 4024 return status; 4025 } 4026 4027 /** 4028 * send_lro_config_cmd_tlv() - process the LRO config command 4029 * @wmi_handle: Pointer to WMI handle 4030 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4031 * 4032 * This function sends down the LRO configuration parameters to 4033 * the firmware to enable LRO, sets the TCP flags and sets the 4034 * seed values for the toeplitz hash generation 4035 * 4036 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4037 */ 4038 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4039 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4040 { 4041 wmi_lro_info_cmd_fixed_param *cmd; 4042 wmi_buf_t buf; 4043 QDF_STATUS status; 4044 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4045 4046 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4047 if (!buf) 4048 return QDF_STATUS_E_FAILURE; 4049 4050 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4051 4052 WMITLV_SET_HDR(&cmd->tlv_header, 4053 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4054 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4055 4056 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4057 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4058 wmi_lro_cmd->tcp_flag); 4059 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4060 wmi_lro_cmd->tcp_flag_mask); 4061 cmd->toeplitz_hash_ipv4_0_3 = 4062 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4063 cmd->toeplitz_hash_ipv4_4_7 = 4064 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4065 cmd->toeplitz_hash_ipv4_8_11 = 4066 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4067 cmd->toeplitz_hash_ipv4_12_15 = 4068 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4069 cmd->toeplitz_hash_ipv4_16 = 4070 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4071 4072 cmd->toeplitz_hash_ipv6_0_3 = 4073 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4074 cmd->toeplitz_hash_ipv6_4_7 = 4075 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4076 cmd->toeplitz_hash_ipv6_8_11 = 4077 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4078 cmd->toeplitz_hash_ipv6_12_15 = 4079 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4080 cmd->toeplitz_hash_ipv6_16_19 = 4081 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4082 cmd->toeplitz_hash_ipv6_20_23 = 4083 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4084 cmd->toeplitz_hash_ipv6_24_27 = 4085 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4086 cmd->toeplitz_hash_ipv6_28_31 = 4087 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4088 cmd->toeplitz_hash_ipv6_32_35 = 4089 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4090 cmd->toeplitz_hash_ipv6_36_39 = 4091 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4092 cmd->toeplitz_hash_ipv6_40 = 4093 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4094 4095 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4096 wmi_handle, 4097 pdev_id); 4098 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4099 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4100 4101 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4102 status = wmi_unified_cmd_send(wmi_handle, buf, 4103 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4104 if (QDF_IS_STATUS_ERROR(status)) { 4105 wmi_buf_free(buf); 4106 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4107 } 4108 4109 return status; 4110 } 4111 4112 /** 4113 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4114 * @wmi_handle: Pointer to wmi handle 4115 * @rate_report_params: Pointer to peer rate report parameters 4116 * 4117 * 4118 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4119 */ 4120 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4121 struct wmi_peer_rate_report_params *rate_report_params) 4122 { 4123 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4124 wmi_buf_t buf = NULL; 4125 QDF_STATUS status = 0; 4126 uint32_t len = 0; 4127 uint32_t i, j; 4128 4129 len = sizeof(*cmd); 4130 4131 buf = wmi_buf_alloc(wmi_handle, len); 4132 if (!buf) 4133 return QDF_STATUS_E_FAILURE; 4134 4135 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4136 wmi_buf_data(buf); 4137 4138 WMITLV_SET_HDR( 4139 &cmd->tlv_header, 4140 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4141 WMITLV_GET_STRUCT_TLVLEN( 4142 wmi_peer_set_rate_report_condition_fixed_param)); 4143 4144 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4145 cmd->report_backoff_time = rate_report_params->backoff_time; 4146 cmd->report_timer_period = rate_report_params->timer_period; 4147 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4148 cmd->cond_per_phy[i].val_cond_flags = 4149 rate_report_params->report_per_phy[i].cond_flags; 4150 cmd->cond_per_phy[i].rate_delta.min_delta = 4151 rate_report_params->report_per_phy[i].delta.delta_min; 4152 cmd->cond_per_phy[i].rate_delta.percentage = 4153 rate_report_params->report_per_phy[i].delta.percent; 4154 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4155 cmd->cond_per_phy[i].rate_threshold[j] = 4156 rate_report_params->report_per_phy[i]. 4157 report_rate_threshold[j]; 4158 } 4159 } 4160 4161 WMI_LOGE("%s enable %d backoff_time %d period %d", __func__, 4162 cmd->enable_rate_report, 4163 cmd->report_backoff_time, cmd->report_timer_period); 4164 4165 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4166 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4167 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4168 if (QDF_IS_STATUS_ERROR(status)) { 4169 wmi_buf_free(buf); 4170 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4171 __func__); 4172 } 4173 return status; 4174 } 4175 4176 /** 4177 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4178 * @wmi_handle: wmi handle 4179 * @vdev_id: vdev id. 4180 * @wmm_vparams: edca parameters 4181 * 4182 * This function updates EDCA parameters to the target 4183 * 4184 * Return: CDF Status 4185 */ 4186 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4187 uint8_t vdev_id, bool mu_edca_param, 4188 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4189 { 4190 uint8_t *buf_ptr; 4191 wmi_buf_t buf; 4192 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4193 wmi_wmm_vparams *wmm_param; 4194 struct wmi_host_wme_vparams *twmm_param; 4195 int len = sizeof(*cmd); 4196 int ac; 4197 4198 buf = wmi_buf_alloc(wmi_handle, len); 4199 4200 if (!buf) 4201 return QDF_STATUS_E_NOMEM; 4202 4203 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4204 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4205 WMITLV_SET_HDR(&cmd->tlv_header, 4206 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4207 WMITLV_GET_STRUCT_TLVLEN 4208 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4209 cmd->vdev_id = vdev_id; 4210 cmd->wmm_param_type = mu_edca_param; 4211 4212 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4213 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4214 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4215 WMITLV_SET_HDR(&wmm_param->tlv_header, 4216 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4217 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4218 wmm_param->cwmin = twmm_param->cwmin; 4219 wmm_param->cwmax = twmm_param->cwmax; 4220 wmm_param->aifs = twmm_param->aifs; 4221 if (mu_edca_param) 4222 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4223 else 4224 wmm_param->txoplimit = twmm_param->txoplimit; 4225 wmm_param->acm = twmm_param->acm; 4226 wmm_param->no_ack = twmm_param->noackpolicy; 4227 } 4228 4229 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4230 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4231 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4232 goto fail; 4233 4234 return QDF_STATUS_SUCCESS; 4235 4236 fail: 4237 wmi_buf_free(buf); 4238 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 4239 return QDF_STATUS_E_FAILURE; 4240 } 4241 4242 /** 4243 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4244 * @wmi_handle: wmi handle 4245 * @vdev_id: vdev id 4246 * @probe_rsp_info: probe response info 4247 * 4248 * Return: QDF_STATUS_SUCCESS for success or error code 4249 */ 4250 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4251 uint8_t vdev_id, 4252 struct wmi_probe_resp_params *probe_rsp_info) 4253 { 4254 wmi_prb_tmpl_cmd_fixed_param *cmd; 4255 wmi_bcn_prb_info *bcn_prb_info; 4256 wmi_buf_t wmi_buf; 4257 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4258 uint8_t *buf_ptr; 4259 QDF_STATUS ret; 4260 4261 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 4262 4263 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4264 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4265 4266 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4267 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4268 tmpl_len_aligned; 4269 4270 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4271 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 4272 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4273 return QDF_STATUS_E_INVAL; 4274 } 4275 4276 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4277 if (!wmi_buf) 4278 return QDF_STATUS_E_NOMEM; 4279 4280 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4281 4282 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4283 WMITLV_SET_HDR(&cmd->tlv_header, 4284 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4285 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4286 cmd->vdev_id = vdev_id; 4287 cmd->buf_len = tmpl_len; 4288 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4289 4290 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4291 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4292 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4293 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4294 bcn_prb_info->caps = 0; 4295 bcn_prb_info->erp = 0; 4296 buf_ptr += sizeof(wmi_bcn_prb_info); 4297 4298 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4299 buf_ptr += WMI_TLV_HDR_SIZE; 4300 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4301 4302 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4303 ret = wmi_unified_cmd_send(wmi_handle, 4304 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4305 if (QDF_IS_STATUS_ERROR(ret)) { 4306 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 4307 wmi_buf_free(wmi_buf); 4308 } 4309 4310 return ret; 4311 } 4312 4313 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4314 #define WPI_IV_LEN 16 4315 4316 /** 4317 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4318 * 4319 * @dest_tx: destination address of tsc key counter 4320 * @src_tx: source address of tsc key counter 4321 * @dest_rx: destination address of rsc key counter 4322 * @src_rx: source address of rsc key counter 4323 * 4324 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4325 * 4326 * Return: None 4327 * 4328 */ 4329 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4330 uint8_t *dest_rx, uint8_t *src_rx) 4331 { 4332 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4333 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4334 } 4335 #else 4336 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4337 uint8_t *dest_rx, uint8_t *src_rx) 4338 { 4339 return; 4340 } 4341 #endif 4342 4343 /** 4344 * send_setup_install_key_cmd_tlv() - set key parameters 4345 * @wmi_handle: wmi handle 4346 * @key_params: key parameters 4347 * 4348 * This function fills structure from information 4349 * passed in key_params. 4350 * 4351 * Return: QDF_STATUS_SUCCESS - success 4352 * QDF_STATUS_E_FAILURE - failure 4353 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4354 */ 4355 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4356 struct set_key_params *key_params) 4357 { 4358 wmi_vdev_install_key_cmd_fixed_param *cmd; 4359 wmi_buf_t buf; 4360 uint8_t *buf_ptr; 4361 uint32_t len; 4362 uint8_t *key_data; 4363 QDF_STATUS status; 4364 4365 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4366 WMI_TLV_HDR_SIZE; 4367 4368 buf = wmi_buf_alloc(wmi_handle, len); 4369 if (!buf) 4370 return QDF_STATUS_E_NOMEM; 4371 4372 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4373 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4374 WMITLV_SET_HDR(&cmd->tlv_header, 4375 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4376 WMITLV_GET_STRUCT_TLVLEN 4377 (wmi_vdev_install_key_cmd_fixed_param)); 4378 cmd->vdev_id = key_params->vdev_id; 4379 cmd->key_ix = key_params->key_idx; 4380 if (key_params->group_key_idx) { 4381 cmd->is_group_key_ix_valid = 1; 4382 cmd->group_key_ix = key_params->group_key_idx; 4383 } 4384 4385 4386 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4387 cmd->key_flags |= key_params->key_flags; 4388 cmd->key_cipher = key_params->key_cipher; 4389 if ((key_params->key_txmic_len) && 4390 (key_params->key_rxmic_len)) { 4391 cmd->key_txmic_len = key_params->key_txmic_len; 4392 cmd->key_rxmic_len = key_params->key_rxmic_len; 4393 } 4394 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4395 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4396 key_params->tx_iv, 4397 cmd->wpi_key_rsc_counter, 4398 key_params->rx_iv); 4399 #endif 4400 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4401 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4402 roundup(key_params->key_len, sizeof(uint32_t))); 4403 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4404 qdf_mem_copy((void *)key_data, 4405 (const void *)key_params->key_data, key_params->key_len); 4406 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4407 sizeof(wmi_key_seq_counter)); 4408 cmd->key_len = key_params->key_len; 4409 4410 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4411 sizeof(wmi_key_seq_counter)); 4412 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4413 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4414 WMI_VDEV_INSTALL_KEY_CMDID); 4415 if (QDF_IS_STATUS_ERROR(status)) { 4416 qdf_mem_zero(wmi_buf_data(buf), len); 4417 wmi_buf_free(buf); 4418 } 4419 return status; 4420 } 4421 4422 /** 4423 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 4424 * @wmi_handle: wmi handle 4425 * @vdev_id: vdev id 4426 * @p2p_ie: p2p IE 4427 * 4428 * Return: QDF_STATUS_SUCCESS for success or error code 4429 */ 4430 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 4431 uint32_t vdev_id, uint8_t *p2p_ie) 4432 { 4433 QDF_STATUS ret; 4434 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 4435 wmi_buf_t wmi_buf; 4436 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 4437 uint8_t *buf_ptr; 4438 4439 ie_len = (uint32_t) (p2p_ie[1] + 2); 4440 4441 /* More than one P2P IE may be included in a single frame. 4442 If multiple P2P IEs are present, the complete P2P attribute 4443 data consists of the concatenation of the P2P Attribute 4444 fields of the P2P IEs. The P2P Attributes field of each 4445 P2P IE may be any length up to the maximum (251 octets). 4446 In this case host sends one P2P IE to firmware so the length 4447 should not exceed more than 251 bytes 4448 */ 4449 if (ie_len > 251) { 4450 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 4451 return QDF_STATUS_E_INVAL; 4452 } 4453 4454 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 4455 4456 wmi_buf_len = 4457 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 4458 WMI_TLV_HDR_SIZE; 4459 4460 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4461 if (!wmi_buf) 4462 return QDF_STATUS_E_NOMEM; 4463 4464 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4465 4466 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 4467 WMITLV_SET_HDR(&cmd->tlv_header, 4468 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 4469 WMITLV_GET_STRUCT_TLVLEN 4470 (wmi_p2p_go_set_beacon_ie_fixed_param)); 4471 cmd->vdev_id = vdev_id; 4472 cmd->ie_buf_len = ie_len; 4473 4474 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 4475 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 4476 buf_ptr += WMI_TLV_HDR_SIZE; 4477 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 4478 4479 WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 4480 4481 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 4482 ret = wmi_unified_cmd_send(wmi_handle, 4483 wmi_buf, wmi_buf_len, 4484 WMI_P2P_GO_SET_BEACON_IE); 4485 if (QDF_IS_STATUS_ERROR(ret)) { 4486 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 4487 wmi_buf_free(wmi_buf); 4488 } 4489 4490 WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 4491 return ret; 4492 } 4493 4494 /** 4495 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 4496 * @wmi_handle: wmi handle 4497 * @psetoui: OUI parameters 4498 * 4499 * set scan probe OUI parameters in firmware 4500 * 4501 * Return: CDF status 4502 */ 4503 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 4504 struct scan_mac_oui *psetoui) 4505 { 4506 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 4507 wmi_buf_t wmi_buf; 4508 uint32_t len; 4509 uint8_t *buf_ptr; 4510 uint32_t *oui_buf; 4511 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 4512 4513 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4514 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 4515 4516 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4517 if (!wmi_buf) 4518 return QDF_STATUS_E_NOMEM; 4519 4520 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4521 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 4522 WMITLV_SET_HDR(&cmd->tlv_header, 4523 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 4524 WMITLV_GET_STRUCT_TLVLEN 4525 (wmi_scan_prob_req_oui_cmd_fixed_param)); 4526 4527 oui_buf = &cmd->prob_req_oui; 4528 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 4529 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 4530 | psetoui->oui[2]; 4531 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 4532 cmd->prob_req_oui); 4533 4534 cmd->vdev_id = psetoui->vdev_id; 4535 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 4536 if (psetoui->enb_probe_req_sno_randomization) 4537 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 4538 4539 if (ie_whitelist->white_list) { 4540 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4541 &cmd->num_vendor_oui, 4542 ie_whitelist); 4543 cmd->flags |= 4544 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4545 } 4546 4547 buf_ptr += sizeof(*cmd); 4548 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4549 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4550 buf_ptr += WMI_TLV_HDR_SIZE; 4551 4552 if (cmd->num_vendor_oui != 0) { 4553 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4554 ie_whitelist->voui); 4555 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4556 } 4557 4558 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4559 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4560 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4561 WMI_LOGE("%s: failed to send command", __func__); 4562 wmi_buf_free(wmi_buf); 4563 return QDF_STATUS_E_FAILURE; 4564 } 4565 return QDF_STATUS_SUCCESS; 4566 } 4567 4568 #ifdef IPA_OFFLOAD 4569 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4570 * @wmi_handle: wmi handle 4571 * @ipa_offload: ipa offload control parameter 4572 * 4573 * Returns: 0 on success, error number otherwise 4574 */ 4575 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4576 struct ipa_uc_offload_control_params *ipa_offload) 4577 { 4578 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4579 wmi_buf_t wmi_buf; 4580 uint32_t len; 4581 u_int8_t *buf_ptr; 4582 4583 len = sizeof(*cmd); 4584 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4585 if (!wmi_buf) 4586 return QDF_STATUS_E_NOMEM; 4587 4588 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 4589 ipa_offload->offload_type, ipa_offload->enable); 4590 4591 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4592 4593 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4594 WMITLV_SET_HDR(&cmd->tlv_header, 4595 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4596 WMITLV_GET_STRUCT_TLVLEN( 4597 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4598 4599 cmd->offload_type = ipa_offload->offload_type; 4600 cmd->vdev_id = ipa_offload->vdev_id; 4601 cmd->enable = ipa_offload->enable; 4602 4603 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4604 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4605 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4606 WMI_LOGE("%s: failed to command", __func__); 4607 wmi_buf_free(wmi_buf); 4608 return QDF_STATUS_E_FAILURE; 4609 } 4610 4611 return QDF_STATUS_SUCCESS; 4612 } 4613 #endif 4614 4615 /** 4616 * send_pno_stop_cmd_tlv() - PNO stop request 4617 * @wmi_handle: wmi handle 4618 * @vdev_id: vdev id 4619 * 4620 * This function request FW to stop ongoing PNO operation. 4621 * 4622 * Return: CDF status 4623 */ 4624 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4625 { 4626 wmi_nlo_config_cmd_fixed_param *cmd; 4627 int32_t len = sizeof(*cmd); 4628 wmi_buf_t buf; 4629 uint8_t *buf_ptr; 4630 int ret; 4631 4632 /* 4633 * TLV place holder for array of structures nlo_configured_parameters 4634 * TLV place holder for array of uint32_t channel_list 4635 * TLV place holder for chnl prediction cfg 4636 */ 4637 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4638 buf = wmi_buf_alloc(wmi_handle, len); 4639 if (!buf) 4640 return QDF_STATUS_E_NOMEM; 4641 4642 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4643 buf_ptr = (uint8_t *) cmd; 4644 4645 WMITLV_SET_HDR(&cmd->tlv_header, 4646 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4647 WMITLV_GET_STRUCT_TLVLEN 4648 (wmi_nlo_config_cmd_fixed_param)); 4649 4650 cmd->vdev_id = vdev_id; 4651 cmd->flags = WMI_NLO_CONFIG_STOP; 4652 buf_ptr += sizeof(*cmd); 4653 4654 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4655 buf_ptr += WMI_TLV_HDR_SIZE; 4656 4657 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 4658 buf_ptr += WMI_TLV_HDR_SIZE; 4659 4660 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4661 buf_ptr += WMI_TLV_HDR_SIZE; 4662 4663 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4664 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4665 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4666 if (ret) { 4667 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 4668 wmi_buf_free(buf); 4669 return QDF_STATUS_E_FAILURE; 4670 } 4671 4672 return QDF_STATUS_SUCCESS; 4673 } 4674 4675 /** 4676 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 4677 * @buf_ptr: Buffer passed by upper layers 4678 * @pno: Buffer to be sent to the firmware 4679 * 4680 * Copy the PNO Channel prediction configuration parameters 4681 * passed by the upper layers to a WMI format TLV and send it 4682 * down to the firmware. 4683 * 4684 * Return: None 4685 */ 4686 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 4687 struct pno_scan_req_params *pno) 4688 { 4689 nlo_channel_prediction_cfg *channel_prediction_cfg = 4690 (nlo_channel_prediction_cfg *) buf_ptr; 4691 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 4692 WMITLV_TAG_ARRAY_BYTE, 4693 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 4694 #ifdef FEATURE_WLAN_SCAN_PNO 4695 channel_prediction_cfg->enable = pno->pno_channel_prediction; 4696 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 4697 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 4698 channel_prediction_cfg->full_scan_period_ms = 4699 pno->channel_prediction_full_scan; 4700 #endif 4701 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4702 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 4703 channel_prediction_cfg->enable, 4704 channel_prediction_cfg->top_k_num, 4705 channel_prediction_cfg->stationary_threshold, 4706 channel_prediction_cfg->full_scan_period_ms); 4707 } 4708 4709 /** 4710 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 4711 * @wmi_handle: wmi handle 4712 * @params: configuration parameters 4713 * 4714 * Return: QDF_STATUS 4715 */ 4716 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 4717 struct nlo_mawc_params *params) 4718 { 4719 wmi_buf_t buf = NULL; 4720 QDF_STATUS status; 4721 int len; 4722 uint8_t *buf_ptr; 4723 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 4724 4725 len = sizeof(*wmi_nlo_mawc_params); 4726 buf = wmi_buf_alloc(wmi_handle, len); 4727 if (!buf) 4728 return QDF_STATUS_E_NOMEM; 4729 4730 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4731 wmi_nlo_mawc_params = 4732 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 4733 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 4734 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 4735 WMITLV_GET_STRUCT_TLVLEN 4736 (wmi_nlo_configure_mawc_cmd_fixed_param)); 4737 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 4738 if (params->enable) 4739 wmi_nlo_mawc_params->enable = 1; 4740 else 4741 wmi_nlo_mawc_params->enable = 0; 4742 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 4743 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 4744 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 4745 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 4746 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 4747 wmi_nlo_mawc_params->exp_backoff_ratio, 4748 wmi_nlo_mawc_params->init_scan_interval, 4749 wmi_nlo_mawc_params->max_scan_interval); 4750 4751 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 4752 status = wmi_unified_cmd_send(wmi_handle, buf, 4753 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 4754 if (QDF_IS_STATUS_ERROR(status)) { 4755 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 4756 status); 4757 wmi_buf_free(buf); 4758 return QDF_STATUS_E_FAILURE; 4759 } 4760 4761 return QDF_STATUS_SUCCESS; 4762 } 4763 4764 /** 4765 * send_pno_start_cmd_tlv() - PNO start request 4766 * @wmi_handle: wmi handle 4767 * @pno: PNO request 4768 * 4769 * This function request FW to start PNO request. 4770 * Request: CDF status 4771 */ 4772 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 4773 struct pno_scan_req_params *pno) 4774 { 4775 wmi_nlo_config_cmd_fixed_param *cmd; 4776 nlo_configured_parameters *nlo_list; 4777 uint32_t *channel_list; 4778 int32_t len; 4779 wmi_buf_t buf; 4780 uint8_t *buf_ptr; 4781 uint8_t i; 4782 int ret; 4783 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 4784 connected_nlo_rssi_params *nlo_relative_rssi; 4785 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 4786 4787 /* 4788 * TLV place holder for array nlo_configured_parameters(nlo_list) 4789 * TLV place holder for array of uint32_t channel_list 4790 * TLV place holder for chnnl prediction cfg 4791 * TLV place holder for array of wmi_vendor_oui 4792 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 4793 */ 4794 len = sizeof(*cmd) + 4795 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 4796 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4797 4798 len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt, 4799 WMI_NLO_MAX_CHAN); 4800 len += sizeof(nlo_configured_parameters) * 4801 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4802 len += sizeof(nlo_channel_prediction_cfg); 4803 len += sizeof(enlo_candidate_score_params); 4804 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 4805 len += sizeof(connected_nlo_rssi_params); 4806 len += sizeof(connected_nlo_bss_band_rssi_pref); 4807 4808 buf = wmi_buf_alloc(wmi_handle, len); 4809 if (!buf) 4810 return QDF_STATUS_E_NOMEM; 4811 4812 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4813 4814 buf_ptr = (uint8_t *) cmd; 4815 WMITLV_SET_HDR(&cmd->tlv_header, 4816 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4817 WMITLV_GET_STRUCT_TLVLEN 4818 (wmi_nlo_config_cmd_fixed_param)); 4819 cmd->vdev_id = pno->vdev_id; 4820 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 4821 4822 #ifdef FEATURE_WLAN_SCAN_PNO 4823 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 4824 pno->adaptive_dwell_mode); 4825 #endif 4826 /* Current FW does not support min-max range for dwell time */ 4827 cmd->active_dwell_time = pno->active_dwell_time; 4828 cmd->passive_dwell_time = pno->passive_dwell_time; 4829 4830 if (pno->do_passive_scan) 4831 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 4832 /* Copy scan interval */ 4833 cmd->fast_scan_period = pno->fast_scan_period; 4834 cmd->slow_scan_period = pno->slow_scan_period; 4835 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 4836 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 4837 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 4838 WMI_LOGD("fast_scan_period: %d msec slow_scan_period: %d msec", 4839 cmd->fast_scan_period, cmd->slow_scan_period); 4840 WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); 4841 4842 /* mac randomization attributes */ 4843 if (pno->scan_random.randomize) { 4844 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 4845 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 4846 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 4847 pno->scan_random.mac_mask, 4848 &cmd->mac_addr, 4849 &cmd->mac_mask); 4850 } 4851 4852 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 4853 4854 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4855 WMI_LOGD("SSID count : %d", cmd->no_of_ssids); 4856 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4857 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 4858 buf_ptr += WMI_TLV_HDR_SIZE; 4859 4860 nlo_list = (nlo_configured_parameters *) buf_ptr; 4861 for (i = 0; i < cmd->no_of_ssids; i++) { 4862 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 4863 WMITLV_TAG_ARRAY_BYTE, 4864 WMITLV_GET_STRUCT_TLVLEN 4865 (nlo_configured_parameters)); 4866 /* Copy ssid and it's length */ 4867 nlo_list[i].ssid.valid = true; 4868 nlo_list[i].ssid.ssid.ssid_len = 4869 pno->networks_list[i].ssid.length; 4870 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 4871 pno->networks_list[i].ssid.ssid, 4872 nlo_list[i].ssid.ssid.ssid_len); 4873 WMI_LOGD("index: %d ssid: %.*s len: %d", i, 4874 nlo_list[i].ssid.ssid.ssid_len, 4875 (char *)nlo_list[i].ssid.ssid.ssid, 4876 nlo_list[i].ssid.ssid.ssid_len); 4877 4878 /* Copy rssi threshold */ 4879 if (pno->networks_list[i].rssi_thresh && 4880 pno->networks_list[i].rssi_thresh > 4881 WMI_RSSI_THOLD_DEFAULT) { 4882 nlo_list[i].rssi_cond.valid = true; 4883 nlo_list[i].rssi_cond.rssi = 4884 pno->networks_list[i].rssi_thresh; 4885 WMI_LOGD("RSSI threshold : %d dBm", 4886 nlo_list[i].rssi_cond.rssi); 4887 } 4888 nlo_list[i].bcast_nw_type.valid = true; 4889 nlo_list[i].bcast_nw_type.bcast_nw_type = 4890 pno->networks_list[i].bc_new_type; 4891 WMI_LOGD("Broadcast NW type (%u)", 4892 nlo_list[i].bcast_nw_type.bcast_nw_type); 4893 } 4894 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 4895 4896 /* Copy channel info */ 4897 cmd->num_of_channels = QDF_MIN(pno->networks_list[0].channel_cnt, 4898 WMI_NLO_MAX_CHAN); 4899 WMI_LOGD("Channel count: %d", cmd->num_of_channels); 4900 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 4901 (cmd->num_of_channels * sizeof(uint32_t))); 4902 buf_ptr += WMI_TLV_HDR_SIZE; 4903 4904 channel_list = (uint32_t *) buf_ptr; 4905 for (i = 0; i < cmd->num_of_channels; i++) { 4906 channel_list[i] = pno->networks_list[0].channels[i]; 4907 4908 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 4909 channel_list[i] = 4910 wlan_chan_to_freq(pno-> 4911 networks_list[0].channels[i]); 4912 4913 WMI_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); 4914 } 4915 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 4916 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4917 sizeof(nlo_channel_prediction_cfg)); 4918 buf_ptr += WMI_TLV_HDR_SIZE; 4919 wmi_set_pno_channel_prediction(buf_ptr, pno); 4920 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4921 /** TODO: Discrete firmware doesn't have command/option to configure 4922 * App IE which comes from wpa_supplicant as of part PNO start request. 4923 */ 4924 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 4925 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 4926 buf_ptr += sizeof(enlo_candidate_score_params); 4927 4928 if (ie_whitelist->white_list) { 4929 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4930 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4931 &cmd->num_vendor_oui, 4932 ie_whitelist); 4933 } 4934 4935 /* ie white list */ 4936 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4937 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4938 buf_ptr += WMI_TLV_HDR_SIZE; 4939 if (cmd->num_vendor_oui != 0) { 4940 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4941 ie_whitelist->voui); 4942 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4943 } 4944 4945 if (pno->relative_rssi_set) 4946 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 4947 4948 /* 4949 * Firmware calculation using connected PNO params: 4950 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 4951 * deduction of rssi_pref for chosen band_pref and 4952 * addition of rssi_pref for remaining bands (other than chosen band). 4953 */ 4954 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 4955 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 4956 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 4957 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 4958 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 4959 WMI_LOGD("relative_rssi %d", nlo_relative_rssi->relative_rssi); 4960 buf_ptr += sizeof(*nlo_relative_rssi); 4961 4962 /* 4963 * As of now Kernel and Host supports one band and rssi preference. 4964 * Firmware supports array of band and rssi preferences 4965 */ 4966 cmd->num_cnlo_band_pref = 1; 4967 WMITLV_SET_HDR(buf_ptr, 4968 WMITLV_TAG_ARRAY_STRUC, 4969 cmd->num_cnlo_band_pref * 4970 sizeof(connected_nlo_bss_band_rssi_pref)); 4971 buf_ptr += WMI_TLV_HDR_SIZE; 4972 4973 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 4974 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 4975 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 4976 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 4977 WMITLV_GET_STRUCT_TLVLEN( 4978 connected_nlo_bss_band_rssi_pref)); 4979 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 4980 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 4981 WMI_LOGI("band_pref %d, rssi_pref %d", 4982 nlo_band_rssi[i].band, 4983 nlo_band_rssi[i].rssi_pref); 4984 } 4985 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 4986 4987 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4988 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4989 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4990 if (ret) { 4991 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 4992 wmi_buf_free(buf); 4993 return QDF_STATUS_E_FAILURE; 4994 } 4995 4996 return QDF_STATUS_SUCCESS; 4997 } 4998 4999 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5000 /** 5001 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5002 * @wmi_handle: wmi handle 5003 * @clear_req: ll stats clear request command params 5004 * 5005 * Return: QDF_STATUS_SUCCESS for success or error code 5006 */ 5007 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5008 const struct ll_stats_clear_params *clear_req) 5009 { 5010 wmi_clear_link_stats_cmd_fixed_param *cmd; 5011 int32_t len; 5012 wmi_buf_t buf; 5013 uint8_t *buf_ptr; 5014 int ret; 5015 5016 len = sizeof(*cmd); 5017 buf = wmi_buf_alloc(wmi_handle, len); 5018 5019 if (!buf) 5020 return QDF_STATUS_E_NOMEM; 5021 5022 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5023 qdf_mem_zero(buf_ptr, len); 5024 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5025 5026 WMITLV_SET_HDR(&cmd->tlv_header, 5027 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5028 WMITLV_GET_STRUCT_TLVLEN 5029 (wmi_clear_link_stats_cmd_fixed_param)); 5030 5031 cmd->stop_stats_collection_req = clear_req->stop_req; 5032 cmd->vdev_id = clear_req->vdev_id; 5033 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5034 5035 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5036 &cmd->peer_macaddr); 5037 5038 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 5039 WMI_LOGD("StopReq: %d", cmd->stop_stats_collection_req); 5040 WMI_LOGD("Vdev Id: %d", cmd->vdev_id); 5041 WMI_LOGD("Clear Stat Mask: %d", cmd->stats_clear_req_mask); 5042 WMI_LOGD("Peer MAC Addr: %pM", clear_req->peer_macaddr.bytes); 5043 5044 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5045 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5046 WMI_CLEAR_LINK_STATS_CMDID); 5047 if (ret) { 5048 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 5049 wmi_buf_free(buf); 5050 return QDF_STATUS_E_FAILURE; 5051 } 5052 5053 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 5054 return QDF_STATUS_SUCCESS; 5055 } 5056 5057 /** 5058 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5059 * @wmi_handle: wmi handle 5060 * @set_req: ll stats set request command params 5061 * 5062 * Return: QDF_STATUS_SUCCESS for success or error code 5063 */ 5064 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5065 const struct ll_stats_set_params *set_req) 5066 { 5067 wmi_start_link_stats_cmd_fixed_param *cmd; 5068 int32_t len; 5069 wmi_buf_t buf; 5070 uint8_t *buf_ptr; 5071 int ret; 5072 5073 len = sizeof(*cmd); 5074 buf = wmi_buf_alloc(wmi_handle, len); 5075 5076 if (!buf) 5077 return QDF_STATUS_E_NOMEM; 5078 5079 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5080 qdf_mem_zero(buf_ptr, len); 5081 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5082 5083 WMITLV_SET_HDR(&cmd->tlv_header, 5084 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5085 WMITLV_GET_STRUCT_TLVLEN 5086 (wmi_start_link_stats_cmd_fixed_param)); 5087 5088 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5089 cmd->aggressive_statistics_gathering = 5090 set_req->aggressive_statistics_gathering; 5091 5092 WMI_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); 5093 WMI_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); 5094 WMI_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); 5095 5096 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5097 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5098 WMI_START_LINK_STATS_CMDID); 5099 if (ret) { 5100 WMI_LOGE("%s: Failed to send set link stats request", __func__); 5101 wmi_buf_free(buf); 5102 return QDF_STATUS_E_FAILURE; 5103 } 5104 5105 return QDF_STATUS_SUCCESS; 5106 } 5107 5108 /** 5109 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5110 * @wmi_handle: wmi handle 5111 * @get_req: ll stats get request command params 5112 * 5113 * Return: QDF_STATUS_SUCCESS for success or error code 5114 */ 5115 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5116 const struct ll_stats_get_params *get_req) 5117 { 5118 wmi_request_link_stats_cmd_fixed_param *cmd; 5119 int32_t len; 5120 wmi_buf_t buf; 5121 uint8_t *buf_ptr; 5122 int ret; 5123 5124 len = sizeof(*cmd); 5125 buf = wmi_buf_alloc(wmi_handle, len); 5126 5127 if (!buf) 5128 return QDF_STATUS_E_NOMEM; 5129 5130 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5131 qdf_mem_zero(buf_ptr, len); 5132 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5133 5134 WMITLV_SET_HDR(&cmd->tlv_header, 5135 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5136 WMITLV_GET_STRUCT_TLVLEN 5137 (wmi_request_link_stats_cmd_fixed_param)); 5138 5139 cmd->request_id = get_req->req_id; 5140 cmd->stats_type = get_req->param_id_mask; 5141 cmd->vdev_id = get_req->vdev_id; 5142 5143 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5144 &cmd->peer_macaddr); 5145 5146 WMI_LOGD("LINK_LAYER_STATS - Get Request Params"); 5147 WMI_LOGD("Request ID: %u", cmd->request_id); 5148 WMI_LOGD("Stats Type: %0x", cmd->stats_type); 5149 WMI_LOGD("Vdev ID: %d", cmd->vdev_id); 5150 WMI_LOGD("Peer MAC Addr: %pM", get_req->peer_macaddr.bytes); 5151 5152 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5153 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5154 WMI_REQUEST_LINK_STATS_CMDID); 5155 if (ret) { 5156 WMI_LOGE("%s: Failed to send get link stats request", __func__); 5157 wmi_buf_free(buf); 5158 return QDF_STATUS_E_FAILURE; 5159 } 5160 5161 return QDF_STATUS_SUCCESS; 5162 } 5163 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 5164 5165 /** 5166 * send_congestion_cmd_tlv() - send request to fw to get CCA 5167 * @wmi_handle: wmi handle 5168 * @vdev_id: vdev id 5169 * 5170 * Return: CDF status 5171 */ 5172 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 5173 uint8_t vdev_id) 5174 { 5175 wmi_buf_t buf; 5176 wmi_request_stats_cmd_fixed_param *cmd; 5177 uint8_t len; 5178 uint8_t *buf_ptr; 5179 5180 len = sizeof(*cmd); 5181 buf = wmi_buf_alloc(wmi_handle, len); 5182 if (!buf) 5183 return QDF_STATUS_E_FAILURE; 5184 5185 buf_ptr = wmi_buf_data(buf); 5186 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 5187 WMITLV_SET_HDR(&cmd->tlv_header, 5188 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5189 WMITLV_GET_STRUCT_TLVLEN 5190 (wmi_request_stats_cmd_fixed_param)); 5191 5192 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 5193 cmd->vdev_id = vdev_id; 5194 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 5195 cmd->vdev_id, cmd->stats_id); 5196 5197 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5198 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5199 WMI_REQUEST_STATS_CMDID)) { 5200 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 5201 __func__); 5202 wmi_buf_free(buf); 5203 return QDF_STATUS_E_FAILURE; 5204 } 5205 5206 return QDF_STATUS_SUCCESS; 5207 } 5208 5209 /** 5210 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 5211 * @wmi_handle: wmi handle 5212 * @rssi_req: get RSSI request 5213 * 5214 * Return: CDF status 5215 */ 5216 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 5217 { 5218 wmi_buf_t buf; 5219 wmi_request_stats_cmd_fixed_param *cmd; 5220 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5221 5222 buf = wmi_buf_alloc(wmi_handle, len); 5223 if (!buf) 5224 return QDF_STATUS_E_FAILURE; 5225 5226 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5227 WMITLV_SET_HDR(&cmd->tlv_header, 5228 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5229 WMITLV_GET_STRUCT_TLVLEN 5230 (wmi_request_stats_cmd_fixed_param)); 5231 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5232 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5233 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5234 WMI_REQUEST_STATS_CMDID)) { 5235 WMI_LOGE("Failed to send host stats request to fw"); 5236 wmi_buf_free(buf); 5237 return QDF_STATUS_E_FAILURE; 5238 } 5239 5240 return QDF_STATUS_SUCCESS; 5241 } 5242 5243 /** 5244 * send_snr_cmd_tlv() - get RSSI from fw 5245 * @wmi_handle: wmi handle 5246 * @vdev_id: vdev id 5247 * 5248 * Return: CDF status 5249 */ 5250 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5251 { 5252 wmi_buf_t buf; 5253 wmi_request_stats_cmd_fixed_param *cmd; 5254 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5255 5256 buf = wmi_buf_alloc(wmi_handle, len); 5257 if (!buf) 5258 return QDF_STATUS_E_FAILURE; 5259 5260 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5261 cmd->vdev_id = vdev_id; 5262 5263 WMITLV_SET_HDR(&cmd->tlv_header, 5264 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5265 WMITLV_GET_STRUCT_TLVLEN 5266 (wmi_request_stats_cmd_fixed_param)); 5267 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5268 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5269 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5270 WMI_REQUEST_STATS_CMDID)) { 5271 WMI_LOGE("Failed to send host stats request to fw"); 5272 wmi_buf_free(buf); 5273 return QDF_STATUS_E_FAILURE; 5274 } 5275 5276 return QDF_STATUS_SUCCESS; 5277 } 5278 5279 /** 5280 * send_link_status_req_cmd_tlv() - process link status request from UMAC 5281 * @wmi_handle: wmi handle 5282 * @link_status: get link params 5283 * 5284 * Return: CDF status 5285 */ 5286 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 5287 struct link_status_params *link_status) 5288 { 5289 wmi_buf_t buf; 5290 wmi_request_stats_cmd_fixed_param *cmd; 5291 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5292 5293 buf = wmi_buf_alloc(wmi_handle, len); 5294 if (!buf) 5295 return QDF_STATUS_E_FAILURE; 5296 5297 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5298 WMITLV_SET_HDR(&cmd->tlv_header, 5299 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5300 WMITLV_GET_STRUCT_TLVLEN 5301 (wmi_request_stats_cmd_fixed_param)); 5302 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 5303 cmd->vdev_id = link_status->vdev_id; 5304 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5305 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5306 WMI_REQUEST_STATS_CMDID)) { 5307 WMI_LOGE("Failed to send WMI link status request to fw"); 5308 wmi_buf_free(buf); 5309 return QDF_STATUS_E_FAILURE; 5310 } 5311 5312 return QDF_STATUS_SUCCESS; 5313 } 5314 5315 #ifdef WLAN_SUPPORT_GREEN_AP 5316 /** 5317 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 5318 * @wmi_handle: wmi handler 5319 * @egap_params: pointer to egap_params 5320 * 5321 * Return: 0 for success, otherwise appropriate error code 5322 */ 5323 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 5324 struct wlan_green_ap_egap_params *egap_params) 5325 { 5326 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 5327 wmi_buf_t buf; 5328 int32_t err; 5329 5330 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5331 if (!buf) 5332 return QDF_STATUS_E_NOMEM; 5333 5334 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 5335 WMITLV_SET_HDR(&cmd->tlv_header, 5336 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 5337 WMITLV_GET_STRUCT_TLVLEN( 5338 wmi_ap_ps_egap_param_cmd_fixed_param)); 5339 5340 cmd->enable = egap_params->host_enable_egap; 5341 cmd->inactivity_time = egap_params->egap_inactivity_time; 5342 cmd->wait_time = egap_params->egap_wait_time; 5343 cmd->flags = egap_params->egap_feature_flags; 5344 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 5345 err = wmi_unified_cmd_send(wmi_handle, buf, 5346 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 5347 if (err) { 5348 WMI_LOGE("Failed to send ap_ps_egap cmd"); 5349 wmi_buf_free(buf); 5350 return QDF_STATUS_E_FAILURE; 5351 } 5352 5353 return QDF_STATUS_SUCCESS; 5354 } 5355 #endif 5356 5357 /** 5358 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 5359 * @wmi_handle: wmi handle 5360 * @vdev_id: vdev id 5361 * 5362 * Return: QDF_STATUS_SUCCESS for success or error code 5363 */ 5364 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 5365 uint8_t vdev_id) 5366 { 5367 wmi_csa_offload_enable_cmd_fixed_param *cmd; 5368 wmi_buf_t buf; 5369 int32_t len = sizeof(*cmd); 5370 5371 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 5372 buf = wmi_buf_alloc(wmi_handle, len); 5373 if (!buf) 5374 return QDF_STATUS_E_NOMEM; 5375 5376 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 5377 WMITLV_SET_HDR(&cmd->tlv_header, 5378 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 5379 WMITLV_GET_STRUCT_TLVLEN 5380 (wmi_csa_offload_enable_cmd_fixed_param)); 5381 cmd->vdev_id = vdev_id; 5382 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 5383 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 5384 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5385 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 5386 WMI_LOGP("%s: Failed to send CSA offload enable command", 5387 __func__); 5388 wmi_buf_free(buf); 5389 return QDF_STATUS_E_FAILURE; 5390 } 5391 5392 return 0; 5393 } 5394 5395 #ifdef WLAN_FEATURE_CIF_CFR 5396 /** 5397 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 5398 * @wmi_handle: wmi handle 5399 * @data_len: len of dma cfg req 5400 * @data: dma cfg req 5401 * 5402 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 5403 */ 5404 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 5405 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 5406 { 5407 wmi_buf_t buf; 5408 uint8_t *cmd; 5409 QDF_STATUS ret; 5410 5411 WMITLV_SET_HDR(cfg, 5412 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 5413 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 5414 5415 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 5416 if (!buf) 5417 return QDF_STATUS_E_FAILURE; 5418 5419 cmd = (uint8_t *) wmi_buf_data(buf); 5420 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 5421 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 5422 sizeof(*cfg)); 5423 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 5424 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 5425 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 5426 if (QDF_IS_STATUS_ERROR(ret)) { 5427 WMI_LOGE(FL(":wmi cmd send failed")); 5428 wmi_buf_free(buf); 5429 } 5430 5431 return ret; 5432 } 5433 #endif 5434 5435 /** 5436 * send_start_11d_scan_cmd_tlv() - start 11d scan request 5437 * @wmi_handle: wmi handle 5438 * @start_11d_scan: 11d scan start request parameters 5439 * 5440 * This function request FW to start 11d scan. 5441 * 5442 * Return: QDF status 5443 */ 5444 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5445 struct reg_start_11d_scan_req *start_11d_scan) 5446 { 5447 wmi_11d_scan_start_cmd_fixed_param *cmd; 5448 int32_t len; 5449 wmi_buf_t buf; 5450 int ret; 5451 5452 len = sizeof(*cmd); 5453 buf = wmi_buf_alloc(wmi_handle, len); 5454 if (!buf) 5455 return QDF_STATUS_E_NOMEM; 5456 5457 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 5458 5459 WMITLV_SET_HDR(&cmd->tlv_header, 5460 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 5461 WMITLV_GET_STRUCT_TLVLEN 5462 (wmi_11d_scan_start_cmd_fixed_param)); 5463 5464 cmd->vdev_id = start_11d_scan->vdev_id; 5465 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 5466 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 5467 5468 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 5469 5470 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 5471 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5472 WMI_11D_SCAN_START_CMDID); 5473 if (ret) { 5474 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 5475 wmi_buf_free(buf); 5476 return QDF_STATUS_E_FAILURE; 5477 } 5478 5479 return QDF_STATUS_SUCCESS; 5480 } 5481 5482 /** 5483 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 5484 * @wmi_handle: wmi handle 5485 * @start_11d_scan: 11d scan stop request parameters 5486 * 5487 * This function request FW to stop 11d scan. 5488 * 5489 * Return: QDF status 5490 */ 5491 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5492 struct reg_stop_11d_scan_req *stop_11d_scan) 5493 { 5494 wmi_11d_scan_stop_cmd_fixed_param *cmd; 5495 int32_t len; 5496 wmi_buf_t buf; 5497 int ret; 5498 5499 len = sizeof(*cmd); 5500 buf = wmi_buf_alloc(wmi_handle, len); 5501 if (!buf) 5502 return QDF_STATUS_E_NOMEM; 5503 5504 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 5505 5506 WMITLV_SET_HDR(&cmd->tlv_header, 5507 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 5508 WMITLV_GET_STRUCT_TLVLEN 5509 (wmi_11d_scan_stop_cmd_fixed_param)); 5510 5511 cmd->vdev_id = stop_11d_scan->vdev_id; 5512 5513 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 5514 5515 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 5516 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5517 WMI_11D_SCAN_STOP_CMDID); 5518 if (ret) { 5519 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 5520 wmi_buf_free(buf); 5521 return QDF_STATUS_E_FAILURE; 5522 } 5523 5524 return QDF_STATUS_SUCCESS; 5525 } 5526 5527 /** 5528 * send_start_oem_data_cmd_tlv() - start OEM data request to target 5529 * @wmi_handle: wmi handle 5530 * @data_len: the length of @data 5531 * @data: the pointer to data buf 5532 * 5533 * Return: CDF status 5534 */ 5535 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 5536 uint32_t data_len, 5537 uint8_t *data) 5538 { 5539 wmi_buf_t buf; 5540 uint8_t *cmd; 5541 QDF_STATUS ret; 5542 5543 buf = wmi_buf_alloc(wmi_handle, 5544 (data_len + WMI_TLV_HDR_SIZE)); 5545 if (!buf) 5546 return QDF_STATUS_E_FAILURE; 5547 5548 cmd = (uint8_t *) wmi_buf_data(buf); 5549 5550 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 5551 cmd += WMI_TLV_HDR_SIZE; 5552 qdf_mem_copy(cmd, data, 5553 data_len); 5554 5555 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 5556 data_len); 5557 5558 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 5559 ret = wmi_unified_cmd_send(wmi_handle, buf, 5560 (data_len + 5561 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 5562 5563 if (QDF_IS_STATUS_ERROR(ret)) { 5564 WMI_LOGE(FL(":wmi cmd send failed")); 5565 wmi_buf_free(buf); 5566 } 5567 5568 return ret; 5569 } 5570 5571 #ifdef FEATURE_OEM_DATA 5572 /** 5573 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 5574 * @wmi_handle: wmi handle 5575 * @oem_data: the pointer to oem data 5576 * 5577 * Return: QDF status 5578 */ 5579 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 5580 struct oem_data *oem_data) 5581 { 5582 QDF_STATUS ret; 5583 wmi_oem_data_cmd_fixed_param *cmd; 5584 wmi_buf_t buf; 5585 uint16_t len = sizeof(*cmd); 5586 uint16_t oem_data_len_aligned; 5587 uint8_t *buf_ptr; 5588 5589 if (!oem_data || !oem_data->data) { 5590 wmi_err_rl("oem data is not valid"); 5591 return QDF_STATUS_E_FAILURE; 5592 } 5593 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 5594 if (oem_data_len_aligned < oem_data->data_len) { 5595 wmi_err_rl("integer overflow while rounding up data_len"); 5596 return QDF_STATUS_E_FAILURE; 5597 } 5598 5599 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 5600 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 5601 return QDF_STATUS_E_FAILURE; 5602 } 5603 5604 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 5605 buf = wmi_buf_alloc(wmi_handle, len); 5606 if (!buf) 5607 return QDF_STATUS_E_NOMEM; 5608 5609 buf_ptr = (uint8_t *)wmi_buf_data(buf); 5610 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 5611 WMITLV_SET_HDR(&cmd->tlv_header, 5612 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 5613 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 5614 5615 cmd->vdev_id = oem_data->vdev_id; 5616 cmd->data_len = oem_data->data_len; 5617 buf_ptr += sizeof(*cmd); 5618 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 5619 buf_ptr += WMI_TLV_HDR_SIZE; 5620 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 5621 5622 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 5623 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 5624 if (QDF_IS_STATUS_ERROR(ret)) { 5625 wmi_err_rl("Failed with ret = %d", ret); 5626 wmi_buf_free(buf); 5627 } 5628 5629 return ret; 5630 } 5631 #endif 5632 5633 /** 5634 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 5635 * @wmi_handle: wmi handle 5636 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 5637 * 5638 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 5639 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 5640 * to firmware based on phyerr filtering 5641 * offload status. 5642 * 5643 * Return: 1 success, 0 failure 5644 */ 5645 static QDF_STATUS 5646 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 5647 bool dfs_phyerr_filter_offload) 5648 { 5649 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 5650 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 5651 wmi_buf_t buf; 5652 uint16_t len; 5653 QDF_STATUS ret; 5654 5655 5656 if (false == dfs_phyerr_filter_offload) { 5657 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 5658 __func__); 5659 len = sizeof(*disable_phyerr_offload_cmd); 5660 buf = wmi_buf_alloc(wmi_handle, len); 5661 if (!buf) 5662 return 0; 5663 5664 disable_phyerr_offload_cmd = 5665 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 5666 wmi_buf_data(buf); 5667 5668 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 5669 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 5670 WMITLV_GET_STRUCT_TLVLEN 5671 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 5672 5673 /* 5674 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 5675 * to the firmware to disable the phyerror 5676 * filtering offload. 5677 */ 5678 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 5679 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5680 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 5681 if (QDF_IS_STATUS_ERROR(ret)) { 5682 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 5683 __func__, ret); 5684 wmi_buf_free(buf); 5685 return QDF_STATUS_E_FAILURE; 5686 } 5687 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 5688 __func__); 5689 } else { 5690 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 5691 __func__); 5692 5693 len = sizeof(*enable_phyerr_offload_cmd); 5694 buf = wmi_buf_alloc(wmi_handle, len); 5695 if (!buf) 5696 return QDF_STATUS_E_FAILURE; 5697 5698 enable_phyerr_offload_cmd = 5699 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 5700 wmi_buf_data(buf); 5701 5702 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 5703 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 5704 WMITLV_GET_STRUCT_TLVLEN 5705 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 5706 5707 /* 5708 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 5709 * to the firmware to enable the phyerror 5710 * filtering offload. 5711 */ 5712 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 5713 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5714 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 5715 5716 if (QDF_IS_STATUS_ERROR(ret)) { 5717 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 5718 __func__, ret); 5719 wmi_buf_free(buf); 5720 return QDF_STATUS_E_FAILURE; 5721 } 5722 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 5723 __func__); 5724 } 5725 5726 return QDF_STATUS_SUCCESS; 5727 } 5728 5729 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 5730 /** 5731 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 5732 * @wmi_handle: wmi handle 5733 * @pktlog_event: pktlog event 5734 * @cmd_id: pktlog cmd id 5735 * @user_triggered: user triggered input for PKTLOG enable mode 5736 * 5737 * Return: CDF status 5738 */ 5739 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 5740 WMI_PKTLOG_EVENT pktlog_event, 5741 WMI_CMD_ID cmd_id, uint8_t user_triggered) 5742 { 5743 WMI_PKTLOG_EVENT PKTLOG_EVENT; 5744 WMI_CMD_ID CMD_ID; 5745 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 5746 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 5747 int len = 0; 5748 wmi_buf_t buf; 5749 5750 PKTLOG_EVENT = pktlog_event; 5751 CMD_ID = cmd_id; 5752 5753 switch (CMD_ID) { 5754 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 5755 len = sizeof(*cmd); 5756 buf = wmi_buf_alloc(wmi_handle, len); 5757 if (!buf) 5758 return QDF_STATUS_E_NOMEM; 5759 5760 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 5761 wmi_buf_data(buf); 5762 WMITLV_SET_HDR(&cmd->tlv_header, 5763 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 5764 WMITLV_GET_STRUCT_TLVLEN 5765 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 5766 cmd->evlist = PKTLOG_EVENT; 5767 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 5768 : WMI_PKTLOG_ENABLE_AUTO; 5769 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5770 wmi_handle, 5771 WMI_HOST_PDEV_ID_SOC); 5772 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 5773 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5774 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 5775 WMI_LOGE("failed to send pktlog enable cmdid"); 5776 goto wmi_send_failed; 5777 } 5778 break; 5779 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 5780 len = sizeof(*disable_cmd); 5781 buf = wmi_buf_alloc(wmi_handle, len); 5782 if (!buf) 5783 return QDF_STATUS_E_NOMEM; 5784 5785 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 5786 wmi_buf_data(buf); 5787 WMITLV_SET_HDR(&disable_cmd->tlv_header, 5788 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 5789 WMITLV_GET_STRUCT_TLVLEN 5790 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 5791 disable_cmd->pdev_id = 5792 wmi_handle->ops->convert_pdev_id_host_to_target( 5793 wmi_handle, 5794 WMI_HOST_PDEV_ID_SOC); 5795 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 5796 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5797 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 5798 WMI_LOGE("failed to send pktlog disable cmdid"); 5799 goto wmi_send_failed; 5800 } 5801 break; 5802 default: 5803 WMI_LOGD("%s: invalid PKTLOG command", __func__); 5804 break; 5805 } 5806 5807 return QDF_STATUS_SUCCESS; 5808 5809 wmi_send_failed: 5810 wmi_buf_free(buf); 5811 return QDF_STATUS_E_FAILURE; 5812 } 5813 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 5814 5815 /** 5816 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 5817 * @wmi_handle: wmi handle 5818 * @preq: stats ext params 5819 * 5820 * Return: CDF status 5821 */ 5822 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 5823 struct stats_ext_params *preq) 5824 { 5825 QDF_STATUS ret; 5826 wmi_req_stats_ext_cmd_fixed_param *cmd; 5827 wmi_buf_t buf; 5828 size_t len; 5829 uint8_t *buf_ptr; 5830 5831 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 5832 5833 buf = wmi_buf_alloc(wmi_handle, len); 5834 if (!buf) 5835 return QDF_STATUS_E_NOMEM; 5836 5837 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5838 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 5839 5840 WMITLV_SET_HDR(&cmd->tlv_header, 5841 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 5842 WMITLV_GET_STRUCT_TLVLEN 5843 (wmi_req_stats_ext_cmd_fixed_param)); 5844 cmd->vdev_id = preq->vdev_id; 5845 cmd->data_len = preq->request_data_len; 5846 5847 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 5848 __func__, preq->request_data_len, preq->vdev_id); 5849 5850 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 5851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 5852 5853 buf_ptr += WMI_TLV_HDR_SIZE; 5854 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 5855 5856 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 5857 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5858 WMI_REQUEST_STATS_EXT_CMDID); 5859 if (QDF_IS_STATUS_ERROR(ret)) { 5860 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 5861 ret); 5862 wmi_buf_free(buf); 5863 } 5864 5865 return ret; 5866 } 5867 5868 /** 5869 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 5870 * @wmi_handle: wmi handle 5871 * @params: DHCP server offload info 5872 * 5873 * Return: QDF_STATUS_SUCCESS for success or error code 5874 */ 5875 static QDF_STATUS 5876 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 5877 struct dhcp_offload_info_params *params) 5878 { 5879 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 5880 wmi_buf_t buf; 5881 QDF_STATUS status; 5882 5883 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5884 if (!buf) 5885 return QDF_STATUS_E_NOMEM; 5886 5887 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 5888 5889 WMITLV_SET_HDR(&cmd->tlv_header, 5890 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 5891 WMITLV_GET_STRUCT_TLVLEN 5892 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 5893 cmd->vdev_id = params->vdev_id; 5894 cmd->enable = params->dhcp_offload_enabled; 5895 cmd->num_client = params->dhcp_client_num; 5896 cmd->srv_ipv4 = params->dhcp_srv_addr; 5897 cmd->start_lsb = 0; 5898 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 5899 status = wmi_unified_cmd_send(wmi_handle, buf, 5900 sizeof(*cmd), 5901 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 5902 if (QDF_IS_STATUS_ERROR(status)) { 5903 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 5904 wmi_buf_free(buf); 5905 return QDF_STATUS_E_FAILURE; 5906 } 5907 WMI_LOGD("Set dhcp server offload to vdevId %d", 5908 params->vdev_id); 5909 5910 return status; 5911 } 5912 5913 /** 5914 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 5915 * @wmi_handle: wmi handle 5916 * @param: pointer to pdev regdomain params 5917 * 5918 * Return: 0 for success or error code 5919 */ 5920 static QDF_STATUS 5921 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 5922 struct pdev_set_regdomain_params *param) 5923 { 5924 wmi_buf_t buf; 5925 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 5926 int32_t len = sizeof(*cmd); 5927 5928 buf = wmi_buf_alloc(wmi_handle, len); 5929 if (!buf) 5930 return QDF_STATUS_E_NOMEM; 5931 5932 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 5933 WMITLV_SET_HDR(&cmd->tlv_header, 5934 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 5935 WMITLV_GET_STRUCT_TLVLEN 5936 (wmi_pdev_set_regdomain_cmd_fixed_param)); 5937 5938 cmd->reg_domain = param->currentRDinuse; 5939 cmd->reg_domain_2G = param->currentRD2G; 5940 cmd->reg_domain_5G = param->currentRD5G; 5941 cmd->conformance_test_limit_2G = param->ctl_2G; 5942 cmd->conformance_test_limit_5G = param->ctl_5G; 5943 cmd->dfs_domain = param->dfsDomain; 5944 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5945 wmi_handle, 5946 param->pdev_id); 5947 5948 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 5949 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5950 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 5951 WMI_LOGE("%s: Failed to send pdev set regdomain command", 5952 __func__); 5953 wmi_buf_free(buf); 5954 return QDF_STATUS_E_FAILURE; 5955 } 5956 5957 return QDF_STATUS_SUCCESS; 5958 } 5959 5960 /** 5961 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 5962 * @wmi_handle: wmi handle 5963 * @reg_dmn: reg domain 5964 * @regdmn2G: 2G reg domain 5965 * @regdmn5G: 5G reg domain 5966 * @ctl2G: 2G test limit 5967 * @ctl5G: 5G test limit 5968 * 5969 * Return: none 5970 */ 5971 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 5972 uint32_t reg_dmn, uint16_t regdmn2G, 5973 uint16_t regdmn5G, uint8_t ctl2G, 5974 uint8_t ctl5G) 5975 { 5976 wmi_buf_t buf; 5977 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 5978 int32_t len = sizeof(*cmd); 5979 5980 5981 buf = wmi_buf_alloc(wmi_handle, len); 5982 if (!buf) 5983 return QDF_STATUS_E_NOMEM; 5984 5985 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 5986 WMITLV_SET_HDR(&cmd->tlv_header, 5987 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 5988 WMITLV_GET_STRUCT_TLVLEN 5989 (wmi_pdev_set_regdomain_cmd_fixed_param)); 5990 cmd->reg_domain = reg_dmn; 5991 cmd->reg_domain_2G = regdmn2G; 5992 cmd->reg_domain_5G = regdmn5G; 5993 cmd->conformance_test_limit_2G = ctl2G; 5994 cmd->conformance_test_limit_5G = ctl5G; 5995 5996 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 5997 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 5998 cmd->conformance_test_limit_2G, 5999 cmd->conformance_test_limit_5G); 6000 6001 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6002 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6003 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6004 WMI_LOGP("%s: Failed to send pdev set regdomain command", 6005 __func__); 6006 wmi_buf_free(buf); 6007 return QDF_STATUS_E_FAILURE; 6008 } 6009 6010 return QDF_STATUS_SUCCESS; 6011 } 6012 6013 /** 6014 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6015 * @param: param sent from the host side 6016 * @cmd: param to be sent to the fw side 6017 */ 6018 static inline void copy_custom_aggr_bitmap( 6019 struct set_custom_aggr_size_params *param, 6020 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6021 { 6022 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6023 param->ac); 6024 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6025 param->aggr_type); 6026 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6027 param->tx_aggr_size_disable); 6028 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6029 param->rx_aggr_size_disable); 6030 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6031 param->tx_ac_enable); 6032 } 6033 6034 /** 6035 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6036 * @wmi_handle: wmi handle 6037 * @param: pointer to hold custom aggr size params 6038 * 6039 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6040 */ 6041 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6042 wmi_unified_t wmi_handle, 6043 struct set_custom_aggr_size_params *param) 6044 { 6045 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6046 wmi_buf_t buf; 6047 int32_t len = sizeof(*cmd); 6048 6049 buf = wmi_buf_alloc(wmi_handle, len); 6050 if (!buf) 6051 return QDF_STATUS_E_FAILURE; 6052 6053 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 6054 wmi_buf_data(buf); 6055 WMITLV_SET_HDR(&cmd->tlv_header, 6056 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 6057 WMITLV_GET_STRUCT_TLVLEN( 6058 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 6059 cmd->vdev_id = param->vdev_id; 6060 cmd->tx_aggr_size = param->tx_aggr_size; 6061 cmd->rx_aggr_size = param->rx_aggr_size; 6062 copy_custom_aggr_bitmap(param, cmd); 6063 6064 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 6065 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 6066 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 6067 "tx_ac_enable=0x%X", 6068 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 6069 param->ac, param->aggr_type, param->tx_aggr_size_disable, 6070 param->rx_aggr_size_disable, param->tx_ac_enable); 6071 6072 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 6073 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6074 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 6075 WMI_LOGE("Seting custom aggregation size failed"); 6076 wmi_buf_free(buf); 6077 return QDF_STATUS_E_FAILURE; 6078 } 6079 6080 return QDF_STATUS_SUCCESS; 6081 } 6082 6083 /** 6084 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 6085 * @param wmi_handle : handle to WMI. 6086 * @param param : pointer to tx antenna param 6087 * 6088 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6089 */ 6090 6091 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6092 struct set_qdepth_thresh_params *param) 6093 { 6094 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 6095 wmi_msduq_qdepth_thresh_update *cmd_update; 6096 wmi_buf_t buf; 6097 int32_t len = 0; 6098 int i; 6099 uint8_t *buf_ptr; 6100 QDF_STATUS ret; 6101 6102 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 6103 WMI_LOGE("%s: Invalid Update Count!", __func__); 6104 return QDF_STATUS_E_INVAL; 6105 } 6106 6107 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 6108 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 6109 param->num_of_msduq_updates); 6110 buf = wmi_buf_alloc(wmi_handle, len); 6111 6112 if (!buf) 6113 return QDF_STATUS_E_NOMEM; 6114 6115 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6116 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 6117 buf_ptr; 6118 6119 WMITLV_SET_HDR(&cmd->tlv_header, 6120 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 6121 , WMITLV_GET_STRUCT_TLVLEN( 6122 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 6123 6124 cmd->pdev_id = 6125 wmi_handle->ops->convert_pdev_id_host_to_target( 6126 wmi_handle, 6127 param->pdev_id); 6128 cmd->vdev_id = param->vdev_id; 6129 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 6130 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 6131 6132 buf_ptr += sizeof( 6133 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 6134 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6135 param->num_of_msduq_updates * 6136 sizeof(wmi_msduq_qdepth_thresh_update)); 6137 buf_ptr += WMI_TLV_HDR_SIZE; 6138 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 6139 6140 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 6141 WMITLV_SET_HDR(&cmd_update->tlv_header, 6142 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 6143 WMITLV_GET_STRUCT_TLVLEN( 6144 wmi_msduq_qdepth_thresh_update)); 6145 cmd_update->tid_num = param->update_params[i].tid_num; 6146 cmd_update->msduq_update_mask = 6147 param->update_params[i].msduq_update_mask; 6148 cmd_update->qdepth_thresh_value = 6149 param->update_params[i].qdepth_thresh_value; 6150 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 6151 "mac_addr_upper4=%X, mac_addr_lower2:%X," 6152 " update mask=0x%X thresh val=0x%X", 6153 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 6154 cmd->peer_mac_address.mac_addr31to0, 6155 cmd->peer_mac_address.mac_addr47to32, 6156 cmd_update->msduq_update_mask, 6157 cmd_update->qdepth_thresh_value); 6158 cmd_update++; 6159 } 6160 6161 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 6162 cmd->vdev_id, 0); 6163 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6164 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 6165 6166 if (ret != 0) { 6167 WMI_LOGE(" %s :WMI Failed", __func__); 6168 wmi_buf_free(buf); 6169 } 6170 6171 return ret; 6172 } 6173 6174 /** 6175 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 6176 * @wmi_handle: wmi handle 6177 * @param: pointer to hold vap dscp tid map param 6178 * 6179 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6180 */ 6181 static QDF_STATUS 6182 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 6183 struct vap_dscp_tid_map_params *param) 6184 { 6185 wmi_buf_t buf; 6186 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 6187 int32_t len = sizeof(*cmd); 6188 6189 buf = wmi_buf_alloc(wmi_handle, len); 6190 if (!buf) 6191 return QDF_STATUS_E_FAILURE; 6192 6193 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 6194 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 6195 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 6196 6197 cmd->vdev_id = param->vdev_id; 6198 cmd->enable_override = 0; 6199 6200 WMI_LOGI("Setting dscp for vap id: %d", cmd->vdev_id); 6201 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 6202 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6203 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 6204 WMI_LOGE("Failed to set dscp cmd"); 6205 wmi_buf_free(buf); 6206 return QDF_STATUS_E_FAILURE; 6207 } 6208 6209 return QDF_STATUS_SUCCESS; 6210 } 6211 6212 /** 6213 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 6214 * @wmi_handle: wmi handle 6215 * @param: pointer to hold fwtest param 6216 * 6217 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6218 */ 6219 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 6220 struct set_fwtest_params *param) 6221 { 6222 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6223 wmi_buf_t buf; 6224 int32_t len = sizeof(*cmd); 6225 6226 buf = wmi_buf_alloc(wmi_handle, len); 6227 6228 if (!buf) 6229 return QDF_STATUS_E_FAILURE; 6230 6231 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 6232 WMITLV_SET_HDR(&cmd->tlv_header, 6233 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6234 WMITLV_GET_STRUCT_TLVLEN( 6235 wmi_fwtest_set_param_cmd_fixed_param)); 6236 cmd->param_id = param->arg; 6237 cmd->param_value = param->value; 6238 6239 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6240 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 6241 WMI_LOGE("Setting FW test param failed"); 6242 wmi_buf_free(buf); 6243 return QDF_STATUS_E_FAILURE; 6244 } 6245 6246 return QDF_STATUS_SUCCESS; 6247 } 6248 6249 /** 6250 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 6251 * 6252 * @param wmi_handle : handle to WMI. 6253 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6254 */ 6255 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 6256 { 6257 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 6258 wmi_buf_t buf; 6259 QDF_STATUS ret; 6260 int32_t len; 6261 6262 len = sizeof(*cmd); 6263 6264 buf = wmi_buf_alloc(wmi_handle, len); 6265 if (!buf) 6266 return QDF_STATUS_E_FAILURE; 6267 6268 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 6269 WMITLV_SET_HDR(&cmd->tlv_header, 6270 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 6271 WMITLV_GET_STRUCT_TLVLEN( 6272 wmi_pdev_dfs_disable_cmd_fixed_param)); 6273 /* Filling it with WMI_PDEV_ID_SOC for now */ 6274 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6275 wmi_handle, 6276 WMI_HOST_PDEV_ID_SOC); 6277 6278 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 6279 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6280 WMI_PDEV_DFS_DISABLE_CMDID); 6281 6282 if (ret != 0) { 6283 WMI_LOGE("Sending PDEV DFS disable cmd failed"); 6284 wmi_buf_free(buf); 6285 } 6286 6287 return ret; 6288 } 6289 6290 /** 6291 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 6292 * 6293 * @param wmi_handle : handle to WMI. 6294 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6295 */ 6296 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 6297 { 6298 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 6299 wmi_buf_t buf; 6300 QDF_STATUS ret; 6301 int32_t len; 6302 6303 len = sizeof(*cmd); 6304 6305 buf = wmi_buf_alloc(wmi_handle, len); 6306 if (!buf) 6307 return QDF_STATUS_E_FAILURE; 6308 6309 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 6310 WMITLV_SET_HDR(&cmd->tlv_header, 6311 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 6312 WMITLV_GET_STRUCT_TLVLEN( 6313 wmi_pdev_dfs_enable_cmd_fixed_param)); 6314 /* Reserved for future use */ 6315 cmd->reserved0 = 0; 6316 6317 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 6318 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6319 WMI_PDEV_DFS_ENABLE_CMDID); 6320 6321 if (ret != 0) { 6322 WMI_LOGE("Sending PDEV DFS enable cmd failed"); 6323 wmi_buf_free(buf); 6324 } 6325 6326 return ret; 6327 } 6328 6329 /** 6330 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 6331 * to fw 6332 * @wmi_handle: wmi handle 6333 * @param: pointer to hold periodic chan stats param 6334 * 6335 * Return: 0 for success or error code 6336 */ 6337 static QDF_STATUS 6338 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 6339 struct periodic_chan_stats_params *param) 6340 { 6341 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 6342 wmi_buf_t buf; 6343 QDF_STATUS ret; 6344 int32_t len; 6345 6346 len = sizeof(*cmd); 6347 6348 buf = wmi_buf_alloc(wmi_handle, len); 6349 if (!buf) 6350 return QDF_STATUS_E_FAILURE; 6351 6352 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 6353 wmi_buf_data(buf); 6354 WMITLV_SET_HDR(&cmd->tlv_header, 6355 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 6356 WMITLV_GET_STRUCT_TLVLEN( 6357 wmi_set_periodic_channel_stats_config_fixed_param)); 6358 cmd->enable = param->enable; 6359 cmd->stats_period = param->stats_period; 6360 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6361 wmi_handle, 6362 param->pdev_id); 6363 6364 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 6365 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6366 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 6367 6368 if (ret != 0) { 6369 WMI_LOGE("Sending periodic chan stats config failed"); 6370 wmi_buf_free(buf); 6371 } 6372 6373 return ret; 6374 } 6375 6376 /** 6377 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 6378 * command to fw 6379 * @wmi_handle: wmi handle 6380 * @param: pointer to hold spectral config parameter 6381 * 6382 * Return: 0 for success or error code 6383 */ 6384 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 6385 struct vdev_spectral_configure_params *param) 6386 { 6387 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 6388 wmi_buf_t buf; 6389 QDF_STATUS ret; 6390 int32_t len; 6391 6392 len = sizeof(*cmd); 6393 buf = wmi_buf_alloc(wmi_handle, len); 6394 if (!buf) 6395 return QDF_STATUS_E_FAILURE; 6396 6397 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 6398 WMITLV_SET_HDR(&cmd->tlv_header, 6399 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 6400 WMITLV_GET_STRUCT_TLVLEN( 6401 wmi_vdev_spectral_configure_cmd_fixed_param)); 6402 6403 cmd->vdev_id = param->vdev_id; 6404 cmd->spectral_scan_count = param->count; 6405 cmd->spectral_scan_period = param->period; 6406 cmd->spectral_scan_priority = param->spectral_pri; 6407 cmd->spectral_scan_fft_size = param->fft_size; 6408 cmd->spectral_scan_gc_ena = param->gc_enable; 6409 cmd->spectral_scan_restart_ena = param->restart_enable; 6410 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 6411 cmd->spectral_scan_init_delay = param->init_delay; 6412 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 6413 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 6414 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 6415 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 6416 cmd->spectral_scan_rssi_thr = param->rssi_thr; 6417 cmd->spectral_scan_pwr_format = param->pwr_format; 6418 cmd->spectral_scan_rpt_mode = param->rpt_mode; 6419 cmd->spectral_scan_bin_scale = param->bin_scale; 6420 cmd->spectral_scan_dBm_adj = param->dbm_adj; 6421 cmd->spectral_scan_chn_mask = param->chn_mask; 6422 cmd->spectral_scan_mode = param->mode; 6423 cmd->spectral_scan_center_freq = param->center_freq; 6424 /* Not used, fill with zeros */ 6425 cmd->spectral_scan_chan_freq = 0; 6426 cmd->spectral_scan_chan_width = 0; 6427 6428 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 6429 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6430 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 6431 6432 if (ret != 0) { 6433 WMI_LOGE("Sending set quiet cmd failed"); 6434 wmi_buf_free(buf); 6435 } 6436 6437 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID", 6438 __func__); 6439 6440 WMI_LOGI("vdev_id = %u", param->vdev_id); 6441 WMI_LOGI("spectral_scan_count = %u", param->count); 6442 WMI_LOGI("spectral_scan_period = %u", param->period); 6443 WMI_LOGI("spectral_scan_priority = %u", param->spectral_pri); 6444 WMI_LOGI("spectral_scan_fft_size = %u", param->fft_size); 6445 WMI_LOGI("spectral_scan_gc_ena = %u", param->gc_enable); 6446 WMI_LOGI("spectral_scan_restart_ena = %u", param->restart_enable); 6447 WMI_LOGI("spectral_scan_noise_floor_ref = %u", param->noise_floor_ref); 6448 WMI_LOGI("spectral_scan_init_delay = %u", param->init_delay); 6449 WMI_LOGI("spectral_scan_nb_tone_thr = %u", param->nb_tone_thr); 6450 WMI_LOGI("spectral_scan_str_bin_thr = %u", param->str_bin_thr); 6451 WMI_LOGI("spectral_scan_wb_rpt_mode = %u", param->wb_rpt_mode); 6452 WMI_LOGI("spectral_scan_rssi_rpt_mode = %u", param->rssi_rpt_mode); 6453 WMI_LOGI("spectral_scan_rssi_thr = %u", param->rssi_thr); 6454 WMI_LOGI("spectral_scan_pwr_format = %u", param->pwr_format); 6455 WMI_LOGI("spectral_scan_rpt_mode = %u", param->rpt_mode); 6456 WMI_LOGI("spectral_scan_bin_scale = %u", param->bin_scale); 6457 WMI_LOGI("spectral_scan_dBm_adj = %u", param->dbm_adj); 6458 WMI_LOGI("spectral_scan_chn_mask = %u", param->chn_mask); 6459 WMI_LOGI("spectral_scan_mode = %u", param->mode); 6460 WMI_LOGI("spectral_scan_center_freq = %u", param->center_freq); 6461 WMI_LOGI("spectral_scan_chan_freq = %u", param->chan_freq); 6462 WMI_LOGI("spectral_scan_chan_width = %u", param->chan_width); 6463 WMI_LOGI("%s: Status: %d", __func__, ret); 6464 6465 return ret; 6466 } 6467 6468 /** 6469 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 6470 * command to fw 6471 * @wmi_handle: wmi handle 6472 * @param: pointer to hold spectral enable parameter 6473 * 6474 * Return: 0 for success or error code 6475 */ 6476 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 6477 struct vdev_spectral_enable_params *param) 6478 { 6479 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 6480 wmi_buf_t buf; 6481 QDF_STATUS ret; 6482 int32_t len; 6483 6484 len = sizeof(*cmd); 6485 buf = wmi_buf_alloc(wmi_handle, len); 6486 if (!buf) 6487 return QDF_STATUS_E_FAILURE; 6488 6489 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 6490 WMITLV_SET_HDR(&cmd->tlv_header, 6491 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 6492 WMITLV_GET_STRUCT_TLVLEN( 6493 wmi_vdev_spectral_enable_cmd_fixed_param)); 6494 6495 cmd->vdev_id = param->vdev_id; 6496 6497 if (param->active_valid) { 6498 cmd->trigger_cmd = param->active ? 1 : 2; 6499 /* 1: Trigger, 2: Clear Trigger */ 6500 } else { 6501 cmd->trigger_cmd = 0; /* 0: Ignore */ 6502 } 6503 6504 if (param->enabled_valid) { 6505 cmd->enable_cmd = param->enabled ? 1 : 2; 6506 /* 1: Enable 2: Disable */ 6507 } else { 6508 cmd->enable_cmd = 0; /* 0: Ignore */ 6509 } 6510 cmd->spectral_scan_mode = param->mode; 6511 6512 WMI_LOGI("vdev_id = %u", cmd->vdev_id); 6513 WMI_LOGI("trigger_cmd = %u", cmd->trigger_cmd); 6514 WMI_LOGI("enable_cmd = %u", cmd->enable_cmd); 6515 WMI_LOGI("spectral_scan_mode = %u", cmd->spectral_scan_mode); 6516 6517 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 6518 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6519 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 6520 6521 if (ret != 0) { 6522 WMI_LOGE("Sending scan enable CMD failed"); 6523 wmi_buf_free(buf); 6524 } 6525 6526 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID", __func__); 6527 6528 WMI_LOGI("%s: Status: %d", __func__, ret); 6529 6530 return ret; 6531 } 6532 6533 /** 6534 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 6535 * @param wmi_handle : handle to WMI. 6536 * @param param : pointer to hold thermal mitigation param 6537 * 6538 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6539 */ 6540 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 6541 wmi_unified_t wmi_handle, 6542 struct thermal_mitigation_params *param) 6543 { 6544 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 6545 wmi_therm_throt_level_config_info *lvl_conf = NULL; 6546 wmi_buf_t buf = NULL; 6547 uint8_t *buf_ptr = NULL; 6548 int error; 6549 int32_t len; 6550 int i; 6551 6552 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 6553 param->num_thermal_conf * 6554 sizeof(wmi_therm_throt_level_config_info); 6555 6556 buf = wmi_buf_alloc(wmi_handle, len); 6557 if (!buf) 6558 return QDF_STATUS_E_NOMEM; 6559 6560 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 6561 6562 /* init fixed params */ 6563 WMITLV_SET_HDR(tt_conf, 6564 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 6565 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 6566 6567 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6568 wmi_handle, 6569 param->pdev_id); 6570 tt_conf->enable = param->enable; 6571 tt_conf->dc = param->dc; 6572 tt_conf->dc_per_event = param->dc_per_event; 6573 tt_conf->therm_throt_levels = param->num_thermal_conf; 6574 6575 buf_ptr = (uint8_t *) ++tt_conf; 6576 /* init TLV params */ 6577 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6578 (param->num_thermal_conf * 6579 sizeof(wmi_therm_throt_level_config_info))); 6580 6581 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 6582 for (i = 0; i < param->num_thermal_conf; i++) { 6583 WMITLV_SET_HDR(&lvl_conf->tlv_header, 6584 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 6585 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 6586 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 6587 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 6588 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 6589 lvl_conf->prio = param->levelconf[i].priority; 6590 lvl_conf++; 6591 } 6592 6593 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 6594 error = wmi_unified_cmd_send(wmi_handle, buf, len, 6595 WMI_THERM_THROT_SET_CONF_CMDID); 6596 if (QDF_IS_STATUS_ERROR(error)) { 6597 wmi_buf_free(buf); 6598 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 6599 } 6600 6601 return error; 6602 } 6603 6604 /** 6605 * send_coex_config_cmd_tlv() - send coex config command to fw 6606 * @wmi_handle: wmi handle 6607 * @param: pointer to coex config param 6608 * 6609 * Return: 0 for success or error code 6610 */ 6611 static QDF_STATUS 6612 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 6613 struct coex_config_params *param) 6614 { 6615 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 6616 wmi_buf_t buf; 6617 QDF_STATUS ret; 6618 int32_t len; 6619 6620 len = sizeof(*cmd); 6621 buf = wmi_buf_alloc(wmi_handle, len); 6622 if (!buf) 6623 return QDF_STATUS_E_FAILURE; 6624 6625 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 6626 WMITLV_SET_HDR(&cmd->tlv_header, 6627 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 6628 WMITLV_GET_STRUCT_TLVLEN( 6629 WMI_COEX_CONFIG_CMD_fixed_param)); 6630 6631 cmd->vdev_id = param->vdev_id; 6632 cmd->config_type = param->config_type; 6633 cmd->config_arg1 = param->config_arg1; 6634 cmd->config_arg2 = param->config_arg2; 6635 cmd->config_arg3 = param->config_arg3; 6636 cmd->config_arg4 = param->config_arg4; 6637 cmd->config_arg5 = param->config_arg5; 6638 cmd->config_arg6 = param->config_arg6; 6639 6640 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 6641 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6642 WMI_COEX_CONFIG_CMDID); 6643 6644 if (ret != 0) { 6645 WMI_LOGE("Sending COEX CONFIG CMD failed"); 6646 wmi_buf_free(buf); 6647 } 6648 6649 return ret; 6650 } 6651 6652 #ifdef WLAN_SUPPORT_TWT 6653 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6654 target_resource_config *tgt_res_cfg) 6655 { 6656 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 6657 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 6658 } 6659 #else 6660 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6661 target_resource_config *tgt_res_cfg) 6662 { 6663 resource_cfg->twt_ap_pdev_count = 0; 6664 resource_cfg->twt_ap_sta_count = 0; 6665 } 6666 #endif 6667 6668 static 6669 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 6670 target_resource_config *tgt_res_cfg) 6671 { 6672 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 6673 resource_cfg->num_peers = tgt_res_cfg->num_peers; 6674 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 6675 resource_cfg->num_offload_reorder_buffs = 6676 tgt_res_cfg->num_offload_reorder_buffs; 6677 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 6678 resource_cfg->num_tids = tgt_res_cfg->num_tids; 6679 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 6680 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 6681 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 6682 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 6683 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 6684 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 6685 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 6686 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 6687 resource_cfg->scan_max_pending_req = 6688 tgt_res_cfg->scan_max_pending_req; 6689 resource_cfg->bmiss_offload_max_vdev = 6690 tgt_res_cfg->bmiss_offload_max_vdev; 6691 resource_cfg->roam_offload_max_vdev = 6692 tgt_res_cfg->roam_offload_max_vdev; 6693 resource_cfg->roam_offload_max_ap_profiles = 6694 tgt_res_cfg->roam_offload_max_ap_profiles; 6695 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 6696 resource_cfg->num_mcast_table_elems = 6697 tgt_res_cfg->num_mcast_table_elems; 6698 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 6699 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 6700 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 6701 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 6702 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 6703 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 6704 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 6705 resource_cfg->vow_config = tgt_res_cfg->vow_config; 6706 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 6707 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 6708 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 6709 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 6710 resource_cfg->num_tdls_conn_table_entries = 6711 tgt_res_cfg->num_tdls_conn_table_entries; 6712 resource_cfg->beacon_tx_offload_max_vdev = 6713 tgt_res_cfg->beacon_tx_offload_max_vdev; 6714 resource_cfg->num_multicast_filter_entries = 6715 tgt_res_cfg->num_multicast_filter_entries; 6716 resource_cfg->num_wow_filters = 6717 tgt_res_cfg->num_wow_filters; 6718 resource_cfg->num_keep_alive_pattern = 6719 tgt_res_cfg->num_keep_alive_pattern; 6720 resource_cfg->keep_alive_pattern_size = 6721 tgt_res_cfg->keep_alive_pattern_size; 6722 resource_cfg->max_tdls_concurrent_sleep_sta = 6723 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 6724 resource_cfg->max_tdls_concurrent_buffer_sta = 6725 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 6726 resource_cfg->wmi_send_separate = 6727 tgt_res_cfg->wmi_send_separate; 6728 resource_cfg->num_ocb_vdevs = 6729 tgt_res_cfg->num_ocb_vdevs; 6730 resource_cfg->num_ocb_channels = 6731 tgt_res_cfg->num_ocb_channels; 6732 resource_cfg->num_ocb_schedules = 6733 tgt_res_cfg->num_ocb_schedules; 6734 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 6735 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 6736 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 6737 resource_cfg->max_num_dbs_scan_duty_cycle = 6738 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 6739 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 6740 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 6741 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 6742 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 6743 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 6744 if (tgt_res_cfg->atf_config) 6745 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 6746 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 6747 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 6748 resource_cfg->flag1, 1); 6749 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 6750 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 6751 resource_cfg->flag1, 1); 6752 if (tgt_res_cfg->cce_disable) 6753 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 6754 if (tgt_res_cfg->eapol_minrate_set) { 6755 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 6756 resource_cfg->flag1, 1); 6757 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 6758 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 6759 resource_cfg->flag1, 1); 6760 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 6761 resource_cfg->flag1, 6762 tgt_res_cfg->eapol_minrate_ac_set); 6763 } 6764 } 6765 if (tgt_res_cfg->new_htt_msg_format) { 6766 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 6767 resource_cfg->flag1, 1); 6768 } 6769 6770 if (tgt_res_cfg->peer_unmap_conf_support) 6771 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 6772 resource_cfg->flag1, 1); 6773 6774 if (tgt_res_cfg->tstamp64_en) 6775 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 6776 resource_cfg->flag1, 1); 6777 6778 if (tgt_res_cfg->three_way_coex_config_legacy_en) 6779 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 6780 resource_cfg->flag1, 1); 6781 if (tgt_res_cfg->pktcapture_support) 6782 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 6783 resource_cfg->flag1, 1); 6784 6785 /* 6786 * Control padding using config param/ini of iphdr_pad_config 6787 */ 6788 if (tgt_res_cfg->iphdr_pad_config) 6789 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 6790 resource_cfg->flag1, 1); 6791 6792 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 6793 tgt_res_cfg->ipa_disable); 6794 6795 if (tgt_res_cfg->time_sync_ftm) 6796 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 6797 1); 6798 6799 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 6800 resource_cfg->peer_map_unmap_v2_support = 6801 tgt_res_cfg->peer_map_unmap_v2; 6802 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 6803 if (tgt_res_cfg->re_ul_resp) 6804 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 6805 tgt_res_cfg->re_ul_resp); 6806 6807 6808 /* 6809 * Enable ast flow override per peer 6810 */ 6811 resource_cfg->msdu_flow_override_config0 = 0; 6812 WMI_MSDU_FLOW_AST_ENABLE_SET( 6813 resource_cfg->msdu_flow_override_config0, 6814 WMI_CONFIG_MSDU_AST_INDEX_1, 6815 tgt_res_cfg->ast_1_valid_mask_enable); 6816 6817 WMI_MSDU_FLOW_AST_ENABLE_SET( 6818 resource_cfg->msdu_flow_override_config0, 6819 WMI_CONFIG_MSDU_AST_INDEX_2, 6820 tgt_res_cfg->ast_2_valid_mask_enable); 6821 6822 WMI_MSDU_FLOW_AST_ENABLE_SET( 6823 resource_cfg->msdu_flow_override_config0, 6824 WMI_CONFIG_MSDU_AST_INDEX_3, 6825 tgt_res_cfg->ast_3_valid_mask_enable); 6826 6827 /* 6828 * Enable ast flow mask and TID valid mask configurations 6829 */ 6830 resource_cfg->msdu_flow_override_config1 = 0; 6831 6832 /*Enable UDP flow for Ast index 0*/ 6833 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 6834 resource_cfg->msdu_flow_override_config1, 6835 WMI_CONFIG_MSDU_AST_INDEX_0, 6836 tgt_res_cfg->ast_0_flow_mask_enable); 6837 6838 /*Enable Non UDP flow for Ast index 1*/ 6839 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 6840 resource_cfg->msdu_flow_override_config1, 6841 WMI_CONFIG_MSDU_AST_INDEX_1, 6842 tgt_res_cfg->ast_1_flow_mask_enable); 6843 6844 /*Enable Hi-Priority flow for Ast index 2*/ 6845 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 6846 resource_cfg->msdu_flow_override_config1, 6847 WMI_CONFIG_MSDU_AST_INDEX_2, 6848 tgt_res_cfg->ast_2_flow_mask_enable); 6849 6850 /*Enable Low-Priority flow for Ast index 3*/ 6851 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 6852 resource_cfg->msdu_flow_override_config1, 6853 WMI_CONFIG_MSDU_AST_INDEX_3, 6854 tgt_res_cfg->ast_3_flow_mask_enable); 6855 6856 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 6857 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 6858 resource_cfg->msdu_flow_override_config1, 6859 tgt_res_cfg->ast_tid_high_mask_enable); 6860 6861 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 6862 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 6863 resource_cfg->msdu_flow_override_config1, 6864 tgt_res_cfg->ast_tid_low_mask_enable); 6865 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 6866 resource_cfg->host_service_flags, 6867 tgt_res_cfg->nan_separate_iface_support); 6868 6869 } 6870 6871 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 6872 * @wmi_handle: pointer to wmi handle 6873 * @buf_ptr: pointer to current position in init command buffer 6874 * @len: pointer to length. This will be updated with current length of cmd 6875 * @param: point host parameters for init command 6876 * 6877 * Return: Updated pointer of buf_ptr. 6878 */ 6879 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 6880 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 6881 { 6882 uint16_t idx; 6883 6884 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 6885 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 6886 wmi_pdev_band_to_mac *band_to_mac; 6887 6888 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 6889 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 6890 sizeof(wmi_resource_config) + 6891 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 6892 sizeof(wlan_host_memory_chunk))); 6893 6894 WMITLV_SET_HDR(&hw_mode->tlv_header, 6895 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 6896 (WMITLV_GET_STRUCT_TLVLEN 6897 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 6898 6899 hw_mode->hw_mode_index = param->hw_mode_id; 6900 hw_mode->num_band_to_mac = param->num_band_to_mac; 6901 6902 buf_ptr = (uint8_t *) (hw_mode + 1); 6903 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 6904 WMI_TLV_HDR_SIZE); 6905 for (idx = 0; idx < param->num_band_to_mac; idx++) { 6906 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 6907 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 6908 WMITLV_GET_STRUCT_TLVLEN 6909 (wmi_pdev_band_to_mac)); 6910 band_to_mac[idx].pdev_id = 6911 wmi_handle->ops->convert_pdev_id_host_to_target( 6912 wmi_handle, 6913 param->band_to_mac[idx].pdev_id); 6914 band_to_mac[idx].start_freq = 6915 param->band_to_mac[idx].start_freq; 6916 band_to_mac[idx].end_freq = 6917 param->band_to_mac[idx].end_freq; 6918 } 6919 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 6920 (param->num_band_to_mac * 6921 sizeof(wmi_pdev_band_to_mac)) + 6922 WMI_TLV_HDR_SIZE; 6923 6924 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6925 (param->num_band_to_mac * 6926 sizeof(wmi_pdev_band_to_mac))); 6927 } 6928 6929 return buf_ptr; 6930 } 6931 6932 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 6933 wmi_init_cmd_fixed_param *cmd) 6934 { 6935 int num_whitelist; 6936 wmi_abi_version my_vers; 6937 6938 num_whitelist = sizeof(version_whitelist) / 6939 sizeof(wmi_whitelist_version_info); 6940 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 6941 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 6942 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 6943 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 6944 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 6945 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 6946 6947 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 6948 &my_vers, 6949 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 6950 &cmd->host_abi_vers); 6951 6952 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 6953 __func__, 6954 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 6955 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 6956 cmd->host_abi_vers.abi_version_ns_0, 6957 cmd->host_abi_vers.abi_version_ns_1, 6958 cmd->host_abi_vers.abi_version_ns_2, 6959 cmd->host_abi_vers.abi_version_ns_3); 6960 6961 /* Save version sent from host - 6962 * Will be used to check ready event 6963 */ 6964 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 6965 sizeof(wmi_abi_version)); 6966 } 6967 6968 /* 6969 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 6970 * @wmi_handle: Pointer to WMi handle 6971 * @ie_data: Pointer for ie data 6972 * 6973 * This function sends action frame tb ppdu cfg to FW 6974 * 6975 * Return: QDF_STATUS_SUCCESS for success otherwise failure 6976 * 6977 */ 6978 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 6979 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 6980 { 6981 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 6982 wmi_buf_t buf; 6983 uint8_t *buf_ptr; 6984 uint32_t len, frm_len_aligned; 6985 QDF_STATUS ret; 6986 6987 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 6988 /* Allocate memory for the WMI command */ 6989 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 6990 6991 buf = wmi_buf_alloc(wmi_handle, len); 6992 if (!buf) 6993 return QDF_STATUS_E_NOMEM; 6994 6995 buf_ptr = wmi_buf_data(buf); 6996 qdf_mem_zero(buf_ptr, len); 6997 6998 /* Populate the WMI command */ 6999 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 7000 7001 WMITLV_SET_HDR(&cmd->tlv_header, 7002 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 7003 WMITLV_GET_STRUCT_TLVLEN( 7004 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 7005 cmd->enable = cfg_msg->cfg; 7006 cmd->data_len = cfg_msg->frm_len; 7007 7008 buf_ptr += sizeof(*cmd); 7009 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 7010 buf_ptr += WMI_TLV_HDR_SIZE; 7011 7012 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 7013 7014 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7015 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 7016 if (QDF_IS_STATUS_ERROR(ret)) { 7017 WMI_LOGE(FL("HE TB action frame cmnd send fail, ret %d"), ret); 7018 wmi_buf_free(buf); 7019 } 7020 7021 return ret; 7022 } 7023 7024 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7025 { 7026 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7027 wmi_service_ready_event_fixed_param *ev; 7028 7029 7030 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7031 7032 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7033 if (!ev) 7034 return QDF_STATUS_E_FAILURE; 7035 7036 /*Save fw version from service ready message */ 7037 /*This will be used while sending INIT message */ 7038 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7039 sizeof(wmi_handle->fw_abi_version)); 7040 7041 return QDF_STATUS_SUCCESS; 7042 } 7043 7044 /** 7045 * wmi_unified_save_fw_version_cmd() - save fw version 7046 * @wmi_handle: pointer to wmi handle 7047 * @res_cfg: resource config 7048 * @num_mem_chunks: no of mem chunck 7049 * @mem_chunk: pointer to mem chunck structure 7050 * 7051 * This function sends IE information to firmware 7052 * 7053 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7054 * 7055 */ 7056 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 7057 void *evt_buf) 7058 { 7059 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7060 wmi_ready_event_fixed_param *ev = NULL; 7061 7062 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7063 ev = param_buf->fixed_param; 7064 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 7065 &wmi_handle->final_abi_vers, 7066 &ev->fw_abi_vers)) { 7067 /* 7068 * Error: Our host version and the given firmware version 7069 * are incompatible. 7070 **/ 7071 WMI_LOGD("%s: Error: Incompatible WMI version." 7072 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 7073 __func__, 7074 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 7075 abi_version_0), 7076 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 7077 abi_version_0), 7078 wmi_handle->final_abi_vers.abi_version_ns_0, 7079 wmi_handle->final_abi_vers.abi_version_ns_1, 7080 wmi_handle->final_abi_vers.abi_version_ns_2, 7081 wmi_handle->final_abi_vers.abi_version_ns_3, 7082 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 7083 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 7084 ev->fw_abi_vers.abi_version_ns_0, 7085 ev->fw_abi_vers.abi_version_ns_1, 7086 ev->fw_abi_vers.abi_version_ns_2, 7087 ev->fw_abi_vers.abi_version_ns_3); 7088 7089 return QDF_STATUS_E_FAILURE; 7090 } 7091 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 7092 sizeof(wmi_abi_version)); 7093 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7094 sizeof(wmi_abi_version)); 7095 7096 return QDF_STATUS_SUCCESS; 7097 } 7098 7099 /** 7100 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 7101 * @handle: wmi handle 7102 * @event: Event received from FW 7103 * @len: Length of the event 7104 * 7105 * Enables the low frequency events and disables the high frequency 7106 * events. Bit 17 indicates if the event if low/high frequency. 7107 * 1 - high frequency, 0 - low frequency 7108 * 7109 * Return: 0 on successfully enabling/disabling the events 7110 */ 7111 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 7112 uint8_t *event, 7113 uint32_t len) 7114 { 7115 uint32_t num_of_diag_events_logs; 7116 wmi_diag_event_log_config_fixed_param *cmd; 7117 wmi_buf_t buf; 7118 uint8_t *buf_ptr; 7119 uint32_t *cmd_args, *evt_args; 7120 uint32_t buf_len, i; 7121 7122 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 7123 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 7124 7125 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 7126 7127 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 7128 if (!param_buf) { 7129 WMI_LOGE("Invalid log supported event buffer"); 7130 return QDF_STATUS_E_INVAL; 7131 } 7132 wmi_event = param_buf->fixed_param; 7133 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 7134 7135 if (num_of_diag_events_logs > 7136 param_buf->num_diag_events_logs_list) { 7137 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 7138 num_of_diag_events_logs, 7139 param_buf->num_diag_events_logs_list); 7140 return QDF_STATUS_E_INVAL; 7141 } 7142 7143 evt_args = param_buf->diag_events_logs_list; 7144 if (!evt_args) { 7145 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 7146 __func__, num_of_diag_events_logs); 7147 return QDF_STATUS_E_INVAL; 7148 } 7149 7150 WMI_LOGD("%s: num_of_diag_events_logs=%d", 7151 __func__, num_of_diag_events_logs); 7152 7153 /* Free any previous allocation */ 7154 if (wmi_handle->events_logs_list) { 7155 qdf_mem_free(wmi_handle->events_logs_list); 7156 wmi_handle->events_logs_list = NULL; 7157 } 7158 7159 if (num_of_diag_events_logs > 7160 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 7161 WMI_LOGE("%s: excess num of logs:%d", __func__, 7162 num_of_diag_events_logs); 7163 QDF_ASSERT(0); 7164 return QDF_STATUS_E_INVAL; 7165 } 7166 /* Store the event list for run time enable/disable */ 7167 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 7168 sizeof(uint32_t)); 7169 if (!wmi_handle->events_logs_list) 7170 return QDF_STATUS_E_NOMEM; 7171 7172 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 7173 7174 /* Prepare the send buffer */ 7175 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7176 (num_of_diag_events_logs * sizeof(uint32_t)); 7177 7178 buf = wmi_buf_alloc(wmi_handle, buf_len); 7179 if (!buf) { 7180 qdf_mem_free(wmi_handle->events_logs_list); 7181 wmi_handle->events_logs_list = NULL; 7182 return QDF_STATUS_E_NOMEM; 7183 } 7184 7185 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7186 buf_ptr = (uint8_t *) cmd; 7187 7188 WMITLV_SET_HDR(&cmd->tlv_header, 7189 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7190 WMITLV_GET_STRUCT_TLVLEN( 7191 wmi_diag_event_log_config_fixed_param)); 7192 7193 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 7194 7195 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7196 7197 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7198 (num_of_diag_events_logs * sizeof(uint32_t))); 7199 7200 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7201 7202 /* Populate the events */ 7203 for (i = 0; i < num_of_diag_events_logs; i++) { 7204 /* Low freq (0) - Enable (1) the event 7205 * High freq (1) - Disable (0) the event 7206 */ 7207 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 7208 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 7209 /* Set the event ID */ 7210 WMI_DIAG_ID_SET(cmd_args[i], 7211 WMI_DIAG_ID_GET(evt_args[i])); 7212 /* Set the type */ 7213 WMI_DIAG_TYPE_SET(cmd_args[i], 7214 WMI_DIAG_TYPE_GET(evt_args[i])); 7215 /* Storing the event/log list in WMI */ 7216 wmi_handle->events_logs_list[i] = evt_args[i]; 7217 } 7218 7219 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7220 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 7221 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7222 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 7223 __func__); 7224 wmi_buf_free(buf); 7225 /* Not clearing events_logs_list, though wmi cmd failed. 7226 * Host can still have this list 7227 */ 7228 return QDF_STATUS_E_INVAL; 7229 } 7230 7231 return 0; 7232 } 7233 7234 /** 7235 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 7236 * @wmi_handle: wmi handle 7237 * @start_log: Start logging related parameters 7238 * 7239 * Send the command to the FW based on which specific logging of diag 7240 * event/log id can be started/stopped 7241 * 7242 * Return: None 7243 */ 7244 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 7245 struct wmi_wifi_start_log *start_log) 7246 { 7247 wmi_diag_event_log_config_fixed_param *cmd; 7248 wmi_buf_t buf; 7249 uint8_t *buf_ptr; 7250 uint32_t len, count, log_level, i; 7251 uint32_t *cmd_args; 7252 uint32_t total_len; 7253 count = 0; 7254 7255 if (!wmi_handle->events_logs_list) { 7256 WMI_LOGD("%s: Not received event/log list from FW, yet", 7257 __func__); 7258 return QDF_STATUS_E_NOMEM; 7259 } 7260 /* total_len stores the number of events where BITS 17 and 18 are set. 7261 * i.e., events of high frequency (17) and for extended debugging (18) 7262 */ 7263 total_len = 0; 7264 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7265 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 7266 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 7267 total_len++; 7268 } 7269 7270 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7271 (total_len * sizeof(uint32_t)); 7272 7273 buf = wmi_buf_alloc(wmi_handle, len); 7274 if (!buf) 7275 return QDF_STATUS_E_NOMEM; 7276 7277 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7278 buf_ptr = (uint8_t *) cmd; 7279 7280 WMITLV_SET_HDR(&cmd->tlv_header, 7281 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7282 WMITLV_GET_STRUCT_TLVLEN( 7283 wmi_diag_event_log_config_fixed_param)); 7284 7285 cmd->num_of_diag_events_logs = total_len; 7286 7287 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7288 7289 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7290 (total_len * sizeof(uint32_t))); 7291 7292 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7293 7294 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 7295 log_level = 1; 7296 else 7297 log_level = 0; 7298 7299 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 7300 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7301 uint32_t val = wmi_handle->events_logs_list[i]; 7302 if ((WMI_DIAG_FREQUENCY_GET(val)) && 7303 (WMI_DIAG_EXT_FEATURE_GET(val))) { 7304 7305 WMI_DIAG_ID_SET(cmd_args[count], 7306 WMI_DIAG_ID_GET(val)); 7307 WMI_DIAG_TYPE_SET(cmd_args[count], 7308 WMI_DIAG_TYPE_GET(val)); 7309 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 7310 log_level); 7311 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 7312 count++; 7313 } 7314 } 7315 7316 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7317 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7318 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7319 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 7320 __func__); 7321 wmi_buf_free(buf); 7322 return QDF_STATUS_E_INVAL; 7323 } 7324 7325 return QDF_STATUS_SUCCESS; 7326 } 7327 7328 /** 7329 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 7330 * @wmi_handle: WMI handle 7331 * 7332 * This function is used to send the flush command to the FW, 7333 * that will flush the fw logs that are residue in the FW 7334 * 7335 * Return: None 7336 */ 7337 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 7338 { 7339 wmi_debug_mesg_flush_fixed_param *cmd; 7340 wmi_buf_t buf; 7341 int len = sizeof(*cmd); 7342 QDF_STATUS ret; 7343 7344 buf = wmi_buf_alloc(wmi_handle, len); 7345 if (!buf) 7346 return QDF_STATUS_E_NOMEM; 7347 7348 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 7349 WMITLV_SET_HDR(&cmd->tlv_header, 7350 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 7351 WMITLV_GET_STRUCT_TLVLEN( 7352 wmi_debug_mesg_flush_fixed_param)); 7353 cmd->reserved0 = 0; 7354 7355 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 7356 ret = wmi_unified_cmd_send(wmi_handle, 7357 buf, 7358 len, 7359 WMI_DEBUG_MESG_FLUSH_CMDID); 7360 if (QDF_IS_STATUS_ERROR(ret)) { 7361 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 7362 wmi_buf_free(buf); 7363 return QDF_STATUS_E_INVAL; 7364 } 7365 WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 7366 7367 return ret; 7368 } 7369 7370 #ifdef BIG_ENDIAN_HOST 7371 /** 7372 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 7373 * @param data_len - data length 7374 * @param data - pointer to data 7375 * 7376 * Return: QDF_STATUS - success or error status 7377 */ 7378 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7379 struct fips_params *param) 7380 { 7381 unsigned char *key_unaligned, *data_unaligned; 7382 int c; 7383 u_int8_t *key_aligned = NULL; 7384 u_int8_t *data_aligned = NULL; 7385 7386 /* Assigning unaligned space to copy the key */ 7387 key_unaligned = qdf_mem_malloc( 7388 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 7389 data_unaligned = qdf_mem_malloc( 7390 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 7391 7392 /* Checking if kmalloc is successful to allocate space */ 7393 if (!key_unaligned) 7394 return QDF_STATUS_SUCCESS; 7395 /* Checking if space is aligned */ 7396 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 7397 /* align to 4 */ 7398 key_aligned = 7399 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 7400 FIPS_ALIGN); 7401 } else { 7402 key_aligned = (u_int8_t *)key_unaligned; 7403 } 7404 7405 /* memset and copy content from key to key aligned */ 7406 OS_MEMSET(key_aligned, 0, param->key_len); 7407 OS_MEMCPY(key_aligned, param->key, param->key_len); 7408 7409 /* print a hexdump for host debug */ 7410 print_hex_dump(KERN_DEBUG, 7411 "\t Aligned and Copied Key:@@@@ ", 7412 DUMP_PREFIX_NONE, 7413 16, 1, key_aligned, param->key_len, true); 7414 7415 /* Checking if kmalloc is successful to allocate space */ 7416 if (!data_unaligned) 7417 return QDF_STATUS_SUCCESS; 7418 /* Checking of space is aligned */ 7419 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 7420 /* align to 4 */ 7421 data_aligned = 7422 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 7423 FIPS_ALIGN); 7424 } else { 7425 data_aligned = (u_int8_t *)data_unaligned; 7426 } 7427 7428 /* memset and copy content from data to data aligned */ 7429 OS_MEMSET(data_aligned, 0, param->data_len); 7430 OS_MEMCPY(data_aligned, param->data, param->data_len); 7431 7432 /* print a hexdump for host debug */ 7433 print_hex_dump(KERN_DEBUG, 7434 "\t Properly Aligned and Copied Data:@@@@ ", 7435 DUMP_PREFIX_NONE, 7436 16, 1, data_aligned, param->data_len, true); 7437 7438 /* converting to little Endian both key_aligned and 7439 * data_aligned*/ 7440 for (c = 0; c < param->key_len/4; c++) { 7441 *((u_int32_t *)key_aligned+c) = 7442 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 7443 } 7444 for (c = 0; c < param->data_len/4; c++) { 7445 *((u_int32_t *)data_aligned+c) = 7446 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 7447 } 7448 7449 /* update endian data to key and data vectors */ 7450 OS_MEMCPY(param->key, key_aligned, param->key_len); 7451 OS_MEMCPY(param->data, data_aligned, param->data_len); 7452 7453 /* clean up allocated spaces */ 7454 qdf_mem_free(key_unaligned); 7455 key_unaligned = NULL; 7456 key_aligned = NULL; 7457 7458 qdf_mem_free(data_unaligned); 7459 data_unaligned = NULL; 7460 data_aligned = NULL; 7461 7462 return QDF_STATUS_SUCCESS; 7463 } 7464 #else 7465 /** 7466 * fips_align_data_be() - DUMMY for LE platform 7467 * 7468 * Return: QDF_STATUS - success 7469 */ 7470 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7471 struct fips_params *param) 7472 { 7473 return QDF_STATUS_SUCCESS; 7474 } 7475 #endif 7476 7477 #ifdef WLAN_FEATURE_DISA 7478 /** 7479 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 7480 * @wmi_handle: wmi handle 7481 * @params: encrypt/decrypt params 7482 * 7483 * Return: QDF_STATUS_SUCCESS for success or error code 7484 */ 7485 static QDF_STATUS 7486 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 7487 struct disa_encrypt_decrypt_req_params 7488 *encrypt_decrypt_params) 7489 { 7490 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 7491 wmi_buf_t wmi_buf; 7492 uint8_t *buf_ptr; 7493 QDF_STATUS ret; 7494 uint32_t len; 7495 7496 WMI_LOGD(FL("Send encrypt decrypt cmd")); 7497 7498 len = sizeof(*cmd) + 7499 encrypt_decrypt_params->data_len + 7500 WMI_TLV_HDR_SIZE; 7501 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7502 if (!wmi_buf) 7503 return QDF_STATUS_E_NOMEM; 7504 7505 buf_ptr = wmi_buf_data(wmi_buf); 7506 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 7507 7508 WMITLV_SET_HDR(&cmd->tlv_header, 7509 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 7510 WMITLV_GET_STRUCT_TLVLEN( 7511 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 7512 7513 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 7514 cmd->key_flag = encrypt_decrypt_params->key_flag; 7515 cmd->key_idx = encrypt_decrypt_params->key_idx; 7516 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 7517 cmd->key_len = encrypt_decrypt_params->key_len; 7518 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 7519 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 7520 7521 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 7522 encrypt_decrypt_params->key_len); 7523 7524 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 7525 MAX_MAC_HEADER_LEN); 7526 7527 cmd->data_len = encrypt_decrypt_params->data_len; 7528 7529 if (cmd->data_len) { 7530 buf_ptr += sizeof(*cmd); 7531 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7532 roundup(encrypt_decrypt_params->data_len, 7533 sizeof(uint32_t))); 7534 buf_ptr += WMI_TLV_HDR_SIZE; 7535 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 7536 encrypt_decrypt_params->data_len); 7537 } 7538 7539 /* This conversion is to facilitate data to FW in little endian */ 7540 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 7541 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 7542 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 7543 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 7544 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 7545 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 7546 7547 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 7548 ret = wmi_unified_cmd_send(wmi_handle, 7549 wmi_buf, len, 7550 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 7551 if (QDF_IS_STATUS_ERROR(ret)) { 7552 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 7553 wmi_buf_free(wmi_buf); 7554 } 7555 7556 return ret; 7557 } 7558 #endif /* WLAN_FEATURE_DISA */ 7559 7560 /** 7561 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 7562 * @wmi_handle: wmi handle 7563 * @param: pointer to hold pdev fips param 7564 * 7565 * Return: 0 for success or error code 7566 */ 7567 static QDF_STATUS 7568 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 7569 struct fips_params *param) 7570 { 7571 wmi_pdev_fips_cmd_fixed_param *cmd; 7572 wmi_buf_t buf; 7573 uint8_t *buf_ptr; 7574 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 7575 QDF_STATUS retval = QDF_STATUS_SUCCESS; 7576 7577 /* Length TLV placeholder for array of bytes */ 7578 len += WMI_TLV_HDR_SIZE; 7579 if (param->data_len) 7580 len += (param->data_len*sizeof(uint8_t)); 7581 7582 /* 7583 * Data length must be multiples of 16 bytes - checked against 0xF - 7584 * and must be less than WMI_SVC_MSG_SIZE - static size of 7585 * wmi_pdev_fips_cmd structure 7586 */ 7587 7588 /* do sanity on the input */ 7589 if (!(((param->data_len & 0xF) == 0) && 7590 ((param->data_len > 0) && 7591 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 7592 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 7593 return QDF_STATUS_E_INVAL; 7594 } 7595 7596 buf = wmi_buf_alloc(wmi_handle, len); 7597 if (!buf) 7598 return QDF_STATUS_E_FAILURE; 7599 7600 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7601 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 7602 WMITLV_SET_HDR(&cmd->tlv_header, 7603 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 7604 WMITLV_GET_STRUCT_TLVLEN 7605 (wmi_pdev_fips_cmd_fixed_param)); 7606 7607 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7608 wmi_handle, 7609 param->pdev_id); 7610 if (param->key && param->data) { 7611 cmd->key_len = param->key_len; 7612 cmd->data_len = param->data_len; 7613 cmd->fips_cmd = !!(param->op); 7614 7615 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 7616 return QDF_STATUS_E_FAILURE; 7617 7618 qdf_mem_copy(cmd->key, param->key, param->key_len); 7619 7620 if (param->mode == FIPS_ENGINE_AES_CTR || 7621 param->mode == FIPS_ENGINE_AES_MIC) { 7622 cmd->mode = param->mode; 7623 } else { 7624 cmd->mode = FIPS_ENGINE_AES_CTR; 7625 } 7626 qdf_print("Key len = %d, Data len = %d", 7627 cmd->key_len, cmd->data_len); 7628 7629 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 7630 cmd->key, cmd->key_len, true); 7631 buf_ptr += sizeof(*cmd); 7632 7633 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 7634 7635 buf_ptr += WMI_TLV_HDR_SIZE; 7636 if (param->data_len) 7637 qdf_mem_copy(buf_ptr, 7638 (uint8_t *) param->data, param->data_len); 7639 7640 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 7641 16, 1, buf_ptr, cmd->data_len, true); 7642 7643 buf_ptr += param->data_len; 7644 7645 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 7646 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 7647 WMI_PDEV_FIPS_CMDID); 7648 qdf_print("%s return value %d", __func__, retval); 7649 } else { 7650 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 7651 wmi_buf_free(buf); 7652 retval = -QDF_STATUS_E_BADMSG; 7653 } 7654 7655 return retval; 7656 } 7657 7658 /** 7659 * send_fw_test_cmd_tlv() - send fw test command to fw. 7660 * @wmi_handle: wmi handle 7661 * @wmi_fwtest: fw test command 7662 * 7663 * This function sends fw test command to fw. 7664 * 7665 * Return: CDF STATUS 7666 */ 7667 static 7668 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 7669 struct set_fwtest_params *wmi_fwtest) 7670 { 7671 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7672 wmi_buf_t wmi_buf; 7673 uint16_t len; 7674 7675 len = sizeof(*cmd); 7676 7677 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7678 if (!wmi_buf) 7679 return QDF_STATUS_E_NOMEM; 7680 7681 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 7682 WMITLV_SET_HDR(&cmd->tlv_header, 7683 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7684 WMITLV_GET_STRUCT_TLVLEN( 7685 wmi_fwtest_set_param_cmd_fixed_param)); 7686 cmd->param_id = wmi_fwtest->arg; 7687 cmd->param_value = wmi_fwtest->value; 7688 7689 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7690 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7691 WMI_FWTEST_CMDID)) { 7692 WMI_LOGP("%s: failed to send fw test command", __func__); 7693 wmi_buf_free(wmi_buf); 7694 return QDF_STATUS_E_FAILURE; 7695 } 7696 7697 return QDF_STATUS_SUCCESS; 7698 } 7699 7700 /** 7701 * send_unit_test_cmd_tlv() - send unit test command to fw. 7702 * @wmi_handle: wmi handle 7703 * @wmi_utest: unit test command 7704 * 7705 * This function send unit test command to fw. 7706 * 7707 * Return: CDF STATUS 7708 */ 7709 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 7710 struct wmi_unit_test_cmd *wmi_utest) 7711 { 7712 wmi_unit_test_cmd_fixed_param *cmd; 7713 wmi_buf_t wmi_buf; 7714 uint8_t *buf_ptr; 7715 int i; 7716 uint16_t len, args_tlv_len; 7717 uint32_t *unit_test_cmd_args; 7718 7719 args_tlv_len = 7720 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 7721 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 7722 7723 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7724 if (!wmi_buf) 7725 return QDF_STATUS_E_NOMEM; 7726 7727 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 7728 buf_ptr = (uint8_t *) cmd; 7729 WMITLV_SET_HDR(&cmd->tlv_header, 7730 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 7731 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 7732 cmd->vdev_id = wmi_utest->vdev_id; 7733 cmd->module_id = wmi_utest->module_id; 7734 cmd->num_args = wmi_utest->num_args; 7735 cmd->diag_token = wmi_utest->diag_token; 7736 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 7737 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7738 (wmi_utest->num_args * sizeof(uint32_t))); 7739 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7740 WMI_LOGI("%s: VDEV ID: %d", __func__, cmd->vdev_id); 7741 WMI_LOGI("%s: MODULE ID: %d", __func__, cmd->module_id); 7742 WMI_LOGI("%s: TOKEN: %d", __func__, cmd->diag_token); 7743 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 7744 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 7745 unit_test_cmd_args[i] = wmi_utest->args[i]; 7746 WMI_LOGI("%d,", wmi_utest->args[i]); 7747 } 7748 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 7749 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 7750 WMI_UNIT_TEST_CMDID)) { 7751 WMI_LOGP("%s: failed to send unit test command", __func__); 7752 wmi_buf_free(wmi_buf); 7753 return QDF_STATUS_E_FAILURE; 7754 } 7755 7756 return QDF_STATUS_SUCCESS; 7757 } 7758 7759 /** 7760 * send_power_dbg_cmd_tlv() - send power debug commands 7761 * @wmi_handle: wmi handle 7762 * @param: wmi power debug parameter 7763 * 7764 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 7765 * 7766 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 7767 */ 7768 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 7769 struct wmi_power_dbg_params *param) 7770 { 7771 wmi_buf_t buf = NULL; 7772 QDF_STATUS status; 7773 int len, args_tlv_len; 7774 uint8_t *buf_ptr; 7775 uint8_t i; 7776 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 7777 uint32_t *cmd_args; 7778 7779 /* Prepare and send power debug cmd parameters */ 7780 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 7781 len = sizeof(*cmd) + args_tlv_len; 7782 buf = wmi_buf_alloc(wmi_handle, len); 7783 if (!buf) 7784 return QDF_STATUS_E_NOMEM; 7785 7786 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7787 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 7788 WMITLV_SET_HDR(&cmd->tlv_header, 7789 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 7790 WMITLV_GET_STRUCT_TLVLEN 7791 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 7792 7793 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7794 wmi_handle, 7795 param->pdev_id); 7796 cmd->module_id = param->module_id; 7797 cmd->num_args = param->num_args; 7798 buf_ptr += sizeof(*cmd); 7799 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7800 (param->num_args * sizeof(uint32_t))); 7801 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7802 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 7803 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 7804 cmd_args[i] = param->args[i]; 7805 WMI_LOGI("%d,", param->args[i]); 7806 } 7807 7808 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 7809 status = wmi_unified_cmd_send(wmi_handle, buf, 7810 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 7811 if (QDF_IS_STATUS_ERROR(status)) { 7812 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 7813 status); 7814 goto error; 7815 } 7816 7817 return QDF_STATUS_SUCCESS; 7818 error: 7819 wmi_buf_free(buf); 7820 7821 return status; 7822 } 7823 7824 /** 7825 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 7826 * @wmi_handle: wmi handle 7827 * @pdev_id: pdev id 7828 * 7829 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 7830 * 7831 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 7832 */ 7833 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7834 uint32_t pdev_id) 7835 { 7836 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 7837 wmi_buf_t buf; 7838 uint16_t len; 7839 QDF_STATUS ret; 7840 7841 len = sizeof(*cmd); 7842 buf = wmi_buf_alloc(wmi_handle, len); 7843 7844 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 7845 7846 if (!buf) 7847 return QDF_STATUS_E_NOMEM; 7848 7849 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 7850 wmi_buf_data(buf); 7851 7852 WMITLV_SET_HDR(&cmd->tlv_header, 7853 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 7854 WMITLV_GET_STRUCT_TLVLEN( 7855 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 7856 7857 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7858 wmi_handle, 7859 pdev_id); 7860 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 7861 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7862 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 7863 if (QDF_IS_STATUS_ERROR(ret)) { 7864 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 7865 __func__, ret, pdev_id); 7866 wmi_buf_free(buf); 7867 return QDF_STATUS_E_FAILURE; 7868 } 7869 7870 return QDF_STATUS_SUCCESS; 7871 } 7872 7873 /** 7874 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 7875 * @wmi_handle: wmi handle 7876 * @pdev_id: pdev id 7877 * 7878 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 7879 * 7880 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 7881 */ 7882 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 7883 uint32_t pdev_id) 7884 { 7885 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 7886 wmi_buf_t buf; 7887 uint16_t len; 7888 QDF_STATUS ret; 7889 7890 len = sizeof(*cmd); 7891 buf = wmi_buf_alloc(wmi_handle, len); 7892 7893 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 7894 7895 if (!buf) 7896 return QDF_STATUS_E_NOMEM; 7897 7898 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 7899 wmi_buf_data(buf); 7900 7901 WMITLV_SET_HDR(&cmd->tlv_header, 7902 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 7903 WMITLV_GET_STRUCT_TLVLEN( 7904 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 7905 7906 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7907 wmi_handle, 7908 pdev_id); 7909 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 7910 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7911 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 7912 if (QDF_IS_STATUS_ERROR(ret)) { 7913 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 7914 __func__, ret, pdev_id); 7915 wmi_buf_free(buf); 7916 return QDF_STATUS_E_FAILURE; 7917 } 7918 7919 return QDF_STATUS_SUCCESS; 7920 } 7921 7922 #ifdef QCA_SUPPORT_AGILE_DFS 7923 static 7924 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7925 struct vdev_adfs_ch_cfg_params *param) 7926 { 7927 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 7928 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 7929 wmi_buf_t buf; 7930 QDF_STATUS ret; 7931 uint16_t len; 7932 7933 len = sizeof(*cmd); 7934 buf = wmi_buf_alloc(wmi_handle, len); 7935 7936 if (!buf) { 7937 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7938 return QDF_STATUS_E_NOMEM; 7939 } 7940 7941 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 7942 wmi_buf_data(buf); 7943 7944 WMITLV_SET_HDR(&cmd->tlv_header, 7945 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 7946 WMITLV_GET_STRUCT_TLVLEN 7947 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 7948 7949 cmd->vdev_id = param->vdev_id; 7950 cmd->ocac_mode = param->ocac_mode; 7951 cmd->center_freq = param->center_freq; 7952 cmd->chan_freq = param->chan_freq; 7953 cmd->chan_width = param->chan_width; 7954 cmd->min_duration_ms = param->min_duration_ms; 7955 cmd->max_duration_ms = param->max_duration_ms; 7956 WMI_LOGD("%s:cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 7957 __func__, cmd->vdev_id, cmd->ocac_mode, 7958 cmd->center_freq); 7959 7960 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 7961 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7962 WMI_VDEV_ADFS_CH_CFG_CMDID); 7963 7964 if (QDF_IS_STATUS_ERROR(ret)) { 7965 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", 7966 __func__, ret); 7967 wmi_buf_free(buf); 7968 return QDF_STATUS_E_FAILURE; 7969 } 7970 7971 return QDF_STATUS_SUCCESS; 7972 } 7973 7974 static 7975 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 7976 struct vdev_adfs_abort_params *param) 7977 { 7978 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 7979 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 7980 wmi_buf_t buf; 7981 QDF_STATUS ret; 7982 uint16_t len; 7983 7984 len = sizeof(*cmd); 7985 buf = wmi_buf_alloc(wmi_handle, len); 7986 7987 if (!buf) { 7988 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 7989 return QDF_STATUS_E_NOMEM; 7990 } 7991 7992 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 7993 wmi_buf_data(buf); 7994 7995 WMITLV_SET_HDR 7996 (&cmd->tlv_header, 7997 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 7998 WMITLV_GET_STRUCT_TLVLEN 7999 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 8000 8001 cmd->vdev_id = param->vdev_id; 8002 8003 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 8004 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8005 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 8006 8007 if (QDF_IS_STATUS_ERROR(ret)) { 8008 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", 8009 __func__, ret); 8010 wmi_buf_free(buf); 8011 return QDF_STATUS_E_FAILURE; 8012 } 8013 8014 return QDF_STATUS_SUCCESS; 8015 } 8016 #endif 8017 8018 /** 8019 * init_cmd_send_tlv() - send initialization cmd to fw 8020 * @wmi_handle: wmi handle 8021 * @param param: pointer to wmi init param 8022 * 8023 * Return: QDF_STATUS_SUCCESS for success or error code 8024 */ 8025 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 8026 struct wmi_init_cmd_param *param) 8027 { 8028 wmi_buf_t buf; 8029 wmi_init_cmd_fixed_param *cmd; 8030 uint8_t *buf_ptr; 8031 wmi_resource_config *resource_cfg; 8032 wlan_host_memory_chunk *host_mem_chunks; 8033 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 8034 uint16_t idx; 8035 int len; 8036 QDF_STATUS ret; 8037 8038 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 8039 WMI_TLV_HDR_SIZE; 8040 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 8041 8042 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 8043 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 8044 WMI_TLV_HDR_SIZE + 8045 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 8046 8047 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 8048 if (!buf) 8049 return QDF_STATUS_E_FAILURE; 8050 8051 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8052 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 8053 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 8054 8055 host_mem_chunks = (wlan_host_memory_chunk *) 8056 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 8057 + WMI_TLV_HDR_SIZE); 8058 8059 WMITLV_SET_HDR(&cmd->tlv_header, 8060 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 8061 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 8062 8063 wmi_copy_resource_config(resource_cfg, param->res_cfg); 8064 WMITLV_SET_HDR(&resource_cfg->tlv_header, 8065 WMITLV_TAG_STRUC_wmi_resource_config, 8066 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 8067 8068 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 8069 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 8070 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 8071 WMITLV_GET_STRUCT_TLVLEN 8072 (wlan_host_memory_chunk)); 8073 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 8074 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 8075 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 8076 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 8077 "chunk %d len %d requested ,ptr 0x%x ", 8078 idx, host_mem_chunks[idx].size, 8079 host_mem_chunks[idx].ptr); 8080 } 8081 cmd->num_host_mem_chunks = param->num_mem_chunks; 8082 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 8083 8084 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 8085 WMITLV_TAG_ARRAY_STRUC, 8086 (sizeof(wlan_host_memory_chunk) * 8087 param->num_mem_chunks)); 8088 8089 /* Fill hw mode id config */ 8090 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 8091 8092 /* Fill fw_abi_vers */ 8093 copy_fw_abi_version_tlv(wmi_handle, cmd); 8094 8095 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 8096 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 8097 if (QDF_IS_STATUS_ERROR(ret)) { 8098 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 8099 ret); 8100 wmi_buf_free(buf); 8101 } 8102 8103 return ret; 8104 8105 } 8106 8107 /** 8108 * send_addba_send_cmd_tlv() - send addba send command to fw 8109 * @wmi_handle: wmi handle 8110 * @param: pointer to delba send params 8111 * @macaddr: peer mac address 8112 * 8113 * Send WMI_ADDBA_SEND_CMDID command to firmware 8114 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8115 */ 8116 static QDF_STATUS 8117 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 8118 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8119 struct addba_send_params *param) 8120 { 8121 wmi_addba_send_cmd_fixed_param *cmd; 8122 wmi_buf_t buf; 8123 uint16_t len; 8124 QDF_STATUS ret; 8125 8126 len = sizeof(*cmd); 8127 8128 buf = wmi_buf_alloc(wmi_handle, len); 8129 if (!buf) 8130 return QDF_STATUS_E_NOMEM; 8131 8132 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 8133 8134 WMITLV_SET_HDR(&cmd->tlv_header, 8135 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 8136 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 8137 8138 cmd->vdev_id = param->vdev_id; 8139 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8140 cmd->tid = param->tidno; 8141 cmd->buffersize = param->buffersize; 8142 8143 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 8144 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 8145 if (QDF_IS_STATUS_ERROR(ret)) { 8146 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8147 wmi_buf_free(buf); 8148 return QDF_STATUS_E_FAILURE; 8149 } 8150 8151 return QDF_STATUS_SUCCESS; 8152 } 8153 8154 /** 8155 * send_delba_send_cmd_tlv() - send delba send command to fw 8156 * @wmi_handle: wmi handle 8157 * @param: pointer to delba send params 8158 * @macaddr: peer mac address 8159 * 8160 * Send WMI_DELBA_SEND_CMDID command to firmware 8161 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8162 */ 8163 static QDF_STATUS 8164 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 8165 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8166 struct delba_send_params *param) 8167 { 8168 wmi_delba_send_cmd_fixed_param *cmd; 8169 wmi_buf_t buf; 8170 uint16_t len; 8171 QDF_STATUS ret; 8172 8173 len = sizeof(*cmd); 8174 8175 buf = wmi_buf_alloc(wmi_handle, len); 8176 if (!buf) 8177 return QDF_STATUS_E_NOMEM; 8178 8179 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 8180 8181 WMITLV_SET_HDR(&cmd->tlv_header, 8182 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 8183 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 8184 8185 cmd->vdev_id = param->vdev_id; 8186 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8187 cmd->tid = param->tidno; 8188 cmd->initiator = param->initiator; 8189 cmd->reasoncode = param->reasoncode; 8190 8191 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 8192 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 8193 if (QDF_IS_STATUS_ERROR(ret)) { 8194 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8195 wmi_buf_free(buf); 8196 return QDF_STATUS_E_FAILURE; 8197 } 8198 8199 return QDF_STATUS_SUCCESS; 8200 } 8201 8202 /** 8203 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 8204 * to fw 8205 * @wmi_handle: wmi handle 8206 * @param: pointer to addba clearresp params 8207 * @macaddr: peer mac address 8208 * Return: 0 for success or error code 8209 */ 8210 static QDF_STATUS 8211 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 8212 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8213 struct addba_clearresponse_params *param) 8214 { 8215 wmi_addba_clear_resp_cmd_fixed_param *cmd; 8216 wmi_buf_t buf; 8217 uint16_t len; 8218 QDF_STATUS ret; 8219 8220 len = sizeof(*cmd); 8221 8222 buf = wmi_buf_alloc(wmi_handle, len); 8223 if (!buf) 8224 return QDF_STATUS_E_FAILURE; 8225 8226 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 8227 8228 WMITLV_SET_HDR(&cmd->tlv_header, 8229 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 8230 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 8231 8232 cmd->vdev_id = param->vdev_id; 8233 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8234 8235 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 8236 ret = wmi_unified_cmd_send(wmi_handle, 8237 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 8238 if (QDF_IS_STATUS_ERROR(ret)) { 8239 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8240 wmi_buf_free(buf); 8241 return QDF_STATUS_E_FAILURE; 8242 } 8243 8244 return QDF_STATUS_SUCCESS; 8245 } 8246 8247 #ifdef OBSS_PD 8248 /** 8249 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 8250 * def thresh to fw 8251 * @wmi_handle: wmi handle 8252 * @thresh: pointer to obss_spatial_reuse_def_thresh 8253 * 8254 * Return: QDF_STATUS_SUCCESS for success or error code 8255 */ 8256 static 8257 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 8258 wmi_unified_t wmi_handle, 8259 struct wmi_host_obss_spatial_reuse_set_def_thresh 8260 *thresh) 8261 { 8262 wmi_buf_t buf; 8263 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 8264 QDF_STATUS ret; 8265 uint32_t cmd_len; 8266 uint32_t tlv_len; 8267 8268 cmd_len = sizeof(*cmd); 8269 8270 buf = wmi_buf_alloc(wmi_handle, cmd_len); 8271 if (!buf) 8272 return QDF_STATUS_E_NOMEM; 8273 8274 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 8275 wmi_buf_data(buf); 8276 8277 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 8278 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 8279 8280 WMITLV_SET_HDR(&cmd->tlv_header, 8281 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 8282 tlv_len); 8283 8284 cmd->obss_min = thresh->obss_min; 8285 cmd->obss_max = thresh->obss_max; 8286 cmd->vdev_type = thresh->vdev_type; 8287 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 8288 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 8289 if (QDF_IS_STATUS_ERROR(ret)) 8290 wmi_buf_free(buf); 8291 8292 return ret; 8293 } 8294 8295 /** 8296 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 8297 * @wmi_handle: wmi handle 8298 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 8299 * 8300 * Return: QDF_STATUS_SUCCESS for success or error code 8301 */ 8302 static 8303 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 8304 struct wmi_host_obss_spatial_reuse_set_param 8305 *obss_spatial_reuse_param) 8306 { 8307 wmi_buf_t buf; 8308 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 8309 QDF_STATUS ret; 8310 uint32_t len; 8311 8312 len = sizeof(*cmd); 8313 8314 buf = wmi_buf_alloc(wmi_handle, len); 8315 if (!buf) 8316 return QDF_STATUS_E_FAILURE; 8317 8318 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 8319 WMITLV_SET_HDR(&cmd->tlv_header, 8320 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 8321 WMITLV_GET_STRUCT_TLVLEN 8322 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 8323 8324 cmd->enable = obss_spatial_reuse_param->enable; 8325 cmd->obss_min = obss_spatial_reuse_param->obss_min; 8326 cmd->obss_max = obss_spatial_reuse_param->obss_max; 8327 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 8328 8329 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8330 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 8331 8332 if (QDF_IS_STATUS_ERROR(ret)) { 8333 WMI_LOGE( 8334 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 8335 ret); 8336 wmi_buf_free(buf); 8337 } 8338 8339 return ret; 8340 } 8341 #endif 8342 8343 #ifdef QCA_SUPPORT_CP_STATS 8344 /** 8345 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 8346 * @wmi_handle: wma handle 8347 * @evt_buf: event buffer 8348 * @out_buff: buffer to populated after stats extraction 8349 * 8350 * Return: status of operation 8351 */ 8352 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 8353 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 8354 { 8355 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 8356 wmi_congestion_stats *congestion_stats; 8357 8358 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 8359 congestion_stats = param_buf->congestion_stats; 8360 if (!congestion_stats) { 8361 WMI_LOGD("%s: no cca stats in event buffer", __func__); 8362 return QDF_STATUS_E_INVAL; 8363 } 8364 8365 out_buff->vdev_id = congestion_stats->vdev_id; 8366 out_buff->congestion = congestion_stats->congestion; 8367 8368 WMI_LOGD("%s: cca stats event processed", __func__); 8369 return QDF_STATUS_SUCCESS; 8370 } 8371 #endif /* QCA_SUPPORT_CP_STATS */ 8372 8373 /** 8374 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 8375 * event 8376 * @wmi_handle: wmi handle 8377 * @param evt_buf: pointer to event buffer 8378 * @param param: Pointer to hold peer ctl data 8379 * 8380 * Return: QDF_STATUS_SUCCESS for success or error code 8381 */ 8382 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 8383 wmi_unified_t wmi_handle, 8384 void *evt_buf, 8385 struct wmi_host_pdev_ctl_failsafe_event *param) 8386 { 8387 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 8388 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 8389 8390 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 8391 if (!param_buf) { 8392 WMI_LOGE("Invalid ctl_failsafe event buffer"); 8393 return QDF_STATUS_E_INVAL; 8394 } 8395 8396 fix_param = param_buf->fixed_param; 8397 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 8398 8399 return QDF_STATUS_SUCCESS; 8400 } 8401 8402 /** 8403 * save_service_bitmap_tlv() - save service bitmap 8404 * @wmi_handle: wmi handle 8405 * @param evt_buf: pointer to event buffer 8406 * @param bitmap_buf: bitmap buffer, for converged legacy support 8407 * 8408 * Return: QDF_STATUS 8409 */ 8410 static 8411 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8412 void *bitmap_buf) 8413 { 8414 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8415 struct wmi_soc *soc = wmi_handle->soc; 8416 8417 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8418 8419 /* If it is already allocated, use that buffer. This can happen 8420 * during target stop/start scenarios where host allocation is skipped. 8421 */ 8422 if (!soc->wmi_service_bitmap) { 8423 soc->wmi_service_bitmap = 8424 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 8425 if (!soc->wmi_service_bitmap) 8426 return QDF_STATUS_E_NOMEM; 8427 } 8428 8429 qdf_mem_copy(soc->wmi_service_bitmap, 8430 param_buf->wmi_service_bitmap, 8431 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 8432 8433 if (bitmap_buf) 8434 qdf_mem_copy(bitmap_buf, 8435 param_buf->wmi_service_bitmap, 8436 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 8437 8438 return QDF_STATUS_SUCCESS; 8439 } 8440 8441 /** 8442 * save_ext_service_bitmap_tlv() - save extendend service bitmap 8443 * @wmi_handle: wmi handle 8444 * @param evt_buf: pointer to event buffer 8445 * @param bitmap_buf: bitmap buffer, for converged legacy support 8446 * 8447 * Return: QDF_STATUS 8448 */ 8449 static 8450 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8451 void *bitmap_buf) 8452 { 8453 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 8454 wmi_service_available_event_fixed_param *ev; 8455 struct wmi_soc *soc = wmi_handle->soc; 8456 8457 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 8458 8459 ev = param_buf->fixed_param; 8460 8461 /* If it is already allocated, use that buffer. This can happen 8462 * during target stop/start scenarios where host allocation is skipped. 8463 */ 8464 if (!soc->wmi_ext_service_bitmap) { 8465 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 8466 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 8467 if (!soc->wmi_ext_service_bitmap) 8468 return QDF_STATUS_E_NOMEM; 8469 } 8470 8471 qdf_mem_copy(soc->wmi_ext_service_bitmap, 8472 ev->wmi_service_segment_bitmap, 8473 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 8474 8475 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 8476 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 8477 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 8478 8479 if (bitmap_buf) 8480 qdf_mem_copy(bitmap_buf, 8481 soc->wmi_ext_service_bitmap, 8482 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 8483 8484 return QDF_STATUS_SUCCESS; 8485 } 8486 /** 8487 * is_service_enabled_tlv() - Check if service enabled 8488 * @param wmi_handle: wmi handle 8489 * @param service_id: service identifier 8490 * 8491 * Return: 1 enabled, 0 disabled 8492 */ 8493 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 8494 uint32_t service_id) 8495 { 8496 struct wmi_soc *soc = wmi_handle->soc; 8497 8498 if (!soc->wmi_service_bitmap) { 8499 WMI_LOGE("WMI service bit map is not saved yet"); 8500 return false; 8501 } 8502 8503 /* if wmi_service_enabled was received with extended bitmap, 8504 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 8505 */ 8506 if (soc->wmi_ext_service_bitmap) 8507 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 8508 soc->wmi_ext_service_bitmap, 8509 service_id); 8510 8511 if (service_id >= WMI_MAX_SERVICE) { 8512 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 8513 service_id); 8514 return false; 8515 } 8516 8517 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 8518 service_id); 8519 } 8520 8521 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 8522 struct wlan_psoc_target_capability_info *cap) 8523 { 8524 /* except LDPC all flags are common betwen legacy and here 8525 * also IBFEER is not defined for TLV 8526 */ 8527 cap->ht_cap_info |= ev_target_cap & ( 8528 WMI_HT_CAP_ENABLED 8529 | WMI_HT_CAP_HT20_SGI 8530 | WMI_HT_CAP_DYNAMIC_SMPS 8531 | WMI_HT_CAP_TX_STBC 8532 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 8533 | WMI_HT_CAP_RX_STBC 8534 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 8535 | WMI_HT_CAP_LDPC 8536 | WMI_HT_CAP_L_SIG_TXOP_PROT 8537 | WMI_HT_CAP_MPDU_DENSITY 8538 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 8539 | WMI_HT_CAP_HT40_SGI); 8540 if (ev_target_cap & WMI_HT_CAP_LDPC) 8541 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 8542 WMI_HOST_HT_CAP_TX_LDPC; 8543 } 8544 /** 8545 * extract_service_ready_tlv() - extract service ready event 8546 * @wmi_handle: wmi handle 8547 * @param evt_buf: pointer to received event buffer 8548 * @param cap: pointer to hold target capability information extracted from even 8549 * 8550 * Return: QDF_STATUS_SUCCESS for success or error code 8551 */ 8552 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 8553 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 8554 { 8555 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8556 wmi_service_ready_event_fixed_param *ev; 8557 8558 8559 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8560 8561 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 8562 if (!ev) { 8563 qdf_print("%s: wmi_buf_alloc failed", __func__); 8564 return QDF_STATUS_E_FAILURE; 8565 } 8566 8567 cap->phy_capability = ev->phy_capability; 8568 cap->max_frag_entry = ev->max_frag_entry; 8569 cap->num_rf_chains = ev->num_rf_chains; 8570 copy_ht_cap_info(ev->ht_cap_info, cap); 8571 cap->vht_cap_info = ev->vht_cap_info; 8572 cap->vht_supp_mcs = ev->vht_supp_mcs; 8573 cap->hw_min_tx_power = ev->hw_min_tx_power; 8574 cap->hw_max_tx_power = ev->hw_max_tx_power; 8575 cap->sys_cap_info = ev->sys_cap_info; 8576 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 8577 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 8578 cap->max_num_scan_channels = ev->max_num_scan_channels; 8579 cap->max_supported_macs = ev->max_supported_macs; 8580 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 8581 cap->txrx_chainmask = ev->txrx_chainmask; 8582 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 8583 cap->num_msdu_desc = ev->num_msdu_desc; 8584 cap->fw_version = ev->fw_build_vers; 8585 /* fw_version_1 is not available in TLV. */ 8586 cap->fw_version_1 = 0; 8587 8588 return QDF_STATUS_SUCCESS; 8589 } 8590 8591 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 8592 * to host internal WMI_HOST_REGDMN_MODE values. 8593 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 8594 * host currently. Add this in the future if required. 8595 * 11AX (Phase II) : 11ax related values are not currently 8596 * advertised separately by FW. As part of phase II regulatory bring-up, 8597 * finalize the advertisement mechanism. 8598 * @target_wireless_mode: target wireless mode received in message 8599 * 8600 * Return: returns the host internal wireless mode. 8601 */ 8602 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 8603 { 8604 8605 uint32_t wireless_modes = 0; 8606 8607 WMI_LOGD("Target wireless mode: 0x%x", target_wireless_mode); 8608 8609 if (target_wireless_mode & REGDMN_MODE_11A) 8610 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 8611 8612 if (target_wireless_mode & REGDMN_MODE_TURBO) 8613 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 8614 8615 if (target_wireless_mode & REGDMN_MODE_11B) 8616 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 8617 8618 if (target_wireless_mode & REGDMN_MODE_PUREG) 8619 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 8620 8621 if (target_wireless_mode & REGDMN_MODE_11G) 8622 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 8623 8624 if (target_wireless_mode & REGDMN_MODE_108G) 8625 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 8626 8627 if (target_wireless_mode & REGDMN_MODE_108A) 8628 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 8629 8630 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 8631 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20_2G; 8632 8633 if (target_wireless_mode & REGDMN_MODE_XR) 8634 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 8635 8636 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 8637 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 8638 8639 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 8640 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 8641 8642 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 8643 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 8644 8645 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 8646 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 8647 8648 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 8649 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 8650 8651 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 8652 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 8653 8654 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 8655 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 8656 8657 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 8658 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 8659 8660 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 8661 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 8662 8663 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 8664 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 8665 8666 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 8667 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 8668 8669 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 8670 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 8671 8672 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 8673 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 8674 8675 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 8676 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 8677 8678 return wireless_modes; 8679 } 8680 8681 /** 8682 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 8683 * @wmi_handle: wmi handle 8684 * @param evt_buf: Pointer to event buffer 8685 * @param cap: pointer to hold HAL reg capabilities 8686 * 8687 * Return: QDF_STATUS_SUCCESS for success or error code 8688 */ 8689 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 8690 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 8691 { 8692 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8693 8694 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8695 if (!param_buf || !param_buf->hal_reg_capabilities) { 8696 WMI_LOGE("%s: Invalid arguments", __func__); 8697 return QDF_STATUS_E_FAILURE; 8698 } 8699 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 8700 sizeof(uint32_t)), 8701 sizeof(struct wlan_psoc_hal_reg_capability)); 8702 8703 cap->wireless_modes = convert_wireless_modes_tlv( 8704 param_buf->hal_reg_capabilities->wireless_modes); 8705 8706 return QDF_STATUS_SUCCESS; 8707 } 8708 8709 /** 8710 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 8711 * @wmi_handle: wmi handle 8712 * @evt_buf: pointer to event buffer 8713 * 8714 * Return: Number of entries requested 8715 */ 8716 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 8717 void *evt_buf) 8718 { 8719 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8720 wmi_service_ready_event_fixed_param *ev; 8721 8722 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8723 8724 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 8725 if (!ev) { 8726 qdf_print("%s: wmi_buf_alloc failed", __func__); 8727 return 0; 8728 } 8729 8730 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 8731 WMI_LOGE("Invalid num_mem_reqs %d:%d", 8732 ev->num_mem_reqs, param_buf->num_mem_reqs); 8733 return 0; 8734 } 8735 8736 return ev->num_mem_reqs; 8737 } 8738 8739 /** 8740 * extract_host_mem_req_tlv() - Extract host memory required from 8741 * service ready event 8742 * @wmi_handle: wmi handle 8743 * @evt_buf: pointer to event buffer 8744 * @mem_reqs: pointer to host memory request structure 8745 * @num_active_peers: number of active peers for peer cache 8746 * @num_peers: number of peers 8747 * @fw_prio: FW priority 8748 * @idx: index for memory request 8749 * 8750 * Return: Host memory request parameters requested by target 8751 */ 8752 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 8753 void *evt_buf, 8754 host_mem_req *mem_reqs, 8755 uint32_t num_active_peers, 8756 uint32_t num_peers, 8757 enum wmi_fw_mem_prio fw_prio, 8758 uint16_t idx) 8759 { 8760 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8761 8762 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 8763 8764 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 8765 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 8766 mem_reqs->num_unit_info = 8767 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 8768 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 8769 mem_reqs->tgt_num_units = 0; 8770 8771 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 8772 (mem_reqs->num_unit_info & 8773 REQ_TO_HOST_FOR_CONT_MEMORY)) || 8774 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 8775 (!(mem_reqs->num_unit_info & 8776 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 8777 /* First allocate the memory that requires contiguous memory */ 8778 mem_reqs->tgt_num_units = mem_reqs->num_units; 8779 if (mem_reqs->num_unit_info) { 8780 if (mem_reqs->num_unit_info & 8781 NUM_UNITS_IS_NUM_PEERS) { 8782 /* 8783 * number of units allocated is equal to number 8784 * of peers, 1 extra for self peer on target. 8785 * this needs to be fixed, host and target can 8786 * get out of sync 8787 */ 8788 mem_reqs->tgt_num_units = num_peers + 1; 8789 } 8790 if (mem_reqs->num_unit_info & 8791 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 8792 /* 8793 * Requesting allocation of memory using 8794 * num_active_peers in qcache. if qcache is 8795 * disabled in host, then it should allocate 8796 * memory for num_peers instead of 8797 * num_active_peers. 8798 */ 8799 if (num_active_peers) 8800 mem_reqs->tgt_num_units = 8801 num_active_peers + 1; 8802 else 8803 mem_reqs->tgt_num_units = 8804 num_peers + 1; 8805 } 8806 } 8807 8808 WMI_LOGI("idx %d req %d num_units %d num_unit_info %d" 8809 "unit size %d actual units %d", 8810 idx, mem_reqs->req_id, 8811 mem_reqs->num_units, 8812 mem_reqs->num_unit_info, 8813 mem_reqs->unit_size, 8814 mem_reqs->tgt_num_units); 8815 } 8816 8817 return QDF_STATUS_SUCCESS; 8818 } 8819 8820 /** 8821 * save_fw_version_in_service_ready_tlv() - Save fw version in service 8822 * ready function 8823 * @wmi_handle: wmi handle 8824 * @param evt_buf: pointer to event buffer 8825 * 8826 * Return: QDF_STATUS_SUCCESS for success or error code 8827 */ 8828 static QDF_STATUS 8829 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 8830 { 8831 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8832 wmi_service_ready_event_fixed_param *ev; 8833 8834 8835 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8836 8837 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 8838 if (!ev) { 8839 qdf_print("%s: wmi_buf_alloc failed", __func__); 8840 return QDF_STATUS_E_FAILURE; 8841 } 8842 8843 /*Save fw version from service ready message */ 8844 /*This will be used while sending INIT message */ 8845 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8846 sizeof(wmi_handle->fw_abi_version)); 8847 8848 return QDF_STATUS_SUCCESS; 8849 } 8850 8851 /** 8852 * ready_extract_init_status_tlv() - Extract init status from ready event 8853 * @wmi_handle: wmi handle 8854 * @param evt_buf: Pointer to event buffer 8855 * 8856 * Return: ready status 8857 */ 8858 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 8859 void *evt_buf) 8860 { 8861 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8862 wmi_ready_event_fixed_param *ev = NULL; 8863 8864 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8865 ev = param_buf->fixed_param; 8866 8867 qdf_print("%s:%d", __func__, ev->status); 8868 8869 return ev->status; 8870 } 8871 8872 /** 8873 * ready_extract_mac_addr_tlv() - extract mac address from ready event 8874 * @wmi_handle: wmi handle 8875 * @param evt_buf: pointer to event buffer 8876 * @param macaddr: Pointer to hold MAC address 8877 * 8878 * Return: QDF_STATUS_SUCCESS for success or error code 8879 */ 8880 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 8881 void *evt_buf, uint8_t *macaddr) 8882 { 8883 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8884 wmi_ready_event_fixed_param *ev = NULL; 8885 8886 8887 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8888 ev = param_buf->fixed_param; 8889 8890 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 8891 8892 return QDF_STATUS_SUCCESS; 8893 } 8894 8895 /** 8896 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 8897 * @wmi_handle: wmi handle 8898 * @param evt_buf: pointer to event buffer 8899 * @param macaddr: Pointer to hold number of MAC addresses 8900 * 8901 * Return: Pointer to addr list 8902 */ 8903 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 8904 void *evt_buf, uint8_t *num_mac) 8905 { 8906 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8907 wmi_ready_event_fixed_param *ev = NULL; 8908 8909 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8910 ev = param_buf->fixed_param; 8911 8912 *num_mac = ev->num_extra_mac_addr; 8913 8914 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 8915 } 8916 8917 /** 8918 * extract_ready_params_tlv() - Extract data from ready event apart from 8919 * status, macaddr and version. 8920 * @wmi_handle: Pointer to WMI handle. 8921 * @evt_buf: Pointer to Ready event buffer. 8922 * @ev_param: Pointer to host defined struct to copy the data from event. 8923 * 8924 * Return: QDF_STATUS_SUCCESS on success. 8925 */ 8926 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 8927 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 8928 { 8929 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8930 wmi_ready_event_fixed_param *ev = NULL; 8931 8932 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8933 ev = param_buf->fixed_param; 8934 8935 ev_param->status = ev->status; 8936 ev_param->num_dscp_table = ev->num_dscp_table; 8937 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 8938 ev_param->num_total_peer = ev->num_total_peers; 8939 ev_param->num_extra_peer = ev->num_extra_peers; 8940 /* Agile_capability in ready event is supported in TLV target, 8941 * as per aDFS FR 8942 */ 8943 ev_param->max_ast_index = ev->max_ast_index; 8944 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 8945 ev_param->agile_capability = 1; 8946 8947 return QDF_STATUS_SUCCESS; 8948 } 8949 8950 /** 8951 * extract_dbglog_data_len_tlv() - extract debuglog data length 8952 * @wmi_handle: wmi handle 8953 * @param evt_buf: pointer to event buffer 8954 * 8955 * Return: length 8956 */ 8957 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 8958 void *evt_buf, uint32_t *len) 8959 { 8960 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 8961 8962 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 8963 8964 *len = param_buf->num_bufp; 8965 8966 return param_buf->bufp; 8967 } 8968 8969 8970 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 8971 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 8972 #else 8973 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 8974 ((_status) & WMI_RXERR_DECRYPT) 8975 #endif 8976 8977 /** 8978 * extract_mgmt_rx_params_tlv() - extract management rx params from event 8979 * @wmi_handle: wmi handle 8980 * @param evt_buf: pointer to event buffer 8981 * @param hdr: Pointer to hold header 8982 * @param bufp: Pointer to hold pointer to rx param buffer 8983 * 8984 * Return: QDF_STATUS_SUCCESS for success or error code 8985 */ 8986 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 8987 void *evt_buf, struct mgmt_rx_event_params *hdr, 8988 uint8_t **bufp) 8989 { 8990 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 8991 wmi_mgmt_rx_hdr *ev_hdr = NULL; 8992 int i; 8993 8994 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 8995 if (!param_tlvs) { 8996 WMI_LOGE("Get NULL point message from FW"); 8997 return QDF_STATUS_E_INVAL; 8998 } 8999 9000 ev_hdr = param_tlvs->hdr; 9001 if (!hdr) { 9002 WMI_LOGE("Rx event is NULL"); 9003 return QDF_STATUS_E_INVAL; 9004 } 9005 9006 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 9007 WMI_LOGE("%s: RX mgmt frame decrypt error, discard it", 9008 __func__); 9009 return QDF_STATUS_E_INVAL; 9010 } 9011 9012 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9013 wmi_handle, 9014 ev_hdr->pdev_id); 9015 hdr->chan_freq = ev_hdr->chan_freq; 9016 hdr->channel = ev_hdr->channel; 9017 hdr->snr = ev_hdr->snr; 9018 hdr->rate = ev_hdr->rate; 9019 hdr->phy_mode = ev_hdr->phy_mode; 9020 hdr->buf_len = ev_hdr->buf_len; 9021 hdr->status = ev_hdr->status; 9022 hdr->flags = ev_hdr->flags; 9023 hdr->rssi = ev_hdr->rssi; 9024 hdr->tsf_delta = ev_hdr->tsf_delta; 9025 for (i = 0; i < ATH_MAX_ANTENNA; i++) 9026 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 9027 9028 *bufp = param_tlvs->bufp; 9029 9030 return QDF_STATUS_SUCCESS; 9031 } 9032 9033 /** 9034 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 9035 * @wmi_handle: wmi handle 9036 * @param evt_buf: pointer to event buffer 9037 * @param param: Pointer to hold roam param 9038 * 9039 * Return: QDF_STATUS_SUCCESS for success or error code 9040 */ 9041 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 9042 void *evt_buf, wmi_host_roam_event *param) 9043 { 9044 WMI_ROAM_EVENTID_param_tlvs *param_buf; 9045 wmi_roam_event_fixed_param *evt; 9046 9047 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 9048 if (!param_buf) { 9049 WMI_LOGE("Invalid roam event buffer"); 9050 return QDF_STATUS_E_INVAL; 9051 } 9052 9053 evt = param_buf->fixed_param; 9054 qdf_mem_zero(param, sizeof(*param)); 9055 9056 param->vdev_id = evt->vdev_id; 9057 param->reason = evt->reason; 9058 param->rssi = evt->rssi; 9059 9060 return QDF_STATUS_SUCCESS; 9061 } 9062 9063 /** 9064 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 9065 * @wmi_handle: wmi handle 9066 * @param evt_buf: pointer to event buffer 9067 * @param param: Pointer to hold vdev scan param 9068 * 9069 * Return: QDF_STATUS_SUCCESS for success or error code 9070 */ 9071 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 9072 void *evt_buf, struct scan_event *param) 9073 { 9074 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 9075 wmi_scan_event_fixed_param *evt = NULL; 9076 9077 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 9078 evt = param_buf->fixed_param; 9079 9080 qdf_mem_zero(param, sizeof(*param)); 9081 9082 switch (evt->event) { 9083 case WMI_SCAN_EVENT_STARTED: 9084 param->type = SCAN_EVENT_TYPE_STARTED; 9085 break; 9086 case WMI_SCAN_EVENT_COMPLETED: 9087 param->type = SCAN_EVENT_TYPE_COMPLETED; 9088 break; 9089 case WMI_SCAN_EVENT_BSS_CHANNEL: 9090 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 9091 break; 9092 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 9093 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 9094 break; 9095 case WMI_SCAN_EVENT_DEQUEUED: 9096 param->type = SCAN_EVENT_TYPE_DEQUEUED; 9097 break; 9098 case WMI_SCAN_EVENT_PREEMPTED: 9099 param->type = SCAN_EVENT_TYPE_PREEMPTED; 9100 break; 9101 case WMI_SCAN_EVENT_START_FAILED: 9102 param->type = SCAN_EVENT_TYPE_START_FAILED; 9103 break; 9104 case WMI_SCAN_EVENT_RESTARTED: 9105 param->type = SCAN_EVENT_TYPE_RESTARTED; 9106 break; 9107 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 9108 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 9109 break; 9110 case WMI_SCAN_EVENT_MAX: 9111 default: 9112 param->type = SCAN_EVENT_TYPE_MAX; 9113 break; 9114 }; 9115 9116 switch (evt->reason) { 9117 case WMI_SCAN_REASON_NONE: 9118 param->reason = SCAN_REASON_NONE; 9119 break; 9120 case WMI_SCAN_REASON_COMPLETED: 9121 param->reason = SCAN_REASON_COMPLETED; 9122 break; 9123 case WMI_SCAN_REASON_CANCELLED: 9124 param->reason = SCAN_REASON_CANCELLED; 9125 break; 9126 case WMI_SCAN_REASON_PREEMPTED: 9127 param->reason = SCAN_REASON_PREEMPTED; 9128 break; 9129 case WMI_SCAN_REASON_TIMEDOUT: 9130 param->reason = SCAN_REASON_TIMEDOUT; 9131 break; 9132 case WMI_SCAN_REASON_INTERNAL_FAILURE: 9133 param->reason = SCAN_REASON_INTERNAL_FAILURE; 9134 break; 9135 case WMI_SCAN_REASON_SUSPENDED: 9136 param->reason = SCAN_REASON_SUSPENDED; 9137 break; 9138 case WMI_SCAN_REASON_DFS_VIOLATION: 9139 param->reason = SCAN_REASON_DFS_VIOLATION; 9140 break; 9141 case WMI_SCAN_REASON_MAX: 9142 param->reason = SCAN_REASON_MAX; 9143 break; 9144 default: 9145 param->reason = SCAN_REASON_MAX; 9146 break; 9147 }; 9148 9149 param->chan_freq = evt->channel_freq; 9150 param->requester = evt->requestor; 9151 param->scan_id = evt->scan_id; 9152 param->vdev_id = evt->vdev_id; 9153 param->timestamp = evt->tsf_timestamp; 9154 9155 return QDF_STATUS_SUCCESS; 9156 } 9157 9158 #ifdef FEATURE_WLAN_SCAN_PNO 9159 /** 9160 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 9161 * @wmi_handle: pointer to WMI handle 9162 * @evt_buf: pointer to WMI event buffer 9163 * @param: pointer to scan event param for NLO match 9164 * 9165 * Return: QDF_STATUS_SUCCESS for success or error code 9166 */ 9167 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 9168 void *evt_buf, 9169 struct scan_event *param) 9170 { 9171 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 9172 wmi_nlo_event *evt = param_buf->fixed_param; 9173 9174 qdf_mem_zero(param, sizeof(*param)); 9175 9176 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 9177 param->vdev_id = evt->vdev_id; 9178 9179 return QDF_STATUS_SUCCESS; 9180 } 9181 9182 /** 9183 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 9184 * @wmi_handle: pointer to WMI handle 9185 * @evt_buf: pointer to WMI event buffer 9186 * @param: pointer to scan event param for NLO complete 9187 * 9188 * Return: QDF_STATUS_SUCCESS for success or error code 9189 */ 9190 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 9191 void *evt_buf, 9192 struct scan_event *param) 9193 { 9194 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 9195 wmi_nlo_event *evt = param_buf->fixed_param; 9196 9197 qdf_mem_zero(param, sizeof(*param)); 9198 9199 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 9200 param->vdev_id = evt->vdev_id; 9201 9202 return QDF_STATUS_SUCCESS; 9203 } 9204 #endif 9205 9206 /** 9207 * extract_all_stats_counts_tlv() - extract all stats count from event 9208 * @wmi_handle: wmi handle 9209 * @param evt_buf: pointer to event buffer 9210 * @param stats_param: Pointer to hold stats count 9211 * 9212 * Return: QDF_STATUS_SUCCESS for success or error code 9213 */ 9214 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 9215 void *evt_buf, wmi_host_stats_event *stats_param) 9216 { 9217 wmi_stats_event_fixed_param *ev; 9218 wmi_per_chain_rssi_stats *rssi_event; 9219 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9220 uint64_t min_data_len; 9221 9222 qdf_mem_zero(stats_param, sizeof(*stats_param)); 9223 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9224 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9225 rssi_event = param_buf->chain_stats; 9226 if (!ev) { 9227 WMI_LOGE("%s: event fixed param NULL", __func__); 9228 return QDF_STATUS_E_FAILURE; 9229 } 9230 9231 if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) { 9232 WMI_LOGE("num_data : %u is invalid", param_buf->num_data); 9233 return QDF_STATUS_E_FAULT; 9234 } 9235 9236 switch (ev->stats_id) { 9237 case WMI_REQUEST_PEER_STAT: 9238 stats_param->stats_id |= WMI_HOST_REQUEST_PEER_STAT; 9239 break; 9240 9241 case WMI_REQUEST_AP_STAT: 9242 stats_param->stats_id |= WMI_HOST_REQUEST_AP_STAT; 9243 break; 9244 9245 case WMI_REQUEST_PDEV_STAT: 9246 stats_param->stats_id |= WMI_HOST_REQUEST_PDEV_STAT; 9247 break; 9248 9249 case WMI_REQUEST_VDEV_STAT: 9250 stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_STAT; 9251 break; 9252 9253 case WMI_REQUEST_BCNFLT_STAT: 9254 stats_param->stats_id |= WMI_HOST_REQUEST_BCNFLT_STAT; 9255 break; 9256 9257 case WMI_REQUEST_VDEV_RATE_STAT: 9258 stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_RATE_STAT; 9259 break; 9260 9261 case WMI_REQUEST_BCN_STAT: 9262 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 9263 break; 9264 case WMI_REQUEST_PEER_EXTD_STAT: 9265 stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT; 9266 break; 9267 9268 case WMI_REQUEST_PEER_EXTD2_STAT: 9269 stats_param->stats_id |= WMI_HOST_REQUEST_PEER_ADV_STATS; 9270 break; 9271 9272 default: 9273 stats_param->stats_id = 0; 9274 break; 9275 9276 } 9277 9278 /* ev->num_*_stats may cause uint32_t overflow, so use uint64_t 9279 * to save total length calculated 9280 */ 9281 min_data_len = 9282 (((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 9283 (((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 9284 (((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) + 9285 (((uint64_t)ev->num_bcnflt_stats) * 9286 sizeof(wmi_bcnfilter_stats_t)) + 9287 (((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) + 9288 (((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) + 9289 (((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) + 9290 (((uint64_t)ev->num_peer_extd_stats) * 9291 sizeof(wmi_peer_extd_stats)) + 9292 (((uint64_t)ev->num_mib_extd_stats) * 9293 sizeof(wmi_mib_extd_stats)); 9294 if (param_buf->num_data != min_data_len) { 9295 WMI_LOGE("data len: %u isn't same as calculated: %llu", 9296 param_buf->num_data, min_data_len); 9297 return QDF_STATUS_E_FAULT; 9298 } 9299 9300 stats_param->last_event = ev->last_event; 9301 stats_param->num_pdev_stats = ev->num_pdev_stats; 9302 stats_param->num_pdev_ext_stats = 0; 9303 stats_param->num_vdev_stats = ev->num_vdev_stats; 9304 stats_param->num_peer_stats = ev->num_peer_stats; 9305 stats_param->num_peer_extd_stats = ev->num_peer_extd_stats; 9306 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 9307 stats_param->num_chan_stats = ev->num_chan_stats; 9308 stats_param->num_mib_stats = ev->num_mib_stats; 9309 stats_param->num_mib_extd_stats = ev->num_mib_extd_stats; 9310 stats_param->num_bcn_stats = ev->num_bcn_stats; 9311 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9312 wmi_handle, 9313 ev->pdev_id); 9314 9315 /* if chain_stats is not populated */ 9316 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 9317 return QDF_STATUS_SUCCESS; 9318 9319 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 9320 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 9321 return QDF_STATUS_SUCCESS; 9322 9323 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 9324 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 9325 return QDF_STATUS_SUCCESS; 9326 9327 if (rssi_event->num_per_chain_rssi_stats >= 9328 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) { 9329 WMI_LOGE("num_per_chain_rssi_stats:%u is out of bounds", 9330 rssi_event->num_per_chain_rssi_stats); 9331 return QDF_STATUS_E_INVAL; 9332 } 9333 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 9334 9335 /* if peer_adv_stats is not populated */ 9336 if (!param_buf->num_peer_extd2_stats) 9337 return QDF_STATUS_SUCCESS; 9338 9339 stats_param->num_peer_adv_stats = param_buf->num_peer_extd2_stats; 9340 9341 return QDF_STATUS_SUCCESS; 9342 } 9343 9344 /** 9345 * extract_pdev_tx_stats() - extract pdev tx stats from event 9346 */ 9347 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, 9348 struct wlan_dbg_tx_stats *tx_stats) 9349 { 9350 /* Tx Stats */ 9351 tx->comp_queued = tx_stats->comp_queued; 9352 tx->comp_delivered = tx_stats->comp_delivered; 9353 tx->msdu_enqued = tx_stats->msdu_enqued; 9354 tx->mpdu_enqued = tx_stats->mpdu_enqued; 9355 tx->wmm_drop = tx_stats->wmm_drop; 9356 tx->local_enqued = tx_stats->local_enqued; 9357 tx->local_freed = tx_stats->local_freed; 9358 tx->hw_queued = tx_stats->hw_queued; 9359 tx->hw_reaped = tx_stats->hw_reaped; 9360 tx->underrun = tx_stats->underrun; 9361 tx->tx_abort = tx_stats->tx_abort; 9362 tx->mpdus_requed = tx_stats->mpdus_requed; 9363 tx->data_rc = tx_stats->data_rc; 9364 tx->self_triggers = tx_stats->self_triggers; 9365 tx->sw_retry_failure = tx_stats->sw_retry_failure; 9366 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 9367 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 9368 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 9369 tx->pdev_resets = tx_stats->pdev_resets; 9370 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 9371 tx->phy_underrun = tx_stats->phy_underrun; 9372 tx->txop_ovf = tx_stats->txop_ovf; 9373 9374 return; 9375 } 9376 9377 9378 /** 9379 * extract_pdev_rx_stats() - extract pdev rx stats from event 9380 */ 9381 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, 9382 struct wlan_dbg_rx_stats *rx_stats) 9383 { 9384 /* Rx Stats */ 9385 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 9386 rx->status_rcvd = rx_stats->status_rcvd; 9387 rx->r0_frags = rx_stats->r0_frags; 9388 rx->r1_frags = rx_stats->r1_frags; 9389 rx->r2_frags = rx_stats->r2_frags; 9390 /* Only TLV */ 9391 rx->r3_frags = 0; 9392 rx->htt_msdus = rx_stats->htt_msdus; 9393 rx->htt_mpdus = rx_stats->htt_mpdus; 9394 rx->loc_msdus = rx_stats->loc_msdus; 9395 rx->loc_mpdus = rx_stats->loc_mpdus; 9396 rx->oversize_amsdu = rx_stats->oversize_amsdu; 9397 rx->phy_errs = rx_stats->phy_errs; 9398 rx->phy_err_drop = rx_stats->phy_err_drop; 9399 rx->mpdu_errs = rx_stats->mpdu_errs; 9400 9401 return; 9402 } 9403 9404 /** 9405 * extract_pdev_stats_tlv() - extract pdev stats from event 9406 * @wmi_handle: wmi handle 9407 * @param evt_buf: pointer to event buffer 9408 * @param index: Index into pdev stats 9409 * @param pdev_stats: Pointer to hold pdev stats 9410 * 9411 * Return: QDF_STATUS_SUCCESS for success or error code 9412 */ 9413 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 9414 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 9415 { 9416 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9417 wmi_stats_event_fixed_param *ev_param; 9418 uint8_t *data; 9419 9420 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9421 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9422 9423 data = param_buf->data; 9424 9425 if (index < ev_param->num_pdev_stats) { 9426 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 9427 (index * sizeof(wmi_pdev_stats))); 9428 9429 pdev_stats->chan_nf = ev->chan_nf; 9430 pdev_stats->tx_frame_count = ev->tx_frame_count; 9431 pdev_stats->rx_frame_count = ev->rx_frame_count; 9432 pdev_stats->rx_clear_count = ev->rx_clear_count; 9433 pdev_stats->cycle_count = ev->cycle_count; 9434 pdev_stats->phy_err_count = ev->phy_err_count; 9435 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 9436 9437 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 9438 &(ev->pdev_stats.tx)); 9439 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 9440 &(ev->pdev_stats.rx)); 9441 } 9442 9443 return QDF_STATUS_SUCCESS; 9444 } 9445 9446 /** 9447 * extract_unit_test_tlv() - extract unit test data 9448 * @wmi_handle: wmi handle 9449 * @param evt_buf: pointer to event buffer 9450 * @param unit_test: pointer to hold unit test data 9451 * @param maxspace: Amount of space in evt_buf 9452 * 9453 * Return: QDF_STATUS_SUCCESS for success or error code 9454 */ 9455 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 9456 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 9457 { 9458 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 9459 wmi_unit_test_event_fixed_param *ev_param; 9460 uint32_t num_bufp; 9461 uint32_t copy_size; 9462 uint8_t *bufp; 9463 9464 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 9465 ev_param = param_buf->fixed_param; 9466 bufp = param_buf->bufp; 9467 num_bufp = param_buf->num_bufp; 9468 unit_test->vdev_id = ev_param->vdev_id; 9469 unit_test->module_id = ev_param->module_id; 9470 unit_test->diag_token = ev_param->diag_token; 9471 unit_test->flag = ev_param->flag; 9472 unit_test->payload_len = ev_param->payload_len; 9473 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d", __func__, 9474 ev_param->vdev_id, 9475 ev_param->module_id, 9476 ev_param->diag_token, 9477 ev_param->flag); 9478 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 9479 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9480 bufp, num_bufp); 9481 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 9482 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 9483 unit_test->buffer_len = copy_size; 9484 9485 return QDF_STATUS_SUCCESS; 9486 } 9487 9488 /** 9489 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 9490 * @wmi_handle: wmi handle 9491 * @param evt_buf: pointer to event buffer 9492 * @param index: Index into extended pdev stats 9493 * @param pdev_ext_stats: Pointer to hold extended pdev stats 9494 * 9495 * Return: QDF_STATUS_SUCCESS for success or error code 9496 */ 9497 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 9498 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 9499 { 9500 return QDF_STATUS_SUCCESS; 9501 } 9502 9503 /** 9504 * extract_vdev_stats_tlv() - extract vdev stats from event 9505 * @wmi_handle: wmi handle 9506 * @param evt_buf: pointer to event buffer 9507 * @param index: Index into vdev stats 9508 * @param vdev_stats: Pointer to hold vdev stats 9509 * 9510 * Return: QDF_STATUS_SUCCESS for success or error code 9511 */ 9512 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 9513 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 9514 { 9515 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9516 wmi_stats_event_fixed_param *ev_param; 9517 uint8_t *data; 9518 9519 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9520 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9521 data = (uint8_t *) param_buf->data; 9522 9523 if (index < ev_param->num_vdev_stats) { 9524 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 9525 ((ev_param->num_pdev_stats) * 9526 sizeof(wmi_pdev_stats)) + 9527 (index * sizeof(wmi_vdev_stats))); 9528 9529 vdev_stats->vdev_id = ev->vdev_id; 9530 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 9531 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 9532 9533 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 9534 sizeof(ev->tx_frm_cnt)); 9535 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 9536 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 9537 ev->multiple_retry_cnt, 9538 sizeof(ev->multiple_retry_cnt)); 9539 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 9540 sizeof(ev->fail_cnt)); 9541 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 9542 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 9543 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 9544 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 9545 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 9546 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 9547 sizeof(ev->tx_rate_history)); 9548 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 9549 sizeof(ev->bcn_rssi_history)); 9550 9551 } 9552 9553 return QDF_STATUS_SUCCESS; 9554 } 9555 9556 /** 9557 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 9558 * buffer 9559 * @wmi_handle: wmi handle 9560 * @evt_buf: pointer to event buffer 9561 * @index: Index into vdev stats 9562 * @rssi_stats: Pointer to hold rssi stats 9563 * 9564 * Return: QDF_STATUS_SUCCESS for success or error code 9565 */ 9566 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 9567 void *evt_buf, uint32_t index, 9568 struct wmi_host_per_chain_rssi_stats *rssi_stats) 9569 { 9570 uint8_t *data; 9571 wmi_rssi_stats *fw_rssi_stats; 9572 wmi_per_chain_rssi_stats *rssi_event; 9573 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9574 9575 if (!evt_buf) { 9576 WMI_LOGE("evt_buf is null"); 9577 return QDF_STATUS_E_NULL_VALUE; 9578 } 9579 9580 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9581 rssi_event = param_buf->chain_stats; 9582 9583 if (index >= rssi_event->num_per_chain_rssi_stats) { 9584 WMI_LOGE("invalid index"); 9585 return QDF_STATUS_E_INVAL; 9586 } 9587 9588 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 9589 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 9590 if (fw_rssi_stats->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 9591 return QDF_STATUS_E_INVAL; 9592 9593 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 9594 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 9595 fw_rssi_stats->rssi_avg_beacon, 9596 sizeof(fw_rssi_stats->rssi_avg_beacon)); 9597 qdf_mem_copy(rssi_stats->rssi_avg_data, 9598 fw_rssi_stats->rssi_avg_data, 9599 sizeof(fw_rssi_stats->rssi_avg_data)); 9600 qdf_mem_copy(&rssi_stats->peer_macaddr, 9601 &fw_rssi_stats->peer_macaddr, 9602 sizeof(fw_rssi_stats->peer_macaddr)); 9603 9604 return QDF_STATUS_SUCCESS; 9605 } 9606 9607 9608 9609 /** 9610 * extract_bcn_stats_tlv() - extract bcn stats from event 9611 * @wmi_handle: wmi handle 9612 * @param evt_buf: pointer to event buffer 9613 * @param index: Index into vdev stats 9614 * @param bcn_stats: Pointer to hold bcn stats 9615 * 9616 * Return: QDF_STATUS_SUCCESS for success or error code 9617 */ 9618 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 9619 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 9620 { 9621 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9622 wmi_stats_event_fixed_param *ev_param; 9623 uint8_t *data; 9624 9625 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9626 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9627 data = (uint8_t *) param_buf->data; 9628 9629 if (index < ev_param->num_bcn_stats) { 9630 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 9631 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 9632 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 9633 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 9634 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 9635 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 9636 (index * sizeof(wmi_bcn_stats))); 9637 9638 bcn_stats->vdev_id = ev->vdev_id; 9639 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 9640 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 9641 } 9642 9643 return QDF_STATUS_SUCCESS; 9644 } 9645 9646 /** 9647 * extract_peer_stats_tlv() - extract peer stats from event 9648 * @wmi_handle: wmi handle 9649 * @param evt_buf: pointer to event buffer 9650 * @param index: Index into peer stats 9651 * @param peer_stats: Pointer to hold peer stats 9652 * 9653 * Return: QDF_STATUS_SUCCESS for success or error code 9654 */ 9655 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 9656 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 9657 { 9658 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9659 wmi_stats_event_fixed_param *ev_param; 9660 uint8_t *data; 9661 9662 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9663 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9664 data = (uint8_t *) param_buf->data; 9665 9666 if (index < ev_param->num_peer_stats) { 9667 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 9668 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 9669 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 9670 (index * sizeof(wmi_peer_stats))); 9671 9672 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 9673 9674 OS_MEMCPY(&(peer_stats->peer_macaddr), 9675 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 9676 9677 peer_stats->peer_rssi = ev->peer_rssi; 9678 peer_stats->peer_tx_rate = ev->peer_tx_rate; 9679 peer_stats->peer_rx_rate = ev->peer_rx_rate; 9680 } 9681 9682 return QDF_STATUS_SUCCESS; 9683 } 9684 9685 /** 9686 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 9687 * @wmi_handle: wmi handle 9688 * @param evt_buf: pointer to event buffer 9689 * @param index: Index into bcn fault stats 9690 * @param bcnflt_stats: Pointer to hold bcn fault stats 9691 * 9692 * Return: QDF_STATUS_SUCCESS for success or error code 9693 */ 9694 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 9695 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 9696 { 9697 return QDF_STATUS_SUCCESS; 9698 } 9699 9700 /** 9701 * extract_peer_adv_stats_tlv() - extract adv peer stats from event 9702 * @wmi_handle: wmi handle 9703 * @param evt_buf: pointer to event buffer 9704 * @param index: Index into extended peer stats 9705 * @param peer_adv_stats: Pointer to hold adv peer stats 9706 * 9707 * Return: QDF_STATUS_SUCCESS for success or error code 9708 */ 9709 static QDF_STATUS extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle, 9710 void *evt_buf, 9711 struct wmi_host_peer_adv_stats 9712 *peer_adv_stats) 9713 { 9714 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9715 wmi_peer_extd2_stats *adv_stats; 9716 int i; 9717 9718 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9719 9720 adv_stats = param_buf->peer_extd2_stats; 9721 if (!adv_stats) { 9722 WMI_LOGD("%s: no peer_adv stats in event buffer", __func__); 9723 return QDF_STATUS_E_INVAL; 9724 } 9725 9726 for (i = 0; i < param_buf->num_peer_extd2_stats; i++) { 9727 WMI_MAC_ADDR_TO_CHAR_ARRAY(&adv_stats[i].peer_macaddr, 9728 peer_adv_stats[i].peer_macaddr); 9729 peer_adv_stats[i].fcs_count = adv_stats[i].rx_fcs_err; 9730 peer_adv_stats[i].rx_bytes = 9731 (uint64_t)adv_stats[i].rx_bytes_u32 << 9732 WMI_LOWER_BITS_SHIFT_32 | 9733 adv_stats[i].rx_bytes_l32; 9734 peer_adv_stats[i].rx_count = adv_stats[i].rx_mpdus; 9735 } 9736 9737 return QDF_STATUS_SUCCESS; 9738 } 9739 9740 /** 9741 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 9742 * @wmi_handle: wmi handle 9743 * @param evt_buf: pointer to event buffer 9744 * @param index: Index into extended peer stats 9745 * @param peer_extd_stats: Pointer to hold extended peer stats 9746 * 9747 * Return: QDF_STATUS_SUCCESS for success or error code 9748 */ 9749 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 9750 void *evt_buf, uint32_t index, 9751 wmi_host_peer_extd_stats *peer_extd_stats) 9752 { 9753 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9754 wmi_stats_event_fixed_param *ev_param; 9755 uint8_t *data; 9756 9757 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9758 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 9759 data = (uint8_t *)param_buf->data; 9760 if (!data) 9761 return QDF_STATUS_E_FAILURE; 9762 9763 if (index < ev_param->num_peer_extd_stats) { 9764 wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data + 9765 (ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) + 9766 (ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) + 9767 (ev_param->num_peer_stats * sizeof(wmi_peer_stats)) + 9768 (ev_param->num_bcnflt_stats * 9769 sizeof(wmi_bcnfilter_stats_t)) + 9770 (ev_param->num_chan_stats * sizeof(wmi_chan_stats)) + 9771 (ev_param->num_mib_stats * sizeof(wmi_mib_stats)) + 9772 (ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) + 9773 (index * sizeof(wmi_peer_extd_stats))); 9774 9775 qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats)); 9776 qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr, 9777 sizeof(wmi_mac_addr)); 9778 9779 peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt; 9780 } 9781 9782 return QDF_STATUS_SUCCESS; 9783 9784 } 9785 9786 /** 9787 * extract_chan_stats_tlv() - extract chan stats from event 9788 * @wmi_handle: wmi handle 9789 * @param evt_buf: pointer to event buffer 9790 * @param index: Index into chan stats 9791 * @param vdev_extd_stats: Pointer to hold chan stats 9792 * 9793 * Return: QDF_STATUS_SUCCESS for success or error code 9794 */ 9795 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 9796 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 9797 { 9798 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9799 wmi_stats_event_fixed_param *ev_param; 9800 uint8_t *data; 9801 9802 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 9803 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 9804 data = (uint8_t *) param_buf->data; 9805 9806 if (index < ev_param->num_chan_stats) { 9807 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 9808 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 9809 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 9810 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 9811 (index * sizeof(wmi_chan_stats))); 9812 9813 9814 /* Non-TLV doesn't have num_chan_stats */ 9815 chan_stats->chan_mhz = ev->chan_mhz; 9816 chan_stats->sampling_period_us = ev->sampling_period_us; 9817 chan_stats->rx_clear_count = ev->rx_clear_count; 9818 chan_stats->tx_duration_us = ev->tx_duration_us; 9819 chan_stats->rx_duration_us = ev->rx_duration_us; 9820 } 9821 9822 return QDF_STATUS_SUCCESS; 9823 } 9824 9825 #ifdef WLAN_FEATURE_MIB_STATS 9826 /** 9827 * extract_mib_stats_tlv() - extract mib stats from event 9828 * @wmi_handle: wmi handle 9829 * @param evt_buf: pointer to event buffer 9830 * @param mib_stats: pointer to hold mib stats 9831 * 9832 * Return: QDF_STATUS_SUCCESS for success or error code 9833 */ 9834 static QDF_STATUS extract_mib_stats_tlv(wmi_unified_t wmi_handle, 9835 void *evt_buf, 9836 struct mib_stats_metrics 9837 *mib_stats) 9838 { 9839 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9840 wmi_stats_event_fixed_param *ev_param; 9841 uint8_t *data; 9842 wmi_mib_stats *ev; 9843 wmi_mib_extd_stats *ev_extd; 9844 9845 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9846 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 9847 data = (uint8_t *)param_buf->data; 9848 9849 ev = (wmi_mib_stats *)(data + 9850 ev_param->num_pdev_stats * sizeof(wmi_pdev_stats) + 9851 ev_param->num_vdev_stats * sizeof(wmi_vdev_stats) + 9852 ev_param->num_peer_stats * sizeof(wmi_peer_stats) + 9853 ev_param->num_bcnflt_stats * 9854 sizeof(wmi_bcnfilter_stats_t) + 9855 ev_param->num_chan_stats * sizeof(wmi_chan_stats)); 9856 9857 qdf_mem_zero(mib_stats, sizeof(*mib_stats)); 9858 9859 mib_stats->mib_counters.tx_frags = 9860 ev->tx_mpdu_grp_frag_cnt; 9861 mib_stats->mib_counters.group_tx_frames = 9862 ev->tx_msdu_grp_frm_cnt; 9863 mib_stats->mib_counters.failed_cnt = ev->tx_msdu_fail_cnt; 9864 mib_stats->mib_counters.rx_frags = ev->rx_mpdu_frag_cnt; 9865 mib_stats->mib_counters.group_rx_frames = 9866 ev->rx_msdu_grp_frm_cnt; 9867 mib_stats->mib_counters.fcs_error_cnt = 9868 ev->rx_mpdu_fcs_err; 9869 mib_stats->mib_counters.tx_frames = 9870 ev->tx_msdu_frm_cnt; 9871 mib_stats->mib_mac_statistics.retry_cnt = 9872 ev->tx_msdu_retry_cnt; 9873 mib_stats->mib_mac_statistics.frame_dup_cnt = 9874 ev->rx_frm_dup_cnt; 9875 mib_stats->mib_mac_statistics.rts_success_cnt = 9876 ev->tx_rts_success_cnt; 9877 mib_stats->mib_mac_statistics.rts_fail_cnt = 9878 ev->tx_rts_fail_cnt; 9879 9880 mib_stats->mib_qos_counters.qos_tx_frag_cnt = 9881 ev->tx_Qos_mpdu_grp_frag_cnt; 9882 mib_stats->mib_qos_counters.qos_retry_cnt = 9883 ev->tx_Qos_msdu_retry_UP; 9884 mib_stats->mib_qos_counters.qos_failed_cnt = 9885 ev->tx_Qos_msdu_fail_UP; 9886 mib_stats->mib_qos_counters.qos_frame_dup_cnt = 9887 ev->rx_Qos_frm_dup_cnt_UP; 9888 mib_stats->mib_qos_counters.qos_rts_success_cnt = 9889 ev->tx_Qos_rts_success_cnt_UP; 9890 mib_stats->mib_qos_counters.qos_rts_fail_cnt = 9891 ev->tx_Qos_rts_fail_cnt_UP; 9892 mib_stats->mib_qos_counters.qos_rx_frag_cnt = 9893 ev->rx_Qos_mpdu_frag_cnt_UP; 9894 mib_stats->mib_qos_counters.qos_tx_frame_cnt = 9895 ev->tx_Qos_msdu_frm_cnt_UP; 9896 mib_stats->mib_qos_counters.qos_discarded_frame_cnt = 9897 ev->rx_Qos_msdu_discard_cnt_UP; 9898 mib_stats->mib_qos_counters.qos_mpdu_rx_cnt = 9899 ev->rx_Qos_mpdu_cnt; 9900 mib_stats->mib_qos_counters.qos_retries_rx_cnt = 9901 ev->rx_Qos_mpdu_retryBit_cnt; 9902 9903 mib_stats->mib_rsna_stats.tkip_icv_err = 9904 ev->rsna_TKIP_icv_err_cnt; 9905 mib_stats->mib_rsna_stats.tkip_replays = 9906 ev->rsna_TKIP_replay_err_cnt; 9907 mib_stats->mib_rsna_stats.ccmp_decrypt_err = 9908 ev->rsna_CCMP_decrypt_err_cnt; 9909 mib_stats->mib_rsna_stats.ccmp_replays = 9910 ev->rsna_CCMP_replay_err_cnt; 9911 9912 mib_stats->mib_counters_group3.tx_ampdu_cnt = 9913 ev->tx_ampdu_cnt; 9914 mib_stats->mib_counters_group3.tx_mpdus_in_ampdu_cnt = 9915 ev->tx_mpdu_cnt_in_ampdu; 9916 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 9917 ev->tx_octets_in_ampdu.upload.high; 9918 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 9919 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt << 32; 9920 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt += 9921 ev->tx_octets_in_ampdu.upload.low; 9922 9923 mib_stats->mib_counters_group3.ampdu_rx_cnt = 9924 ev->rx_ampdu_cnt; 9925 mib_stats->mib_counters_group3.mpdu_in_rx_ampdu_cnt = 9926 ev->rx_mpdu_cnt_in_ampdu; 9927 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 9928 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_high; 9929 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 9930 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt << 32; 9931 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt += 9932 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_low; 9933 9934 if (ev_param->num_mib_extd_stats) { 9935 ev_extd = (wmi_mib_extd_stats *)((uint8_t *)ev + 9936 ev_param->num_mib_stats * sizeof(wmi_mib_stats) + 9937 ev_param->num_bcn_stats * sizeof(wmi_bcn_stats) + 9938 ev_param->num_peer_extd_stats * 9939 sizeof(wmi_peer_extd_stats)); 9940 mib_stats->mib_mac_statistics.multi_retry_cnt = 9941 ev_extd->tx_msdu_multi_retry_cnt; 9942 mib_stats->mib_mac_statistics.tx_ack_fail_cnt = 9943 ev_extd->tx_ack_fail_cnt; 9944 9945 mib_stats->mib_qos_counters.qos_multi_retry_cnt = 9946 ev_extd->tx_qos_msdu_multi_retry_up; 9947 mib_stats->mib_qos_counters.tx_qos_ack_fail_cnt_up = 9948 ev_extd->tx_qos_ack_fail_cnt_up; 9949 9950 mib_stats->mib_rsna_stats.cmac_icv_err = 9951 ev_extd->rsna_cmac_icv_err_cnt; 9952 mib_stats->mib_rsna_stats.cmac_replays = 9953 ev_extd->rsna_cmac_replay_err_cnt; 9954 9955 mib_stats->mib_counters_group3.rx_ampdu_deli_crc_err_cnt = 9956 ev_extd->rx_ampdu_deli_crc_err_cnt; 9957 } 9958 9959 return QDF_STATUS_SUCCESS; 9960 } 9961 #endif 9962 9963 /** 9964 * extract_profile_ctx_tlv() - extract profile context from event 9965 * @wmi_handle: wmi handle 9966 * @param evt_buf: pointer to event buffer 9967 * @idx: profile stats index to extract 9968 * @param profile_ctx: Pointer to hold profile context 9969 * 9970 * Return: QDF_STATUS_SUCCESS for success or error code 9971 */ 9972 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 9973 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 9974 { 9975 return QDF_STATUS_SUCCESS; 9976 } 9977 9978 /** 9979 * extract_profile_data_tlv() - extract profile data from event 9980 * @wmi_handle: wmi handle 9981 * @param evt_buf: pointer to event buffer 9982 * @param profile_data: Pointer to hold profile data 9983 * 9984 * Return: QDF_STATUS_SUCCESS for success or error code 9985 */ 9986 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 9987 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 9988 { 9989 9990 return QDF_STATUS_SUCCESS; 9991 } 9992 9993 /** 9994 * extract_pdev_utf_event_tlv() - extract UTF data info from event 9995 * @wmi_handle: WMI handle 9996 * @param evt_buf: Pointer to event buffer 9997 * @param param: Pointer to hold data 9998 * 9999 * Return : QDF_STATUS_SUCCESS for success or error code 10000 */ 10001 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 10002 uint8_t *evt_buf, 10003 struct wmi_host_pdev_utf_event *event) 10004 { 10005 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 10006 struct wmi_host_utf_seg_header_info *seg_hdr; 10007 10008 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 10009 event->data = param_buf->data; 10010 event->datalen = param_buf->num_data; 10011 10012 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 10013 WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen); 10014 return QDF_STATUS_E_INVAL; 10015 } 10016 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 10017 /* Set pdev_id=1 until FW adds support to include pdev_id */ 10018 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10019 wmi_handle, 10020 seg_hdr->pdev_id); 10021 10022 return QDF_STATUS_SUCCESS; 10023 } 10024 10025 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 10026 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10027 uint8_t *event, 10028 uint32_t *num_rf_characterization_entries) 10029 { 10030 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10031 10032 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10033 if (!param_buf) 10034 return QDF_STATUS_E_INVAL; 10035 10036 *num_rf_characterization_entries = 10037 param_buf->num_wmi_chan_rf_characterization_info; 10038 10039 return QDF_STATUS_SUCCESS; 10040 } 10041 10042 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10043 uint8_t *event, 10044 uint32_t num_rf_characterization_entries, 10045 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 10046 { 10047 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10048 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 10049 uint8_t ix; 10050 10051 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10052 if (!param_buf) 10053 return QDF_STATUS_E_INVAL; 10054 10055 wmi_rf_characterization_entry = 10056 param_buf->wmi_chan_rf_characterization_info; 10057 if (!wmi_rf_characterization_entry) 10058 return QDF_STATUS_E_INVAL; 10059 10060 /* 10061 * Using num_wmi_chan_rf_characterization instead of param_buf value 10062 * since memory for rf_characterization_entries was allocated using 10063 * the former. 10064 */ 10065 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 10066 rf_characterization_entries[ix].freq = 10067 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 10068 &wmi_rf_characterization_entry[ix]); 10069 10070 rf_characterization_entries[ix].bw = 10071 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 10072 &wmi_rf_characterization_entry[ix]); 10073 10074 rf_characterization_entries[ix].chan_metric = 10075 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 10076 &wmi_rf_characterization_entry[ix]); 10077 10078 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 10079 "bw: %u, chan_metric: %u", 10080 ix, rf_characterization_entries[ix].freq, 10081 rf_characterization_entries[ix].bw, 10082 rf_characterization_entries[ix].chan_metric); 10083 } 10084 10085 return QDF_STATUS_SUCCESS; 10086 } 10087 #endif 10088 10089 /** 10090 * extract_chainmask_tables_tlv() - extract chain mask tables from event 10091 * @wmi_handle: wmi handle 10092 * @param evt_buf: pointer to event buffer 10093 * @param param: Pointer to hold evt buf 10094 * 10095 * Return: QDF_STATUS_SUCCESS for success or error code 10096 */ 10097 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 10098 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 10099 { 10100 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10101 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 10102 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10103 uint8_t i = 0, j = 0; 10104 uint32_t num_mac_phy_chainmask_caps = 0; 10105 10106 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10107 if (!param_buf) 10108 return QDF_STATUS_E_INVAL; 10109 10110 hw_caps = param_buf->soc_hw_mode_caps; 10111 if (!hw_caps) 10112 return QDF_STATUS_E_INVAL; 10113 10114 if ((!hw_caps->num_chainmask_tables) || 10115 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 10116 (hw_caps->num_chainmask_tables > 10117 param_buf->num_mac_phy_chainmask_combo)) 10118 return QDF_STATUS_E_INVAL; 10119 10120 chainmask_caps = param_buf->mac_phy_chainmask_caps; 10121 10122 if (!chainmask_caps) 10123 return QDF_STATUS_E_INVAL; 10124 10125 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 10126 if (chainmask_table[i].num_valid_chainmasks > 10127 (UINT_MAX - num_mac_phy_chainmask_caps)) { 10128 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 10129 num_mac_phy_chainmask_caps, i, 10130 chainmask_table[i].num_valid_chainmasks); 10131 return QDF_STATUS_E_INVAL; 10132 } 10133 num_mac_phy_chainmask_caps += 10134 chainmask_table[i].num_valid_chainmasks; 10135 } 10136 10137 if (num_mac_phy_chainmask_caps > 10138 param_buf->num_mac_phy_chainmask_caps) { 10139 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 10140 num_mac_phy_chainmask_caps, 10141 param_buf->num_mac_phy_chainmask_caps); 10142 return QDF_STATUS_E_INVAL; 10143 } 10144 10145 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 10146 10147 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 10148 i); 10149 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 10150 10151 chainmask_table[i].cap_list[j].chainmask = 10152 chainmask_caps->chainmask; 10153 10154 chainmask_table[i].cap_list[j].supports_chan_width_20 = 10155 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 10156 10157 chainmask_table[i].cap_list[j].supports_chan_width_40 = 10158 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 10159 10160 chainmask_table[i].cap_list[j].supports_chan_width_80 = 10161 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 10162 10163 chainmask_table[i].cap_list[j].supports_chan_width_160 = 10164 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 10165 10166 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 10167 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 10168 10169 chainmask_table[i].cap_list[j].chain_mask_2G = 10170 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 10171 10172 chainmask_table[i].cap_list[j].chain_mask_5G = 10173 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 10174 10175 chainmask_table[i].cap_list[j].chain_mask_tx = 10176 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 10177 10178 chainmask_table[i].cap_list[j].chain_mask_rx = 10179 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 10180 10181 chainmask_table[i].cap_list[j].supports_aDFS = 10182 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 10183 10184 chainmask_table[i].cap_list[j].supports_aSpectral = 10185 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 10186 10187 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 10188 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 10189 10190 chainmask_table[i].cap_list[j].supports_aDFS_160 = 10191 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 10192 10193 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 10194 chainmask_caps->supported_flags, 10195 chainmask_caps->chainmask); 10196 chainmask_caps++; 10197 } 10198 } 10199 10200 return QDF_STATUS_SUCCESS; 10201 } 10202 10203 /** 10204 * extract_service_ready_ext_tlv() - extract basic extended service ready params 10205 * from event 10206 * @wmi_handle: wmi handle 10207 * @param evt_buf: pointer to event buffer 10208 * @param param: Pointer to hold evt buf 10209 * 10210 * Return: QDF_STATUS_SUCCESS for success or error code 10211 */ 10212 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 10213 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 10214 { 10215 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10216 wmi_service_ready_ext_event_fixed_param *ev; 10217 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10218 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 10219 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 10220 uint8_t i = 0; 10221 10222 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10223 if (!param_buf) 10224 return QDF_STATUS_E_INVAL; 10225 10226 ev = param_buf->fixed_param; 10227 if (!ev) 10228 return QDF_STATUS_E_INVAL; 10229 10230 /* Move this to host based bitmap */ 10231 param->default_conc_scan_config_bits = 10232 ev->default_conc_scan_config_bits; 10233 param->default_fw_config_bits = ev->default_fw_config_bits; 10234 param->he_cap_info = ev->he_cap_info; 10235 param->mpdu_density = ev->mpdu_density; 10236 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 10237 param->fw_build_vers_ext = ev->fw_build_vers_ext; 10238 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 10239 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 10240 param->max_bssid_indicator = ev->max_bssid_indicator; 10241 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 10242 10243 hw_caps = param_buf->soc_hw_mode_caps; 10244 if (hw_caps) 10245 param->num_hw_modes = hw_caps->num_hw_modes; 10246 else 10247 param->num_hw_modes = 0; 10248 10249 reg_caps = param_buf->soc_hal_reg_caps; 10250 if (reg_caps) 10251 param->num_phy = reg_caps->num_phy; 10252 else 10253 param->num_phy = 0; 10254 10255 if (hw_caps) { 10256 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 10257 wmi_nofl_debug("Num chain mask tables: %d", 10258 hw_caps->num_chainmask_tables); 10259 } else 10260 param->num_chainmask_tables = 0; 10261 10262 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 10263 param->num_chainmask_tables > 10264 param_buf->num_mac_phy_chainmask_combo) { 10265 wmi_err_rl("num_chainmask_tables is OOB: %u", 10266 param->num_chainmask_tables); 10267 return QDF_STATUS_E_INVAL; 10268 } 10269 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 10270 10271 if (!chain_mask_combo) 10272 return QDF_STATUS_SUCCESS; 10273 10274 wmi_nofl_debug("Dumping chain mask combo data"); 10275 10276 for (i = 0; i < param->num_chainmask_tables; i++) { 10277 10278 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 10279 chain_mask_combo->chainmask_table_id, 10280 chain_mask_combo->num_valid_chainmask); 10281 10282 param->chainmask_table[i].table_id = 10283 chain_mask_combo->chainmask_table_id; 10284 param->chainmask_table[i].num_valid_chainmasks = 10285 chain_mask_combo->num_valid_chainmask; 10286 chain_mask_combo++; 10287 } 10288 wmi_nofl_debug("chain mask combo end"); 10289 10290 return QDF_STATUS_SUCCESS; 10291 } 10292 10293 /** 10294 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 10295 * event 10296 * @wmi_handle: wmi handle 10297 * @event: pointer to event buffer 10298 * @param: Pointer to hold the params 10299 * 10300 * Return: QDF_STATUS_SUCCESS for success or error code 10301 */ 10302 static QDF_STATUS 10303 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 10304 struct wlan_psoc_host_service_ext2_param *param) 10305 { 10306 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 10307 wmi_service_ready_ext2_event_fixed_param *ev; 10308 10309 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 10310 if (!param_buf) 10311 return QDF_STATUS_E_INVAL; 10312 10313 ev = param_buf->fixed_param; 10314 if (!ev) 10315 return QDF_STATUS_E_INVAL; 10316 10317 param->reg_db_version_major = 10318 WMI_REG_DB_VERSION_MAJOR_GET( 10319 ev->reg_db_version); 10320 param->reg_db_version_minor = 10321 WMI_REG_DB_VERSION_MINOR_GET( 10322 ev->reg_db_version); 10323 param->bdf_reg_db_version_major = 10324 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 10325 ev->reg_db_version); 10326 param->bdf_reg_db_version_minor = 10327 WMI_BDF_REG_DB_VERSION_MINOR_GET( 10328 ev->reg_db_version); 10329 10330 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 10331 return QDF_STATUS_SUCCESS; 10332 } 10333 10334 /** 10335 * extract_sar_cap_service_ready_ext_tlv() - 10336 * extract SAR cap from service ready event 10337 * @wmi_handle: wmi handle 10338 * @event: pointer to event buffer 10339 * @ext_param: extended target info 10340 * 10341 * Return: QDF_STATUS_SUCCESS for success or error code 10342 */ 10343 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 10344 wmi_unified_t wmi_handle, 10345 uint8_t *event, 10346 struct wlan_psoc_host_service_ext_param *ext_param) 10347 { 10348 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10349 WMI_SAR_CAPABILITIES *sar_caps; 10350 10351 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 10352 10353 if (!param_buf) 10354 return QDF_STATUS_E_INVAL; 10355 10356 sar_caps = param_buf->sar_caps; 10357 if (sar_caps) 10358 ext_param->sar_version = sar_caps->active_version; 10359 else 10360 ext_param->sar_version = 0; 10361 10362 return QDF_STATUS_SUCCESS; 10363 } 10364 10365 /** 10366 * extract_hw_mode_cap_service_ready_ext_tlv() - 10367 * extract HW mode cap from service ready event 10368 * @wmi_handle: wmi handle 10369 * @param evt_buf: pointer to event buffer 10370 * @param param: Pointer to hold evt buf 10371 * @param hw_mode_idx: hw mode idx should be less than num_mode 10372 * 10373 * Return: QDF_STATUS_SUCCESS for success or error code 10374 */ 10375 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 10376 wmi_unified_t wmi_handle, 10377 uint8_t *event, uint8_t hw_mode_idx, 10378 struct wlan_psoc_host_hw_mode_caps *param) 10379 { 10380 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10381 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10382 10383 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10384 if (!param_buf) 10385 return QDF_STATUS_E_INVAL; 10386 10387 hw_caps = param_buf->soc_hw_mode_caps; 10388 if (!hw_caps) 10389 return QDF_STATUS_E_INVAL; 10390 10391 if (!hw_caps->num_hw_modes || 10392 !param_buf->hw_mode_caps || 10393 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 10394 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 10395 return QDF_STATUS_E_INVAL; 10396 10397 if (hw_mode_idx >= hw_caps->num_hw_modes) 10398 return QDF_STATUS_E_INVAL; 10399 10400 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 10401 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 10402 10403 param->hw_mode_config_type = 10404 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 10405 10406 return QDF_STATUS_SUCCESS; 10407 } 10408 10409 /** 10410 * extract_mac_phy_cap_service_ready_ext_tlv() - 10411 * extract MAC phy cap from service ready event 10412 * @wmi_handle: wmi handle 10413 * @param evt_buf: pointer to event buffer 10414 * @param param: Pointer to hold evt buf 10415 * @param hw_mode_idx: hw mode idx should be less than num_mode 10416 * @param phy_id: phy id within hw_mode 10417 * 10418 * Return: QDF_STATUS_SUCCESS for success or error code 10419 */ 10420 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 10421 wmi_unified_t wmi_handle, 10422 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 10423 struct wlan_psoc_host_mac_phy_caps *param) 10424 { 10425 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10426 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 10427 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10428 uint32_t phy_map; 10429 uint8_t hw_idx, phy_idx = 0; 10430 10431 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10432 if (!param_buf) 10433 return QDF_STATUS_E_INVAL; 10434 10435 hw_caps = param_buf->soc_hw_mode_caps; 10436 if (!hw_caps) 10437 return QDF_STATUS_E_INVAL; 10438 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 10439 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 10440 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 10441 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 10442 return QDF_STATUS_E_INVAL; 10443 } 10444 10445 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 10446 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 10447 break; 10448 10449 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 10450 while (phy_map) { 10451 phy_map >>= 1; 10452 phy_idx++; 10453 } 10454 } 10455 10456 if (hw_idx == hw_caps->num_hw_modes) 10457 return QDF_STATUS_E_INVAL; 10458 10459 phy_idx += phy_id; 10460 if (phy_idx >= param_buf->num_mac_phy_caps) 10461 return QDF_STATUS_E_INVAL; 10462 10463 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 10464 10465 param->hw_mode_id = mac_phy_caps->hw_mode_id; 10466 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10467 wmi_handle, 10468 mac_phy_caps->pdev_id); 10469 param->tgt_pdev_id = mac_phy_caps->pdev_id; 10470 param->phy_id = mac_phy_caps->phy_id; 10471 param->supports_11b = 10472 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 10473 param->supports_11g = 10474 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 10475 param->supports_11a = 10476 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 10477 param->supports_11n = 10478 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 10479 param->supports_11ac = 10480 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 10481 param->supports_11ax = 10482 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 10483 10484 param->supported_bands = mac_phy_caps->supported_bands; 10485 param->ampdu_density = mac_phy_caps->ampdu_density; 10486 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 10487 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 10488 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 10489 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 10490 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 10491 mac_phy_caps->he_cap_info_2G; 10492 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 10493 mac_phy_caps->he_cap_info_2G_ext; 10494 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 10495 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 10496 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 10497 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 10498 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 10499 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 10500 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 10501 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 10502 mac_phy_caps->he_cap_info_5G; 10503 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 10504 mac_phy_caps->he_cap_info_5G_ext; 10505 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 10506 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 10507 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 10508 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 10509 qdf_mem_copy(¶m->he_cap_phy_info_2G, 10510 &mac_phy_caps->he_cap_phy_info_2G, 10511 sizeof(param->he_cap_phy_info_2G)); 10512 qdf_mem_copy(¶m->he_cap_phy_info_5G, 10513 &mac_phy_caps->he_cap_phy_info_5G, 10514 sizeof(param->he_cap_phy_info_5G)); 10515 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 10516 sizeof(param->he_ppet2G)); 10517 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 10518 sizeof(param->he_ppet5G)); 10519 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 10520 param->lmac_id = mac_phy_caps->lmac_id; 10521 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 10522 (mac_phy_caps->wireless_modes); 10523 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 10524 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 10525 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 10526 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 10527 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 10528 mac_phy_caps->nss_ratio); 10529 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 10530 10531 return QDF_STATUS_SUCCESS; 10532 } 10533 10534 /** 10535 * extract_reg_cap_service_ready_ext_tlv() - 10536 * extract REG cap from service ready event 10537 * @wmi_handle: wmi handle 10538 * @param evt_buf: pointer to event buffer 10539 * @param param: Pointer to hold evt buf 10540 * @param phy_idx: phy idx should be less than num_mode 10541 * 10542 * Return: QDF_STATUS_SUCCESS for success or error code 10543 */ 10544 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 10545 wmi_unified_t wmi_handle, 10546 uint8_t *event, uint8_t phy_idx, 10547 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 10548 { 10549 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10550 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 10551 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 10552 10553 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10554 if (!param_buf) 10555 return QDF_STATUS_E_INVAL; 10556 10557 reg_caps = param_buf->soc_hal_reg_caps; 10558 if (!reg_caps) 10559 return QDF_STATUS_E_INVAL; 10560 10561 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 10562 return QDF_STATUS_E_INVAL; 10563 10564 if (phy_idx >= reg_caps->num_phy) 10565 return QDF_STATUS_E_INVAL; 10566 10567 if (!param_buf->hal_reg_caps) 10568 return QDF_STATUS_E_INVAL; 10569 10570 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 10571 10572 param->phy_id = ext_reg_cap->phy_id; 10573 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 10574 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 10575 param->regcap1 = ext_reg_cap->regcap1; 10576 param->regcap2 = ext_reg_cap->regcap2; 10577 param->wireless_modes = convert_wireless_modes_tlv( 10578 ext_reg_cap->wireless_modes); 10579 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 10580 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 10581 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 10582 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 10583 10584 return QDF_STATUS_SUCCESS; 10585 } 10586 10587 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 10588 uint8_t num_dma_ring_caps) 10589 { 10590 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 10591 if (!num_dma_ring_caps) { 10592 WMI_LOGI("%s: dma_ring_caps %d", __func__, num_dma_ring_caps); 10593 return QDF_STATUS_E_INVAL; 10594 } 10595 if (idx >= num_dma_ring_caps) { 10596 WMI_LOGE("%s: Index %d exceeds range", __func__, idx); 10597 return QDF_STATUS_E_INVAL; 10598 } 10599 return QDF_STATUS_SUCCESS; 10600 } 10601 10602 static void 10603 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 10604 struct wlan_psoc_host_dbr_ring_caps *param, 10605 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 10606 { 10607 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 10608 wmi_handle, 10609 dbr_ring_caps->pdev_id); 10610 param->mod_id = dbr_ring_caps->mod_id; 10611 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 10612 param->min_buf_size = dbr_ring_caps->min_buf_size; 10613 param->min_buf_align = dbr_ring_caps->min_buf_align; 10614 } 10615 10616 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 10617 wmi_unified_t wmi_handle, 10618 uint8_t *event, uint8_t idx, 10619 struct wlan_psoc_host_dbr_ring_caps *param) 10620 { 10621 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10622 QDF_STATUS status; 10623 10624 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 10625 if (!param_buf) 10626 return QDF_STATUS_E_INVAL; 10627 10628 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 10629 if (status != QDF_STATUS_SUCCESS) 10630 return status; 10631 10632 populate_dbr_ring_cap_elems(wmi_handle, param, 10633 ¶m_buf->dma_ring_caps[idx]); 10634 return QDF_STATUS_SUCCESS; 10635 } 10636 10637 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 10638 wmi_unified_t wmi_handle, 10639 uint8_t *event, uint8_t idx, 10640 struct wlan_psoc_host_dbr_ring_caps *param) 10641 { 10642 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 10643 QDF_STATUS status; 10644 10645 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 10646 if (!param_buf) 10647 return QDF_STATUS_E_INVAL; 10648 10649 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 10650 if (status != QDF_STATUS_SUCCESS) 10651 return status; 10652 10653 populate_dbr_ring_cap_elems(wmi_handle, param, 10654 ¶m_buf->dma_ring_caps[idx]); 10655 return QDF_STATUS_SUCCESS; 10656 } 10657 /** 10658 * extract_thermal_stats_tlv() - extract thermal stats from event 10659 * @wmi_handle: wmi handle 10660 * @param evt_buf: Pointer to event buffer 10661 * @param temp: Pointer to hold extracted temperature 10662 * @param level: Pointer to hold extracted level 10663 * 10664 * Return: 0 for success or error code 10665 */ 10666 static QDF_STATUS 10667 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 10668 void *evt_buf, uint32_t *temp, 10669 uint32_t *level, uint32_t *pdev_id) 10670 { 10671 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 10672 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 10673 10674 param_buf = 10675 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 10676 if (!param_buf) 10677 return QDF_STATUS_E_INVAL; 10678 10679 tt_stats_event = param_buf->fixed_param; 10680 10681 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10682 wmi_handle, 10683 tt_stats_event->pdev_id); 10684 *temp = tt_stats_event->temp; 10685 *level = tt_stats_event->level; 10686 10687 return QDF_STATUS_SUCCESS; 10688 } 10689 10690 /** 10691 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 10692 * @wmi_handle: wmi handle 10693 * @param evt_buf: pointer to event buffer 10694 * @param idx: Index to level stats 10695 * @param levelcount: Pointer to hold levelcount 10696 * @param dccount: Pointer to hold dccount 10697 * 10698 * Return: 0 for success or error code 10699 */ 10700 static QDF_STATUS 10701 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 10702 void *evt_buf, uint8_t idx, uint32_t *levelcount, 10703 uint32_t *dccount) 10704 { 10705 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 10706 wmi_therm_throt_level_stats_info *tt_level_info; 10707 10708 param_buf = 10709 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 10710 if (!param_buf) 10711 return QDF_STATUS_E_INVAL; 10712 10713 tt_level_info = param_buf->therm_throt_level_stats_info; 10714 10715 if (idx < THERMAL_LEVELS) { 10716 *levelcount = tt_level_info[idx].level_count; 10717 *dccount = tt_level_info[idx].dc_count; 10718 return QDF_STATUS_SUCCESS; 10719 } 10720 10721 return QDF_STATUS_E_FAILURE; 10722 } 10723 #ifdef BIG_ENDIAN_HOST 10724 /** 10725 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 10726 * @param data_len - data length 10727 * @param data - pointer to data 10728 * 10729 * Return: QDF_STATUS - success or error status 10730 */ 10731 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 10732 { 10733 uint8_t *data_aligned = NULL; 10734 int c; 10735 unsigned char *data_unaligned; 10736 10737 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 10738 FIPS_ALIGN)); 10739 /* Assigning unaligned space to copy the data */ 10740 /* Checking if kmalloc does successful allocation */ 10741 if (!data_unaligned) 10742 return QDF_STATUS_E_FAILURE; 10743 10744 /* Checking if space is alligned */ 10745 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10746 /* align the data space */ 10747 data_aligned = 10748 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10749 } else { 10750 data_aligned = (u_int8_t *)data_unaligned; 10751 } 10752 10753 /* memset and copy content from data to data aligned */ 10754 OS_MEMSET(data_aligned, 0, data_len); 10755 OS_MEMCPY(data_aligned, data, data_len); 10756 /* Endianness to LE */ 10757 for (c = 0; c < data_len/4; c++) { 10758 *((u_int32_t *)data_aligned + c) = 10759 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 10760 } 10761 10762 /* Copy content to event->data */ 10763 OS_MEMCPY(data, data_aligned, data_len); 10764 10765 /* clean up allocated space */ 10766 qdf_mem_free(data_unaligned); 10767 data_aligned = NULL; 10768 data_unaligned = NULL; 10769 10770 /*************************************************************/ 10771 10772 return QDF_STATUS_SUCCESS; 10773 } 10774 #else 10775 /** 10776 * fips_conv_data_be() - DUMMY for LE platform 10777 * 10778 * Return: QDF_STATUS - success 10779 */ 10780 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 10781 { 10782 return QDF_STATUS_SUCCESS; 10783 } 10784 #endif 10785 10786 /** 10787 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 10788 * @wmi_handle - wmi handle 10789 * @params - PN request params for peer 10790 * 10791 * Return: QDF_STATUS - success or error status 10792 */ 10793 static QDF_STATUS 10794 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 10795 struct peer_request_pn_param *params) 10796 { 10797 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 10798 wmi_buf_t buf; 10799 uint8_t *buf_ptr; 10800 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 10801 10802 buf = wmi_buf_alloc(wmi_handle, len); 10803 if (!buf) { 10804 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 10805 return QDF_STATUS_E_FAILURE; 10806 } 10807 10808 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10809 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 10810 10811 WMITLV_SET_HDR(&cmd->tlv_header, 10812 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 10813 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 10814 10815 cmd->vdev_id = params->vdev_id; 10816 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 10817 cmd->key_type = params->key_type; 10818 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10819 WMI_PEER_TX_PN_REQUEST_CMDID)) { 10820 WMI_LOGE("%s:Failed to send WMI command\n", __func__); 10821 wmi_buf_free(buf); 10822 return QDF_STATUS_E_FAILURE; 10823 } 10824 return QDF_STATUS_SUCCESS; 10825 } 10826 10827 /** 10828 * extract_get_pn_data_tlv() - extract pn resp 10829 * @wmi_handle - wmi handle 10830 * @params - PN response params for peer 10831 * 10832 * Return: QDF_STATUS - success or error status 10833 */ 10834 static QDF_STATUS 10835 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10836 struct wmi_host_get_pn_event *param) 10837 { 10838 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 10839 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 10840 10841 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 10842 event = 10843 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 10844 10845 param->vdev_id = event->vdev_id; 10846 param->key_type = event->key_type; 10847 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 10848 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 10849 10850 return QDF_STATUS_SUCCESS; 10851 } 10852 10853 /** 10854 * extract_fips_event_data_tlv() - extract fips event data 10855 * @wmi_handle: wmi handle 10856 * @param evt_buf: pointer to event buffer 10857 * @param param: pointer FIPS event params 10858 * 10859 * Return: 0 for success or error code 10860 */ 10861 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 10862 void *evt_buf, struct wmi_host_fips_event_param *param) 10863 { 10864 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 10865 wmi_pdev_fips_event_fixed_param *event; 10866 10867 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 10868 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 10869 10870 if (fips_conv_data_be(event->data_len, param_buf->data) != 10871 QDF_STATUS_SUCCESS) 10872 return QDF_STATUS_E_FAILURE; 10873 10874 param->data = (uint32_t *)param_buf->data; 10875 param->data_len = event->data_len; 10876 param->error_status = event->error_status; 10877 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10878 wmi_handle, 10879 event->pdev_id); 10880 10881 return QDF_STATUS_SUCCESS; 10882 } 10883 10884 #ifdef WLAN_FEATURE_DISA 10885 /** 10886 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 10887 * params from event 10888 * @wmi_handle: wmi handle 10889 * @evt_buf: pointer to event buffer 10890 * @resp: Pointer to hold resp parameters 10891 * 10892 * Return: QDF_STATUS_SUCCESS for success or error code 10893 */ 10894 static QDF_STATUS 10895 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 10896 void *evt_buf, 10897 struct disa_encrypt_decrypt_resp_params 10898 *resp) 10899 { 10900 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 10901 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 10902 10903 param_buf = evt_buf; 10904 if (!param_buf) { 10905 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 10906 return QDF_STATUS_E_INVAL; 10907 } 10908 10909 data_event = param_buf->fixed_param; 10910 10911 resp->vdev_id = data_event->vdev_id; 10912 resp->status = data_event->status; 10913 10914 if ((data_event->data_length > param_buf->num_enc80211_frame) || 10915 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 10916 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 10917 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 10918 data_event->data_length, 10919 param_buf->num_enc80211_frame); 10920 return QDF_STATUS_E_INVAL; 10921 } 10922 10923 resp->data_len = data_event->data_length; 10924 10925 if (resp->data_len) 10926 resp->data = (uint8_t *)param_buf->enc80211_frame; 10927 10928 return QDF_STATUS_SUCCESS; 10929 } 10930 #endif /* WLAN_FEATURE_DISA */ 10931 10932 static bool is_management_record_tlv(uint32_t cmd_id) 10933 { 10934 switch (cmd_id) { 10935 case WMI_MGMT_TX_SEND_CMDID: 10936 case WMI_MGMT_TX_COMPLETION_EVENTID: 10937 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 10938 case WMI_MGMT_RX_EVENTID: 10939 return true; 10940 default: 10941 return false; 10942 } 10943 } 10944 10945 static bool is_diag_event_tlv(uint32_t event_id) 10946 { 10947 if (WMI_DIAG_EVENTID == event_id) 10948 return true; 10949 10950 return false; 10951 } 10952 10953 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 10954 { 10955 uint16_t tag = 0; 10956 10957 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 10958 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 10959 __func__); 10960 return tag; 10961 } 10962 10963 if (wmi_handle->tag_crash_inject) 10964 tag = HTC_TX_PACKET_TAG_AUTO_PM; 10965 10966 wmi_handle->tag_crash_inject = false; 10967 return tag; 10968 } 10969 10970 /** 10971 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 10972 * @wmi_handle: WMI handle 10973 * @buf: WMI buffer 10974 * @cmd_id: WMI command Id 10975 * 10976 * Return htc_tx_tag 10977 */ 10978 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 10979 wmi_buf_t buf, 10980 uint32_t cmd_id) 10981 { 10982 uint16_t htc_tx_tag = 0; 10983 10984 switch (cmd_id) { 10985 case WMI_WOW_ENABLE_CMDID: 10986 case WMI_PDEV_SUSPEND_CMDID: 10987 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 10988 case WMI_PDEV_RESUME_CMDID: 10989 case WMI_HB_SET_ENABLE_CMDID: 10990 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 10991 #ifdef FEATURE_WLAN_D0WOW 10992 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 10993 #endif 10994 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 10995 break; 10996 case WMI_FORCE_FW_HANG_CMDID: 10997 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 10998 break; 10999 default: 11000 break; 11001 } 11002 11003 return htc_tx_tag; 11004 } 11005 11006 static struct cur_reg_rule 11007 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 11008 wmi_regulatory_rule_struct *wmi_reg_rule) 11009 { 11010 struct cur_reg_rule *reg_rule_ptr; 11011 uint32_t count; 11012 11013 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * sizeof(*reg_rule_ptr)); 11014 11015 if (!reg_rule_ptr) 11016 return NULL; 11017 11018 for (count = 0; count < num_reg_rules; count++) { 11019 reg_rule_ptr[count].start_freq = 11020 WMI_REG_RULE_START_FREQ_GET( 11021 wmi_reg_rule[count].freq_info); 11022 reg_rule_ptr[count].end_freq = 11023 WMI_REG_RULE_END_FREQ_GET( 11024 wmi_reg_rule[count].freq_info); 11025 reg_rule_ptr[count].max_bw = 11026 WMI_REG_RULE_MAX_BW_GET( 11027 wmi_reg_rule[count].bw_pwr_info); 11028 reg_rule_ptr[count].reg_power = 11029 WMI_REG_RULE_REG_POWER_GET( 11030 wmi_reg_rule[count].bw_pwr_info); 11031 reg_rule_ptr[count].ant_gain = 11032 WMI_REG_RULE_ANTENNA_GAIN_GET( 11033 wmi_reg_rule[count].bw_pwr_info); 11034 reg_rule_ptr[count].flags = 11035 WMI_REG_RULE_FLAGS_GET( 11036 wmi_reg_rule[count].flag_info); 11037 } 11038 11039 return reg_rule_ptr; 11040 } 11041 11042 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 11043 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11044 struct cur_regulatory_info *reg_info, uint32_t len) 11045 { 11046 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 11047 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 11048 wmi_regulatory_rule_struct *wmi_reg_rule; 11049 uint32_t num_2g_reg_rules, num_5g_reg_rules; 11050 11051 WMI_LOGD("processing regulatory channel list"); 11052 11053 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 11054 if (!param_buf) { 11055 WMI_LOGE("invalid channel list event buf"); 11056 return QDF_STATUS_E_FAILURE; 11057 } 11058 11059 chan_list_event_hdr = param_buf->fixed_param; 11060 11061 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 11062 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 11063 num_2g_reg_rules = reg_info->num_2g_reg_rules; 11064 num_5g_reg_rules = reg_info->num_5g_reg_rules; 11065 if ((num_2g_reg_rules > MAX_REG_RULES) || 11066 (num_5g_reg_rules > MAX_REG_RULES) || 11067 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 11068 (num_2g_reg_rules + num_5g_reg_rules != 11069 param_buf->num_reg_rule_array)) { 11070 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 11071 num_2g_reg_rules, num_5g_reg_rules); 11072 return QDF_STATUS_E_FAILURE; 11073 } 11074 if (param_buf->num_reg_rule_array > 11075 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 11076 sizeof(*wmi_reg_rule)) { 11077 wmi_err_rl("Invalid num_reg_rule_array: %u", 11078 param_buf->num_reg_rule_array); 11079 return QDF_STATUS_E_FAILURE; 11080 } 11081 11082 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 11083 REG_ALPHA2_LEN); 11084 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 11085 reg_info->phybitmap = chan_list_event_hdr->phybitmap; 11086 reg_info->offload_enabled = true; 11087 reg_info->num_phy = chan_list_event_hdr->num_phy; 11088 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 11089 wmi_handle, chan_list_event_hdr->phy_id); 11090 reg_info->ctry_code = chan_list_event_hdr->country_id; 11091 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 11092 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 11093 reg_info->status_code = REG_SET_CC_STATUS_PASS; 11094 else if (chan_list_event_hdr->status_code == 11095 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 11096 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 11097 else if (chan_list_event_hdr->status_code == 11098 WMI_REG_INIT_ALPHA2_NOT_FOUND) 11099 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 11100 else if (chan_list_event_hdr->status_code == 11101 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 11102 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 11103 else if (chan_list_event_hdr->status_code == 11104 WMI_REG_SET_CC_STATUS_NO_MEMORY) 11105 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 11106 else if (chan_list_event_hdr->status_code == 11107 WMI_REG_SET_CC_STATUS_FAIL) 11108 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 11109 11110 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 11111 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 11112 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 11113 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 11114 11115 WMI_LOGD(FL("num_phys = %u and phy_id = %u"), 11116 reg_info->num_phy, reg_info->phy_id); 11117 11118 WMI_LOGD("%s:cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 11119 __func__, reg_info->alpha2, reg_info->dfs_region, 11120 reg_info->min_bw_2g, reg_info->max_bw_2g, 11121 reg_info->min_bw_5g, reg_info->max_bw_5g); 11122 11123 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 11124 num_2g_reg_rules, num_5g_reg_rules); 11125 wmi_reg_rule = 11126 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 11127 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 11128 + WMI_TLV_HDR_SIZE); 11129 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 11130 wmi_reg_rule); 11131 wmi_reg_rule += num_2g_reg_rules; 11132 11133 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 11134 wmi_reg_rule); 11135 11136 WMI_LOGD("processed regulatory channel list"); 11137 11138 return QDF_STATUS_SUCCESS; 11139 } 11140 11141 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 11142 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11143 struct reg_11d_new_country *reg_11d_country, uint32_t len) 11144 { 11145 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 11146 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 11147 11148 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 11149 if (!param_buf) { 11150 WMI_LOGE("invalid 11d country event buf"); 11151 return QDF_STATUS_E_FAILURE; 11152 } 11153 11154 reg_11d_country_event = param_buf->fixed_param; 11155 11156 qdf_mem_copy(reg_11d_country->alpha2, 11157 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 11158 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 11159 11160 WMI_LOGD("processed 11d country event, new cc %s", 11161 reg_11d_country->alpha2); 11162 11163 return QDF_STATUS_SUCCESS; 11164 } 11165 11166 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 11167 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11168 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 11169 { 11170 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 11171 wmi_avoid_freq_range_desc *afr_desc; 11172 uint32_t num_freq_ranges, freq_range_idx; 11173 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 11174 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 11175 11176 if (!param_buf) { 11177 WMI_LOGE("Invalid channel avoid event buffer"); 11178 return QDF_STATUS_E_INVAL; 11179 } 11180 11181 afr_fixed_param = param_buf->fixed_param; 11182 if (!afr_fixed_param) { 11183 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 11184 return QDF_STATUS_E_INVAL; 11185 } 11186 11187 if (!ch_avoid_ind) { 11188 WMI_LOGE("Invalid channel avoid indication buffer"); 11189 return QDF_STATUS_E_INVAL; 11190 } 11191 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 11192 WMI_LOGE(FL("no.of freq ranges exceeded the limit")); 11193 return QDF_STATUS_E_INVAL; 11194 } 11195 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 11196 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 11197 afr_fixed_param->num_freq_ranges; 11198 11199 WMI_LOGD("Channel avoid event received with %d ranges", 11200 num_freq_ranges); 11201 11202 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 11203 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 11204 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 11205 freq_range_idx++) { 11206 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 11207 afr_desc->start_freq; 11208 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 11209 afr_desc->end_freq; 11210 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 11211 freq_range_idx, afr_desc->tlv_header, 11212 afr_desc->start_freq, afr_desc->end_freq); 11213 afr_desc++; 11214 } 11215 11216 return QDF_STATUS_SUCCESS; 11217 } 11218 11219 #ifdef DFS_COMPONENT_ENABLE 11220 /** 11221 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 11222 * @wmi_handle: wma handle 11223 * @evt_buf: event buffer 11224 * @vdev_id: vdev id 11225 * @len: length of buffer 11226 * 11227 * Return: 0 for success or error code 11228 */ 11229 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 11230 uint8_t *evt_buf, 11231 uint32_t *vdev_id, 11232 uint32_t len) 11233 { 11234 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 11235 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 11236 11237 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 11238 if (!param_tlvs) { 11239 WMI_LOGE("invalid cac complete event buf"); 11240 return QDF_STATUS_E_FAILURE; 11241 } 11242 11243 cac_event = param_tlvs->fixed_param; 11244 *vdev_id = cac_event->vdev_id; 11245 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 11246 11247 return QDF_STATUS_SUCCESS; 11248 } 11249 11250 /** 11251 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 11252 * @wmi_handle: wma handle 11253 * @evt_buf: event buffer 11254 * @vdev_id: vdev id 11255 * @len: length of buffer 11256 * 11257 * Return: 0 for success or error code 11258 */ 11259 static QDF_STATUS 11260 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 11261 uint8_t *evt_buf, 11262 struct vdev_adfs_complete_status *param) 11263 { 11264 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 11265 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 11266 11267 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 11268 if (!param_tlvs) { 11269 WMI_LOGE("invalid ocac complete event buf"); 11270 return QDF_STATUS_E_FAILURE; 11271 } 11272 11273 if (!param_tlvs->fixed_param) { 11274 WMI_LOGE("invalid param_tlvs->fixed_param"); 11275 return QDF_STATUS_E_FAILURE; 11276 } 11277 11278 ocac_complete_status = param_tlvs->fixed_param; 11279 param->vdev_id = ocac_complete_status->vdev_id; 11280 param->chan_freq = ocac_complete_status->chan_freq; 11281 param->center_freq = ocac_complete_status->center_freq; 11282 param->ocac_status = ocac_complete_status->status; 11283 param->chan_width = ocac_complete_status->chan_width; 11284 WMI_LOGD("processed ocac complete event vdev %d agile chan %d", 11285 param->vdev_id, param->center_freq); 11286 11287 return QDF_STATUS_SUCCESS; 11288 } 11289 11290 /** 11291 * extract_dfs_radar_detection_event_tlv() - extract radar found event 11292 * @wmi_handle: wma handle 11293 * @evt_buf: event buffer 11294 * @radar_found: radar found event info 11295 * @len: length of buffer 11296 * 11297 * Return: 0 for success or error code 11298 */ 11299 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 11300 wmi_unified_t wmi_handle, 11301 uint8_t *evt_buf, 11302 struct radar_found_info *radar_found, 11303 uint32_t len) 11304 { 11305 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 11306 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 11307 11308 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 11309 if (!param_tlv) { 11310 WMI_LOGE("invalid radar detection event buf"); 11311 return QDF_STATUS_E_FAILURE; 11312 } 11313 11314 radar_event = param_tlv->fixed_param; 11315 11316 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 11317 wmi_handle, 11318 radar_event->pdev_id); 11319 11320 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 11321 return QDF_STATUS_E_FAILURE; 11322 11323 radar_found->detection_mode = radar_event->detection_mode; 11324 radar_found->chan_freq = radar_event->chan_freq; 11325 radar_found->chan_width = radar_event->chan_width; 11326 radar_found->detector_id = radar_event->detector_id; 11327 radar_found->segment_id = radar_event->segment_id; 11328 radar_found->timestamp = radar_event->timestamp; 11329 radar_found->is_chirp = radar_event->is_chirp; 11330 radar_found->freq_offset = radar_event->freq_offset; 11331 radar_found->sidx = radar_event->sidx; 11332 11333 WMI_LOGI("processed radar found event pdev %d," 11334 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 11335 "chan_width (RSSI) %d,detector_id (false_radar) %d," 11336 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 11337 "is_chirp %d,detection mode %d", 11338 radar_event->pdev_id, radar_found->pdev_id, 11339 radar_event->timestamp, radar_event->chan_freq, 11340 radar_event->chan_width, radar_event->detector_id, 11341 radar_event->freq_offset, radar_event->segment_id, 11342 radar_event->sidx, radar_event->is_chirp, 11343 radar_event->detection_mode); 11344 11345 return QDF_STATUS_SUCCESS; 11346 } 11347 11348 #ifdef QCA_MCL_DFS_SUPPORT 11349 /** 11350 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 11351 * @wmi_handle: wma handle 11352 * @evt_buf: event buffer 11353 * @wlan_radar_event: Pointer to struct radar_event_info 11354 * @len: length of buffer 11355 * 11356 * Return: QDF_STATUS 11357 */ 11358 static QDF_STATUS extract_wlan_radar_event_info_tlv( 11359 wmi_unified_t wmi_handle, 11360 uint8_t *evt_buf, 11361 struct radar_event_info *wlan_radar_event, 11362 uint32_t len) 11363 { 11364 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 11365 wmi_dfs_radar_event_fixed_param *radar_event; 11366 11367 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 11368 if (!param_tlv) { 11369 WMI_LOGE("invalid wlan radar event buf"); 11370 return QDF_STATUS_E_FAILURE; 11371 } 11372 11373 radar_event = param_tlv->fixed_param; 11374 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 11375 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 11376 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 11377 wlan_radar_event->rssi = radar_event->rssi; 11378 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 11379 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 11380 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 11381 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 11382 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 11383 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 11384 if (radar_event->pulse_flags & 11385 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 11386 wlan_radar_event->is_psidx_diff_valid = true; 11387 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 11388 } else { 11389 wlan_radar_event->is_psidx_diff_valid = false; 11390 } 11391 11392 wlan_radar_event->pdev_id = radar_event->pdev_id; 11393 11394 return QDF_STATUS_SUCCESS; 11395 } 11396 #else 11397 static QDF_STATUS extract_wlan_radar_event_info_tlv( 11398 wmi_unified_t wmi_handle, 11399 uint8_t *evt_buf, 11400 struct radar_event_info *wlan_radar_event, 11401 uint32_t len) 11402 { 11403 return QDF_STATUS_SUCCESS; 11404 } 11405 #endif 11406 #endif 11407 11408 /** 11409 * send_get_rcpi_cmd_tlv() - send request for rcpi value 11410 * @wmi_handle: wmi handle 11411 * @get_rcpi_param: rcpi params 11412 * 11413 * Return: QDF status 11414 */ 11415 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 11416 struct rcpi_req *get_rcpi_param) 11417 { 11418 wmi_buf_t buf; 11419 wmi_request_rcpi_cmd_fixed_param *cmd; 11420 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 11421 11422 buf = wmi_buf_alloc(wmi_handle, len); 11423 if (!buf) 11424 return QDF_STATUS_E_NOMEM; 11425 11426 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 11427 WMITLV_SET_HDR(&cmd->tlv_header, 11428 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 11429 WMITLV_GET_STRUCT_TLVLEN 11430 (wmi_request_rcpi_cmd_fixed_param)); 11431 11432 cmd->vdev_id = get_rcpi_param->vdev_id; 11433 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 11434 &cmd->peer_macaddr); 11435 11436 switch (get_rcpi_param->measurement_type) { 11437 11438 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 11439 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 11440 break; 11441 11442 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 11443 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 11444 break; 11445 11446 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 11447 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 11448 break; 11449 11450 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 11451 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 11452 break; 11453 11454 default: 11455 /* 11456 * invalid rcpi measurement type, fall back to 11457 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 11458 */ 11459 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 11460 break; 11461 } 11462 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 11463 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 11464 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11465 WMI_REQUEST_RCPI_CMDID)) { 11466 11467 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 11468 __func__); 11469 wmi_buf_free(buf); 11470 return QDF_STATUS_E_FAILURE; 11471 } 11472 11473 return QDF_STATUS_SUCCESS; 11474 } 11475 11476 /** 11477 * extract_rcpi_response_event_tlv() - Extract RCPI event params 11478 * @wmi_handle: wmi handle 11479 * @evt_buf: pointer to event buffer 11480 * @res: pointer to hold rcpi response from firmware 11481 * 11482 * Return: QDF_STATUS_SUCCESS for successful event parse 11483 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 11484 */ 11485 static QDF_STATUS 11486 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 11487 void *evt_buf, struct rcpi_res *res) 11488 { 11489 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 11490 wmi_update_rcpi_event_fixed_param *event; 11491 11492 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 11493 if (!param_buf) { 11494 WMI_LOGE(FL("Invalid rcpi event")); 11495 return QDF_STATUS_E_INVAL; 11496 } 11497 11498 event = param_buf->fixed_param; 11499 res->vdev_id = event->vdev_id; 11500 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 11501 11502 switch (event->measurement_type) { 11503 11504 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 11505 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 11506 break; 11507 11508 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 11509 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 11510 break; 11511 11512 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 11513 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 11514 break; 11515 11516 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 11517 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 11518 break; 11519 11520 default: 11521 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 11522 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 11523 return QDF_STATUS_E_FAILURE; 11524 } 11525 11526 if (event->status) 11527 return QDF_STATUS_E_FAILURE; 11528 else 11529 return QDF_STATUS_SUCCESS; 11530 } 11531 11532 /** 11533 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 11534 * host to target defines. For legacy there is not conversion 11535 * required. Just return pdev_id as it is. 11536 * @param pdev_id: host pdev_id to be converted. 11537 * Return: target pdev_id after conversion. 11538 */ 11539 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 11540 wmi_unified_t wmi_handle, 11541 uint32_t pdev_id) 11542 { 11543 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 11544 return WMI_PDEV_ID_SOC; 11545 11546 /*No conversion required*/ 11547 return pdev_id; 11548 } 11549 11550 /** 11551 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 11552 * target to host defines. For legacy there is not conversion 11553 * required. Just return pdev_id as it is. 11554 * @param pdev_id: target pdev_id to be converted. 11555 * Return: host pdev_id after conversion. 11556 */ 11557 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 11558 wmi_unified_t wmi_handle, 11559 uint32_t pdev_id) 11560 { 11561 /*No conversion required*/ 11562 return pdev_id; 11563 } 11564 11565 /** 11566 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 11567 * host to target defines. For legacy there is not conversion 11568 * required. Just return phy_id as it is. 11569 * @param pdev_id: host phy_id to be converted. 11570 * Return: target phy_id after conversion. 11571 */ 11572 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 11573 wmi_unified_t wmi_handle, 11574 uint32_t phy_id) 11575 { 11576 /*No conversion required*/ 11577 return phy_id; 11578 } 11579 11580 /** 11581 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 11582 * target to host defines. For legacy there is not conversion 11583 * required. Just return phy_id as it is. 11584 * @param pdev_id: target phy_id to be converted. 11585 * Return: host phy_id after conversion. 11586 */ 11587 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 11588 wmi_unified_t wmi_handle, 11589 uint32_t phy_id) 11590 { 11591 /*No conversion required*/ 11592 return phy_id; 11593 } 11594 11595 /** 11596 * send_set_country_cmd_tlv() - WMI scan channel list function 11597 * @param wmi_handle : handle to WMI. 11598 * @param param : pointer to hold scan channel list parameter 11599 * 11600 * Return: 0 on success and -ve on failure. 11601 */ 11602 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 11603 struct set_country *params) 11604 { 11605 wmi_buf_t buf; 11606 QDF_STATUS qdf_status; 11607 wmi_set_current_country_cmd_fixed_param *cmd; 11608 uint16_t len = sizeof(*cmd); 11609 uint8_t pdev_id = params->pdev_id; 11610 11611 buf = wmi_buf_alloc(wmi_handle, len); 11612 if (!buf) { 11613 qdf_status = QDF_STATUS_E_NOMEM; 11614 goto end; 11615 } 11616 11617 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 11618 WMITLV_SET_HDR(&cmd->tlv_header, 11619 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 11620 WMITLV_GET_STRUCT_TLVLEN 11621 (wmi_set_current_country_cmd_fixed_param)); 11622 11623 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 11624 wmi_handle, 11625 pdev_id); 11626 WMI_LOGD("setting current country to %s and target pdev_id = %u", 11627 params->country, cmd->pdev_id); 11628 11629 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 11630 11631 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 11632 qdf_status = wmi_unified_cmd_send(wmi_handle, 11633 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 11634 11635 if (QDF_IS_STATUS_ERROR(qdf_status)) { 11636 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 11637 wmi_buf_free(buf); 11638 } 11639 11640 end: 11641 return qdf_status; 11642 } 11643 11644 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 11645 WMI_SET_BITS(alpha, 0, 8, val0); \ 11646 WMI_SET_BITS(alpha, 8, 8, val1); \ 11647 WMI_SET_BITS(alpha, 16, 8, val2); \ 11648 } while (0) 11649 11650 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 11651 uint8_t pdev_id, struct cc_regdmn_s *rd) 11652 { 11653 wmi_set_init_country_cmd_fixed_param *cmd; 11654 uint16_t len; 11655 wmi_buf_t buf; 11656 int ret; 11657 11658 len = sizeof(wmi_set_init_country_cmd_fixed_param); 11659 buf = wmi_buf_alloc(wmi_handle, len); 11660 if (!buf) 11661 return QDF_STATUS_E_NOMEM; 11662 11663 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 11664 WMITLV_SET_HDR(&cmd->tlv_header, 11665 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 11666 WMITLV_GET_STRUCT_TLVLEN 11667 (wmi_set_init_country_cmd_fixed_param)); 11668 11669 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11670 wmi_handle, 11671 pdev_id); 11672 11673 if (rd->flags == CC_IS_SET) { 11674 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 11675 cmd->country_code.country_id = rd->cc.country_code; 11676 } else if (rd->flags == ALPHA_IS_SET) { 11677 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 11678 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 11679 rd->cc.alpha[0], 11680 rd->cc.alpha[1], 11681 rd->cc.alpha[2]); 11682 } else if (rd->flags == REGDMN_IS_SET) { 11683 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 11684 cmd->country_code.domain_code = rd->cc.regdmn_id; 11685 } 11686 11687 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 11688 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11689 WMI_SET_INIT_COUNTRY_CMDID); 11690 if (ret) { 11691 WMI_LOGE("Failed to config wow wakeup event"); 11692 wmi_buf_free(buf); 11693 return QDF_STATUS_E_FAILURE; 11694 } 11695 11696 return QDF_STATUS_SUCCESS; 11697 } 11698 11699 /** 11700 * send_obss_detection_cfg_cmd_tlv() - send obss detection 11701 * configurations to firmware. 11702 * @wmi_handle: wmi handle 11703 * @obss_cfg_param: obss detection configurations 11704 * 11705 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 11706 * 11707 * Return: QDF_STATUS 11708 */ 11709 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11710 struct wmi_obss_detection_cfg_param *obss_cfg_param) 11711 { 11712 wmi_buf_t buf; 11713 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 11714 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 11715 11716 buf = wmi_buf_alloc(wmi_handle, len); 11717 if (!buf) 11718 return QDF_STATUS_E_NOMEM; 11719 11720 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 11721 WMITLV_SET_HDR(&cmd->tlv_header, 11722 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 11723 WMITLV_GET_STRUCT_TLVLEN 11724 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 11725 11726 cmd->vdev_id = obss_cfg_param->vdev_id; 11727 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 11728 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 11729 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 11730 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 11731 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 11732 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 11733 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 11734 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 11735 11736 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 11737 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11738 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 11739 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 11740 wmi_buf_free(buf); 11741 return QDF_STATUS_E_FAILURE; 11742 } 11743 11744 return QDF_STATUS_SUCCESS; 11745 } 11746 11747 /** 11748 * extract_obss_detection_info_tlv() - Extract obss detection info 11749 * received from firmware. 11750 * @evt_buf: pointer to event buffer 11751 * @obss_detection: Pointer to hold obss detection info 11752 * 11753 * Return: QDF_STATUS 11754 */ 11755 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 11756 struct wmi_obss_detect_info 11757 *obss_detection) 11758 { 11759 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 11760 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 11761 11762 if (!obss_detection) { 11763 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 11764 return QDF_STATUS_E_INVAL; 11765 } 11766 11767 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 11768 if (!param_buf) { 11769 WMI_LOGE("%s: Invalid evt_buf", __func__); 11770 return QDF_STATUS_E_INVAL; 11771 } 11772 11773 fix_param = param_buf->fixed_param; 11774 obss_detection->vdev_id = fix_param->vdev_id; 11775 obss_detection->matched_detection_masks = 11776 fix_param->matched_detection_masks; 11777 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 11778 &obss_detection->matched_bssid_addr[0]); 11779 switch (fix_param->reason) { 11780 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 11781 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 11782 break; 11783 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 11784 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 11785 break; 11786 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 11787 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 11788 break; 11789 default: 11790 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 11791 return QDF_STATUS_E_INVAL; 11792 } 11793 11794 return QDF_STATUS_SUCCESS; 11795 } 11796 11797 /** 11798 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 11799 * @wmi_handle: wmi handle 11800 * @params: pointer to request structure 11801 * 11802 * Return: QDF_STATUS 11803 */ 11804 static QDF_STATUS 11805 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 11806 struct wmi_roam_scan_stats_req *params) 11807 { 11808 wmi_buf_t buf; 11809 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 11810 WMITLV_TAG_ID tag; 11811 uint32_t size; 11812 uint32_t len = sizeof(*cmd); 11813 11814 buf = wmi_buf_alloc(wmi_handle, len); 11815 if (!buf) 11816 return QDF_STATUS_E_FAILURE; 11817 11818 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 11819 11820 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 11821 size = WMITLV_GET_STRUCT_TLVLEN( 11822 wmi_request_roam_scan_stats_cmd_fixed_param); 11823 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 11824 11825 cmd->vdev_id = params->vdev_id; 11826 11827 WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id); 11828 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11829 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 11830 WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID", 11831 __func__); 11832 wmi_buf_free(buf); 11833 return QDF_STATUS_E_FAILURE; 11834 } 11835 11836 return QDF_STATUS_SUCCESS; 11837 } 11838 11839 /** 11840 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 11841 * @wmi_handle: wmi handle 11842 * @evt_buf: pointer to event buffer 11843 * @vdev_id: output pointer to hold vdev id 11844 * @res_param: output pointer to hold the allocated response 11845 * 11846 * Return: QDF_STATUS 11847 */ 11848 static QDF_STATUS 11849 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11850 uint32_t *vdev_id, 11851 struct wmi_roam_scan_stats_res **res_param) 11852 { 11853 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 11854 wmi_roam_scan_stats_event_fixed_param *fixed_param; 11855 uint32_t *client_id = NULL; 11856 wmi_roaming_timestamp *timestamp = NULL; 11857 uint32_t *num_channels = NULL; 11858 uint32_t *chan_info = NULL; 11859 wmi_mac_addr *old_bssid = NULL; 11860 uint32_t *is_roaming_success = NULL; 11861 wmi_mac_addr *new_bssid = NULL; 11862 uint32_t *num_roam_candidates = NULL; 11863 wmi_roam_scan_trigger_reason *roam_reason = NULL; 11864 wmi_mac_addr *bssid = NULL; 11865 uint32_t *score = NULL; 11866 uint32_t *channel = NULL; 11867 uint32_t *rssi = NULL; 11868 int chan_idx = 0, cand_idx = 0; 11869 uint32_t total_len; 11870 struct wmi_roam_scan_stats_res *res; 11871 uint32_t i, j; 11872 uint32_t num_scans, scan_param_size; 11873 11874 *res_param = NULL; 11875 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 11876 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 11877 if (!param_buf) { 11878 WMI_LOGE(FL("Invalid roam scan stats event")); 11879 return QDF_STATUS_E_INVAL; 11880 } 11881 11882 fixed_param = param_buf->fixed_param; 11883 11884 num_scans = fixed_param->num_roam_scans; 11885 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 11886 *vdev_id = fixed_param->vdev_id; 11887 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 11888 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 11889 num_scans, WMI_ROAM_SCAN_STATS_MAX); 11890 return QDF_STATUS_E_INVAL; 11891 } 11892 11893 total_len = sizeof(*res) + num_scans * scan_param_size; 11894 11895 res = qdf_mem_malloc(total_len); 11896 if (!res) 11897 return QDF_STATUS_E_NOMEM; 11898 11899 if (!num_scans) { 11900 *res_param = res; 11901 return QDF_STATUS_SUCCESS; 11902 } 11903 11904 if (param_buf->client_id && 11905 param_buf->num_client_id == num_scans) 11906 client_id = param_buf->client_id; 11907 11908 if (param_buf->timestamp && 11909 param_buf->num_timestamp == num_scans) 11910 timestamp = param_buf->timestamp; 11911 11912 if (param_buf->old_bssid && 11913 param_buf->num_old_bssid == num_scans) 11914 old_bssid = param_buf->old_bssid; 11915 11916 if (param_buf->new_bssid && 11917 param_buf->num_new_bssid == num_scans) 11918 new_bssid = param_buf->new_bssid; 11919 11920 if (param_buf->is_roaming_success && 11921 param_buf->num_is_roaming_success == num_scans) 11922 is_roaming_success = param_buf->is_roaming_success; 11923 11924 if (param_buf->roam_reason && 11925 param_buf->num_roam_reason == num_scans) 11926 roam_reason = param_buf->roam_reason; 11927 11928 if (param_buf->num_channels && 11929 param_buf->num_num_channels == num_scans) { 11930 uint32_t count, chan_info_sum = 0; 11931 11932 num_channels = param_buf->num_channels; 11933 for (count = 0; count < param_buf->num_num_channels; count++) { 11934 if (param_buf->num_channels[count] > 11935 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 11936 wmi_err_rl("%u exceeded max scan channels %u", 11937 param_buf->num_channels[count], 11938 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 11939 goto error; 11940 } 11941 chan_info_sum += param_buf->num_channels[count]; 11942 } 11943 11944 if (param_buf->chan_info && 11945 param_buf->num_chan_info == chan_info_sum) 11946 chan_info = param_buf->chan_info; 11947 } 11948 11949 if (param_buf->num_roam_candidates && 11950 param_buf->num_num_roam_candidates == num_scans) { 11951 uint32_t cnt, roam_cand_sum = 0; 11952 11953 num_roam_candidates = param_buf->num_roam_candidates; 11954 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 11955 if (param_buf->num_roam_candidates[cnt] > 11956 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 11957 wmi_err_rl("%u exceeded max scan cand %u", 11958 param_buf->num_roam_candidates[cnt], 11959 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 11960 goto error; 11961 } 11962 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 11963 } 11964 11965 if (param_buf->bssid && 11966 param_buf->num_bssid == roam_cand_sum) 11967 bssid = param_buf->bssid; 11968 11969 if (param_buf->score && 11970 param_buf->num_score == roam_cand_sum) 11971 score = param_buf->score; 11972 11973 if (param_buf->channel && 11974 param_buf->num_channel == roam_cand_sum) 11975 channel = param_buf->channel; 11976 11977 if (param_buf->rssi && 11978 param_buf->num_rssi == roam_cand_sum) 11979 rssi = param_buf->rssi; 11980 } 11981 11982 res->num_roam_scans = num_scans; 11983 for (i = 0; i < num_scans; i++) { 11984 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 11985 11986 if (timestamp) 11987 roam->time_stamp = timestamp[i].lower32bit | 11988 (timestamp[i].upper32bit << 31); 11989 11990 if (client_id) 11991 roam->client_id = client_id[i]; 11992 11993 if (num_channels) { 11994 roam->num_scan_chans = num_channels[i]; 11995 if (chan_info) { 11996 for (j = 0; j < num_channels[i]; j++) 11997 roam->scan_freqs[j] = 11998 chan_info[chan_idx++]; 11999 } 12000 } 12001 12002 if (is_roaming_success) 12003 roam->is_roam_successful = is_roaming_success[i]; 12004 12005 if (roam_reason) { 12006 roam->trigger_id = roam_reason[i].trigger_id; 12007 roam->trigger_value = roam_reason[i].trigger_value; 12008 } 12009 12010 if (num_roam_candidates) { 12011 roam->num_roam_candidates = num_roam_candidates[i]; 12012 12013 for (j = 0; j < num_roam_candidates[i]; j++) { 12014 if (score) 12015 roam->cand[j].score = score[cand_idx]; 12016 if (rssi) 12017 roam->cand[j].rssi = rssi[cand_idx]; 12018 if (channel) 12019 roam->cand[j].freq = 12020 channel[cand_idx]; 12021 12022 if (bssid) 12023 WMI_MAC_ADDR_TO_CHAR_ARRAY( 12024 &bssid[cand_idx], 12025 roam->cand[j].bssid); 12026 12027 cand_idx++; 12028 } 12029 } 12030 12031 if (old_bssid) 12032 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 12033 roam->old_bssid); 12034 12035 if (new_bssid) 12036 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 12037 roam->new_bssid); 12038 } 12039 12040 *res_param = res; 12041 12042 return QDF_STATUS_SUCCESS; 12043 error: 12044 qdf_mem_free(res); 12045 return QDF_STATUS_E_FAILURE; 12046 } 12047 12048 /** 12049 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 12050 * @wmi_handle: wmi handle 12051 * @evt_buf: pointer to event buffer 12052 * @vdev_id: output pointer to hold vdev id 12053 * @tx_status: output pointer to hold the tx_status 12054 * 12055 * Return: QDF_STATUS 12056 */ 12057 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 12058 void *evt_buf, 12059 uint32_t *vdev_id, 12060 uint32_t *tx_status) { 12061 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 12062 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 12063 12064 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 12065 if (!param_buf) { 12066 WMI_LOGE("Invalid offload bcn tx status event buffer"); 12067 return QDF_STATUS_E_INVAL; 12068 } 12069 12070 bcn_tx_status_event = param_buf->fixed_param; 12071 *vdev_id = bcn_tx_status_event->vdev_id; 12072 *tx_status = bcn_tx_status_event->tx_status; 12073 12074 return QDF_STATUS_SUCCESS; 12075 } 12076 12077 #ifdef WLAN_SUPPORT_GREEN_AP 12078 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 12079 uint8_t *evt_buf, 12080 struct wlan_green_ap_egap_status_info *egap_status_info_params) 12081 { 12082 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 12083 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 12084 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 12085 12086 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 12087 if (!param_buf) { 12088 WMI_LOGE("Invalid EGAP Info status event buffer"); 12089 return QDF_STATUS_E_INVAL; 12090 } 12091 12092 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 12093 param_buf->fixed_param; 12094 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 12095 param_buf->chainmask_list; 12096 12097 if (!egap_info_event || !chainmask_event) { 12098 WMI_LOGE("Invalid EGAP Info event or chainmask event"); 12099 return QDF_STATUS_E_INVAL; 12100 } 12101 12102 egap_status_info_params->status = egap_info_event->status; 12103 egap_status_info_params->mac_id = chainmask_event->mac_id; 12104 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 12105 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 12106 12107 return QDF_STATUS_SUCCESS; 12108 } 12109 #endif 12110 12111 /* 12112 * extract_comb_phyerr_tlv() - extract comb phy error from event 12113 * @wmi_handle: wmi handle 12114 * @evt_buf: pointer to event buffer 12115 * @datalen: data length of event buffer 12116 * @buf_offset: Pointer to hold value of current event buffer offset 12117 * post extraction 12118 * @phyerr: Pointer to hold phyerr 12119 * 12120 * Return: QDF_STATUS 12121 */ 12122 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 12123 void *evt_buf, 12124 uint16_t datalen, 12125 uint16_t *buf_offset, 12126 wmi_host_phyerr_t *phyerr) 12127 { 12128 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 12129 wmi_comb_phyerr_rx_hdr *pe_hdr; 12130 12131 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 12132 if (!param_tlvs) { 12133 WMI_LOGD("%s: Received null data from FW", __func__); 12134 return QDF_STATUS_E_FAILURE; 12135 } 12136 12137 pe_hdr = param_tlvs->hdr; 12138 if (!pe_hdr) { 12139 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 12140 return QDF_STATUS_E_FAILURE; 12141 } 12142 12143 /* Ensure it's at least the size of the header */ 12144 if (datalen < sizeof(*pe_hdr)) { 12145 WMI_LOGD("%s: Expected minimum size %zu, received %d", 12146 __func__, sizeof(*pe_hdr), datalen); 12147 return QDF_STATUS_E_FAILURE; 12148 } 12149 12150 phyerr->pdev_id = wmi_handle->ops-> 12151 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 12152 phyerr->tsf64 = pe_hdr->tsf_l32; 12153 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 12154 phyerr->bufp = param_tlvs->bufp; 12155 12156 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 12157 WMI_LOGD("Invalid buf_len %d, num_bufp %d", 12158 pe_hdr->buf_len, param_tlvs->num_bufp); 12159 return QDF_STATUS_E_FAILURE; 12160 } 12161 12162 phyerr->buf_len = pe_hdr->buf_len; 12163 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 12164 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 12165 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 12166 12167 return QDF_STATUS_SUCCESS; 12168 } 12169 12170 /** 12171 * extract_single_phyerr_tlv() - extract single phy error from event 12172 * @wmi_handle: wmi handle 12173 * @evt_buf: pointer to event buffer 12174 * @datalen: data length of event buffer 12175 * @buf_offset: Pointer to hold value of current event buffer offset 12176 * post extraction 12177 * @phyerr: Pointer to hold phyerr 12178 * 12179 * Return: QDF_STATUS 12180 */ 12181 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 12182 void *evt_buf, 12183 uint16_t datalen, 12184 uint16_t *buf_offset, 12185 wmi_host_phyerr_t *phyerr) 12186 { 12187 wmi_single_phyerr_rx_event *ev; 12188 uint16_t n = *buf_offset; 12189 uint8_t *data = (uint8_t *)evt_buf; 12190 12191 if (n < datalen) { 12192 if ((datalen - n) < sizeof(ev->hdr)) { 12193 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 12194 __func__, datalen, n, sizeof(ev->hdr)); 12195 return QDF_STATUS_E_FAILURE; 12196 } 12197 12198 /* 12199 * Obtain a pointer to the beginning of the current event. 12200 * data[0] is the beginning of the WMI payload. 12201 */ 12202 ev = (wmi_single_phyerr_rx_event *)&data[n]; 12203 12204 /* 12205 * Sanity check the buffer length of the event against 12206 * what we currently have. 12207 * 12208 * Since buf_len is 32 bits, we check if it overflows 12209 * a large 32 bit value. It's not 0x7fffffff because 12210 * we increase n by (buf_len + sizeof(hdr)), which would 12211 * in itself cause n to overflow. 12212 * 12213 * If "int" is 64 bits then this becomes a moot point. 12214 */ 12215 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 12216 WMI_LOGD("%s: buf_len is garbage 0x%x", 12217 __func__, ev->hdr.buf_len); 12218 return QDF_STATUS_E_FAILURE; 12219 } 12220 12221 if ((n + ev->hdr.buf_len) > datalen) { 12222 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 12223 __func__, n, ev->hdr.buf_len, datalen); 12224 return QDF_STATUS_E_FAILURE; 12225 } 12226 12227 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 12228 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 12229 phyerr->bufp = &ev->bufp[0]; 12230 phyerr->buf_len = ev->hdr.buf_len; 12231 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 12232 12233 /* 12234 * Advance the buffer pointer to the next PHY error. 12235 * buflen is the length of this payload, so we need to 12236 * advance past the current header _AND_ the payload. 12237 */ 12238 n += sizeof(*ev) + ev->hdr.buf_len; 12239 } 12240 *buf_offset = n; 12241 12242 return QDF_STATUS_SUCCESS; 12243 } 12244 12245 /** 12246 * extract_esp_estimation_ev_param_tlv() - extract air time from event 12247 * @wmi_handle: wmi handle 12248 * @evt_buf: pointer to event buffer 12249 * @param: Pointer to hold esp event 12250 * 12251 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 12252 */ 12253 static QDF_STATUS 12254 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 12255 void *evt_buf, 12256 struct esp_estimation_event *param) 12257 { 12258 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 12259 wmi_esp_estimate_event_fixed_param *esp_event; 12260 12261 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 12262 if (!param_buf) { 12263 WMI_LOGE("Invalid ESP Estimate Event buffer"); 12264 return QDF_STATUS_E_INVAL; 12265 } 12266 esp_event = param_buf->fixed_param; 12267 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 12268 12269 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 12270 wmi_handle, 12271 esp_event->pdev_id); 12272 12273 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 12274 return QDF_STATUS_E_FAILURE; 12275 12276 return QDF_STATUS_SUCCESS; 12277 } 12278 12279 /* 12280 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 12281 * updating bss color change within firmware when AP announces bss color change. 12282 * @wmi_handle: wmi handle 12283 * @vdev_id: vdev ID 12284 * @enable: enable bss color change within firmware 12285 * 12286 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 12287 * 12288 * Return: QDF_STATUS 12289 */ 12290 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 12291 uint32_t vdev_id, 12292 bool enable) 12293 { 12294 wmi_buf_t buf; 12295 wmi_bss_color_change_enable_fixed_param *cmd; 12296 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 12297 12298 buf = wmi_buf_alloc(wmi_handle, len); 12299 if (!buf) 12300 return QDF_STATUS_E_NOMEM; 12301 12302 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 12303 WMITLV_SET_HDR(&cmd->tlv_header, 12304 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 12305 WMITLV_GET_STRUCT_TLVLEN 12306 (wmi_bss_color_change_enable_fixed_param)); 12307 cmd->vdev_id = vdev_id; 12308 cmd->enable = enable; 12309 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 12310 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12311 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 12312 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 12313 wmi_buf_free(buf); 12314 return QDF_STATUS_E_FAILURE; 12315 } 12316 12317 return QDF_STATUS_SUCCESS; 12318 } 12319 12320 /** 12321 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 12322 * configurations to firmware. 12323 * @wmi_handle: wmi handle 12324 * @cfg_param: obss detection configurations 12325 * 12326 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 12327 * 12328 * Return: QDF_STATUS 12329 */ 12330 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 12331 wmi_unified_t wmi_handle, 12332 struct wmi_obss_color_collision_cfg_param *cfg_param) 12333 { 12334 wmi_buf_t buf; 12335 wmi_obss_color_collision_det_config_fixed_param *cmd; 12336 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 12337 12338 buf = wmi_buf_alloc(wmi_handle, len); 12339 if (!buf) 12340 return QDF_STATUS_E_NOMEM; 12341 12342 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 12343 buf); 12344 WMITLV_SET_HDR(&cmd->tlv_header, 12345 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 12346 WMITLV_GET_STRUCT_TLVLEN 12347 (wmi_obss_color_collision_det_config_fixed_param)); 12348 cmd->vdev_id = cfg_param->vdev_id; 12349 cmd->flags = cfg_param->flags; 12350 cmd->current_bss_color = cfg_param->current_bss_color; 12351 cmd->detection_period_ms = cfg_param->detection_period_ms; 12352 cmd->scan_period_ms = cfg_param->scan_period_ms; 12353 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 12354 12355 switch (cfg_param->evt_type) { 12356 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 12357 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 12358 break; 12359 case OBSS_COLOR_COLLISION_DETECTION: 12360 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 12361 break; 12362 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 12363 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 12364 break; 12365 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 12366 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 12367 break; 12368 default: 12369 WMI_LOGE("%s: invalid event type: %d", 12370 __func__, cfg_param->evt_type); 12371 wmi_buf_free(buf); 12372 return QDF_STATUS_E_FAILURE; 12373 } 12374 12375 WMI_LOGD("%s: evt_type: %d vdev id: %d current_bss_color: %d\n" 12376 "detection_period_ms: %d scan_period_ms: %d\n" 12377 "free_slot_expiry_timer_ms: %d", 12378 __func__, cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 12379 cmd->detection_period_ms, cmd->scan_period_ms, 12380 cmd->free_slot_expiry_time_ms); 12381 12382 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 12383 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12384 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 12385 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 12386 __func__, cfg_param->vdev_id); 12387 wmi_buf_free(buf); 12388 return QDF_STATUS_E_FAILURE; 12389 } 12390 12391 return QDF_STATUS_SUCCESS; 12392 } 12393 12394 /** 12395 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 12396 * received from firmware. 12397 * @evt_buf: pointer to event buffer 12398 * @info: Pointer to hold bss collision info 12399 * 12400 * Return: QDF_STATUS 12401 */ 12402 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 12403 struct wmi_obss_color_collision_info *info) 12404 { 12405 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 12406 wmi_obss_color_collision_evt_fixed_param *fix_param; 12407 12408 if (!info) { 12409 WMI_LOGE("%s: Invalid obss color buffer", __func__); 12410 return QDF_STATUS_E_INVAL; 12411 } 12412 12413 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 12414 evt_buf; 12415 if (!param_buf) { 12416 WMI_LOGE("%s: Invalid evt_buf", __func__); 12417 return QDF_STATUS_E_INVAL; 12418 } 12419 12420 fix_param = param_buf->fixed_param; 12421 info->vdev_id = fix_param->vdev_id; 12422 info->obss_color_bitmap_bit0to31 = 12423 fix_param->bss_color_bitmap_bit0to31; 12424 info->obss_color_bitmap_bit32to63 = 12425 fix_param->bss_color_bitmap_bit32to63; 12426 12427 switch (fix_param->evt_type) { 12428 case WMI_BSS_COLOR_COLLISION_DISABLE: 12429 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 12430 break; 12431 case WMI_BSS_COLOR_COLLISION_DETECTION: 12432 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 12433 break; 12434 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 12435 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 12436 break; 12437 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 12438 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 12439 break; 12440 default: 12441 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 12442 __func__, fix_param->evt_type, fix_param->vdev_id); 12443 return QDF_STATUS_E_FAILURE; 12444 } 12445 12446 return QDF_STATUS_SUCCESS; 12447 } 12448 12449 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 12450 { 12451 struct wmi_ops *ops = wmi_handle->ops; 12452 12453 ops->send_obss_color_collision_cfg_cmd = 12454 send_obss_color_collision_cfg_cmd_tlv; 12455 ops->extract_obss_color_collision_info = 12456 extract_obss_color_collision_info_tlv; 12457 } 12458 12459 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 12460 static QDF_STATUS 12461 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 12462 struct config_fils_params *param) 12463 { 12464 wmi_buf_t buf; 12465 wmi_enable_fils_cmd_fixed_param *cmd; 12466 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 12467 12468 buf = wmi_buf_alloc(wmi_handle, len); 12469 if (!buf) 12470 return QDF_STATUS_E_NOMEM; 12471 12472 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 12473 buf); 12474 WMITLV_SET_HDR(&cmd->tlv_header, 12475 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 12476 WMITLV_GET_STRUCT_TLVLEN 12477 (wmi_enable_fils_cmd_fixed_param)); 12478 cmd->vdev_id = param->vdev_id; 12479 cmd->fd_period = param->fd_period; 12480 if (param->send_prb_rsp_frame) 12481 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 12482 WMI_LOGD("%s: vdev id: %d fd_period: %d cmd->Flags %d", 12483 __func__, cmd->vdev_id, cmd->fd_period, cmd->flags); 12484 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 12485 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12486 WMI_ENABLE_FILS_CMDID)) { 12487 WMI_LOGE("%s: Sending FILS cmd failed, vdev_id: %d", 12488 __func__, param->vdev_id); 12489 wmi_buf_free(buf); 12490 return QDF_STATUS_E_FAILURE; 12491 } 12492 12493 return QDF_STATUS_SUCCESS; 12494 } 12495 #endif 12496 12497 #ifdef WLAN_MWS_INFO_DEBUGFS 12498 /** 12499 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 12500 * 12501 * @wmi_handle: wmi handle 12502 * @vdev_id: vdev id 12503 * @cmd_id: Coex command id 12504 * 12505 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 12506 * 12507 * Return: QDF_STATUS 12508 */ 12509 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 12510 uint32_t vdev_id, 12511 uint32_t cmd_id) 12512 { 12513 wmi_buf_t buf; 12514 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 12515 uint16_t len = sizeof(*cmd); 12516 int ret; 12517 12518 buf = wmi_buf_alloc(wmi_handle, len); 12519 if (!buf) { 12520 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 12521 return QDF_STATUS_E_NOMEM; 12522 } 12523 12524 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 12525 WMITLV_SET_HDR(&cmd->tlv_header, 12526 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 12527 WMITLV_GET_STRUCT_TLVLEN 12528 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 12529 cmd->vdev_id = vdev_id; 12530 cmd->cmd_id = cmd_id; 12531 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 12532 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12533 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 12534 if (QDF_IS_STATUS_ERROR(ret)) { 12535 WMI_LOGE("Failed to send set param command ret = %d", ret); 12536 wmi_buf_free(buf); 12537 } 12538 return ret; 12539 } 12540 #endif 12541 12542 #ifdef WIFI_POS_CONVERGED 12543 /** 12544 * extract_oem_response_param_tlv() - Extract oem response params 12545 * @wmi_handle: wmi handle 12546 * @resp_buf: response buffer 12547 * @oem_resp_param: pointer to hold oem response params 12548 * 12549 * Return: QDF_STATUS_SUCCESS on success or proper error code. 12550 */ 12551 static QDF_STATUS 12552 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 12553 struct wmi_oem_response_param *oem_resp_param) 12554 { 12555 uint64_t temp_addr; 12556 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 12557 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 12558 12559 if (!param_buf) { 12560 WMI_LOGE("Invalid OEM response"); 12561 return QDF_STATUS_E_INVAL; 12562 } 12563 12564 if (param_buf->num_data) { 12565 oem_resp_param->num_data1 = param_buf->num_data; 12566 oem_resp_param->data_1 = param_buf->data; 12567 } 12568 12569 if (param_buf->num_data2) { 12570 oem_resp_param->num_data2 = param_buf->num_data2; 12571 oem_resp_param->data_2 = param_buf->data2; 12572 } 12573 12574 if (param_buf->indirect_data) { 12575 oem_resp_param->indirect_data.pdev_id = 12576 param_buf->indirect_data->pdev_id; 12577 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 12578 oem_resp_param->indirect_data.addr = 12579 param_buf->indirect_data->addr_lo + 12580 ((uint64_t)temp_addr << 32); 12581 oem_resp_param->indirect_data.len = 12582 param_buf->indirect_data->len; 12583 } 12584 12585 return QDF_STATUS_SUCCESS; 12586 } 12587 #endif /* WIFI_POS_CONVERGED */ 12588 12589 /** 12590 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 12591 * @wmi_handle: wmi handle 12592 * @event_buf: pointer to event buffer 12593 * @cmd_status: status of HW mode change command 12594 * 12595 * Return QDF_STATUS_SUCCESS on success or proper error code. 12596 */ 12597 static QDF_STATUS 12598 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12599 uint32_t *cmd_status) 12600 { 12601 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 12602 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 12603 12604 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 12605 if (!param_buf) { 12606 WMI_LOGE("Invalid mode change event buffer"); 12607 return QDF_STATUS_E_INVAL; 12608 } 12609 12610 fixed_param = param_buf->fixed_param; 12611 if (!fixed_param) { 12612 WMI_LOGE("Invalid fixed param"); 12613 return QDF_STATUS_E_INVAL; 12614 } 12615 12616 *cmd_status = fixed_param->status; 12617 return QDF_STATUS_SUCCESS; 12618 } 12619 12620 #ifdef FEATURE_ANI_LEVEL_REQUEST 12621 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 12622 uint32_t *freqs, 12623 uint8_t num_freqs) 12624 { 12625 wmi_buf_t buf; 12626 wmi_get_channel_ani_cmd_fixed_param *cmd; 12627 QDF_STATUS ret; 12628 uint32_t len; 12629 A_UINT32 *chan_list; 12630 uint8_t i, *buf_ptr; 12631 12632 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 12633 WMI_TLV_HDR_SIZE + 12634 num_freqs * sizeof(A_UINT32); 12635 12636 buf = wmi_buf_alloc(wmi_handle, len); 12637 if (!buf) 12638 return QDF_STATUS_E_FAILURE; 12639 12640 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12641 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 12642 WMITLV_SET_HDR(&cmd->tlv_header, 12643 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 12644 WMITLV_GET_STRUCT_TLVLEN( 12645 wmi_get_channel_ani_cmd_fixed_param)); 12646 12647 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 12648 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 12649 (num_freqs * sizeof(A_UINT32))); 12650 12651 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 12652 for (i = 0; i < num_freqs; i++) { 12653 chan_list[i] = freqs[i]; 12654 WMI_LOGD("Requesting ANI for channel[%d]", chan_list[i]); 12655 } 12656 12657 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12658 WMI_GET_CHANNEL_ANI_CMDID); 12659 12660 if (QDF_IS_STATUS_ERROR(ret)) { 12661 WMI_LOGE("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 12662 wmi_buf_free(buf); 12663 } 12664 12665 return ret; 12666 } 12667 12668 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 12669 struct wmi_host_ani_level_event **info, 12670 uint32_t *num_freqs) 12671 { 12672 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 12673 wmi_get_channel_ani_event_fixed_param *fixed_param; 12674 wmi_channel_ani_info_tlv_param *tlv_params; 12675 uint8_t *buf_ptr, i; 12676 12677 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 12678 if (!param_buf) { 12679 wmi_err("Invalid ani level event buffer"); 12680 return QDF_STATUS_E_INVAL; 12681 } 12682 12683 fixed_param = 12684 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 12685 if (!fixed_param) { 12686 wmi_err("Invalid fixed param"); 12687 return QDF_STATUS_E_INVAL; 12688 } 12689 12690 buf_ptr = (uint8_t *)fixed_param; 12691 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 12692 buf_ptr += WMI_TLV_HDR_SIZE; 12693 12694 *num_freqs = param_buf->num_ani_info; 12695 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 12696 wmi_err("Invalid number of freqs received"); 12697 return QDF_STATUS_E_INVAL; 12698 } 12699 12700 *info = qdf_mem_malloc(*num_freqs * 12701 sizeof(struct wmi_host_ani_level_event)); 12702 if (!(*info)) 12703 return QDF_STATUS_E_NOMEM; 12704 12705 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 12706 for (i = 0; i < param_buf->num_ani_info; i++) { 12707 (*info)[i].ani_level = tlv_params->ani_level; 12708 (*info)[i].chan_freq = tlv_params->chan_freq; 12709 tlv_params++; 12710 } 12711 12712 return QDF_STATUS_SUCCESS; 12713 } 12714 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 12715 12716 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 12717 /** 12718 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 12719 * from the WMI_ROAM_STATS_EVENTID 12720 * @wmi_handle: wmi handle 12721 * @evt_buf: Pointer to the event buffer 12722 * @trig: Pointer to destination structure to fill data 12723 * @idx: TLV id 12724 */ 12725 static QDF_STATUS 12726 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12727 struct wmi_roam_trigger_info *trig, uint8_t idx) 12728 { 12729 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 12730 wmi_roam_trigger_reason *src_data = NULL; 12731 12732 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 12733 if (!param_buf || !param_buf->roam_trigger_reason) 12734 return QDF_STATUS_E_FAILURE; 12735 12736 src_data = ¶m_buf->roam_trigger_reason[idx]; 12737 12738 trig->present = true; 12739 trig->trigger_reason = src_data->trigger_reason; 12740 trig->trigger_sub_reason = src_data->trigger_sub_reason; 12741 trig->current_rssi = src_data->current_rssi; 12742 trig->timestamp = src_data->timestamp; 12743 12744 switch (trig->trigger_reason) { 12745 case WMI_ROAM_TRIGGER_REASON_PER: 12746 case WMI_ROAM_TRIGGER_REASON_BMISS: 12747 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 12748 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 12749 case WMI_ROAM_TRIGGER_REASON_MAWC: 12750 case WMI_ROAM_TRIGGER_REASON_DENSE: 12751 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 12752 case WMI_ROAM_TRIGGER_REASON_IDLE: 12753 case WMI_ROAM_TRIGGER_REASON_FORCED: 12754 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 12755 return QDF_STATUS_SUCCESS; 12756 12757 case WMI_ROAM_TRIGGER_REASON_BTM: 12758 trig->btm_trig_data.btm_request_mode = 12759 src_data->btm_request_mode; 12760 trig->btm_trig_data.disassoc_timer = 12761 src_data->disassoc_imminent_timer; 12762 trig->btm_trig_data.validity_interval = 12763 src_data->validity_internal; 12764 trig->btm_trig_data.candidate_list_count = 12765 src_data->candidate_list_count; 12766 trig->btm_trig_data.btm_resp_status = 12767 src_data->btm_response_status_code; 12768 return QDF_STATUS_SUCCESS; 12769 12770 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 12771 trig->cu_trig_data.cu_load = src_data->cu_load; 12772 return QDF_STATUS_SUCCESS; 12773 12774 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 12775 trig->deauth_trig_data.type = src_data->deauth_type; 12776 trig->deauth_trig_data.reason = src_data->deauth_reason; 12777 return QDF_STATUS_SUCCESS; 12778 12779 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 12780 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 12781 return QDF_STATUS_SUCCESS; 12782 12783 default: 12784 return QDF_STATUS_SUCCESS; 12785 } 12786 12787 return QDF_STATUS_SUCCESS; 12788 } 12789 12790 /** 12791 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 12792 * from the WMI_ROAM_STATS_EVENTID 12793 * @wmi_handle: wmi handle 12794 * @evt_buf: Pointer to the event buffer 12795 * @dst: Pointer to destination structure to fill data 12796 * @ap_idx: TLV index for this roam scan 12797 * @num_cand: number of candidates list in the roam scan 12798 */ 12799 static QDF_STATUS 12800 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12801 struct wmi_roam_candidate_info *dst, 12802 uint8_t ap_idx, uint16_t num_cand) 12803 { 12804 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 12805 wmi_roam_ap_info *src = NULL; 12806 uint8_t i; 12807 12808 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 12809 if (!param_buf) 12810 return QDF_STATUS_E_FAILURE; 12811 12812 src = ¶m_buf->roam_ap_info[ap_idx]; 12813 12814 for (i = 0; i < num_cand; i++) { 12815 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 12816 dst->type = src->candidate_type; 12817 dst->freq = src->channel; 12818 dst->etp = src->etp; 12819 dst->rssi = src->rssi; 12820 dst->rssi_score = src->rssi_score; 12821 dst->cu_load = src->cu_load; 12822 dst->cu_score = src->cu_score; 12823 dst->total_score = src->total_score; 12824 dst->timestamp = src->timestamp; 12825 12826 src++; 12827 dst++; 12828 } 12829 12830 return QDF_STATUS_SUCCESS; 12831 } 12832 12833 /** 12834 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 12835 * from the WMI_ROAM_STATS_EVENTID 12836 * @wmi_handle: wmi handle 12837 * @evt_buf: Pointer to the event buffer 12838 * @dst: Pointer to destination structure to fill data 12839 * @idx: TLV id 12840 * @chan_idx: Index of the channel tlv for the current roam trigger 12841 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 12842 */ 12843 static QDF_STATUS 12844 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12845 struct wmi_roam_scan_data *dst, uint8_t idx, 12846 uint8_t chan_idx, uint8_t ap_idx) 12847 { 12848 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 12849 wmi_roam_scan_info *src_data = NULL; 12850 wmi_roam_scan_channel_info *src_chan = NULL; 12851 QDF_STATUS status; 12852 uint8_t i; 12853 12854 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 12855 if (!param_buf || !param_buf->roam_scan_info) 12856 return QDF_STATUS_E_FAILURE; 12857 12858 src_data = ¶m_buf->roam_scan_info[idx]; 12859 12860 dst->present = true; 12861 dst->type = src_data->roam_scan_type; 12862 dst->num_chan = src_data->roam_scan_channel_count; 12863 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 12864 12865 /* Read the channel data only for dst->type is 0 (partial scan) */ 12866 if (dst->num_chan && !dst->type) { 12867 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 12868 dst->num_chan = MAX_ROAM_SCAN_CHAN; 12869 12870 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 12871 for (i = 0; i < dst->num_chan; i++) { 12872 dst->chan_freq[i] = src_chan->channel; 12873 src_chan++; 12874 } 12875 } 12876 12877 if (!src_data->roam_ap_count) 12878 return QDF_STATUS_SUCCESS; 12879 12880 dst->num_ap = src_data->roam_ap_count; 12881 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 12882 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 12883 12884 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 12885 ap_idx, dst->num_ap); 12886 if (QDF_IS_STATUS_ERROR(status)) { 12887 WMI_LOGE("Extract candidate stats for tlv[%d] failed", idx); 12888 return status; 12889 } 12890 12891 return QDF_STATUS_SUCCESS; 12892 } 12893 12894 /** 12895 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 12896 * from the WMI_ROAM_STATS_EVENTID 12897 * @wmi_handle: wmi handle 12898 * @evt_buf: Pointer to the event buffer 12899 * @dst: Pointer to destination structure to fill data 12900 * @idx: TLV id 12901 */ 12902 static QDF_STATUS 12903 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12904 struct wmi_roam_result *dst, uint8_t idx) 12905 { 12906 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 12907 wmi_roam_result *src_data = NULL; 12908 12909 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 12910 if (!param_buf || !param_buf->roam_result) 12911 return QDF_STATUS_E_FAILURE; 12912 12913 src_data = ¶m_buf->roam_result[idx]; 12914 12915 dst->present = true; 12916 dst->status = src_data->roam_status ? false : true; 12917 dst->timestamp = src_data->timestamp; 12918 dst->fail_reason = src_data->roam_fail_reason; 12919 12920 return QDF_STATUS_SUCCESS; 12921 } 12922 12923 /** 12924 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 12925 * from the WMI_ROAM_STATS_EVENTID 12926 * @wmi_handle: wmi handle 12927 * @evt_buf: Pointer to the event buffer 12928 * @dst: Pointer to destination structure to fill data 12929 * @idx: TLV id 12930 * @rpt_idx: Neighbor report Channel index 12931 */ 12932 static QDF_STATUS 12933 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12934 struct wmi_neighbor_report_data *dst, 12935 uint8_t idx, uint8_t rpt_idx) 12936 { 12937 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 12938 wmi_roam_neighbor_report_info *src_data = NULL; 12939 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 12940 uint8_t i; 12941 12942 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 12943 if (!param_buf || !param_buf->roam_neighbor_report_info) 12944 return QDF_STATUS_E_FAILURE; 12945 12946 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 12947 12948 dst->present = true; 12949 dst->req_type = src_data->request_type; 12950 dst->num_freq = src_data->neighbor_report_channel_count; 12951 dst->req_time = src_data->neighbor_report_request_timestamp; 12952 dst->resp_time = src_data->neighbor_report_response_timestamp; 12953 12954 if (!dst->num_freq) 12955 return QDF_STATUS_SUCCESS; 12956 12957 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 12958 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 12959 dst->num_freq = MAX_ROAM_SCAN_CHAN; 12960 12961 for (i = 0; i < dst->num_freq; i++) { 12962 dst->freq[i] = src_freq->channel; 12963 src_freq++; 12964 } 12965 12966 return QDF_STATUS_SUCCESS; 12967 } 12968 #else 12969 static inline QDF_STATUS 12970 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12971 struct wmi_roam_trigger_info *trig, uint8_t idx) 12972 { 12973 return QDF_STATUS_E_NOSUPPORT; 12974 } 12975 12976 static inline QDF_STATUS 12977 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12978 struct wmi_roam_result *dst, uint8_t idx) 12979 { 12980 return QDF_STATUS_E_NOSUPPORT; 12981 } 12982 12983 static QDF_STATUS 12984 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12985 struct wmi_neighbor_report_data *dst, 12986 uint8_t idx, uint8_t rpt_idx) 12987 { 12988 return QDF_STATUS_E_NOSUPPORT; 12989 } 12990 12991 static QDF_STATUS 12992 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12993 struct wmi_roam_scan_data *dst, uint8_t idx, 12994 uint8_t chan_idx, uint8_t ap_idx) 12995 { 12996 return QDF_STATUS_E_NOSUPPORT; 12997 } 12998 #endif 12999 13000 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 13001 /** 13002 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 13003 * 13004 * @wmi: wmi handle 13005 * @vdev_id: vdev id 13006 * @burst_mode: Indicates whether relation derived using FTM is needed for 13007 * each FTM frame or only aggregated result is required. 13008 * 13009 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 13010 * 13011 * Return: QDF_STATUS 13012 */ 13013 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 13014 uint32_t vdev_id, 13015 bool burst_mode) 13016 { 13017 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 13018 wmi_buf_t buf; 13019 int32_t len = sizeof(*cmd); 13020 13021 buf = wmi_buf_alloc(wmi, len); 13022 if (!buf) { 13023 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13024 return QDF_STATUS_E_NOMEM; 13025 } 13026 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 13027 WMITLV_SET_HDR(&cmd->tlv_header, 13028 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 13029 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 13030 cmd->vdev_id = vdev_id; 13031 cmd->agg_relation = burst_mode ? false : true; 13032 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 13033 WMI_LOGE("%s: failed to send audio sync trigger cmd", __func__); 13034 wmi_buf_free(buf); 13035 return QDF_STATUS_E_FAILURE; 13036 } 13037 13038 return QDF_STATUS_SUCCESS; 13039 } 13040 13041 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 13042 uint32_t vdev_id, 13043 uint64_t lpass_ts) 13044 { 13045 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 13046 wmi_buf_t buf; 13047 int32_t len = sizeof(*cmd); 13048 13049 buf = wmi_buf_alloc(wmi, len); 13050 if (!buf) { 13051 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 13052 return QDF_STATUS_E_NOMEM; 13053 } 13054 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 13055 WMITLV_SET_HDR(&cmd->tlv_header, 13056 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 13057 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 13058 cmd->vdev_id = vdev_id; 13059 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 13060 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 13061 13062 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 13063 WMI_LOGP("%s: Failed to send audio qtime command", __func__); 13064 wmi_buf_free(buf); 13065 return QDF_STATUS_E_FAILURE; 13066 } 13067 13068 return QDF_STATUS_SUCCESS; 13069 } 13070 13071 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 13072 wmi_unified_t wmi, void *buf, 13073 struct ftm_time_sync_start_stop_params *param) 13074 { 13075 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 13076 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 13077 13078 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 13079 if (!param_buf) { 13080 WMI_LOGE("Invalid audio sync start stop event buffer"); 13081 return QDF_STATUS_E_FAILURE; 13082 } 13083 13084 resp_event = param_buf->fixed_param; 13085 if (!resp_event) { 13086 WMI_LOGE("Invalid audio sync start stop fixed param buffer"); 13087 return QDF_STATUS_E_FAILURE; 13088 } 13089 13090 param->vdev_id = resp_event->vdev_id; 13091 param->timer_interval = resp_event->periodicity; 13092 param->num_reads = resp_event->reads_needed; 13093 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 13094 resp_event->qtimer_l32; 13095 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 13096 resp_event->mac_timer_l32; 13097 13098 WMI_LOGI("%s: FTM time sync time_interval %d, num_reads %d", __func__, 13099 param->timer_interval, param->num_reads); 13100 13101 return QDF_STATUS_SUCCESS; 13102 } 13103 13104 static QDF_STATUS 13105 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 13106 struct ftm_time_sync_offset *param) 13107 { 13108 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 13109 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 13110 wmi_audio_sync_q_master_slave_times *q_pair; 13111 int iter; 13112 13113 param_buf = 13114 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 13115 if (!param_buf) { 13116 WMI_LOGE("Invalid timesync ftm offset event buffer"); 13117 return QDF_STATUS_E_FAILURE; 13118 } 13119 13120 resp_event = param_buf->fixed_param; 13121 if (!resp_event) { 13122 WMI_LOGE("Invalid timesync ftm offset fixed param buffer"); 13123 return QDF_STATUS_E_FAILURE; 13124 } 13125 13126 param->vdev_id = resp_event->vdev_id; 13127 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 13128 q_pair = param_buf->audio_sync_q_master_slave_times; 13129 if (!q_pair) { 13130 WMI_LOGE("Invalid q_master_slave_times buffer"); 13131 return QDF_STATUS_E_FAILURE; 13132 } 13133 13134 for (iter = 0; iter < param->num_qtime; iter++) { 13135 param->pairs[iter].qtime_master = ( 13136 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 13137 q_pair[iter].qmaster_l32; 13138 param->pairs[iter].qtime_slave = ( 13139 (uint64_t)q_pair[iter].qslave_u32 << 32) | 13140 q_pair[iter].qslave_l32; 13141 } 13142 return QDF_STATUS_SUCCESS; 13143 } 13144 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 13145 13146 struct wmi_ops tlv_ops = { 13147 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 13148 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 13149 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 13150 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 13151 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 13152 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 13153 .send_peer_param_cmd = send_peer_param_cmd_tlv, 13154 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 13155 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 13156 .send_peer_create_cmd = send_peer_create_cmd_tlv, 13157 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 13158 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 13159 .send_peer_rx_reorder_queue_setup_cmd = 13160 send_peer_rx_reorder_queue_setup_cmd_tlv, 13161 .send_peer_rx_reorder_queue_remove_cmd = 13162 send_peer_rx_reorder_queue_remove_cmd_tlv, 13163 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 13164 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 13165 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 13166 .send_suspend_cmd = send_suspend_cmd_tlv, 13167 .send_resume_cmd = send_resume_cmd_tlv, 13168 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 13169 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 13170 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 13171 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 13172 #ifdef FEATURE_FW_LOG_PARSING 13173 .send_dbglog_cmd = send_dbglog_cmd_tlv, 13174 #endif 13175 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 13176 .send_stats_request_cmd = send_stats_request_cmd_tlv, 13177 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 13178 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 13179 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 13180 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 13181 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 13182 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 13183 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 13184 .send_scan_start_cmd = send_scan_start_cmd_tlv, 13185 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 13186 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 13187 .send_mgmt_cmd = send_mgmt_cmd_tlv, 13188 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 13189 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 13190 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 13191 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 13192 .send_set_sta_uapsd_auto_trig_cmd = 13193 send_set_sta_uapsd_auto_trig_cmd_tlv, 13194 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 13195 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 13196 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 13197 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 13198 .send_lro_config_cmd = send_lro_config_cmd_tlv, 13199 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 13200 .send_probe_rsp_tmpl_send_cmd = 13201 send_probe_rsp_tmpl_send_cmd_tlv, 13202 .send_p2p_go_set_beacon_ie_cmd = 13203 send_p2p_go_set_beacon_ie_cmd_tlv, 13204 .send_setup_install_key_cmd = 13205 send_setup_install_key_cmd_tlv, 13206 .send_scan_probe_setoui_cmd = 13207 send_scan_probe_setoui_cmd_tlv, 13208 #ifdef IPA_OFFLOAD 13209 .send_ipa_offload_control_cmd = 13210 send_ipa_offload_control_cmd_tlv, 13211 #endif 13212 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 13213 .send_pno_start_cmd = send_pno_start_cmd_tlv, 13214 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 13215 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 13216 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 13217 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 13218 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 13219 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 13220 .send_congestion_cmd = send_congestion_cmd_tlv, 13221 .send_snr_request_cmd = send_snr_request_cmd_tlv, 13222 .send_snr_cmd = send_snr_cmd_tlv, 13223 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 13224 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 13225 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 13226 #endif 13227 #ifdef WLAN_SUPPORT_GREEN_AP 13228 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 13229 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 13230 .extract_green_ap_egap_status_info = 13231 extract_green_ap_egap_status_info_tlv, 13232 #endif 13233 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 13234 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 13235 #ifdef FEATURE_OEM_DATA 13236 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 13237 #endif 13238 #ifdef WLAN_FEATURE_CIF_CFR 13239 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 13240 #endif 13241 .send_dfs_phyerr_filter_offload_en_cmd = 13242 send_dfs_phyerr_filter_offload_en_cmd_tlv, 13243 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 13244 .send_process_dhcpserver_offload_cmd = 13245 send_process_dhcpserver_offload_cmd_tlv, 13246 .send_pdev_set_regdomain_cmd = 13247 send_pdev_set_regdomain_cmd_tlv, 13248 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 13249 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 13250 .save_fw_version_cmd = save_fw_version_cmd_tlv, 13251 .check_and_update_fw_version = 13252 check_and_update_fw_version_cmd_tlv, 13253 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 13254 .send_enable_specific_fw_logs_cmd = 13255 send_enable_specific_fw_logs_cmd_tlv, 13256 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 13257 .send_unit_test_cmd = send_unit_test_cmd_tlv, 13258 #ifdef FEATURE_WLAN_APF 13259 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 13260 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 13261 .send_apf_write_work_memory_cmd = 13262 wmi_send_apf_write_work_memory_cmd_tlv, 13263 .send_apf_read_work_memory_cmd = 13264 wmi_send_apf_read_work_memory_cmd_tlv, 13265 .extract_apf_read_memory_resp_event = 13266 wmi_extract_apf_read_memory_resp_event_tlv, 13267 #endif /* FEATURE_WLAN_APF */ 13268 .init_cmd_send = init_cmd_send_tlv, 13269 .send_vdev_set_custom_aggr_size_cmd = 13270 send_vdev_set_custom_aggr_size_cmd_tlv, 13271 .send_vdev_set_qdepth_thresh_cmd = 13272 send_vdev_set_qdepth_thresh_cmd_tlv, 13273 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 13274 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 13275 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 13276 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 13277 .send_periodic_chan_stats_config_cmd = 13278 send_periodic_chan_stats_config_cmd_tlv, 13279 .send_vdev_spectral_configure_cmd = 13280 send_vdev_spectral_configure_cmd_tlv, 13281 .send_vdev_spectral_enable_cmd = 13282 send_vdev_spectral_enable_cmd_tlv, 13283 .send_thermal_mitigation_param_cmd = 13284 send_thermal_mitigation_param_cmd_tlv, 13285 .send_process_update_edca_param_cmd = 13286 send_process_update_edca_param_cmd_tlv, 13287 .send_bss_color_change_enable_cmd = 13288 send_bss_color_change_enable_cmd_tlv, 13289 .send_coex_config_cmd = send_coex_config_cmd_tlv, 13290 .send_set_country_cmd = send_set_country_cmd_tlv, 13291 .send_addba_send_cmd = send_addba_send_cmd_tlv, 13292 .send_delba_send_cmd = send_delba_send_cmd_tlv, 13293 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 13294 .get_target_cap_from_service_ready = extract_service_ready_tlv, 13295 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 13296 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 13297 .extract_host_mem_req = extract_host_mem_req_tlv, 13298 .save_service_bitmap = save_service_bitmap_tlv, 13299 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 13300 .is_service_enabled = is_service_enabled_tlv, 13301 .save_fw_version = save_fw_version_in_service_ready_tlv, 13302 .ready_extract_init_status = ready_extract_init_status_tlv, 13303 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 13304 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 13305 .extract_ready_event_params = extract_ready_event_params_tlv, 13306 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 13307 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 13308 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 13309 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 13310 #ifdef FEATURE_WLAN_SCAN_PNO 13311 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 13312 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 13313 #endif 13314 .extract_all_stats_count = extract_all_stats_counts_tlv, 13315 .extract_pdev_stats = extract_pdev_stats_tlv, 13316 .extract_unit_test = extract_unit_test_tlv, 13317 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 13318 .extract_vdev_stats = extract_vdev_stats_tlv, 13319 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 13320 .extract_peer_stats = extract_peer_stats_tlv, 13321 .extract_bcn_stats = extract_bcn_stats_tlv, 13322 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 13323 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 13324 .extract_peer_adv_stats = extract_peer_adv_stats_tlv, 13325 .extract_chan_stats = extract_chan_stats_tlv, 13326 #ifdef WLAN_FEATURE_MIB_STATS 13327 .extract_mib_stats = extract_mib_stats_tlv, 13328 #endif 13329 .extract_profile_ctx = extract_profile_ctx_tlv, 13330 .extract_profile_data = extract_profile_data_tlv, 13331 .send_fw_test_cmd = send_fw_test_cmd_tlv, 13332 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 13333 .extract_service_ready_ext = extract_service_ready_ext_tlv, 13334 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 13335 .extract_hw_mode_cap_service_ready_ext = 13336 extract_hw_mode_cap_service_ready_ext_tlv, 13337 .extract_mac_phy_cap_service_ready_ext = 13338 extract_mac_phy_cap_service_ready_ext_tlv, 13339 .extract_reg_cap_service_ready_ext = 13340 extract_reg_cap_service_ready_ext_tlv, 13341 .extract_dbr_ring_cap_service_ready_ext = 13342 extract_dbr_ring_cap_service_ready_ext_tlv, 13343 .extract_dbr_ring_cap_service_ready_ext2 = 13344 extract_dbr_ring_cap_service_ready_ext2_tlv, 13345 .extract_sar_cap_service_ready_ext = 13346 extract_sar_cap_service_ready_ext_tlv, 13347 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 13348 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 13349 .extract_fips_event_data = extract_fips_event_data_tlv, 13350 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 13351 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 13352 #endif 13353 #ifdef WLAN_FEATURE_DISA 13354 .extract_encrypt_decrypt_resp_event = 13355 extract_encrypt_decrypt_resp_event_tlv, 13356 #endif 13357 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 13358 .extract_get_pn_data = extract_get_pn_data_tlv, 13359 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 13360 #ifdef WLAN_FEATURE_DISA 13361 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 13362 #endif 13363 .is_management_record = is_management_record_tlv, 13364 .is_diag_event = is_diag_event_tlv, 13365 #ifdef WLAN_FEATURE_ACTION_OUI 13366 .send_action_oui_cmd = send_action_oui_cmd_tlv, 13367 #endif 13368 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 13369 #ifdef QCA_SUPPORT_AGILE_DFS 13370 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 13371 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 13372 #endif 13373 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 13374 .extract_reg_chan_list_update_event = 13375 extract_reg_chan_list_update_event_tlv, 13376 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13377 .extract_num_rf_characterization_entries = 13378 extract_num_rf_characterization_entries_tlv, 13379 .extract_rf_characterization_entries = 13380 extract_rf_characterization_entries_tlv, 13381 #endif 13382 .extract_chainmask_tables = 13383 extract_chainmask_tables_tlv, 13384 .extract_thermal_stats = extract_thermal_stats_tlv, 13385 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 13386 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 13387 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 13388 #ifdef DFS_COMPONENT_ENABLE 13389 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 13390 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 13391 .extract_dfs_radar_detection_event = 13392 extract_dfs_radar_detection_event_tlv, 13393 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 13394 #endif 13395 .convert_pdev_id_host_to_target = 13396 convert_host_pdev_id_to_target_pdev_id_legacy, 13397 .convert_pdev_id_target_to_host = 13398 convert_target_pdev_id_to_host_pdev_id_legacy, 13399 13400 .convert_host_pdev_id_to_target = 13401 convert_host_pdev_id_to_target_pdev_id, 13402 .convert_target_pdev_id_to_host = 13403 convert_target_pdev_id_to_host_pdev_id, 13404 13405 .convert_phy_id_host_to_target = 13406 convert_host_phy_id_to_target_phy_id_legacy, 13407 .convert_phy_id_target_to_host = 13408 convert_target_phy_id_to_host_phy_id_legacy, 13409 13410 .convert_host_phy_id_to_target = 13411 convert_host_phy_id_to_target_phy_id, 13412 .convert_target_phy_id_to_host = 13413 convert_target_phy_id_to_host_phy_id, 13414 13415 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 13416 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 13417 .extract_reg_11d_new_country_event = 13418 extract_reg_11d_new_country_event_tlv, 13419 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 13420 .extract_reg_ch_avoid_event = 13421 extract_reg_ch_avoid_event_tlv, 13422 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 13423 .extract_obss_detection_info = extract_obss_detection_info_tlv, 13424 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 13425 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 13426 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 13427 .wmi_check_command_params = wmitlv_check_command_tlv_params, 13428 .extract_comb_phyerr = extract_comb_phyerr_tlv, 13429 .extract_single_phyerr = extract_single_phyerr_tlv, 13430 #ifdef QCA_SUPPORT_CP_STATS 13431 .extract_cca_stats = extract_cca_stats_tlv, 13432 #endif 13433 .extract_esp_estimation_ev_param = 13434 extract_esp_estimation_ev_param_tlv, 13435 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 13436 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 13437 #ifdef OBSS_PD 13438 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 13439 .send_obss_spatial_reuse_set_def_thresh = 13440 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 13441 #endif 13442 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 13443 .extract_ctl_failsafe_check_ev_param = 13444 extract_ctl_failsafe_check_ev_param_tlv, 13445 #ifdef WIFI_POS_CONVERGED 13446 .extract_oem_response_param = extract_oem_response_param_tlv, 13447 #endif /* WIFI_POS_CONVERGED */ 13448 #ifdef WLAN_MWS_INFO_DEBUGFS 13449 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 13450 #endif 13451 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 13452 #ifdef FEATURE_ANI_LEVEL_REQUEST 13453 .send_ani_level_cmd = send_ani_level_cmd_tlv, 13454 .extract_ani_level = extract_ani_level_tlv, 13455 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 13456 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 13457 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 13458 .extract_roam_result_stats = extract_roam_result_stats_tlv, 13459 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 13460 13461 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 13462 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 13463 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 13464 .extract_time_sync_ftm_start_stop_event = 13465 extract_time_sync_ftm_start_stop_event_tlv, 13466 .extract_time_sync_ftm_offset_event = 13467 extract_time_sync_ftm_offset_event_tlv, 13468 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 13469 }; 13470 13471 /** 13472 * populate_tlv_event_id() - populates wmi event ids 13473 * 13474 * @param event_ids: Pointer to hold event ids 13475 * Return: None 13476 */ 13477 static void populate_tlv_events_id(uint32_t *event_ids) 13478 { 13479 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 13480 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 13481 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 13482 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 13483 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 13484 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 13485 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 13486 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 13487 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 13488 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 13489 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 13490 event_ids[wmi_service_ready_ext_event_id] = 13491 WMI_SERVICE_READY_EXT_EVENTID; 13492 event_ids[wmi_service_ready_ext2_event_id] = 13493 WMI_SERVICE_READY_EXT2_EVENTID; 13494 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 13495 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 13496 event_ids[wmi_vdev_install_key_complete_event_id] = 13497 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 13498 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 13499 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 13500 13501 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 13502 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 13503 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 13504 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 13505 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 13506 event_ids[wmi_peer_estimated_linkspeed_event_id] = 13507 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 13508 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 13509 event_ids[wmi_peer_delete_response_event_id] = 13510 WMI_PEER_DELETE_RESP_EVENTID; 13511 event_ids[wmi_peer_delete_all_response_event_id] = 13512 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 13513 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 13514 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 13515 event_ids[wmi_tbttoffset_update_event_id] = 13516 WMI_TBTTOFFSET_UPDATE_EVENTID; 13517 event_ids[wmi_ext_tbttoffset_update_event_id] = 13518 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 13519 event_ids[wmi_offload_bcn_tx_status_event_id] = 13520 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 13521 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 13522 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 13523 event_ids[wmi_mgmt_tx_completion_event_id] = 13524 WMI_MGMT_TX_COMPLETION_EVENTID; 13525 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 13526 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 13527 event_ids[wmi_tx_delba_complete_event_id] = 13528 WMI_TX_DELBA_COMPLETE_EVENTID; 13529 event_ids[wmi_tx_addba_complete_event_id] = 13530 WMI_TX_ADDBA_COMPLETE_EVENTID; 13531 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 13532 13533 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 13534 13535 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 13536 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 13537 13538 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 13539 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 13540 13541 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 13542 13543 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 13544 event_ids[wmi_p2p_lo_stop_event_id] = 13545 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 13546 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 13547 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 13548 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 13549 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 13550 event_ids[wmi_d0_wow_disable_ack_event_id] = 13551 WMI_D0_WOW_DISABLE_ACK_EVENTID; 13552 event_ids[wmi_wow_initial_wakeup_event_id] = 13553 WMI_WOW_INITIAL_WAKEUP_EVENTID; 13554 13555 event_ids[wmi_rtt_meas_report_event_id] = 13556 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 13557 event_ids[wmi_tsf_meas_report_event_id] = 13558 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 13559 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 13560 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 13561 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 13562 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 13563 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 13564 event_ids[wmi_diag_event_id_log_supported_event_id] = 13565 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 13566 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 13567 event_ids[wmi_nlo_scan_complete_event_id] = 13568 WMI_NLO_SCAN_COMPLETE_EVENTID; 13569 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 13570 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 13571 13572 event_ids[wmi_gtk_offload_status_event_id] = 13573 WMI_GTK_OFFLOAD_STATUS_EVENTID; 13574 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 13575 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 13576 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 13577 13578 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 13579 13580 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 13581 13582 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 13583 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 13584 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 13585 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 13586 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 13587 event_ids[wmi_wlan_profile_data_event_id] = 13588 WMI_WLAN_PROFILE_DATA_EVENTID; 13589 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 13590 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 13591 event_ids[wmi_vdev_get_keepalive_event_id] = 13592 WMI_VDEV_GET_KEEPALIVE_EVENTID; 13593 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 13594 13595 event_ids[wmi_diag_container_event_id] = 13596 WMI_DIAG_DATA_CONTAINER_EVENTID; 13597 13598 event_ids[wmi_host_auto_shutdown_event_id] = 13599 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 13600 13601 event_ids[wmi_update_whal_mib_stats_event_id] = 13602 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 13603 13604 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 13605 event_ids[wmi_update_vdev_rate_stats_event_id] = 13606 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 13607 13608 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 13609 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 13610 13611 /** Set OCB Sched Response, deprecated */ 13612 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 13613 13614 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 13615 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 13616 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 13617 13618 /* GPIO Event */ 13619 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 13620 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 13621 13622 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 13623 event_ids[wmi_rfkill_state_change_event_id] = 13624 WMI_RFKILL_STATE_CHANGE_EVENTID; 13625 13626 /* TDLS Event */ 13627 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 13628 13629 event_ids[wmi_batch_scan_enabled_event_id] = 13630 WMI_BATCH_SCAN_ENABLED_EVENTID; 13631 event_ids[wmi_batch_scan_result_event_id] = 13632 WMI_BATCH_SCAN_RESULT_EVENTID; 13633 /* OEM Event */ 13634 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 13635 event_ids[wmi_oem_meas_report_event_id] = 13636 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 13637 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 13638 13639 /* NAN Event */ 13640 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 13641 13642 /* LPI Event */ 13643 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 13644 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 13645 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 13646 13647 /* ExtScan events */ 13648 event_ids[wmi_extscan_start_stop_event_id] = 13649 WMI_EXTSCAN_START_STOP_EVENTID; 13650 event_ids[wmi_extscan_operation_event_id] = 13651 WMI_EXTSCAN_OPERATION_EVENTID; 13652 event_ids[wmi_extscan_table_usage_event_id] = 13653 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 13654 event_ids[wmi_extscan_cached_results_event_id] = 13655 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 13656 event_ids[wmi_extscan_wlan_change_results_event_id] = 13657 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 13658 event_ids[wmi_extscan_hotlist_match_event_id] = 13659 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 13660 event_ids[wmi_extscan_capabilities_event_id] = 13661 WMI_EXTSCAN_CAPABILITIES_EVENTID; 13662 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 13663 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 13664 13665 /* mDNS offload events */ 13666 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 13667 13668 /* SAP Authentication offload events */ 13669 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 13670 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 13671 13672 /** Out-of-context-of-bss (OCB) events */ 13673 event_ids[wmi_ocb_set_config_resp_event_id] = 13674 WMI_OCB_SET_CONFIG_RESP_EVENTID; 13675 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 13676 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 13677 event_ids[wmi_dcc_get_stats_resp_event_id] = 13678 WMI_DCC_GET_STATS_RESP_EVENTID; 13679 event_ids[wmi_dcc_update_ndl_resp_event_id] = 13680 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 13681 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 13682 /* System-On-Chip events */ 13683 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 13684 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 13685 event_ids[wmi_soc_hw_mode_transition_event_id] = 13686 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 13687 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 13688 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 13689 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 13690 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 13691 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 13692 event_ids[wmi_vdev_ocac_complete_event_id] = 13693 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 13694 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 13695 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 13696 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 13697 event_ids[wmi_peer_sta_ps_statechg_event_id] = 13698 WMI_PEER_STA_PS_STATECHG_EVENTID; 13699 event_ids[wmi_pdev_channel_hopping_event_id] = 13700 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 13701 event_ids[wmi_offchan_data_tx_completion_event] = 13702 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 13703 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 13704 event_ids[wmi_dfs_radar_detection_event_id] = 13705 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 13706 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 13707 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 13708 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 13709 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 13710 event_ids[wmi_service_available_event_id] = 13711 WMI_SERVICE_AVAILABLE_EVENTID; 13712 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 13713 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 13714 /* NDP events */ 13715 event_ids[wmi_ndp_initiator_rsp_event_id] = 13716 WMI_NDP_INITIATOR_RSP_EVENTID; 13717 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 13718 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 13719 event_ids[wmi_ndp_responder_rsp_event_id] = 13720 WMI_NDP_RESPONDER_RSP_EVENTID; 13721 event_ids[wmi_ndp_end_indication_event_id] = 13722 WMI_NDP_END_INDICATION_EVENTID; 13723 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 13724 event_ids[wmi_ndl_schedule_update_event_id] = 13725 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 13726 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 13727 13728 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 13729 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 13730 event_ids[wmi_pdev_chip_power_stats_event_id] = 13731 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 13732 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 13733 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 13734 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 13735 event_ids[wmi_apf_capability_info_event_id] = 13736 WMI_BPF_CAPABILIY_INFO_EVENTID; 13737 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 13738 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 13739 event_ids[wmi_report_rx_aggr_failure_event_id] = 13740 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 13741 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 13742 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 13743 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 13744 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 13745 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 13746 event_ids[wmi_pdev_hw_mode_transition_event_id] = 13747 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 13748 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 13749 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 13750 event_ids[wmi_coex_bt_activity_event_id] = 13751 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 13752 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 13753 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 13754 event_ids[wmi_radio_tx_power_level_stats_event_id] = 13755 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 13756 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 13757 event_ids[wmi_dma_buf_release_event_id] = 13758 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 13759 event_ids[wmi_sap_obss_detection_report_event_id] = 13760 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 13761 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 13762 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 13763 event_ids[wmi_obss_color_collision_report_event_id] = 13764 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 13765 event_ids[wmi_pdev_div_rssi_antid_event_id] = 13766 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 13767 event_ids[wmi_twt_enable_complete_event_id] = 13768 WMI_TWT_ENABLE_COMPLETE_EVENTID; 13769 event_ids[wmi_twt_disable_complete_event_id] = 13770 WMI_TWT_DISABLE_COMPLETE_EVENTID; 13771 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 13772 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 13773 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 13774 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 13775 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 13776 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 13777 event_ids[wmi_pdev_interop_issues_ap_event_id] = 13778 WMI_PDEV_RAP_INFO_EVENTID; 13779 #endif 13780 #ifdef AST_HKV1_WORKAROUND 13781 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 13782 #endif 13783 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 13784 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 13785 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 13786 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 13787 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 13788 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 13789 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 13790 event_ids[wmi_pdev_cold_boot_cal_event_id] = 13791 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 13792 #ifdef WLAN_MWS_INFO_DEBUGFS 13793 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 13794 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 13795 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 13796 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 13797 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 13798 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 13799 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 13800 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 13801 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 13802 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 13803 #endif 13804 event_ids[wmi_coex_report_antenna_isolation_event_id] = 13805 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 13806 event_ids[wmi_peer_ratecode_list_event_id] = 13807 WMI_PEER_RATECODE_LIST_EVENTID; 13808 event_ids[wmi_chan_rf_characterization_info_event_id] = 13809 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 13810 event_ids[wmi_roam_auth_offload_event_id] = 13811 WMI_ROAM_PREAUTH_START_EVENTID; 13812 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 13813 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 13814 event_ids[wmi_motion_det_base_line_host_eventid] = 13815 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 13816 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 13817 event_ids[wmi_peer_tx_pn_response_event_id] = 13818 WMI_PEER_TX_PN_RESPONSE_EVENTID; 13819 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 13820 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 13821 event_ids[wmi_mgmt_offload_data_event_id] = 13822 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 13823 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 13824 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 13825 event_ids[wmi_roam_pmkid_request_event_id] = 13826 WMI_ROAM_PMKID_REQUEST_EVENTID; 13827 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 13828 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 13829 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 13830 event_ids[wmi_wlan_time_sync_q_master_slave_offset_eventid] = 13831 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 13832 #endif 13833 } 13834 13835 /** 13836 * populate_tlv_service() - populates wmi services 13837 * 13838 * @param wmi_service: Pointer to hold wmi_service 13839 * Return: None 13840 */ 13841 static void populate_tlv_service(uint32_t *wmi_service) 13842 { 13843 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 13844 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 13845 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 13846 wmi_service[wmi_service_roam_scan_offload] = 13847 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 13848 wmi_service[wmi_service_bcn_miss_offload] = 13849 WMI_SERVICE_BCN_MISS_OFFLOAD; 13850 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 13851 wmi_service[wmi_service_sta_advanced_pwrsave] = 13852 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 13853 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 13854 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 13855 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 13856 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 13857 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 13858 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 13859 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 13860 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 13861 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 13862 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 13863 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 13864 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 13865 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 13866 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 13867 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 13868 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 13869 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 13870 wmi_service[wmi_service_packet_power_save] = 13871 WMI_SERVICE_PACKET_POWER_SAVE; 13872 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 13873 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 13874 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 13875 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 13876 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 13877 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 13878 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 13879 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 13880 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 13881 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 13882 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 13883 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 13884 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 13885 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 13886 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 13887 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 13888 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 13889 wmi_service[wmi_service_mcc_bcn_interval_change] = 13890 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 13891 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 13892 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 13893 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 13894 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 13895 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 13896 wmi_service[wmi_service_lte_ant_share_support] = 13897 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 13898 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 13899 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 13900 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 13901 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 13902 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 13903 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 13904 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 13905 wmi_service[wmi_service_bcn_txrate_override] = 13906 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 13907 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 13908 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 13909 wmi_service[wmi_service_estimate_linkspeed] = 13910 WMI_SERVICE_ESTIMATE_LINKSPEED; 13911 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 13912 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 13913 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 13914 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 13915 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 13916 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 13917 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 13918 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 13919 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 13920 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 13921 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 13922 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 13923 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 13924 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 13925 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 13926 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 13927 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 13928 wmi_service[wmi_service_sap_auth_offload] = 13929 WMI_SERVICE_SAP_AUTH_OFFLOAD; 13930 wmi_service[wmi_service_dual_band_simultaneous_support] = 13931 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 13932 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 13933 wmi_service[wmi_service_ap_arpns_offload] = 13934 WMI_SERVICE_AP_ARPNS_OFFLOAD; 13935 wmi_service[wmi_service_per_band_chainmask_support] = 13936 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 13937 wmi_service[wmi_service_packet_filter_offload] = 13938 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 13939 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 13940 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 13941 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 13942 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 13943 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 13944 wmi_service[wmi_service_multiple_vdev_restart] = 13945 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 13946 wmi_service[wmi_service_smart_antenna_sw_support] = 13947 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 13948 wmi_service[wmi_service_smart_antenna_hw_support] = 13949 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 13950 13951 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 13952 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 13953 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 13954 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 13955 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 13956 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 13957 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 13958 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 13959 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 13960 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 13961 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 13962 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 13963 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 13964 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 13965 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 13966 wmi_service[wmi_service_periodic_chan_stat_support] = 13967 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 13968 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 13969 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 13970 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 13971 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 13972 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 13973 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 13974 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 13975 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 13976 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 13977 wmi_service[wmi_service_unified_wow_capability] = 13978 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 13979 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 13980 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 13981 wmi_service[wmi_service_sync_delete_cmds] = 13982 WMI_SERVICE_SYNC_DELETE_CMDS; 13983 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 13984 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 13985 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 13986 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 13987 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 13988 wmi_service[wmi_service_deprecated_replace] = 13989 WMI_SERVICE_DEPRECATED_REPLACE; 13990 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 13991 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 13992 wmi_service[wmi_service_enhanced_mcast_filter] = 13993 WMI_SERVICE_ENHANCED_MCAST_FILTER; 13994 wmi_service[wmi_service_half_rate_quarter_rate_support] = 13995 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 13996 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 13997 wmi_service[wmi_service_p2p_listen_offload_support] = 13998 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 13999 wmi_service[wmi_service_mark_first_wakeup_packet] = 14000 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 14001 wmi_service[wmi_service_multiple_mcast_filter_set] = 14002 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 14003 wmi_service[wmi_service_host_managed_rx_reorder] = 14004 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 14005 wmi_service[wmi_service_flash_rdwr_support] = 14006 WMI_SERVICE_FLASH_RDWR_SUPPORT; 14007 wmi_service[wmi_service_wlan_stats_report] = 14008 WMI_SERVICE_WLAN_STATS_REPORT; 14009 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 14010 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 14011 wmi_service[wmi_service_dfs_phyerr_offload] = 14012 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 14013 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 14014 wmi_service[wmi_service_fw_mem_dump_support] = 14015 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 14016 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 14017 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 14018 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 14019 wmi_service[wmi_service_hw_data_filtering] = 14020 WMI_SERVICE_HW_DATA_FILTERING; 14021 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 14022 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 14023 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 14024 wmi_service[wmi_service_extended_nss_support] = 14025 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 14026 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 14027 wmi_service[wmi_service_bcn_offload_start_stop_support] = 14028 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 14029 wmi_service[wmi_service_offchan_data_tid_support] = 14030 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 14031 wmi_service[wmi_service_support_dma] = 14032 WMI_SERVICE_SUPPORT_DIRECT_DMA; 14033 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 14034 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 14035 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 14036 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 14037 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 14038 wmi_service[wmi_service_11k_neighbour_report_support] = 14039 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 14040 wmi_service[wmi_service_ap_obss_detection_offload] = 14041 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 14042 wmi_service[wmi_service_bss_color_offload] = 14043 WMI_SERVICE_BSS_COLOR_OFFLOAD; 14044 wmi_service[wmi_service_gmac_offload_support] = 14045 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 14046 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 14047 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 14048 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 14049 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 14050 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 14051 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 14052 wmi_service[wmi_service_listen_interval_offload_support] = 14053 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 14054 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 14055 wmi_service[wmi_service_obss_spatial_reuse] = 14056 WMI_SERVICE_OBSS_SPATIAL_REUSE; 14057 wmi_service[wmi_service_per_vdev_chain_support] = 14058 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 14059 wmi_service[wmi_service_new_htt_msg_format] = 14060 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 14061 wmi_service[wmi_service_peer_unmap_cnf_support] = 14062 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 14063 wmi_service[wmi_service_beacon_reception_stats] = 14064 WMI_SERVICE_BEACON_RECEPTION_STATS; 14065 wmi_service[wmi_service_vdev_latency_config] = 14066 WMI_SERVICE_VDEV_LATENCY_CONFIG; 14067 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 14068 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 14069 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 14070 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 14071 wmi_service[wmi_service_nan_disable_support] = 14072 WMI_SERVICE_NAN_DISABLE_SUPPORT; 14073 wmi_service[wmi_service_sta_plus_sta_support] = 14074 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 14075 wmi_service[wmi_service_hw_db2dbm_support] = 14076 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 14077 wmi_service[wmi_service_wlm_stats_support] = 14078 WMI_SERVICE_WLM_STATS_REQUEST; 14079 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 14080 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 14081 wmi_service[wmi_service_cfr_capture_support] = 14082 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 14083 wmi_service[wmi_service_bcast_twt_support] = 14084 WMI_SERVICE_BROADCAST_TWT; 14085 wmi_service[wmi_service_wpa3_ft_sae_support] = 14086 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 14087 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 14088 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 14089 wmi_service[wmi_service_ft_fils] = 14090 WMI_SERVICE_WPA3_FT_FILS; 14091 wmi_service[wmi_service_adaptive_11r_support] = 14092 WMI_SERVICE_ADAPTIVE_11R_ROAM; 14093 wmi_service[wmi_service_tx_compl_tsf64] = 14094 WMI_SERVICE_TX_COMPL_TSF64; 14095 wmi_service[wmi_service_data_stall_recovery_support] = 14096 WMI_SERVICE_DSM_ROAM_FILTER; 14097 wmi_service[wmi_service_vdev_delete_all_peer] = 14098 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 14099 wmi_service[wmi_service_three_way_coex_config_legacy] = 14100 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 14101 wmi_service[wmi_service_rx_fse_support] = 14102 WMI_SERVICE_RX_FSE_SUPPORT; 14103 wmi_service[wmi_service_sae_roam_support] = 14104 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 14105 wmi_service[wmi_service_owe_roam_support] = 14106 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 14107 wmi_service[wmi_service_6ghz_support] = 14108 WMI_SERVICE_6GHZ_SUPPORT; 14109 wmi_service[wmi_service_bw_165mhz_support] = 14110 WMI_SERVICE_BW_165MHZ_SUPPORT; 14111 wmi_service[wmi_service_packet_capture_support] = 14112 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 14113 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 14114 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 14115 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 14116 wmi_service[wmi_service_multiple_vdev_restart_ext] = 14117 WMI_SERVICE_UNAVAILABLE; 14118 wmi_service[wmi_service_time_sync_ftm] = 14119 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 14120 wmi_service[wmi_service_nss_ratio_to_host_support] = 14121 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 14122 } 14123 14124 /** 14125 * wmi_ocb_ut_attach() - Attach OCB test framework 14126 * @wmi_handle: wmi handle 14127 * 14128 * Return: None 14129 */ 14130 #ifdef WLAN_OCB_UT 14131 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 14132 #else 14133 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 14134 { 14135 return; 14136 } 14137 #endif 14138 14139 /** 14140 * wmi_tlv_attach() - Attach TLV APIs 14141 * 14142 * Return: None 14143 */ 14144 void wmi_tlv_attach(wmi_unified_t wmi_handle) 14145 { 14146 wmi_handle->ops = &tlv_ops; 14147 wmi_ocb_ut_attach(wmi_handle); 14148 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 14149 #ifdef WMI_INTERFACE_EVENT_LOGGING 14150 /* Skip saving WMI_CMD_HDR and TLV HDR */ 14151 wmi_handle->soc->buf_offset_command = 8; 14152 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 14153 wmi_handle->soc->buf_offset_event = 4; 14154 #endif 14155 populate_tlv_events_id(wmi_handle->wmi_events); 14156 populate_tlv_service(wmi_handle->services); 14157 wmi_twt_attach_tlv(wmi_handle); 14158 wmi_extscan_attach_tlv(wmi_handle); 14159 wmi_smart_ant_attach_tlv(wmi_handle); 14160 wmi_dbr_attach_tlv(wmi_handle); 14161 wmi_atf_attach_tlv(wmi_handle); 14162 wmi_ap_attach_tlv(wmi_handle); 14163 wmi_bcn_attach_tlv(wmi_handle); 14164 wmi_ocb_attach_tlv(wmi_handle); 14165 wmi_nan_attach_tlv(wmi_handle); 14166 wmi_p2p_attach_tlv(wmi_handle); 14167 wmi_interop_issues_ap_attach_tlv(wmi_handle); 14168 wmi_roam_attach_tlv(wmi_handle); 14169 wmi_concurrency_attach_tlv(wmi_handle); 14170 wmi_pmo_attach_tlv(wmi_handle); 14171 wmi_sta_attach_tlv(wmi_handle); 14172 wmi_11ax_bss_color_attach_tlv(wmi_handle); 14173 wmi_fwol_attach_tlv(wmi_handle); 14174 wmi_vdev_attach_tlv(wmi_handle); 14175 wmi_cfr_attach_tlv(wmi_handle); 14176 } 14177 qdf_export_symbol(wmi_tlv_attach); 14178 14179 /** 14180 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 14181 * 14182 * Return: None 14183 */ 14184 void wmi_tlv_init(void) 14185 { 14186 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 14187 } 14188