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