1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_whitelist.h" 25 #include <qdf_module.h> 26 #include <wlan_defs.h> 27 #include <wlan_cmn.h> 28 #include <htc_services.h> 29 #ifdef FEATURE_WLAN_APF 30 #include "wmi_unified_apf_tlv.h" 31 #endif 32 #ifdef WLAN_FEATURE_ACTION_OUI 33 #include "wmi_unified_action_oui_tlv.h" 34 #endif 35 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 36 #include "wlan_pmo_hw_filter_public_struct.h" 37 #endif 38 #include <wlan_utility.h> 39 #ifdef WLAN_SUPPORT_GREEN_AP 40 #include "wlan_green_ap_api.h" 41 #endif 42 43 #include "wmi_unified_twt_api.h" 44 #include "wmi_unified_wds_api.h" 45 46 #ifdef WLAN_POLICY_MGR_ENABLE 47 #include "wlan_policy_mgr_public_struct.h" 48 #endif 49 50 #ifdef WMI_SMART_ANT_SUPPORT 51 #include "wmi_unified_smart_ant_api.h" 52 #endif 53 54 #ifdef WMI_DBR_SUPPORT 55 #include "wmi_unified_dbr_api.h" 56 #endif 57 58 #ifdef WMI_ATF_SUPPORT 59 #include "wmi_unified_atf_api.h" 60 #endif 61 62 #ifdef WMI_AP_SUPPORT 63 #include "wmi_unified_ap_api.h" 64 #endif 65 66 #include <wmi_unified_vdev_api.h> 67 #include <wmi_unified_vdev_tlv.h> 68 #include <wmi_unified_11be_tlv.h> 69 70 /* 71 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 72 * then channel_list may fill the upper 12 bits with channel flags, 73 * while using only the lower 20 bits for channel frequency. 74 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 75 * then channel_list only holds the frequency value. 76 */ 77 #define CHAN_LIST_FLAG_MASK_POS 20 78 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 79 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 80 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 81 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 82 83 /* HTC service ids for WMI for multi-radio */ 84 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 85 WMI_CONTROL_SVC_WMAC1, 86 WMI_CONTROL_SVC_WMAC2}; 87 88 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 89 /*Populate peer_param array whose index as host id and 90 *value as target id 91 */ 92 static const uint32_t peer_param_tlv[] = { 93 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 94 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 95 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 96 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 97 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 98 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 99 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 100 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 101 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 102 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 103 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 104 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 105 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 106 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 107 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 108 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 109 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 110 [WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST, 111 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 112 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 113 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 114 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 115 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 116 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 117 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 118 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 119 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 120 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 121 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 122 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 123 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 124 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 125 }; 126 127 /** 128 * Populate pdev_param_value whose index is host param and value is target 129 * param 130 */ 131 static const uint32_t pdev_param_tlv[] = { 132 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 133 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 134 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 135 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 136 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 137 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 138 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 139 [wmi_pdev_param_resmgr_offchan_mode] = 140 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 141 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 142 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 143 [wmi_pdev_param_non_agg_sw_retry_th] = 144 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 145 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 146 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 147 [wmi_pdev_param_ac_aggrsize_scaling] = 148 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 149 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 150 [wmi_pdev_param_ltr_ac_latency_be] = 151 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 152 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 153 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 154 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 155 [wmi_pdev_param_ltr_ac_latency_timeout] = 156 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 157 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 158 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 159 [wmi_pdev_param_ltr_tx_activity_timeout] = 160 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 161 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 162 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 163 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 164 [wmi_pdev_param_pcielp_txbuf_watermark] = 165 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 166 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 167 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 168 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 169 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 170 [wmi_pdev_param_pdev_stats_update_period] = 171 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 172 [wmi_pdev_param_vdev_stats_update_period] = 173 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 174 [wmi_pdev_param_peer_stats_update_period] = 175 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 176 [wmi_pdev_param_bcnflt_stats_update_period] = 177 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 178 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 179 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 180 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 181 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 182 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 183 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 184 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 185 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 186 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 187 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 188 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 189 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 190 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 191 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 192 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 193 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 194 [wmi_pdev_param_low_power_rf_enable] = 195 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 196 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 197 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 198 [wmi_pdev_param_power_collapse_enable] = 199 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 200 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 201 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 202 [wmi_pdev_param_audio_over_wlan_latency] = 203 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 204 [wmi_pdev_param_audio_over_wlan_enable] = 205 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 206 [wmi_pdev_param_whal_mib_stats_update_enable] = 207 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 208 [wmi_pdev_param_vdev_rate_stats_update_period] = 209 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 210 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 211 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 212 [wmi_pdev_param_adaptive_early_rx_enable] = 213 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 214 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 215 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 216 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 217 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 218 [wmi_pdev_param_early_rx_fix_sleep_slop] = 219 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 220 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 221 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 222 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 223 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 224 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 225 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 226 [wmi_pdev_param_bto_fix_bcn_timeout] = 227 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 228 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 229 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 230 [wmi_pdev_param_ce_bto_combo_ce_value] = 231 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 232 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 233 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 234 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 235 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 236 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 237 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 238 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 239 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 240 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 241 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 242 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 243 [wmi_pdev_peer_sta_ps_statechg_enable] = 244 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 245 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 246 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 247 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 248 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 249 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 250 [wmi_pdev_param_set_mcast_bcast_echo] = 251 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 252 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 253 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 254 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 255 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 256 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 257 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 258 [wmi_pdev_param_enable_per_tid_amsdu] = 259 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 260 [wmi_pdev_param_enable_per_tid_ampdu] = 261 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 262 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 263 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 264 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 265 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 266 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 267 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 268 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 269 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 270 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 271 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 272 [wmi_pdev_param_atf_obss_noise_sch] = 273 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 274 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 275 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 276 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 277 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 278 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 279 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 280 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 281 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 282 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 283 [wmi_pdev_param_set_disable_reset_cmdid] = 284 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 285 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 286 [wmi_pdev_param_txbf_sound_period_cmdid] = 287 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 288 [wmi_pdev_param_set_burst_mode_cmdid] = 289 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 290 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 291 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 292 [wmi_pdev_param_set_promisc_mode_cmdid] = 293 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 294 [wmi_pdev_param_set_ppdu_duration_cmdid] = 295 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 296 [wmi_pdev_param_remove_mcast2ucast_buffer] = 297 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 298 [wmi_pdev_param_set_mcast2ucast_buffer] = 299 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 300 [wmi_pdev_param_set_mcast2ucast_mode] = 301 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 302 [wmi_pdev_param_smart_antenna_default_antenna] = 303 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 304 [wmi_pdev_param_fast_channel_reset] = 305 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 306 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 307 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 308 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 309 [wmi_pdev_param_antenna_gain_half_db] = 310 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 311 [wmi_pdev_param_esp_indication_period] = 312 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 313 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 314 [wmi_pdev_param_esp_airtime_fraction] = 315 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 316 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 317 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 318 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 319 /* Trigger interval for all trigger types. */ 320 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 321 [wmi_pdev_param_sub_channel_marking] = 322 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 323 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 324 [wmi_pdev_param_equal_ru_allocation_enable] = 325 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 326 [wmi_pdev_param_per_peer_prd_cfr_enable] = 327 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 328 [wmi_pdev_param_nav_override_config] = 329 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 330 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 331 [wmi_pdev_param_set_prb_rsp_ttl] = 332 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 333 [wmi_pdev_param_set_mu_ppdu_duration] = 334 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 335 [wmi_pdev_param_set_tbtt_ctrl] = 336 WMI_PDEV_PARAM_SET_TBTT_CTRL, 337 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 338 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 339 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 340 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 341 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 342 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 343 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 344 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 345 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 346 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 347 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 348 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 349 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 350 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 351 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 352 [wmi_pdev_param_low_latency_mode] = 353 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 354 [wmi_pdev_param_scan_radio_tx_on_dfs] = 355 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 356 }; 357 358 /** 359 * Populate vdev_param_value_tlv array whose index is host param 360 * and value is target param 361 */ 362 static const uint32_t vdev_param_tlv[] = { 363 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 364 [wmi_vdev_param_fragmentation_threshold] = 365 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 366 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 367 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 368 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 369 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 370 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 371 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 372 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 373 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 374 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 375 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 376 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 377 [wmi_vdev_oc_scheduler_air_time_limit] = 378 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 379 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 380 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 381 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 382 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 383 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 384 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 385 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 386 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 387 [wmi_vdev_param_disable_htprotection] = 388 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 389 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 390 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 391 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 392 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 393 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 394 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 395 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 396 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 397 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 398 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 399 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 400 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 401 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 402 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 403 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 404 [wmi_vdev_param_unknown_dest_indicate] = 405 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 406 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 407 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 408 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 409 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 410 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 411 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 412 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 413 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 414 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 415 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 416 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 417 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 418 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 419 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 420 [wmi_vdev_param_early_rx_adjust_enable] = 421 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 422 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 423 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 424 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 425 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 426 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 427 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 428 [wmi_vdev_param_early_rx_adjust_pause] = 429 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 430 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 431 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 432 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 433 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 434 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 435 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 436 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 437 [wmi_vdev_param_early_rx_drift_sample] = 438 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 439 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 440 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 441 [wmi_vdev_param_ebt_resync_timeout] = 442 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 443 [wmi_vdev_param_aggr_trig_event_enable] = 444 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 445 [wmi_vdev_param_is_ibss_power_save_allowed] = 446 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 447 [wmi_vdev_param_is_power_collapse_allowed] = 448 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 449 [wmi_vdev_param_is_awake_on_txrx_enabled] = 450 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 451 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 452 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 453 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 454 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 455 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 456 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 457 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 458 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 459 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 460 [wmi_vdev_param_stats_avg_factor] = 461 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 462 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 463 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 464 [wmi_vdev_param_mcc_rtscts_protection_enable] = 465 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 466 [wmi_vdev_param_mcc_broadcast_probe_enable] = 467 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 468 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 469 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 470 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 471 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 472 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 473 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 474 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 475 [wmi_vdev_param_set_he_sounding_mode] = 476 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 477 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 478 #ifdef WLAN_FEATURE_11BE 479 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 480 [wmi_vdev_param_set_eht_mu_mode] = WMI_VDEV_PARAM_SET_EHT_MU_MODE, 481 [wmi_vdev_param_set_eht_puncturing_mode] = 482 WMI_VDEV_PARAM_SET_EHT_PUNCTURING_MODE, 483 [wmi_vdev_param_set_eht_ltf] = WMI_VDEV_PARAM_EHT_LTF, 484 [wmi_vdev_param_set_ul_eht_ltf] = WMI_VDEV_PARAM_UL_EHT_LTF, 485 [wmi_vdev_param_set_eht_dcm] = WMI_VDEV_PARAM_EHT_DCM, 486 [wmi_vdev_param_set_eht_range_ext] = WMI_VDEV_PARAM_EHT_RANGE_EXT, 487 [wmi_vdev_param_set_non_data_eht_range_ext] = 488 WMI_VDEV_PARAM_NON_DATA_EHT_RANGE_EXT, 489 #endif 490 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 491 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 492 [wmi_vdev_param_atf_ssid_sched_policy] = 493 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 494 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 495 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 496 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 497 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 498 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 499 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 500 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 501 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 502 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 503 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 504 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 505 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 506 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 507 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 508 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 509 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 510 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 511 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 512 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 513 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 514 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 515 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 516 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 517 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 518 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 519 [wmi_vdev_param_mcast_rc_stale_period] = 520 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 521 [wmi_vdev_param_enable_multi_group_key] = 522 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 523 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 524 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 525 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 526 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 527 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 528 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 529 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 530 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 531 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 532 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 533 [wmi_vdev_param_nan_config_features] = 534 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 535 [wmi_vdev_param_enable_disable_rtt_responder_role] = 536 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 537 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 538 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 539 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 540 }; 541 #endif 542 543 #ifndef WMI_PKTLOG_EVENT_CBF 544 #define WMI_PKTLOG_EVENT_CBF 0x100 545 #endif 546 547 /** 548 * Populate the pktlog event tlv array, where 549 * the values are the FW WMI events, which host 550 * uses to communicate with FW for pktlog 551 */ 552 553 static const uint32_t pktlog_event_tlv[] = { 554 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 555 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 556 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 557 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 558 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 559 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 560 WMI_PKTLOG_EVENT_SMART_ANTENNA, 561 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 562 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 563 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 564 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 565 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 566 #ifdef QCA_WIFI_QCN9224 567 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 568 #endif 569 }; 570 571 /** 572 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 573 * host to target defines. 574 * @wmi_handle: pointer to wmi_handle 575 * @param pdev_id: host pdev_id to be converted. 576 * Return: target pdev_id after conversion. 577 */ 578 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 579 uint32_t pdev_id) 580 { 581 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 582 if (!wmi_handle->soc->is_pdev_is_map_enable) { 583 switch (pdev_id) { 584 case WMI_HOST_PDEV_ID_0: 585 return WMI_PDEV_ID_1ST; 586 case WMI_HOST_PDEV_ID_1: 587 return WMI_PDEV_ID_2ND; 588 case WMI_HOST_PDEV_ID_2: 589 return WMI_PDEV_ID_3RD; 590 } 591 } else { 592 return wmi_handle->cmd_pdev_id_map[pdev_id]; 593 } 594 } else { 595 return WMI_PDEV_ID_SOC; 596 } 597 598 QDF_ASSERT(0); 599 600 return WMI_PDEV_ID_SOC; 601 } 602 603 /** 604 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 605 * target to host defines. 606 * @wmi_handle: pointer to wmi_handle 607 * @param pdev_id: target pdev_id to be converted. 608 * Return: host pdev_id after conversion. 609 */ 610 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 611 uint32_t pdev_id) 612 { 613 614 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 615 if (!wmi_handle->soc->is_pdev_is_map_enable) { 616 switch (pdev_id) { 617 case WMI_PDEV_ID_1ST: 618 return WMI_HOST_PDEV_ID_0; 619 case WMI_PDEV_ID_2ND: 620 return WMI_HOST_PDEV_ID_1; 621 case WMI_PDEV_ID_3RD: 622 return WMI_HOST_PDEV_ID_2; 623 } 624 } else { 625 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 626 } 627 } else if (pdev_id == WMI_PDEV_ID_SOC) { 628 return WMI_HOST_PDEV_ID_SOC; 629 } else { 630 wmi_err("Invalid pdev_id"); 631 } 632 633 return WMI_HOST_PDEV_ID_INVALID; 634 } 635 636 /** 637 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 638 * host to target defines. 639 * @wmi_handle: pointer to wmi_handle 640 * @param phy_id: host pdev_id to be converted. 641 * Return: target phy_id after conversion. 642 */ 643 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 644 uint32_t phy_id) 645 { 646 if (!wmi_handle->soc->is_phy_id_map_enable || 647 phy_id >= WMI_MAX_RADIOS) { 648 return phy_id; 649 } 650 651 return wmi_handle->cmd_phy_id_map[phy_id]; 652 } 653 654 /** 655 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 656 * target to host defines. 657 * @wmi_handle: pointer to wmi_handle 658 * @param phy_id: target phy_id to be converted. 659 * Return: host phy_id after conversion. 660 */ 661 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 662 uint32_t phy_id) 663 { 664 if (!wmi_handle->soc->is_phy_id_map_enable || 665 phy_id >= WMI_MAX_RADIOS) { 666 return phy_id; 667 } 668 669 return wmi_handle->evt_phy_id_map[phy_id]; 670 } 671 672 /** 673 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 674 * 675 * Return None. 676 */ 677 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 678 uint32_t *pdev_id_map, 679 uint8_t size) 680 { 681 int i = 0; 682 683 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 684 for (i = 0; i < size; i++) { 685 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 686 wmi_handle->evt_pdev_id_map[i] = 687 WMI_HOST_PDEV_ID_INVALID; 688 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 689 wmi_handle->evt_phy_id_map[i] = 690 WMI_HOST_PDEV_ID_INVALID; 691 } 692 693 for (i = 0; i < size; i++) { 694 if (wmi_handle->cmd_pdev_id_map[i] != 695 WMI_HOST_PDEV_ID_INVALID) { 696 wmi_handle->evt_pdev_id_map 697 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 698 } 699 if (wmi_handle->cmd_phy_id_map[i] != 700 WMI_HOST_PDEV_ID_INVALID) { 701 wmi_handle->evt_phy_id_map 702 [wmi_handle->cmd_phy_id_map[i]] = i; 703 } 704 } 705 wmi_handle->soc->is_pdev_is_map_enable = true; 706 wmi_handle->soc->is_phy_id_map_enable = true; 707 } else { 708 wmi_handle->soc->is_pdev_is_map_enable = false; 709 wmi_handle->soc->is_phy_id_map_enable = false; 710 } 711 712 wmi_handle->ops->convert_pdev_id_host_to_target = 713 convert_host_pdev_id_to_target_pdev_id; 714 wmi_handle->ops->convert_pdev_id_target_to_host = 715 convert_target_pdev_id_to_host_pdev_id; 716 717 /* phy_id convert function assignments */ 718 wmi_handle->ops->convert_phy_id_host_to_target = 719 convert_host_phy_id_to_target_phy_id; 720 wmi_handle->ops->convert_phy_id_target_to_host = 721 convert_target_phy_id_to_host_phy_id; 722 } 723 724 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 725 * buffer. 726 * @wmi_handle: pointer to wmi_handle 727 * @cmd: pointer target vdev create command buffer 728 * @param: pointer host params for vdev create 729 * 730 * Return: None 731 */ 732 static inline void copy_vdev_create_pdev_id( 733 struct wmi_unified *wmi_handle, 734 wmi_vdev_create_cmd_fixed_param * cmd, 735 struct vdev_create_params *param) 736 { 737 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 738 wmi_handle, 739 param->pdev_id); 740 } 741 742 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 743 { 744 uint16_t mtrace_message_id; 745 746 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 747 (QDF_WMI_MTRACE_GRP_ID(message_id) << 748 QDF_WMI_MTRACE_CMD_NUM_BITS); 749 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 750 mtrace_message_id, vdev_id, data); 751 } 752 qdf_export_symbol(wmi_mtrace); 753 754 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 755 wmi_buf_t buf, 756 uint32_t buflen, uint32_t cmd_id, 757 bool is_qmi_send_support) 758 { 759 if (!is_qmi_send_support) 760 goto send_over_wmi; 761 762 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 763 goto send_over_wmi; 764 765 if (wmi_is_target_suspend_acked(wmi_handle)) { 766 if (QDF_IS_STATUS_SUCCESS( 767 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 768 buflen, cmd_id))) 769 return QDF_STATUS_SUCCESS; 770 } 771 772 send_over_wmi: 773 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 774 775 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 776 } 777 778 /** 779 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 780 * @wmi_handle: wmi handle 781 * @param: pointer to hold vdev create parameter 782 * @macaddr: vdev mac address 783 * 784 * Return: QDF_STATUS_SUCCESS for success or error code 785 */ 786 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 787 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 788 struct vdev_create_params *param) 789 { 790 wmi_vdev_create_cmd_fixed_param *cmd; 791 wmi_buf_t buf; 792 int32_t len = sizeof(*cmd); 793 QDF_STATUS ret; 794 int num_bands = 2; 795 uint8_t *buf_ptr; 796 wmi_vdev_txrx_streams *txrx_streams; 797 798 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 799 len += vdev_create_mlo_params_size(); 800 801 buf = wmi_buf_alloc(wmi_handle, len); 802 if (!buf) 803 return QDF_STATUS_E_NOMEM; 804 805 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 806 WMITLV_SET_HDR(&cmd->tlv_header, 807 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 808 WMITLV_GET_STRUCT_TLVLEN 809 (wmi_vdev_create_cmd_fixed_param)); 810 cmd->vdev_id = param->vdev_id; 811 cmd->vdev_type = param->type; 812 cmd->vdev_subtype = param->subtype; 813 cmd->flags = param->mbssid_flags; 814 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 815 cmd->vdevid_trans = param->vdevid_trans; 816 cmd->num_cfg_txrx_streams = num_bands; 817 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 818 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 819 cmd->vdev_stats_id = param->vdev_stats_id; 820 #endif 821 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 822 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 823 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 824 param->vdev_id, cmd->pdev_id, 825 QDF_MAC_ADDR_REF(macaddr)); 826 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 827 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 828 (num_bands * sizeof(wmi_vdev_txrx_streams))); 829 buf_ptr += WMI_TLV_HDR_SIZE; 830 831 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 832 param->type, param->subtype, 833 param->nss_2g, param->nss_5g); 834 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 835 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 836 txrx_streams->supported_tx_streams = param->nss_2g; 837 txrx_streams->supported_rx_streams = param->nss_2g; 838 WMITLV_SET_HDR(&txrx_streams->tlv_header, 839 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 840 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 841 842 txrx_streams++; 843 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 844 txrx_streams->supported_tx_streams = param->nss_5g; 845 txrx_streams->supported_rx_streams = param->nss_5g; 846 WMITLV_SET_HDR(&txrx_streams->tlv_header, 847 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 848 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 849 850 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 851 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 852 853 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 854 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 855 if (QDF_IS_STATUS_ERROR(ret)) { 856 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 857 wmi_buf_free(buf); 858 } 859 860 return ret; 861 } 862 863 /** 864 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 865 * @wmi_handle: wmi handle 866 * @if_id: vdev id 867 * 868 * Return: QDF_STATUS_SUCCESS for success or error code 869 */ 870 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 871 uint8_t if_id) 872 { 873 wmi_vdev_delete_cmd_fixed_param *cmd; 874 wmi_buf_t buf; 875 QDF_STATUS ret; 876 877 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 878 if (!buf) 879 return QDF_STATUS_E_NOMEM; 880 881 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 882 WMITLV_SET_HDR(&cmd->tlv_header, 883 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 884 WMITLV_GET_STRUCT_TLVLEN 885 (wmi_vdev_delete_cmd_fixed_param)); 886 cmd->vdev_id = if_id; 887 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 888 ret = wmi_unified_cmd_send(wmi_handle, buf, 889 sizeof(wmi_vdev_delete_cmd_fixed_param), 890 WMI_VDEV_DELETE_CMDID); 891 if (QDF_IS_STATUS_ERROR(ret)) { 892 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 893 wmi_buf_free(buf); 894 } 895 wmi_debug("vdev id = %d", if_id); 896 897 return ret; 898 } 899 900 /** 901 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 902 * @wmi_handle: wmi handle 903 * @vdev_id: vdev id 904 * @nss_chains_user_cfg: user configured nss chain params 905 * 906 * Return: QDF_STATUS_SUCCESS for success or error code 907 */ 908 static QDF_STATUS 909 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 910 uint8_t vdev_id, 911 struct vdev_nss_chains *user_cfg) 912 { 913 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 914 wmi_buf_t buf; 915 QDF_STATUS ret; 916 917 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 918 if (!buf) 919 return QDF_STATUS_E_NOMEM; 920 921 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 922 WMITLV_SET_HDR(&cmd->tlv_header, 923 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 924 WMITLV_GET_STRUCT_TLVLEN 925 (wmi_vdev_chainmask_config_cmd_fixed_param)); 926 cmd->vdev_id = vdev_id; 927 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 928 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 929 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 930 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 931 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 932 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 933 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 934 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 935 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 936 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 937 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 938 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 939 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 940 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 941 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 942 943 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 944 ret = wmi_unified_cmd_send(wmi_handle, buf, 945 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 946 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 947 if (QDF_IS_STATUS_ERROR(ret)) { 948 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 949 wmi_buf_free(buf); 950 } 951 wmi_debug("vdev_id %d", vdev_id); 952 953 return ret; 954 } 955 956 /** 957 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 958 * @wmi: wmi handle 959 * @vdev_id: vdev id 960 * 961 * Return: QDF_STATUS_SUCCESS for success or erro code 962 */ 963 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 964 uint8_t vdev_id) 965 { 966 wmi_vdev_stop_cmd_fixed_param *cmd; 967 wmi_buf_t buf; 968 int32_t len = sizeof(*cmd); 969 970 buf = wmi_buf_alloc(wmi, len); 971 if (!buf) 972 return QDF_STATUS_E_NOMEM; 973 974 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 975 WMITLV_SET_HDR(&cmd->tlv_header, 976 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 977 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 978 cmd->vdev_id = vdev_id; 979 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 980 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 981 wmi_err("Failed to send vdev stop command"); 982 wmi_buf_free(buf); 983 return QDF_STATUS_E_FAILURE; 984 } 985 wmi_debug("vdev id = %d", vdev_id); 986 987 return 0; 988 } 989 990 /** 991 * send_vdev_down_cmd_tlv() - send vdev down command to fw 992 * @wmi: wmi handle 993 * @vdev_id: vdev id 994 * 995 * Return: QDF_STATUS_SUCCESS for success or error code 996 */ 997 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 998 { 999 wmi_vdev_down_cmd_fixed_param *cmd; 1000 wmi_buf_t buf; 1001 int32_t len = sizeof(*cmd); 1002 1003 buf = wmi_buf_alloc(wmi, len); 1004 if (!buf) 1005 return QDF_STATUS_E_NOMEM; 1006 1007 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1008 WMITLV_SET_HDR(&cmd->tlv_header, 1009 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1010 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1011 cmd->vdev_id = vdev_id; 1012 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1013 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1014 wmi_err("Failed to send vdev down"); 1015 wmi_buf_free(buf); 1016 return QDF_STATUS_E_FAILURE; 1017 } 1018 wmi_debug("vdev_id %d", vdev_id); 1019 1020 return 0; 1021 } 1022 1023 static inline void copy_channel_info( 1024 wmi_vdev_start_request_cmd_fixed_param * cmd, 1025 wmi_channel *chan, 1026 struct vdev_start_params *req) 1027 { 1028 chan->mhz = req->channel.mhz; 1029 1030 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1031 1032 chan->band_center_freq1 = req->channel.cfreq1; 1033 chan->band_center_freq2 = req->channel.cfreq2; 1034 1035 if (req->channel.half_rate) 1036 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1037 else if (req->channel.quarter_rate) 1038 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1039 1040 if (req->channel.dfs_set) { 1041 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1042 cmd->disable_hw_ack = req->disable_hw_ack; 1043 } 1044 1045 if (req->channel.dfs_set_cfreq2) 1046 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1047 1048 if (req->channel.is_stadfs_en) 1049 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1050 1051 /* According to firmware both reg power and max tx power 1052 * on set channel power is used and set it to max reg 1053 * power from regulatory. 1054 */ 1055 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1056 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1057 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1058 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1059 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1060 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1061 1062 } 1063 1064 /** 1065 * vdev_start_cmd_fill_11be() - 11be information fiiling in vdev_ststart 1066 * @cmd: wmi cmd 1067 * @req: vdev start params 1068 * 1069 * Return: QDF status 1070 */ 1071 #ifdef WLAN_FEATURE_11BE 1072 static void 1073 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1074 struct vdev_start_params *req) 1075 { 1076 cmd->eht_ops = req->eht_ops; 1077 cmd->puncture_20mhz_bitmap = req->channel.puncture_pattern; 1078 wmi_info("EHT ops: %x puncture_pattern %x", 1079 req->eht_ops, req->channel.puncture_pattern); 1080 } 1081 #else 1082 static void 1083 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1084 struct vdev_start_params *req) 1085 { 1086 } 1087 #endif 1088 1089 /** 1090 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1091 * @wmi_handle: wmi handle 1092 * @req: vdev start params 1093 * 1094 * Return: QDF status 1095 */ 1096 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1097 struct vdev_start_params *req) 1098 { 1099 wmi_vdev_start_request_cmd_fixed_param *cmd; 1100 wmi_buf_t buf; 1101 wmi_channel *chan; 1102 int32_t len, ret; 1103 uint8_t *buf_ptr; 1104 1105 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1106 if (!req->is_restart) 1107 len += vdev_start_mlo_params_size(req); 1108 buf = wmi_buf_alloc(wmi_handle, len); 1109 if (!buf) 1110 return QDF_STATUS_E_NOMEM; 1111 1112 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1113 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1114 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1115 WMITLV_SET_HDR(&cmd->tlv_header, 1116 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1117 WMITLV_GET_STRUCT_TLVLEN 1118 (wmi_vdev_start_request_cmd_fixed_param)); 1119 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1120 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1121 cmd->vdev_id = req->vdev_id; 1122 1123 /* Fill channel info */ 1124 copy_channel_info(cmd, chan, req); 1125 cmd->beacon_interval = req->beacon_interval; 1126 cmd->dtim_period = req->dtim_period; 1127 1128 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1129 if (req->bcn_tx_rate_code) 1130 wmi_enable_bcn_ratecode(&cmd->flags); 1131 1132 if (!req->is_restart) { 1133 if (req->pmf_enabled) 1134 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1135 1136 cmd->mbss_capability_flags = req->mbssid_flags; 1137 cmd->vdevid_trans = req->vdevid_trans; 1138 } 1139 1140 /* Copy the SSID */ 1141 if (req->ssid.length) { 1142 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1143 cmd->ssid.ssid_len = req->ssid.length; 1144 else 1145 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1146 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1147 cmd->ssid.ssid_len); 1148 } 1149 1150 if (req->hidden_ssid) 1151 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1152 1153 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1154 cmd->num_noa_descriptors = req->num_noa_descriptors; 1155 cmd->preferred_rx_streams = req->preferred_rx_streams; 1156 cmd->preferred_tx_streams = req->preferred_tx_streams; 1157 cmd->cac_duration_ms = req->cac_duration_ms; 1158 cmd->regdomain = req->regdomain; 1159 cmd->he_ops = req->he_ops; 1160 1161 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1162 sizeof(wmi_channel)); 1163 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1164 cmd->num_noa_descriptors * 1165 sizeof(wmi_p2p_noa_descriptor)); 1166 if (!req->is_restart) { 1167 buf_ptr += WMI_TLV_HDR_SIZE + 1168 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1169 1170 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1171 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1172 } 1173 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1174 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1175 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1176 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1177 "req->dis_hw_ack: %d ", req->vdev_id, 1178 chan->mhz, req->channel.phy_mode, chan->info, 1179 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1180 chan->band_center_freq1, chan->band_center_freq2, 1181 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1182 req->preferred_tx_streams, req->preferred_rx_streams, 1183 req->ldpc_rx_enabled, req->cac_duration_ms, 1184 req->regdomain, req->he_ops, 1185 req->disable_hw_ack); 1186 1187 vdev_start_cmd_fill_11be(cmd, req); 1188 1189 if (req->is_restart) { 1190 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1191 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1192 WMI_VDEV_RESTART_REQUEST_CMDID); 1193 } else { 1194 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1195 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1196 WMI_VDEV_START_REQUEST_CMDID); 1197 } 1198 if (ret) { 1199 wmi_err("Failed to send vdev start command"); 1200 wmi_buf_free(buf); 1201 return QDF_STATUS_E_FAILURE; 1202 } 1203 1204 return QDF_STATUS_SUCCESS; 1205 } 1206 1207 /** 1208 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1209 * @wmi: wmi handle 1210 * @peer_addr: peer mac address 1211 * @param: pointer to hold peer flush tid parameter 1212 * 1213 * Return: 0 for success or error code 1214 */ 1215 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1216 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1217 struct peer_flush_params *param) 1218 { 1219 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1220 wmi_buf_t buf; 1221 int32_t len = sizeof(*cmd); 1222 1223 buf = wmi_buf_alloc(wmi, len); 1224 if (!buf) 1225 return QDF_STATUS_E_NOMEM; 1226 1227 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1228 WMITLV_SET_HDR(&cmd->tlv_header, 1229 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1230 WMITLV_GET_STRUCT_TLVLEN 1231 (wmi_peer_flush_tids_cmd_fixed_param)); 1232 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1233 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1234 cmd->vdev_id = param->vdev_id; 1235 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1236 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1237 param->peer_tid_bitmap); 1238 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1239 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1240 wmi_err("Failed to send flush tid command"); 1241 wmi_buf_free(buf); 1242 return QDF_STATUS_E_FAILURE; 1243 } 1244 1245 return 0; 1246 } 1247 1248 /** 1249 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1250 * @wmi: wmi handle 1251 * @peer_addr: peer mac addr 1252 * @vdev_id: vdev id 1253 * 1254 * Return: QDF_STATUS_SUCCESS for success or error code 1255 */ 1256 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1257 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1258 uint8_t vdev_id) 1259 { 1260 wmi_peer_delete_cmd_fixed_param *cmd; 1261 wmi_buf_t buf; 1262 int32_t len = sizeof(*cmd); 1263 buf = wmi_buf_alloc(wmi, len); 1264 if (!buf) 1265 return QDF_STATUS_E_NOMEM; 1266 1267 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 1268 WMITLV_SET_HDR(&cmd->tlv_header, 1269 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1270 WMITLV_GET_STRUCT_TLVLEN 1271 (wmi_peer_delete_cmd_fixed_param)); 1272 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1273 cmd->vdev_id = vdev_id; 1274 1275 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1276 QDF_MAC_ADDR_REF(peer_addr), vdev_id); 1277 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1278 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1279 wmi_err("Failed to send peer delete command"); 1280 wmi_buf_free(buf); 1281 return QDF_STATUS_E_FAILURE; 1282 } 1283 1284 return 0; 1285 } 1286 1287 /** 1288 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1289 * @wmi: wmi handle 1290 * @param: pointer to hold peer delete all parameter 1291 * 1292 * Return: QDF_STATUS_SUCCESS for success or error code 1293 */ 1294 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1295 wmi_unified_t wmi, 1296 struct peer_delete_all_params *param) 1297 { 1298 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1299 wmi_buf_t buf; 1300 int32_t len = sizeof(*cmd); 1301 1302 buf = wmi_buf_alloc(wmi, len); 1303 if (!buf) 1304 return QDF_STATUS_E_NOMEM; 1305 1306 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1307 WMITLV_SET_HDR( 1308 &cmd->tlv_header, 1309 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1310 WMITLV_GET_STRUCT_TLVLEN 1311 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1312 cmd->vdev_id = param->vdev_id; 1313 1314 wmi_debug("vdev_id %d", cmd->vdev_id); 1315 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1316 if (wmi_unified_cmd_send(wmi, buf, len, 1317 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1318 wmi_err("Failed to send peer del all command"); 1319 wmi_buf_free(buf); 1320 return QDF_STATUS_E_FAILURE; 1321 } 1322 1323 return QDF_STATUS_SUCCESS; 1324 } 1325 1326 /** 1327 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1328 * to target id. 1329 * @peer_param_id: host param id. 1330 * 1331 * Return: Target param id. 1332 */ 1333 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1334 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1335 uint32_t peer_param_id) 1336 { 1337 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1338 return peer_param_tlv[peer_param_id]; 1339 return WMI_UNAVAILABLE_PARAM; 1340 } 1341 #else 1342 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1343 uint32_t peer_param_id) 1344 { 1345 return peer_param_id; 1346 } 1347 #endif 1348 1349 /** 1350 * send_peer_param_cmd_tlv() - set peer parameter in fw 1351 * @wmi: wmi handle 1352 * @peer_addr: peer mac address 1353 * @param : pointer to hold peer set parameter 1354 * 1355 * Return: QDF_STATUS_SUCCESS for success or error code 1356 */ 1357 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1358 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1359 struct peer_set_params *param) 1360 { 1361 wmi_peer_set_param_cmd_fixed_param *cmd; 1362 wmi_buf_t buf; 1363 int32_t err; 1364 uint32_t param_id; 1365 1366 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1367 if (param_id == WMI_UNAVAILABLE_PARAM) { 1368 wmi_err("Unavailable param %d", param->param_id); 1369 return QDF_STATUS_E_NOSUPPORT; 1370 } 1371 1372 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1373 if (!buf) 1374 return QDF_STATUS_E_NOMEM; 1375 1376 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1377 WMITLV_SET_HDR(&cmd->tlv_header, 1378 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1379 WMITLV_GET_STRUCT_TLVLEN 1380 (wmi_peer_set_param_cmd_fixed_param)); 1381 cmd->vdev_id = param->vdev_id; 1382 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1383 cmd->param_id = param_id; 1384 cmd->param_value = param->param_value; 1385 1386 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1387 cmd->vdev_id, 1388 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1389 cmd->param_value); 1390 1391 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1392 err = wmi_unified_cmd_send(wmi, buf, 1393 sizeof(wmi_peer_set_param_cmd_fixed_param), 1394 WMI_PEER_SET_PARAM_CMDID); 1395 if (err) { 1396 wmi_err("Failed to send set_param cmd"); 1397 wmi_buf_free(buf); 1398 return QDF_STATUS_E_FAILURE; 1399 } 1400 1401 return 0; 1402 } 1403 1404 /** 1405 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1406 * @wmi: wmi handle 1407 * @bssid: bssid 1408 * @vdev_up_params: pointer to hold vdev up parameter 1409 * 1410 * Return: QDF_STATUS_SUCCESS for success or error code 1411 */ 1412 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1413 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1414 struct vdev_up_params *params) 1415 { 1416 wmi_vdev_up_cmd_fixed_param *cmd; 1417 wmi_buf_t buf; 1418 int32_t len = sizeof(*cmd); 1419 1420 wmi_debug("VDEV_UP"); 1421 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1422 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1423 buf = wmi_buf_alloc(wmi, len); 1424 if (!buf) 1425 return QDF_STATUS_E_NOMEM; 1426 1427 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1428 WMITLV_SET_HDR(&cmd->tlv_header, 1429 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1430 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1431 cmd->vdev_id = params->vdev_id; 1432 cmd->vdev_assoc_id = params->assoc_id; 1433 cmd->profile_idx = params->profile_idx; 1434 cmd->profile_num = params->profile_num; 1435 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1436 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1437 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1438 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1439 wmi_err("Failed to send vdev up command"); 1440 wmi_buf_free(buf); 1441 return QDF_STATUS_E_FAILURE; 1442 } 1443 1444 return 0; 1445 } 1446 1447 /** 1448 * send_peer_create_cmd_tlv() - send peer create command to fw 1449 * @wmi: wmi handle 1450 * @peer_addr: peer mac address 1451 * @peer_type: peer type 1452 * @vdev_id: vdev id 1453 * 1454 * Return: QDF_STATUS_SUCCESS for success or error code 1455 */ 1456 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1457 struct peer_create_params *param) 1458 { 1459 wmi_peer_create_cmd_fixed_param *cmd; 1460 wmi_buf_t buf; 1461 uint8_t *buf_ptr; 1462 int32_t len = sizeof(*cmd); 1463 1464 len += peer_create_mlo_params_size(param); 1465 buf = wmi_buf_alloc(wmi, len); 1466 if (!buf) 1467 return QDF_STATUS_E_NOMEM; 1468 1469 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1470 WMITLV_SET_HDR(&cmd->tlv_header, 1471 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1472 WMITLV_GET_STRUCT_TLVLEN 1473 (wmi_peer_create_cmd_fixed_param)); 1474 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1475 cmd->peer_type = param->peer_type; 1476 cmd->vdev_id = param->vdev_id; 1477 1478 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1479 buf_ptr += sizeof(*cmd); 1480 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1481 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1482 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1483 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1484 wmi_buf_free(buf); 1485 return QDF_STATUS_E_FAILURE; 1486 } 1487 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1488 QDF_MAC_ADDR_REF(param->peer_addr), 1489 param->vdev_id); 1490 1491 return 0; 1492 } 1493 1494 /** 1495 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1496 * command to fw 1497 * @wmi: wmi handle 1498 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1499 * 1500 * Return: 0 for success or error code 1501 */ 1502 static 1503 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1504 struct rx_reorder_queue_setup_params *param) 1505 { 1506 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1507 wmi_buf_t buf; 1508 int32_t len = sizeof(*cmd); 1509 1510 buf = wmi_buf_alloc(wmi, len); 1511 if (!buf) 1512 return QDF_STATUS_E_NOMEM; 1513 1514 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1515 WMITLV_SET_HDR(&cmd->tlv_header, 1516 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1517 WMITLV_GET_STRUCT_TLVLEN 1518 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1519 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1520 cmd->vdev_id = param->vdev_id; 1521 cmd->tid = param->tid; 1522 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1523 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1524 cmd->queue_no = param->queue_no; 1525 cmd->ba_window_size_valid = param->ba_window_size_valid; 1526 cmd->ba_window_size = param->ba_window_size; 1527 1528 1529 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1530 if (wmi_unified_cmd_send(wmi, buf, len, 1531 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1532 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1533 wmi_buf_free(buf); 1534 return QDF_STATUS_E_FAILURE; 1535 } 1536 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1537 QDF_MAC_ADDR_REF(param->peer_macaddr), 1538 param->vdev_id, param->tid); 1539 1540 return QDF_STATUS_SUCCESS; 1541 } 1542 1543 /** 1544 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1545 * command to fw 1546 * @wmi: wmi handle 1547 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1548 * 1549 * Return: 0 for success or error code 1550 */ 1551 static 1552 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1553 struct rx_reorder_queue_remove_params *param) 1554 { 1555 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1556 wmi_buf_t buf; 1557 int32_t len = sizeof(*cmd); 1558 1559 buf = wmi_buf_alloc(wmi, len); 1560 if (!buf) 1561 return QDF_STATUS_E_NOMEM; 1562 1563 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1564 wmi_buf_data(buf); 1565 WMITLV_SET_HDR(&cmd->tlv_header, 1566 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1567 WMITLV_GET_STRUCT_TLVLEN 1568 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1569 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1570 cmd->vdev_id = param->vdev_id; 1571 cmd->tid_mask = param->peer_tid_bitmap; 1572 1573 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1574 if (wmi_unified_cmd_send(wmi, buf, len, 1575 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1576 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1577 wmi_buf_free(buf); 1578 return QDF_STATUS_E_FAILURE; 1579 } 1580 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1581 QDF_MAC_ADDR_REF(param->peer_macaddr), 1582 param->vdev_id, param->peer_tid_bitmap); 1583 1584 return QDF_STATUS_SUCCESS; 1585 } 1586 1587 #ifdef WLAN_SUPPORT_GREEN_AP 1588 /** 1589 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1590 * @wmi_handle: wmi handle 1591 * @value: value 1592 * @pdev_id: pdev id to have radio context 1593 * 1594 * Return: QDF_STATUS_SUCCESS for success or error code 1595 */ 1596 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1597 uint32_t value, uint8_t pdev_id) 1598 { 1599 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1600 wmi_buf_t buf; 1601 int32_t len = sizeof(*cmd); 1602 1603 wmi_debug("Set Green AP PS val %d", value); 1604 1605 buf = wmi_buf_alloc(wmi_handle, len); 1606 if (!buf) 1607 return QDF_STATUS_E_NOMEM; 1608 1609 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1610 WMITLV_SET_HDR(&cmd->tlv_header, 1611 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1612 WMITLV_GET_STRUCT_TLVLEN 1613 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1614 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1615 wmi_handle, 1616 pdev_id); 1617 cmd->enable = value; 1618 1619 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1620 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1621 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1622 wmi_err("Set Green AP PS param Failed val %d", value); 1623 wmi_buf_free(buf); 1624 return QDF_STATUS_E_FAILURE; 1625 } 1626 1627 return 0; 1628 } 1629 #endif 1630 1631 /** 1632 * send_pdev_utf_cmd_tlv() - send utf command to fw 1633 * @wmi_handle: wmi handle 1634 * @param: pointer to pdev_utf_params 1635 * @mac_id: mac id to have radio context 1636 * 1637 * Return: QDF_STATUS_SUCCESS for success or error code 1638 */ 1639 static QDF_STATUS 1640 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1641 struct pdev_utf_params *param, 1642 uint8_t mac_id) 1643 { 1644 wmi_buf_t buf; 1645 uint8_t *cmd; 1646 /* if param->len is 0 no data is sent, return error */ 1647 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1648 static uint8_t msgref = 1; 1649 uint8_t segNumber = 0, segInfo, numSegments; 1650 uint16_t chunk_len, total_bytes; 1651 uint8_t *bufpos; 1652 struct seg_hdr_info segHdrInfo; 1653 1654 bufpos = param->utf_payload; 1655 total_bytes = param->len; 1656 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1657 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1658 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1659 1660 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1661 numSegments++; 1662 1663 while (param->len) { 1664 if (param->len > MAX_WMI_UTF_LEN) 1665 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1666 else 1667 chunk_len = param->len; 1668 1669 buf = wmi_buf_alloc(wmi_handle, 1670 (chunk_len + sizeof(segHdrInfo) + 1671 WMI_TLV_HDR_SIZE)); 1672 if (!buf) 1673 return QDF_STATUS_E_NOMEM; 1674 1675 cmd = (uint8_t *) wmi_buf_data(buf); 1676 1677 segHdrInfo.len = total_bytes; 1678 segHdrInfo.msgref = msgref; 1679 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1680 segHdrInfo.segmentInfo = segInfo; 1681 segHdrInfo.pad = 0; 1682 1683 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1684 " segHdrInfo.segmentInfo = %d", 1685 segHdrInfo.len, segHdrInfo.msgref, 1686 segHdrInfo.segmentInfo); 1687 1688 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 1689 " chunk len %d", total_bytes, segNumber, 1690 numSegments, chunk_len); 1691 1692 segNumber++; 1693 1694 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1695 (chunk_len + sizeof(segHdrInfo))); 1696 cmd += WMI_TLV_HDR_SIZE; 1697 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1698 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 1699 bufpos, chunk_len); 1700 1701 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1702 ret = wmi_unified_cmd_send(wmi_handle, buf, 1703 (chunk_len + sizeof(segHdrInfo) + 1704 WMI_TLV_HDR_SIZE), 1705 WMI_PDEV_UTF_CMDID); 1706 1707 if (QDF_IS_STATUS_ERROR(ret)) { 1708 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 1709 wmi_buf_free(buf); 1710 break; 1711 } 1712 1713 param->len -= chunk_len; 1714 bufpos += chunk_len; 1715 } 1716 1717 msgref++; 1718 1719 return ret; 1720 } 1721 1722 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1723 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1724 { 1725 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1726 return pdev_param_tlv[host_param]; 1727 return WMI_UNAVAILABLE_PARAM; 1728 } 1729 #else 1730 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1731 { 1732 return host_param; 1733 } 1734 #endif 1735 1736 /** 1737 * send_pdev_param_cmd_tlv() - set pdev parameters 1738 * @wmi_handle: wmi handle 1739 * @param: pointer to pdev parameter 1740 * @mac_id: radio context 1741 * 1742 * Return: 0 on success, errno on failure 1743 */ 1744 static QDF_STATUS 1745 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1746 struct pdev_params *param, 1747 uint8_t mac_id) 1748 { 1749 QDF_STATUS ret; 1750 wmi_pdev_set_param_cmd_fixed_param *cmd; 1751 wmi_buf_t buf; 1752 uint16_t len = sizeof(*cmd); 1753 uint32_t pdev_param; 1754 1755 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1756 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1757 wmi_err("Unavailable param %d", param->param_id); 1758 return QDF_STATUS_E_INVAL; 1759 } 1760 1761 buf = wmi_buf_alloc(wmi_handle, len); 1762 if (!buf) 1763 return QDF_STATUS_E_NOMEM; 1764 1765 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1766 WMITLV_SET_HDR(&cmd->tlv_header, 1767 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1768 WMITLV_GET_STRUCT_TLVLEN 1769 (wmi_pdev_set_param_cmd_fixed_param)); 1770 if (param->is_host_pdev_id) 1771 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1772 wmi_handle, 1773 mac_id); 1774 else 1775 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1776 wmi_handle, 1777 mac_id); 1778 cmd->param_id = pdev_param; 1779 cmd->param_value = param->param_value; 1780 wmi_debug("Setting pdev param = %x, value = %u", param->param_id, 1781 param->param_value); 1782 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1783 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1784 WMI_PDEV_SET_PARAM_CMDID); 1785 if (QDF_IS_STATUS_ERROR(ret)) { 1786 wmi_err("Failed to send set param command ret = %d", ret); 1787 wmi_buf_free(buf); 1788 } 1789 return ret; 1790 } 1791 1792 /** 1793 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1794 * @wmi_handle: wmi handle 1795 * @msg: Structure containing the following parameters 1796 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1797 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 1798 * 1799 * Provides notification to the WLAN firmware that host driver is requesting a 1800 * HardWare (HW) Mode change. This command is needed to support iHelium in the 1801 * configurations that include the Dual Band Simultaneous (DBS) feature. 1802 * 1803 * Return: Success if the cmd is sent successfully to the firmware 1804 */ 1805 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 1806 uint32_t hw_mode_index) 1807 { 1808 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 1809 wmi_buf_t buf; 1810 uint32_t len; 1811 1812 len = sizeof(*cmd); 1813 1814 buf = wmi_buf_alloc(wmi_handle, len); 1815 if (!buf) 1816 return QDF_STATUS_E_NOMEM; 1817 1818 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 1819 WMITLV_SET_HDR(&cmd->tlv_header, 1820 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 1821 WMITLV_GET_STRUCT_TLVLEN( 1822 wmi_pdev_set_hw_mode_cmd_fixed_param)); 1823 1824 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1825 wmi_handle, 1826 WMI_HOST_PDEV_ID_SOC); 1827 cmd->hw_mode_index = hw_mode_index; 1828 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 1829 1830 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 1831 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1832 WMI_PDEV_SET_HW_MODE_CMDID)) { 1833 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 1834 wmi_buf_free(buf); 1835 return QDF_STATUS_E_FAILURE; 1836 } 1837 1838 return QDF_STATUS_SUCCESS; 1839 } 1840 1841 /** 1842 * send_suspend_cmd_tlv() - WMI suspend function 1843 * @param wmi_handle : handle to WMI. 1844 * @param param : pointer to hold suspend parameter 1845 * @mac_id: radio context 1846 * 1847 * Return 0 on success and -ve on failure. 1848 */ 1849 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1850 struct suspend_params *param, 1851 uint8_t mac_id) 1852 { 1853 wmi_pdev_suspend_cmd_fixed_param *cmd; 1854 wmi_buf_t wmibuf; 1855 uint32_t len = sizeof(*cmd); 1856 int32_t ret; 1857 1858 /* 1859 * send the command to Target to ignore the 1860 * PCIE reset so as to ensure that Host and target 1861 * states are in sync 1862 */ 1863 wmibuf = wmi_buf_alloc(wmi_handle, len); 1864 if (!wmibuf) 1865 return QDF_STATUS_E_NOMEM; 1866 1867 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1868 WMITLV_SET_HDR(&cmd->tlv_header, 1869 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1870 WMITLV_GET_STRUCT_TLVLEN 1871 (wmi_pdev_suspend_cmd_fixed_param)); 1872 if (param->disable_target_intr) 1873 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1874 else 1875 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1876 1877 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1878 wmi_handle, 1879 mac_id); 1880 1881 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1882 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1883 WMI_PDEV_SUSPEND_CMDID); 1884 if (ret) { 1885 wmi_buf_free(wmibuf); 1886 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1887 } 1888 1889 return ret; 1890 } 1891 1892 /** 1893 * send_resume_cmd_tlv() - WMI resume function 1894 * @param wmi_handle : handle to WMI. 1895 * @mac_id: radio context 1896 * 1897 * Return: 0 on success and -ve on failure. 1898 */ 1899 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1900 uint8_t mac_id) 1901 { 1902 wmi_buf_t wmibuf; 1903 wmi_pdev_resume_cmd_fixed_param *cmd; 1904 QDF_STATUS ret; 1905 1906 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1907 if (!wmibuf) 1908 return QDF_STATUS_E_NOMEM; 1909 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1910 WMITLV_SET_HDR(&cmd->tlv_header, 1911 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1912 WMITLV_GET_STRUCT_TLVLEN 1913 (wmi_pdev_resume_cmd_fixed_param)); 1914 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1915 wmi_handle, 1916 mac_id); 1917 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1918 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1919 WMI_PDEV_RESUME_CMDID); 1920 if (QDF_IS_STATUS_ERROR(ret)) { 1921 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 1922 wmi_buf_free(wmibuf); 1923 } 1924 1925 return ret; 1926 } 1927 1928 /** 1929 * send_wow_enable_cmd_tlv() - WMI wow enable function 1930 * @param wmi_handle : handle to WMI. 1931 * @param param : pointer to hold wow enable parameter 1932 * @mac_id: radio context 1933 * 1934 * Return: 0 on success and -ve on failure. 1935 */ 1936 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1937 struct wow_cmd_params *param, 1938 uint8_t mac_id) 1939 { 1940 wmi_wow_enable_cmd_fixed_param *cmd; 1941 wmi_buf_t buf; 1942 int32_t len; 1943 int32_t ret; 1944 1945 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1946 1947 buf = wmi_buf_alloc(wmi_handle, len); 1948 if (!buf) 1949 return QDF_STATUS_E_NOMEM; 1950 1951 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1952 WMITLV_SET_HDR(&cmd->tlv_header, 1953 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1954 WMITLV_GET_STRUCT_TLVLEN 1955 (wmi_wow_enable_cmd_fixed_param)); 1956 cmd->enable = param->enable; 1957 if (param->can_suspend_link) 1958 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1959 else 1960 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1961 cmd->flags = param->flags; 1962 1963 wmi_info("suspend type: %s flag is 0x%x", 1964 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1965 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 1966 cmd->flags); 1967 1968 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1969 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1970 WMI_WOW_ENABLE_CMDID); 1971 if (ret) 1972 wmi_buf_free(buf); 1973 1974 return ret; 1975 } 1976 1977 /** 1978 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1979 * @wmi_handle: wmi handle 1980 * @peer_addr: peer mac address 1981 * @param: pointer to ap_ps parameter structure 1982 * 1983 * Return: QDF_STATUS_SUCCESS for success or error code 1984 */ 1985 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1986 uint8_t *peer_addr, 1987 struct ap_ps_params *param) 1988 { 1989 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1990 wmi_buf_t buf; 1991 int32_t err; 1992 1993 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1994 if (!buf) 1995 return QDF_STATUS_E_NOMEM; 1996 1997 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1998 WMITLV_SET_HDR(&cmd->tlv_header, 1999 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2000 WMITLV_GET_STRUCT_TLVLEN 2001 (wmi_ap_ps_peer_cmd_fixed_param)); 2002 cmd->vdev_id = param->vdev_id; 2003 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2004 cmd->param = param->param; 2005 cmd->value = param->value; 2006 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2007 err = wmi_unified_cmd_send(wmi_handle, buf, 2008 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2009 if (err) { 2010 wmi_err("Failed to send set_ap_ps_param cmd"); 2011 wmi_buf_free(buf); 2012 return QDF_STATUS_E_FAILURE; 2013 } 2014 2015 return 0; 2016 } 2017 2018 /** 2019 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2020 * @wmi_handle: wmi handle 2021 * @peer_addr: peer mac address 2022 * @param: pointer to sta_ps parameter structure 2023 * 2024 * Return: QDF_STATUS_SUCCESS for success or error code 2025 */ 2026 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2027 struct sta_ps_params *param) 2028 { 2029 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2030 wmi_buf_t buf; 2031 int32_t len = sizeof(*cmd); 2032 2033 buf = wmi_buf_alloc(wmi_handle, len); 2034 if (!buf) 2035 return QDF_STATUS_E_NOMEM; 2036 2037 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2038 WMITLV_SET_HDR(&cmd->tlv_header, 2039 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2040 WMITLV_GET_STRUCT_TLVLEN 2041 (wmi_sta_powersave_param_cmd_fixed_param)); 2042 cmd->vdev_id = param->vdev_id; 2043 cmd->param = param->param_id; 2044 cmd->value = param->value; 2045 2046 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2047 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2048 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2049 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2050 param->vdev_id, param->param_id, param->value); 2051 wmi_buf_free(buf); 2052 return QDF_STATUS_E_FAILURE; 2053 } 2054 2055 return 0; 2056 } 2057 2058 /** 2059 * send_crash_inject_cmd_tlv() - inject fw crash 2060 * @wmi_handle: wmi handle 2061 * @param: ponirt to crash inject parameter structure 2062 * 2063 * Return: QDF_STATUS_SUCCESS for success or return error 2064 */ 2065 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2066 struct crash_inject *param) 2067 { 2068 int32_t ret = 0; 2069 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2070 uint16_t len = sizeof(*cmd); 2071 wmi_buf_t buf; 2072 2073 buf = wmi_buf_alloc(wmi_handle, len); 2074 if (!buf) 2075 return QDF_STATUS_E_NOMEM; 2076 2077 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2078 WMITLV_SET_HDR(&cmd->tlv_header, 2079 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2080 WMITLV_GET_STRUCT_TLVLEN 2081 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2082 cmd->type = param->type; 2083 cmd->delay_time_ms = param->delay_time_ms; 2084 2085 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2086 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2087 WMI_FORCE_FW_HANG_CMDID); 2088 if (ret) { 2089 wmi_err("Failed to send set param command, ret = %d", ret); 2090 wmi_buf_free(buf); 2091 } 2092 2093 return ret; 2094 } 2095 2096 /** 2097 * send_dbglog_cmd_tlv() - set debug log level 2098 * @param wmi_handle : handle to WMI. 2099 * @param param : pointer to hold dbglog level parameter 2100 * 2101 * Return: 0 on success and -ve on failure. 2102 */ 2103 static QDF_STATUS 2104 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2105 struct dbglog_params *dbglog_param) 2106 { 2107 wmi_buf_t buf; 2108 wmi_debug_log_config_cmd_fixed_param *configmsg; 2109 QDF_STATUS status; 2110 int32_t i; 2111 int32_t len; 2112 int8_t *buf_ptr; 2113 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2114 2115 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2116 2117 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2118 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2119 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2120 buf = wmi_buf_alloc(wmi_handle, len); 2121 if (!buf) 2122 return QDF_STATUS_E_NOMEM; 2123 2124 configmsg = 2125 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2126 buf_ptr = (int8_t *) configmsg; 2127 WMITLV_SET_HDR(&configmsg->tlv_header, 2128 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2129 WMITLV_GET_STRUCT_TLVLEN 2130 (wmi_debug_log_config_cmd_fixed_param)); 2131 configmsg->dbg_log_param = dbglog_param->param; 2132 configmsg->value = dbglog_param->val; 2133 /* Filling in the data part of second tlv -- should 2134 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2135 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2136 sizeof 2137 (wmi_debug_log_config_cmd_fixed_param) 2138 + WMI_TLV_HDR_SIZE); 2139 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2140 WMITLV_TAG_ARRAY_UINT32, 2141 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2142 if (dbglog_param->module_id_bitmap) { 2143 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2144 module_id_bitmap_array[i] = 2145 dbglog_param->module_id_bitmap[i]; 2146 } 2147 } 2148 2149 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2150 status = wmi_unified_cmd_send(wmi_handle, buf, 2151 len, WMI_DBGLOG_CFG_CMDID); 2152 2153 if (status != QDF_STATUS_SUCCESS) 2154 wmi_buf_free(buf); 2155 2156 return status; 2157 } 2158 2159 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2160 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2161 { 2162 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2163 return vdev_param_tlv[host_param]; 2164 return WMI_UNAVAILABLE_PARAM; 2165 } 2166 #else 2167 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2168 { 2169 return host_param; 2170 } 2171 #endif 2172 2173 /** 2174 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2175 * @param wmi_handle : handle to WMI. 2176 * @param macaddr : MAC address 2177 * @param param : pointer to hold vdev set parameter 2178 * 2179 * Return: 0 on success and -ve on failure. 2180 */ 2181 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2182 struct vdev_set_params *param) 2183 { 2184 QDF_STATUS ret; 2185 wmi_vdev_set_param_cmd_fixed_param *cmd; 2186 wmi_buf_t buf; 2187 uint16_t len = sizeof(*cmd); 2188 uint32_t vdev_param; 2189 2190 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2191 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2192 wmi_err("Vdev param %d not available", param->param_id); 2193 return QDF_STATUS_E_INVAL; 2194 2195 } 2196 2197 buf = wmi_buf_alloc(wmi_handle, len); 2198 if (!buf) 2199 return QDF_STATUS_E_NOMEM; 2200 2201 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2202 WMITLV_SET_HDR(&cmd->tlv_header, 2203 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2204 WMITLV_GET_STRUCT_TLVLEN 2205 (wmi_vdev_set_param_cmd_fixed_param)); 2206 cmd->vdev_id = param->vdev_id; 2207 cmd->param_id = vdev_param; 2208 cmd->param_value = param->param_value; 2209 wmi_debug("Setting vdev %d param = %x, value = %u", 2210 cmd->vdev_id, cmd->param_id, cmd->param_value); 2211 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2212 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2213 WMI_VDEV_SET_PARAM_CMDID); 2214 if (QDF_IS_STATUS_ERROR(ret)) { 2215 wmi_err("Failed to send set param command ret = %d", ret); 2216 wmi_buf_free(buf); 2217 } 2218 2219 return ret; 2220 } 2221 2222 /** 2223 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2224 * @param wmi_handle : handle to WMI. 2225 * @param param : pointer to hold mu sniffer parameter 2226 * 2227 * Return: 0 on success and -ve on failure. 2228 */ 2229 static 2230 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2231 struct vdev_set_mu_snif_param *param) 2232 { 2233 QDF_STATUS ret; 2234 wmi_vdev_set_mu_snif_cmd_param *cmd; 2235 wmi_buf_t buf; 2236 uint32_t *tmp_ptr; 2237 uint16_t len = sizeof(*cmd); 2238 uint8_t *buf_ptr; 2239 uint32_t i; 2240 2241 /* Length TLV placeholder for array of uint32_t */ 2242 len += WMI_TLV_HDR_SIZE; 2243 2244 if (param->num_aid) 2245 len += param->num_aid * sizeof(uint32_t); 2246 2247 buf = wmi_buf_alloc(wmi_handle, len); 2248 if (!buf) 2249 return QDF_STATUS_E_NOMEM; 2250 2251 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2252 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2253 2254 WMITLV_SET_HDR(&cmd->tlv_header, 2255 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2256 WMITLV_GET_STRUCT_TLVLEN 2257 (wmi_vdev_set_mu_snif_cmd_param)); 2258 2259 cmd->vdev_id = param->vdev_id; 2260 cmd->mode = param->mode; 2261 cmd->max_num_user = param->num_user; 2262 2263 buf_ptr += sizeof(*cmd); 2264 2265 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2266 2267 for (i = 0; i < param->num_aid; ++i) 2268 tmp_ptr[i] = param->aid[i]; 2269 2270 WMITLV_SET_HDR(buf_ptr, 2271 WMITLV_TAG_ARRAY_UINT32, 2272 (param->num_aid * sizeof(uint32_t))); 2273 2274 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2275 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2276 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2277 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2278 WMI_VDEV_SET_MU_SNIF_CMDID); 2279 if (QDF_IS_STATUS_ERROR(ret)) { 2280 wmi_err("Failed to send set param command ret = %d", ret); 2281 wmi_buf_free(buf); 2282 } 2283 2284 return ret; 2285 } 2286 2287 /** 2288 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2289 * @wmi_handle: handle to WMI. 2290 * @macaddr: Peer mac address to be filter 2291 * @mac_id: mac id to have radio context 2292 * @enb_dsb: Enable MAC based filtering or Disable 2293 * 2294 * Return: QDF_STATUS 2295 */ 2296 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2297 uint8_t *macaddr, 2298 uint8_t mac_id, 2299 uint8_t enb_dsb) 2300 { 2301 int32_t ret; 2302 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2303 wmi_pdev_pktlog_filter_info *mac_info; 2304 wmi_buf_t buf; 2305 uint8_t *buf_ptr; 2306 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2307 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2308 2309 buf = wmi_buf_alloc(wmi_handle, len); 2310 if (!buf) 2311 return QDF_STATUS_E_NOMEM; 2312 2313 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2314 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2315 WMITLV_SET_HDR(&cmd->tlv_header, 2316 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2317 WMITLV_GET_STRUCT_TLVLEN 2318 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2319 cmd->pdev_id = mac_id; 2320 cmd->enable = enb_dsb; 2321 cmd->num_of_mac_addresses = 1; 2322 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2323 2324 buf_ptr += sizeof(*cmd); 2325 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2326 sizeof(wmi_pdev_pktlog_filter_info)); 2327 buf_ptr += WMI_TLV_HDR_SIZE; 2328 2329 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2330 2331 WMITLV_SET_HDR(&mac_info->tlv_header, 2332 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2333 WMITLV_GET_STRUCT_TLVLEN 2334 (wmi_pdev_pktlog_filter_info)); 2335 2336 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2337 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2338 WMI_PDEV_PKTLOG_FILTER_CMDID); 2339 if (ret) { 2340 wmi_err("Failed to send peer based pktlog command to FW =%d" 2341 , ret); 2342 wmi_buf_free(buf); 2343 } 2344 2345 return ret; 2346 } 2347 2348 /** 2349 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2350 * @param wmi_handle : handle to WMI. 2351 * @param PKTLOG_EVENT : packet log event 2352 * @mac_id: mac id to have radio context 2353 * 2354 * Return: 0 on success and -ve on failure. 2355 */ 2356 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2357 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2358 { 2359 int32_t ret, idx, max_idx; 2360 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2361 wmi_buf_t buf; 2362 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2363 2364 buf = wmi_buf_alloc(wmi_handle, len); 2365 if (!buf) 2366 return -QDF_STATUS_E_NOMEM; 2367 2368 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2369 WMITLV_SET_HDR(&cmd->tlv_header, 2370 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2371 WMITLV_GET_STRUCT_TLVLEN 2372 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2373 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2374 cmd->evlist = 0; 2375 for (idx = 0; idx < max_idx; idx++) { 2376 if (PKTLOG_EVENT & (1 << idx)) 2377 cmd->evlist |= pktlog_event_tlv[idx]; 2378 } 2379 cmd->pdev_id = mac_id; 2380 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2381 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2382 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2383 if (ret) { 2384 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2385 wmi_buf_free(buf); 2386 } 2387 2388 return ret; 2389 } 2390 2391 /** 2392 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2393 * @param wmi_handle : handle to WMI. 2394 * @mac_id: mac id to have radio context 2395 * 2396 * Return: 0 on success and -ve on failure. 2397 */ 2398 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2399 uint8_t mac_id) 2400 { 2401 int32_t ret; 2402 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2403 wmi_buf_t buf; 2404 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2405 2406 buf = wmi_buf_alloc(wmi_handle, len); 2407 if (!buf) 2408 return -QDF_STATUS_E_NOMEM; 2409 2410 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2411 WMITLV_SET_HDR(&cmd->tlv_header, 2412 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2413 WMITLV_GET_STRUCT_TLVLEN 2414 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2415 cmd->pdev_id = mac_id; 2416 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2417 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2418 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2419 if (ret) { 2420 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 2421 wmi_buf_free(buf); 2422 } 2423 2424 return ret; 2425 } 2426 2427 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2428 /** 2429 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2430 * sync time between bwtween host and firmware 2431 * @param wmi_handle : handle to WMI. 2432 * 2433 * Return: None 2434 */ 2435 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2436 { 2437 wmi_buf_t buf; 2438 QDF_STATUS status = QDF_STATUS_SUCCESS; 2439 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2440 int32_t len; 2441 qdf_time_t time_ms; 2442 2443 len = sizeof(*time_stamp); 2444 buf = wmi_buf_alloc(wmi_handle, len); 2445 2446 if (!buf) 2447 return; 2448 2449 time_stamp = 2450 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2451 (wmi_buf_data(buf)); 2452 WMITLV_SET_HDR(&time_stamp->tlv_header, 2453 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2454 WMITLV_GET_STRUCT_TLVLEN( 2455 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2456 2457 time_ms = qdf_get_time_of_the_day_ms(); 2458 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2459 time_stamp->time_stamp_low = time_ms & 2460 WMI_FW_TIME_STAMP_LOW_MASK; 2461 /* 2462 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2463 * wont exceed 27 bit 2464 */ 2465 time_stamp->time_stamp_high = 0; 2466 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 2467 time_stamp->mode, time_stamp->time_stamp_low, 2468 time_stamp->time_stamp_high); 2469 2470 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2471 status = wmi_unified_cmd_send(wmi_handle, buf, 2472 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2473 if (status) { 2474 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2475 wmi_buf_free(buf); 2476 } 2477 2478 } 2479 2480 /** 2481 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2482 * @param wmi_handle : handle to WMI. 2483 * @param param : pointer to hold FILS Discovery send cmd parameter 2484 * 2485 * Return: 0 on success and -ve on failure. 2486 */ 2487 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2488 struct fils_discovery_tmpl_params *param) 2489 { 2490 int32_t ret; 2491 wmi_fd_tmpl_cmd_fixed_param *cmd; 2492 wmi_buf_t wmi_buf; 2493 uint8_t *buf_ptr; 2494 uint32_t wmi_buf_len; 2495 2496 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2497 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2498 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2499 if (!wmi_buf) 2500 return QDF_STATUS_E_NOMEM; 2501 2502 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2503 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2504 WMITLV_SET_HDR(&cmd->tlv_header, 2505 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2506 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2507 cmd->vdev_id = param->vdev_id; 2508 cmd->buf_len = param->tmpl_len; 2509 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2510 2511 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2512 buf_ptr += WMI_TLV_HDR_SIZE; 2513 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2514 2515 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2516 ret = wmi_unified_cmd_send(wmi_handle, 2517 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2518 2519 if (ret) { 2520 wmi_err("Failed to send fd tmpl: %d", ret); 2521 wmi_buf_free(wmi_buf); 2522 return ret; 2523 } 2524 2525 return 0; 2526 } 2527 2528 /** 2529 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2530 * @param wmi_handle : handle to WMI. 2531 * @param param : pointer to hold beacon send cmd parameter 2532 * 2533 * Return: 0 on success and -ve on failure. 2534 */ 2535 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2536 struct beacon_tmpl_params *param) 2537 { 2538 int32_t ret; 2539 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2540 wmi_bcn_prb_info *bcn_prb_info; 2541 wmi_buf_t wmi_buf; 2542 uint8_t *buf_ptr; 2543 uint32_t wmi_buf_len; 2544 2545 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2546 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2547 param->tmpl_len_aligned; 2548 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2549 if (!wmi_buf) 2550 return QDF_STATUS_E_NOMEM; 2551 2552 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2553 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2554 WMITLV_SET_HDR(&cmd->tlv_header, 2555 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2556 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2557 cmd->vdev_id = param->vdev_id; 2558 cmd->tim_ie_offset = param->tim_ie_offset; 2559 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2560 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2561 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2562 cmd->esp_ie_offset = param->esp_ie_offset; 2563 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2564 cmd->ema_params = param->ema_params; 2565 cmd->buf_len = param->tmpl_len; 2566 cmd->csa_event_bitmap = param->csa_event_bitmap; 2567 2568 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2569 param->enable_bigtk); 2570 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2571 2572 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2573 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2574 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2575 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2576 bcn_prb_info->caps = 0; 2577 bcn_prb_info->erp = 0; 2578 buf_ptr += sizeof(wmi_bcn_prb_info); 2579 2580 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2581 buf_ptr += WMI_TLV_HDR_SIZE; 2582 2583 /* for big endian host, copy engine byte_swap is enabled 2584 * But the frame content is in network byte order 2585 * Need to byte swap the frame content - so when copy engine 2586 * does byte_swap - target gets frame content in the correct order 2587 */ 2588 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 2589 param->tmpl_len); 2590 2591 buf_ptr += param->tmpl_len; 2592 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 2593 2594 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2595 ret = wmi_unified_cmd_send(wmi_handle, 2596 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2597 if (ret) { 2598 wmi_err("Failed to send bcn tmpl: %d", ret); 2599 wmi_buf_free(wmi_buf); 2600 } 2601 2602 return 0; 2603 } 2604 2605 #ifdef WLAN_FEATURE_11BE 2606 static inline void copy_peer_flags_tlv_11be( 2607 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2608 struct peer_assoc_params *param) 2609 { 2610 if (param->bw_320) 2611 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 2612 if (param->eht_flag) 2613 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 2614 2615 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 2616 } 2617 #else 2618 static inline void copy_peer_flags_tlv_11be( 2619 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2620 struct peer_assoc_params *param) 2621 { 2622 } 2623 #endif 2624 2625 static inline void copy_peer_flags_tlv( 2626 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2627 struct peer_assoc_params *param) 2628 { 2629 /* 2630 * The target only needs a subset of the flags maintained in the host. 2631 * Just populate those flags and send it down 2632 */ 2633 cmd->peer_flags = 0; 2634 if (param->peer_dms_capable) 2635 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 2636 /* 2637 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2638 */ 2639 if (param->is_wme_set) { 2640 2641 if (param->qos_flag) 2642 cmd->peer_flags |= WMI_PEER_QOS; 2643 if (param->apsd_flag) 2644 cmd->peer_flags |= WMI_PEER_APSD; 2645 if (param->ht_flag) 2646 cmd->peer_flags |= WMI_PEER_HT; 2647 if (param->bw_40) 2648 cmd->peer_flags |= WMI_PEER_40MHZ; 2649 if (param->bw_80) 2650 cmd->peer_flags |= WMI_PEER_80MHZ; 2651 if (param->bw_160) 2652 cmd->peer_flags |= WMI_PEER_160MHZ; 2653 2654 copy_peer_flags_tlv_11be(cmd, param); 2655 2656 /* Typically if STBC is enabled for VHT it should be enabled 2657 * for HT as well 2658 **/ 2659 if (param->stbc_flag) 2660 cmd->peer_flags |= WMI_PEER_STBC; 2661 2662 /* Typically if LDPC is enabled for VHT it should be enabled 2663 * for HT as well 2664 **/ 2665 if (param->ldpc_flag) 2666 cmd->peer_flags |= WMI_PEER_LDPC; 2667 2668 if (param->static_mimops_flag) 2669 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2670 if (param->dynamic_mimops_flag) 2671 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2672 if (param->spatial_mux_flag) 2673 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2674 if (param->vht_flag) 2675 cmd->peer_flags |= WMI_PEER_VHT; 2676 if (param->he_flag) 2677 cmd->peer_flags |= WMI_PEER_HE; 2678 if (param->p2p_capable_sta) 2679 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2680 } 2681 2682 if (param->is_pmf_enabled) 2683 cmd->peer_flags |= WMI_PEER_PMF; 2684 /* 2685 * Suppress authorization for all AUTH modes that need 4-way handshake 2686 * (during re-association). 2687 * Authorization will be done for these modes on key installation. 2688 */ 2689 if (param->auth_flag) 2690 cmd->peer_flags |= WMI_PEER_AUTH; 2691 if (param->need_ptk_4_way) 2692 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2693 else 2694 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2695 if (param->need_gtk_2_way) 2696 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2697 /* safe mode bypass the 4-way handshake */ 2698 if (param->safe_mode_enabled) 2699 cmd->peer_flags &= 2700 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2701 /* inter BSS peer */ 2702 if (param->inter_bss_peer) 2703 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2704 /* Disable AMSDU for station transmit, if user configures it */ 2705 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2706 * it 2707 * if (param->amsdu_disable) Add after FW support 2708 **/ 2709 2710 /* Target asserts if node is marked HT and all MCS is set to 0. 2711 * Mark the node as non-HT if all the mcs rates are disabled through 2712 * iwpriv 2713 **/ 2714 if (param->peer_ht_rates.num_rates == 0) 2715 cmd->peer_flags &= ~WMI_PEER_HT; 2716 2717 if (param->twt_requester) 2718 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2719 2720 if (param->twt_responder) 2721 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2722 } 2723 2724 static inline void copy_peer_mac_addr_tlv( 2725 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2726 struct peer_assoc_params *param) 2727 { 2728 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2729 } 2730 2731 #ifdef WLAN_FEATURE_11BE 2732 static uint8_t *update_peer_flags_tlv_ehtinfo( 2733 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2734 struct peer_assoc_params *param, uint8_t *buf_ptr) 2735 { 2736 wmi_eht_rate_set *eht_mcs; 2737 int i; 2738 2739 cmd->peer_eht_ops = param->peer_eht_ops; 2740 cmd->puncture_20mhz_bitmap = param->puncture_pattern; 2741 2742 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 2743 sizeof(param->peer_eht_cap_macinfo)); 2744 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 2745 sizeof(param->peer_eht_cap_phyinfo)); 2746 2747 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2748 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 2749 buf_ptr += WMI_TLV_HDR_SIZE; 2750 2751 /* Loop through the EHT rate set */ 2752 for (i = 0; i < param->peer_eht_mcs_count; i++) { 2753 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 2754 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 2755 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 2756 2757 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 2758 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 2759 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 2760 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 2761 buf_ptr += sizeof(wmi_eht_rate_set); 2762 } 2763 2764 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 2765 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2766 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 2767 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2768 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2769 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 2770 param->peer_eht_tx_mcs_set 2771 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2772 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 2773 param->peer_eht_rx_mcs_set 2774 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2775 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2776 QDF_MAC_ADDR_REF(param->peer_mac)); 2777 } 2778 2779 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 2780 cmd->peer_eht_cap_mac[0], 2781 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 2782 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 2783 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 2784 2785 return buf_ptr; 2786 } 2787 #else 2788 static uint8_t *update_peer_flags_tlv_ehtinfo( 2789 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2790 struct peer_assoc_params *param, uint8_t *buf_ptr) 2791 { 2792 return buf_ptr; 2793 } 2794 #endif 2795 2796 #ifdef WLAN_FEATURE_11BE 2797 static 2798 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 2799 { 2800 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 2801 + WMI_TLV_HDR_SIZE); 2802 } 2803 2804 static void wmi_populate_service_11be(uint32_t *wmi_service) 2805 { 2806 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 2807 } 2808 2809 #else 2810 static 2811 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 2812 { 2813 return 0; 2814 } 2815 2816 static void wmi_populate_service_11be(uint32_t *wmi_service) 2817 { 2818 } 2819 2820 #endif 2821 2822 /** 2823 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2824 * @param wmi_handle : handle to WMI. 2825 * @param param : pointer to peer assoc parameter 2826 * 2827 * Return: 0 on success and -ve on failure. 2828 */ 2829 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2830 struct peer_assoc_params *param) 2831 { 2832 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2833 wmi_vht_rate_set *mcs; 2834 wmi_he_rate_set *he_mcs; 2835 wmi_buf_t buf; 2836 int32_t len; 2837 uint8_t *buf_ptr; 2838 QDF_STATUS ret; 2839 uint32_t peer_legacy_rates_align; 2840 uint32_t peer_ht_rates_align; 2841 int32_t i; 2842 2843 2844 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2845 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2846 2847 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2848 (peer_legacy_rates_align * sizeof(uint8_t)) + 2849 WMI_TLV_HDR_SIZE + 2850 (peer_ht_rates_align * sizeof(uint8_t)) + 2851 sizeof(wmi_vht_rate_set) + 2852 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2853 + WMI_TLV_HDR_SIZE) 2854 + wmi_eht_peer_assoc_params_len(param) + 2855 peer_assoc_mlo_params_size(param); 2856 2857 buf = wmi_buf_alloc(wmi_handle, len); 2858 if (!buf) 2859 return QDF_STATUS_E_NOMEM; 2860 2861 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2862 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2863 WMITLV_SET_HDR(&cmd->tlv_header, 2864 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2865 WMITLV_GET_STRUCT_TLVLEN 2866 (wmi_peer_assoc_complete_cmd_fixed_param)); 2867 2868 cmd->vdev_id = param->vdev_id; 2869 2870 cmd->peer_new_assoc = param->peer_new_assoc; 2871 cmd->peer_associd = param->peer_associd; 2872 2873 copy_peer_flags_tlv(cmd, param); 2874 copy_peer_mac_addr_tlv(cmd, param); 2875 2876 cmd->peer_rate_caps = param->peer_rate_caps; 2877 cmd->peer_caps = param->peer_caps; 2878 cmd->peer_listen_intval = param->peer_listen_intval; 2879 cmd->peer_ht_caps = param->peer_ht_caps; 2880 cmd->peer_max_mpdu = param->peer_max_mpdu; 2881 cmd->peer_mpdu_density = param->peer_mpdu_density; 2882 cmd->peer_vht_caps = param->peer_vht_caps; 2883 cmd->peer_phymode = param->peer_phymode; 2884 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 2885 2886 /* Update 11ax capabilities */ 2887 cmd->peer_he_cap_info = 2888 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2889 cmd->peer_he_cap_info_ext = 2890 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2891 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 2892 cmd->peer_he_ops = param->peer_he_ops; 2893 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2894 sizeof(param->peer_he_cap_phyinfo)); 2895 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2896 sizeof(param->peer_ppet)); 2897 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 2898 2899 /* Update peer legacy rate information */ 2900 buf_ptr += sizeof(*cmd); 2901 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2902 peer_legacy_rates_align); 2903 buf_ptr += WMI_TLV_HDR_SIZE; 2904 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2905 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2906 param->peer_legacy_rates.num_rates); 2907 2908 /* Update peer HT rate information */ 2909 buf_ptr += peer_legacy_rates_align; 2910 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2911 peer_ht_rates_align); 2912 buf_ptr += WMI_TLV_HDR_SIZE; 2913 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2914 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2915 param->peer_ht_rates.num_rates); 2916 2917 /* VHT Rates */ 2918 buf_ptr += peer_ht_rates_align; 2919 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2920 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2921 2922 cmd->auth_mode = param->akm; 2923 cmd->peer_nss = param->peer_nss; 2924 2925 /* Update bandwidth-NSS mapping */ 2926 cmd->peer_bw_rxnss_override = 0; 2927 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2928 2929 mcs = (wmi_vht_rate_set *) buf_ptr; 2930 if (param->vht_capable) { 2931 mcs->rx_max_rate = param->rx_max_rate; 2932 mcs->rx_mcs_set = param->rx_mcs_set; 2933 mcs->tx_max_rate = param->tx_max_rate; 2934 mcs->tx_mcs_set = param->tx_mcs_set; 2935 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 2936 } 2937 2938 /* HE Rates */ 2939 cmd->min_data_rate = param->min_data_rate; 2940 cmd->peer_he_mcs = param->peer_he_mcs_count; 2941 buf_ptr += sizeof(wmi_vht_rate_set); 2942 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2943 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2944 buf_ptr += WMI_TLV_HDR_SIZE; 2945 2946 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 2947 /* Loop through the HE rate set */ 2948 for (i = 0; i < param->peer_he_mcs_count; i++) { 2949 he_mcs = (wmi_he_rate_set *) buf_ptr; 2950 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2951 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2952 2953 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2954 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2955 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 2956 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2957 buf_ptr += sizeof(wmi_he_rate_set); 2958 } 2959 2960 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 2961 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2962 == WMI_HOST_HE_INVALID_MCSNSSMAP || 2963 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2964 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2965 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 2966 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2967 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 2968 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2969 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2970 QDF_MAC_ADDR_REF(param->peer_mac)); 2971 } 2972 2973 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 2974 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2975 "nss %d phymode %d peer_mpdu_density %d " 2976 "cmd->peer_vht_caps %x " 2977 "HE cap_info %x ops %x " 2978 "HE cap_info_ext %x " 2979 "HE phy %x %x %x " 2980 "peer_bw_rxnss_override %x", 2981 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2982 cmd->peer_rate_caps, cmd->peer_caps, 2983 cmd->peer_listen_intval, cmd->peer_ht_caps, 2984 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2985 cmd->peer_mpdu_density, 2986 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2987 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2988 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2989 cmd->peer_he_cap_phy[2], 2990 cmd->peer_bw_rxnss_override); 2991 2992 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 2993 2994 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 2995 2996 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 2997 2998 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2999 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3000 WMI_PEER_ASSOC_CMDID); 3001 if (QDF_IS_STATUS_ERROR(ret)) { 3002 wmi_err("Failed to send peer assoc command ret = %d", ret); 3003 wmi_buf_free(buf); 3004 } 3005 3006 return ret; 3007 } 3008 3009 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3010 */ 3011 static inline void copy_scan_event_cntrl_flags( 3012 wmi_start_scan_cmd_fixed_param * cmd, 3013 struct scan_req_params *param) 3014 { 3015 3016 /* Scan events subscription */ 3017 if (param->scan_ev_started) 3018 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3019 if (param->scan_ev_completed) 3020 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3021 if (param->scan_ev_bss_chan) 3022 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3023 if (param->scan_ev_foreign_chan) 3024 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3025 if (param->scan_ev_dequeued) 3026 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3027 if (param->scan_ev_preempted) 3028 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3029 if (param->scan_ev_start_failed) 3030 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3031 if (param->scan_ev_restarted) 3032 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3033 if (param->scan_ev_foreign_chn_exit) 3034 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3035 if (param->scan_ev_suspended) 3036 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3037 if (param->scan_ev_resumed) 3038 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3039 3040 /** Set scan control flags */ 3041 cmd->scan_ctrl_flags = 0; 3042 if (param->scan_f_passive) 3043 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3044 if (param->scan_f_strict_passive_pch) 3045 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3046 if (param->scan_f_promisc_mode) 3047 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3048 if (param->scan_f_capture_phy_err) 3049 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3050 if (param->scan_f_half_rate) 3051 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3052 if (param->scan_f_quarter_rate) 3053 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3054 if (param->scan_f_cck_rates) 3055 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3056 if (param->scan_f_ofdm_rates) 3057 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3058 if (param->scan_f_chan_stat_evnt) 3059 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3060 if (param->scan_f_filter_prb_req) 3061 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3062 if (param->scan_f_bcast_probe) 3063 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3064 if (param->scan_f_offchan_mgmt_tx) 3065 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3066 if (param->scan_f_offchan_data_tx) 3067 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3068 if (param->scan_f_force_active_dfs_chn) 3069 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3070 if (param->scan_f_add_tpc_ie_in_probe) 3071 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3072 if (param->scan_f_add_ds_ie_in_probe) 3073 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3074 if (param->scan_f_add_spoofed_mac_in_probe) 3075 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3076 if (param->scan_f_add_rand_seq_in_probe) 3077 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3078 if (param->scan_f_en_ie_whitelist_in_probe) 3079 cmd->scan_ctrl_flags |= 3080 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3081 3082 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3083 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3084 param->adaptive_dwell_time_mode); 3085 } 3086 3087 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3088 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3089 struct scan_req_params *params) 3090 { 3091 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3092 } 3093 3094 /** 3095 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3096 * @mac: random mac addr 3097 * @mask: random mac mask 3098 * @mac_addr: wmi random mac 3099 * @mac_mask: wmi random mac mask 3100 * 3101 * Return None. 3102 */ 3103 static inline 3104 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3105 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3106 { 3107 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3108 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3109 } 3110 3111 /* 3112 * wmi_fill_vendor_oui() - fill vendor OUIs 3113 * @buf_ptr: pointer to wmi tlv buffer 3114 * @num_vendor_oui: number of vendor OUIs to be filled 3115 * @param_voui: pointer to OUI buffer 3116 * 3117 * This function populates the wmi tlv buffer when vendor specific OUIs are 3118 * present. 3119 * 3120 * Return: None 3121 */ 3122 static inline 3123 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3124 uint32_t *pvoui) 3125 { 3126 wmi_vendor_oui *voui = NULL; 3127 uint32_t i; 3128 3129 voui = (wmi_vendor_oui *)buf_ptr; 3130 3131 for (i = 0; i < num_vendor_oui; i++) { 3132 WMITLV_SET_HDR(&voui[i].tlv_header, 3133 WMITLV_TAG_STRUC_wmi_vendor_oui, 3134 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3135 voui[i].oui_type_subtype = pvoui[i]; 3136 } 3137 } 3138 3139 /* 3140 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 3141 * @ie_bitmap: output pointer to ie bit map in cmd 3142 * @num_vendor_oui: output pointer to num vendor OUIs 3143 * @ie_whitelist: input parameter 3144 * 3145 * This function populates the IE whitelist attrs of scan, pno and 3146 * scan oui commands for ie_whitelist parameter. 3147 * 3148 * Return: None 3149 */ 3150 static inline 3151 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 3152 uint32_t *num_vendor_oui, 3153 struct probe_req_whitelist_attr *ie_whitelist) 3154 { 3155 uint32_t i = 0; 3156 3157 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3158 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 3159 3160 *num_vendor_oui = ie_whitelist->num_vendor_oui; 3161 } 3162 3163 /** 3164 * send_scan_start_cmd_tlv() - WMI scan start function 3165 * @param wmi_handle : handle to WMI. 3166 * @param param : pointer to hold scan start cmd parameter 3167 * 3168 * Return: 0 on success and -ve on failure. 3169 */ 3170 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3171 struct scan_req_params *params) 3172 { 3173 int32_t ret = 0; 3174 int32_t i; 3175 wmi_buf_t wmi_buf; 3176 wmi_start_scan_cmd_fixed_param *cmd; 3177 uint8_t *buf_ptr; 3178 uint32_t *tmp_ptr; 3179 wmi_ssid *ssid = NULL; 3180 wmi_mac_addr *bssid; 3181 size_t len = sizeof(*cmd); 3182 uint16_t extraie_len_with_pad = 0; 3183 uint8_t phymode_roundup = 0; 3184 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 3185 wmi_hint_freq_short_ssid *s_ssid = NULL; 3186 wmi_hint_freq_bssid *hint_bssid = NULL; 3187 3188 /* Length TLV placeholder for array of uint32_t */ 3189 len += WMI_TLV_HDR_SIZE; 3190 /* calculate the length of buffer required */ 3191 if (params->chan_list.num_chan) 3192 len += params->chan_list.num_chan * sizeof(uint32_t); 3193 3194 /* Length TLV placeholder for array of wmi_ssid structures */ 3195 len += WMI_TLV_HDR_SIZE; 3196 if (params->num_ssids) 3197 len += params->num_ssids * sizeof(wmi_ssid); 3198 3199 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3200 len += WMI_TLV_HDR_SIZE; 3201 if (params->num_bssid) 3202 len += sizeof(wmi_mac_addr) * params->num_bssid; 3203 3204 /* Length TLV placeholder for array of bytes */ 3205 len += WMI_TLV_HDR_SIZE; 3206 if (params->extraie.len) 3207 extraie_len_with_pad = 3208 roundup(params->extraie.len, sizeof(uint32_t)); 3209 len += extraie_len_with_pad; 3210 3211 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3212 if (ie_whitelist->num_vendor_oui) 3213 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 3214 3215 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3216 if (params->scan_f_wide_band) 3217 phymode_roundup = 3218 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3219 sizeof(uint32_t)); 3220 len += phymode_roundup; 3221 3222 len += WMI_TLV_HDR_SIZE; 3223 if (params->num_hint_bssid) 3224 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3225 3226 len += WMI_TLV_HDR_SIZE; 3227 if (params->num_hint_s_ssid) 3228 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3229 3230 /* Allocate the memory */ 3231 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3232 if (!wmi_buf) 3233 return QDF_STATUS_E_FAILURE; 3234 3235 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3236 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3237 WMITLV_SET_HDR(&cmd->tlv_header, 3238 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3239 WMITLV_GET_STRUCT_TLVLEN 3240 (wmi_start_scan_cmd_fixed_param)); 3241 3242 cmd->scan_id = params->scan_id; 3243 cmd->scan_req_id = params->scan_req_id; 3244 cmd->vdev_id = params->vdev_id; 3245 cmd->scan_priority = params->scan_priority; 3246 3247 copy_scan_event_cntrl_flags(cmd, params); 3248 3249 cmd->dwell_time_active = params->dwell_time_active; 3250 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3251 cmd->dwell_time_passive = params->dwell_time_passive; 3252 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3253 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3254 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3255 cmd->scan_start_offset = params->scan_offset_time; 3256 cmd->min_rest_time = params->min_rest_time; 3257 cmd->max_rest_time = params->max_rest_time; 3258 cmd->repeat_probe_time = params->repeat_probe_time; 3259 cmd->probe_spacing_time = params->probe_spacing_time; 3260 cmd->idle_time = params->idle_time; 3261 cmd->max_scan_time = params->max_scan_time; 3262 cmd->probe_delay = params->probe_delay; 3263 cmd->burst_duration = params->burst_duration; 3264 cmd->num_chan = params->chan_list.num_chan; 3265 cmd->num_bssid = params->num_bssid; 3266 cmd->num_ssids = params->num_ssids; 3267 cmd->ie_len = params->extraie.len; 3268 cmd->n_probes = params->n_probes; 3269 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3270 3271 if (params->scan_random.randomize) 3272 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3273 params->scan_random.mac_mask, 3274 &cmd->mac_addr, 3275 &cmd->mac_mask); 3276 3277 if (ie_whitelist->white_list) 3278 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 3279 &cmd->num_vendor_oui, 3280 ie_whitelist); 3281 3282 buf_ptr += sizeof(*cmd); 3283 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3284 for (i = 0; i < params->chan_list.num_chan; ++i) { 3285 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 3286 params->chan_list.chan[i].freq); 3287 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3288 params->chan_list.chan[i].flags); 3289 } 3290 3291 WMITLV_SET_HDR(buf_ptr, 3292 WMITLV_TAG_ARRAY_UINT32, 3293 (params->chan_list.num_chan * sizeof(uint32_t))); 3294 buf_ptr += WMI_TLV_HDR_SIZE + 3295 (params->chan_list.num_chan * sizeof(uint32_t)); 3296 3297 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3298 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3299 goto error; 3300 } 3301 3302 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3303 (params->num_ssids * sizeof(wmi_ssid))); 3304 3305 if (params->num_ssids) { 3306 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3307 for (i = 0; i < params->num_ssids; ++i) { 3308 ssid->ssid_len = params->ssid[i].length; 3309 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3310 params->ssid[i].length); 3311 ssid++; 3312 } 3313 } 3314 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3315 3316 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3317 (params->num_bssid * sizeof(wmi_mac_addr))); 3318 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3319 3320 if (params->num_bssid) { 3321 for (i = 0; i < params->num_bssid; ++i) { 3322 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3323 ¶ms->bssid_list[i].bytes[0], bssid); 3324 bssid++; 3325 } 3326 } 3327 3328 buf_ptr += WMI_TLV_HDR_SIZE + 3329 (params->num_bssid * sizeof(wmi_mac_addr)); 3330 3331 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3332 if (params->extraie.len) 3333 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3334 params); 3335 3336 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3337 3338 /* probe req ie whitelisting */ 3339 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3340 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3341 3342 buf_ptr += WMI_TLV_HDR_SIZE; 3343 3344 if (cmd->num_vendor_oui) { 3345 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3346 ie_whitelist->voui); 3347 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3348 } 3349 3350 /* Add phy mode TLV if it's a wide band scan */ 3351 if (params->scan_f_wide_band) { 3352 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3353 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3354 for (i = 0; i < params->chan_list.num_chan; ++i) 3355 buf_ptr[i] = 3356 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3357 buf_ptr += phymode_roundup; 3358 } else { 3359 /* Add ZERO legth phy mode TLV */ 3360 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3361 buf_ptr += WMI_TLV_HDR_SIZE; 3362 } 3363 3364 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3365 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3366 if (params->num_hint_s_ssid) { 3367 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3368 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3369 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3370 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3371 s_ssid++; 3372 } 3373 } 3374 buf_ptr += WMI_TLV_HDR_SIZE + 3375 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3376 3377 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3378 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3379 if (params->num_hint_bssid) { 3380 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3381 for (i = 0; i < params->num_hint_bssid; ++i) { 3382 hint_bssid->freq_flags = 3383 params->hint_bssid[i].freq_flags; 3384 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3385 &hint_bssid->bssid); 3386 hint_bssid++; 3387 } 3388 } 3389 3390 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3391 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3392 len, WMI_START_SCAN_CMDID); 3393 if (ret) { 3394 wmi_err("Failed to start scan: %d", ret); 3395 wmi_buf_free(wmi_buf); 3396 } 3397 return ret; 3398 error: 3399 wmi_buf_free(wmi_buf); 3400 return QDF_STATUS_E_FAILURE; 3401 } 3402 3403 /** 3404 * send_scan_stop_cmd_tlv() - WMI scan start function 3405 * @param wmi_handle : handle to WMI. 3406 * @param param : pointer to hold scan cancel cmd parameter 3407 * 3408 * Return: 0 on success and -ve on failure. 3409 */ 3410 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3411 struct scan_cancel_param *param) 3412 { 3413 wmi_stop_scan_cmd_fixed_param *cmd; 3414 int ret; 3415 int len = sizeof(*cmd); 3416 wmi_buf_t wmi_buf; 3417 3418 /* Allocate the memory */ 3419 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3420 if (!wmi_buf) { 3421 ret = QDF_STATUS_E_NOMEM; 3422 goto error; 3423 } 3424 3425 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3426 WMITLV_SET_HDR(&cmd->tlv_header, 3427 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3428 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3429 cmd->vdev_id = param->vdev_id; 3430 cmd->requestor = param->requester; 3431 cmd->scan_id = param->scan_id; 3432 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3433 wmi_handle, 3434 param->pdev_id); 3435 /* stop the scan with the corresponding scan_id */ 3436 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3437 /* Cancelling all scans */ 3438 cmd->req_type = WMI_SCAN_STOP_ALL; 3439 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3440 /* Cancelling VAP scans */ 3441 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3442 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3443 /* Cancelling specific scan */ 3444 cmd->req_type = WMI_SCAN_STOP_ONE; 3445 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3446 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3447 } else { 3448 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 3449 wmi_buf_free(wmi_buf); 3450 return QDF_STATUS_E_INVAL; 3451 } 3452 3453 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3454 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3455 len, WMI_STOP_SCAN_CMDID); 3456 if (ret) { 3457 wmi_err("Failed to send stop scan: %d", ret); 3458 wmi_buf_free(wmi_buf); 3459 } 3460 3461 error: 3462 return ret; 3463 } 3464 3465 #define WMI_MAX_CHAN_INFO_LOG 192 3466 3467 /** 3468 * wmi_scan_chanlist_dump() - Dump scan channel list info 3469 * @scan_chan_list: scan channel list 3470 * 3471 * Return: void 3472 */ 3473 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3474 { 3475 uint32_t i; 3476 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3477 uint32_t len = 0; 3478 struct channel_param *chan; 3479 int ret; 3480 3481 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3482 for (i = 0; i < scan_chan_list->nallchans; i++) { 3483 chan = &scan_chan_list->ch_param[i]; 3484 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3485 " %d[%d][%d][%d]", chan->mhz, 3486 chan->maxregpower, 3487 chan->dfs_set, chan->nan_disabled); 3488 if (ret <= 0) 3489 break; 3490 len += ret; 3491 if (len >= (sizeof(info) - 20)) { 3492 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 3493 info); 3494 len = 0; 3495 } 3496 } 3497 if (len) 3498 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3499 } 3500 3501 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3502 struct scan_chan_list_params *chan_list) 3503 { 3504 wmi_buf_t buf; 3505 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3506 wmi_scan_chan_list_cmd_fixed_param *cmd; 3507 int i; 3508 uint8_t *buf_ptr; 3509 wmi_channel *chan_info; 3510 struct channel_param *tchan_info; 3511 uint16_t len; 3512 uint16_t num_send_chans, num_sends = 0; 3513 3514 wmi_scan_chanlist_dump(chan_list); 3515 tchan_info = &chan_list->ch_param[0]; 3516 while (chan_list->nallchans) { 3517 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3518 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3519 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3520 else 3521 num_send_chans = chan_list->nallchans; 3522 3523 chan_list->nallchans -= num_send_chans; 3524 len += sizeof(wmi_channel) * num_send_chans; 3525 buf = wmi_buf_alloc(wmi_handle, len); 3526 if (!buf) { 3527 qdf_status = QDF_STATUS_E_NOMEM; 3528 goto end; 3529 } 3530 3531 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3532 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3533 WMITLV_SET_HDR(&cmd->tlv_header, 3534 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3535 WMITLV_GET_STRUCT_TLVLEN 3536 (wmi_scan_chan_list_cmd_fixed_param)); 3537 3538 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 3539 3540 if (num_sends) 3541 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3542 3543 if (chan_list->max_bw_support_present) 3544 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3545 3546 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3547 wmi_handle, 3548 chan_list->pdev_id); 3549 3550 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3551 3552 cmd->num_scan_chans = num_send_chans; 3553 WMITLV_SET_HDR((buf_ptr + 3554 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3555 WMITLV_TAG_ARRAY_STRUC, 3556 sizeof(wmi_channel) * num_send_chans); 3557 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3558 WMI_TLV_HDR_SIZE); 3559 3560 for (i = 0; i < num_send_chans; ++i) { 3561 WMITLV_SET_HDR(&chan_info->tlv_header, 3562 WMITLV_TAG_STRUC_wmi_channel, 3563 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3564 chan_info->mhz = tchan_info->mhz; 3565 chan_info->band_center_freq1 = 3566 tchan_info->cfreq1; 3567 chan_info->band_center_freq2 = 3568 tchan_info->cfreq2; 3569 3570 if (tchan_info->is_chan_passive) 3571 WMI_SET_CHANNEL_FLAG(chan_info, 3572 WMI_CHAN_FLAG_PASSIVE); 3573 if (tchan_info->dfs_set) 3574 WMI_SET_CHANNEL_FLAG(chan_info, 3575 WMI_CHAN_FLAG_DFS); 3576 3577 if (tchan_info->dfs_set_cfreq2) 3578 WMI_SET_CHANNEL_FLAG(chan_info, 3579 WMI_CHAN_FLAG_DFS_CFREQ2); 3580 3581 if (tchan_info->allow_he) 3582 WMI_SET_CHANNEL_FLAG(chan_info, 3583 WMI_CHAN_FLAG_ALLOW_HE); 3584 3585 if (tchan_info->allow_vht) 3586 WMI_SET_CHANNEL_FLAG(chan_info, 3587 WMI_CHAN_FLAG_ALLOW_VHT); 3588 3589 if (tchan_info->allow_ht) 3590 WMI_SET_CHANNEL_FLAG(chan_info, 3591 WMI_CHAN_FLAG_ALLOW_HT); 3592 WMI_SET_CHANNEL_MODE(chan_info, 3593 tchan_info->phy_mode); 3594 3595 if (tchan_info->half_rate) 3596 WMI_SET_CHANNEL_FLAG(chan_info, 3597 WMI_CHAN_FLAG_HALF_RATE); 3598 3599 if (tchan_info->quarter_rate) 3600 WMI_SET_CHANNEL_FLAG(chan_info, 3601 WMI_CHAN_FLAG_QUARTER_RATE); 3602 3603 if (tchan_info->psc_channel) 3604 WMI_SET_CHANNEL_FLAG(chan_info, 3605 WMI_CHAN_FLAG_PSC); 3606 3607 if (tchan_info->nan_disabled) 3608 WMI_SET_CHANNEL_FLAG(chan_info, 3609 WMI_CHAN_FLAG_NAN_DISABLED); 3610 3611 /* also fill in power information */ 3612 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3613 tchan_info->minpower); 3614 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3615 tchan_info->maxpower); 3616 WMI_SET_CHANNEL_REG_POWER(chan_info, 3617 tchan_info->maxregpower); 3618 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3619 tchan_info->antennamax); 3620 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3621 tchan_info->reg_class_id); 3622 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3623 tchan_info->maxregpower); 3624 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3625 tchan_info->max_bw_supported); 3626 3627 tchan_info++; 3628 chan_info++; 3629 } 3630 3631 qdf_status = wmi_unified_cmd_send( 3632 wmi_handle, 3633 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3634 3635 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3636 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3637 wmi_buf_free(buf); 3638 goto end; 3639 } 3640 num_sends++; 3641 } 3642 3643 end: 3644 return qdf_status; 3645 } 3646 3647 /** 3648 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3649 * 3650 * @bufp: Pointer to buffer 3651 * @param: Pointer to tx param 3652 * 3653 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3654 */ 3655 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3656 struct tx_send_params param) 3657 { 3658 wmi_tx_send_params *tx_param; 3659 QDF_STATUS status = QDF_STATUS_SUCCESS; 3660 3661 if (!bufp) { 3662 status = QDF_STATUS_E_FAILURE; 3663 return status; 3664 } 3665 tx_param = (wmi_tx_send_params *)bufp; 3666 WMITLV_SET_HDR(&tx_param->tlv_header, 3667 WMITLV_TAG_STRUC_wmi_tx_send_params, 3668 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3669 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3670 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3671 param.mcs_mask); 3672 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3673 param.nss_mask); 3674 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3675 param.retry_limit); 3676 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3677 param.chain_mask); 3678 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3679 param.bw_mask); 3680 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3681 param.preamble_type); 3682 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3683 param.frame_type); 3684 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3685 param.cfr_enable); 3686 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 3687 param.en_beamforming); 3688 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 3689 param.retry_limit_ext); 3690 3691 return status; 3692 } 3693 3694 #ifdef CONFIG_HL_SUPPORT 3695 /** 3696 * send_mgmt_cmd_tlv() - WMI scan start function 3697 * @wmi_handle : handle to WMI. 3698 * @param : pointer to hold mgmt cmd parameter 3699 * 3700 * Return: 0 on success and -ve on failure. 3701 */ 3702 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3703 struct wmi_mgmt_params *param) 3704 { 3705 wmi_buf_t buf; 3706 uint8_t *bufp; 3707 int32_t cmd_len; 3708 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3709 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3710 mgmt_tx_dl_frm_len; 3711 3712 if (param->frm_len > mgmt_tx_dl_frm_len) { 3713 wmi_err("mgmt frame len %u exceeds %u", 3714 param->frm_len, mgmt_tx_dl_frm_len); 3715 return QDF_STATUS_E_INVAL; 3716 } 3717 3718 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3719 WMI_TLV_HDR_SIZE + 3720 roundup(bufp_len, sizeof(uint32_t)); 3721 3722 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3723 if (!buf) 3724 return QDF_STATUS_E_NOMEM; 3725 3726 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3727 bufp = (uint8_t *) cmd; 3728 WMITLV_SET_HDR(&cmd->tlv_header, 3729 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3730 WMITLV_GET_STRUCT_TLVLEN 3731 (wmi_mgmt_tx_send_cmd_fixed_param)); 3732 3733 cmd->vdev_id = param->vdev_id; 3734 3735 cmd->desc_id = param->desc_id; 3736 cmd->chanfreq = param->chanfreq; 3737 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3738 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3739 sizeof(uint32_t))); 3740 bufp += WMI_TLV_HDR_SIZE; 3741 qdf_mem_copy(bufp, param->pdata, bufp_len); 3742 3743 cmd->frame_len = param->frm_len; 3744 cmd->buf_len = bufp_len; 3745 cmd->tx_params_valid = param->tx_params_valid; 3746 cmd->tx_flags = param->tx_flags; 3747 cmd->peer_rssi = param->peer_rssi; 3748 3749 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3750 bufp, cmd->vdev_id, cmd->chanfreq); 3751 3752 bufp += roundup(bufp_len, sizeof(uint32_t)); 3753 if (param->tx_params_valid) { 3754 if (populate_tx_send_params(bufp, param->tx_param) != 3755 QDF_STATUS_SUCCESS) { 3756 wmi_err("Populate TX send params failed"); 3757 goto free_buf; 3758 } 3759 cmd_len += sizeof(wmi_tx_send_params); 3760 } 3761 3762 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3763 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3764 WMI_MGMT_TX_SEND_CMDID)) { 3765 wmi_err("Failed to send mgmt Tx"); 3766 goto free_buf; 3767 } 3768 return QDF_STATUS_SUCCESS; 3769 3770 free_buf: 3771 wmi_buf_free(buf); 3772 return QDF_STATUS_E_FAILURE; 3773 } 3774 #else 3775 /** 3776 * send_mgmt_cmd_tlv() - WMI scan start function 3777 * @wmi_handle : handle to WMI. 3778 * @param : pointer to hold mgmt cmd parameter 3779 * 3780 * Return: 0 on success and -ve on failure. 3781 */ 3782 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3783 struct wmi_mgmt_params *param) 3784 { 3785 wmi_buf_t buf; 3786 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3787 int32_t cmd_len; 3788 uint64_t dma_addr; 3789 void *qdf_ctx = param->qdf_ctx; 3790 uint8_t *bufp; 3791 QDF_STATUS status = QDF_STATUS_SUCCESS; 3792 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3793 mgmt_tx_dl_frm_len; 3794 3795 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3796 WMI_TLV_HDR_SIZE + 3797 roundup(bufp_len, sizeof(uint32_t)); 3798 3799 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3800 if (!buf) 3801 return QDF_STATUS_E_NOMEM; 3802 3803 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3804 bufp = (uint8_t *) cmd; 3805 WMITLV_SET_HDR(&cmd->tlv_header, 3806 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3807 WMITLV_GET_STRUCT_TLVLEN 3808 (wmi_mgmt_tx_send_cmd_fixed_param)); 3809 3810 cmd->vdev_id = param->vdev_id; 3811 3812 cmd->desc_id = param->desc_id; 3813 cmd->chanfreq = param->chanfreq; 3814 cmd->peer_rssi = param->peer_rssi; 3815 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3816 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3817 sizeof(uint32_t))); 3818 bufp += WMI_TLV_HDR_SIZE; 3819 3820 /* for big endian host, copy engine byte_swap is enabled 3821 * But the frame content is in network byte order 3822 * Need to byte swap the frame content - so when copy engine 3823 * does byte_swap - target gets frame content in the correct order 3824 */ 3825 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 3826 3827 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3828 QDF_DMA_TO_DEVICE); 3829 if (status != QDF_STATUS_SUCCESS) { 3830 wmi_err("wmi buf map failed"); 3831 goto free_buf; 3832 } 3833 3834 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3835 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3836 #if defined(HTT_PADDR64) 3837 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3838 #endif 3839 cmd->frame_len = param->frm_len; 3840 cmd->buf_len = bufp_len; 3841 cmd->tx_params_valid = param->tx_params_valid; 3842 cmd->tx_flags = param->tx_flags; 3843 3844 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3845 bufp, cmd->vdev_id, cmd->chanfreq); 3846 3847 bufp += roundup(bufp_len, sizeof(uint32_t)); 3848 if (param->tx_params_valid) { 3849 status = populate_tx_send_params(bufp, param->tx_param); 3850 if (status != QDF_STATUS_SUCCESS) { 3851 wmi_err("Populate TX send params failed"); 3852 goto unmap_tx_frame; 3853 } 3854 cmd_len += sizeof(wmi_tx_send_params); 3855 } 3856 3857 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3858 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3859 WMI_MGMT_TX_SEND_CMDID)) { 3860 wmi_err("Failed to send mgmt Tx"); 3861 goto unmap_tx_frame; 3862 } 3863 return QDF_STATUS_SUCCESS; 3864 3865 unmap_tx_frame: 3866 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3867 QDF_DMA_TO_DEVICE); 3868 free_buf: 3869 wmi_buf_free(buf); 3870 return QDF_STATUS_E_FAILURE; 3871 } 3872 #endif /* CONFIG_HL_SUPPORT */ 3873 3874 /** 3875 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3876 * @wmi_handle : handle to WMI. 3877 * @param : pointer to offchan data tx cmd parameter 3878 * 3879 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3880 */ 3881 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3882 struct wmi_offchan_data_tx_params *param) 3883 { 3884 wmi_buf_t buf; 3885 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3886 int32_t cmd_len; 3887 uint64_t dma_addr; 3888 void *qdf_ctx = param->qdf_ctx; 3889 uint8_t *bufp; 3890 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3891 param->frm_len : mgmt_tx_dl_frm_len; 3892 QDF_STATUS status = QDF_STATUS_SUCCESS; 3893 3894 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3895 WMI_TLV_HDR_SIZE + 3896 roundup(bufp_len, sizeof(uint32_t)); 3897 3898 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3899 if (!buf) 3900 return QDF_STATUS_E_NOMEM; 3901 3902 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3903 bufp = (uint8_t *) cmd; 3904 WMITLV_SET_HDR(&cmd->tlv_header, 3905 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3906 WMITLV_GET_STRUCT_TLVLEN 3907 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3908 3909 cmd->vdev_id = param->vdev_id; 3910 3911 cmd->desc_id = param->desc_id; 3912 cmd->chanfreq = param->chanfreq; 3913 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3914 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3915 sizeof(uint32_t))); 3916 bufp += WMI_TLV_HDR_SIZE; 3917 qdf_mem_copy(bufp, param->pdata, bufp_len); 3918 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3919 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3920 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3921 #if defined(HTT_PADDR64) 3922 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3923 #endif 3924 cmd->frame_len = param->frm_len; 3925 cmd->buf_len = bufp_len; 3926 cmd->tx_params_valid = param->tx_params_valid; 3927 3928 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3929 bufp, cmd->vdev_id, cmd->chanfreq); 3930 3931 bufp += roundup(bufp_len, sizeof(uint32_t)); 3932 if (param->tx_params_valid) { 3933 status = populate_tx_send_params(bufp, param->tx_param); 3934 if (status != QDF_STATUS_SUCCESS) { 3935 wmi_err("Populate TX send params failed"); 3936 goto err1; 3937 } 3938 cmd_len += sizeof(wmi_tx_send_params); 3939 } 3940 3941 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3942 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3943 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3944 wmi_err("Failed to offchan data Tx"); 3945 goto err1; 3946 } 3947 3948 return QDF_STATUS_SUCCESS; 3949 3950 err1: 3951 wmi_buf_free(buf); 3952 return QDF_STATUS_E_FAILURE; 3953 } 3954 3955 /** 3956 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3957 * @wmi_handle: wmi handle 3958 * @param_value: parameter value 3959 * 3960 * Return: QDF_STATUS_SUCCESS for success or error code 3961 */ 3962 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3963 uint32_t param_value) 3964 { 3965 QDF_STATUS ret; 3966 wmi_modem_power_state_cmd_param *cmd; 3967 wmi_buf_t buf; 3968 uint16_t len = sizeof(*cmd); 3969 3970 buf = wmi_buf_alloc(wmi_handle, len); 3971 if (!buf) 3972 return QDF_STATUS_E_NOMEM; 3973 3974 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3975 WMITLV_SET_HDR(&cmd->tlv_header, 3976 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3977 WMITLV_GET_STRUCT_TLVLEN 3978 (wmi_modem_power_state_cmd_param)); 3979 cmd->modem_power_state = param_value; 3980 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 3981 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3982 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3983 WMI_MODEM_POWER_STATE_CMDID); 3984 if (QDF_IS_STATUS_ERROR(ret)) { 3985 wmi_err("Failed to send notify cmd ret = %d", ret); 3986 wmi_buf_free(buf); 3987 } 3988 3989 return ret; 3990 } 3991 3992 /** 3993 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3994 * @wmi_handle: wmi handle 3995 * @vdev_id: vdev id 3996 * @val: value 3997 * 3998 * Return: QDF_STATUS_SUCCESS for success or error code. 3999 */ 4000 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4001 uint32_t vdev_id, uint8_t val) 4002 { 4003 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4004 wmi_buf_t buf; 4005 int32_t len = sizeof(*cmd); 4006 4007 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4008 4009 buf = wmi_buf_alloc(wmi_handle, len); 4010 if (!buf) 4011 return QDF_STATUS_E_NOMEM; 4012 4013 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4014 WMITLV_SET_HDR(&cmd->tlv_header, 4015 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4016 WMITLV_GET_STRUCT_TLVLEN 4017 (wmi_sta_powersave_mode_cmd_fixed_param)); 4018 cmd->vdev_id = vdev_id; 4019 if (val) 4020 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4021 else 4022 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4023 4024 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4025 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4026 WMI_STA_POWERSAVE_MODE_CMDID)) { 4027 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4028 vdev_id, val); 4029 wmi_buf_free(buf); 4030 return QDF_STATUS_E_FAILURE; 4031 } 4032 return QDF_STATUS_SUCCESS; 4033 } 4034 4035 /** 4036 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4037 * @wmi_handle: wmi handle 4038 * @vdev_id: vdev id 4039 * 4040 * Return: QDF_STATUS_SUCCESS for success or error code. 4041 */ 4042 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4043 uint8_t val) 4044 { 4045 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4046 wmi_buf_t buf; 4047 size_t len = sizeof(*cmd); 4048 4049 buf = wmi_buf_alloc(wmi_handle, len); 4050 if (!buf) 4051 return QDF_STATUS_E_NOMEM; 4052 4053 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4054 WMITLV_SET_HDR(&cmd->tlv_header, 4055 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4056 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4057 4058 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4059 WMI_IDLE_TRIGGER_MONITOR_OFF); 4060 4061 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4062 4063 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4064 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4065 wmi_buf_free(buf); 4066 return QDF_STATUS_E_FAILURE; 4067 } 4068 return QDF_STATUS_SUCCESS; 4069 } 4070 4071 /** 4072 * send_set_mimops_cmd_tlv() - set MIMO powersave 4073 * @wmi_handle: wmi handle 4074 * @vdev_id: vdev id 4075 * @value: value 4076 * 4077 * Return: QDF_STATUS_SUCCESS for success or error code. 4078 */ 4079 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4080 uint8_t vdev_id, int value) 4081 { 4082 QDF_STATUS ret; 4083 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4084 wmi_buf_t buf; 4085 uint16_t len = sizeof(*cmd); 4086 4087 buf = wmi_buf_alloc(wmi_handle, len); 4088 if (!buf) 4089 return QDF_STATUS_E_NOMEM; 4090 4091 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4092 WMITLV_SET_HDR(&cmd->tlv_header, 4093 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4094 WMITLV_GET_STRUCT_TLVLEN 4095 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4096 4097 cmd->vdev_id = vdev_id; 4098 4099 /* WMI_SMPS_FORCED_MODE values do not directly map 4100 * to SM power save values defined in the specification. 4101 * Make sure to send the right mapping. 4102 */ 4103 switch (value) { 4104 case 0: 4105 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4106 break; 4107 case 1: 4108 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4109 break; 4110 case 2: 4111 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4112 break; 4113 case 3: 4114 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4115 break; 4116 default: 4117 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4118 wmi_buf_free(buf); 4119 return QDF_STATUS_E_FAILURE; 4120 } 4121 4122 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4123 4124 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4125 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4126 WMI_STA_SMPS_FORCE_MODE_CMDID); 4127 if (QDF_IS_STATUS_ERROR(ret)) { 4128 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4129 wmi_buf_free(buf); 4130 } 4131 4132 return ret; 4133 } 4134 4135 /** 4136 * send_set_smps_params_cmd_tlv() - set smps params 4137 * @wmi_handle: wmi handle 4138 * @vdev_id: vdev id 4139 * @value: value 4140 * 4141 * Return: QDF_STATUS_SUCCESS for success or error code. 4142 */ 4143 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4144 int value) 4145 { 4146 QDF_STATUS ret; 4147 wmi_sta_smps_param_cmd_fixed_param *cmd; 4148 wmi_buf_t buf; 4149 uint16_t len = sizeof(*cmd); 4150 4151 buf = wmi_buf_alloc(wmi_handle, len); 4152 if (!buf) 4153 return QDF_STATUS_E_NOMEM; 4154 4155 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4156 WMITLV_SET_HDR(&cmd->tlv_header, 4157 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4158 WMITLV_GET_STRUCT_TLVLEN 4159 (wmi_sta_smps_param_cmd_fixed_param)); 4160 4161 cmd->vdev_id = vdev_id; 4162 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4163 cmd->param = 4164 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4165 4166 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4167 cmd->param); 4168 4169 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4170 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4171 WMI_STA_SMPS_PARAM_CMDID); 4172 if (QDF_IS_STATUS_ERROR(ret)) { 4173 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4174 wmi_buf_free(buf); 4175 } 4176 4177 return ret; 4178 } 4179 4180 /** 4181 * send_get_temperature_cmd_tlv() - get pdev temperature req 4182 * @wmi_handle: wmi handle 4183 * 4184 * Return: QDF_STATUS_SUCCESS for success or error code. 4185 */ 4186 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4187 { 4188 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4189 wmi_buf_t wmi_buf; 4190 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4191 uint8_t *buf_ptr; 4192 4193 if (!wmi_handle) { 4194 wmi_err("WMI is closed, can not issue cmd"); 4195 return QDF_STATUS_E_INVAL; 4196 } 4197 4198 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4199 if (!wmi_buf) 4200 return QDF_STATUS_E_NOMEM; 4201 4202 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4203 4204 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4205 WMITLV_SET_HDR(&cmd->tlv_header, 4206 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4207 WMITLV_GET_STRUCT_TLVLEN 4208 (wmi_pdev_get_temperature_cmd_fixed_param)); 4209 4210 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4211 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4212 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4213 wmi_err("Failed to send get temperature command"); 4214 wmi_buf_free(wmi_buf); 4215 return QDF_STATUS_E_FAILURE; 4216 } 4217 4218 return QDF_STATUS_SUCCESS; 4219 } 4220 4221 /** 4222 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4223 * @wmi_handle: wmi handle 4224 * @vdevid: vdev id 4225 * @peer_addr: peer mac address 4226 * @auto_triggerparam: auto trigger parameters 4227 * @num_ac: number of access category 4228 * 4229 * This function sets the trigger 4230 * uapsd params such as service interval, delay interval 4231 * and suspend interval which will be used by the firmware 4232 * to send trigger frames periodically when there is no 4233 * traffic on the transmit side. 4234 * 4235 * Return: QDF_STATUS_SUCCESS for success or error code. 4236 */ 4237 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4238 struct sta_uapsd_trig_params *param) 4239 { 4240 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4241 QDF_STATUS ret; 4242 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4243 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4244 uint32_t i; 4245 wmi_buf_t buf; 4246 uint8_t *buf_ptr; 4247 struct sta_uapsd_params *uapsd_param; 4248 wmi_sta_uapsd_auto_trig_param *trig_param; 4249 4250 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4251 if (!buf) 4252 return QDF_STATUS_E_NOMEM; 4253 4254 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4255 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4256 WMITLV_SET_HDR(&cmd->tlv_header, 4257 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4258 WMITLV_GET_STRUCT_TLVLEN 4259 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4260 cmd->vdev_id = param->vdevid; 4261 cmd->num_ac = param->num_ac; 4262 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4263 4264 /* TLV indicating array of structures to follow */ 4265 buf_ptr += sizeof(*cmd); 4266 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4267 4268 buf_ptr += WMI_TLV_HDR_SIZE; 4269 4270 /* 4271 * Update tag and length for uapsd auto trigger params (this will take 4272 * care of updating tag and length if it is not pre-filled by caller). 4273 */ 4274 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4275 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4276 for (i = 0; i < param->num_ac; i++) { 4277 WMITLV_SET_HDR((buf_ptr + 4278 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4279 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4280 WMITLV_GET_STRUCT_TLVLEN 4281 (wmi_sta_uapsd_auto_trig_param)); 4282 trig_param->wmm_ac = uapsd_param->wmm_ac; 4283 trig_param->user_priority = uapsd_param->user_priority; 4284 trig_param->service_interval = uapsd_param->service_interval; 4285 trig_param->suspend_interval = uapsd_param->suspend_interval; 4286 trig_param->delay_interval = uapsd_param->delay_interval; 4287 trig_param++; 4288 uapsd_param++; 4289 } 4290 4291 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4292 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4293 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4294 if (QDF_IS_STATUS_ERROR(ret)) { 4295 wmi_err("Failed to send set uapsd param ret = %d", ret); 4296 wmi_buf_free(buf); 4297 } 4298 4299 return ret; 4300 } 4301 4302 /** 4303 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4304 * @wmi_handle: Pointer to wmi handle 4305 * @thermal_info: Thermal command information 4306 * 4307 * This function sends the thermal management command 4308 * to the firmware 4309 * 4310 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4311 */ 4312 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4313 struct thermal_cmd_params *thermal_info) 4314 { 4315 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4316 wmi_buf_t buf = NULL; 4317 QDF_STATUS status; 4318 uint32_t len = 0; 4319 uint8_t action; 4320 4321 switch (thermal_info->thermal_action) { 4322 case THERMAL_MGMT_ACTION_DEFAULT: 4323 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4324 break; 4325 4326 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4327 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4328 break; 4329 4330 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4331 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4332 break; 4333 4334 case THERMAL_MGMT_ACTION_CHAINSCALING: 4335 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4336 break; 4337 4338 default: 4339 wmi_err("Invalid thermal_action code %d", 4340 thermal_info->thermal_action); 4341 return QDF_STATUS_E_FAILURE; 4342 } 4343 4344 len = sizeof(*cmd); 4345 4346 buf = wmi_buf_alloc(wmi_handle, len); 4347 if (!buf) 4348 return QDF_STATUS_E_FAILURE; 4349 4350 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4351 4352 WMITLV_SET_HDR(&cmd->tlv_header, 4353 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4354 WMITLV_GET_STRUCT_TLVLEN 4355 (wmi_thermal_mgmt_cmd_fixed_param)); 4356 4357 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4358 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4359 cmd->enable = thermal_info->thermal_enable; 4360 cmd->action = action; 4361 4362 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 4363 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 4364 cmd->enable, cmd->action); 4365 4366 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4367 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4368 WMI_THERMAL_MGMT_CMDID); 4369 if (QDF_IS_STATUS_ERROR(status)) { 4370 wmi_buf_free(buf); 4371 wmi_err("Failed to send thermal mgmt command"); 4372 } 4373 4374 return status; 4375 } 4376 4377 /** 4378 * send_lro_config_cmd_tlv() - process the LRO config command 4379 * @wmi_handle: Pointer to WMI handle 4380 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4381 * 4382 * This function sends down the LRO configuration parameters to 4383 * the firmware to enable LRO, sets the TCP flags and sets the 4384 * seed values for the toeplitz hash generation 4385 * 4386 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4387 */ 4388 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4389 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4390 { 4391 wmi_lro_info_cmd_fixed_param *cmd; 4392 wmi_buf_t buf; 4393 QDF_STATUS status; 4394 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4395 4396 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4397 if (!buf) 4398 return QDF_STATUS_E_FAILURE; 4399 4400 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4401 4402 WMITLV_SET_HDR(&cmd->tlv_header, 4403 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4404 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4405 4406 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4407 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4408 wmi_lro_cmd->tcp_flag); 4409 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4410 wmi_lro_cmd->tcp_flag_mask); 4411 cmd->toeplitz_hash_ipv4_0_3 = 4412 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4413 cmd->toeplitz_hash_ipv4_4_7 = 4414 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4415 cmd->toeplitz_hash_ipv4_8_11 = 4416 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4417 cmd->toeplitz_hash_ipv4_12_15 = 4418 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4419 cmd->toeplitz_hash_ipv4_16 = 4420 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4421 4422 cmd->toeplitz_hash_ipv6_0_3 = 4423 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4424 cmd->toeplitz_hash_ipv6_4_7 = 4425 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4426 cmd->toeplitz_hash_ipv6_8_11 = 4427 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4428 cmd->toeplitz_hash_ipv6_12_15 = 4429 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4430 cmd->toeplitz_hash_ipv6_16_19 = 4431 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4432 cmd->toeplitz_hash_ipv6_20_23 = 4433 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4434 cmd->toeplitz_hash_ipv6_24_27 = 4435 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4436 cmd->toeplitz_hash_ipv6_28_31 = 4437 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4438 cmd->toeplitz_hash_ipv6_32_35 = 4439 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4440 cmd->toeplitz_hash_ipv6_36_39 = 4441 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4442 cmd->toeplitz_hash_ipv6_40 = 4443 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4444 4445 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4446 wmi_handle, 4447 pdev_id); 4448 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4449 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4450 4451 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4452 status = wmi_unified_cmd_send(wmi_handle, buf, 4453 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4454 if (QDF_IS_STATUS_ERROR(status)) { 4455 wmi_buf_free(buf); 4456 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 4457 } 4458 4459 return status; 4460 } 4461 4462 /** 4463 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4464 * @wmi_handle: Pointer to wmi handle 4465 * @rate_report_params: Pointer to peer rate report parameters 4466 * 4467 * 4468 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4469 */ 4470 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4471 struct wmi_peer_rate_report_params *rate_report_params) 4472 { 4473 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4474 wmi_buf_t buf = NULL; 4475 QDF_STATUS status = 0; 4476 uint32_t len = 0; 4477 uint32_t i, j; 4478 4479 len = sizeof(*cmd); 4480 4481 buf = wmi_buf_alloc(wmi_handle, len); 4482 if (!buf) 4483 return QDF_STATUS_E_FAILURE; 4484 4485 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4486 wmi_buf_data(buf); 4487 4488 WMITLV_SET_HDR( 4489 &cmd->tlv_header, 4490 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4491 WMITLV_GET_STRUCT_TLVLEN( 4492 wmi_peer_set_rate_report_condition_fixed_param)); 4493 4494 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4495 cmd->report_backoff_time = rate_report_params->backoff_time; 4496 cmd->report_timer_period = rate_report_params->timer_period; 4497 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4498 cmd->cond_per_phy[i].val_cond_flags = 4499 rate_report_params->report_per_phy[i].cond_flags; 4500 cmd->cond_per_phy[i].rate_delta.min_delta = 4501 rate_report_params->report_per_phy[i].delta.delta_min; 4502 cmd->cond_per_phy[i].rate_delta.percentage = 4503 rate_report_params->report_per_phy[i].delta.percent; 4504 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4505 cmd->cond_per_phy[i].rate_threshold[j] = 4506 rate_report_params->report_per_phy[i]. 4507 report_rate_threshold[j]; 4508 } 4509 } 4510 4511 wmi_debug("enable %d backoff_time %d period %d", 4512 cmd->enable_rate_report, 4513 cmd->report_backoff_time, cmd->report_timer_period); 4514 4515 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4516 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4517 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4518 if (QDF_IS_STATUS_ERROR(status)) { 4519 wmi_buf_free(buf); 4520 wmi_err("Failed to send peer_set_report_cond command"); 4521 } 4522 return status; 4523 } 4524 4525 /** 4526 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4527 * @wmi_handle: wmi handle 4528 * @vdev_id: vdev id. 4529 * @wmm_vparams: edca parameters 4530 * 4531 * This function updates EDCA parameters to the target 4532 * 4533 * Return: CDF Status 4534 */ 4535 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4536 uint8_t vdev_id, bool mu_edca_param, 4537 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4538 { 4539 uint8_t *buf_ptr; 4540 wmi_buf_t buf; 4541 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4542 wmi_wmm_vparams *wmm_param; 4543 struct wmi_host_wme_vparams *twmm_param; 4544 int len = sizeof(*cmd); 4545 int ac; 4546 4547 buf = wmi_buf_alloc(wmi_handle, len); 4548 4549 if (!buf) 4550 return QDF_STATUS_E_NOMEM; 4551 4552 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4553 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4554 WMITLV_SET_HDR(&cmd->tlv_header, 4555 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4556 WMITLV_GET_STRUCT_TLVLEN 4557 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4558 cmd->vdev_id = vdev_id; 4559 cmd->wmm_param_type = mu_edca_param; 4560 4561 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4562 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4563 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4564 WMITLV_SET_HDR(&wmm_param->tlv_header, 4565 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4566 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4567 wmm_param->cwmin = twmm_param->cwmin; 4568 wmm_param->cwmax = twmm_param->cwmax; 4569 wmm_param->aifs = twmm_param->aifs; 4570 if (mu_edca_param) 4571 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4572 else 4573 wmm_param->txoplimit = twmm_param->txoplimit; 4574 wmm_param->acm = twmm_param->acm; 4575 wmm_param->no_ack = twmm_param->noackpolicy; 4576 } 4577 4578 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4579 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4580 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4581 goto fail; 4582 4583 return QDF_STATUS_SUCCESS; 4584 4585 fail: 4586 wmi_buf_free(buf); 4587 wmi_err("Failed to set WMM Parameters"); 4588 return QDF_STATUS_E_FAILURE; 4589 } 4590 4591 /** 4592 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4593 * @wmi_handle: wmi handle 4594 * @vdev_id: vdev id 4595 * @probe_rsp_info: probe response info 4596 * 4597 * Return: QDF_STATUS_SUCCESS for success or error code 4598 */ 4599 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4600 uint8_t vdev_id, 4601 struct wmi_probe_resp_params *probe_rsp_info) 4602 { 4603 wmi_prb_tmpl_cmd_fixed_param *cmd; 4604 wmi_bcn_prb_info *bcn_prb_info; 4605 wmi_buf_t wmi_buf; 4606 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4607 uint8_t *buf_ptr; 4608 QDF_STATUS ret; 4609 4610 wmi_debug("Send probe response template for vdev %d", vdev_id); 4611 4612 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4613 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4614 4615 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4616 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4617 tmpl_len_aligned; 4618 4619 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4620 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 4621 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4622 return QDF_STATUS_E_INVAL; 4623 } 4624 4625 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4626 if (!wmi_buf) 4627 return QDF_STATUS_E_NOMEM; 4628 4629 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4630 4631 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4632 WMITLV_SET_HDR(&cmd->tlv_header, 4633 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4634 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4635 cmd->vdev_id = vdev_id; 4636 cmd->buf_len = tmpl_len; 4637 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4638 4639 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4640 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4641 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4642 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4643 bcn_prb_info->caps = 0; 4644 bcn_prb_info->erp = 0; 4645 buf_ptr += sizeof(wmi_bcn_prb_info); 4646 4647 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4648 buf_ptr += WMI_TLV_HDR_SIZE; 4649 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4650 4651 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4652 ret = wmi_unified_cmd_send(wmi_handle, 4653 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4654 if (QDF_IS_STATUS_ERROR(ret)) { 4655 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 4656 wmi_buf_free(wmi_buf); 4657 } 4658 4659 return ret; 4660 } 4661 4662 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4663 #define WPI_IV_LEN 16 4664 4665 /** 4666 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4667 * 4668 * @dest_tx: destination address of tsc key counter 4669 * @src_tx: source address of tsc key counter 4670 * @dest_rx: destination address of rsc key counter 4671 * @src_rx: source address of rsc key counter 4672 * 4673 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4674 * 4675 * Return: None 4676 * 4677 */ 4678 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4679 uint8_t *dest_rx, uint8_t *src_rx) 4680 { 4681 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4682 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4683 } 4684 #else 4685 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4686 uint8_t *dest_rx, uint8_t *src_rx) 4687 { 4688 return; 4689 } 4690 #endif 4691 4692 /** 4693 * send_setup_install_key_cmd_tlv() - set key parameters 4694 * @wmi_handle: wmi handle 4695 * @key_params: key parameters 4696 * 4697 * This function fills structure from information 4698 * passed in key_params. 4699 * 4700 * Return: QDF_STATUS_SUCCESS - success 4701 * QDF_STATUS_E_FAILURE - failure 4702 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4703 */ 4704 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4705 struct set_key_params *key_params) 4706 { 4707 wmi_vdev_install_key_cmd_fixed_param *cmd; 4708 wmi_buf_t buf; 4709 uint8_t *buf_ptr; 4710 uint32_t len; 4711 uint8_t *key_data; 4712 QDF_STATUS status; 4713 4714 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4715 WMI_TLV_HDR_SIZE; 4716 4717 buf = wmi_buf_alloc(wmi_handle, len); 4718 if (!buf) 4719 return QDF_STATUS_E_NOMEM; 4720 4721 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4722 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4723 WMITLV_SET_HDR(&cmd->tlv_header, 4724 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4725 WMITLV_GET_STRUCT_TLVLEN 4726 (wmi_vdev_install_key_cmd_fixed_param)); 4727 cmd->vdev_id = key_params->vdev_id; 4728 cmd->key_ix = key_params->key_idx; 4729 if (key_params->group_key_idx) { 4730 cmd->is_group_key_ix_valid = 1; 4731 cmd->group_key_ix = key_params->group_key_idx; 4732 } 4733 4734 4735 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4736 cmd->key_flags |= key_params->key_flags; 4737 cmd->key_cipher = key_params->key_cipher; 4738 if ((key_params->key_txmic_len) && 4739 (key_params->key_rxmic_len)) { 4740 cmd->key_txmic_len = key_params->key_txmic_len; 4741 cmd->key_rxmic_len = key_params->key_rxmic_len; 4742 } 4743 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4744 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4745 key_params->tx_iv, 4746 cmd->wpi_key_rsc_counter, 4747 key_params->rx_iv); 4748 #endif 4749 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4750 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4751 roundup(key_params->key_len, sizeof(uint32_t))); 4752 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4753 4754 /* for big endian host, copy engine byte_swap is enabled 4755 * But key_data is in network byte order 4756 * Need to byte swap the key_data - so when copy engine 4757 * does byte_swap - target gets key_data in the correct order 4758 */ 4759 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 4760 (const void *)key_params->key_data, 4761 key_params->key_len); 4762 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4763 sizeof(wmi_key_seq_counter)); 4764 cmd->key_len = key_params->key_len; 4765 4766 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4767 sizeof(wmi_key_seq_counter)); 4768 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4769 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4770 WMI_VDEV_INSTALL_KEY_CMDID); 4771 if (QDF_IS_STATUS_ERROR(status)) { 4772 qdf_mem_zero(wmi_buf_data(buf), len); 4773 wmi_buf_free(buf); 4774 } 4775 return status; 4776 } 4777 4778 /** 4779 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 4780 * @wmi_handle: wmi handle 4781 * @vdev_id: vdev id 4782 * @p2p_ie: p2p IE 4783 * 4784 * Return: QDF_STATUS_SUCCESS for success or error code 4785 */ 4786 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 4787 uint32_t vdev_id, uint8_t *p2p_ie) 4788 { 4789 QDF_STATUS ret; 4790 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 4791 wmi_buf_t wmi_buf; 4792 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 4793 uint8_t *buf_ptr; 4794 4795 ie_len = (uint32_t) (p2p_ie[1] + 2); 4796 4797 /* More than one P2P IE may be included in a single frame. 4798 If multiple P2P IEs are present, the complete P2P attribute 4799 data consists of the concatenation of the P2P Attribute 4800 fields of the P2P IEs. The P2P Attributes field of each 4801 P2P IE may be any length up to the maximum (251 octets). 4802 In this case host sends one P2P IE to firmware so the length 4803 should not exceed more than 251 bytes 4804 */ 4805 if (ie_len > 251) { 4806 wmi_err("Invalid p2p ie length %u", ie_len); 4807 return QDF_STATUS_E_INVAL; 4808 } 4809 4810 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 4811 4812 wmi_buf_len = 4813 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 4814 WMI_TLV_HDR_SIZE; 4815 4816 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4817 if (!wmi_buf) 4818 return QDF_STATUS_E_NOMEM; 4819 4820 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4821 4822 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 4823 WMITLV_SET_HDR(&cmd->tlv_header, 4824 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 4825 WMITLV_GET_STRUCT_TLVLEN 4826 (wmi_p2p_go_set_beacon_ie_fixed_param)); 4827 cmd->vdev_id = vdev_id; 4828 cmd->ie_buf_len = ie_len; 4829 4830 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 4831 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 4832 buf_ptr += WMI_TLV_HDR_SIZE; 4833 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 4834 4835 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 4836 4837 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 4838 ret = wmi_unified_cmd_send(wmi_handle, 4839 wmi_buf, wmi_buf_len, 4840 WMI_P2P_GO_SET_BEACON_IE); 4841 if (QDF_IS_STATUS_ERROR(ret)) { 4842 wmi_err("Failed to send bcn tmpl: %d", ret); 4843 wmi_buf_free(wmi_buf); 4844 } 4845 4846 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 4847 return ret; 4848 } 4849 4850 /** 4851 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 4852 * @wmi_handle: wmi handle 4853 * @psetoui: OUI parameters 4854 * 4855 * set scan probe OUI parameters in firmware 4856 * 4857 * Return: CDF status 4858 */ 4859 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 4860 struct scan_mac_oui *psetoui) 4861 { 4862 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 4863 wmi_buf_t wmi_buf; 4864 uint32_t len; 4865 uint8_t *buf_ptr; 4866 uint32_t *oui_buf; 4867 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 4868 4869 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4870 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 4871 4872 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4873 if (!wmi_buf) 4874 return QDF_STATUS_E_NOMEM; 4875 4876 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4877 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 4878 WMITLV_SET_HDR(&cmd->tlv_header, 4879 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 4880 WMITLV_GET_STRUCT_TLVLEN 4881 (wmi_scan_prob_req_oui_cmd_fixed_param)); 4882 4883 oui_buf = &cmd->prob_req_oui; 4884 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 4885 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 4886 | psetoui->oui[2]; 4887 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 4888 4889 cmd->vdev_id = psetoui->vdev_id; 4890 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 4891 if (psetoui->enb_probe_req_sno_randomization) 4892 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 4893 4894 if (ie_whitelist->white_list) { 4895 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4896 &cmd->num_vendor_oui, 4897 ie_whitelist); 4898 cmd->flags |= 4899 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4900 } 4901 4902 buf_ptr += sizeof(*cmd); 4903 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4904 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4905 buf_ptr += WMI_TLV_HDR_SIZE; 4906 4907 if (cmd->num_vendor_oui != 0) { 4908 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4909 ie_whitelist->voui); 4910 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4911 } 4912 4913 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4914 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4915 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4916 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 4917 wmi_buf_free(wmi_buf); 4918 return QDF_STATUS_E_FAILURE; 4919 } 4920 return QDF_STATUS_SUCCESS; 4921 } 4922 4923 #ifdef IPA_OFFLOAD 4924 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4925 * @wmi_handle: wmi handle 4926 * @ipa_offload: ipa offload control parameter 4927 * 4928 * Returns: 0 on success, error number otherwise 4929 */ 4930 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4931 struct ipa_uc_offload_control_params *ipa_offload) 4932 { 4933 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4934 wmi_buf_t wmi_buf; 4935 uint32_t len; 4936 u_int8_t *buf_ptr; 4937 4938 len = sizeof(*cmd); 4939 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4940 if (!wmi_buf) 4941 return QDF_STATUS_E_NOMEM; 4942 4943 wmi_debug("offload_type=%d, enable=%d", 4944 ipa_offload->offload_type, ipa_offload->enable); 4945 4946 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4947 4948 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4949 WMITLV_SET_HDR(&cmd->tlv_header, 4950 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4951 WMITLV_GET_STRUCT_TLVLEN( 4952 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4953 4954 cmd->offload_type = ipa_offload->offload_type; 4955 cmd->vdev_id = ipa_offload->vdev_id; 4956 cmd->enable = ipa_offload->enable; 4957 4958 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4959 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4960 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4961 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 4962 wmi_buf_free(wmi_buf); 4963 return QDF_STATUS_E_FAILURE; 4964 } 4965 4966 return QDF_STATUS_SUCCESS; 4967 } 4968 #endif 4969 4970 /** 4971 * send_pno_stop_cmd_tlv() - PNO stop request 4972 * @wmi_handle: wmi handle 4973 * @vdev_id: vdev id 4974 * 4975 * This function request FW to stop ongoing PNO operation. 4976 * 4977 * Return: CDF status 4978 */ 4979 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4980 { 4981 wmi_nlo_config_cmd_fixed_param *cmd; 4982 int32_t len = sizeof(*cmd); 4983 wmi_buf_t buf; 4984 uint8_t *buf_ptr; 4985 int ret; 4986 4987 /* 4988 * TLV place holder for array of structures nlo_configured_parameters 4989 * TLV place holder for array of uint32_t channel_list 4990 * TLV place holder for chnl prediction cfg 4991 */ 4992 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4993 buf = wmi_buf_alloc(wmi_handle, len); 4994 if (!buf) 4995 return QDF_STATUS_E_NOMEM; 4996 4997 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4998 buf_ptr = (uint8_t *) cmd; 4999 5000 WMITLV_SET_HDR(&cmd->tlv_header, 5001 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5002 WMITLV_GET_STRUCT_TLVLEN 5003 (wmi_nlo_config_cmd_fixed_param)); 5004 5005 cmd->vdev_id = vdev_id; 5006 cmd->flags = WMI_NLO_CONFIG_STOP; 5007 buf_ptr += sizeof(*cmd); 5008 5009 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5010 buf_ptr += WMI_TLV_HDR_SIZE; 5011 5012 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5013 buf_ptr += WMI_TLV_HDR_SIZE; 5014 5015 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5016 buf_ptr += WMI_TLV_HDR_SIZE; 5017 5018 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5019 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5020 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5021 if (ret) { 5022 wmi_err("Failed to send nlo wmi cmd"); 5023 wmi_buf_free(buf); 5024 return QDF_STATUS_E_FAILURE; 5025 } 5026 5027 return QDF_STATUS_SUCCESS; 5028 } 5029 5030 /** 5031 * send_obss_disable_cmd_tlv() - disable obss scan request 5032 * @wmi_handle: wmi handle 5033 * @vdev_id: vdev id 5034 * 5035 * This function request FW to disable ongoing obss scan operation. 5036 * 5037 * Return: QDF status 5038 */ 5039 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5040 uint8_t vdev_id) 5041 { 5042 QDF_STATUS status; 5043 wmi_buf_t buf; 5044 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5045 int len = sizeof(*cmd); 5046 5047 buf = wmi_buf_alloc(wmi_handle, len); 5048 if (!buf) 5049 return QDF_STATUS_E_NOMEM; 5050 5051 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5052 5053 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5054 WMITLV_SET_HDR(&cmd->tlv_header, 5055 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5056 WMITLV_GET_STRUCT_TLVLEN( 5057 wmi_obss_scan_disable_cmd_fixed_param)); 5058 5059 cmd->vdev_id = vdev_id; 5060 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5061 WMI_OBSS_SCAN_DISABLE_CMDID); 5062 if (QDF_IS_STATUS_ERROR(status)) 5063 wmi_buf_free(buf); 5064 5065 return status; 5066 } 5067 5068 /** 5069 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5070 * @buf_ptr: Buffer passed by upper layers 5071 * @pno: Buffer to be sent to the firmware 5072 * 5073 * Copy the PNO Channel prediction configuration parameters 5074 * passed by the upper layers to a WMI format TLV and send it 5075 * down to the firmware. 5076 * 5077 * Return: None 5078 */ 5079 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5080 struct pno_scan_req_params *pno) 5081 { 5082 nlo_channel_prediction_cfg *channel_prediction_cfg = 5083 (nlo_channel_prediction_cfg *) buf_ptr; 5084 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5085 WMITLV_TAG_ARRAY_BYTE, 5086 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5087 #ifdef FEATURE_WLAN_SCAN_PNO 5088 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5089 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5090 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5091 channel_prediction_cfg->full_scan_period_ms = 5092 pno->channel_prediction_full_scan; 5093 #endif 5094 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5095 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5096 channel_prediction_cfg->enable, 5097 channel_prediction_cfg->top_k_num, 5098 channel_prediction_cfg->stationary_threshold, 5099 channel_prediction_cfg->full_scan_period_ms); 5100 } 5101 5102 /** 5103 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5104 * @wmi_handle: wmi handle 5105 * @buf_ptr: Buffer passed by upper layers 5106 * @buf_len: Length of passed buffer by upper layer 5107 * 5108 * Copy the buffer passed by the upper layers and send it 5109 * down to the firmware. 5110 * 5111 * Return: None 5112 */ 5113 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5114 void *buf_ptr, uint32_t buf_len) 5115 { 5116 wmi_buf_t buf = NULL; 5117 QDF_STATUS status; 5118 int len; 5119 uint8_t *data_ptr; 5120 5121 len = buf_len; 5122 buf = wmi_buf_alloc(wmi_handle, len); 5123 if (!buf) 5124 return QDF_STATUS_E_NOMEM; 5125 5126 data_ptr = (uint8_t *)wmi_buf_data(buf); 5127 qdf_mem_copy(data_ptr, buf_ptr, len); 5128 5129 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5130 status = wmi_unified_cmd_send(wmi_handle, buf, 5131 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5132 5133 if (QDF_IS_STATUS_ERROR(status)) { 5134 wmi_buf_free(buf); 5135 return QDF_STATUS_E_FAILURE; 5136 } 5137 return QDF_STATUS_SUCCESS; 5138 } 5139 5140 /** 5141 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5142 * @wmi_handle: wmi handle 5143 * @evt_buf: event buffer 5144 * @more_flag: buffer to populate more flag 5145 * 5146 * Return: status of operation 5147 */ 5148 static QDF_STATUS 5149 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5150 uint32_t *more_flag) 5151 { 5152 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5153 wmi_ctrl_path_stats_event_fixed_param *ev; 5154 5155 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5156 if (!param_buf) { 5157 wmi_err_rl("param_buf is NULL"); 5158 return QDF_STATUS_E_FAILURE; 5159 } 5160 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5161 5162 *more_flag = ev->more; 5163 return QDF_STATUS_SUCCESS; 5164 } 5165 5166 /** 5167 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 5168 * @wmi_handle: wmi handle 5169 * @params: configuration parameters 5170 * 5171 * Return: QDF_STATUS 5172 */ 5173 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 5174 struct nlo_mawc_params *params) 5175 { 5176 wmi_buf_t buf = NULL; 5177 QDF_STATUS status; 5178 int len; 5179 uint8_t *buf_ptr; 5180 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 5181 5182 len = sizeof(*wmi_nlo_mawc_params); 5183 buf = wmi_buf_alloc(wmi_handle, len); 5184 if (!buf) 5185 return QDF_STATUS_E_NOMEM; 5186 5187 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5188 wmi_nlo_mawc_params = 5189 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 5190 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 5191 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 5192 WMITLV_GET_STRUCT_TLVLEN 5193 (wmi_nlo_configure_mawc_cmd_fixed_param)); 5194 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 5195 if (params->enable) 5196 wmi_nlo_mawc_params->enable = 1; 5197 else 5198 wmi_nlo_mawc_params->enable = 0; 5199 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 5200 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 5201 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 5202 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 5203 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 5204 wmi_nlo_mawc_params->exp_backoff_ratio, 5205 wmi_nlo_mawc_params->init_scan_interval, 5206 wmi_nlo_mawc_params->max_scan_interval); 5207 5208 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 5209 status = wmi_unified_cmd_send(wmi_handle, buf, 5210 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 5211 if (QDF_IS_STATUS_ERROR(status)) { 5212 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 5213 status); 5214 wmi_buf_free(buf); 5215 return QDF_STATUS_E_FAILURE; 5216 } 5217 5218 return QDF_STATUS_SUCCESS; 5219 } 5220 5221 /** 5222 * send_pno_start_cmd_tlv() - PNO start request 5223 * @wmi_handle: wmi handle 5224 * @pno: PNO request 5225 * 5226 * This function request FW to start PNO request. 5227 * Request: CDF status 5228 */ 5229 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 5230 struct pno_scan_req_params *pno) 5231 { 5232 wmi_nlo_config_cmd_fixed_param *cmd; 5233 nlo_configured_parameters *nlo_list; 5234 uint32_t *channel_list; 5235 int32_t len; 5236 wmi_buf_t buf; 5237 uint8_t *buf_ptr; 5238 uint8_t i; 5239 int ret; 5240 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 5241 connected_nlo_rssi_params *nlo_relative_rssi; 5242 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 5243 5244 /* 5245 * TLV place holder for array nlo_configured_parameters(nlo_list) 5246 * TLV place holder for array of uint32_t channel_list 5247 * TLV place holder for chnnl prediction cfg 5248 * TLV place holder for array of wmi_vendor_oui 5249 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 5250 */ 5251 len = sizeof(*cmd) + 5252 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 5253 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5254 5255 len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt; 5256 len += sizeof(nlo_configured_parameters) * 5257 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5258 len += sizeof(nlo_channel_prediction_cfg); 5259 len += sizeof(enlo_candidate_score_params); 5260 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 5261 len += sizeof(connected_nlo_rssi_params); 5262 len += sizeof(connected_nlo_bss_band_rssi_pref); 5263 5264 buf = wmi_buf_alloc(wmi_handle, len); 5265 if (!buf) 5266 return QDF_STATUS_E_NOMEM; 5267 5268 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5269 5270 buf_ptr = (uint8_t *) cmd; 5271 WMITLV_SET_HDR(&cmd->tlv_header, 5272 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5273 WMITLV_GET_STRUCT_TLVLEN 5274 (wmi_nlo_config_cmd_fixed_param)); 5275 cmd->vdev_id = pno->vdev_id; 5276 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 5277 5278 #ifdef FEATURE_WLAN_SCAN_PNO 5279 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 5280 pno->adaptive_dwell_mode); 5281 #endif 5282 /* Current FW does not support min-max range for dwell time */ 5283 cmd->active_dwell_time = pno->active_dwell_time; 5284 cmd->passive_dwell_time = pno->passive_dwell_time; 5285 5286 if (pno->do_passive_scan) 5287 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 5288 /* Copy scan interval */ 5289 cmd->fast_scan_period = pno->fast_scan_period; 5290 cmd->slow_scan_period = pno->slow_scan_period; 5291 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 5292 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 5293 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 5294 5295 /* mac randomization attributes */ 5296 if (pno->scan_random.randomize) { 5297 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 5298 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 5299 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 5300 pno->scan_random.mac_mask, 5301 &cmd->mac_addr, 5302 &cmd->mac_mask); 5303 } 5304 5305 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 5306 5307 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5308 5309 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5310 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 5311 buf_ptr += WMI_TLV_HDR_SIZE; 5312 5313 nlo_list = (nlo_configured_parameters *) buf_ptr; 5314 for (i = 0; i < cmd->no_of_ssids; i++) { 5315 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 5316 WMITLV_TAG_ARRAY_BYTE, 5317 WMITLV_GET_STRUCT_TLVLEN 5318 (nlo_configured_parameters)); 5319 /* Copy ssid and it's length */ 5320 nlo_list[i].ssid.valid = true; 5321 nlo_list[i].ssid.ssid.ssid_len = 5322 pno->networks_list[i].ssid.length; 5323 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 5324 pno->networks_list[i].ssid.ssid, 5325 nlo_list[i].ssid.ssid.ssid_len); 5326 5327 /* Copy rssi threshold */ 5328 if (pno->networks_list[i].rssi_thresh && 5329 pno->networks_list[i].rssi_thresh > 5330 WMI_RSSI_THOLD_DEFAULT) { 5331 nlo_list[i].rssi_cond.valid = true; 5332 nlo_list[i].rssi_cond.rssi = 5333 pno->networks_list[i].rssi_thresh; 5334 } 5335 nlo_list[i].bcast_nw_type.valid = true; 5336 nlo_list[i].bcast_nw_type.bcast_nw_type = 5337 pno->networks_list[i].bc_new_type; 5338 } 5339 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 5340 5341 /* Copy channel info */ 5342 cmd->num_of_channels = pno->networks_list[0].channel_cnt; 5343 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5344 (cmd->num_of_channels * sizeof(uint32_t))); 5345 buf_ptr += WMI_TLV_HDR_SIZE; 5346 5347 channel_list = (uint32_t *) buf_ptr; 5348 for (i = 0; i < cmd->num_of_channels; i++) { 5349 channel_list[i] = pno->networks_list[0].channels[i]; 5350 5351 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 5352 channel_list[i] = 5353 wlan_chan_to_freq(pno-> 5354 networks_list[0].channels[i]); 5355 } 5356 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 5357 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5358 sizeof(nlo_channel_prediction_cfg)); 5359 buf_ptr += WMI_TLV_HDR_SIZE; 5360 wmi_set_pno_channel_prediction(buf_ptr, pno); 5361 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5362 /** TODO: Discrete firmware doesn't have command/option to configure 5363 * App IE which comes from wpa_supplicant as of part PNO start request. 5364 */ 5365 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 5366 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 5367 buf_ptr += sizeof(enlo_candidate_score_params); 5368 5369 if (ie_whitelist->white_list) { 5370 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5371 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5372 &cmd->num_vendor_oui, 5373 ie_whitelist); 5374 } 5375 5376 /* ie white list */ 5377 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5378 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5379 buf_ptr += WMI_TLV_HDR_SIZE; 5380 if (cmd->num_vendor_oui != 0) { 5381 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5382 ie_whitelist->voui); 5383 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5384 } 5385 5386 if (pno->relative_rssi_set) 5387 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 5388 5389 /* 5390 * Firmware calculation using connected PNO params: 5391 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 5392 * deduction of rssi_pref for chosen band_pref and 5393 * addition of rssi_pref for remaining bands (other than chosen band). 5394 */ 5395 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 5396 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 5397 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 5398 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 5399 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 5400 buf_ptr += sizeof(*nlo_relative_rssi); 5401 5402 /* 5403 * As of now Kernel and Host supports one band and rssi preference. 5404 * Firmware supports array of band and rssi preferences 5405 */ 5406 cmd->num_cnlo_band_pref = 1; 5407 WMITLV_SET_HDR(buf_ptr, 5408 WMITLV_TAG_ARRAY_STRUC, 5409 cmd->num_cnlo_band_pref * 5410 sizeof(connected_nlo_bss_band_rssi_pref)); 5411 buf_ptr += WMI_TLV_HDR_SIZE; 5412 5413 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 5414 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 5415 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5416 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5417 WMITLV_GET_STRUCT_TLVLEN( 5418 connected_nlo_bss_band_rssi_pref)); 5419 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5420 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5421 } 5422 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5423 5424 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5425 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5426 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5427 if (ret) { 5428 wmi_err("Failed to send nlo wmi cmd"); 5429 wmi_buf_free(buf); 5430 return QDF_STATUS_E_FAILURE; 5431 } 5432 5433 return QDF_STATUS_SUCCESS; 5434 } 5435 5436 /** 5437 * is_service_enabled_tlv() - Check if service enabled 5438 * @param wmi_handle: wmi handle 5439 * @param service_id: service identifier 5440 * 5441 * Return: 1 enabled, 0 disabled 5442 */ 5443 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 5444 uint32_t service_id) 5445 { 5446 struct wmi_soc *soc = wmi_handle->soc; 5447 5448 if (!soc->wmi_service_bitmap) { 5449 wmi_err("WMI service bit map is not saved yet"); 5450 return false; 5451 } 5452 5453 /* if wmi_service_enabled was received with extended2 bitmap, 5454 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 5455 */ 5456 if (soc->wmi_ext2_service_bitmap) { 5457 if (!soc->wmi_ext_service_bitmap) { 5458 wmi_err("WMI service ext bit map is not saved yet"); 5459 return false; 5460 } 5461 5462 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 5463 soc->wmi_ext_service_bitmap, 5464 soc->wmi_ext2_service_bitmap, 5465 service_id); 5466 } 5467 5468 if (service_id >= WMI_MAX_EXT_SERVICE) { 5469 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 5470 service_id); 5471 return false; 5472 } 5473 /* if wmi_service_enabled was received with extended bitmap, 5474 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 5475 */ 5476 if (soc->wmi_ext_service_bitmap) 5477 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 5478 soc->wmi_ext_service_bitmap, 5479 service_id); 5480 5481 if (service_id >= WMI_MAX_SERVICE) { 5482 wmi_err("Service id %d but WMI ext service bitmap is NULL", 5483 service_id); 5484 return false; 5485 } 5486 5487 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 5488 service_id); 5489 } 5490 5491 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5492 /** 5493 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5494 * @wmi_handle: wmi handle 5495 * @clear_req: ll stats clear request command params 5496 * 5497 * Return: QDF_STATUS_SUCCESS for success or error code 5498 */ 5499 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5500 const struct ll_stats_clear_params *clear_req) 5501 { 5502 wmi_clear_link_stats_cmd_fixed_param *cmd; 5503 int32_t len; 5504 wmi_buf_t buf; 5505 uint8_t *buf_ptr; 5506 int ret; 5507 5508 len = sizeof(*cmd); 5509 buf = wmi_buf_alloc(wmi_handle, len); 5510 5511 if (!buf) 5512 return QDF_STATUS_E_NOMEM; 5513 5514 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5515 qdf_mem_zero(buf_ptr, len); 5516 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5517 5518 WMITLV_SET_HDR(&cmd->tlv_header, 5519 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5520 WMITLV_GET_STRUCT_TLVLEN 5521 (wmi_clear_link_stats_cmd_fixed_param)); 5522 5523 cmd->stop_stats_collection_req = clear_req->stop_req; 5524 cmd->vdev_id = clear_req->vdev_id; 5525 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5526 5527 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5528 &cmd->peer_macaddr); 5529 5530 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 5531 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 5532 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5533 cmd->stop_stats_collection_req, 5534 cmd->vdev_id, cmd->stats_clear_req_mask, 5535 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 5536 5537 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5538 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5539 WMI_CLEAR_LINK_STATS_CMDID); 5540 if (ret) { 5541 wmi_err("Failed to send clear link stats req"); 5542 wmi_buf_free(buf); 5543 return QDF_STATUS_E_FAILURE; 5544 } 5545 5546 wmi_debug("Clear Link Layer Stats request sent successfully"); 5547 return QDF_STATUS_SUCCESS; 5548 } 5549 5550 /** 5551 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5552 * @wmi_handle: wmi handle 5553 * @set_req: ll stats set request command params 5554 * 5555 * Return: QDF_STATUS_SUCCESS for success or error code 5556 */ 5557 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5558 const struct ll_stats_set_params *set_req) 5559 { 5560 wmi_start_link_stats_cmd_fixed_param *cmd; 5561 int32_t len; 5562 wmi_buf_t buf; 5563 uint8_t *buf_ptr; 5564 int ret; 5565 5566 len = sizeof(*cmd); 5567 buf = wmi_buf_alloc(wmi_handle, len); 5568 5569 if (!buf) 5570 return QDF_STATUS_E_NOMEM; 5571 5572 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5573 qdf_mem_zero(buf_ptr, len); 5574 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5575 5576 WMITLV_SET_HDR(&cmd->tlv_header, 5577 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5578 WMITLV_GET_STRUCT_TLVLEN 5579 (wmi_start_link_stats_cmd_fixed_param)); 5580 5581 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5582 cmd->aggressive_statistics_gathering = 5583 set_req->aggressive_statistics_gathering; 5584 5585 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5586 cmd->mpdu_size_threshold, 5587 cmd->aggressive_statistics_gathering); 5588 5589 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5590 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5591 WMI_START_LINK_STATS_CMDID); 5592 if (ret) { 5593 wmi_err("Failed to send set link stats request"); 5594 wmi_buf_free(buf); 5595 return QDF_STATUS_E_FAILURE; 5596 } 5597 5598 return QDF_STATUS_SUCCESS; 5599 } 5600 5601 /** 5602 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5603 * @wmi_handle: wmi handle 5604 * @get_req: ll stats get request command params 5605 * 5606 * Return: QDF_STATUS_SUCCESS for success or error code 5607 */ 5608 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5609 const struct ll_stats_get_params *get_req) 5610 { 5611 wmi_request_link_stats_cmd_fixed_param *cmd; 5612 int32_t len; 5613 wmi_buf_t buf; 5614 uint8_t *buf_ptr; 5615 int ret; 5616 5617 len = sizeof(*cmd); 5618 buf = wmi_buf_alloc(wmi_handle, len); 5619 5620 if (!buf) 5621 return QDF_STATUS_E_NOMEM; 5622 5623 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5624 qdf_mem_zero(buf_ptr, len); 5625 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5626 5627 WMITLV_SET_HDR(&cmd->tlv_header, 5628 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5629 WMITLV_GET_STRUCT_TLVLEN 5630 (wmi_request_link_stats_cmd_fixed_param)); 5631 5632 cmd->request_id = get_req->req_id; 5633 cmd->stats_type = get_req->param_id_mask; 5634 cmd->vdev_id = get_req->vdev_id; 5635 5636 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5637 &cmd->peer_macaddr); 5638 5639 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5640 cmd->request_id, cmd->stats_type, cmd->vdev_id, 5641 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5642 5643 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5644 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5645 WMI_REQUEST_LINK_STATS_CMDID, true); 5646 if (ret) { 5647 wmi_buf_free(buf); 5648 return QDF_STATUS_E_FAILURE; 5649 } 5650 5651 return QDF_STATUS_SUCCESS; 5652 } 5653 5654 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 5655 /** 5656 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 5657 * station request 5658 * @wmi_handle: wmi handle 5659 * @get_req: ll stats get request command params 5660 * 5661 * Return: QDF_STATUS_SUCCESS for success or error code 5662 */ 5663 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 5664 wmi_unified_t wmi_handle, 5665 const struct ll_stats_get_params *get_req) 5666 { 5667 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 5668 int32_t len; 5669 wmi_buf_t buf; 5670 void *buf_ptr; 5671 QDF_STATUS ret; 5672 bool is_ll_get_sta_stats_over_qmi; 5673 5674 len = sizeof(*unified_cmd); 5675 buf = wmi_buf_alloc(wmi_handle, len); 5676 5677 if (!buf) 5678 return QDF_STATUS_E_NOMEM; 5679 5680 buf_ptr = wmi_buf_data(buf); 5681 5682 unified_cmd = buf_ptr; 5683 WMITLV_SET_HDR( 5684 &unified_cmd->tlv_header, 5685 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 5686 WMITLV_GET_STRUCT_TLVLEN 5687 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 5688 5689 unified_cmd->link_stats_type = get_req->param_id_mask; 5690 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 5691 WMI_REQUEST_PEER_STAT | 5692 WMI_REQUEST_VDEV_STAT | 5693 WMI_REQUEST_PDEV_STAT | 5694 WMI_REQUEST_PEER_EXTD2_STAT | 5695 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 5696 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5697 wmi_handle, 5698 WMI_HOST_PDEV_ID_SOC); 5699 5700 unified_cmd->vdev_id = get_req->vdev_id; 5701 unified_cmd->request_id = get_req->req_id; 5702 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5703 &unified_cmd->peer_macaddr); 5704 5705 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 5706 QDF_MAC_ADDR_FMT, 5707 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 5708 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5709 5710 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 5711 5712 /** 5713 * FW support for LL_get_sta command. True represents the unified 5714 * ll_get_sta command should be sent over QMI always irrespective of 5715 * WOW state. 5716 */ 5717 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 5718 wmi_handle, 5719 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 5720 5721 if (is_ll_get_sta_stats_over_qmi) { 5722 ret = wmi_unified_cmd_send_over_qmi( 5723 wmi_handle, buf, len, 5724 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 5725 } else { 5726 ret = wmi_unified_cmd_send_pm_chk( 5727 wmi_handle, buf, len, 5728 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 5729 true); 5730 } 5731 5732 if (QDF_IS_STATUS_ERROR(ret)) { 5733 wmi_buf_free(buf); 5734 return QDF_STATUS_E_FAILURE; 5735 } 5736 5737 return ret; 5738 } 5739 #endif 5740 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 5741 5742 /** 5743 * send_congestion_cmd_tlv() - send request to fw to get CCA 5744 * @wmi_handle: wmi handle 5745 * @vdev_id: vdev id 5746 * 5747 * Return: CDF status 5748 */ 5749 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 5750 uint8_t vdev_id) 5751 { 5752 wmi_buf_t buf; 5753 wmi_request_stats_cmd_fixed_param *cmd; 5754 uint8_t len; 5755 uint8_t *buf_ptr; 5756 5757 len = sizeof(*cmd); 5758 buf = wmi_buf_alloc(wmi_handle, len); 5759 if (!buf) 5760 return QDF_STATUS_E_FAILURE; 5761 5762 buf_ptr = wmi_buf_data(buf); 5763 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 5764 WMITLV_SET_HDR(&cmd->tlv_header, 5765 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5766 WMITLV_GET_STRUCT_TLVLEN 5767 (wmi_request_stats_cmd_fixed_param)); 5768 5769 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 5770 cmd->vdev_id = vdev_id; 5771 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 5772 cmd->vdev_id, cmd->stats_id); 5773 5774 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5775 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5776 WMI_REQUEST_STATS_CMDID)) { 5777 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 5778 wmi_buf_free(buf); 5779 return QDF_STATUS_E_FAILURE; 5780 } 5781 5782 return QDF_STATUS_SUCCESS; 5783 } 5784 5785 /** 5786 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 5787 * @wmi_handle: wmi handle 5788 * @rssi_req: get RSSI request 5789 * 5790 * Return: CDF status 5791 */ 5792 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 5793 { 5794 wmi_buf_t buf; 5795 wmi_request_stats_cmd_fixed_param *cmd; 5796 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5797 5798 buf = wmi_buf_alloc(wmi_handle, len); 5799 if (!buf) 5800 return QDF_STATUS_E_FAILURE; 5801 5802 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5803 WMITLV_SET_HDR(&cmd->tlv_header, 5804 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5805 WMITLV_GET_STRUCT_TLVLEN 5806 (wmi_request_stats_cmd_fixed_param)); 5807 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5808 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5809 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5810 WMI_REQUEST_STATS_CMDID)) { 5811 wmi_err("Failed to send host stats request to fw"); 5812 wmi_buf_free(buf); 5813 return QDF_STATUS_E_FAILURE; 5814 } 5815 5816 return QDF_STATUS_SUCCESS; 5817 } 5818 5819 /** 5820 * send_snr_cmd_tlv() - get RSSI from fw 5821 * @wmi_handle: wmi handle 5822 * @vdev_id: vdev id 5823 * 5824 * Return: CDF status 5825 */ 5826 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5827 { 5828 wmi_buf_t buf; 5829 wmi_request_stats_cmd_fixed_param *cmd; 5830 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5831 5832 buf = wmi_buf_alloc(wmi_handle, len); 5833 if (!buf) 5834 return QDF_STATUS_E_FAILURE; 5835 5836 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5837 cmd->vdev_id = vdev_id; 5838 5839 WMITLV_SET_HDR(&cmd->tlv_header, 5840 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5841 WMITLV_GET_STRUCT_TLVLEN 5842 (wmi_request_stats_cmd_fixed_param)); 5843 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5844 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5845 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5846 WMI_REQUEST_STATS_CMDID)) { 5847 wmi_err("Failed to send host stats request to fw"); 5848 wmi_buf_free(buf); 5849 return QDF_STATUS_E_FAILURE; 5850 } 5851 5852 return QDF_STATUS_SUCCESS; 5853 } 5854 5855 /** 5856 * send_link_status_req_cmd_tlv() - process link status request from UMAC 5857 * @wmi_handle: wmi handle 5858 * @link_status: get link params 5859 * 5860 * Return: CDF status 5861 */ 5862 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 5863 struct link_status_params *link_status) 5864 { 5865 wmi_buf_t buf; 5866 wmi_request_stats_cmd_fixed_param *cmd; 5867 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5868 5869 buf = wmi_buf_alloc(wmi_handle, len); 5870 if (!buf) 5871 return QDF_STATUS_E_FAILURE; 5872 5873 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5874 WMITLV_SET_HDR(&cmd->tlv_header, 5875 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5876 WMITLV_GET_STRUCT_TLVLEN 5877 (wmi_request_stats_cmd_fixed_param)); 5878 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 5879 cmd->vdev_id = link_status->vdev_id; 5880 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5881 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5882 WMI_REQUEST_STATS_CMDID)) { 5883 wmi_err("Failed to send WMI link status request to fw"); 5884 wmi_buf_free(buf); 5885 return QDF_STATUS_E_FAILURE; 5886 } 5887 5888 return QDF_STATUS_SUCCESS; 5889 } 5890 5891 #ifdef WLAN_SUPPORT_GREEN_AP 5892 /** 5893 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 5894 * @wmi_handle: wmi handler 5895 * @egap_params: pointer to egap_params 5896 * 5897 * Return: 0 for success, otherwise appropriate error code 5898 */ 5899 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 5900 struct wlan_green_ap_egap_params *egap_params) 5901 { 5902 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 5903 wmi_buf_t buf; 5904 int32_t err; 5905 5906 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5907 if (!buf) 5908 return QDF_STATUS_E_NOMEM; 5909 5910 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 5911 WMITLV_SET_HDR(&cmd->tlv_header, 5912 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 5913 WMITLV_GET_STRUCT_TLVLEN( 5914 wmi_ap_ps_egap_param_cmd_fixed_param)); 5915 5916 cmd->enable = egap_params->host_enable_egap; 5917 cmd->inactivity_time = egap_params->egap_inactivity_time; 5918 cmd->wait_time = egap_params->egap_wait_time; 5919 cmd->flags = egap_params->egap_feature_flags; 5920 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 5921 err = wmi_unified_cmd_send(wmi_handle, buf, 5922 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 5923 if (err) { 5924 wmi_err("Failed to send ap_ps_egap cmd"); 5925 wmi_buf_free(buf); 5926 return QDF_STATUS_E_FAILURE; 5927 } 5928 5929 return QDF_STATUS_SUCCESS; 5930 } 5931 #endif 5932 5933 /** 5934 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 5935 * @wmi_handle: wmi handle 5936 * @vdev_id: vdev id 5937 * 5938 * Return: QDF_STATUS_SUCCESS for success or error code 5939 */ 5940 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 5941 uint8_t vdev_id) 5942 { 5943 wmi_csa_offload_enable_cmd_fixed_param *cmd; 5944 wmi_buf_t buf; 5945 int32_t len = sizeof(*cmd); 5946 5947 wmi_debug("vdev_id %d", vdev_id); 5948 buf = wmi_buf_alloc(wmi_handle, len); 5949 if (!buf) 5950 return QDF_STATUS_E_NOMEM; 5951 5952 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 5953 WMITLV_SET_HDR(&cmd->tlv_header, 5954 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 5955 WMITLV_GET_STRUCT_TLVLEN 5956 (wmi_csa_offload_enable_cmd_fixed_param)); 5957 cmd->vdev_id = vdev_id; 5958 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 5959 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 5960 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5961 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 5962 wmi_err("Failed to send CSA offload enable command"); 5963 wmi_buf_free(buf); 5964 return QDF_STATUS_E_FAILURE; 5965 } 5966 5967 return 0; 5968 } 5969 5970 #ifdef WLAN_FEATURE_CIF_CFR 5971 /** 5972 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 5973 * @wmi_handle: wmi handle 5974 * @data_len: len of dma cfg req 5975 * @data: dma cfg req 5976 * 5977 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 5978 */ 5979 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 5980 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 5981 { 5982 wmi_buf_t buf; 5983 uint8_t *cmd; 5984 QDF_STATUS ret; 5985 5986 WMITLV_SET_HDR(cfg, 5987 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 5988 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 5989 5990 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 5991 if (!buf) 5992 return QDF_STATUS_E_FAILURE; 5993 5994 cmd = (uint8_t *) wmi_buf_data(buf); 5995 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 5996 wmi_debug("Sending OEM Data Request to target, data len %lu", 5997 sizeof(*cfg)); 5998 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 5999 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6000 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6001 if (QDF_IS_STATUS_ERROR(ret)) { 6002 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6003 wmi_buf_free(buf); 6004 } 6005 6006 return ret; 6007 } 6008 #endif 6009 6010 /** 6011 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6012 * @wmi_handle: wmi handle 6013 * @start_11d_scan: 11d scan start request parameters 6014 * 6015 * This function request FW to start 11d scan. 6016 * 6017 * Return: QDF status 6018 */ 6019 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6020 struct reg_start_11d_scan_req *start_11d_scan) 6021 { 6022 wmi_11d_scan_start_cmd_fixed_param *cmd; 6023 int32_t len; 6024 wmi_buf_t buf; 6025 int ret; 6026 6027 len = sizeof(*cmd); 6028 buf = wmi_buf_alloc(wmi_handle, len); 6029 if (!buf) 6030 return QDF_STATUS_E_NOMEM; 6031 6032 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6033 6034 WMITLV_SET_HDR(&cmd->tlv_header, 6035 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6036 WMITLV_GET_STRUCT_TLVLEN 6037 (wmi_11d_scan_start_cmd_fixed_param)); 6038 6039 cmd->vdev_id = start_11d_scan->vdev_id; 6040 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6041 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6042 6043 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6044 6045 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 6046 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6047 WMI_11D_SCAN_START_CMDID); 6048 if (ret) { 6049 wmi_err("Failed to send start 11d scan wmi cmd"); 6050 wmi_buf_free(buf); 6051 return QDF_STATUS_E_FAILURE; 6052 } 6053 6054 return QDF_STATUS_SUCCESS; 6055 } 6056 6057 /** 6058 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 6059 * @wmi_handle: wmi handle 6060 * @start_11d_scan: 11d scan stop request parameters 6061 * 6062 * This function request FW to stop 11d scan. 6063 * 6064 * Return: QDF status 6065 */ 6066 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6067 struct reg_stop_11d_scan_req *stop_11d_scan) 6068 { 6069 wmi_11d_scan_stop_cmd_fixed_param *cmd; 6070 int32_t len; 6071 wmi_buf_t buf; 6072 int ret; 6073 6074 len = sizeof(*cmd); 6075 buf = wmi_buf_alloc(wmi_handle, len); 6076 if (!buf) 6077 return QDF_STATUS_E_NOMEM; 6078 6079 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 6080 6081 WMITLV_SET_HDR(&cmd->tlv_header, 6082 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 6083 WMITLV_GET_STRUCT_TLVLEN 6084 (wmi_11d_scan_stop_cmd_fixed_param)); 6085 6086 cmd->vdev_id = stop_11d_scan->vdev_id; 6087 6088 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 6089 6090 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 6091 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6092 WMI_11D_SCAN_STOP_CMDID); 6093 if (ret) { 6094 wmi_err("Failed to send stop 11d scan wmi cmd"); 6095 wmi_buf_free(buf); 6096 return QDF_STATUS_E_FAILURE; 6097 } 6098 6099 return QDF_STATUS_SUCCESS; 6100 } 6101 6102 /** 6103 * send_start_oem_data_cmd_tlv() - start OEM data request to target 6104 * @wmi_handle: wmi handle 6105 * @data_len: the length of @data 6106 * @data: the pointer to data buf 6107 * 6108 * Return: CDF status 6109 */ 6110 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 6111 uint32_t data_len, 6112 uint8_t *data) 6113 { 6114 wmi_buf_t buf; 6115 uint8_t *cmd; 6116 QDF_STATUS ret; 6117 6118 buf = wmi_buf_alloc(wmi_handle, 6119 (data_len + WMI_TLV_HDR_SIZE)); 6120 if (!buf) 6121 return QDF_STATUS_E_FAILURE; 6122 6123 cmd = (uint8_t *) wmi_buf_data(buf); 6124 6125 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 6126 cmd += WMI_TLV_HDR_SIZE; 6127 qdf_mem_copy(cmd, data, 6128 data_len); 6129 6130 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 6131 6132 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 6133 ret = wmi_unified_cmd_send(wmi_handle, buf, 6134 (data_len + 6135 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 6136 6137 if (QDF_IS_STATUS_ERROR(ret)) { 6138 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 6139 wmi_buf_free(buf); 6140 } 6141 6142 return ret; 6143 } 6144 6145 #ifdef FEATURE_OEM_DATA 6146 /** 6147 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 6148 * @wmi_handle: wmi handle 6149 * @oem_data: the pointer to oem data 6150 * 6151 * Return: QDF status 6152 */ 6153 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 6154 struct oem_data *oem_data) 6155 { 6156 QDF_STATUS ret; 6157 wmi_oem_data_cmd_fixed_param *cmd; 6158 struct wmi_ops *ops; 6159 wmi_buf_t buf; 6160 uint16_t len = sizeof(*cmd); 6161 uint16_t oem_data_len_aligned; 6162 uint8_t *buf_ptr; 6163 uint32_t pdev_id; 6164 6165 if (!oem_data || !oem_data->data) { 6166 wmi_err_rl("oem data is not valid"); 6167 return QDF_STATUS_E_FAILURE; 6168 } 6169 6170 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 6171 if (oem_data_len_aligned < oem_data->data_len) { 6172 wmi_err_rl("integer overflow while rounding up data_len"); 6173 return QDF_STATUS_E_FAILURE; 6174 } 6175 6176 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 6177 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 6178 return QDF_STATUS_E_FAILURE; 6179 } 6180 6181 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 6182 buf = wmi_buf_alloc(wmi_handle, len); 6183 if (!buf) 6184 return QDF_STATUS_E_NOMEM; 6185 6186 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6187 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 6188 WMITLV_SET_HDR(&cmd->tlv_header, 6189 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 6190 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 6191 6192 pdev_id = oem_data->pdev_id; 6193 if (oem_data->pdev_vdev_flag) { 6194 ops = wmi_handle->ops; 6195 if (oem_data->is_host_pdev_id) 6196 pdev_id = 6197 ops->convert_host_pdev_id_to_target(wmi_handle, 6198 pdev_id); 6199 else 6200 pdev_id = 6201 ops->convert_pdev_id_host_to_target(wmi_handle, 6202 pdev_id); 6203 } 6204 6205 cmd->vdev_id = oem_data->vdev_id; 6206 cmd->data_len = oem_data->data_len; 6207 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 6208 cmd->pdev_id = pdev_id; 6209 6210 buf_ptr += sizeof(*cmd); 6211 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 6212 buf_ptr += WMI_TLV_HDR_SIZE; 6213 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 6214 6215 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 6216 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 6217 if (QDF_IS_STATUS_ERROR(ret)) { 6218 wmi_err_rl("Failed with ret = %d", ret); 6219 wmi_buf_free(buf); 6220 } 6221 6222 return ret; 6223 } 6224 #endif 6225 6226 /** 6227 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 6228 * @wmi_handle: wmi handle 6229 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 6230 * 6231 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 6232 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 6233 * to firmware based on phyerr filtering 6234 * offload status. 6235 * 6236 * Return: 1 success, 0 failure 6237 */ 6238 static QDF_STATUS 6239 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 6240 bool dfs_phyerr_filter_offload) 6241 { 6242 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 6243 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 6244 wmi_buf_t buf; 6245 uint16_t len; 6246 QDF_STATUS ret; 6247 6248 6249 if (false == dfs_phyerr_filter_offload) { 6250 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 6251 len = sizeof(*disable_phyerr_offload_cmd); 6252 buf = wmi_buf_alloc(wmi_handle, len); 6253 if (!buf) 6254 return 0; 6255 6256 disable_phyerr_offload_cmd = 6257 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 6258 wmi_buf_data(buf); 6259 6260 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 6261 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 6262 WMITLV_GET_STRUCT_TLVLEN 6263 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 6264 6265 /* 6266 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 6267 * to the firmware to disable the phyerror 6268 * filtering offload. 6269 */ 6270 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 6271 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6272 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 6273 if (QDF_IS_STATUS_ERROR(ret)) { 6274 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 6275 ret); 6276 wmi_buf_free(buf); 6277 return QDF_STATUS_E_FAILURE; 6278 } 6279 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 6280 } else { 6281 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 6282 6283 len = sizeof(*enable_phyerr_offload_cmd); 6284 buf = wmi_buf_alloc(wmi_handle, len); 6285 if (!buf) 6286 return QDF_STATUS_E_FAILURE; 6287 6288 enable_phyerr_offload_cmd = 6289 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 6290 wmi_buf_data(buf); 6291 6292 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 6293 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 6294 WMITLV_GET_STRUCT_TLVLEN 6295 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 6296 6297 /* 6298 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 6299 * to the firmware to enable the phyerror 6300 * filtering offload. 6301 */ 6302 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 6303 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6304 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 6305 6306 if (QDF_IS_STATUS_ERROR(ret)) { 6307 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 6308 wmi_buf_free(buf); 6309 return QDF_STATUS_E_FAILURE; 6310 } 6311 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 6312 } 6313 6314 return QDF_STATUS_SUCCESS; 6315 } 6316 6317 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 6318 /** 6319 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 6320 * @wmi_handle: wmi handle 6321 * @pktlog_event: pktlog event 6322 * @cmd_id: pktlog cmd id 6323 * @user_triggered: user triggered input for PKTLOG enable mode 6324 * 6325 * Return: CDF status 6326 */ 6327 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 6328 WMI_PKTLOG_EVENT pktlog_event, 6329 WMI_CMD_ID cmd_id, uint8_t user_triggered) 6330 { 6331 WMI_PKTLOG_EVENT PKTLOG_EVENT; 6332 WMI_CMD_ID CMD_ID; 6333 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 6334 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 6335 int len = 0; 6336 wmi_buf_t buf; 6337 int32_t idx, max_idx; 6338 6339 PKTLOG_EVENT = pktlog_event; 6340 CMD_ID = cmd_id; 6341 6342 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 6343 switch (CMD_ID) { 6344 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 6345 len = sizeof(*cmd); 6346 buf = wmi_buf_alloc(wmi_handle, len); 6347 if (!buf) 6348 return QDF_STATUS_E_NOMEM; 6349 6350 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 6351 wmi_buf_data(buf); 6352 WMITLV_SET_HDR(&cmd->tlv_header, 6353 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 6354 WMITLV_GET_STRUCT_TLVLEN 6355 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 6356 cmd->evlist = 0; 6357 for (idx = 0; idx < max_idx; idx++) { 6358 if (PKTLOG_EVENT & (1 << idx)) 6359 cmd->evlist |= pktlog_event_tlv[idx]; 6360 } 6361 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 6362 : WMI_PKTLOG_ENABLE_AUTO; 6363 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6364 wmi_handle, 6365 WMI_HOST_PDEV_ID_SOC); 6366 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 6367 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6368 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 6369 wmi_err("Failed to send pktlog enable cmdid"); 6370 goto wmi_send_failed; 6371 } 6372 break; 6373 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 6374 len = sizeof(*disable_cmd); 6375 buf = wmi_buf_alloc(wmi_handle, len); 6376 if (!buf) 6377 return QDF_STATUS_E_NOMEM; 6378 6379 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 6380 wmi_buf_data(buf); 6381 WMITLV_SET_HDR(&disable_cmd->tlv_header, 6382 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 6383 WMITLV_GET_STRUCT_TLVLEN 6384 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 6385 disable_cmd->pdev_id = 6386 wmi_handle->ops->convert_pdev_id_host_to_target( 6387 wmi_handle, 6388 WMI_HOST_PDEV_ID_SOC); 6389 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 6390 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6391 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 6392 wmi_err("failed to send pktlog disable cmdid"); 6393 goto wmi_send_failed; 6394 } 6395 break; 6396 default: 6397 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 6398 break; 6399 } 6400 6401 return QDF_STATUS_SUCCESS; 6402 6403 wmi_send_failed: 6404 wmi_buf_free(buf); 6405 return QDF_STATUS_E_FAILURE; 6406 } 6407 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 6408 6409 /** 6410 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 6411 * @wmi_handle: wmi handle 6412 * @preq: stats ext params 6413 * 6414 * Return: CDF status 6415 */ 6416 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 6417 struct stats_ext_params *preq) 6418 { 6419 QDF_STATUS ret; 6420 wmi_req_stats_ext_cmd_fixed_param *cmd; 6421 wmi_buf_t buf; 6422 size_t len; 6423 uint8_t *buf_ptr; 6424 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 6425 6426 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 6427 sizeof(*cmd))) { 6428 wmi_err("Data length=%d is greater than max wmi msg size", 6429 preq->request_data_len); 6430 return QDF_STATUS_E_FAILURE; 6431 } 6432 6433 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 6434 6435 buf = wmi_buf_alloc(wmi_handle, len); 6436 if (!buf) 6437 return QDF_STATUS_E_NOMEM; 6438 6439 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6440 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 6441 6442 WMITLV_SET_HDR(&cmd->tlv_header, 6443 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 6444 WMITLV_GET_STRUCT_TLVLEN 6445 (wmi_req_stats_ext_cmd_fixed_param)); 6446 cmd->vdev_id = preq->vdev_id; 6447 cmd->data_len = preq->request_data_len; 6448 6449 wmi_debug("The data len value is %u and vdev id set is %u", 6450 preq->request_data_len, preq->vdev_id); 6451 6452 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 6453 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 6454 6455 buf_ptr += WMI_TLV_HDR_SIZE; 6456 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 6457 6458 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 6459 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6460 WMI_REQUEST_STATS_EXT_CMDID); 6461 if (QDF_IS_STATUS_ERROR(ret)) { 6462 wmi_err("Failed to send notify cmd ret = %d", ret); 6463 wmi_buf_free(buf); 6464 } 6465 6466 return ret; 6467 } 6468 6469 /** 6470 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 6471 * @wmi_handle: wmi handle 6472 * @params: DHCP server offload info 6473 * 6474 * Return: QDF_STATUS_SUCCESS for success or error code 6475 */ 6476 static QDF_STATUS 6477 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 6478 struct dhcp_offload_info_params *params) 6479 { 6480 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 6481 wmi_buf_t buf; 6482 QDF_STATUS status; 6483 6484 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6485 if (!buf) 6486 return QDF_STATUS_E_NOMEM; 6487 6488 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 6489 6490 WMITLV_SET_HDR(&cmd->tlv_header, 6491 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 6492 WMITLV_GET_STRUCT_TLVLEN 6493 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 6494 cmd->vdev_id = params->vdev_id; 6495 cmd->enable = params->dhcp_offload_enabled; 6496 cmd->num_client = params->dhcp_client_num; 6497 cmd->srv_ipv4 = params->dhcp_srv_addr; 6498 cmd->start_lsb = 0; 6499 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 6500 status = wmi_unified_cmd_send(wmi_handle, buf, 6501 sizeof(*cmd), 6502 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 6503 if (QDF_IS_STATUS_ERROR(status)) { 6504 wmi_err("Failed to send set_dhcp_server_offload cmd"); 6505 wmi_buf_free(buf); 6506 return QDF_STATUS_E_FAILURE; 6507 } 6508 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 6509 6510 return status; 6511 } 6512 6513 /** 6514 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 6515 * @wmi_handle: wmi handle 6516 * @param: pointer to pdev regdomain params 6517 * 6518 * Return: 0 for success or error code 6519 */ 6520 static QDF_STATUS 6521 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 6522 struct pdev_set_regdomain_params *param) 6523 { 6524 wmi_buf_t buf; 6525 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6526 int32_t len = sizeof(*cmd); 6527 6528 buf = wmi_buf_alloc(wmi_handle, len); 6529 if (!buf) 6530 return QDF_STATUS_E_NOMEM; 6531 6532 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6533 WMITLV_SET_HDR(&cmd->tlv_header, 6534 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6535 WMITLV_GET_STRUCT_TLVLEN 6536 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6537 6538 cmd->reg_domain = param->currentRDinuse; 6539 cmd->reg_domain_2G = param->currentRD2G; 6540 cmd->reg_domain_5G = param->currentRD5G; 6541 cmd->conformance_test_limit_2G = param->ctl_2G; 6542 cmd->conformance_test_limit_5G = param->ctl_5G; 6543 cmd->dfs_domain = param->dfsDomain; 6544 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6545 wmi_handle, 6546 param->pdev_id); 6547 6548 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6549 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6550 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6551 wmi_err("Failed to send pdev set regdomain command"); 6552 wmi_buf_free(buf); 6553 return QDF_STATUS_E_FAILURE; 6554 } 6555 6556 return QDF_STATUS_SUCCESS; 6557 } 6558 6559 /** 6560 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 6561 * @wmi_handle: wmi handle 6562 * @reg_dmn: reg domain 6563 * @regdmn2G: 2G reg domain 6564 * @regdmn5G: 5G reg domain 6565 * @ctl2G: 2G test limit 6566 * @ctl5G: 5G test limit 6567 * 6568 * Return: none 6569 */ 6570 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 6571 uint32_t reg_dmn, uint16_t regdmn2G, 6572 uint16_t regdmn5G, uint8_t ctl2G, 6573 uint8_t ctl5G) 6574 { 6575 wmi_buf_t buf; 6576 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6577 int32_t len = sizeof(*cmd); 6578 6579 6580 buf = wmi_buf_alloc(wmi_handle, len); 6581 if (!buf) 6582 return QDF_STATUS_E_NOMEM; 6583 6584 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6585 WMITLV_SET_HDR(&cmd->tlv_header, 6586 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6587 WMITLV_GET_STRUCT_TLVLEN 6588 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6589 cmd->reg_domain = reg_dmn; 6590 cmd->reg_domain_2G = regdmn2G; 6591 cmd->reg_domain_5G = regdmn5G; 6592 cmd->conformance_test_limit_2G = ctl2G; 6593 cmd->conformance_test_limit_5G = ctl5G; 6594 6595 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 6596 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 6597 cmd->conformance_test_limit_2G, 6598 cmd->conformance_test_limit_5G); 6599 6600 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6601 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6602 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6603 wmi_err("Failed to send pdev set regdomain command"); 6604 wmi_buf_free(buf); 6605 return QDF_STATUS_E_FAILURE; 6606 } 6607 6608 return QDF_STATUS_SUCCESS; 6609 } 6610 6611 /** 6612 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6613 * @param: param sent from the host side 6614 * @cmd: param to be sent to the fw side 6615 */ 6616 static inline void copy_custom_aggr_bitmap( 6617 struct set_custom_aggr_size_params *param, 6618 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6619 { 6620 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6621 param->ac); 6622 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6623 param->aggr_type); 6624 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6625 param->tx_aggr_size_disable); 6626 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6627 param->rx_aggr_size_disable); 6628 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6629 param->tx_ac_enable); 6630 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 6631 param->aggr_ba_enable); 6632 } 6633 6634 /** 6635 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6636 * @wmi_handle: wmi handle 6637 * @param: pointer to hold custom aggr size params 6638 * 6639 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6640 */ 6641 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6642 wmi_unified_t wmi_handle, 6643 struct set_custom_aggr_size_params *param) 6644 { 6645 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6646 wmi_buf_t buf; 6647 int32_t len = sizeof(*cmd); 6648 6649 buf = wmi_buf_alloc(wmi_handle, len); 6650 if (!buf) 6651 return QDF_STATUS_E_FAILURE; 6652 6653 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 6654 wmi_buf_data(buf); 6655 WMITLV_SET_HDR(&cmd->tlv_header, 6656 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 6657 WMITLV_GET_STRUCT_TLVLEN( 6658 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 6659 cmd->vdev_id = param->vdev_id; 6660 cmd->tx_aggr_size = param->tx_aggr_size; 6661 cmd->rx_aggr_size = param->rx_aggr_size; 6662 copy_custom_aggr_bitmap(param, cmd); 6663 6664 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 6665 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 6666 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 6667 "tx_ac_enable=0x%X", 6668 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 6669 param->ac, param->aggr_type, param->tx_aggr_size_disable, 6670 param->rx_aggr_size_disable, param->tx_ac_enable); 6671 6672 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 6673 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6674 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 6675 wmi_err("Setting custom aggregation size failed"); 6676 wmi_buf_free(buf); 6677 return QDF_STATUS_E_FAILURE; 6678 } 6679 6680 return QDF_STATUS_SUCCESS; 6681 } 6682 6683 /** 6684 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 6685 * @param wmi_handle : handle to WMI. 6686 * @param param : pointer to tx antenna param 6687 * 6688 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6689 */ 6690 6691 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6692 struct set_qdepth_thresh_params *param) 6693 { 6694 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 6695 wmi_msduq_qdepth_thresh_update *cmd_update; 6696 wmi_buf_t buf; 6697 int32_t len = 0; 6698 int i; 6699 uint8_t *buf_ptr; 6700 QDF_STATUS ret; 6701 6702 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 6703 wmi_err("Invalid Update Count!"); 6704 return QDF_STATUS_E_INVAL; 6705 } 6706 6707 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 6708 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 6709 param->num_of_msduq_updates); 6710 buf = wmi_buf_alloc(wmi_handle, len); 6711 6712 if (!buf) 6713 return QDF_STATUS_E_NOMEM; 6714 6715 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6716 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 6717 buf_ptr; 6718 6719 WMITLV_SET_HDR(&cmd->tlv_header, 6720 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 6721 , WMITLV_GET_STRUCT_TLVLEN( 6722 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 6723 6724 cmd->pdev_id = 6725 wmi_handle->ops->convert_pdev_id_host_to_target( 6726 wmi_handle, 6727 param->pdev_id); 6728 cmd->vdev_id = param->vdev_id; 6729 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 6730 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 6731 6732 buf_ptr += sizeof( 6733 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 6734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6735 param->num_of_msduq_updates * 6736 sizeof(wmi_msduq_qdepth_thresh_update)); 6737 buf_ptr += WMI_TLV_HDR_SIZE; 6738 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 6739 6740 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 6741 WMITLV_SET_HDR(&cmd_update->tlv_header, 6742 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 6743 WMITLV_GET_STRUCT_TLVLEN( 6744 wmi_msduq_qdepth_thresh_update)); 6745 cmd_update->tid_num = param->update_params[i].tid_num; 6746 cmd_update->msduq_update_mask = 6747 param->update_params[i].msduq_update_mask; 6748 cmd_update->qdepth_thresh_value = 6749 param->update_params[i].qdepth_thresh_value; 6750 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 6751 "mac_addr_upper4=%X, mac_addr_lower2:%X," 6752 " update mask=0x%X thresh val=0x%X", 6753 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 6754 cmd->peer_mac_address.mac_addr31to0, 6755 cmd->peer_mac_address.mac_addr47to32, 6756 cmd_update->msduq_update_mask, 6757 cmd_update->qdepth_thresh_value); 6758 cmd_update++; 6759 } 6760 6761 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 6762 cmd->vdev_id, 0); 6763 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6764 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 6765 6766 if (ret != 0) { 6767 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 6768 wmi_buf_free(buf); 6769 } 6770 6771 return ret; 6772 } 6773 6774 /** 6775 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 6776 * @wmi_handle: wmi handle 6777 * @param: pointer to hold vap dscp tid map param 6778 * 6779 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6780 */ 6781 static QDF_STATUS 6782 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 6783 struct vap_dscp_tid_map_params *param) 6784 { 6785 wmi_buf_t buf; 6786 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 6787 int32_t len = sizeof(*cmd); 6788 6789 buf = wmi_buf_alloc(wmi_handle, len); 6790 if (!buf) 6791 return QDF_STATUS_E_FAILURE; 6792 6793 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 6794 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 6795 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 6796 6797 cmd->vdev_id = param->vdev_id; 6798 cmd->enable_override = 0; 6799 6800 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 6801 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 6802 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6803 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 6804 wmi_err("Failed to set dscp cmd"); 6805 wmi_buf_free(buf); 6806 return QDF_STATUS_E_FAILURE; 6807 } 6808 6809 return QDF_STATUS_SUCCESS; 6810 } 6811 6812 /** 6813 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 6814 * @wmi_handle: wmi handle 6815 * @param: pointer to hold fwtest param 6816 * 6817 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6818 */ 6819 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 6820 struct set_fwtest_params *param) 6821 { 6822 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6823 wmi_buf_t buf; 6824 int32_t len = sizeof(*cmd); 6825 6826 buf = wmi_buf_alloc(wmi_handle, len); 6827 6828 if (!buf) 6829 return QDF_STATUS_E_FAILURE; 6830 6831 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 6832 WMITLV_SET_HDR(&cmd->tlv_header, 6833 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6834 WMITLV_GET_STRUCT_TLVLEN( 6835 wmi_fwtest_set_param_cmd_fixed_param)); 6836 cmd->param_id = param->arg; 6837 cmd->param_value = param->value; 6838 6839 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6840 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 6841 wmi_err("Setting FW test param failed"); 6842 wmi_buf_free(buf); 6843 return QDF_STATUS_E_FAILURE; 6844 } 6845 6846 return QDF_STATUS_SUCCESS; 6847 } 6848 6849 /** 6850 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 6851 * 6852 * @param wmi_handle : handle to WMI. 6853 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6854 */ 6855 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 6856 { 6857 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 6858 wmi_buf_t buf; 6859 QDF_STATUS ret; 6860 int32_t len; 6861 6862 len = sizeof(*cmd); 6863 6864 buf = wmi_buf_alloc(wmi_handle, len); 6865 if (!buf) 6866 return QDF_STATUS_E_FAILURE; 6867 6868 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 6869 WMITLV_SET_HDR(&cmd->tlv_header, 6870 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 6871 WMITLV_GET_STRUCT_TLVLEN( 6872 wmi_pdev_dfs_disable_cmd_fixed_param)); 6873 /* Filling it with WMI_PDEV_ID_SOC for now */ 6874 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6875 wmi_handle, 6876 WMI_HOST_PDEV_ID_SOC); 6877 6878 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 6879 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6880 WMI_PDEV_DFS_DISABLE_CMDID); 6881 6882 if (ret != 0) { 6883 wmi_err("Sending PDEV DFS disable cmd failed"); 6884 wmi_buf_free(buf); 6885 } 6886 6887 return ret; 6888 } 6889 6890 /** 6891 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 6892 * 6893 * @param wmi_handle : handle to WMI. 6894 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6895 */ 6896 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 6897 { 6898 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 6899 wmi_buf_t buf; 6900 QDF_STATUS ret; 6901 int32_t len; 6902 6903 len = sizeof(*cmd); 6904 6905 buf = wmi_buf_alloc(wmi_handle, len); 6906 if (!buf) 6907 return QDF_STATUS_E_FAILURE; 6908 6909 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 6910 WMITLV_SET_HDR(&cmd->tlv_header, 6911 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 6912 WMITLV_GET_STRUCT_TLVLEN( 6913 wmi_pdev_dfs_enable_cmd_fixed_param)); 6914 /* Reserved for future use */ 6915 cmd->reserved0 = 0; 6916 6917 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 6918 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6919 WMI_PDEV_DFS_ENABLE_CMDID); 6920 6921 if (ret != 0) { 6922 wmi_err("Sending PDEV DFS enable cmd failed"); 6923 wmi_buf_free(buf); 6924 } 6925 6926 return ret; 6927 } 6928 6929 /** 6930 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 6931 * to fw 6932 * @wmi_handle: wmi handle 6933 * @param: pointer to hold periodic chan stats param 6934 * 6935 * Return: 0 for success or error code 6936 */ 6937 static QDF_STATUS 6938 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 6939 struct periodic_chan_stats_params *param) 6940 { 6941 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 6942 wmi_buf_t buf; 6943 QDF_STATUS ret; 6944 int32_t len; 6945 6946 len = sizeof(*cmd); 6947 6948 buf = wmi_buf_alloc(wmi_handle, len); 6949 if (!buf) 6950 return QDF_STATUS_E_FAILURE; 6951 6952 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 6953 wmi_buf_data(buf); 6954 WMITLV_SET_HDR(&cmd->tlv_header, 6955 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 6956 WMITLV_GET_STRUCT_TLVLEN( 6957 wmi_set_periodic_channel_stats_config_fixed_param)); 6958 cmd->enable = param->enable; 6959 cmd->stats_period = param->stats_period; 6960 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6961 wmi_handle, 6962 param->pdev_id); 6963 6964 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 6965 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6966 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 6967 6968 if (ret != 0) { 6969 wmi_err("Sending periodic chan stats config failed"); 6970 wmi_buf_free(buf); 6971 } 6972 6973 return ret; 6974 } 6975 6976 #ifdef WLAN_IOT_SIM_SUPPORT 6977 /** 6978 * send_simulation_test_cmd_tlv() - send simulation test command to fw 6979 * 6980 * @wmi_handle: wmi handle 6981 * @param: pointer to hold simulation test parameter 6982 * 6983 * Return: 0 for success or error code 6984 */ 6985 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 6986 struct simulation_test_params 6987 *param) 6988 { 6989 wmi_simulation_test_cmd_fixed_param *cmd; 6990 u32 wmi_buf_len; 6991 wmi_buf_t buf; 6992 u8 *buf_ptr; 6993 u32 aligned_len = 0; 6994 6995 wmi_buf_len = sizeof(*cmd); 6996 if (param->buf_len) { 6997 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 6998 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 6999 } 7000 7001 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7002 if (!buf) { 7003 wmi_err("wmi_buf_alloc failed"); 7004 return QDF_STATUS_E_NOMEM; 7005 } 7006 7007 buf_ptr = wmi_buf_data(buf); 7008 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7009 WMITLV_SET_HDR(&cmd->tlv_header, 7010 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7011 WMITLV_GET_STRUCT_TLVLEN( 7012 wmi_simulation_test_cmd_fixed_param)); 7013 cmd->pdev_id = param->pdev_id; 7014 cmd->vdev_id = param->vdev_id; 7015 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7016 cmd->test_cmd_type = param->test_cmd_type; 7017 cmd->test_subcmd_type = param->test_subcmd_type; 7018 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7019 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7020 param->frame_subtype); 7021 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7022 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7023 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7024 cmd->buf_len = param->buf_len; 7025 7026 if (param->buf_len) { 7027 buf_ptr += sizeof(*cmd); 7028 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7029 buf_ptr += WMI_TLV_HDR_SIZE; 7030 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 7031 } 7032 7033 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 7034 WMI_SIMULATION_TEST_CMDID)) { 7035 wmi_err("Failed to send test simulation cmd"); 7036 wmi_buf_free(buf); 7037 return QDF_STATUS_E_FAILURE; 7038 } 7039 7040 return QDF_STATUS_SUCCESS; 7041 } 7042 #endif 7043 7044 #ifdef WLAN_FEATURE_11BE 7045 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 7046 #else 7047 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 7048 #endif 7049 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 7050 { 7051 switch (wmi_width) { 7052 case WMI_CHAN_WIDTH_20: 7053 return CH_WIDTH_20MHZ; 7054 case WMI_CHAN_WIDTH_40: 7055 return CH_WIDTH_40MHZ; 7056 case WMI_CHAN_WIDTH_80: 7057 return CH_WIDTH_80MHZ; 7058 case WMI_CHAN_WIDTH_160: 7059 return CH_WIDTH_160MHZ; 7060 case WMI_CHAN_WIDTH_80P80: 7061 return CH_WIDTH_80P80MHZ; 7062 case WMI_CHAN_WIDTH_5: 7063 return CH_WIDTH_5MHZ; 7064 case WMI_CHAN_WIDTH_10: 7065 return CH_WIDTH_10MHZ; 7066 case WMI_CHAN_WIDTH_320: 7067 return WLAN_PHY_CH_WIDTH_320MHZ; 7068 default: 7069 return CH_WIDTH_INVALID; 7070 } 7071 } 7072 7073 /** 7074 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 7075 * command to fw 7076 * @wmi_handle: wmi handle 7077 * @param: pointer to hold spectral config parameter 7078 * 7079 * Return: 0 for success or error code 7080 */ 7081 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 7082 struct vdev_spectral_configure_params *param) 7083 { 7084 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 7085 wmi_buf_t buf; 7086 QDF_STATUS ret; 7087 int32_t len; 7088 7089 len = sizeof(*cmd); 7090 buf = wmi_buf_alloc(wmi_handle, len); 7091 if (!buf) 7092 return QDF_STATUS_E_FAILURE; 7093 7094 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 7095 WMITLV_SET_HDR(&cmd->tlv_header, 7096 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 7097 WMITLV_GET_STRUCT_TLVLEN( 7098 wmi_vdev_spectral_configure_cmd_fixed_param)); 7099 7100 cmd->vdev_id = param->vdev_id; 7101 cmd->spectral_scan_count = param->count; 7102 cmd->spectral_scan_period = param->period; 7103 cmd->spectral_scan_priority = param->spectral_pri; 7104 cmd->spectral_scan_fft_size = param->fft_size; 7105 cmd->spectral_scan_gc_ena = param->gc_enable; 7106 cmd->spectral_scan_restart_ena = param->restart_enable; 7107 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 7108 cmd->spectral_scan_init_delay = param->init_delay; 7109 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 7110 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 7111 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 7112 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 7113 cmd->spectral_scan_rssi_thr = param->rssi_thr; 7114 cmd->spectral_scan_pwr_format = param->pwr_format; 7115 cmd->spectral_scan_rpt_mode = param->rpt_mode; 7116 cmd->spectral_scan_bin_scale = param->bin_scale; 7117 cmd->spectral_scan_dBm_adj = param->dbm_adj; 7118 cmd->spectral_scan_chn_mask = param->chn_mask; 7119 cmd->spectral_scan_mode = param->mode; 7120 cmd->spectral_scan_center_freq1 = param->center_freq1; 7121 cmd->spectral_scan_center_freq2 = param->center_freq2; 7122 cmd->spectral_scan_chan_width = param->chan_width; 7123 /* Not used, fill with zeros */ 7124 cmd->spectral_scan_chan_freq = 0; 7125 7126 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 7127 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7128 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 7129 7130 if (ret != 0) { 7131 wmi_err("Sending set quiet cmd failed"); 7132 wmi_buf_free(buf); 7133 } 7134 7135 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 7136 wmi_debug("vdev_id: %u spectral_scan_count: %u", 7137 param->vdev_id, param->count); 7138 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 7139 param->period, param->spectral_pri); 7140 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 7141 param->fft_size, param->gc_enable); 7142 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 7143 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 7144 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 7145 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 7146 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 7147 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 7148 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 7149 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 7150 param->rssi_thr, param->pwr_format); 7151 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 7152 param->rpt_mode, param->bin_scale); 7153 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 7154 param->dbm_adj, param->chn_mask); 7155 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 7156 param->mode, param->center_freq1); 7157 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 7158 param->center_freq2, param->chan_freq); 7159 wmi_debug("spectral_scan_chan_width: %u Status: %d", 7160 param->chan_width, ret); 7161 7162 return ret; 7163 } 7164 7165 /** 7166 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 7167 * command to fw 7168 * @wmi_handle: wmi handle 7169 * @param: pointer to hold spectral enable parameter 7170 * 7171 * Return: 0 for success or error code 7172 */ 7173 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 7174 struct vdev_spectral_enable_params *param) 7175 { 7176 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 7177 wmi_buf_t buf; 7178 QDF_STATUS ret; 7179 int32_t len; 7180 7181 len = sizeof(*cmd); 7182 buf = wmi_buf_alloc(wmi_handle, len); 7183 if (!buf) 7184 return QDF_STATUS_E_FAILURE; 7185 7186 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 7187 WMITLV_SET_HDR(&cmd->tlv_header, 7188 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 7189 WMITLV_GET_STRUCT_TLVLEN( 7190 wmi_vdev_spectral_enable_cmd_fixed_param)); 7191 7192 cmd->vdev_id = param->vdev_id; 7193 7194 if (param->active_valid) { 7195 cmd->trigger_cmd = param->active ? 1 : 2; 7196 /* 1: Trigger, 2: Clear Trigger */ 7197 } else { 7198 cmd->trigger_cmd = 0; /* 0: Ignore */ 7199 } 7200 7201 if (param->enabled_valid) { 7202 cmd->enable_cmd = param->enabled ? 1 : 2; 7203 /* 1: Enable 2: Disable */ 7204 } else { 7205 cmd->enable_cmd = 0; /* 0: Ignore */ 7206 } 7207 cmd->spectral_scan_mode = param->mode; 7208 7209 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 7210 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 7211 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 7212 7213 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 7214 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7215 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 7216 7217 if (ret != 0) { 7218 wmi_err("Sending scan enable CMD failed"); 7219 wmi_buf_free(buf); 7220 } 7221 7222 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 7223 ret); 7224 7225 return ret; 7226 } 7227 7228 #ifdef WLAN_CONV_SPECTRAL_ENABLE 7229 static QDF_STATUS 7230 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 7231 wmi_unified_t wmi_handle, 7232 uint8_t *event, struct spectral_startscan_resp_params *param) 7233 { 7234 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7235 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 7236 7237 if (!wmi_handle) { 7238 wmi_err("WMI handle is null"); 7239 return QDF_STATUS_E_INVAL; 7240 } 7241 7242 if (!event) { 7243 wmi_err("WMI event is null"); 7244 return QDF_STATUS_E_INVAL; 7245 } 7246 7247 if (!param) { 7248 wmi_err("Spectral startscan response params is null"); 7249 return QDF_STATUS_E_INVAL; 7250 } 7251 7252 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7253 if (!param_buf) 7254 return QDF_STATUS_E_INVAL; 7255 7256 ev = param_buf->fixed_param; 7257 if (!ev) 7258 return QDF_STATUS_E_INVAL; 7259 7260 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 7261 wmi_handle, 7262 ev->pdev_id); 7263 param->smode = ev->spectral_scan_mode; 7264 param->num_fft_bin_index = param_buf->num_fft_bin_index; 7265 wmi_debug("pdev id %u scan mode %u num_fft_bin_index %u", 7266 param->pdev_id, param->smode, param->num_fft_bin_index); 7267 7268 return QDF_STATUS_SUCCESS; 7269 } 7270 7271 static QDF_STATUS 7272 extract_pdev_sscan_fft_bin_index_tlv( 7273 wmi_unified_t wmi_handle, uint8_t *event, 7274 struct spectral_fft_bin_markers_160_165mhz *param) 7275 { 7276 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7277 wmi_pdev_sscan_fft_bin_index *ev; 7278 7279 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7280 if (!param_buf) 7281 return QDF_STATUS_E_INVAL; 7282 7283 ev = param_buf->fft_bin_index; 7284 if (!ev) 7285 return QDF_STATUS_E_INVAL; 7286 7287 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 7288 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 7289 param->start_pri80 + 1; 7290 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 7291 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 7292 param->start_sec80 + 1; 7293 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 7294 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 7295 param->start_5mhz + 1; 7296 param->is_valid = true; 7297 7298 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 7299 param->start_pri80, param->num_pri80, 7300 param->start_sec80, param->num_sec80, 7301 param->start_5mhz, param->num_5mhz); 7302 7303 return QDF_STATUS_SUCCESS; 7304 } 7305 7306 #ifdef SPECTRAL_BERYLLIUM 7307 /** 7308 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 7309 * for a spectral scan session 7310 * @wmi_handle: handle to WMI. 7311 * @event: Event buffer 7312 * @chan_info: Spectral session channel information data structure to be filled 7313 * by this API 7314 * 7315 * Return: QDF_STATUS of operation 7316 */ 7317 static QDF_STATUS 7318 extract_pdev_spectral_session_chan_info_tlv( 7319 wmi_unified_t wmi_handle, void *event, 7320 struct spectral_session_chan_info *chan_info) 7321 { 7322 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7323 wmi_pdev_sscan_chan_info *chan_info_tlv; 7324 7325 if (!param_buf) { 7326 wmi_err("param_buf is NULL"); 7327 return QDF_STATUS_E_NULL_VALUE; 7328 } 7329 7330 if (!chan_info) { 7331 wmi_err("chan_info is NULL"); 7332 return QDF_STATUS_E_NULL_VALUE; 7333 } 7334 7335 chan_info_tlv = param_buf->chan_info; 7336 if (!chan_info_tlv) { 7337 wmi_err("chan_info tlv is not present in the event"); 7338 return QDF_STATUS_E_NULL_VALUE; 7339 } 7340 7341 chan_info->operating_pri20_freq = 7342 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 7343 chan_info->operating_cfreq1 = 7344 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 7345 chan_info->operating_cfreq2 = 7346 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 7347 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 7348 chan_info->operating_puncture_20mhz_bitmap = 7349 chan_info_tlv->operating_puncture_20mhz_bitmap; 7350 7351 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 7352 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 7353 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 7354 chan_info->sscan_puncture_20mhz_bitmap = 7355 chan_info_tlv->sscan_puncture_20mhz_bitmap; 7356 7357 return QDF_STATUS_SUCCESS; 7358 } 7359 7360 static QDF_STATUS 7361 extract_pdev_spectral_session_detector_info_tlv( 7362 wmi_unified_t wmi_handle, void *event, 7363 struct spectral_session_det_info *det_info, uint8_t idx) 7364 { 7365 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7366 wmi_pdev_sscan_detector_info *det_info_tlv; 7367 7368 if (!param_buf) { 7369 wmi_err("param_buf is NULL"); 7370 return QDF_STATUS_E_NULL_VALUE; 7371 } 7372 7373 if (!det_info) { 7374 wmi_err("chan_info is NULL"); 7375 return QDF_STATUS_E_NULL_VALUE; 7376 } 7377 7378 if (!param_buf->det_info) { 7379 wmi_err("det_info tlv is not present in the event"); 7380 return QDF_STATUS_E_NULL_VALUE; 7381 } 7382 7383 if (idx >= param_buf->num_det_info) { 7384 wmi_err("det_info index(%u) is greater than or equal to %u", 7385 idx, param_buf->num_det_info); 7386 return QDF_STATUS_E_FAILURE; 7387 } 7388 7389 det_info_tlv = ¶m_buf->det_info[idx]; 7390 7391 det_info->det_id = det_info_tlv->detector_id; 7392 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 7393 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 7394 7395 return QDF_STATUS_SUCCESS; 7396 } 7397 #endif /* SPECTRAL_BERYLLIUM */ 7398 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 7399 7400 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 7401 static inline void 7402 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7403 struct thermal_mitigation_params *param) 7404 { 7405 tt_conf->client_id = param->client_id; 7406 tt_conf->priority = param->priority; 7407 } 7408 #else 7409 static inline void 7410 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7411 struct thermal_mitigation_params *param) 7412 { 7413 } 7414 #endif 7415 7416 /** 7417 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 7418 * @param wmi_handle : handle to WMI. 7419 * @param param : pointer to hold thermal mitigation param 7420 * 7421 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7422 */ 7423 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 7424 wmi_unified_t wmi_handle, 7425 struct thermal_mitigation_params *param) 7426 { 7427 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 7428 wmi_therm_throt_level_config_info *lvl_conf = NULL; 7429 wmi_buf_t buf = NULL; 7430 uint8_t *buf_ptr = NULL; 7431 int error; 7432 int32_t len; 7433 int i; 7434 7435 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 7436 param->num_thermal_conf * 7437 sizeof(wmi_therm_throt_level_config_info); 7438 7439 buf = wmi_buf_alloc(wmi_handle, len); 7440 if (!buf) 7441 return QDF_STATUS_E_NOMEM; 7442 7443 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 7444 7445 /* init fixed params */ 7446 WMITLV_SET_HDR(tt_conf, 7447 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 7448 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 7449 7450 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7451 wmi_handle, 7452 param->pdev_id); 7453 tt_conf->enable = param->enable; 7454 tt_conf->dc = param->dc; 7455 tt_conf->dc_per_event = param->dc_per_event; 7456 tt_conf->therm_throt_levels = param->num_thermal_conf; 7457 wmi_fill_client_id_priority(tt_conf, param); 7458 buf_ptr = (uint8_t *) ++tt_conf; 7459 /* init TLV params */ 7460 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7461 (param->num_thermal_conf * 7462 sizeof(wmi_therm_throt_level_config_info))); 7463 7464 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 7465 for (i = 0; i < param->num_thermal_conf; i++) { 7466 WMITLV_SET_HDR(&lvl_conf->tlv_header, 7467 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 7468 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 7469 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 7470 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 7471 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 7472 lvl_conf->prio = param->levelconf[i].priority; 7473 lvl_conf++; 7474 } 7475 7476 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 7477 error = wmi_unified_cmd_send(wmi_handle, buf, len, 7478 WMI_THERM_THROT_SET_CONF_CMDID); 7479 if (QDF_IS_STATUS_ERROR(error)) { 7480 wmi_buf_free(buf); 7481 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 7482 } 7483 7484 return error; 7485 } 7486 7487 /** 7488 * send_coex_config_cmd_tlv() - send coex config command to fw 7489 * @wmi_handle: wmi handle 7490 * @param: pointer to coex config param 7491 * 7492 * Return: 0 for success or error code 7493 */ 7494 static QDF_STATUS 7495 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 7496 struct coex_config_params *param) 7497 { 7498 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 7499 wmi_buf_t buf; 7500 QDF_STATUS ret; 7501 int32_t len; 7502 7503 len = sizeof(*cmd); 7504 buf = wmi_buf_alloc(wmi_handle, len); 7505 if (!buf) 7506 return QDF_STATUS_E_FAILURE; 7507 7508 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 7509 WMITLV_SET_HDR(&cmd->tlv_header, 7510 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 7511 WMITLV_GET_STRUCT_TLVLEN( 7512 WMI_COEX_CONFIG_CMD_fixed_param)); 7513 7514 cmd->vdev_id = param->vdev_id; 7515 cmd->config_type = param->config_type; 7516 cmd->config_arg1 = param->config_arg1; 7517 cmd->config_arg2 = param->config_arg2; 7518 cmd->config_arg3 = param->config_arg3; 7519 cmd->config_arg4 = param->config_arg4; 7520 cmd->config_arg5 = param->config_arg5; 7521 cmd->config_arg6 = param->config_arg6; 7522 7523 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 7524 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7525 WMI_COEX_CONFIG_CMDID); 7526 7527 if (ret != 0) { 7528 wmi_err("Sending COEX CONFIG CMD failed"); 7529 wmi_buf_free(buf); 7530 } 7531 7532 return ret; 7533 } 7534 7535 #ifdef WLAN_SUPPORT_TWT 7536 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7537 target_resource_config *tgt_res_cfg) 7538 { 7539 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 7540 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 7541 } 7542 #else 7543 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7544 target_resource_config *tgt_res_cfg) 7545 { 7546 resource_cfg->twt_ap_pdev_count = 0; 7547 resource_cfg->twt_ap_sta_count = 0; 7548 } 7549 #endif 7550 7551 #ifdef WLAN_FEATURE_NAN 7552 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 7553 { 7554 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 7555 resource_cfg->host_service_flags, 1); 7556 } 7557 #else 7558 static inline 7559 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 7560 { 7561 } 7562 #endif 7563 7564 static 7565 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 7566 target_resource_config *tgt_res_cfg) 7567 { 7568 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 7569 resource_cfg->num_peers = tgt_res_cfg->num_peers; 7570 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 7571 resource_cfg->num_offload_reorder_buffs = 7572 tgt_res_cfg->num_offload_reorder_buffs; 7573 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 7574 resource_cfg->num_tids = tgt_res_cfg->num_tids; 7575 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 7576 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 7577 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 7578 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 7579 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 7580 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 7581 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 7582 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 7583 resource_cfg->scan_max_pending_req = 7584 tgt_res_cfg->scan_max_pending_req; 7585 resource_cfg->bmiss_offload_max_vdev = 7586 tgt_res_cfg->bmiss_offload_max_vdev; 7587 resource_cfg->roam_offload_max_vdev = 7588 tgt_res_cfg->roam_offload_max_vdev; 7589 resource_cfg->roam_offload_max_ap_profiles = 7590 tgt_res_cfg->roam_offload_max_ap_profiles; 7591 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 7592 resource_cfg->num_mcast_table_elems = 7593 tgt_res_cfg->num_mcast_table_elems; 7594 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 7595 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 7596 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 7597 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 7598 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 7599 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 7600 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 7601 resource_cfg->vow_config = tgt_res_cfg->vow_config; 7602 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 7603 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 7604 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 7605 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 7606 resource_cfg->num_tdls_conn_table_entries = 7607 tgt_res_cfg->num_tdls_conn_table_entries; 7608 resource_cfg->beacon_tx_offload_max_vdev = 7609 tgt_res_cfg->beacon_tx_offload_max_vdev; 7610 resource_cfg->num_multicast_filter_entries = 7611 tgt_res_cfg->num_multicast_filter_entries; 7612 resource_cfg->num_wow_filters = 7613 tgt_res_cfg->num_wow_filters; 7614 resource_cfg->num_keep_alive_pattern = 7615 tgt_res_cfg->num_keep_alive_pattern; 7616 resource_cfg->keep_alive_pattern_size = 7617 tgt_res_cfg->keep_alive_pattern_size; 7618 resource_cfg->max_tdls_concurrent_sleep_sta = 7619 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 7620 resource_cfg->max_tdls_concurrent_buffer_sta = 7621 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 7622 resource_cfg->wmi_send_separate = 7623 tgt_res_cfg->wmi_send_separate; 7624 resource_cfg->num_ocb_vdevs = 7625 tgt_res_cfg->num_ocb_vdevs; 7626 resource_cfg->num_ocb_channels = 7627 tgt_res_cfg->num_ocb_channels; 7628 resource_cfg->num_ocb_schedules = 7629 tgt_res_cfg->num_ocb_schedules; 7630 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 7631 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 7632 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 7633 resource_cfg->max_num_dbs_scan_duty_cycle = 7634 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 7635 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 7636 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 7637 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 7638 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 7639 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 7640 /* Deferred AI: Max rnr neighbors supported in multisoc case 7641 * where in SoC can support 6ghz. During WMI init of a SoC 7642 * currently there is no way to figure if another SOC is plugged in 7643 * and it can support 6Ghz. 7644 */ 7645 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 7646 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 7647 resource_cfg->ema_max_profile_period = 7648 tgt_res_cfg->ema_max_profile_period; 7649 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 7650 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 7651 7652 if (tgt_res_cfg->max_ndp_sessions) 7653 resource_cfg->max_ndp_sessions = 7654 tgt_res_cfg->max_ndp_sessions; 7655 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 7656 7657 if (tgt_res_cfg->atf_config) 7658 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 7659 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 7660 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 7661 resource_cfg->flag1, 1); 7662 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 7663 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 7664 resource_cfg->flag1, 1); 7665 if (tgt_res_cfg->cce_disable) 7666 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 7667 if (tgt_res_cfg->enable_pci_gen) 7668 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 7669 resource_cfg->flag1, 1); 7670 if (tgt_res_cfg->eapol_minrate_set) { 7671 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 7672 resource_cfg->flag1, 1); 7673 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 7674 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 7675 resource_cfg->flag1, 1); 7676 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 7677 resource_cfg->flag1, 7678 tgt_res_cfg->eapol_minrate_ac_set); 7679 } 7680 } 7681 if (tgt_res_cfg->new_htt_msg_format) { 7682 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 7683 resource_cfg->flag1, 1); 7684 } 7685 7686 if (tgt_res_cfg->peer_unmap_conf_support) 7687 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 7688 resource_cfg->flag1, 1); 7689 7690 if (tgt_res_cfg->tstamp64_en) 7691 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 7692 resource_cfg->flag1, 1); 7693 7694 if (tgt_res_cfg->three_way_coex_config_legacy_en) 7695 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 7696 resource_cfg->flag1, 1); 7697 if (tgt_res_cfg->pktcapture_support) 7698 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 7699 resource_cfg->flag1, 1); 7700 7701 /* 7702 * Control padding using config param/ini of iphdr_pad_config 7703 */ 7704 if (tgt_res_cfg->iphdr_pad_config) 7705 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 7706 resource_cfg->flag1, 1); 7707 7708 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 7709 tgt_res_cfg->ipa_disable); 7710 7711 if (tgt_res_cfg->time_sync_ftm) 7712 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 7713 1); 7714 7715 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 7716 resource_cfg->peer_map_unmap_versions = 7717 tgt_res_cfg->peer_map_unmap_version; 7718 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 7719 if (tgt_res_cfg->re_ul_resp) 7720 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 7721 tgt_res_cfg->re_ul_resp); 7722 7723 7724 /* 7725 * Enable ast flow override per peer 7726 */ 7727 resource_cfg->msdu_flow_override_config0 = 0; 7728 WMI_MSDU_FLOW_AST_ENABLE_SET( 7729 resource_cfg->msdu_flow_override_config0, 7730 WMI_CONFIG_MSDU_AST_INDEX_1, 7731 tgt_res_cfg->ast_1_valid_mask_enable); 7732 7733 WMI_MSDU_FLOW_AST_ENABLE_SET( 7734 resource_cfg->msdu_flow_override_config0, 7735 WMI_CONFIG_MSDU_AST_INDEX_2, 7736 tgt_res_cfg->ast_2_valid_mask_enable); 7737 7738 WMI_MSDU_FLOW_AST_ENABLE_SET( 7739 resource_cfg->msdu_flow_override_config0, 7740 WMI_CONFIG_MSDU_AST_INDEX_3, 7741 tgt_res_cfg->ast_3_valid_mask_enable); 7742 7743 /* 7744 * Enable ast flow mask and TID valid mask configurations 7745 */ 7746 resource_cfg->msdu_flow_override_config1 = 0; 7747 7748 /*Enable UDP flow for Ast index 0*/ 7749 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7750 resource_cfg->msdu_flow_override_config1, 7751 WMI_CONFIG_MSDU_AST_INDEX_0, 7752 tgt_res_cfg->ast_0_flow_mask_enable); 7753 7754 /*Enable Non UDP flow for Ast index 1*/ 7755 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7756 resource_cfg->msdu_flow_override_config1, 7757 WMI_CONFIG_MSDU_AST_INDEX_1, 7758 tgt_res_cfg->ast_1_flow_mask_enable); 7759 7760 /*Enable Hi-Priority flow for Ast index 2*/ 7761 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7762 resource_cfg->msdu_flow_override_config1, 7763 WMI_CONFIG_MSDU_AST_INDEX_2, 7764 tgt_res_cfg->ast_2_flow_mask_enable); 7765 7766 /*Enable Low-Priority flow for Ast index 3*/ 7767 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7768 resource_cfg->msdu_flow_override_config1, 7769 WMI_CONFIG_MSDU_AST_INDEX_3, 7770 tgt_res_cfg->ast_3_flow_mask_enable); 7771 7772 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 7773 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 7774 resource_cfg->msdu_flow_override_config1, 7775 tgt_res_cfg->ast_tid_high_mask_enable); 7776 7777 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 7778 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 7779 resource_cfg->msdu_flow_override_config1, 7780 tgt_res_cfg->ast_tid_low_mask_enable); 7781 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 7782 resource_cfg->host_service_flags, 7783 tgt_res_cfg->nan_separate_iface_support); 7784 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 7785 resource_cfg->host_service_flags, 1); 7786 7787 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 7788 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 7789 7790 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 7791 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 7792 resource_cfg->flags2, 1); 7793 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 7794 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 7795 resource_cfg->flags2, 1); 7796 7797 if (tgt_res_cfg->sae_eapol_offload) 7798 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 7799 resource_cfg->host_service_flags, 1); 7800 7801 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 7802 resource_cfg->host_service_flags, 7803 tgt_res_cfg->is_reg_cc_ext_event_supported); 7804 7805 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 7806 resource_cfg->host_service_flags, 7807 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 7808 7809 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 7810 resource_cfg->host_service_flags, 7811 tgt_res_cfg->afc_timer_check_disable); 7812 7813 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 7814 resource_cfg->host_service_flags, 7815 tgt_res_cfg->afc_req_id_check_disable); 7816 7817 wmi_set_nan_channel_support(resource_cfg); 7818 7819 if (tgt_res_cfg->twt_ack_support_cap) 7820 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 7821 resource_cfg->host_service_flags, 1); 7822 7823 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 7824 tgt_res_cfg->target_cap_flags); 7825 } 7826 7827 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 7828 * @wmi_handle: pointer to wmi handle 7829 * @buf_ptr: pointer to current position in init command buffer 7830 * @len: pointer to length. This will be updated with current length of cmd 7831 * @param: point host parameters for init command 7832 * 7833 * Return: Updated pointer of buf_ptr. 7834 */ 7835 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 7836 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 7837 { 7838 uint16_t idx; 7839 7840 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 7841 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 7842 wmi_pdev_band_to_mac *band_to_mac; 7843 7844 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 7845 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 7846 sizeof(wmi_resource_config) + 7847 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 7848 sizeof(wlan_host_memory_chunk))); 7849 7850 WMITLV_SET_HDR(&hw_mode->tlv_header, 7851 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 7852 (WMITLV_GET_STRUCT_TLVLEN 7853 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 7854 7855 hw_mode->hw_mode_index = param->hw_mode_id; 7856 hw_mode->num_band_to_mac = param->num_band_to_mac; 7857 7858 buf_ptr = (uint8_t *) (hw_mode + 1); 7859 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 7860 WMI_TLV_HDR_SIZE); 7861 for (idx = 0; idx < param->num_band_to_mac; idx++) { 7862 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 7863 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 7864 WMITLV_GET_STRUCT_TLVLEN 7865 (wmi_pdev_band_to_mac)); 7866 band_to_mac[idx].pdev_id = 7867 wmi_handle->ops->convert_pdev_id_host_to_target( 7868 wmi_handle, 7869 param->band_to_mac[idx].pdev_id); 7870 band_to_mac[idx].start_freq = 7871 param->band_to_mac[idx].start_freq; 7872 band_to_mac[idx].end_freq = 7873 param->band_to_mac[idx].end_freq; 7874 } 7875 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 7876 (param->num_band_to_mac * 7877 sizeof(wmi_pdev_band_to_mac)) + 7878 WMI_TLV_HDR_SIZE; 7879 7880 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7881 (param->num_band_to_mac * 7882 sizeof(wmi_pdev_band_to_mac))); 7883 } 7884 7885 return buf_ptr; 7886 } 7887 7888 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 7889 wmi_init_cmd_fixed_param *cmd) 7890 { 7891 int num_whitelist; 7892 wmi_abi_version my_vers; 7893 7894 num_whitelist = sizeof(version_whitelist) / 7895 sizeof(wmi_whitelist_version_info); 7896 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 7897 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 7898 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 7899 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 7900 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 7901 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 7902 7903 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 7904 &my_vers, 7905 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 7906 &cmd->host_abi_vers); 7907 7908 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 7909 __func__, 7910 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 7911 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 7912 cmd->host_abi_vers.abi_version_ns_0, 7913 cmd->host_abi_vers.abi_version_ns_1, 7914 cmd->host_abi_vers.abi_version_ns_2, 7915 cmd->host_abi_vers.abi_version_ns_3); 7916 7917 /* Save version sent from host - 7918 * Will be used to check ready event 7919 */ 7920 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 7921 sizeof(wmi_abi_version)); 7922 } 7923 7924 /* 7925 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 7926 * @wmi_handle: Pointer to WMi handle 7927 * @ie_data: Pointer for ie data 7928 * 7929 * This function sends action frame tb ppdu cfg to FW 7930 * 7931 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7932 * 7933 */ 7934 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 7935 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 7936 { 7937 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 7938 wmi_buf_t buf; 7939 uint8_t *buf_ptr; 7940 uint32_t len, frm_len_aligned; 7941 QDF_STATUS ret; 7942 7943 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 7944 /* Allocate memory for the WMI command */ 7945 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 7946 7947 buf = wmi_buf_alloc(wmi_handle, len); 7948 if (!buf) 7949 return QDF_STATUS_E_NOMEM; 7950 7951 buf_ptr = wmi_buf_data(buf); 7952 qdf_mem_zero(buf_ptr, len); 7953 7954 /* Populate the WMI command */ 7955 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 7956 7957 WMITLV_SET_HDR(&cmd->tlv_header, 7958 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 7959 WMITLV_GET_STRUCT_TLVLEN( 7960 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 7961 cmd->enable = cfg_msg->cfg; 7962 cmd->data_len = cfg_msg->frm_len; 7963 7964 buf_ptr += sizeof(*cmd); 7965 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 7966 buf_ptr += WMI_TLV_HDR_SIZE; 7967 7968 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 7969 7970 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7971 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 7972 if (QDF_IS_STATUS_ERROR(ret)) { 7973 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 7974 wmi_buf_free(buf); 7975 } 7976 7977 return ret; 7978 } 7979 7980 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7981 { 7982 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7983 wmi_service_ready_event_fixed_param *ev; 7984 7985 7986 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7987 7988 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7989 if (!ev) 7990 return QDF_STATUS_E_FAILURE; 7991 7992 /*Save fw version from service ready message */ 7993 /*This will be used while sending INIT message */ 7994 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7995 sizeof(wmi_handle->fw_abi_version)); 7996 7997 return QDF_STATUS_SUCCESS; 7998 } 7999 8000 /** 8001 * wmi_unified_save_fw_version_cmd() - save fw version 8002 * @wmi_handle: pointer to wmi handle 8003 * @res_cfg: resource config 8004 * @num_mem_chunks: no of mem chunck 8005 * @mem_chunk: pointer to mem chunck structure 8006 * 8007 * This function sends IE information to firmware 8008 * 8009 * Return: QDF_STATUS_SUCCESS for success otherwise failure 8010 * 8011 */ 8012 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 8013 void *evt_buf) 8014 { 8015 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8016 wmi_ready_event_fixed_param *ev = NULL; 8017 8018 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8019 ev = param_buf->fixed_param; 8020 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 8021 &wmi_handle->final_abi_vers, 8022 &ev->fw_abi_vers)) { 8023 /* 8024 * Error: Our host version and the given firmware version 8025 * are incompatible. 8026 **/ 8027 wmi_debug("Error: Incompatible WMI version." 8028 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 8029 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 8030 abi_version_0), 8031 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 8032 abi_version_0), 8033 wmi_handle->final_abi_vers.abi_version_ns_0, 8034 wmi_handle->final_abi_vers.abi_version_ns_1, 8035 wmi_handle->final_abi_vers.abi_version_ns_2, 8036 wmi_handle->final_abi_vers.abi_version_ns_3, 8037 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 8038 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 8039 ev->fw_abi_vers.abi_version_ns_0, 8040 ev->fw_abi_vers.abi_version_ns_1, 8041 ev->fw_abi_vers.abi_version_ns_2, 8042 ev->fw_abi_vers.abi_version_ns_3); 8043 8044 return QDF_STATUS_E_FAILURE; 8045 } 8046 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 8047 sizeof(wmi_abi_version)); 8048 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8049 sizeof(wmi_abi_version)); 8050 8051 return QDF_STATUS_SUCCESS; 8052 } 8053 8054 /** 8055 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 8056 * @handle: wmi handle 8057 * @event: Event received from FW 8058 * @len: Length of the event 8059 * 8060 * Enables the low frequency events and disables the high frequency 8061 * events. Bit 17 indicates if the event if low/high frequency. 8062 * 1 - high frequency, 0 - low frequency 8063 * 8064 * Return: 0 on successfully enabling/disabling the events 8065 */ 8066 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 8067 uint8_t *event, 8068 uint32_t len) 8069 { 8070 uint32_t num_of_diag_events_logs; 8071 wmi_diag_event_log_config_fixed_param *cmd; 8072 wmi_buf_t buf; 8073 uint8_t *buf_ptr; 8074 uint32_t *cmd_args, *evt_args; 8075 uint32_t buf_len, i; 8076 8077 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 8078 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 8079 8080 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 8081 8082 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 8083 if (!param_buf) { 8084 wmi_err("Invalid log supported event buffer"); 8085 return QDF_STATUS_E_INVAL; 8086 } 8087 wmi_event = param_buf->fixed_param; 8088 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 8089 8090 if (num_of_diag_events_logs > 8091 param_buf->num_diag_events_logs_list) { 8092 wmi_err("message number of events %d is more than tlv hdr content %d", 8093 num_of_diag_events_logs, 8094 param_buf->num_diag_events_logs_list); 8095 return QDF_STATUS_E_INVAL; 8096 } 8097 8098 evt_args = param_buf->diag_events_logs_list; 8099 if (!evt_args) { 8100 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 8101 num_of_diag_events_logs); 8102 return QDF_STATUS_E_INVAL; 8103 } 8104 8105 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 8106 8107 /* Free any previous allocation */ 8108 if (wmi_handle->events_logs_list) { 8109 qdf_mem_free(wmi_handle->events_logs_list); 8110 wmi_handle->events_logs_list = NULL; 8111 } 8112 8113 if (num_of_diag_events_logs > 8114 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 8115 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 8116 QDF_ASSERT(0); 8117 return QDF_STATUS_E_INVAL; 8118 } 8119 /* Store the event list for run time enable/disable */ 8120 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 8121 sizeof(uint32_t)); 8122 if (!wmi_handle->events_logs_list) 8123 return QDF_STATUS_E_NOMEM; 8124 8125 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 8126 8127 /* Prepare the send buffer */ 8128 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8129 (num_of_diag_events_logs * sizeof(uint32_t)); 8130 8131 buf = wmi_buf_alloc(wmi_handle, buf_len); 8132 if (!buf) { 8133 qdf_mem_free(wmi_handle->events_logs_list); 8134 wmi_handle->events_logs_list = NULL; 8135 return QDF_STATUS_E_NOMEM; 8136 } 8137 8138 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8139 buf_ptr = (uint8_t *) cmd; 8140 8141 WMITLV_SET_HDR(&cmd->tlv_header, 8142 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8143 WMITLV_GET_STRUCT_TLVLEN( 8144 wmi_diag_event_log_config_fixed_param)); 8145 8146 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 8147 8148 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8149 8150 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8151 (num_of_diag_events_logs * sizeof(uint32_t))); 8152 8153 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8154 8155 /* Populate the events */ 8156 for (i = 0; i < num_of_diag_events_logs; i++) { 8157 /* Low freq (0) - Enable (1) the event 8158 * High freq (1) - Disable (0) the event 8159 */ 8160 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 8161 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 8162 /* Set the event ID */ 8163 WMI_DIAG_ID_SET(cmd_args[i], 8164 WMI_DIAG_ID_GET(evt_args[i])); 8165 /* Set the type */ 8166 WMI_DIAG_TYPE_SET(cmd_args[i], 8167 WMI_DIAG_TYPE_GET(evt_args[i])); 8168 /* Storing the event/log list in WMI */ 8169 wmi_handle->events_logs_list[i] = evt_args[i]; 8170 } 8171 8172 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8173 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 8174 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8175 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8176 wmi_buf_free(buf); 8177 /* Not clearing events_logs_list, though wmi cmd failed. 8178 * Host can still have this list 8179 */ 8180 return QDF_STATUS_E_INVAL; 8181 } 8182 8183 return 0; 8184 } 8185 8186 /** 8187 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 8188 * @wmi_handle: wmi handle 8189 * @start_log: Start logging related parameters 8190 * 8191 * Send the command to the FW based on which specific logging of diag 8192 * event/log id can be started/stopped 8193 * 8194 * Return: None 8195 */ 8196 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 8197 struct wmi_wifi_start_log *start_log) 8198 { 8199 wmi_diag_event_log_config_fixed_param *cmd; 8200 wmi_buf_t buf; 8201 uint8_t *buf_ptr; 8202 uint32_t len, count, log_level, i; 8203 uint32_t *cmd_args; 8204 uint32_t total_len; 8205 count = 0; 8206 8207 if (!wmi_handle->events_logs_list) { 8208 wmi_debug("Not received event/log list from FW, yet"); 8209 return QDF_STATUS_E_NOMEM; 8210 } 8211 /* total_len stores the number of events where BITS 17 and 18 are set. 8212 * i.e., events of high frequency (17) and for extended debugging (18) 8213 */ 8214 total_len = 0; 8215 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8216 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 8217 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 8218 total_len++; 8219 } 8220 8221 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8222 (total_len * sizeof(uint32_t)); 8223 8224 buf = wmi_buf_alloc(wmi_handle, len); 8225 if (!buf) 8226 return QDF_STATUS_E_NOMEM; 8227 8228 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8229 buf_ptr = (uint8_t *) cmd; 8230 8231 WMITLV_SET_HDR(&cmd->tlv_header, 8232 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8233 WMITLV_GET_STRUCT_TLVLEN( 8234 wmi_diag_event_log_config_fixed_param)); 8235 8236 cmd->num_of_diag_events_logs = total_len; 8237 8238 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8239 8240 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8241 (total_len * sizeof(uint32_t))); 8242 8243 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8244 8245 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 8246 log_level = 1; 8247 else 8248 log_level = 0; 8249 8250 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 8251 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8252 uint32_t val = wmi_handle->events_logs_list[i]; 8253 if ((WMI_DIAG_FREQUENCY_GET(val)) && 8254 (WMI_DIAG_EXT_FEATURE_GET(val))) { 8255 8256 WMI_DIAG_ID_SET(cmd_args[count], 8257 WMI_DIAG_ID_GET(val)); 8258 WMI_DIAG_TYPE_SET(cmd_args[count], 8259 WMI_DIAG_TYPE_GET(val)); 8260 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 8261 log_level); 8262 wmi_debug("Idx:%d, val:%x", i, val); 8263 count++; 8264 } 8265 } 8266 8267 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8268 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8269 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8270 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8271 wmi_buf_free(buf); 8272 return QDF_STATUS_E_INVAL; 8273 } 8274 8275 return QDF_STATUS_SUCCESS; 8276 } 8277 8278 /** 8279 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 8280 * @wmi_handle: WMI handle 8281 * 8282 * This function is used to send the flush command to the FW, 8283 * that will flush the fw logs that are residue in the FW 8284 * 8285 * Return: None 8286 */ 8287 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 8288 { 8289 wmi_debug_mesg_flush_fixed_param *cmd; 8290 wmi_buf_t buf; 8291 int len = sizeof(*cmd); 8292 QDF_STATUS ret; 8293 8294 buf = wmi_buf_alloc(wmi_handle, len); 8295 if (!buf) 8296 return QDF_STATUS_E_NOMEM; 8297 8298 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 8299 WMITLV_SET_HDR(&cmd->tlv_header, 8300 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 8301 WMITLV_GET_STRUCT_TLVLEN( 8302 wmi_debug_mesg_flush_fixed_param)); 8303 cmd->reserved0 = 0; 8304 8305 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 8306 ret = wmi_unified_cmd_send(wmi_handle, 8307 buf, 8308 len, 8309 WMI_DEBUG_MESG_FLUSH_CMDID); 8310 if (QDF_IS_STATUS_ERROR(ret)) { 8311 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 8312 wmi_buf_free(buf); 8313 return QDF_STATUS_E_INVAL; 8314 } 8315 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 8316 8317 return ret; 8318 } 8319 8320 #ifdef BIG_ENDIAN_HOST 8321 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 8322 /** 8323 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 8324 * @param - fips extend param related parameters 8325 * 8326 * Return: QDF_STATUS - success or error status 8327 */ 8328 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 8329 struct fips_extend_params *param) 8330 { 8331 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 8332 int c; 8333 u_int8_t *key_aligned = NULL; 8334 u_int8_t *nonce_iv_aligned = NULL; 8335 u_int8_t *data_aligned = NULL; 8336 int ret = QDF_STATUS_SUCCESS; 8337 8338 /* Assigning unaligned space to copy the key */ 8339 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 8340 param->cmd_params.key_len + FIPS_ALIGN); 8341 /* Checking if kmalloc is successful to allocate space */ 8342 if (!key_unaligned) 8343 return QDF_STATUS_E_INVAL; 8344 8345 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 8346 FIPS_ALIGN); 8347 /* Checking if kmalloc is successful to allocate space */ 8348 if (!data_unaligned) { 8349 ret = QDF_STATUS_E_INVAL; 8350 goto fips_align_fail_data; 8351 } 8352 8353 /* Checking if space is aligned */ 8354 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 8355 /* align to 4 */ 8356 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 8357 FIPS_ALIGN); 8358 } else { 8359 key_aligned = (u_int8_t *)key_unaligned; 8360 } 8361 8362 /* memset and copy content from key to key aligned */ 8363 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 8364 OS_MEMCPY(key_aligned, param->cmd_params.key, 8365 param->cmd_params.key_len); 8366 8367 /* print a hexdump for host debug */ 8368 wmi_debug("Aligned and Copied Key: "); 8369 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8370 key_aligned, param->cmd_params.key_len); 8371 8372 /* Checking of space is aligned */ 8373 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 8374 /* align to 4 */ 8375 data_aligned = 8376 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 8377 } else { 8378 data_aligned = (u_int8_t *)data_unaligned; 8379 } 8380 8381 /* memset and copy content from data to data aligned */ 8382 OS_MEMSET(data_aligned, 0, param->data_len); 8383 OS_MEMCPY(data_aligned, param->data, param->data_len); 8384 8385 /* print a hexdump for host debug */ 8386 wmi_debug("\t Properly Aligned and Copied Data: "); 8387 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8388 data_aligned, param->data_len); 8389 8390 /* converting to little Endian */ 8391 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 8392 *((u_int32_t *)key_aligned + c) = 8393 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 8394 } 8395 for (c = 0; c < param->data_len / 4; c++) { 8396 *((u_int32_t *)data_aligned + c) = 8397 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 8398 } 8399 8400 /* update endian data */ 8401 OS_MEMCPY(param->cmd_params.key, key_aligned, 8402 param->cmd_params.key_len); 8403 OS_MEMCPY(param->data, data_aligned, param->data_len); 8404 8405 if (param->cmd_params.nonce_iv_len) { 8406 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 8407 param->cmd_params.nonce_iv_len + 8408 FIPS_ALIGN); 8409 8410 /* Checking if kmalloc is successful to allocate space */ 8411 if (!nonce_iv_unaligned) { 8412 ret = QDF_STATUS_E_INVAL; 8413 goto fips_align_fail_nonce_iv; 8414 } 8415 /* Checking if space is aligned */ 8416 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 8417 /* align to 4 */ 8418 nonce_iv_aligned = 8419 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 8420 FIPS_ALIGN); 8421 } else { 8422 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 8423 } 8424 8425 /* memset and copy content from iv to iv aligned */ 8426 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 8427 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 8428 param->cmd_params.nonce_iv_len); 8429 8430 /* print a hexdump for host debug */ 8431 wmi_debug("\t Aligned and Copied Nonce_IV: "); 8432 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8433 nonce_iv_aligned, 8434 param->cmd_params.nonce_iv_len); 8435 8436 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 8437 *((u_int32_t *)nonce_iv_aligned + c) = 8438 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 8439 } 8440 } 8441 8442 /* clean up allocated spaces */ 8443 qdf_mem_free(nonce_iv_unaligned); 8444 nonce_iv_unaligned = NULL; 8445 nonce_iv_aligned = NULL; 8446 8447 fips_align_fail_nonce_iv: 8448 qdf_mem_free(data_unaligned); 8449 data_unaligned = NULL; 8450 data_aligned = NULL; 8451 8452 fips_align_fail_data: 8453 qdf_mem_free(key_unaligned); 8454 key_unaligned = NULL; 8455 key_aligned = NULL; 8456 8457 return ret; 8458 } 8459 #endif 8460 8461 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 8462 struct fips_params *param) 8463 { 8464 unsigned char *key_unaligned, *data_unaligned; 8465 int c; 8466 u_int8_t *key_aligned = NULL; 8467 u_int8_t *data_aligned = NULL; 8468 8469 /* Assigning unaligned space to copy the key */ 8470 key_unaligned = qdf_mem_malloc( 8471 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 8472 data_unaligned = qdf_mem_malloc( 8473 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 8474 8475 /* Checking if kmalloc is successful to allocate space */ 8476 if (!key_unaligned) 8477 return QDF_STATUS_SUCCESS; 8478 /* Checking if space is aligned */ 8479 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 8480 /* align to 4 */ 8481 key_aligned = 8482 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 8483 FIPS_ALIGN); 8484 } else { 8485 key_aligned = (u_int8_t *)key_unaligned; 8486 } 8487 8488 /* memset and copy content from key to key aligned */ 8489 OS_MEMSET(key_aligned, 0, param->key_len); 8490 OS_MEMCPY(key_aligned, param->key, param->key_len); 8491 8492 /* print a hexdump for host debug */ 8493 print_hex_dump(KERN_DEBUG, 8494 "\t Aligned and Copied Key:@@@@ ", 8495 DUMP_PREFIX_NONE, 8496 16, 1, key_aligned, param->key_len, true); 8497 8498 /* Checking if kmalloc is successful to allocate space */ 8499 if (!data_unaligned) 8500 return QDF_STATUS_SUCCESS; 8501 /* Checking of space is aligned */ 8502 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 8503 /* align to 4 */ 8504 data_aligned = 8505 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 8506 FIPS_ALIGN); 8507 } else { 8508 data_aligned = (u_int8_t *)data_unaligned; 8509 } 8510 8511 /* memset and copy content from data to data aligned */ 8512 OS_MEMSET(data_aligned, 0, param->data_len); 8513 OS_MEMCPY(data_aligned, param->data, param->data_len); 8514 8515 /* print a hexdump for host debug */ 8516 print_hex_dump(KERN_DEBUG, 8517 "\t Properly Aligned and Copied Data:@@@@ ", 8518 DUMP_PREFIX_NONE, 8519 16, 1, data_aligned, param->data_len, true); 8520 8521 /* converting to little Endian both key_aligned and 8522 * data_aligned*/ 8523 for (c = 0; c < param->key_len/4; c++) { 8524 *((u_int32_t *)key_aligned+c) = 8525 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 8526 } 8527 for (c = 0; c < param->data_len/4; c++) { 8528 *((u_int32_t *)data_aligned+c) = 8529 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 8530 } 8531 8532 /* update endian data to key and data vectors */ 8533 OS_MEMCPY(param->key, key_aligned, param->key_len); 8534 OS_MEMCPY(param->data, data_aligned, param->data_len); 8535 8536 /* clean up allocated spaces */ 8537 qdf_mem_free(key_unaligned); 8538 key_unaligned = NULL; 8539 key_aligned = NULL; 8540 8541 qdf_mem_free(data_unaligned); 8542 data_unaligned = NULL; 8543 data_aligned = NULL; 8544 8545 return QDF_STATUS_SUCCESS; 8546 } 8547 #else 8548 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 8549 /** 8550 * fips_extend_align_data_be() - DUMMY for LE platform 8551 * 8552 * Return: QDF_STATUS - success 8553 */ 8554 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 8555 struct fips_extend_params *param) 8556 { 8557 return QDF_STATUS_SUCCESS; 8558 } 8559 #endif 8560 8561 /** 8562 * fips_align_data_be() - DUMMY for LE platform 8563 * 8564 * Return: QDF_STATUS - success 8565 */ 8566 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 8567 struct fips_params *param) 8568 { 8569 return QDF_STATUS_SUCCESS; 8570 } 8571 #endif 8572 8573 #ifdef WLAN_FEATURE_DISA 8574 /** 8575 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 8576 * @wmi_handle: wmi handle 8577 * @params: encrypt/decrypt params 8578 * 8579 * Return: QDF_STATUS_SUCCESS for success or error code 8580 */ 8581 static QDF_STATUS 8582 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 8583 struct disa_encrypt_decrypt_req_params 8584 *encrypt_decrypt_params) 8585 { 8586 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 8587 wmi_buf_t wmi_buf; 8588 uint8_t *buf_ptr; 8589 QDF_STATUS ret; 8590 uint32_t len; 8591 8592 wmi_debug("Send encrypt decrypt cmd"); 8593 8594 len = sizeof(*cmd) + 8595 encrypt_decrypt_params->data_len + 8596 WMI_TLV_HDR_SIZE; 8597 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8598 if (!wmi_buf) 8599 return QDF_STATUS_E_NOMEM; 8600 8601 buf_ptr = wmi_buf_data(wmi_buf); 8602 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 8603 8604 WMITLV_SET_HDR(&cmd->tlv_header, 8605 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 8606 WMITLV_GET_STRUCT_TLVLEN( 8607 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 8608 8609 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 8610 cmd->key_flag = encrypt_decrypt_params->key_flag; 8611 cmd->key_idx = encrypt_decrypt_params->key_idx; 8612 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 8613 cmd->key_len = encrypt_decrypt_params->key_len; 8614 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 8615 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 8616 8617 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 8618 encrypt_decrypt_params->key_len); 8619 8620 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 8621 MAX_MAC_HEADER_LEN); 8622 8623 cmd->data_len = encrypt_decrypt_params->data_len; 8624 8625 if (cmd->data_len) { 8626 buf_ptr += sizeof(*cmd); 8627 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 8628 roundup(encrypt_decrypt_params->data_len, 8629 sizeof(uint32_t))); 8630 buf_ptr += WMI_TLV_HDR_SIZE; 8631 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 8632 encrypt_decrypt_params->data_len); 8633 } 8634 8635 /* This conversion is to facilitate data to FW in little endian */ 8636 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 8637 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 8638 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 8639 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 8640 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 8641 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 8642 8643 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 8644 ret = wmi_unified_cmd_send(wmi_handle, 8645 wmi_buf, len, 8646 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 8647 if (QDF_IS_STATUS_ERROR(ret)) { 8648 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 8649 wmi_buf_free(wmi_buf); 8650 } 8651 8652 return ret; 8653 } 8654 #endif /* WLAN_FEATURE_DISA */ 8655 8656 /** 8657 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 8658 * @wmi_handle: wmi handle 8659 * @param: pointer to hold pdev fips param 8660 * 8661 * Return: 0 for success or error code 8662 */ 8663 static QDF_STATUS 8664 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 8665 struct fips_params *param) 8666 { 8667 wmi_pdev_fips_cmd_fixed_param *cmd; 8668 wmi_buf_t buf; 8669 uint8_t *buf_ptr; 8670 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 8671 QDF_STATUS retval = QDF_STATUS_SUCCESS; 8672 8673 /* Length TLV placeholder for array of bytes */ 8674 len += WMI_TLV_HDR_SIZE; 8675 if (param->data_len) 8676 len += (param->data_len*sizeof(uint8_t)); 8677 8678 /* 8679 * Data length must be multiples of 16 bytes - checked against 0xF - 8680 * and must be less than WMI_SVC_MSG_SIZE - static size of 8681 * wmi_pdev_fips_cmd structure 8682 */ 8683 8684 /* do sanity on the input */ 8685 if (!(((param->data_len & 0xF) == 0) && 8686 ((param->data_len > 0) && 8687 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 8688 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 8689 return QDF_STATUS_E_INVAL; 8690 } 8691 8692 buf = wmi_buf_alloc(wmi_handle, len); 8693 if (!buf) 8694 return QDF_STATUS_E_FAILURE; 8695 8696 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8697 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 8698 WMITLV_SET_HDR(&cmd->tlv_header, 8699 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 8700 WMITLV_GET_STRUCT_TLVLEN 8701 (wmi_pdev_fips_cmd_fixed_param)); 8702 8703 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8704 wmi_handle, 8705 param->pdev_id); 8706 if (param->key && param->data) { 8707 cmd->key_len = param->key_len; 8708 cmd->data_len = param->data_len; 8709 cmd->fips_cmd = !!(param->op); 8710 8711 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 8712 return QDF_STATUS_E_FAILURE; 8713 8714 qdf_mem_copy(cmd->key, param->key, param->key_len); 8715 8716 if (param->mode == FIPS_ENGINE_AES_CTR || 8717 param->mode == FIPS_ENGINE_AES_MIC) { 8718 cmd->mode = param->mode; 8719 } else { 8720 cmd->mode = FIPS_ENGINE_AES_CTR; 8721 } 8722 qdf_print("Key len = %d, Data len = %d", 8723 cmd->key_len, cmd->data_len); 8724 8725 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 8726 cmd->key, cmd->key_len, true); 8727 buf_ptr += sizeof(*cmd); 8728 8729 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 8730 8731 buf_ptr += WMI_TLV_HDR_SIZE; 8732 if (param->data_len) 8733 qdf_mem_copy(buf_ptr, 8734 (uint8_t *) param->data, param->data_len); 8735 8736 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 8737 16, 1, buf_ptr, cmd->data_len, true); 8738 8739 buf_ptr += param->data_len; 8740 8741 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 8742 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 8743 WMI_PDEV_FIPS_CMDID); 8744 qdf_print("%s return value %d", __func__, retval); 8745 } else { 8746 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 8747 wmi_buf_free(buf); 8748 retval = -QDF_STATUS_E_BADMSG; 8749 } 8750 8751 return retval; 8752 } 8753 8754 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 8755 /** 8756 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 8757 * @wmi_handle: wmi handle 8758 * @param: pointer to hold pdev fips param 8759 * 8760 * Return: 0 for success or error code 8761 */ 8762 static QDF_STATUS 8763 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 8764 struct fips_extend_params *param) 8765 { 8766 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 8767 wmi_buf_t buf; 8768 uint8_t *buf_ptr; 8769 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 8770 uint32_t data_len_aligned; 8771 QDF_STATUS retval = QDF_STATUS_SUCCESS; 8772 8773 len += WMI_TLV_HDR_SIZE; 8774 if (param->frag_idx == 0) 8775 len += sizeof(wmi_fips_extend_cmd_init_params); 8776 8777 /* Length TLV placeholder for array of bytes */ 8778 len += WMI_TLV_HDR_SIZE; 8779 if (param->data_len) { 8780 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 8781 len += (data_len_aligned * sizeof(uint8_t)); 8782 } 8783 8784 buf = wmi_buf_alloc(wmi_handle, len); 8785 if (!buf) 8786 return QDF_STATUS_E_FAILURE; 8787 8788 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8789 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 8790 WMITLV_SET_HDR(&cmd->tlv_header, 8791 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 8792 WMITLV_GET_STRUCT_TLVLEN 8793 (wmi_pdev_fips_extend_cmd_fixed_param)); 8794 8795 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8796 wmi_handle, 8797 param->pdev_id); 8798 8799 cmd->fips_cookie = param->cookie; 8800 cmd->frag_idx = param->frag_idx; 8801 cmd->more_bit = param->more_bit; 8802 cmd->data_len = param->data_len; 8803 8804 if (fips_extend_align_data_be(wmi_handle, param) != 8805 QDF_STATUS_SUCCESS) { 8806 wmi_buf_free(buf); 8807 return QDF_STATUS_E_FAILURE; 8808 } 8809 8810 buf_ptr = (uint8_t *)(cmd + 1); 8811 if (cmd->frag_idx == 0) { 8812 wmi_fips_extend_cmd_init_params *cmd_params; 8813 8814 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8815 sizeof(wmi_fips_extend_cmd_init_params)); 8816 buf_ptr += WMI_TLV_HDR_SIZE; 8817 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 8818 WMITLV_SET_HDR(buf_ptr, 8819 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 8820 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 8821 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 8822 cmd_params->key_cipher = param->cmd_params.key_cipher; 8823 cmd_params->key_len = param->cmd_params.key_len; 8824 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 8825 cmd_params->tag_len = param->cmd_params.tag_len; 8826 cmd_params->aad_len = param->cmd_params.aad_len; 8827 cmd_params->payload_len = param->cmd_params.payload_len; 8828 8829 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 8830 param->cmd_params.key_len); 8831 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 8832 param->cmd_params.nonce_iv_len); 8833 8834 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 8835 cmd_params->key_len, cmd_params->nonce_iv_len, 8836 cmd_params->tag_len, cmd_params->aad_len, 8837 cmd_params->payload_len); 8838 8839 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 8840 } else { 8841 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8842 buf_ptr += WMI_TLV_HDR_SIZE; 8843 } 8844 8845 if (param->data_len && param->data) { 8846 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 8847 data_len_aligned); 8848 8849 buf_ptr += WMI_TLV_HDR_SIZE; 8850 if (param->data_len) 8851 qdf_mem_copy(buf_ptr, 8852 (uint8_t *)param->data, param->data_len); 8853 8854 wmi_debug("Data: "); 8855 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8856 buf_ptr, cmd->data_len); 8857 8858 if (param->data_len) 8859 buf_ptr += param->data_len; 8860 8861 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 8862 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 8863 WMI_PDEV_FIPS_EXTEND_CMDID); 8864 wmi_debug("return value %d", retval); 8865 } else { 8866 wmi_debug("Key or Data is NULL"); 8867 wmi_buf_free(buf); 8868 retval = QDF_STATUS_E_BADMSG; 8869 } 8870 8871 return retval; 8872 } 8873 8874 /** 8875 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 8876 * @wmi_handle: wmi handle 8877 * @param: pointer to hold pdev fips param 8878 * 8879 * Return: 0 for success or error code 8880 */ 8881 static QDF_STATUS 8882 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 8883 struct fips_mode_set_params *param) 8884 { 8885 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 8886 wmi_buf_t buf; 8887 uint8_t *buf_ptr; 8888 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 8889 QDF_STATUS retval = QDF_STATUS_SUCCESS; 8890 8891 buf = wmi_buf_alloc(wmi_handle, len); 8892 if (!buf) 8893 return QDF_STATUS_E_FAILURE; 8894 8895 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8896 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 8897 WMITLV_SET_HDR(&cmd->tlv_header, 8898 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 8899 WMITLV_GET_STRUCT_TLVLEN 8900 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 8901 8902 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8903 wmi_handle, 8904 param->pdev_id); 8905 8906 cmd->fips_mode_set = param->mode; 8907 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 8908 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 8909 WMI_PDEV_FIPS_MODE_SET_CMDID); 8910 if (retval) { 8911 wmi_err("Failed to send FIPS mode enable cmd"); 8912 wmi_buf_free(buf); 8913 } 8914 return retval; 8915 } 8916 #endif 8917 8918 /** 8919 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 8920 * to fw 8921 * @wmi_handle: wmi handle 8922 * @param: pointer to wlan profile param 8923 * 8924 * Return: 0 for success or error code 8925 */ 8926 static QDF_STATUS 8927 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 8928 struct wlan_profile_params *param) 8929 { 8930 wmi_buf_t buf; 8931 uint16_t len; 8932 QDF_STATUS ret; 8933 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8934 8935 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8936 buf = wmi_buf_alloc(wmi_handle, len); 8937 if (!buf) { 8938 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 8939 return QDF_STATUS_E_NOMEM; 8940 } 8941 8942 profile_enable_cmd = 8943 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8944 wmi_buf_data(buf); 8945 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8946 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8947 WMITLV_GET_STRUCT_TLVLEN 8948 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8949 8950 profile_enable_cmd->profile_id = param->profile_id; 8951 profile_enable_cmd->enable = param->enable; 8952 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 8953 NO_SESSION, 0); 8954 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8955 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8956 if (ret) { 8957 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 8958 wmi_buf_free(buf); 8959 } 8960 return ret; 8961 } 8962 8963 /** 8964 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 8965 * to fw 8966 * @wmi_handle: wmi handle 8967 * @param: pointer to wlan profile param 8968 * 8969 * Return: 0 for success or error code 8970 */ 8971 static QDF_STATUS 8972 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 8973 struct wlan_profile_params *param) 8974 { 8975 wmi_buf_t buf; 8976 uint16_t len; 8977 QDF_STATUS ret; 8978 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8979 8980 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8981 buf = wmi_buf_alloc(wmi_handle, len); 8982 if (!buf) { 8983 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 8984 return QDF_STATUS_E_NOMEM; 8985 } 8986 8987 prof_trig_cmd = 8988 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8989 wmi_buf_data(buf); 8990 8991 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8992 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8993 WMITLV_GET_STRUCT_TLVLEN 8994 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8995 8996 prof_trig_cmd->enable = param->enable; 8997 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 8998 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8999 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9000 if (ret) { 9001 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 9002 wmi_buf_free(buf); 9003 } 9004 return ret; 9005 } 9006 9007 /** 9008 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 9009 * to fw 9010 * @wmi_handle: wmi handle 9011 * @param: pointer to wlan profile param 9012 * 9013 * Return: 0 for success or error code 9014 */ 9015 static QDF_STATUS 9016 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 9017 struct wlan_profile_params *param) 9018 { 9019 wmi_buf_t buf; 9020 int32_t len = 0; 9021 QDF_STATUS ret; 9022 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9023 9024 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9025 buf = wmi_buf_alloc(wmi_handle, len); 9026 if (!buf) { 9027 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 9028 return QDF_STATUS_E_NOMEM; 9029 } 9030 9031 hist_intvl_cmd = 9032 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9033 wmi_buf_data(buf); 9034 9035 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9036 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9037 WMITLV_GET_STRUCT_TLVLEN 9038 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9039 9040 hist_intvl_cmd->profile_id = param->profile_id; 9041 hist_intvl_cmd->value = param->enable; 9042 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 9043 NO_SESSION, 0); 9044 9045 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9046 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9047 if (ret) { 9048 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 9049 wmi_buf_free(buf); 9050 } 9051 return ret; 9052 } 9053 9054 /** 9055 * send_fw_test_cmd_tlv() - send fw test command to fw. 9056 * @wmi_handle: wmi handle 9057 * @wmi_fwtest: fw test command 9058 * 9059 * This function sends fw test command to fw. 9060 * 9061 * Return: CDF STATUS 9062 */ 9063 static 9064 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 9065 struct set_fwtest_params *wmi_fwtest) 9066 { 9067 wmi_fwtest_set_param_cmd_fixed_param *cmd; 9068 wmi_buf_t wmi_buf; 9069 uint16_t len; 9070 9071 len = sizeof(*cmd); 9072 9073 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9074 if (!wmi_buf) 9075 return QDF_STATUS_E_NOMEM; 9076 9077 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9078 WMITLV_SET_HDR(&cmd->tlv_header, 9079 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 9080 WMITLV_GET_STRUCT_TLVLEN( 9081 wmi_fwtest_set_param_cmd_fixed_param)); 9082 cmd->param_id = wmi_fwtest->arg; 9083 cmd->param_value = wmi_fwtest->value; 9084 9085 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 9086 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9087 WMI_FWTEST_CMDID)) { 9088 wmi_err("Failed to send fw test command"); 9089 wmi_buf_free(wmi_buf); 9090 return QDF_STATUS_E_FAILURE; 9091 } 9092 9093 return QDF_STATUS_SUCCESS; 9094 } 9095 9096 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 9097 { 9098 uint16_t len = 0; 9099 9100 if (config == WFA_CONFIG_RXNE) 9101 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 9102 else 9103 len += WMI_TLV_HDR_SIZE; 9104 9105 if (config == WFA_CONFIG_CSA) 9106 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 9107 else 9108 len += WMI_TLV_HDR_SIZE; 9109 9110 if (config == WFA_CONFIG_OCV) 9111 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 9112 else 9113 len += WMI_TLV_HDR_SIZE; 9114 9115 if (config == WFA_CONFIG_SA_QUERY) 9116 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 9117 else 9118 len += WMI_TLV_HDR_SIZE; 9119 9120 return len; 9121 } 9122 9123 /** 9124 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 9125 * @host_frmtype: Host defined OCV frame type 9126 * @ocv_frmtype: Pointer to hold WMI OCV frame type 9127 * 9128 * This function converts and fills host defined OCV frame type into WMI OCV 9129 * frame type. 9130 * 9131 * Return: CDF STATUS 9132 */ 9133 static QDF_STATUS 9134 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 9135 { 9136 switch (host_frmtype) { 9137 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 9138 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 9139 break; 9140 9141 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 9142 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 9143 break; 9144 9145 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 9146 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 9147 break; 9148 9149 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 9150 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 9151 break; 9152 9153 default: 9154 wmi_err("Invalid command type cmd %d", host_frmtype); 9155 return QDF_STATUS_E_FAILURE; 9156 } 9157 9158 return QDF_STATUS_SUCCESS; 9159 } 9160 9161 /** 9162 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 9163 * @wmi_handle: wmi handle 9164 * @wmi_wfatest: wfa test command 9165 * 9166 * This function sends wfa test command to fw. 9167 * 9168 * Return: CDF STATUS 9169 */ 9170 static 9171 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 9172 struct set_wfatest_params *wmi_wfatest) 9173 { 9174 wmi_wfa_config_cmd_fixed_param *cmd; 9175 wmi_wfa_config_rsnxe *rxne; 9176 wmi_wfa_config_csa *csa; 9177 wmi_wfa_config_ocv *ocv; 9178 wmi_wfa_config_saquery *saquery; 9179 wmi_buf_t wmi_buf; 9180 uint16_t len = sizeof(*cmd); 9181 uint8_t *buf_ptr; 9182 9183 len += wfa_config_param_len(wmi_wfatest->cmd); 9184 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9185 if (!wmi_buf) 9186 return QDF_STATUS_E_NOMEM; 9187 9188 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 9189 WMITLV_SET_HDR(&cmd->tlv_header, 9190 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 9191 WMITLV_GET_STRUCT_TLVLEN( 9192 wmi_wfa_config_cmd_fixed_param)); 9193 9194 cmd->vdev_id = wmi_wfatest->vdev_id; 9195 buf_ptr = (uint8_t *)(cmd + 1); 9196 9197 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 9198 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9199 sizeof(wmi_wfa_config_rsnxe)); 9200 buf_ptr += WMI_TLV_HDR_SIZE; 9201 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 9202 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 9203 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 9204 rxne->rsnxe_param = wmi_wfatest->value; 9205 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 9206 } else { 9207 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9208 buf_ptr += WMI_TLV_HDR_SIZE; 9209 } 9210 9211 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 9212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9213 sizeof(wmi_wfa_config_csa)); 9214 buf_ptr += WMI_TLV_HDR_SIZE; 9215 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 9216 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 9217 csa = (wmi_wfa_config_csa *)buf_ptr; 9218 csa->ignore_csa = wmi_wfatest->value; 9219 buf_ptr += sizeof(wmi_wfa_config_csa); 9220 } else { 9221 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9222 buf_ptr += WMI_TLV_HDR_SIZE; 9223 } 9224 9225 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 9226 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9227 sizeof(wmi_wfa_config_ocv)); 9228 buf_ptr += WMI_TLV_HDR_SIZE; 9229 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 9230 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 9231 ocv = (wmi_wfa_config_ocv *)buf_ptr; 9232 9233 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 9234 &ocv->frame_types)) 9235 goto error; 9236 9237 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 9238 buf_ptr += sizeof(wmi_wfa_config_ocv); 9239 } else { 9240 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9241 buf_ptr += WMI_TLV_HDR_SIZE; 9242 } 9243 9244 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 9245 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9246 sizeof(wmi_wfa_config_saquery)); 9247 buf_ptr += WMI_TLV_HDR_SIZE; 9248 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 9249 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 9250 9251 saquery = (wmi_wfa_config_saquery *)buf_ptr; 9252 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 9253 } else { 9254 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9255 buf_ptr += WMI_TLV_HDR_SIZE; 9256 } 9257 9258 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 9259 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9260 WMI_WFA_CONFIG_CMDID)) { 9261 wmi_err("Failed to send wfa test command"); 9262 goto error; 9263 } 9264 9265 return QDF_STATUS_SUCCESS; 9266 9267 error: 9268 wmi_buf_free(wmi_buf); 9269 return QDF_STATUS_E_FAILURE; 9270 } 9271 9272 /** 9273 * send_unit_test_cmd_tlv() - send unit test command to fw. 9274 * @wmi_handle: wmi handle 9275 * @wmi_utest: unit test command 9276 * 9277 * This function send unit test command to fw. 9278 * 9279 * Return: CDF STATUS 9280 */ 9281 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 9282 struct wmi_unit_test_cmd *wmi_utest) 9283 { 9284 wmi_unit_test_cmd_fixed_param *cmd; 9285 wmi_buf_t wmi_buf; 9286 uint8_t *buf_ptr; 9287 int i; 9288 uint16_t len, args_tlv_len; 9289 uint32_t *unit_test_cmd_args; 9290 9291 args_tlv_len = 9292 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 9293 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 9294 9295 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9296 if (!wmi_buf) 9297 return QDF_STATUS_E_NOMEM; 9298 9299 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9300 buf_ptr = (uint8_t *) cmd; 9301 WMITLV_SET_HDR(&cmd->tlv_header, 9302 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 9303 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 9304 cmd->vdev_id = wmi_utest->vdev_id; 9305 cmd->module_id = wmi_utest->module_id; 9306 cmd->num_args = wmi_utest->num_args; 9307 cmd->diag_token = wmi_utest->diag_token; 9308 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 9309 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9310 (wmi_utest->num_args * sizeof(uint32_t))); 9311 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9312 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 9313 cmd->vdev_id, cmd->module_id, cmd->diag_token); 9314 wmi_debug("%d num of args = ", wmi_utest->num_args); 9315 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 9316 unit_test_cmd_args[i] = wmi_utest->args[i]; 9317 wmi_debug("%d,", wmi_utest->args[i]); 9318 } 9319 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 9320 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9321 WMI_UNIT_TEST_CMDID)) { 9322 wmi_err("Failed to send unit test command"); 9323 wmi_buf_free(wmi_buf); 9324 return QDF_STATUS_E_FAILURE; 9325 } 9326 9327 return QDF_STATUS_SUCCESS; 9328 } 9329 9330 /** 9331 * send_power_dbg_cmd_tlv() - send power debug commands 9332 * @wmi_handle: wmi handle 9333 * @param: wmi power debug parameter 9334 * 9335 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 9336 * 9337 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9338 */ 9339 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 9340 struct wmi_power_dbg_params *param) 9341 { 9342 wmi_buf_t buf = NULL; 9343 QDF_STATUS status; 9344 int len, args_tlv_len; 9345 uint8_t *buf_ptr; 9346 uint8_t i; 9347 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 9348 uint32_t *cmd_args; 9349 9350 /* Prepare and send power debug cmd parameters */ 9351 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 9352 len = sizeof(*cmd) + args_tlv_len; 9353 buf = wmi_buf_alloc(wmi_handle, len); 9354 if (!buf) 9355 return QDF_STATUS_E_NOMEM; 9356 9357 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9358 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 9359 WMITLV_SET_HDR(&cmd->tlv_header, 9360 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 9361 WMITLV_GET_STRUCT_TLVLEN 9362 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 9363 9364 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9365 wmi_handle, 9366 param->pdev_id); 9367 cmd->module_id = param->module_id; 9368 cmd->num_args = param->num_args; 9369 buf_ptr += sizeof(*cmd); 9370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9371 (param->num_args * sizeof(uint32_t))); 9372 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9373 wmi_debug("%d num of args = ", param->num_args); 9374 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 9375 cmd_args[i] = param->args[i]; 9376 wmi_debug("%d,", param->args[i]); 9377 } 9378 9379 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 9380 status = wmi_unified_cmd_send(wmi_handle, buf, 9381 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 9382 if (QDF_IS_STATUS_ERROR(status)) { 9383 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 9384 status); 9385 goto error; 9386 } 9387 9388 return QDF_STATUS_SUCCESS; 9389 error: 9390 wmi_buf_free(buf); 9391 9392 return status; 9393 } 9394 9395 /** 9396 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 9397 * @wmi_handle: wmi handle 9398 * @pdev_id: pdev id 9399 * 9400 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 9401 * 9402 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9403 */ 9404 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9405 uint32_t pdev_id) 9406 { 9407 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 9408 wmi_buf_t buf; 9409 uint16_t len; 9410 QDF_STATUS ret; 9411 9412 len = sizeof(*cmd); 9413 buf = wmi_buf_alloc(wmi_handle, len); 9414 9415 wmi_debug("pdev_id=%d", pdev_id); 9416 9417 if (!buf) 9418 return QDF_STATUS_E_NOMEM; 9419 9420 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 9421 wmi_buf_data(buf); 9422 9423 WMITLV_SET_HDR(&cmd->tlv_header, 9424 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 9425 WMITLV_GET_STRUCT_TLVLEN( 9426 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 9427 9428 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9429 wmi_handle, 9430 pdev_id); 9431 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 9432 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9433 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 9434 if (QDF_IS_STATUS_ERROR(ret)) { 9435 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 9436 ret, pdev_id); 9437 wmi_buf_free(buf); 9438 return QDF_STATUS_E_FAILURE; 9439 } 9440 9441 return QDF_STATUS_SUCCESS; 9442 } 9443 9444 /** 9445 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 9446 * @wmi_handle: wmi handle 9447 * @pdev_id: pdev id 9448 * 9449 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 9450 * 9451 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9452 */ 9453 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 9454 uint32_t pdev_id) 9455 { 9456 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 9457 wmi_buf_t buf; 9458 uint16_t len; 9459 QDF_STATUS ret; 9460 9461 len = sizeof(*cmd); 9462 buf = wmi_buf_alloc(wmi_handle, len); 9463 9464 wmi_debug("pdev_id=%d", pdev_id); 9465 9466 if (!buf) 9467 return QDF_STATUS_E_NOMEM; 9468 9469 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 9470 wmi_buf_data(buf); 9471 9472 WMITLV_SET_HDR(&cmd->tlv_header, 9473 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 9474 WMITLV_GET_STRUCT_TLVLEN( 9475 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 9476 9477 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9478 wmi_handle, 9479 pdev_id); 9480 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 9481 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9482 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 9483 if (QDF_IS_STATUS_ERROR(ret)) { 9484 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 9485 ret, pdev_id); 9486 wmi_buf_free(buf); 9487 return QDF_STATUS_E_FAILURE; 9488 } 9489 9490 return QDF_STATUS_SUCCESS; 9491 } 9492 9493 #ifdef QCA_SUPPORT_AGILE_DFS 9494 static 9495 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 9496 struct vdev_adfs_ch_cfg_params *param) 9497 { 9498 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 9499 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 9500 wmi_buf_t buf; 9501 QDF_STATUS ret; 9502 uint16_t len; 9503 9504 len = sizeof(*cmd); 9505 buf = wmi_buf_alloc(wmi_handle, len); 9506 9507 if (!buf) { 9508 wmi_err("wmi_buf_alloc failed"); 9509 return QDF_STATUS_E_NOMEM; 9510 } 9511 9512 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 9513 wmi_buf_data(buf); 9514 9515 WMITLV_SET_HDR(&cmd->tlv_header, 9516 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 9517 WMITLV_GET_STRUCT_TLVLEN 9518 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 9519 9520 cmd->vdev_id = param->vdev_id; 9521 cmd->ocac_mode = param->ocac_mode; 9522 cmd->center_freq1 = param->center_freq1; 9523 cmd->center_freq2 = param->center_freq2; 9524 cmd->chan_freq = param->chan_freq; 9525 cmd->chan_width = param->chan_width; 9526 cmd->min_duration_ms = param->min_duration_ms; 9527 cmd->max_duration_ms = param->max_duration_ms; 9528 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 9529 cmd->vdev_id, cmd->ocac_mode, 9530 cmd->center_freq); 9531 9532 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 9533 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9534 WMI_VDEV_ADFS_CH_CFG_CMDID); 9535 9536 if (QDF_IS_STATUS_ERROR(ret)) { 9537 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9538 wmi_buf_free(buf); 9539 return QDF_STATUS_E_FAILURE; 9540 } 9541 9542 return QDF_STATUS_SUCCESS; 9543 } 9544 9545 static 9546 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 9547 struct vdev_adfs_abort_params *param) 9548 { 9549 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 9550 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 9551 wmi_buf_t buf; 9552 QDF_STATUS ret; 9553 uint16_t len; 9554 9555 len = sizeof(*cmd); 9556 buf = wmi_buf_alloc(wmi_handle, len); 9557 9558 if (!buf) { 9559 wmi_err("wmi_buf_alloc failed"); 9560 return QDF_STATUS_E_NOMEM; 9561 } 9562 9563 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 9564 wmi_buf_data(buf); 9565 9566 WMITLV_SET_HDR 9567 (&cmd->tlv_header, 9568 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 9569 WMITLV_GET_STRUCT_TLVLEN 9570 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 9571 9572 cmd->vdev_id = param->vdev_id; 9573 9574 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 9575 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9576 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 9577 9578 if (QDF_IS_STATUS_ERROR(ret)) { 9579 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9580 wmi_buf_free(buf); 9581 return QDF_STATUS_E_FAILURE; 9582 } 9583 9584 return QDF_STATUS_SUCCESS; 9585 } 9586 #endif 9587 9588 /** 9589 * init_cmd_send_tlv() - send initialization cmd to fw 9590 * @wmi_handle: wmi handle 9591 * @param param: pointer to wmi init param 9592 * 9593 * Return: QDF_STATUS_SUCCESS for success or error code 9594 */ 9595 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 9596 struct wmi_init_cmd_param *param) 9597 { 9598 wmi_buf_t buf; 9599 wmi_init_cmd_fixed_param *cmd; 9600 uint8_t *buf_ptr; 9601 wmi_resource_config *resource_cfg; 9602 wlan_host_memory_chunk *host_mem_chunks; 9603 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 9604 uint16_t idx; 9605 int len; 9606 QDF_STATUS ret; 9607 9608 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 9609 WMI_TLV_HDR_SIZE; 9610 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 9611 9612 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 9613 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9614 WMI_TLV_HDR_SIZE + 9615 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 9616 9617 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 9618 if (!buf) 9619 return QDF_STATUS_E_FAILURE; 9620 9621 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9622 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 9623 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 9624 9625 host_mem_chunks = (wlan_host_memory_chunk *) 9626 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 9627 + WMI_TLV_HDR_SIZE); 9628 9629 WMITLV_SET_HDR(&cmd->tlv_header, 9630 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 9631 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 9632 wmi_copy_resource_config(resource_cfg, param->res_cfg); 9633 WMITLV_SET_HDR(&resource_cfg->tlv_header, 9634 WMITLV_TAG_STRUC_wmi_resource_config, 9635 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 9636 9637 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 9638 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 9639 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 9640 WMITLV_GET_STRUCT_TLVLEN 9641 (wlan_host_memory_chunk)); 9642 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 9643 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 9644 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 9645 if (is_service_enabled_tlv(wmi_handle, 9646 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 9647 host_mem_chunks[idx].ptr_high = 9648 qdf_get_upper_32_bits( 9649 param->mem_chunks[idx].paddr); 9650 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 9651 "chunk %d len %d requested ,ptr 0x%x ", 9652 idx, host_mem_chunks[idx].size, 9653 host_mem_chunks[idx].ptr); 9654 } 9655 cmd->num_host_mem_chunks = param->num_mem_chunks; 9656 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 9657 9658 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 9659 WMITLV_TAG_ARRAY_STRUC, 9660 (sizeof(wlan_host_memory_chunk) * 9661 param->num_mem_chunks)); 9662 9663 wmi_debug("num peers: %d , num offload peers: %d, num vdevs: %d, num tids: %d, num tdls conn tb entries: %d, num tdls vdevs: %d", 9664 resource_cfg->num_peers, resource_cfg->num_offload_peers, 9665 resource_cfg->num_vdevs, resource_cfg->num_tids, 9666 resource_cfg->num_tdls_conn_table_entries, 9667 resource_cfg->num_tdls_vdevs); 9668 9669 /* Fill hw mode id config */ 9670 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 9671 9672 /* Fill fw_abi_vers */ 9673 copy_fw_abi_version_tlv(wmi_handle, cmd); 9674 9675 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 9676 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 9677 if (QDF_IS_STATUS_ERROR(ret)) { 9678 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 9679 ret); 9680 wmi_buf_free(buf); 9681 } 9682 9683 return ret; 9684 9685 } 9686 9687 /** 9688 * send_addba_send_cmd_tlv() - send addba send command to fw 9689 * @wmi_handle: wmi handle 9690 * @param: pointer to delba send params 9691 * @macaddr: peer mac address 9692 * 9693 * Send WMI_ADDBA_SEND_CMDID command to firmware 9694 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 9695 */ 9696 static QDF_STATUS 9697 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 9698 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9699 struct addba_send_params *param) 9700 { 9701 wmi_addba_send_cmd_fixed_param *cmd; 9702 wmi_buf_t buf; 9703 uint16_t len; 9704 QDF_STATUS ret; 9705 9706 len = sizeof(*cmd); 9707 9708 buf = wmi_buf_alloc(wmi_handle, len); 9709 if (!buf) 9710 return QDF_STATUS_E_NOMEM; 9711 9712 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 9713 9714 WMITLV_SET_HDR(&cmd->tlv_header, 9715 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 9716 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 9717 9718 cmd->vdev_id = param->vdev_id; 9719 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9720 cmd->tid = param->tidno; 9721 cmd->buffersize = param->buffersize; 9722 9723 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 9724 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 9725 if (QDF_IS_STATUS_ERROR(ret)) { 9726 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9727 wmi_buf_free(buf); 9728 return QDF_STATUS_E_FAILURE; 9729 } 9730 9731 return QDF_STATUS_SUCCESS; 9732 } 9733 9734 /** 9735 * send_delba_send_cmd_tlv() - send delba send command to fw 9736 * @wmi_handle: wmi handle 9737 * @param: pointer to delba send params 9738 * @macaddr: peer mac address 9739 * 9740 * Send WMI_DELBA_SEND_CMDID command to firmware 9741 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 9742 */ 9743 static QDF_STATUS 9744 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 9745 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9746 struct delba_send_params *param) 9747 { 9748 wmi_delba_send_cmd_fixed_param *cmd; 9749 wmi_buf_t buf; 9750 uint16_t len; 9751 QDF_STATUS ret; 9752 9753 len = sizeof(*cmd); 9754 9755 buf = wmi_buf_alloc(wmi_handle, len); 9756 if (!buf) 9757 return QDF_STATUS_E_NOMEM; 9758 9759 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 9760 9761 WMITLV_SET_HDR(&cmd->tlv_header, 9762 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 9763 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 9764 9765 cmd->vdev_id = param->vdev_id; 9766 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9767 cmd->tid = param->tidno; 9768 cmd->initiator = param->initiator; 9769 cmd->reasoncode = param->reasoncode; 9770 9771 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 9772 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 9773 if (QDF_IS_STATUS_ERROR(ret)) { 9774 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9775 wmi_buf_free(buf); 9776 return QDF_STATUS_E_FAILURE; 9777 } 9778 9779 return QDF_STATUS_SUCCESS; 9780 } 9781 9782 /** 9783 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 9784 * to fw 9785 * @wmi_handle: wmi handle 9786 * @param: pointer to addba clearresp params 9787 * @macaddr: peer mac address 9788 * Return: 0 for success or error code 9789 */ 9790 static QDF_STATUS 9791 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 9792 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9793 struct addba_clearresponse_params *param) 9794 { 9795 wmi_addba_clear_resp_cmd_fixed_param *cmd; 9796 wmi_buf_t buf; 9797 uint16_t len; 9798 QDF_STATUS ret; 9799 9800 len = sizeof(*cmd); 9801 9802 buf = wmi_buf_alloc(wmi_handle, len); 9803 if (!buf) 9804 return QDF_STATUS_E_FAILURE; 9805 9806 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 9807 9808 WMITLV_SET_HDR(&cmd->tlv_header, 9809 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 9810 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 9811 9812 cmd->vdev_id = param->vdev_id; 9813 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9814 9815 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 9816 ret = wmi_unified_cmd_send(wmi_handle, 9817 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 9818 if (QDF_IS_STATUS_ERROR(ret)) { 9819 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9820 wmi_buf_free(buf); 9821 return QDF_STATUS_E_FAILURE; 9822 } 9823 9824 return QDF_STATUS_SUCCESS; 9825 } 9826 9827 #ifdef OBSS_PD 9828 /** 9829 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 9830 * def thresh to fw 9831 * @wmi_handle: wmi handle 9832 * @thresh: pointer to obss_spatial_reuse_def_thresh 9833 * 9834 * Return: QDF_STATUS_SUCCESS for success or error code 9835 */ 9836 static 9837 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 9838 wmi_unified_t wmi_handle, 9839 struct wmi_host_obss_spatial_reuse_set_def_thresh 9840 *thresh) 9841 { 9842 wmi_buf_t buf; 9843 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 9844 QDF_STATUS ret; 9845 uint32_t cmd_len; 9846 uint32_t tlv_len; 9847 9848 cmd_len = sizeof(*cmd); 9849 9850 buf = wmi_buf_alloc(wmi_handle, cmd_len); 9851 if (!buf) 9852 return QDF_STATUS_E_NOMEM; 9853 9854 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 9855 wmi_buf_data(buf); 9856 9857 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 9858 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 9859 9860 WMITLV_SET_HDR(&cmd->tlv_header, 9861 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 9862 tlv_len); 9863 9864 cmd->obss_min = thresh->obss_min; 9865 cmd->obss_max = thresh->obss_max; 9866 cmd->vdev_type = thresh->vdev_type; 9867 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 9868 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 9869 if (QDF_IS_STATUS_ERROR(ret)) 9870 wmi_buf_free(buf); 9871 9872 return ret; 9873 } 9874 9875 /** 9876 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 9877 * @wmi_handle: wmi handle 9878 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 9879 * 9880 * Return: QDF_STATUS_SUCCESS for success or error code 9881 */ 9882 static 9883 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 9884 struct wmi_host_obss_spatial_reuse_set_param 9885 *obss_spatial_reuse_param) 9886 { 9887 wmi_buf_t buf; 9888 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 9889 QDF_STATUS ret; 9890 uint32_t len; 9891 9892 len = sizeof(*cmd); 9893 9894 buf = wmi_buf_alloc(wmi_handle, len); 9895 if (!buf) 9896 return QDF_STATUS_E_FAILURE; 9897 9898 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 9899 WMITLV_SET_HDR(&cmd->tlv_header, 9900 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 9901 WMITLV_GET_STRUCT_TLVLEN 9902 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 9903 9904 cmd->enable = obss_spatial_reuse_param->enable; 9905 cmd->obss_min = obss_spatial_reuse_param->obss_min; 9906 cmd->obss_max = obss_spatial_reuse_param->obss_max; 9907 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 9908 9909 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9910 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 9911 9912 if (QDF_IS_STATUS_ERROR(ret)) { 9913 wmi_err( 9914 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 9915 ret); 9916 wmi_buf_free(buf); 9917 } 9918 9919 return ret; 9920 } 9921 9922 /** 9923 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 9924 * to be used by SRG based Spatial Reuse feature to the FW 9925 * @wmi_handle: wmi handle 9926 * @bitmap_0: lower 32 bits in BSS color bitmap 9927 * @bitmap_1: upper 32 bits in BSS color bitmap 9928 * @pdev_id: pdev ID 9929 * 9930 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9931 */ 9932 static QDF_STATUS 9933 send_self_srg_bss_color_bitmap_set_cmd_tlv( 9934 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9935 uint32_t bitmap_1, uint8_t pdev_id) 9936 { 9937 wmi_buf_t buf; 9938 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 9939 QDF_STATUS ret; 9940 uint32_t len; 9941 9942 len = sizeof(*cmd); 9943 9944 buf = wmi_buf_alloc(wmi_handle, len); 9945 if (!buf) 9946 return QDF_STATUS_E_FAILURE; 9947 9948 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 9949 wmi_buf_data(buf); 9950 9951 WMITLV_SET_HDR( 9952 &cmd->tlv_header, 9953 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 9954 WMITLV_GET_STRUCT_TLVLEN 9955 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 9956 9957 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9958 wmi_handle, pdev_id); 9959 cmd->srg_bss_color_bitmap[0] = bitmap_0; 9960 cmd->srg_bss_color_bitmap[1] = bitmap_1; 9961 9962 ret = wmi_unified_cmd_send( 9963 wmi_handle, buf, len, 9964 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 9965 9966 if (QDF_IS_STATUS_ERROR(ret)) { 9967 wmi_err( 9968 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 9969 ret); 9970 wmi_buf_free(buf); 9971 } 9972 9973 return ret; 9974 } 9975 9976 /** 9977 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 9978 * bitmap to be used by SRG based Spatial Reuse feature to the FW 9979 * @wmi_handle: wmi handle 9980 * @bitmap_0: lower 32 bits in partial BSSID bitmap 9981 * @bitmap_1: upper 32 bits in partial BSSID bitmap 9982 * @pdev_id: pdev ID 9983 * 9984 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9985 */ 9986 static QDF_STATUS 9987 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 9988 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9989 uint32_t bitmap_1, uint8_t pdev_id) 9990 { 9991 wmi_buf_t buf; 9992 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 9993 QDF_STATUS ret; 9994 uint32_t len; 9995 9996 len = sizeof(*cmd); 9997 9998 buf = wmi_buf_alloc(wmi_handle, len); 9999 if (!buf) 10000 return QDF_STATUS_E_FAILURE; 10001 10002 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 10003 wmi_buf_data(buf); 10004 10005 WMITLV_SET_HDR( 10006 &cmd->tlv_header, 10007 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 10008 WMITLV_GET_STRUCT_TLVLEN 10009 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 10010 10011 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10012 wmi_handle, pdev_id); 10013 10014 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 10015 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 10016 10017 ret = wmi_unified_cmd_send( 10018 wmi_handle, buf, len, 10019 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 10020 10021 if (QDF_IS_STATUS_ERROR(ret)) { 10022 wmi_err( 10023 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 10024 ret); 10025 wmi_buf_free(buf); 10026 } 10027 10028 return ret; 10029 } 10030 10031 /** 10032 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10033 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10034 * @wmi_handle: wmi handle 10035 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10036 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10037 * @pdev_id: pdev ID 10038 * 10039 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10040 */ 10041 static QDF_STATUS 10042 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 10043 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10044 uint32_t bitmap_1, uint8_t pdev_id) 10045 { 10046 wmi_buf_t buf; 10047 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10048 QDF_STATUS ret; 10049 uint32_t len; 10050 10051 len = sizeof(*cmd); 10052 10053 buf = wmi_buf_alloc(wmi_handle, len); 10054 if (!buf) 10055 return QDF_STATUS_E_FAILURE; 10056 10057 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10058 wmi_buf_data(buf); 10059 10060 WMITLV_SET_HDR( 10061 &cmd->tlv_header, 10062 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 10063 WMITLV_GET_STRUCT_TLVLEN 10064 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10065 10066 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10067 wmi_handle, pdev_id); 10068 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 10069 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 10070 10071 ret = wmi_unified_cmd_send( 10072 wmi_handle, buf, len, 10073 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10074 10075 if (QDF_IS_STATUS_ERROR(ret)) { 10076 wmi_err( 10077 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10078 ret); 10079 wmi_buf_free(buf); 10080 } 10081 10082 return ret; 10083 } 10084 10085 /** 10086 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10087 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10088 * @wmi_handle: wmi handle 10089 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10090 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10091 * @pdev_id: pdev ID 10092 * 10093 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10094 */ 10095 static QDF_STATUS 10096 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 10097 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10098 uint32_t bitmap_1, uint8_t pdev_id) 10099 { 10100 wmi_buf_t buf; 10101 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10102 QDF_STATUS ret; 10103 uint32_t len; 10104 10105 len = sizeof(*cmd); 10106 10107 buf = wmi_buf_alloc(wmi_handle, len); 10108 if (!buf) 10109 return QDF_STATUS_E_FAILURE; 10110 10111 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10112 wmi_buf_data(buf); 10113 10114 WMITLV_SET_HDR( 10115 &cmd->tlv_header, 10116 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10117 WMITLV_GET_STRUCT_TLVLEN 10118 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10119 10120 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10121 wmi_handle, pdev_id); 10122 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 10123 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 10124 10125 ret = wmi_unified_cmd_send( 10126 wmi_handle, buf, len, 10127 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10128 10129 if (QDF_IS_STATUS_ERROR(ret)) { 10130 wmi_err( 10131 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10132 ret); 10133 wmi_buf_free(buf); 10134 } 10135 10136 return ret; 10137 } 10138 10139 /** 10140 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10141 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10142 * @wmi_handle: wmi handle 10143 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10144 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10145 * @pdev_id: pdev ID 10146 * 10147 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10148 */ 10149 static QDF_STATUS 10150 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 10151 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10152 uint32_t bitmap_1, uint8_t pdev_id) 10153 { 10154 wmi_buf_t buf; 10155 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10156 QDF_STATUS ret; 10157 uint32_t len; 10158 10159 len = sizeof(*cmd); 10160 10161 buf = wmi_buf_alloc(wmi_handle, len); 10162 if (!buf) 10163 return QDF_STATUS_E_FAILURE; 10164 10165 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10166 wmi_buf_data(buf); 10167 10168 WMITLV_SET_HDR( 10169 &cmd->tlv_header, 10170 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 10171 WMITLV_GET_STRUCT_TLVLEN 10172 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10173 10174 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10175 wmi_handle, pdev_id); 10176 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 10177 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 10178 10179 ret = wmi_unified_cmd_send( 10180 wmi_handle, buf, len, 10181 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10182 10183 if (QDF_IS_STATUS_ERROR(ret)) { 10184 wmi_err( 10185 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10186 ret); 10187 wmi_buf_free(buf); 10188 } 10189 10190 return ret; 10191 } 10192 10193 /** 10194 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10195 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10196 * @wmi_handle: wmi handle 10197 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10198 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10199 * @pdev_id: pdev ID 10200 * 10201 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10202 */ 10203 static QDF_STATUS 10204 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 10205 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10206 uint32_t bitmap_1, uint8_t pdev_id) 10207 { 10208 wmi_buf_t buf; 10209 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10210 QDF_STATUS ret; 10211 uint32_t len; 10212 10213 len = sizeof(*cmd); 10214 10215 buf = wmi_buf_alloc(wmi_handle, len); 10216 if (!buf) 10217 return QDF_STATUS_E_FAILURE; 10218 10219 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10220 wmi_buf_data(buf); 10221 10222 WMITLV_SET_HDR( 10223 &cmd->tlv_header, 10224 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10225 WMITLV_GET_STRUCT_TLVLEN 10226 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10227 10228 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10229 wmi_handle, pdev_id); 10230 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 10231 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 10232 10233 ret = wmi_unified_cmd_send( 10234 wmi_handle, buf, len, 10235 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10236 10237 if (QDF_IS_STATUS_ERROR(ret)) { 10238 wmi_err( 10239 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10240 ret); 10241 wmi_buf_free(buf); 10242 } 10243 10244 return ret; 10245 } 10246 #endif 10247 10248 static 10249 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 10250 struct wmi_host_injector_frame_params *inject_config_params) 10251 { 10252 wmi_buf_t buf; 10253 wmi_frame_inject_cmd_fixed_param *cmd; 10254 QDF_STATUS ret; 10255 uint32_t len; 10256 10257 len = sizeof(*cmd); 10258 10259 buf = wmi_buf_alloc(wmi_handle, len); 10260 if (!buf) 10261 return QDF_STATUS_E_NOMEM; 10262 10263 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 10264 WMITLV_SET_HDR(&cmd->tlv_header, 10265 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 10266 WMITLV_GET_STRUCT_TLVLEN 10267 (wmi_frame_inject_cmd_fixed_param)); 10268 10269 cmd->vdev_id = inject_config_params->vdev_id; 10270 cmd->enable = inject_config_params->enable; 10271 cmd->frame_type = inject_config_params->frame_type; 10272 cmd->frame_inject_period = inject_config_params->frame_inject_period; 10273 cmd->fc_duration = inject_config_params->frame_duration; 10274 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 10275 &cmd->frame_addr1); 10276 10277 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10278 WMI_PDEV_FRAME_INJECT_CMDID); 10279 10280 if (QDF_IS_STATUS_ERROR(ret)) { 10281 wmi_err( 10282 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 10283 ret); 10284 wmi_buf_free(buf); 10285 } 10286 10287 return ret; 10288 } 10289 #ifdef QCA_SUPPORT_CP_STATS 10290 /** 10291 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 10292 * @wmi_handle: wma handle 10293 * @evt_buf: event buffer 10294 * @out_buff: buffer to populated after stats extraction 10295 * 10296 * Return: status of operation 10297 */ 10298 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 10299 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 10300 { 10301 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10302 wmi_congestion_stats *congestion_stats; 10303 10304 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10305 congestion_stats = param_buf->congestion_stats; 10306 if (!congestion_stats) 10307 return QDF_STATUS_E_INVAL; 10308 10309 out_buff->vdev_id = congestion_stats->vdev_id; 10310 out_buff->congestion = congestion_stats->congestion; 10311 10312 wmi_debug("cca stats event processed"); 10313 return QDF_STATUS_SUCCESS; 10314 } 10315 #endif /* QCA_SUPPORT_CP_STATS */ 10316 10317 /** 10318 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 10319 * event 10320 * @wmi_handle: wmi handle 10321 * @param evt_buf: pointer to event buffer 10322 * @param param: Pointer to hold peer ctl data 10323 * 10324 * Return: QDF_STATUS_SUCCESS for success or error code 10325 */ 10326 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 10327 wmi_unified_t wmi_handle, 10328 void *evt_buf, 10329 struct wmi_host_pdev_ctl_failsafe_event *param) 10330 { 10331 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 10332 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 10333 10334 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 10335 if (!param_buf) { 10336 wmi_err("Invalid ctl_failsafe event buffer"); 10337 return QDF_STATUS_E_INVAL; 10338 } 10339 10340 fix_param = param_buf->fixed_param; 10341 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 10342 10343 return QDF_STATUS_SUCCESS; 10344 } 10345 10346 /** 10347 * save_service_bitmap_tlv() - save service bitmap 10348 * @wmi_handle: wmi handle 10349 * @param evt_buf: pointer to event buffer 10350 * @param bitmap_buf: bitmap buffer, for converged legacy support 10351 * 10352 * Return: QDF_STATUS 10353 */ 10354 static 10355 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10356 void *bitmap_buf) 10357 { 10358 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10359 struct wmi_soc *soc = wmi_handle->soc; 10360 10361 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10362 10363 /* If it is already allocated, use that buffer. This can happen 10364 * during target stop/start scenarios where host allocation is skipped. 10365 */ 10366 if (!soc->wmi_service_bitmap) { 10367 soc->wmi_service_bitmap = 10368 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 10369 if (!soc->wmi_service_bitmap) 10370 return QDF_STATUS_E_NOMEM; 10371 } 10372 10373 qdf_mem_copy(soc->wmi_service_bitmap, 10374 param_buf->wmi_service_bitmap, 10375 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 10376 10377 if (bitmap_buf) 10378 qdf_mem_copy(bitmap_buf, 10379 param_buf->wmi_service_bitmap, 10380 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 10381 10382 return QDF_STATUS_SUCCESS; 10383 } 10384 10385 /** 10386 * save_ext_service_bitmap_tlv() - save extendend service bitmap 10387 * @wmi_handle: wmi handle 10388 * @param evt_buf: pointer to event buffer 10389 * @param bitmap_buf: bitmap buffer, for converged legacy support 10390 * 10391 * Return: QDF_STATUS 10392 */ 10393 static 10394 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10395 void *bitmap_buf) 10396 { 10397 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 10398 wmi_service_available_event_fixed_param *ev; 10399 struct wmi_soc *soc = wmi_handle->soc; 10400 uint32_t i = 0; 10401 10402 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 10403 10404 ev = param_buf->fixed_param; 10405 10406 /* If it is already allocated, use that buffer. This can happen 10407 * during target stop/start scenarios where host allocation is skipped. 10408 */ 10409 if (!soc->wmi_ext_service_bitmap) { 10410 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 10411 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 10412 if (!soc->wmi_ext_service_bitmap) 10413 return QDF_STATUS_E_NOMEM; 10414 } 10415 10416 qdf_mem_copy(soc->wmi_ext_service_bitmap, 10417 ev->wmi_service_segment_bitmap, 10418 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 10419 10420 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 10421 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 10422 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 10423 10424 if (bitmap_buf) 10425 qdf_mem_copy(bitmap_buf, 10426 soc->wmi_ext_service_bitmap, 10427 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 10428 10429 if (!param_buf->wmi_service_ext_bitmap) { 10430 wmi_debug("wmi_service_ext_bitmap not available"); 10431 return QDF_STATUS_SUCCESS; 10432 } 10433 10434 if (!soc->wmi_ext2_service_bitmap) { 10435 soc->wmi_ext2_service_bitmap = 10436 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 10437 sizeof(uint32_t)); 10438 if (!soc->wmi_ext2_service_bitmap) 10439 return QDF_STATUS_E_NOMEM; 10440 } 10441 10442 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 10443 param_buf->wmi_service_ext_bitmap, 10444 (param_buf->num_wmi_service_ext_bitmap * 10445 sizeof(uint32_t))); 10446 10447 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 10448 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 10449 i, soc->wmi_ext2_service_bitmap[i]); 10450 } 10451 10452 return QDF_STATUS_SUCCESS; 10453 } 10454 10455 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 10456 struct wlan_psoc_target_capability_info *cap) 10457 { 10458 /* except LDPC all flags are common betwen legacy and here 10459 * also IBFEER is not defined for TLV 10460 */ 10461 cap->ht_cap_info |= ev_target_cap & ( 10462 WMI_HT_CAP_ENABLED 10463 | WMI_HT_CAP_HT20_SGI 10464 | WMI_HT_CAP_DYNAMIC_SMPS 10465 | WMI_HT_CAP_TX_STBC 10466 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 10467 | WMI_HT_CAP_RX_STBC 10468 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 10469 | WMI_HT_CAP_LDPC 10470 | WMI_HT_CAP_L_SIG_TXOP_PROT 10471 | WMI_HT_CAP_MPDU_DENSITY 10472 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 10473 | WMI_HT_CAP_HT40_SGI); 10474 if (ev_target_cap & WMI_HT_CAP_LDPC) 10475 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 10476 WMI_HOST_HT_CAP_TX_LDPC; 10477 } 10478 /** 10479 * extract_service_ready_tlv() - extract service ready event 10480 * @wmi_handle: wmi handle 10481 * @param evt_buf: pointer to received event buffer 10482 * @param cap: pointer to hold target capability information extracted from even 10483 * 10484 * Return: QDF_STATUS_SUCCESS for success or error code 10485 */ 10486 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 10487 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 10488 { 10489 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10490 wmi_service_ready_event_fixed_param *ev; 10491 10492 10493 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10494 10495 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10496 if (!ev) { 10497 qdf_print("%s: wmi_buf_alloc failed", __func__); 10498 return QDF_STATUS_E_FAILURE; 10499 } 10500 10501 cap->phy_capability = ev->phy_capability; 10502 cap->max_frag_entry = ev->max_frag_entry; 10503 cap->num_rf_chains = ev->num_rf_chains; 10504 copy_ht_cap_info(ev->ht_cap_info, cap); 10505 cap->vht_cap_info = ev->vht_cap_info; 10506 cap->vht_supp_mcs = ev->vht_supp_mcs; 10507 cap->hw_min_tx_power = ev->hw_min_tx_power; 10508 cap->hw_max_tx_power = ev->hw_max_tx_power; 10509 cap->sys_cap_info = ev->sys_cap_info; 10510 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 10511 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 10512 cap->max_num_scan_channels = ev->max_num_scan_channels; 10513 cap->max_supported_macs = ev->max_supported_macs; 10514 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 10515 cap->txrx_chainmask = ev->txrx_chainmask; 10516 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 10517 cap->num_msdu_desc = ev->num_msdu_desc; 10518 cap->fw_version = ev->fw_build_vers; 10519 /* fw_version_1 is not available in TLV. */ 10520 cap->fw_version_1 = 0; 10521 10522 return QDF_STATUS_SUCCESS; 10523 } 10524 10525 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 10526 * to host internal HOST_REGDMN_MODE values. 10527 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 10528 * host currently. Add this in the future if required. 10529 * 11AX (Phase II) : 11ax related values are not currently 10530 * advertised separately by FW. As part of phase II regulatory bring-up, 10531 * finalize the advertisement mechanism. 10532 * @target_wireless_mode: target wireless mode received in message 10533 * 10534 * Return: returns the host internal wireless mode. 10535 */ 10536 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 10537 { 10538 10539 uint32_t wireless_modes = 0; 10540 10541 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 10542 10543 if (target_wireless_mode & REGDMN_MODE_11A) 10544 wireless_modes |= HOST_REGDMN_MODE_11A; 10545 10546 if (target_wireless_mode & REGDMN_MODE_TURBO) 10547 wireless_modes |= HOST_REGDMN_MODE_TURBO; 10548 10549 if (target_wireless_mode & REGDMN_MODE_11B) 10550 wireless_modes |= HOST_REGDMN_MODE_11B; 10551 10552 if (target_wireless_mode & REGDMN_MODE_PUREG) 10553 wireless_modes |= HOST_REGDMN_MODE_PUREG; 10554 10555 if (target_wireless_mode & REGDMN_MODE_11G) 10556 wireless_modes |= HOST_REGDMN_MODE_11G; 10557 10558 if (target_wireless_mode & REGDMN_MODE_108G) 10559 wireless_modes |= HOST_REGDMN_MODE_108G; 10560 10561 if (target_wireless_mode & REGDMN_MODE_108A) 10562 wireless_modes |= HOST_REGDMN_MODE_108A; 10563 10564 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 10565 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 10566 10567 if (target_wireless_mode & REGDMN_MODE_XR) 10568 wireless_modes |= HOST_REGDMN_MODE_XR; 10569 10570 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 10571 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 10572 10573 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 10574 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 10575 10576 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 10577 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 10578 10579 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 10580 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 10581 10582 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 10583 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 10584 10585 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 10586 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 10587 10588 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 10589 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 10590 10591 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 10592 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 10593 10594 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 10595 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 10596 10597 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 10598 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 10599 10600 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 10601 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 10602 10603 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 10604 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 10605 10606 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 10607 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 10608 10609 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 10610 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 10611 10612 return wireless_modes; 10613 } 10614 10615 /** 10616 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 10617 * to regulatory flags. 10618 * @target_phybitmap: target phybitmap. 10619 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 10620 * phybitmap. 10621 * 10622 * Return: None 10623 */ 10624 10625 #ifdef WLAN_FEATURE_11BE 10626 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 10627 uint32_t *phybitmap) 10628 { 10629 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 10630 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 10631 } 10632 #else 10633 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 10634 uint32_t *phybitmap) 10635 { 10636 } 10637 #endif 10638 10639 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 10640 * target to host internal REGULATORY_PHYMODE values. 10641 * 10642 * @target_target_phybitmap: target phybitmap received in the message. 10643 * 10644 * Return: returns the host internal REGULATORY_PHYMODE. 10645 */ 10646 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 10647 { 10648 uint32_t phybitmap = 0; 10649 10650 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 10651 10652 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 10653 phybitmap |= REGULATORY_PHYMODE_NO11A; 10654 10655 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 10656 phybitmap |= REGULATORY_PHYMODE_NO11B; 10657 10658 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 10659 phybitmap |= REGULATORY_PHYMODE_NO11G; 10660 10661 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 10662 phybitmap |= REGULATORY_CHAN_NO11N; 10663 10664 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 10665 phybitmap |= REGULATORY_PHYMODE_NO11AC; 10666 10667 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 10668 phybitmap |= REGULATORY_PHYMODE_NO11AX; 10669 10670 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 10671 10672 return phybitmap; 10673 } 10674 10675 /** 10676 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 10677 * advertised by the target to wireless mode ext flags. 10678 * @target_wireless_modes_ext: Target wireless mode 10679 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 10680 * 10681 * Return: None 10682 */ 10683 #ifdef WLAN_FEATURE_11BE 10684 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 10685 uint64_t *wireless_modes_ext) 10686 { 10687 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 10688 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 10689 10690 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 10691 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 10692 10693 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 10694 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 10695 10696 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 10697 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 10698 10699 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 10700 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 10701 10702 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 10703 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 10704 10705 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 10706 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 10707 10708 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 10709 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 10710 10711 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 10712 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 10713 } 10714 #else 10715 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 10716 uint64_t *wireless_modes_ext) 10717 { 10718 } 10719 #endif 10720 10721 static inline uint64_t convert_wireless_modes_ext_tlv( 10722 uint32_t target_wireless_modes_ext) 10723 { 10724 uint64_t wireless_modes_ext = 0; 10725 10726 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 10727 10728 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 10729 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 10730 10731 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 10732 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 10733 10734 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 10735 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 10736 10737 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 10738 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 10739 10740 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 10741 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 10742 10743 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 10744 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 10745 10746 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 10747 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 10748 10749 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 10750 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 10751 10752 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 10753 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 10754 10755 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 10756 &wireless_modes_ext); 10757 10758 return wireless_modes_ext; 10759 } 10760 10761 /** 10762 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 10763 * @wmi_handle: wmi handle 10764 * @param evt_buf: Pointer to event buffer 10765 * @param cap: pointer to hold HAL reg capabilities 10766 * 10767 * Return: QDF_STATUS_SUCCESS for success or error code 10768 */ 10769 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 10770 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 10771 { 10772 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10773 10774 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10775 if (!param_buf || !param_buf->hal_reg_capabilities) { 10776 wmi_err("Invalid arguments"); 10777 return QDF_STATUS_E_FAILURE; 10778 } 10779 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 10780 sizeof(uint32_t)), 10781 sizeof(struct wlan_psoc_hal_reg_capability)); 10782 10783 cap->wireless_modes = convert_wireless_modes_tlv( 10784 param_buf->hal_reg_capabilities->wireless_modes); 10785 10786 return QDF_STATUS_SUCCESS; 10787 } 10788 10789 /** 10790 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 10791 * @wmi_handle: wmi handle 10792 * @param evt_buf: Pointer to event buffer 10793 * @param cap: pointer to hold HAL reg capabilities 10794 * 10795 * Return: QDF_STATUS_SUCCESS for success or error code 10796 */ 10797 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 10798 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 10799 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 10800 { 10801 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 10802 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 10803 10804 if (!evt_buf) { 10805 wmi_err("null evt_buf"); 10806 return QDF_STATUS_E_INVAL; 10807 } 10808 10809 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 10810 10811 if (!param_buf->num_hal_reg_caps) 10812 return QDF_STATUS_SUCCESS; 10813 10814 if (phy_idx >= param_buf->num_hal_reg_caps) 10815 return QDF_STATUS_E_INVAL; 10816 10817 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 10818 10819 param->phy_id = reg_caps->phy_id; 10820 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 10821 reg_caps->wireless_modes_ext); 10822 10823 return QDF_STATUS_SUCCESS; 10824 } 10825 10826 /** 10827 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 10828 * @wmi_handle: wmi handle 10829 * @evt_buf: pointer to event buffer 10830 * 10831 * Return: Number of entries requested 10832 */ 10833 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 10834 void *evt_buf) 10835 { 10836 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10837 wmi_service_ready_event_fixed_param *ev; 10838 10839 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10840 10841 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10842 if (!ev) { 10843 qdf_print("%s: wmi_buf_alloc failed", __func__); 10844 return 0; 10845 } 10846 10847 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 10848 wmi_err("Invalid num_mem_reqs %d:%d", 10849 ev->num_mem_reqs, param_buf->num_mem_reqs); 10850 return 0; 10851 } 10852 10853 return ev->num_mem_reqs; 10854 } 10855 10856 /** 10857 * extract_host_mem_req_tlv() - Extract host memory required from 10858 * service ready event 10859 * @wmi_handle: wmi handle 10860 * @evt_buf: pointer to event buffer 10861 * @mem_reqs: pointer to host memory request structure 10862 * @num_active_peers: number of active peers for peer cache 10863 * @num_peers: number of peers 10864 * @fw_prio: FW priority 10865 * @idx: index for memory request 10866 * 10867 * Return: Host memory request parameters requested by target 10868 */ 10869 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 10870 void *evt_buf, 10871 host_mem_req *mem_reqs, 10872 uint32_t num_active_peers, 10873 uint32_t num_peers, 10874 enum wmi_fw_mem_prio fw_prio, 10875 uint16_t idx) 10876 { 10877 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10878 10879 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 10880 10881 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 10882 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 10883 mem_reqs->num_unit_info = 10884 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 10885 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 10886 mem_reqs->tgt_num_units = 0; 10887 10888 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 10889 (mem_reqs->num_unit_info & 10890 REQ_TO_HOST_FOR_CONT_MEMORY)) || 10891 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 10892 (!(mem_reqs->num_unit_info & 10893 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 10894 /* First allocate the memory that requires contiguous memory */ 10895 mem_reqs->tgt_num_units = mem_reqs->num_units; 10896 if (mem_reqs->num_unit_info) { 10897 if (mem_reqs->num_unit_info & 10898 NUM_UNITS_IS_NUM_PEERS) { 10899 /* 10900 * number of units allocated is equal to number 10901 * of peers, 1 extra for self peer on target. 10902 * this needs to be fixed, host and target can 10903 * get out of sync 10904 */ 10905 mem_reqs->tgt_num_units = num_peers + 1; 10906 } 10907 if (mem_reqs->num_unit_info & 10908 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 10909 /* 10910 * Requesting allocation of memory using 10911 * num_active_peers in qcache. if qcache is 10912 * disabled in host, then it should allocate 10913 * memory for num_peers instead of 10914 * num_active_peers. 10915 */ 10916 if (num_active_peers) 10917 mem_reqs->tgt_num_units = 10918 num_active_peers + 1; 10919 else 10920 mem_reqs->tgt_num_units = 10921 num_peers + 1; 10922 } 10923 } 10924 10925 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 10926 "unit size %d actual units %d", 10927 idx, mem_reqs->req_id, 10928 mem_reqs->num_units, 10929 mem_reqs->num_unit_info, 10930 mem_reqs->unit_size, 10931 mem_reqs->tgt_num_units); 10932 } 10933 10934 return QDF_STATUS_SUCCESS; 10935 } 10936 10937 /** 10938 * save_fw_version_in_service_ready_tlv() - Save fw version in service 10939 * ready function 10940 * @wmi_handle: wmi handle 10941 * @param evt_buf: pointer to event buffer 10942 * 10943 * Return: QDF_STATUS_SUCCESS for success or error code 10944 */ 10945 static QDF_STATUS 10946 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10947 { 10948 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10949 wmi_service_ready_event_fixed_param *ev; 10950 10951 10952 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10953 10954 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10955 if (!ev) { 10956 qdf_print("%s: wmi_buf_alloc failed", __func__); 10957 return QDF_STATUS_E_FAILURE; 10958 } 10959 10960 /*Save fw version from service ready message */ 10961 /*This will be used while sending INIT message */ 10962 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10963 sizeof(wmi_handle->fw_abi_version)); 10964 10965 return QDF_STATUS_SUCCESS; 10966 } 10967 10968 /** 10969 * ready_extract_init_status_tlv() - Extract init status from ready event 10970 * @wmi_handle: wmi handle 10971 * @param evt_buf: Pointer to event buffer 10972 * 10973 * Return: ready status 10974 */ 10975 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 10976 void *evt_buf) 10977 { 10978 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10979 wmi_ready_event_fixed_param *ev = NULL; 10980 10981 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10982 ev = param_buf->fixed_param; 10983 10984 qdf_print("%s:%d", __func__, ev->status); 10985 10986 return ev->status; 10987 } 10988 10989 /** 10990 * ready_extract_mac_addr_tlv() - extract mac address from ready event 10991 * @wmi_handle: wmi handle 10992 * @param evt_buf: pointer to event buffer 10993 * @param macaddr: Pointer to hold MAC address 10994 * 10995 * Return: QDF_STATUS_SUCCESS for success or error code 10996 */ 10997 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 10998 void *evt_buf, uint8_t *macaddr) 10999 { 11000 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11001 wmi_ready_event_fixed_param *ev = NULL; 11002 11003 11004 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11005 ev = param_buf->fixed_param; 11006 11007 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 11008 11009 return QDF_STATUS_SUCCESS; 11010 } 11011 11012 /** 11013 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 11014 * @wmi_handle: wmi handle 11015 * @param evt_buf: pointer to event buffer 11016 * @param macaddr: Pointer to hold number of MAC addresses 11017 * 11018 * Return: Pointer to addr list 11019 */ 11020 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 11021 void *evt_buf, uint8_t *num_mac) 11022 { 11023 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11024 wmi_ready_event_fixed_param *ev = NULL; 11025 11026 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11027 ev = param_buf->fixed_param; 11028 11029 *num_mac = ev->num_extra_mac_addr; 11030 11031 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 11032 } 11033 11034 /** 11035 * extract_ready_params_tlv() - Extract data from ready event apart from 11036 * status, macaddr and version. 11037 * @wmi_handle: Pointer to WMI handle. 11038 * @evt_buf: Pointer to Ready event buffer. 11039 * @ev_param: Pointer to host defined struct to copy the data from event. 11040 * 11041 * Return: QDF_STATUS_SUCCESS on success. 11042 */ 11043 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 11044 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 11045 { 11046 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11047 wmi_ready_event_fixed_param *ev = NULL; 11048 11049 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11050 ev = param_buf->fixed_param; 11051 11052 ev_param->status = ev->status; 11053 ev_param->num_dscp_table = ev->num_dscp_table; 11054 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 11055 ev_param->num_total_peer = ev->num_total_peers; 11056 ev_param->num_extra_peer = ev->num_extra_peers; 11057 /* Agile_capability in ready event is supported in TLV target, 11058 * as per aDFS FR 11059 */ 11060 ev_param->max_ast_index = ev->max_ast_index; 11061 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 11062 ev_param->agile_capability = 1; 11063 11064 return QDF_STATUS_SUCCESS; 11065 } 11066 11067 /** 11068 * extract_dbglog_data_len_tlv() - extract debuglog data length 11069 * @wmi_handle: wmi handle 11070 * @param evt_buf: pointer to event buffer 11071 * 11072 * Return: length 11073 */ 11074 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 11075 void *evt_buf, uint32_t *len) 11076 { 11077 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 11078 11079 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 11080 11081 *len = param_buf->num_bufp; 11082 11083 return param_buf->bufp; 11084 } 11085 11086 11087 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 11088 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 11089 #else 11090 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 11091 ((_status) & WMI_RXERR_DECRYPT) 11092 #endif 11093 11094 /** 11095 * extract_mgmt_rx_params_tlv() - extract management rx params from event 11096 * @wmi_handle: wmi handle 11097 * @param evt_buf: pointer to event buffer 11098 * @param hdr: Pointer to hold header 11099 * @param bufp: Pointer to hold pointer to rx param buffer 11100 * 11101 * Return: QDF_STATUS_SUCCESS for success or error code 11102 */ 11103 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 11104 void *evt_buf, struct mgmt_rx_event_params *hdr, 11105 uint8_t **bufp) 11106 { 11107 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 11108 wmi_mgmt_rx_hdr *ev_hdr = NULL; 11109 int i; 11110 11111 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 11112 if (!param_tlvs) { 11113 wmi_err("Get NULL point message from FW"); 11114 return QDF_STATUS_E_INVAL; 11115 } 11116 11117 ev_hdr = param_tlvs->hdr; 11118 if (!hdr) { 11119 wmi_err("Rx event is NULL"); 11120 return QDF_STATUS_E_INVAL; 11121 } 11122 11123 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 11124 wmi_err("RX mgmt frame decrypt error, discard it"); 11125 return QDF_STATUS_E_INVAL; 11126 } 11127 11128 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 11129 wmi_err("Rx mgmt frame length mismatch, discard it"); 11130 return QDF_STATUS_E_INVAL; 11131 } 11132 11133 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11134 wmi_handle, 11135 ev_hdr->pdev_id); 11136 hdr->chan_freq = ev_hdr->chan_freq; 11137 hdr->channel = ev_hdr->channel; 11138 hdr->snr = ev_hdr->snr; 11139 hdr->rate = ev_hdr->rate; 11140 hdr->phy_mode = ev_hdr->phy_mode; 11141 hdr->buf_len = ev_hdr->buf_len; 11142 hdr->status = ev_hdr->status; 11143 hdr->flags = ev_hdr->flags; 11144 hdr->rssi = ev_hdr->rssi; 11145 hdr->tsf_delta = ev_hdr->tsf_delta; 11146 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 11147 for (i = 0; i < ATH_MAX_ANTENNA; i++) 11148 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 11149 11150 *bufp = param_tlvs->bufp; 11151 11152 return QDF_STATUS_SUCCESS; 11153 } 11154 11155 #ifdef WLAN_MGMT_RX_REO_SUPPORT 11156 /** 11157 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 11158 * @wmi_handle: wmi handle 11159 * @evt_buf: pointer to event buffer 11160 * @params: Pointer to MGMT Rx REO parameters 11161 * 11162 * Return: QDF_STATUS_SUCCESS for success or error code 11163 */ 11164 static QDF_STATUS 11165 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 11166 void *evt_buf, 11167 struct mgmt_rx_reo_params *params) 11168 { 11169 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 11170 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 11171 11172 param_tlvs = evt_buf; 11173 if (!param_tlvs) { 11174 wmi_err("param_tlvs is NULL"); 11175 return QDF_STATUS_E_INVAL; 11176 } 11177 11178 ev_hdr = param_tlvs->hdr; 11179 if (!params) { 11180 wmi_err("Rx REO parameters is NULL"); 11181 return QDF_STATUS_E_INVAL; 11182 } 11183 11184 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11185 wmi_handle, 11186 ev_hdr->pdev_id); 11187 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 11188 ev_hdr->mgmt_pkt_ctr_info); 11189 params->global_timestamp = ev_hdr->global_timestamp; 11190 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 11191 ev_hdr->mgmt_pkt_ctr_info); 11192 11193 return QDF_STATUS_SUCCESS; 11194 } 11195 11196 /** 11197 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 11198 * MGMT_RX_EVENT_ID 11199 * @wmi_handle: wmi handle 11200 * @evt_buf: pointer to event buffer 11201 * @params: Pointer to MGMT Rx REO parameters 11202 * 11203 * Return: QDF_STATUS_SUCCESS for success or error code 11204 */ 11205 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 11206 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 11207 { 11208 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 11209 wmi_mgmt_rx_reo_params *reo_params_tlv; 11210 wmi_mgmt_rx_hdr *ev_hdr; 11211 11212 param_tlvs = evt_buf; 11213 if (!param_tlvs) { 11214 wmi_err("param_tlvs is NULL"); 11215 return QDF_STATUS_E_INVAL; 11216 } 11217 11218 ev_hdr = param_tlvs->hdr; 11219 if (!ev_hdr) { 11220 wmi_err("Rx event is NULL"); 11221 return QDF_STATUS_E_INVAL; 11222 } 11223 11224 reo_params_tlv = param_tlvs->reo_params; 11225 if (!reo_params_tlv) { 11226 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 11227 return QDF_STATUS_E_INVAL; 11228 } 11229 11230 if (!reo_params) { 11231 wmi_err("MGMT Rx REO params is NULL"); 11232 return QDF_STATUS_E_INVAL; 11233 } 11234 11235 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11236 wmi_handle, 11237 ev_hdr->pdev_id); 11238 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 11239 reo_params_tlv->mgmt_pkt_ctr_link_info); 11240 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 11241 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 11242 reo_params_tlv->mgmt_pkt_ctr_link_info); 11243 11244 return QDF_STATUS_SUCCESS; 11245 } 11246 11247 /** 11248 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 11249 * configuration command 11250 * @wmi_handle: wmi handle 11251 * @pdev_id: pdev ID of the radio 11252 * @filter: Pointer to MGMT Rx REO filter 11253 * 11254 * Return: QDF_STATUS_SUCCESS for success or error code 11255 */ 11256 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 11257 wmi_unified_t wmi_handle, 11258 uint8_t pdev_id, 11259 struct mgmt_rx_reo_filter *filter) 11260 { 11261 QDF_STATUS ret; 11262 wmi_buf_t buf; 11263 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 11264 size_t len = sizeof(*cmd); 11265 11266 if (!filter) { 11267 wmi_err("mgmt_rx_reo_filter is NULL"); 11268 return QDF_STATUS_E_INVAL; 11269 } 11270 11271 buf = wmi_buf_alloc(wmi_handle, len); 11272 if (!buf) { 11273 wmi_err("wmi_buf_alloc failed"); 11274 return QDF_STATUS_E_NOMEM; 11275 } 11276 11277 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 11278 wmi_buf_data(buf); 11279 11280 WMITLV_SET_HDR(&cmd->tlv_header, 11281 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 11282 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 11283 11284 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 11285 wmi_handle, 11286 pdev_id); 11287 cmd->filter_low = filter->low; 11288 cmd->filter_high = filter->high; 11289 11290 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 11291 ret = wmi_unified_cmd_send( 11292 wmi_handle, buf, len, 11293 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 11294 11295 if (QDF_IS_STATUS_ERROR(ret)) { 11296 wmi_err("Failed to send WMI command"); 11297 wmi_buf_free(buf); 11298 } 11299 11300 return ret; 11301 } 11302 #endif 11303 11304 /** 11305 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 11306 * @wmi_handle: wmi handle 11307 * @param evt_buf: pointer to event buffer 11308 * @param param: Pointer to hold roam param 11309 * 11310 * Return: QDF_STATUS_SUCCESS for success or error code 11311 */ 11312 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 11313 void *evt_buf, wmi_host_roam_event *param) 11314 { 11315 WMI_ROAM_EVENTID_param_tlvs *param_buf; 11316 wmi_roam_event_fixed_param *evt; 11317 11318 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 11319 if (!param_buf) { 11320 wmi_err("Invalid roam event buffer"); 11321 return QDF_STATUS_E_INVAL; 11322 } 11323 11324 evt = param_buf->fixed_param; 11325 qdf_mem_zero(param, sizeof(*param)); 11326 11327 param->vdev_id = evt->vdev_id; 11328 param->reason = evt->reason; 11329 param->rssi = evt->rssi; 11330 11331 return QDF_STATUS_SUCCESS; 11332 } 11333 11334 /** 11335 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 11336 * @wmi_handle: wmi handle 11337 * @param evt_buf: pointer to event buffer 11338 * @param param: Pointer to hold vdev scan param 11339 * 11340 * Return: QDF_STATUS_SUCCESS for success or error code 11341 */ 11342 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 11343 void *evt_buf, struct scan_event *param) 11344 { 11345 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 11346 wmi_scan_event_fixed_param *evt = NULL; 11347 11348 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 11349 evt = param_buf->fixed_param; 11350 11351 qdf_mem_zero(param, sizeof(*param)); 11352 11353 switch (evt->event) { 11354 case WMI_SCAN_EVENT_STARTED: 11355 param->type = SCAN_EVENT_TYPE_STARTED; 11356 break; 11357 case WMI_SCAN_EVENT_COMPLETED: 11358 param->type = SCAN_EVENT_TYPE_COMPLETED; 11359 break; 11360 case WMI_SCAN_EVENT_BSS_CHANNEL: 11361 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 11362 break; 11363 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 11364 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 11365 break; 11366 case WMI_SCAN_EVENT_DEQUEUED: 11367 param->type = SCAN_EVENT_TYPE_DEQUEUED; 11368 break; 11369 case WMI_SCAN_EVENT_PREEMPTED: 11370 param->type = SCAN_EVENT_TYPE_PREEMPTED; 11371 break; 11372 case WMI_SCAN_EVENT_START_FAILED: 11373 param->type = SCAN_EVENT_TYPE_START_FAILED; 11374 break; 11375 case WMI_SCAN_EVENT_RESTARTED: 11376 param->type = SCAN_EVENT_TYPE_RESTARTED; 11377 break; 11378 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 11379 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 11380 break; 11381 case WMI_SCAN_EVENT_MAX: 11382 default: 11383 param->type = SCAN_EVENT_TYPE_MAX; 11384 break; 11385 }; 11386 11387 switch (evt->reason) { 11388 case WMI_SCAN_REASON_NONE: 11389 param->reason = SCAN_REASON_NONE; 11390 break; 11391 case WMI_SCAN_REASON_COMPLETED: 11392 param->reason = SCAN_REASON_COMPLETED; 11393 break; 11394 case WMI_SCAN_REASON_CANCELLED: 11395 param->reason = SCAN_REASON_CANCELLED; 11396 break; 11397 case WMI_SCAN_REASON_PREEMPTED: 11398 param->reason = SCAN_REASON_PREEMPTED; 11399 break; 11400 case WMI_SCAN_REASON_TIMEDOUT: 11401 param->reason = SCAN_REASON_TIMEDOUT; 11402 break; 11403 case WMI_SCAN_REASON_INTERNAL_FAILURE: 11404 param->reason = SCAN_REASON_INTERNAL_FAILURE; 11405 break; 11406 case WMI_SCAN_REASON_SUSPENDED: 11407 param->reason = SCAN_REASON_SUSPENDED; 11408 break; 11409 case WMI_SCAN_REASON_DFS_VIOLATION: 11410 param->reason = SCAN_REASON_DFS_VIOLATION; 11411 break; 11412 case WMI_SCAN_REASON_MAX: 11413 param->reason = SCAN_REASON_MAX; 11414 break; 11415 default: 11416 param->reason = SCAN_REASON_MAX; 11417 break; 11418 }; 11419 11420 param->chan_freq = evt->channel_freq; 11421 param->requester = evt->requestor; 11422 param->scan_id = evt->scan_id; 11423 param->vdev_id = evt->vdev_id; 11424 param->timestamp = evt->tsf_timestamp; 11425 11426 return QDF_STATUS_SUCCESS; 11427 } 11428 11429 #ifdef FEATURE_WLAN_SCAN_PNO 11430 /** 11431 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 11432 * @wmi_handle: pointer to WMI handle 11433 * @evt_buf: pointer to WMI event buffer 11434 * @param: pointer to scan event param for NLO match 11435 * 11436 * Return: QDF_STATUS_SUCCESS for success or error code 11437 */ 11438 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 11439 void *evt_buf, 11440 struct scan_event *param) 11441 { 11442 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 11443 wmi_nlo_event *evt = param_buf->fixed_param; 11444 11445 qdf_mem_zero(param, sizeof(*param)); 11446 11447 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 11448 param->vdev_id = evt->vdev_id; 11449 11450 return QDF_STATUS_SUCCESS; 11451 } 11452 11453 /** 11454 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 11455 * @wmi_handle: pointer to WMI handle 11456 * @evt_buf: pointer to WMI event buffer 11457 * @param: pointer to scan event param for NLO complete 11458 * 11459 * Return: QDF_STATUS_SUCCESS for success or error code 11460 */ 11461 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 11462 void *evt_buf, 11463 struct scan_event *param) 11464 { 11465 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 11466 wmi_nlo_event *evt = param_buf->fixed_param; 11467 11468 qdf_mem_zero(param, sizeof(*param)); 11469 11470 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 11471 param->vdev_id = evt->vdev_id; 11472 11473 return QDF_STATUS_SUCCESS; 11474 } 11475 #endif 11476 11477 /** 11478 * extract_unit_test_tlv() - extract unit test data 11479 * @wmi_handle: wmi handle 11480 * @param evt_buf: pointer to event buffer 11481 * @param unit_test: pointer to hold unit test data 11482 * @param maxspace: Amount of space in evt_buf 11483 * 11484 * Return: QDF_STATUS_SUCCESS for success or error code 11485 */ 11486 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 11487 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 11488 { 11489 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 11490 wmi_unit_test_event_fixed_param *ev_param; 11491 uint32_t num_bufp; 11492 uint32_t copy_size; 11493 uint8_t *bufp; 11494 11495 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 11496 ev_param = param_buf->fixed_param; 11497 bufp = param_buf->bufp; 11498 num_bufp = param_buf->num_bufp; 11499 unit_test->vdev_id = ev_param->vdev_id; 11500 unit_test->module_id = ev_param->module_id; 11501 unit_test->diag_token = ev_param->diag_token; 11502 unit_test->flag = ev_param->flag; 11503 unit_test->payload_len = ev_param->payload_len; 11504 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 11505 ev_param->vdev_id, 11506 ev_param->module_id, 11507 ev_param->diag_token, 11508 ev_param->flag); 11509 wmi_debug("Unit-test data given below %d", num_bufp); 11510 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11511 bufp, num_bufp); 11512 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 11513 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 11514 unit_test->buffer_len = copy_size; 11515 11516 return QDF_STATUS_SUCCESS; 11517 } 11518 11519 /** 11520 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 11521 * @wmi_handle: wmi handle 11522 * @param evt_buf: pointer to event buffer 11523 * @param index: Index into extended pdev stats 11524 * @param pdev_ext_stats: Pointer to hold extended pdev stats 11525 * 11526 * Return: QDF_STATUS_SUCCESS for success or error code 11527 */ 11528 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 11529 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 11530 { 11531 return QDF_STATUS_SUCCESS; 11532 } 11533 11534 /** 11535 * extract_bcn_stats_tlv() - extract bcn stats from event 11536 * @wmi_handle: wmi handle 11537 * @param evt_buf: pointer to event buffer 11538 * @param index: Index into vdev stats 11539 * @param bcn_stats: Pointer to hold bcn stats 11540 * 11541 * Return: QDF_STATUS_SUCCESS for success or error code 11542 */ 11543 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 11544 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 11545 { 11546 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11547 wmi_stats_event_fixed_param *ev_param; 11548 uint8_t *data; 11549 11550 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 11551 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 11552 data = (uint8_t *) param_buf->data; 11553 11554 if (index < ev_param->num_bcn_stats) { 11555 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 11556 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 11557 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 11558 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 11559 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 11560 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 11561 (index * sizeof(wmi_bcn_stats))); 11562 11563 bcn_stats->vdev_id = ev->vdev_id; 11564 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 11565 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 11566 } 11567 11568 return QDF_STATUS_SUCCESS; 11569 } 11570 11571 /** 11572 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 11573 * stats from event 11574 * @wmi_handle: wmi handle 11575 * @param evt_buf: pointer to event buffer 11576 * @param index: Index into vdev stats 11577 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 11578 * 11579 * Return: QDF_STATUS_SUCCESS for success or error code 11580 */ 11581 static QDF_STATUS 11582 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 11583 void *evt_buf, uint32_t index, 11584 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 11585 { 11586 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11587 wmi_vdev_extd_stats *ev; 11588 11589 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11590 11591 if (param_buf->vdev_extd_stats) { 11592 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 11593 index); 11594 vdev_stats->vdev_id = ev->vdev_id; 11595 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 11596 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 11597 vdev_stats->unsolicited_prb_succ_cnt = 11598 ev->unsolicited_prb_succ_cnt; 11599 vdev_stats->unsolicited_prb_fail_cnt = 11600 ev->unsolicited_prb_fail_cnt; 11601 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 11602 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 11603 ev->unsolicited_prb_succ_cnt, 11604 ev->unsolicited_prb_fail_cnt); 11605 } 11606 11607 return QDF_STATUS_SUCCESS; 11608 } 11609 11610 /** 11611 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 11612 * @wmi_handle: wmi handle 11613 * @param evt_buf: pointer to event buffer 11614 * @param index: Index into bcn fault stats 11615 * @param bcnflt_stats: Pointer to hold bcn fault stats 11616 * 11617 * Return: QDF_STATUS_SUCCESS for success or error code 11618 */ 11619 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 11620 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 11621 { 11622 return QDF_STATUS_SUCCESS; 11623 } 11624 11625 /** 11626 * extract_chan_stats_tlv() - extract chan stats from event 11627 * @wmi_handle: wmi handle 11628 * @param evt_buf: pointer to event buffer 11629 * @param index: Index into chan stats 11630 * @param vdev_extd_stats: Pointer to hold chan stats 11631 * 11632 * Return: QDF_STATUS_SUCCESS for success or error code 11633 */ 11634 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 11635 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 11636 { 11637 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11638 wmi_stats_event_fixed_param *ev_param; 11639 uint8_t *data; 11640 11641 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 11642 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 11643 data = (uint8_t *) param_buf->data; 11644 11645 if (index < ev_param->num_chan_stats) { 11646 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 11647 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 11648 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 11649 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 11650 (index * sizeof(wmi_chan_stats))); 11651 11652 11653 /* Non-TLV doesn't have num_chan_stats */ 11654 chan_stats->chan_mhz = ev->chan_mhz; 11655 chan_stats->sampling_period_us = ev->sampling_period_us; 11656 chan_stats->rx_clear_count = ev->rx_clear_count; 11657 chan_stats->tx_duration_us = ev->tx_duration_us; 11658 chan_stats->rx_duration_us = ev->rx_duration_us; 11659 } 11660 11661 return QDF_STATUS_SUCCESS; 11662 } 11663 11664 /** 11665 * extract_profile_ctx_tlv() - extract profile context from event 11666 * @wmi_handle: wmi handle 11667 * @param evt_buf: pointer to event buffer 11668 * @idx: profile stats index to extract 11669 * @param profile_ctx: Pointer to hold profile context 11670 * 11671 * Return: QDF_STATUS_SUCCESS for success or error code 11672 */ 11673 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 11674 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 11675 { 11676 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 11677 11678 wmi_wlan_profile_ctx_t *ev; 11679 11680 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 11681 if (!param_buf) { 11682 wmi_err("Invalid profile data event buf"); 11683 return QDF_STATUS_E_INVAL; 11684 } 11685 11686 ev = param_buf->profile_ctx; 11687 11688 profile_ctx->tot = ev->tot; 11689 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 11690 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 11691 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 11692 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 11693 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 11694 profile_ctx->bin_count = ev->bin_count; 11695 11696 return QDF_STATUS_SUCCESS; 11697 } 11698 11699 /** 11700 * extract_profile_data_tlv() - extract profile data from event 11701 * @wmi_handle: wmi handle 11702 * @param evt_buf: pointer to event buffer 11703 * @param profile_data: Pointer to hold profile data 11704 * 11705 * Return: QDF_STATUS_SUCCESS for success or error code 11706 */ 11707 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 11708 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 11709 { 11710 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 11711 wmi_wlan_profile_t *ev; 11712 uint8_t *buf_ptr; 11713 11714 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 11715 if (!param_buf) { 11716 wmi_err("Invalid profile data event buf"); 11717 return QDF_STATUS_E_INVAL; 11718 } 11719 11720 buf_ptr = (uint8_t *)param_buf->profile_ctx; 11721 buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE; 11722 11723 buf_ptr = buf_ptr + (sizeof(wmi_wlan_profile_t) * idx); 11724 ev = (wmi_wlan_profile_t *)buf_ptr; 11725 11726 profile_data->id = ev->id; 11727 profile_data->cnt = ev->cnt; 11728 profile_data->tot = ev->tot; 11729 profile_data->min = ev->min; 11730 profile_data->max = ev->max; 11731 profile_data->hist_intvl = ev->hist_intvl; 11732 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 11733 11734 return QDF_STATUS_SUCCESS; 11735 } 11736 11737 /** 11738 * extract_pdev_utf_event_tlv() - extract UTF data info from event 11739 * @wmi_handle: WMI handle 11740 * @param evt_buf: Pointer to event buffer 11741 * @param param: Pointer to hold data 11742 * 11743 * Return : QDF_STATUS_SUCCESS for success or error code 11744 */ 11745 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 11746 uint8_t *evt_buf, 11747 struct wmi_host_pdev_utf_event *event) 11748 { 11749 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 11750 struct wmi_host_utf_seg_header_info *seg_hdr; 11751 11752 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 11753 event->data = param_buf->data; 11754 event->datalen = param_buf->num_data; 11755 11756 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 11757 wmi_err("Invalid datalen: %d", event->datalen); 11758 return QDF_STATUS_E_INVAL; 11759 } 11760 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 11761 /* Set pdev_id=1 until FW adds support to include pdev_id */ 11762 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11763 wmi_handle, 11764 seg_hdr->pdev_id); 11765 11766 return QDF_STATUS_SUCCESS; 11767 } 11768 11769 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 11770 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 11771 uint8_t *event, 11772 uint32_t *num_rf_characterization_entries) 11773 { 11774 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 11775 11776 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 11777 if (!param_buf) 11778 return QDF_STATUS_E_INVAL; 11779 11780 *num_rf_characterization_entries = 11781 param_buf->num_wmi_chan_rf_characterization_info; 11782 11783 return QDF_STATUS_SUCCESS; 11784 } 11785 11786 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 11787 uint8_t *event, 11788 uint32_t num_rf_characterization_entries, 11789 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 11790 { 11791 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 11792 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 11793 uint8_t ix; 11794 11795 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 11796 if (!param_buf) 11797 return QDF_STATUS_E_INVAL; 11798 11799 wmi_rf_characterization_entry = 11800 param_buf->wmi_chan_rf_characterization_info; 11801 if (!wmi_rf_characterization_entry) 11802 return QDF_STATUS_E_INVAL; 11803 11804 /* 11805 * Using num_wmi_chan_rf_characterization instead of param_buf value 11806 * since memory for rf_characterization_entries was allocated using 11807 * the former. 11808 */ 11809 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 11810 rf_characterization_entries[ix].freq = 11811 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 11812 &wmi_rf_characterization_entry[ix]); 11813 11814 rf_characterization_entries[ix].bw = 11815 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 11816 &wmi_rf_characterization_entry[ix]); 11817 11818 rf_characterization_entries[ix].chan_metric = 11819 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 11820 &wmi_rf_characterization_entry[ix]); 11821 11822 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 11823 "bw: %u, chan_metric: %u", 11824 ix, rf_characterization_entries[ix].freq, 11825 rf_characterization_entries[ix].bw, 11826 rf_characterization_entries[ix].chan_metric); 11827 } 11828 11829 return QDF_STATUS_SUCCESS; 11830 } 11831 #endif 11832 11833 #ifdef WLAN_FEATURE_11BE 11834 static void 11835 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 11836 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 11837 { 11838 cap->supports_chan_width_320 = 11839 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 11840 } 11841 #else 11842 static void 11843 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 11844 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 11845 { 11846 } 11847 #endif /* WLAN_FEATURE_11BE */ 11848 11849 /** 11850 * extract_chainmask_tables_tlv() - extract chain mask tables from event 11851 * @wmi_handle: wmi handle 11852 * @param evt_buf: pointer to event buffer 11853 * @param param: Pointer to hold evt buf 11854 * 11855 * Return: QDF_STATUS_SUCCESS for success or error code 11856 */ 11857 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 11858 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 11859 { 11860 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11861 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 11862 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11863 uint8_t i = 0, j = 0; 11864 uint32_t num_mac_phy_chainmask_caps = 0; 11865 11866 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11867 if (!param_buf) 11868 return QDF_STATUS_E_INVAL; 11869 11870 hw_caps = param_buf->soc_hw_mode_caps; 11871 if (!hw_caps) 11872 return QDF_STATUS_E_INVAL; 11873 11874 if ((!hw_caps->num_chainmask_tables) || 11875 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 11876 (hw_caps->num_chainmask_tables > 11877 param_buf->num_mac_phy_chainmask_combo)) 11878 return QDF_STATUS_E_INVAL; 11879 11880 chainmask_caps = param_buf->mac_phy_chainmask_caps; 11881 11882 if (!chainmask_caps) 11883 return QDF_STATUS_E_INVAL; 11884 11885 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 11886 if (chainmask_table[i].num_valid_chainmasks > 11887 (UINT_MAX - num_mac_phy_chainmask_caps)) { 11888 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 11889 num_mac_phy_chainmask_caps, i, 11890 chainmask_table[i].num_valid_chainmasks); 11891 return QDF_STATUS_E_INVAL; 11892 } 11893 num_mac_phy_chainmask_caps += 11894 chainmask_table[i].num_valid_chainmasks; 11895 } 11896 11897 if (num_mac_phy_chainmask_caps > 11898 param_buf->num_mac_phy_chainmask_caps) { 11899 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 11900 num_mac_phy_chainmask_caps, 11901 param_buf->num_mac_phy_chainmask_caps); 11902 return QDF_STATUS_E_INVAL; 11903 } 11904 11905 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 11906 11907 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 11908 i); 11909 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 11910 11911 chainmask_table[i].cap_list[j].chainmask = 11912 chainmask_caps->chainmask; 11913 11914 chainmask_table[i].cap_list[j].supports_chan_width_20 = 11915 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 11916 11917 chainmask_table[i].cap_list[j].supports_chan_width_40 = 11918 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 11919 11920 chainmask_table[i].cap_list[j].supports_chan_width_80 = 11921 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 11922 11923 chainmask_table[i].cap_list[j].supports_chan_width_160 = 11924 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 11925 11926 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 11927 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 11928 11929 chainmask_table[i].cap_list[j].chain_mask_2G = 11930 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 11931 11932 chainmask_table[i].cap_list[j].chain_mask_5G = 11933 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 11934 11935 chainmask_table[i].cap_list[j].chain_mask_tx = 11936 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 11937 11938 chainmask_table[i].cap_list[j].chain_mask_rx = 11939 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 11940 11941 chainmask_table[i].cap_list[j].supports_aDFS = 11942 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 11943 11944 chainmask_table[i].cap_list[j].supports_aSpectral = 11945 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 11946 11947 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 11948 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 11949 11950 chainmask_table[i].cap_list[j].supports_aDFS_160 = 11951 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 11952 11953 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 11954 chainmask_caps); 11955 11956 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 11957 chainmask_caps->supported_flags, 11958 chainmask_caps->chainmask); 11959 chainmask_caps++; 11960 } 11961 } 11962 11963 return QDF_STATUS_SUCCESS; 11964 } 11965 11966 /** 11967 * extract_service_ready_ext_tlv() - extract basic extended service ready params 11968 * from event 11969 * @wmi_handle: wmi handle 11970 * @param evt_buf: pointer to event buffer 11971 * @param param: Pointer to hold evt buf 11972 * 11973 * Return: QDF_STATUS_SUCCESS for success or error code 11974 */ 11975 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 11976 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 11977 { 11978 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11979 wmi_service_ready_ext_event_fixed_param *ev; 11980 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11981 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11982 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 11983 uint8_t i = 0; 11984 11985 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11986 if (!param_buf) 11987 return QDF_STATUS_E_INVAL; 11988 11989 ev = param_buf->fixed_param; 11990 if (!ev) 11991 return QDF_STATUS_E_INVAL; 11992 11993 /* Move this to host based bitmap */ 11994 param->default_conc_scan_config_bits = 11995 ev->default_conc_scan_config_bits; 11996 param->default_fw_config_bits = ev->default_fw_config_bits; 11997 param->he_cap_info = ev->he_cap_info; 11998 param->mpdu_density = ev->mpdu_density; 11999 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 12000 param->fw_build_vers_ext = ev->fw_build_vers_ext; 12001 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 12002 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 12003 param->max_bssid_indicator = ev->max_bssid_indicator; 12004 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 12005 12006 hw_caps = param_buf->soc_hw_mode_caps; 12007 if (hw_caps) 12008 param->num_hw_modes = hw_caps->num_hw_modes; 12009 else 12010 param->num_hw_modes = 0; 12011 12012 reg_caps = param_buf->soc_hal_reg_caps; 12013 if (reg_caps) 12014 param->num_phy = reg_caps->num_phy; 12015 else 12016 param->num_phy = 0; 12017 12018 if (hw_caps) { 12019 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 12020 wmi_nofl_debug("Num chain mask tables: %d", 12021 hw_caps->num_chainmask_tables); 12022 } else 12023 param->num_chainmask_tables = 0; 12024 12025 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 12026 param->num_chainmask_tables > 12027 param_buf->num_mac_phy_chainmask_combo) { 12028 wmi_err_rl("num_chainmask_tables is OOB: %u", 12029 param->num_chainmask_tables); 12030 return QDF_STATUS_E_INVAL; 12031 } 12032 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 12033 12034 if (!chain_mask_combo) 12035 return QDF_STATUS_SUCCESS; 12036 12037 wmi_nofl_debug("Dumping chain mask combo data"); 12038 12039 for (i = 0; i < param->num_chainmask_tables; i++) { 12040 12041 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 12042 chain_mask_combo->chainmask_table_id, 12043 chain_mask_combo->num_valid_chainmask); 12044 12045 param->chainmask_table[i].table_id = 12046 chain_mask_combo->chainmask_table_id; 12047 param->chainmask_table[i].num_valid_chainmasks = 12048 chain_mask_combo->num_valid_chainmask; 12049 chain_mask_combo++; 12050 } 12051 wmi_nofl_debug("chain mask combo end"); 12052 12053 return QDF_STATUS_SUCCESS; 12054 } 12055 12056 /** 12057 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 12058 * event 12059 * @wmi_handle: wmi handle 12060 * @event: pointer to event buffer 12061 * @param: Pointer to hold the params 12062 * 12063 * Return: QDF_STATUS_SUCCESS for success or error code 12064 */ 12065 static QDF_STATUS 12066 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 12067 struct wlan_psoc_host_service_ext2_param *param) 12068 { 12069 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12070 wmi_service_ready_ext2_event_fixed_param *ev; 12071 12072 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12073 if (!param_buf) 12074 return QDF_STATUS_E_INVAL; 12075 12076 ev = param_buf->fixed_param; 12077 if (!ev) 12078 return QDF_STATUS_E_INVAL; 12079 12080 param->reg_db_version_major = 12081 WMI_REG_DB_VERSION_MAJOR_GET( 12082 ev->reg_db_version); 12083 param->reg_db_version_minor = 12084 WMI_REG_DB_VERSION_MINOR_GET( 12085 ev->reg_db_version); 12086 param->bdf_reg_db_version_major = 12087 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 12088 ev->reg_db_version); 12089 param->bdf_reg_db_version_minor = 12090 WMI_BDF_REG_DB_VERSION_MINOR_GET( 12091 ev->reg_db_version); 12092 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 12093 12094 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 12095 12096 if (param_buf->nan_cap) 12097 param->max_ndp_sessions = 12098 param_buf->nan_cap->max_ndp_sessions; 12099 else 12100 param->max_ndp_sessions = 0; 12101 12102 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 12103 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 12104 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 12105 ev->max_user_per_ppdu_ofdma); 12106 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 12107 ev->max_user_per_ppdu_ofdma); 12108 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 12109 ev->max_user_per_ppdu_mumimo); 12110 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 12111 ev->max_user_per_ppdu_mumimo); 12112 param->target_cap_flags = ev->target_cap_flags; 12113 wmi_debug("htt peer data :%d", ev->target_cap_flags); 12114 return QDF_STATUS_SUCCESS; 12115 } 12116 12117 /* 12118 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 12119 * service ready ext 2 12120 * 12121 * @wmi_handle: wmi handle 12122 * @event: pointer to event buffer 12123 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 12124 * it indicates async SBS mode is supported, and 12125 * lower-band/higher band to MAC mapping is 12126 * switch-able. unit: mhz. examples 5180, 5320 12127 * 12128 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 12129 */ 12130 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 12131 wmi_unified_t wmi_handle, uint8_t *event, 12132 uint32_t *sbs_lower_band_end_freq) 12133 { 12134 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12135 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 12136 12137 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12138 if (!param_buf) 12139 return QDF_STATUS_E_INVAL; 12140 12141 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 12142 if (!dbs_or_sbs_caps) 12143 return QDF_STATUS_E_INVAL; 12144 12145 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 12146 12147 return QDF_STATUS_SUCCESS; 12148 } 12149 12150 /** 12151 * extract_sar_cap_service_ready_ext_tlv() - 12152 * extract SAR cap from service ready event 12153 * @wmi_handle: wmi handle 12154 * @event: pointer to event buffer 12155 * @ext_param: extended target info 12156 * 12157 * Return: QDF_STATUS_SUCCESS for success or error code 12158 */ 12159 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 12160 wmi_unified_t wmi_handle, 12161 uint8_t *event, 12162 struct wlan_psoc_host_service_ext_param *ext_param) 12163 { 12164 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12165 WMI_SAR_CAPABILITIES *sar_caps; 12166 12167 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 12168 12169 if (!param_buf) 12170 return QDF_STATUS_E_INVAL; 12171 12172 sar_caps = param_buf->sar_caps; 12173 if (sar_caps) 12174 ext_param->sar_version = sar_caps->active_version; 12175 else 12176 ext_param->sar_version = 0; 12177 12178 return QDF_STATUS_SUCCESS; 12179 } 12180 12181 /** 12182 * extract_hw_mode_cap_service_ready_ext_tlv() - 12183 * extract HW mode cap from service ready event 12184 * @wmi_handle: wmi handle 12185 * @param evt_buf: pointer to event buffer 12186 * @param param: Pointer to hold evt buf 12187 * @param hw_mode_idx: hw mode idx should be less than num_mode 12188 * 12189 * Return: QDF_STATUS_SUCCESS for success or error code 12190 */ 12191 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 12192 wmi_unified_t wmi_handle, 12193 uint8_t *event, uint8_t hw_mode_idx, 12194 struct wlan_psoc_host_hw_mode_caps *param) 12195 { 12196 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12197 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12198 12199 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12200 if (!param_buf) 12201 return QDF_STATUS_E_INVAL; 12202 12203 hw_caps = param_buf->soc_hw_mode_caps; 12204 if (!hw_caps) 12205 return QDF_STATUS_E_INVAL; 12206 12207 if (!hw_caps->num_hw_modes || 12208 !param_buf->hw_mode_caps || 12209 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 12210 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 12211 return QDF_STATUS_E_INVAL; 12212 12213 if (hw_mode_idx >= hw_caps->num_hw_modes) 12214 return QDF_STATUS_E_INVAL; 12215 12216 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 12217 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 12218 12219 param->hw_mode_config_type = 12220 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 12221 12222 return QDF_STATUS_SUCCESS; 12223 } 12224 12225 /** 12226 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 12227 * @param param: host mac phy capabilities 12228 * @param mac_phy_caps: mac phy capabilities 12229 * 12230 * Return: void 12231 */ 12232 #ifdef WLAN_FEATURE_11BE 12233 static void 12234 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 12235 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12236 { 12237 param->supports_11be = 12238 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 12239 12240 wmi_debug("11be support %d", param->supports_11be); 12241 } 12242 #else 12243 static void 12244 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 12245 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12246 { 12247 } 12248 #endif 12249 12250 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 12251 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 12252 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12253 { 12254 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 12255 } 12256 #else 12257 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 12258 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12259 { 12260 } 12261 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 12262 12263 /** 12264 * extract_mac_phy_cap_service_ready_ext_tlv() - 12265 * extract MAC phy cap from service ready event 12266 * @wmi_handle: wmi handle 12267 * @param evt_buf: pointer to event buffer 12268 * @param param: Pointer to hold evt buf 12269 * @param hw_mode_idx: hw mode idx should be less than num_mode 12270 * @param phy_id: phy id within hw_mode 12271 * 12272 * Return: QDF_STATUS_SUCCESS for success or error code 12273 */ 12274 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 12275 wmi_unified_t wmi_handle, 12276 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 12277 struct wlan_psoc_host_mac_phy_caps *param) 12278 { 12279 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12280 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 12281 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12282 uint32_t phy_map; 12283 uint8_t hw_idx, phy_idx = 0, pdev_id; 12284 12285 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12286 if (!param_buf) 12287 return QDF_STATUS_E_INVAL; 12288 12289 hw_caps = param_buf->soc_hw_mode_caps; 12290 if (!hw_caps) 12291 return QDF_STATUS_E_INVAL; 12292 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 12293 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 12294 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 12295 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 12296 return QDF_STATUS_E_INVAL; 12297 } 12298 12299 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 12300 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 12301 break; 12302 12303 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 12304 while (phy_map) { 12305 phy_map >>= 1; 12306 phy_idx++; 12307 } 12308 } 12309 12310 if (hw_idx == hw_caps->num_hw_modes) 12311 return QDF_STATUS_E_INVAL; 12312 12313 phy_idx += phy_id; 12314 if (phy_idx >= param_buf->num_mac_phy_caps) 12315 return QDF_STATUS_E_INVAL; 12316 12317 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 12318 12319 param->hw_mode_id = mac_phy_caps->hw_mode_id; 12320 param->phy_idx = phy_idx; 12321 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 12322 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12323 wmi_handle, 12324 pdev_id); 12325 param->tgt_pdev_id = pdev_id; 12326 extract_hw_link_id(param, mac_phy_caps); 12327 param->phy_id = mac_phy_caps->phy_id; 12328 param->supports_11b = 12329 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 12330 param->supports_11g = 12331 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 12332 param->supports_11a = 12333 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 12334 param->supports_11n = 12335 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 12336 param->supports_11ac = 12337 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 12338 param->supports_11ax = 12339 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 12340 12341 extract_service_ready_11be_support(param, mac_phy_caps); 12342 12343 param->supported_bands = mac_phy_caps->supported_bands; 12344 param->ampdu_density = mac_phy_caps->ampdu_density; 12345 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 12346 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 12347 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 12348 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 12349 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 12350 mac_phy_caps->he_cap_info_2G; 12351 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 12352 mac_phy_caps->he_cap_info_2G_ext; 12353 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 12354 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 12355 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 12356 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 12357 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 12358 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 12359 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 12360 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 12361 mac_phy_caps->he_cap_info_5G; 12362 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 12363 mac_phy_caps->he_cap_info_5G_ext; 12364 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 12365 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 12366 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 12367 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 12368 qdf_mem_copy(¶m->he_cap_phy_info_2G, 12369 &mac_phy_caps->he_cap_phy_info_2G, 12370 sizeof(param->he_cap_phy_info_2G)); 12371 qdf_mem_copy(¶m->he_cap_phy_info_5G, 12372 &mac_phy_caps->he_cap_phy_info_5G, 12373 sizeof(param->he_cap_phy_info_5G)); 12374 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 12375 sizeof(param->he_ppet2G)); 12376 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 12377 sizeof(param->he_ppet5G)); 12378 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 12379 param->lmac_id = mac_phy_caps->lmac_id; 12380 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 12381 (mac_phy_caps->wireless_modes); 12382 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 12383 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 12384 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 12385 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 12386 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 12387 mac_phy_caps->nss_ratio); 12388 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 12389 12390 return QDF_STATUS_SUCCESS; 12391 } 12392 12393 /** 12394 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 12395 * @param param: host ext2 mac phy capabilities 12396 * @param mac_phy_caps: ext mac phy capabilities 12397 * 12398 * Return: void 12399 */ 12400 #ifdef WLAN_FEATURE_11BE 12401 static void extract_mac_phy_cap_ehtcaps( 12402 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 12403 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 12404 { 12405 uint32_t i; 12406 12407 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 12408 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 12409 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 12410 12411 qdf_mem_copy(¶m->eht_cap_info_2G, 12412 &mac_phy_caps->eht_cap_mac_info_2G, 12413 sizeof(param->eht_cap_info_2G)); 12414 qdf_mem_copy(¶m->eht_cap_info_5G, 12415 &mac_phy_caps->eht_cap_mac_info_5G, 12416 sizeof(param->eht_cap_info_5G)); 12417 12418 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 12419 &mac_phy_caps->eht_cap_phy_info_2G, 12420 sizeof(param->eht_cap_phy_info_2G)); 12421 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 12422 &mac_phy_caps->eht_cap_phy_info_5G, 12423 sizeof(param->eht_cap_phy_info_5G)); 12424 12425 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 12426 &mac_phy_caps->eht_supp_mcs_ext_2G, 12427 sizeof(param->eht_supp_mcs_ext_2G)); 12428 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 12429 &mac_phy_caps->eht_supp_mcs_ext_5G, 12430 sizeof(param->eht_supp_mcs_ext_5G)); 12431 12432 wmi_debug("EHT mac caps: mac cap_info_2G %x, mac cap_info_5G %x, supp_mcs_2G %x, supp_mcs_5G %x, info_internal %x", 12433 mac_phy_caps->eht_cap_mac_info_2G[0], 12434 mac_phy_caps->eht_cap_mac_info_5G[0], 12435 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 12436 mac_phy_caps->eht_cap_info_internal); 12437 12438 wmi_nofl_debug("EHT phy caps: "); 12439 12440 wmi_nofl_debug("2G:"); 12441 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 12442 wmi_nofl_debug("index %d value %d", 12443 i, param->eht_cap_phy_info_2G[i]); 12444 } 12445 wmi_nofl_debug("5G:"); 12446 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 12447 wmi_nofl_debug("index %d value %d", 12448 i, param->eht_cap_phy_info_5G[i]); 12449 } 12450 wmi_nofl_debug("2G MCS ext Map:"); 12451 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 12452 wmi_nofl_debug("index %d value %d", 12453 i, param->eht_supp_mcs_ext_2G[i]); 12454 } 12455 wmi_nofl_debug("5G MCS ext Map:"); 12456 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 12457 wmi_nofl_debug("index %d value %d", 12458 i, param->eht_supp_mcs_ext_5G[i]); 12459 } 12460 } 12461 #else 12462 static void extract_mac_phy_cap_ehtcaps( 12463 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 12464 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 12465 { 12466 } 12467 #endif 12468 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 12469 wmi_unified_t wmi_handle, 12470 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 12471 uint8_t phy_idx, 12472 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 12473 { 12474 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12475 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 12476 12477 if (!event) { 12478 wmi_err("null evt_buf"); 12479 return QDF_STATUS_E_INVAL; 12480 } 12481 12482 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12483 12484 if (!param_buf->num_mac_phy_caps) 12485 return QDF_STATUS_SUCCESS; 12486 12487 if (phy_idx >= param_buf->num_mac_phy_caps) 12488 return QDF_STATUS_E_INVAL; 12489 12490 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 12491 12492 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 12493 (phy_id != mac_phy_caps->phy_id)) 12494 return QDF_STATUS_E_INVAL; 12495 12496 param->hw_mode_id = mac_phy_caps->hw_mode_id; 12497 param->phy_id = mac_phy_caps->phy_id; 12498 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12499 wmi_handle, mac_phy_caps->pdev_id); 12500 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12501 mac_phy_caps->wireless_modes_ext); 12502 12503 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 12504 12505 return QDF_STATUS_SUCCESS; 12506 } 12507 12508 /** 12509 * extract_reg_cap_service_ready_ext_tlv() - 12510 * extract REG cap from service ready event 12511 * @wmi_handle: wmi handle 12512 * @param evt_buf: pointer to event buffer 12513 * @param param: Pointer to hold evt buf 12514 * @param phy_idx: phy idx should be less than num_mode 12515 * 12516 * Return: QDF_STATUS_SUCCESS for success or error code 12517 */ 12518 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 12519 wmi_unified_t wmi_handle, 12520 uint8_t *event, uint8_t phy_idx, 12521 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 12522 { 12523 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12524 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 12525 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 12526 12527 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12528 if (!param_buf) 12529 return QDF_STATUS_E_INVAL; 12530 12531 reg_caps = param_buf->soc_hal_reg_caps; 12532 if (!reg_caps) 12533 return QDF_STATUS_E_INVAL; 12534 12535 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 12536 return QDF_STATUS_E_INVAL; 12537 12538 if (phy_idx >= reg_caps->num_phy) 12539 return QDF_STATUS_E_INVAL; 12540 12541 if (!param_buf->hal_reg_caps) 12542 return QDF_STATUS_E_INVAL; 12543 12544 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 12545 12546 param->phy_id = ext_reg_cap->phy_id; 12547 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 12548 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 12549 param->regcap1 = ext_reg_cap->regcap1; 12550 param->regcap2 = ext_reg_cap->regcap2; 12551 param->wireless_modes = convert_wireless_modes_tlv( 12552 ext_reg_cap->wireless_modes); 12553 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 12554 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 12555 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 12556 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 12557 12558 return QDF_STATUS_SUCCESS; 12559 } 12560 12561 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 12562 uint8_t num_dma_ring_caps) 12563 { 12564 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 12565 if (!num_dma_ring_caps) { 12566 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 12567 return QDF_STATUS_E_INVAL; 12568 } 12569 if (idx >= num_dma_ring_caps) { 12570 wmi_err("Index %d exceeds range", idx); 12571 return QDF_STATUS_E_INVAL; 12572 } 12573 return QDF_STATUS_SUCCESS; 12574 } 12575 12576 static void 12577 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 12578 struct wlan_psoc_host_dbr_ring_caps *param, 12579 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 12580 { 12581 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 12582 wmi_handle, 12583 dbr_ring_caps->pdev_id); 12584 param->mod_id = dbr_ring_caps->mod_id; 12585 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 12586 param->min_buf_size = dbr_ring_caps->min_buf_size; 12587 param->min_buf_align = dbr_ring_caps->min_buf_align; 12588 } 12589 12590 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 12591 wmi_unified_t wmi_handle, 12592 uint8_t *event, uint8_t idx, 12593 struct wlan_psoc_host_dbr_ring_caps *param) 12594 { 12595 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12596 QDF_STATUS status; 12597 12598 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 12599 if (!param_buf) 12600 return QDF_STATUS_E_INVAL; 12601 12602 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 12603 if (status != QDF_STATUS_SUCCESS) 12604 return status; 12605 12606 populate_dbr_ring_cap_elems(wmi_handle, param, 12607 ¶m_buf->dma_ring_caps[idx]); 12608 return QDF_STATUS_SUCCESS; 12609 } 12610 12611 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 12612 wmi_unified_t wmi_handle, 12613 uint8_t *event, uint8_t idx, 12614 struct wlan_psoc_host_dbr_ring_caps *param) 12615 { 12616 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12617 QDF_STATUS status; 12618 12619 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12620 if (!param_buf) 12621 return QDF_STATUS_E_INVAL; 12622 12623 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 12624 if (status != QDF_STATUS_SUCCESS) 12625 return status; 12626 12627 populate_dbr_ring_cap_elems(wmi_handle, param, 12628 ¶m_buf->dma_ring_caps[idx]); 12629 return QDF_STATUS_SUCCESS; 12630 } 12631 12632 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 12633 wmi_unified_t wmi_handle, 12634 uint8_t *event, uint8_t idx, 12635 struct wlan_psoc_host_scan_radio_caps *param) 12636 { 12637 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12638 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 12639 12640 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12641 if (!param_buf) 12642 return QDF_STATUS_E_INVAL; 12643 12644 if (idx >= param_buf->num_wmi_scan_radio_caps) 12645 return QDF_STATUS_E_INVAL; 12646 12647 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 12648 param->phy_id = scan_radio_caps->phy_id; 12649 param->scan_radio_supported = 12650 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 12651 param->dfs_en = 12652 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 12653 12654 return QDF_STATUS_SUCCESS; 12655 } 12656 12657 /** 12658 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 12659 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 12660 * 12661 * Return: host thermal throt level 12662 */ 12663 static enum thermal_throttle_level 12664 wmi_tgt_thermal_level_to_host(uint32_t level) 12665 { 12666 switch (level) { 12667 case WMI_THERMAL_FULLPERF: 12668 return THERMAL_FULLPERF; 12669 case WMI_THERMAL_MITIGATION: 12670 return THERMAL_MITIGATION; 12671 case WMI_THERMAL_SHUTOFF: 12672 return THERMAL_SHUTOFF; 12673 case WMI_THERMAL_SHUTDOWN_TGT: 12674 return THERMAL_SHUTDOWN_TARGET; 12675 default: 12676 return THERMAL_UNKNOWN; 12677 } 12678 } 12679 12680 #ifdef THERMAL_STATS_SUPPORT 12681 static void 12682 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 12683 uint32_t *therm_throt_levels, 12684 struct thermal_throt_level_stats *tt_temp_range_stats) 12685 { 12686 uint8_t lvl_idx; 12687 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 12688 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 12689 12690 tt_stats_event = param_buf->fixed_param; 12691 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 12692 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 12693 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 12694 tt_stats_event->therm_throt_levels; 12695 12696 wmi_tt_stats = param_buf->temp_range_stats; 12697 if (!wmi_tt_stats) { 12698 wmi_err("wmi_tt_stats Null"); 12699 return; 12700 } 12701 12702 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 12703 tt_temp_range_stats[lvl_idx].start_temp_level = 12704 wmi_tt_stats[lvl_idx].start_temp_level; 12705 tt_temp_range_stats[lvl_idx].end_temp_level = 12706 wmi_tt_stats[lvl_idx].end_temp_level; 12707 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 12708 wmi_tt_stats[lvl_idx].total_time_ms_lo; 12709 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 12710 wmi_tt_stats[lvl_idx].total_time_ms_hi; 12711 tt_temp_range_stats[lvl_idx].num_entry = 12712 wmi_tt_stats[lvl_idx].num_entry; 12713 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 12714 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 12715 wmi_tt_stats[lvl_idx].end_temp_level, 12716 wmi_tt_stats[lvl_idx].total_time_ms_lo, 12717 wmi_tt_stats[lvl_idx].total_time_ms_hi, 12718 wmi_tt_stats[lvl_idx].num_entry); 12719 } 12720 } 12721 #else 12722 static void 12723 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 12724 uint32_t *therm_throt_levels, 12725 struct thermal_throt_level_stats *tt_temp_range_stats) 12726 { 12727 } 12728 #endif 12729 12730 /** 12731 * extract_thermal_stats_tlv() - extract thermal stats from event 12732 * @wmi_handle: wmi handle 12733 * @param evt_buf: Pointer to event buffer 12734 * @param temp: Pointer to hold extracted temperature 12735 * @param level: Pointer to hold extracted level in host enum 12736 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 12737 * range 12738 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 12739 * every level 12740 * 12741 * Return: 0 for success or error code 12742 */ 12743 static QDF_STATUS 12744 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 12745 void *evt_buf, uint32_t *temp, 12746 enum thermal_throttle_level *level, 12747 uint32_t *therm_throt_levels, 12748 struct thermal_throt_level_stats *tt_temp_range_stats_event, 12749 uint32_t *pdev_id) 12750 { 12751 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 12752 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 12753 12754 param_buf = 12755 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 12756 if (!param_buf) 12757 return QDF_STATUS_E_INVAL; 12758 12759 tt_stats_event = param_buf->fixed_param; 12760 wmi_debug("thermal temperature %d level %d", 12761 tt_stats_event->temp, tt_stats_event->level); 12762 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12763 wmi_handle, 12764 tt_stats_event->pdev_id); 12765 *temp = tt_stats_event->temp; 12766 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 12767 12768 if (tt_stats_event->therm_throt_levels) 12769 populate_thermal_stats(param_buf, therm_throt_levels, 12770 tt_temp_range_stats_event); 12771 12772 return QDF_STATUS_SUCCESS; 12773 } 12774 12775 /** 12776 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 12777 * @wmi_handle: wmi handle 12778 * @param evt_buf: pointer to event buffer 12779 * @param idx: Index to level stats 12780 * @param levelcount: Pointer to hold levelcount 12781 * @param dccount: Pointer to hold dccount 12782 * 12783 * Return: 0 for success or error code 12784 */ 12785 static QDF_STATUS 12786 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 12787 void *evt_buf, uint8_t idx, uint32_t *levelcount, 12788 uint32_t *dccount) 12789 { 12790 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 12791 wmi_therm_throt_level_stats_info *tt_level_info; 12792 12793 param_buf = 12794 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 12795 if (!param_buf) 12796 return QDF_STATUS_E_INVAL; 12797 12798 tt_level_info = param_buf->therm_throt_level_stats_info; 12799 12800 if (idx < THERMAL_LEVELS) { 12801 *levelcount = tt_level_info[idx].level_count; 12802 *dccount = tt_level_info[idx].dc_count; 12803 return QDF_STATUS_SUCCESS; 12804 } 12805 12806 return QDF_STATUS_E_FAILURE; 12807 } 12808 #ifdef BIG_ENDIAN_HOST 12809 /** 12810 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 12811 * @param data_len - data length 12812 * @param data - pointer to data 12813 * 12814 * Return: QDF_STATUS - success or error status 12815 */ 12816 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 12817 { 12818 uint8_t *data_aligned = NULL; 12819 int c; 12820 unsigned char *data_unaligned; 12821 12822 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 12823 FIPS_ALIGN)); 12824 /* Assigning unaligned space to copy the data */ 12825 /* Checking if kmalloc does successful allocation */ 12826 if (!data_unaligned) 12827 return QDF_STATUS_E_FAILURE; 12828 12829 /* Checking if space is alligned */ 12830 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 12831 /* align the data space */ 12832 data_aligned = 12833 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 12834 } else { 12835 data_aligned = (u_int8_t *)data_unaligned; 12836 } 12837 12838 /* memset and copy content from data to data aligned */ 12839 OS_MEMSET(data_aligned, 0, data_len); 12840 OS_MEMCPY(data_aligned, data, data_len); 12841 /* Endianness to LE */ 12842 for (c = 0; c < data_len/4; c++) { 12843 *((u_int32_t *)data_aligned + c) = 12844 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 12845 } 12846 12847 /* Copy content to event->data */ 12848 OS_MEMCPY(data, data_aligned, data_len); 12849 12850 /* clean up allocated space */ 12851 qdf_mem_free(data_unaligned); 12852 data_aligned = NULL; 12853 data_unaligned = NULL; 12854 12855 /*************************************************************/ 12856 12857 return QDF_STATUS_SUCCESS; 12858 } 12859 #else 12860 /** 12861 * fips_conv_data_be() - DUMMY for LE platform 12862 * 12863 * Return: QDF_STATUS - success 12864 */ 12865 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 12866 { 12867 return QDF_STATUS_SUCCESS; 12868 } 12869 #endif 12870 12871 /** 12872 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 12873 * @wmi_handle - wmi handle 12874 * @params - PN request params for peer 12875 * 12876 * Return: QDF_STATUS - success or error status 12877 */ 12878 static QDF_STATUS 12879 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 12880 struct peer_request_pn_param *params) 12881 { 12882 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 12883 wmi_buf_t buf; 12884 uint8_t *buf_ptr; 12885 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 12886 12887 buf = wmi_buf_alloc(wmi_handle, len); 12888 if (!buf) { 12889 wmi_err("wmi_buf_alloc failed"); 12890 return QDF_STATUS_E_FAILURE; 12891 } 12892 12893 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12894 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 12895 12896 WMITLV_SET_HDR(&cmd->tlv_header, 12897 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 12898 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 12899 12900 cmd->vdev_id = params->vdev_id; 12901 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 12902 cmd->key_type = params->key_type; 12903 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12904 WMI_PEER_TX_PN_REQUEST_CMDID)) { 12905 wmi_err("Failed to send WMI command"); 12906 wmi_buf_free(buf); 12907 return QDF_STATUS_E_FAILURE; 12908 } 12909 return QDF_STATUS_SUCCESS; 12910 } 12911 12912 /** 12913 * extract_get_pn_data_tlv() - extract pn resp 12914 * @wmi_handle - wmi handle 12915 * @params - PN response params for peer 12916 * 12917 * Return: QDF_STATUS - success or error status 12918 */ 12919 static QDF_STATUS 12920 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12921 struct wmi_host_get_pn_event *param) 12922 { 12923 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 12924 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 12925 12926 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 12927 event = 12928 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 12929 12930 param->vdev_id = event->vdev_id; 12931 param->key_type = event->key_type; 12932 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 12933 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 12934 12935 return QDF_STATUS_SUCCESS; 12936 } 12937 12938 /** 12939 * extract_fips_event_data_tlv() - extract fips event data 12940 * @wmi_handle: wmi handle 12941 * @param evt_buf: pointer to event buffer 12942 * @param param: pointer FIPS event params 12943 * 12944 * Return: 0 for success or error code 12945 */ 12946 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 12947 void *evt_buf, struct wmi_host_fips_event_param *param) 12948 { 12949 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 12950 wmi_pdev_fips_event_fixed_param *event; 12951 12952 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 12953 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 12954 12955 if (event->data_len > param_buf->num_data) 12956 return QDF_STATUS_E_FAILURE; 12957 12958 if (fips_conv_data_be(event->data_len, param_buf->data) != 12959 QDF_STATUS_SUCCESS) 12960 return QDF_STATUS_E_FAILURE; 12961 12962 param->data = (uint32_t *)param_buf->data; 12963 param->data_len = event->data_len; 12964 param->error_status = event->error_status; 12965 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12966 wmi_handle, 12967 event->pdev_id); 12968 12969 return QDF_STATUS_SUCCESS; 12970 } 12971 12972 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 12973 /** 12974 * extract_fips_extend_event_data_tlv() - extract fips event data 12975 * @wmi_handle: wmi handle 12976 * @param evt_buf: pointer to event buffer 12977 * @param param: pointer FIPS event params 12978 * 12979 * Return: 0 for success or error code 12980 */ 12981 static QDF_STATUS 12982 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 12983 void *evt_buf, 12984 struct wmi_host_fips_extend_event_param 12985 *param) 12986 { 12987 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 12988 wmi_pdev_fips_extend_event_fixed_param *event; 12989 12990 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 12991 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 12992 12993 if (fips_conv_data_be(event->data_len, param_buf->data) != 12994 QDF_STATUS_SUCCESS) 12995 return QDF_STATUS_E_FAILURE; 12996 12997 param->data = (uint32_t *)param_buf->data; 12998 param->data_len = event->data_len; 12999 param->error_status = event->error_status; 13000 param->fips_cookie = event->fips_cookie; 13001 param->cmd_frag_idx = event->cmd_frag_idx; 13002 param->more_bit = event->more_bit; 13003 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13004 wmi_handle, 13005 event->pdev_id); 13006 13007 return QDF_STATUS_SUCCESS; 13008 } 13009 #endif 13010 13011 #ifdef WLAN_FEATURE_DISA 13012 /** 13013 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 13014 * params from event 13015 * @wmi_handle: wmi handle 13016 * @evt_buf: pointer to event buffer 13017 * @resp: Pointer to hold resp parameters 13018 * 13019 * Return: QDF_STATUS_SUCCESS for success or error code 13020 */ 13021 static QDF_STATUS 13022 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 13023 void *evt_buf, 13024 struct disa_encrypt_decrypt_resp_params 13025 *resp) 13026 { 13027 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 13028 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 13029 13030 param_buf = evt_buf; 13031 if (!param_buf) { 13032 wmi_err("encrypt decrypt resp evt_buf is NULL"); 13033 return QDF_STATUS_E_INVAL; 13034 } 13035 13036 data_event = param_buf->fixed_param; 13037 13038 resp->vdev_id = data_event->vdev_id; 13039 resp->status = data_event->status; 13040 13041 if ((data_event->data_length > param_buf->num_enc80211_frame) || 13042 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 13043 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 13044 wmi_err("FW msg data_len %d more than TLV hdr %d", 13045 data_event->data_length, 13046 param_buf->num_enc80211_frame); 13047 return QDF_STATUS_E_INVAL; 13048 } 13049 13050 resp->data_len = data_event->data_length; 13051 13052 if (resp->data_len) 13053 resp->data = (uint8_t *)param_buf->enc80211_frame; 13054 13055 return QDF_STATUS_SUCCESS; 13056 } 13057 #endif /* WLAN_FEATURE_DISA */ 13058 13059 static bool is_management_record_tlv(uint32_t cmd_id) 13060 { 13061 switch (cmd_id) { 13062 case WMI_MGMT_TX_SEND_CMDID: 13063 case WMI_MGMT_TX_COMPLETION_EVENTID: 13064 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 13065 case WMI_MGMT_RX_EVENTID: 13066 return true; 13067 default: 13068 return false; 13069 } 13070 } 13071 13072 static bool is_diag_event_tlv(uint32_t event_id) 13073 { 13074 if (WMI_DIAG_EVENTID == event_id) 13075 return true; 13076 13077 return false; 13078 } 13079 13080 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 13081 { 13082 uint16_t tag = 0; 13083 13084 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 13085 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 13086 __func__); 13087 return tag; 13088 } 13089 13090 if (wmi_handle->tag_crash_inject) 13091 tag = HTC_TX_PACKET_TAG_AUTO_PM; 13092 13093 wmi_handle->tag_crash_inject = false; 13094 return tag; 13095 } 13096 13097 /** 13098 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 13099 * @wmi_handle: WMI handle 13100 * @buf: WMI buffer 13101 * @cmd_id: WMI command Id 13102 * 13103 * Return htc_tx_tag 13104 */ 13105 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 13106 wmi_buf_t buf, 13107 uint32_t cmd_id) 13108 { 13109 uint16_t htc_tx_tag = 0; 13110 13111 switch (cmd_id) { 13112 case WMI_WOW_ENABLE_CMDID: 13113 case WMI_PDEV_SUSPEND_CMDID: 13114 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 13115 case WMI_PDEV_RESUME_CMDID: 13116 case WMI_HB_SET_ENABLE_CMDID: 13117 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 13118 #ifdef FEATURE_WLAN_D0WOW 13119 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 13120 #endif 13121 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 13122 break; 13123 case WMI_FORCE_FW_HANG_CMDID: 13124 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 13125 break; 13126 default: 13127 break; 13128 } 13129 13130 return htc_tx_tag; 13131 } 13132 13133 #ifdef CONFIG_BAND_6GHZ 13134 static struct cur_reg_rule 13135 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 13136 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 13137 { 13138 struct cur_reg_rule *reg_rule_ptr; 13139 uint32_t count; 13140 13141 if (!num_reg_rules) 13142 return NULL; 13143 13144 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 13145 sizeof(*reg_rule_ptr)); 13146 13147 if (!reg_rule_ptr) 13148 return NULL; 13149 13150 for (count = 0; count < num_reg_rules; count++) { 13151 reg_rule_ptr[count].start_freq = 13152 WMI_REG_RULE_START_FREQ_GET( 13153 wmi_reg_rule[count].freq_info); 13154 reg_rule_ptr[count].end_freq = 13155 WMI_REG_RULE_END_FREQ_GET( 13156 wmi_reg_rule[count].freq_info); 13157 reg_rule_ptr[count].max_bw = 13158 WMI_REG_RULE_MAX_BW_GET( 13159 wmi_reg_rule[count].bw_pwr_info); 13160 reg_rule_ptr[count].reg_power = 13161 WMI_REG_RULE_REG_POWER_GET( 13162 wmi_reg_rule[count].bw_pwr_info); 13163 reg_rule_ptr[count].ant_gain = 13164 WMI_REG_RULE_ANTENNA_GAIN_GET( 13165 wmi_reg_rule[count].bw_pwr_info); 13166 reg_rule_ptr[count].flags = 13167 WMI_REG_RULE_FLAGS_GET( 13168 wmi_reg_rule[count].flag_info); 13169 reg_rule_ptr[count].psd_flag = 13170 WMI_REG_RULE_PSD_FLAG_GET( 13171 wmi_reg_rule[count].psd_power_info); 13172 reg_rule_ptr[count].psd_eirp = 13173 WMI_REG_RULE_PSD_EIRP_GET( 13174 wmi_reg_rule[count].psd_power_info); 13175 } 13176 13177 return reg_rule_ptr; 13178 } 13179 #endif 13180 13181 static struct cur_reg_rule 13182 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 13183 wmi_regulatory_rule_struct *wmi_reg_rule) 13184 { 13185 struct cur_reg_rule *reg_rule_ptr; 13186 uint32_t count; 13187 13188 if (!num_reg_rules) 13189 return NULL; 13190 13191 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 13192 sizeof(*reg_rule_ptr)); 13193 13194 if (!reg_rule_ptr) 13195 return NULL; 13196 13197 for (count = 0; count < num_reg_rules; count++) { 13198 reg_rule_ptr[count].start_freq = 13199 WMI_REG_RULE_START_FREQ_GET( 13200 wmi_reg_rule[count].freq_info); 13201 reg_rule_ptr[count].end_freq = 13202 WMI_REG_RULE_END_FREQ_GET( 13203 wmi_reg_rule[count].freq_info); 13204 reg_rule_ptr[count].max_bw = 13205 WMI_REG_RULE_MAX_BW_GET( 13206 wmi_reg_rule[count].bw_pwr_info); 13207 reg_rule_ptr[count].reg_power = 13208 WMI_REG_RULE_REG_POWER_GET( 13209 wmi_reg_rule[count].bw_pwr_info); 13210 reg_rule_ptr[count].ant_gain = 13211 WMI_REG_RULE_ANTENNA_GAIN_GET( 13212 wmi_reg_rule[count].bw_pwr_info); 13213 reg_rule_ptr[count].flags = 13214 WMI_REG_RULE_FLAGS_GET( 13215 wmi_reg_rule[count].flag_info); 13216 } 13217 13218 return reg_rule_ptr; 13219 } 13220 13221 static enum cc_setting_code wmi_reg_status_to_reg_status( 13222 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 13223 { 13224 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 13225 return REG_SET_CC_STATUS_PASS; 13226 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 13227 return REG_CURRENT_ALPHA2_NOT_FOUND; 13228 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 13229 return REG_INIT_ALPHA2_NOT_FOUND; 13230 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 13231 return REG_SET_CC_CHANGE_NOT_ALLOWED; 13232 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 13233 return REG_SET_CC_STATUS_NO_MEMORY; 13234 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 13235 return REG_SET_CC_STATUS_FAIL; 13236 13237 wmi_debug("Unknown reg status code from WMI"); 13238 return REG_SET_CC_STATUS_FAIL; 13239 } 13240 13241 #ifdef CONFIG_BAND_6GHZ 13242 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 13243 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13244 struct cur_regulatory_info *reg_info, uint32_t len) 13245 { 13246 uint32_t i, j, k; 13247 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 13248 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 13249 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 13250 uint32_t num_2g_reg_rules, num_5g_reg_rules; 13251 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 13252 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 13253 uint32_t total_reg_rules = 0; 13254 13255 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 13256 if (!param_buf) { 13257 wmi_err("invalid channel list event buf"); 13258 return QDF_STATUS_E_FAILURE; 13259 } 13260 13261 ext_chan_list_event_hdr = param_buf->fixed_param; 13262 13263 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 13264 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 13265 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 13266 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 13267 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 13268 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 13269 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 13270 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 13271 13272 wmi_debug("num reg rules from fw"); 13273 wmi_debug("AP SP %d, LPI %d, VLP %d", 13274 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 13275 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 13276 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 13277 13278 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 13279 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 13280 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 13281 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 13282 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 13283 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 13284 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 13285 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 13286 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 13287 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 13288 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 13289 } 13290 13291 num_2g_reg_rules = reg_info->num_2g_reg_rules; 13292 total_reg_rules += num_2g_reg_rules; 13293 num_5g_reg_rules = reg_info->num_5g_reg_rules; 13294 total_reg_rules += num_5g_reg_rules; 13295 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 13296 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 13297 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 13298 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 13299 num_6g_reg_rules_ap[i]); 13300 return QDF_STATUS_E_FAILURE; 13301 } 13302 total_reg_rules += num_6g_reg_rules_ap[i]; 13303 num_6g_reg_rules_client[i] = 13304 reg_info->num_6g_reg_rules_client[i]; 13305 } 13306 13307 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 13308 total_reg_rules += 13309 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 13310 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 13311 total_reg_rules += 13312 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 13313 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 13314 MAX_6G_REG_RULES) || 13315 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 13316 MAX_6G_REG_RULES) || 13317 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 13318 MAX_6G_REG_RULES)) { 13319 wmi_err_rl("Invalid num_6g_reg_rules_client_sp: %u, num_6g_reg_rules_client_lpi: %u, num_6g_reg_rules_client_vlp: %u, client %d", 13320 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 13321 num_6g_reg_rules_client[REG_INDOOR_AP][i], 13322 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 13323 i); 13324 return QDF_STATUS_E_FAILURE; 13325 } 13326 } 13327 13328 if (total_reg_rules != param_buf->num_reg_rule_array) { 13329 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 13330 total_reg_rules, param_buf->num_reg_rule_array); 13331 return QDF_STATUS_E_FAILURE; 13332 } 13333 13334 if ((num_2g_reg_rules > MAX_REG_RULES) || 13335 (num_5g_reg_rules > MAX_REG_RULES)) { 13336 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 13337 num_2g_reg_rules, num_5g_reg_rules); 13338 return QDF_STATUS_E_FAILURE; 13339 } 13340 13341 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 13342 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 13343 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 13344 wmi_err_rl("Invalid num_6g_reg_rules_ap_sp: %u, num_6g_reg_rules_ap_lpi: %u, num_6g_reg_rules_ap_vlp: %u", 13345 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 13346 num_6g_reg_rules_ap[REG_INDOOR_AP], 13347 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 13348 return QDF_STATUS_E_FAILURE; 13349 } 13350 13351 if (param_buf->num_reg_rule_array > 13352 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 13353 sizeof(*ext_wmi_reg_rule)) { 13354 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 13355 param_buf->num_reg_rule_array); 13356 return QDF_STATUS_E_FAILURE; 13357 } 13358 13359 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 13360 REG_ALPHA2_LEN); 13361 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 13362 reg_info->phybitmap = convert_phybitmap_tlv( 13363 ext_chan_list_event_hdr->phybitmap); 13364 reg_info->offload_enabled = true; 13365 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 13366 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 13367 wmi_handle, ext_chan_list_event_hdr->phy_id); 13368 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 13369 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 13370 13371 reg_info->status_code = 13372 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 13373 status_code); 13374 13375 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 13376 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 13377 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 13378 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 13379 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 13380 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 13381 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 13382 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 13383 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 13384 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 13385 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 13386 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 13387 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 13388 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 13389 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 13390 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 13391 13392 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 13393 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 13394 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 13395 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 13396 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 13397 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 13398 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 13399 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 13400 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 13401 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 13402 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 13403 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 13404 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 13405 } 13406 13407 wmi_debug("num_phys = %u and phy_id = %u", 13408 reg_info->num_phy, reg_info->phy_id); 13409 13410 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 13411 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 13412 reg_info->max_bw_2g, reg_info->min_bw_5g, 13413 reg_info->max_bw_5g); 13414 13415 wmi_debug("min_bw_6g_ap_sp %d max_bw_6g_ap_sp %d min_bw_6g_ap_lpi %d max_bw_6g_ap_lpi %d min_bw_6g_ap_vlp %d max_bw_6g_ap_vlp %d", 13416 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 13417 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 13418 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 13419 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 13420 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 13421 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 13422 13423 wmi_debug("min_bw_6g_def_cli_sp %d max_bw_6g_def_cli_sp %d min_bw_6g_def_cli_lpi %d max_bw_6g_def_cli_lpi %d min_bw_6g_def_cli_vlp %d max_bw_6g_def_cli_vlp %d", 13424 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 13425 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 13426 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 13427 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 13428 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 13429 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 13430 13431 wmi_debug("min_bw_6g_sub_client_sp %d max_bw_6g_sub_client_sp %d min_bw_6g_sub_client_lpi %d max_bw_6g_sub_client_lpi %d min_bw_6g_sub_client_vlp %d max_bw_6g_sub_client_vlp %d", 13432 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 13433 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 13434 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 13435 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 13436 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 13437 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 13438 13439 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 13440 num_2g_reg_rules, num_5g_reg_rules); 13441 13442 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 13443 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 13444 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 13445 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 13446 13447 wmi_debug("num_6g_def_cli_sp_reg_rules %d num_6g_def_cli_lpi_reg_rules %d num_6g_def_cli_vlp_reg_rules %d", 13448 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 13449 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 13450 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 13451 13452 wmi_debug("num_6g_sub_cli_sp_reg_rules %d num_6g_sub_cli_lpi_reg_rules %d num_6g_sub_cli_vlp_reg_rules %d", 13453 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 13454 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 13455 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 13456 13457 ext_wmi_reg_rule = 13458 (wmi_regulatory_rule_ext_struct *) 13459 ((uint8_t *)ext_chan_list_event_hdr + 13460 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 13461 WMI_TLV_HDR_SIZE); 13462 reg_info->reg_rules_2g_ptr = 13463 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 13464 ext_wmi_reg_rule); 13465 ext_wmi_reg_rule += num_2g_reg_rules; 13466 for (i = 0; i < num_2g_reg_rules; i++) { 13467 if (!reg_info->reg_rules_2g_ptr) 13468 break; 13469 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 13470 i, reg_info->reg_rules_2g_ptr[i].start_freq, 13471 reg_info->reg_rules_2g_ptr[i].end_freq, 13472 reg_info->reg_rules_2g_ptr[i].flags); 13473 } 13474 reg_info->reg_rules_5g_ptr = 13475 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 13476 ext_wmi_reg_rule); 13477 ext_wmi_reg_rule += num_5g_reg_rules; 13478 for (i = 0; i < num_5g_reg_rules; i++) { 13479 if (!reg_info->reg_rules_5g_ptr) 13480 break; 13481 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 13482 i, reg_info->reg_rules_5g_ptr[i].start_freq, 13483 reg_info->reg_rules_5g_ptr[i].end_freq, 13484 reg_info->reg_rules_5g_ptr[i].flags); 13485 } 13486 13487 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 13488 reg_info->reg_rules_6g_ap_ptr[i] = 13489 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 13490 ext_wmi_reg_rule); 13491 13492 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 13493 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 13494 if (!reg_info->reg_rules_6g_ap_ptr[i]) 13495 break; 13496 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 13497 i, j, 13498 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 13499 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 13500 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 13501 } 13502 } 13503 13504 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 13505 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 13506 reg_info->reg_rules_6g_client_ptr[j][i] = 13507 create_ext_reg_rules_from_wmi( 13508 num_6g_reg_rules_client[j][i], 13509 ext_wmi_reg_rule); 13510 13511 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 13512 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 13513 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 13514 break; 13515 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 13516 j, i, k, 13517 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 13518 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 13519 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 13520 } 13521 } 13522 } 13523 13524 reg_info->client_type = ext_chan_list_event_hdr->client_type; 13525 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 13526 reg_info->unspecified_ap_usable = 13527 ext_chan_list_event_hdr->unspecified_ap_usable; 13528 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 13529 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 13530 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 13531 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 13532 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 13533 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 13534 13535 wmi_debug("client type %d", reg_info->client_type); 13536 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 13537 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 13538 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 13539 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 13540 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 13541 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 13542 13543 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 13544 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 13545 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 13546 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 13547 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 13548 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 13549 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 13550 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 13551 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 13552 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 13553 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 13554 } 13555 13556 reg_info->domain_code_6g_super_id = 13557 ext_chan_list_event_hdr->domain_code_6g_super_id; 13558 13559 wmi_debug("processed regulatory extended channel list"); 13560 13561 return QDF_STATUS_SUCCESS; 13562 } 13563 13564 #ifdef CONFIG_AFC_SUPPORT 13565 /** 13566 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 13567 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 13568 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 13569 * an index pointer required to store the current index of 13570 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 13571 * @chan_eirp_info: pointer to chan_eirp_info 13572 * @num_chans: Number of channels 13573 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 13574 * @index: Pointer to index 13575 * 13576 * Return: void 13577 */ 13578 static void 13579 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 13580 uint8_t num_chans, 13581 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 13582 uint8_t *index) 13583 { 13584 uint8_t chan_idx; 13585 13586 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 13587 chan_eirp_info[chan_idx].cfi = 13588 chan_eirp_power_info_hdr[*index].channel_cfi; 13589 chan_eirp_info[chan_idx].eirp_power = 13590 chan_eirp_power_info_hdr[*index].eirp_pwr; 13591 } 13592 } 13593 13594 /** 13595 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 13596 * to the internal buffer afc_chan_info. 13597 * @afc_chan_info: pointer to afc_chan_info 13598 * @num_chan_objs: Number of channel objects 13599 * @channel_info_hdr: Pointer to channel_info_hdr 13600 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 13601 * 13602 * Return: void 13603 */ 13604 static void 13605 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 13606 uint8_t num_chan_objs, 13607 wmi_6g_afc_channel_info *channel_info_hdr, 13608 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 13609 { 13610 uint8_t count; 13611 uint8_t src_pwr_index = 0; 13612 13613 for (count = 0; count < num_chan_objs; count++) { 13614 afc_chan_info[count].global_opclass = 13615 channel_info_hdr[count].global_operating_class; 13616 afc_chan_info[count].num_chans = 13617 channel_info_hdr[count].num_channels; 13618 13619 if (afc_chan_info[count].num_chans > 0) { 13620 struct chan_eirp_obj *chan_eirp_info; 13621 13622 chan_eirp_info = 13623 qdf_mem_malloc(afc_chan_info[count].num_chans * 13624 sizeof(*chan_eirp_info)); 13625 13626 if (!chan_eirp_info) 13627 return; 13628 13629 copy_afc_chan_eirp_info(chan_eirp_info, 13630 afc_chan_info[count].num_chans, 13631 chan_eirp_power_info_hdr, 13632 &src_pwr_index); 13633 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 13634 } else { 13635 wmi_err("Number of channels is zero in object idx %d", 13636 count); 13637 } 13638 } 13639 } 13640 13641 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 13642 uint8_t num_freq_objs, 13643 wmi_6g_afc_frequency_info *freq_info_hdr) 13644 { 13645 uint8_t count; 13646 13647 for (count = 0; count < num_freq_objs; count++) { 13648 afc_freq_info[count].low_freq = 13649 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 13650 afc_freq_info[count].high_freq = 13651 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 13652 afc_freq_info[count].max_psd = 13653 freq_info_hdr[count].psd_power_info; 13654 } 13655 } 13656 13657 /** 13658 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 13659 * the power event info from the WMI AFC event buffer to the internal buffer 13660 * power_info. 13661 * @power_info: pointer to power_info 13662 * @afc_power_event_hdr: pointer to afc_power_event_hdr 13663 * 13664 * Return: void 13665 */ 13666 static void 13667 copy_afc_event_fixed_hdr_power_info( 13668 struct reg_fw_afc_power_event *power_info, 13669 wmi_afc_power_event_param *afc_power_event_hdr) 13670 { 13671 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 13672 power_info->resp_id = afc_power_event_hdr->resp_id; 13673 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 13674 power_info->afc_wfa_version = 13675 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 13676 power_info->afc_wfa_version |= 13677 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 13678 13679 power_info->avail_exp_time_d = 13680 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 13681 power_info->avail_exp_time_d |= 13682 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 13683 power_info->avail_exp_time_d |= 13684 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 13685 13686 power_info->avail_exp_time_t = 13687 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 13688 power_info->avail_exp_time_t |= 13689 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 13690 power_info->avail_exp_time_t |= 13691 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 13692 } 13693 13694 /** 13695 * copy_power_event() - Copy the power event parameters from the AFC event 13696 * buffer to the power_info within the afc_info. 13697 * @afc_info: pointer to afc_info 13698 * @param_buf: pointer to param_buf 13699 * 13700 * Return: void 13701 */ 13702 static void copy_power_event(struct afc_regulatory_info *afc_info, 13703 WMI_AFC_EVENTID_param_tlvs *param_buf) 13704 { 13705 struct reg_fw_afc_power_event *power_info; 13706 wmi_afc_power_event_param *afc_power_event_hdr; 13707 struct afc_freq_obj *afc_freq_info; 13708 13709 power_info = qdf_mem_malloc(sizeof(*power_info)); 13710 13711 if (!power_info) 13712 return; 13713 13714 afc_power_event_hdr = param_buf->afc_power_event_param; 13715 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 13716 afc_info->power_info = power_info; 13717 13718 power_info->num_freq_objs = param_buf->num_freq_info_array; 13719 if (power_info->num_freq_objs > 0) { 13720 wmi_6g_afc_frequency_info *freq_info_hdr; 13721 13722 freq_info_hdr = param_buf->freq_info_array; 13723 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 13724 sizeof(*afc_freq_info)); 13725 13726 if (!afc_freq_info) 13727 return; 13728 13729 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 13730 freq_info_hdr); 13731 power_info->afc_freq_info = afc_freq_info; 13732 } else { 13733 wmi_err("Number of frequency objects is zero"); 13734 } 13735 13736 power_info->num_chan_objs = param_buf->num_channel_info_array; 13737 if (power_info->num_chan_objs > 0) { 13738 struct afc_chan_obj *afc_chan_info; 13739 wmi_6g_afc_channel_info *channel_info_hdr; 13740 13741 channel_info_hdr = param_buf->channel_info_array; 13742 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 13743 sizeof(*afc_chan_info)); 13744 13745 if (!afc_chan_info) 13746 return; 13747 13748 copy_afc_chan_obj_info(afc_chan_info, 13749 power_info->num_chan_objs, 13750 channel_info_hdr, 13751 param_buf->chan_eirp_power_info_array); 13752 power_info->afc_chan_info = afc_chan_info; 13753 } else { 13754 wmi_err("Number of channel objects is zero"); 13755 } 13756 } 13757 13758 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 13759 WMI_AFC_EVENTID_param_tlvs *param_buf) 13760 { 13761 struct reg_afc_expiry_event *expiry_info; 13762 13763 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 13764 13765 if (!expiry_info) 13766 return; 13767 13768 expiry_info->request_id = 13769 param_buf->expiry_event_param->request_id; 13770 expiry_info->event_subtype = 13771 param_buf->expiry_event_param->event_subtype; 13772 afc_info->expiry_info = expiry_info; 13773 } 13774 13775 /** 13776 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 13777 * in the AFC event. 'Common' indicates that these parameters are common for 13778 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 13779 * @wmi_handle: wmi handle 13780 * @afc_info: pointer to afc_info 13781 * @event_fixed_hdr: pointer to event_fixed_hdr 13782 * 13783 * Return: void 13784 */ 13785 static void 13786 copy_afc_event_common_info(wmi_unified_t wmi_handle, 13787 struct afc_regulatory_info *afc_info, 13788 wmi_afc_event_fixed_param *event_fixed_hdr) 13789 { 13790 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 13791 wmi_handle, event_fixed_hdr->phy_id); 13792 afc_info->event_type = event_fixed_hdr->event_type; 13793 } 13794 13795 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 13796 uint8_t *evt_buf, 13797 struct afc_regulatory_info *afc_info, 13798 uint32_t len) 13799 { 13800 WMI_AFC_EVENTID_param_tlvs *param_buf; 13801 wmi_afc_event_fixed_param *event_fixed_hdr; 13802 13803 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 13804 if (!param_buf) { 13805 wmi_err("Invalid AFC event buf"); 13806 return QDF_STATUS_E_FAILURE; 13807 } 13808 13809 event_fixed_hdr = param_buf->fixed_param; 13810 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 13811 13812 switch (afc_info->event_type) { 13813 case WMI_AFC_EVENT_POWER_INFO: 13814 copy_power_event(afc_info, param_buf); 13815 break; 13816 case WMI_AFC_EVENT_TIMER_EXPIRY: 13817 copy_expiry_event(afc_info, param_buf); 13818 return QDF_STATUS_SUCCESS; 13819 default: 13820 wmi_err("Invalid event type"); 13821 return QDF_STATUS_E_FAILURE; 13822 } 13823 13824 return QDF_STATUS_SUCCESS; 13825 } 13826 #endif 13827 #endif 13828 13829 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 13830 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13831 struct cur_regulatory_info *reg_info, uint32_t len) 13832 { 13833 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 13834 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 13835 wmi_regulatory_rule_struct *wmi_reg_rule; 13836 uint32_t num_2g_reg_rules, num_5g_reg_rules; 13837 13838 wmi_debug("processing regulatory channel list"); 13839 13840 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 13841 if (!param_buf) { 13842 wmi_err("invalid channel list event buf"); 13843 return QDF_STATUS_E_FAILURE; 13844 } 13845 13846 chan_list_event_hdr = param_buf->fixed_param; 13847 13848 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 13849 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 13850 num_2g_reg_rules = reg_info->num_2g_reg_rules; 13851 num_5g_reg_rules = reg_info->num_5g_reg_rules; 13852 if ((num_2g_reg_rules > MAX_REG_RULES) || 13853 (num_5g_reg_rules > MAX_REG_RULES) || 13854 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 13855 (num_2g_reg_rules + num_5g_reg_rules != 13856 param_buf->num_reg_rule_array)) { 13857 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 13858 num_2g_reg_rules, num_5g_reg_rules); 13859 return QDF_STATUS_E_FAILURE; 13860 } 13861 if (param_buf->num_reg_rule_array > 13862 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 13863 sizeof(*wmi_reg_rule)) { 13864 wmi_err_rl("Invalid num_reg_rule_array: %u", 13865 param_buf->num_reg_rule_array); 13866 return QDF_STATUS_E_FAILURE; 13867 } 13868 13869 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 13870 REG_ALPHA2_LEN); 13871 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 13872 reg_info->phybitmap = convert_phybitmap_tlv( 13873 chan_list_event_hdr->phybitmap); 13874 reg_info->offload_enabled = true; 13875 reg_info->num_phy = chan_list_event_hdr->num_phy; 13876 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 13877 wmi_handle, chan_list_event_hdr->phy_id); 13878 reg_info->ctry_code = chan_list_event_hdr->country_id; 13879 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 13880 13881 reg_info->status_code = 13882 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 13883 13884 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 13885 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 13886 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 13887 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 13888 13889 wmi_debug("num_phys = %u and phy_id = %u", 13890 reg_info->num_phy, reg_info->phy_id); 13891 13892 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 13893 reg_info->alpha2, reg_info->dfs_region, 13894 reg_info->min_bw_2g, reg_info->max_bw_2g, 13895 reg_info->min_bw_5g, reg_info->max_bw_5g); 13896 13897 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 13898 num_2g_reg_rules, num_5g_reg_rules); 13899 wmi_reg_rule = 13900 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 13901 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 13902 + WMI_TLV_HDR_SIZE); 13903 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 13904 wmi_reg_rule); 13905 wmi_reg_rule += num_2g_reg_rules; 13906 13907 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 13908 wmi_reg_rule); 13909 13910 wmi_debug("processed regulatory channel list"); 13911 13912 return QDF_STATUS_SUCCESS; 13913 } 13914 13915 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 13916 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13917 struct reg_11d_new_country *reg_11d_country, uint32_t len) 13918 { 13919 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 13920 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 13921 13922 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 13923 if (!param_buf) { 13924 wmi_err("invalid 11d country event buf"); 13925 return QDF_STATUS_E_FAILURE; 13926 } 13927 13928 reg_11d_country_event = param_buf->fixed_param; 13929 13930 qdf_mem_copy(reg_11d_country->alpha2, 13931 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 13932 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 13933 13934 wmi_debug("processed 11d country event, new cc %s", 13935 reg_11d_country->alpha2); 13936 13937 return QDF_STATUS_SUCCESS; 13938 } 13939 13940 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 13941 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13942 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 13943 { 13944 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 13945 wmi_avoid_freq_range_desc *afr_desc; 13946 uint32_t num_freq_ranges, freq_range_idx; 13947 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 13948 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 13949 13950 if (!param_buf) { 13951 wmi_err("Invalid channel avoid event buffer"); 13952 return QDF_STATUS_E_INVAL; 13953 } 13954 13955 afr_fixed_param = param_buf->fixed_param; 13956 if (!afr_fixed_param) { 13957 wmi_err("Invalid channel avoid event fixed param buffer"); 13958 return QDF_STATUS_E_INVAL; 13959 } 13960 13961 if (!ch_avoid_ind) { 13962 wmi_err("Invalid channel avoid indication buffer"); 13963 return QDF_STATUS_E_INVAL; 13964 } 13965 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 13966 wmi_err("no.of freq ranges exceeded the limit"); 13967 return QDF_STATUS_E_INVAL; 13968 } 13969 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 13970 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 13971 afr_fixed_param->num_freq_ranges; 13972 13973 wmi_debug("Channel avoid event received with %d ranges", 13974 num_freq_ranges); 13975 13976 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 13977 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 13978 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 13979 freq_range_idx++) { 13980 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 13981 afr_desc->start_freq; 13982 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 13983 afr_desc->end_freq; 13984 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 13985 freq_range_idx, afr_desc->tlv_header, 13986 afr_desc->start_freq, afr_desc->end_freq); 13987 afr_desc++; 13988 } 13989 13990 return QDF_STATUS_SUCCESS; 13991 } 13992 13993 #ifdef DFS_COMPONENT_ENABLE 13994 /** 13995 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 13996 * @wmi_handle: wma handle 13997 * @evt_buf: event buffer 13998 * @vdev_id: vdev id 13999 * @len: length of buffer 14000 * 14001 * Return: 0 for success or error code 14002 */ 14003 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 14004 uint8_t *evt_buf, 14005 uint32_t *vdev_id, 14006 uint32_t len) 14007 { 14008 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 14009 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 14010 14011 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 14012 if (!param_tlvs) { 14013 wmi_err("invalid cac complete event buf"); 14014 return QDF_STATUS_E_FAILURE; 14015 } 14016 14017 cac_event = param_tlvs->fixed_param; 14018 *vdev_id = cac_event->vdev_id; 14019 wmi_debug("processed cac complete event vdev %d", *vdev_id); 14020 14021 return QDF_STATUS_SUCCESS; 14022 } 14023 14024 /** 14025 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 14026 * @wmi_handle: wma handle 14027 * @evt_buf: event buffer 14028 * @vdev_id: vdev id 14029 * @len: length of buffer 14030 * 14031 * Return: 0 for success or error code 14032 */ 14033 static QDF_STATUS 14034 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 14035 uint8_t *evt_buf, 14036 struct vdev_adfs_complete_status *param) 14037 { 14038 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 14039 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 14040 14041 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 14042 if (!param_tlvs) { 14043 wmi_err("invalid ocac complete event buf"); 14044 return QDF_STATUS_E_FAILURE; 14045 } 14046 14047 if (!param_tlvs->fixed_param) { 14048 wmi_err("invalid param_tlvs->fixed_param"); 14049 return QDF_STATUS_E_FAILURE; 14050 } 14051 14052 ocac_complete_status = param_tlvs->fixed_param; 14053 param->vdev_id = ocac_complete_status->vdev_id; 14054 param->chan_freq = ocac_complete_status->chan_freq; 14055 param->center_freq1 = ocac_complete_status->center_freq1; 14056 param->center_freq2 = ocac_complete_status->center_freq2; 14057 param->ocac_status = ocac_complete_status->status; 14058 param->chan_width = ocac_complete_status->chan_width; 14059 wmi_debug("processed ocac complete event vdev %d" 14060 " agile chan %d %d width %d status %d", 14061 param->vdev_id, 14062 param->center_freq1, 14063 param->center_freq2, 14064 param->chan_width, 14065 param->ocac_status); 14066 14067 return QDF_STATUS_SUCCESS; 14068 } 14069 14070 /** 14071 * extract_dfs_radar_detection_event_tlv() - extract radar found event 14072 * @wmi_handle: wma handle 14073 * @evt_buf: event buffer 14074 * @radar_found: radar found event info 14075 * @len: length of buffer 14076 * 14077 * Return: 0 for success or error code 14078 */ 14079 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 14080 wmi_unified_t wmi_handle, 14081 uint8_t *evt_buf, 14082 struct radar_found_info *radar_found, 14083 uint32_t len) 14084 { 14085 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 14086 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 14087 14088 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 14089 if (!param_tlv) { 14090 wmi_err("invalid radar detection event buf"); 14091 return QDF_STATUS_E_FAILURE; 14092 } 14093 14094 radar_event = param_tlv->fixed_param; 14095 14096 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 14097 wmi_handle, 14098 radar_event->pdev_id); 14099 14100 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 14101 return QDF_STATUS_E_FAILURE; 14102 14103 radar_found->detection_mode = radar_event->detection_mode; 14104 radar_found->chan_freq = radar_event->chan_freq; 14105 radar_found->chan_width = radar_event->chan_width; 14106 radar_found->detector_id = radar_event->detector_id; 14107 radar_found->segment_id = radar_event->segment_id; 14108 radar_found->timestamp = radar_event->timestamp; 14109 radar_found->is_chirp = radar_event->is_chirp; 14110 radar_found->freq_offset = radar_event->freq_offset; 14111 radar_found->sidx = radar_event->sidx; 14112 14113 wmi_debug("processed radar found event pdev %d," 14114 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 14115 "chan_width (RSSI) %d,detector_id (false_radar) %d," 14116 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 14117 "is_chirp %d,detection mode %d", 14118 radar_event->pdev_id, radar_found->pdev_id, 14119 radar_event->timestamp, radar_event->chan_freq, 14120 radar_event->chan_width, radar_event->detector_id, 14121 radar_event->freq_offset, radar_event->segment_id, 14122 radar_event->sidx, radar_event->is_chirp, 14123 radar_event->detection_mode); 14124 14125 return QDF_STATUS_SUCCESS; 14126 } 14127 14128 #ifdef MOBILE_DFS_SUPPORT 14129 /** 14130 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 14131 * @wmi_handle: wma handle 14132 * @evt_buf: event buffer 14133 * @wlan_radar_event: Pointer to struct radar_event_info 14134 * @len: length of buffer 14135 * 14136 * Return: QDF_STATUS 14137 */ 14138 static QDF_STATUS extract_wlan_radar_event_info_tlv( 14139 wmi_unified_t wmi_handle, 14140 uint8_t *evt_buf, 14141 struct radar_event_info *wlan_radar_event, 14142 uint32_t len) 14143 { 14144 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 14145 wmi_dfs_radar_event_fixed_param *radar_event; 14146 14147 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 14148 if (!param_tlv) { 14149 wmi_err("invalid wlan radar event buf"); 14150 return QDF_STATUS_E_FAILURE; 14151 } 14152 14153 radar_event = param_tlv->fixed_param; 14154 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 14155 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 14156 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 14157 wlan_radar_event->rssi = radar_event->rssi; 14158 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 14159 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 14160 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 14161 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 14162 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 14163 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 14164 if (radar_event->pulse_flags & 14165 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 14166 wlan_radar_event->is_psidx_diff_valid = true; 14167 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 14168 } else { 14169 wlan_radar_event->is_psidx_diff_valid = false; 14170 } 14171 14172 wlan_radar_event->pdev_id = radar_event->pdev_id; 14173 14174 return QDF_STATUS_SUCCESS; 14175 } 14176 #else 14177 static QDF_STATUS extract_wlan_radar_event_info_tlv( 14178 wmi_unified_t wmi_handle, 14179 uint8_t *evt_buf, 14180 struct radar_event_info *wlan_radar_event, 14181 uint32_t len) 14182 { 14183 return QDF_STATUS_SUCCESS; 14184 } 14185 #endif 14186 #endif 14187 14188 /** 14189 * send_get_rcpi_cmd_tlv() - send request for rcpi value 14190 * @wmi_handle: wmi handle 14191 * @get_rcpi_param: rcpi params 14192 * 14193 * Return: QDF status 14194 */ 14195 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 14196 struct rcpi_req *get_rcpi_param) 14197 { 14198 wmi_buf_t buf; 14199 wmi_request_rcpi_cmd_fixed_param *cmd; 14200 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 14201 14202 buf = wmi_buf_alloc(wmi_handle, len); 14203 if (!buf) 14204 return QDF_STATUS_E_NOMEM; 14205 14206 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 14207 WMITLV_SET_HDR(&cmd->tlv_header, 14208 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 14209 WMITLV_GET_STRUCT_TLVLEN 14210 (wmi_request_rcpi_cmd_fixed_param)); 14211 14212 cmd->vdev_id = get_rcpi_param->vdev_id; 14213 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 14214 &cmd->peer_macaddr); 14215 14216 switch (get_rcpi_param->measurement_type) { 14217 14218 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 14219 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 14220 break; 14221 14222 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 14223 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 14224 break; 14225 14226 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 14227 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 14228 break; 14229 14230 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 14231 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 14232 break; 14233 14234 default: 14235 /* 14236 * invalid rcpi measurement type, fall back to 14237 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 14238 */ 14239 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 14240 break; 14241 } 14242 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 14243 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 14244 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14245 WMI_REQUEST_RCPI_CMDID)) { 14246 14247 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 14248 wmi_buf_free(buf); 14249 return QDF_STATUS_E_FAILURE; 14250 } 14251 14252 return QDF_STATUS_SUCCESS; 14253 } 14254 14255 /** 14256 * extract_rcpi_response_event_tlv() - Extract RCPI event params 14257 * @wmi_handle: wmi handle 14258 * @evt_buf: pointer to event buffer 14259 * @res: pointer to hold rcpi response from firmware 14260 * 14261 * Return: QDF_STATUS_SUCCESS for successful event parse 14262 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 14263 */ 14264 static QDF_STATUS 14265 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 14266 void *evt_buf, struct rcpi_res *res) 14267 { 14268 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 14269 wmi_update_rcpi_event_fixed_param *event; 14270 14271 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 14272 if (!param_buf) { 14273 wmi_err("Invalid rcpi event"); 14274 return QDF_STATUS_E_INVAL; 14275 } 14276 14277 event = param_buf->fixed_param; 14278 res->vdev_id = event->vdev_id; 14279 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 14280 14281 switch (event->measurement_type) { 14282 14283 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 14284 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 14285 break; 14286 14287 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 14288 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 14289 break; 14290 14291 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 14292 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 14293 break; 14294 14295 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 14296 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 14297 break; 14298 14299 default: 14300 wmi_err("Invalid rcpi measurement type from firmware"); 14301 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 14302 return QDF_STATUS_E_FAILURE; 14303 } 14304 14305 if (event->status) 14306 return QDF_STATUS_E_FAILURE; 14307 else 14308 return QDF_STATUS_SUCCESS; 14309 } 14310 14311 /** 14312 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 14313 * host to target defines. For legacy there is not conversion 14314 * required. Just return pdev_id as it is. 14315 * @param pdev_id: host pdev_id to be converted. 14316 * Return: target pdev_id after conversion. 14317 */ 14318 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 14319 wmi_unified_t wmi_handle, 14320 uint32_t pdev_id) 14321 { 14322 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 14323 return WMI_PDEV_ID_SOC; 14324 14325 /*No conversion required*/ 14326 return pdev_id; 14327 } 14328 14329 /** 14330 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 14331 * target to host defines. For legacy there is not conversion 14332 * required. Just return pdev_id as it is. 14333 * @param pdev_id: target pdev_id to be converted. 14334 * Return: host pdev_id after conversion. 14335 */ 14336 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 14337 wmi_unified_t wmi_handle, 14338 uint32_t pdev_id) 14339 { 14340 /*No conversion required*/ 14341 return pdev_id; 14342 } 14343 14344 /** 14345 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 14346 * host to target defines. For legacy there is not conversion 14347 * required. Just return phy_id as it is. 14348 * @param pdev_id: host phy_id to be converted. 14349 * Return: target phy_id after conversion. 14350 */ 14351 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 14352 wmi_unified_t wmi_handle, 14353 uint32_t phy_id) 14354 { 14355 /*No conversion required*/ 14356 return phy_id; 14357 } 14358 14359 /** 14360 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 14361 * target to host defines. For legacy there is not conversion 14362 * required. Just return phy_id as it is. 14363 * @param pdev_id: target phy_id to be converted. 14364 * Return: host phy_id after conversion. 14365 */ 14366 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 14367 wmi_unified_t wmi_handle, 14368 uint32_t phy_id) 14369 { 14370 /*No conversion required*/ 14371 return phy_id; 14372 } 14373 14374 /** 14375 * send_set_country_cmd_tlv() - WMI scan channel list function 14376 * @param wmi_handle : handle to WMI. 14377 * @param param : pointer to hold scan channel list parameter 14378 * 14379 * Return: 0 on success and -ve on failure. 14380 */ 14381 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 14382 struct set_country *params) 14383 { 14384 wmi_buf_t buf; 14385 QDF_STATUS qdf_status; 14386 wmi_set_current_country_cmd_fixed_param *cmd; 14387 uint16_t len = sizeof(*cmd); 14388 uint8_t pdev_id = params->pdev_id; 14389 14390 buf = wmi_buf_alloc(wmi_handle, len); 14391 if (!buf) { 14392 qdf_status = QDF_STATUS_E_NOMEM; 14393 goto end; 14394 } 14395 14396 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 14397 WMITLV_SET_HDR(&cmd->tlv_header, 14398 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 14399 WMITLV_GET_STRUCT_TLVLEN 14400 (wmi_set_current_country_cmd_fixed_param)); 14401 14402 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 14403 wmi_handle, 14404 pdev_id); 14405 wmi_debug("setting current country to %s and target pdev_id = %u", 14406 params->country, cmd->pdev_id); 14407 14408 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 14409 14410 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 14411 qdf_status = wmi_unified_cmd_send(wmi_handle, 14412 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 14413 14414 if (QDF_IS_STATUS_ERROR(qdf_status)) { 14415 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 14416 wmi_buf_free(buf); 14417 } 14418 14419 end: 14420 return qdf_status; 14421 } 14422 14423 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 14424 WMI_SET_BITS(alpha, 0, 8, val0); \ 14425 WMI_SET_BITS(alpha, 8, 8, val1); \ 14426 WMI_SET_BITS(alpha, 16, 8, val2); \ 14427 } while (0) 14428 14429 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 14430 uint8_t pdev_id, struct cc_regdmn_s *rd) 14431 { 14432 wmi_set_init_country_cmd_fixed_param *cmd; 14433 uint16_t len; 14434 wmi_buf_t buf; 14435 int ret; 14436 14437 len = sizeof(wmi_set_init_country_cmd_fixed_param); 14438 buf = wmi_buf_alloc(wmi_handle, len); 14439 if (!buf) 14440 return QDF_STATUS_E_NOMEM; 14441 14442 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 14443 WMITLV_SET_HDR(&cmd->tlv_header, 14444 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 14445 WMITLV_GET_STRUCT_TLVLEN 14446 (wmi_set_init_country_cmd_fixed_param)); 14447 14448 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 14449 wmi_handle, 14450 pdev_id); 14451 14452 if (rd->flags == CC_IS_SET) { 14453 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 14454 cmd->country_code.country_id = rd->cc.country_code; 14455 } else if (rd->flags == ALPHA_IS_SET) { 14456 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 14457 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 14458 rd->cc.alpha[0], 14459 rd->cc.alpha[1], 14460 rd->cc.alpha[2]); 14461 } else if (rd->flags == REGDMN_IS_SET) { 14462 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 14463 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 14464 rd->cc.regdmn.reg_2g_5g_pair_id); 14465 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 14466 rd->cc.regdmn.sixg_superdmn_id); 14467 } 14468 14469 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 14470 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14471 WMI_SET_INIT_COUNTRY_CMDID); 14472 if (ret) { 14473 wmi_err("Failed to config wow wakeup event"); 14474 wmi_buf_free(buf); 14475 return QDF_STATUS_E_FAILURE; 14476 } 14477 14478 return QDF_STATUS_SUCCESS; 14479 } 14480 14481 /** 14482 * send_obss_detection_cfg_cmd_tlv() - send obss detection 14483 * configurations to firmware. 14484 * @wmi_handle: wmi handle 14485 * @obss_cfg_param: obss detection configurations 14486 * 14487 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 14488 * 14489 * Return: QDF_STATUS 14490 */ 14491 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 14492 struct wmi_obss_detection_cfg_param *obss_cfg_param) 14493 { 14494 wmi_buf_t buf; 14495 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 14496 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 14497 14498 buf = wmi_buf_alloc(wmi_handle, len); 14499 if (!buf) 14500 return QDF_STATUS_E_NOMEM; 14501 14502 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 14503 WMITLV_SET_HDR(&cmd->tlv_header, 14504 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 14505 WMITLV_GET_STRUCT_TLVLEN 14506 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 14507 14508 cmd->vdev_id = obss_cfg_param->vdev_id; 14509 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 14510 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 14511 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 14512 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 14513 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 14514 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 14515 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 14516 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 14517 14518 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 14519 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14520 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 14521 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 14522 wmi_buf_free(buf); 14523 return QDF_STATUS_E_FAILURE; 14524 } 14525 14526 return QDF_STATUS_SUCCESS; 14527 } 14528 14529 /** 14530 * extract_obss_detection_info_tlv() - Extract obss detection info 14531 * received from firmware. 14532 * @evt_buf: pointer to event buffer 14533 * @obss_detection: Pointer to hold obss detection info 14534 * 14535 * Return: QDF_STATUS 14536 */ 14537 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 14538 struct wmi_obss_detect_info 14539 *obss_detection) 14540 { 14541 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 14542 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 14543 14544 if (!obss_detection) { 14545 wmi_err("Invalid obss_detection event buffer"); 14546 return QDF_STATUS_E_INVAL; 14547 } 14548 14549 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 14550 if (!param_buf) { 14551 wmi_err("Invalid evt_buf"); 14552 return QDF_STATUS_E_INVAL; 14553 } 14554 14555 fix_param = param_buf->fixed_param; 14556 obss_detection->vdev_id = fix_param->vdev_id; 14557 obss_detection->matched_detection_masks = 14558 fix_param->matched_detection_masks; 14559 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 14560 &obss_detection->matched_bssid_addr[0]); 14561 switch (fix_param->reason) { 14562 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 14563 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 14564 break; 14565 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 14566 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 14567 break; 14568 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 14569 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 14570 break; 14571 default: 14572 wmi_err("Invalid reason: %d", fix_param->reason); 14573 return QDF_STATUS_E_INVAL; 14574 } 14575 14576 return QDF_STATUS_SUCCESS; 14577 } 14578 14579 /** 14580 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 14581 * @wmi_handle: wmi handle 14582 * @params: pointer to request structure 14583 * 14584 * Return: QDF_STATUS 14585 */ 14586 static QDF_STATUS 14587 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 14588 struct wmi_roam_scan_stats_req *params) 14589 { 14590 wmi_buf_t buf; 14591 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 14592 WMITLV_TAG_ID tag; 14593 uint32_t size; 14594 uint32_t len = sizeof(*cmd); 14595 14596 buf = wmi_buf_alloc(wmi_handle, len); 14597 if (!buf) 14598 return QDF_STATUS_E_FAILURE; 14599 14600 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 14601 14602 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 14603 size = WMITLV_GET_STRUCT_TLVLEN( 14604 wmi_request_roam_scan_stats_cmd_fixed_param); 14605 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 14606 14607 cmd->vdev_id = params->vdev_id; 14608 14609 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 14610 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14611 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 14612 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 14613 wmi_buf_free(buf); 14614 return QDF_STATUS_E_FAILURE; 14615 } 14616 14617 return QDF_STATUS_SUCCESS; 14618 } 14619 14620 /** 14621 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 14622 * channel list from firmware 14623 * @wmi_handle: wmi handler 14624 * @vdev_id: vdev id 14625 * 14626 * Return: QDF_STATUS 14627 */ 14628 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 14629 uint32_t vdev_id) 14630 { 14631 wmi_buf_t buf; 14632 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 14633 uint16_t len = sizeof(*cmd); 14634 int ret; 14635 14636 buf = wmi_buf_alloc(wmi_handle, len); 14637 if (!buf) { 14638 wmi_err("Failed to allocate wmi buffer"); 14639 return QDF_STATUS_E_NOMEM; 14640 } 14641 14642 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 14643 wmi_buf_data(buf); 14644 WMITLV_SET_HDR(&cmd->tlv_header, 14645 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 14646 WMITLV_GET_STRUCT_TLVLEN( 14647 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 14648 cmd->vdev_id = vdev_id; 14649 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 14650 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14651 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 14652 if (QDF_IS_STATUS_ERROR(ret)) { 14653 wmi_err("Failed to send get roam scan channels request = %d", 14654 ret); 14655 wmi_buf_free(buf); 14656 } 14657 return ret; 14658 } 14659 14660 /** 14661 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 14662 * @wmi_handle: wmi handle 14663 * @evt_buf: pointer to event buffer 14664 * @vdev_id: output pointer to hold vdev id 14665 * @res_param: output pointer to hold the allocated response 14666 * 14667 * Return: QDF_STATUS 14668 */ 14669 static QDF_STATUS 14670 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14671 uint32_t *vdev_id, 14672 struct wmi_roam_scan_stats_res **res_param) 14673 { 14674 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 14675 wmi_roam_scan_stats_event_fixed_param *fixed_param; 14676 uint32_t *client_id = NULL; 14677 wmi_roaming_timestamp *timestamp = NULL; 14678 uint32_t *num_channels = NULL; 14679 uint32_t *chan_info = NULL; 14680 wmi_mac_addr *old_bssid = NULL; 14681 uint32_t *is_roaming_success = NULL; 14682 wmi_mac_addr *new_bssid = NULL; 14683 uint32_t *num_roam_candidates = NULL; 14684 wmi_roam_scan_trigger_reason *roam_reason = NULL; 14685 wmi_mac_addr *bssid = NULL; 14686 uint32_t *score = NULL; 14687 uint32_t *channel = NULL; 14688 uint32_t *rssi = NULL; 14689 int chan_idx = 0, cand_idx = 0; 14690 uint32_t total_len; 14691 struct wmi_roam_scan_stats_res *res; 14692 uint32_t i, j; 14693 uint32_t num_scans, scan_param_size; 14694 14695 *res_param = NULL; 14696 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 14697 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 14698 if (!param_buf) { 14699 wmi_err("Invalid roam scan stats event"); 14700 return QDF_STATUS_E_INVAL; 14701 } 14702 14703 fixed_param = param_buf->fixed_param; 14704 14705 num_scans = fixed_param->num_roam_scans; 14706 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 14707 *vdev_id = fixed_param->vdev_id; 14708 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 14709 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 14710 num_scans, WMI_ROAM_SCAN_STATS_MAX); 14711 return QDF_STATUS_E_INVAL; 14712 } 14713 14714 total_len = sizeof(*res) + num_scans * scan_param_size; 14715 14716 res = qdf_mem_malloc(total_len); 14717 if (!res) 14718 return QDF_STATUS_E_NOMEM; 14719 14720 if (!num_scans) { 14721 *res_param = res; 14722 return QDF_STATUS_SUCCESS; 14723 } 14724 14725 if (param_buf->client_id && 14726 param_buf->num_client_id == num_scans) 14727 client_id = param_buf->client_id; 14728 14729 if (param_buf->timestamp && 14730 param_buf->num_timestamp == num_scans) 14731 timestamp = param_buf->timestamp; 14732 14733 if (param_buf->old_bssid && 14734 param_buf->num_old_bssid == num_scans) 14735 old_bssid = param_buf->old_bssid; 14736 14737 if (param_buf->new_bssid && 14738 param_buf->num_new_bssid == num_scans) 14739 new_bssid = param_buf->new_bssid; 14740 14741 if (param_buf->is_roaming_success && 14742 param_buf->num_is_roaming_success == num_scans) 14743 is_roaming_success = param_buf->is_roaming_success; 14744 14745 if (param_buf->roam_reason && 14746 param_buf->num_roam_reason == num_scans) 14747 roam_reason = param_buf->roam_reason; 14748 14749 if (param_buf->num_channels && 14750 param_buf->num_num_channels == num_scans) { 14751 uint32_t count, chan_info_sum = 0; 14752 14753 num_channels = param_buf->num_channels; 14754 for (count = 0; count < param_buf->num_num_channels; count++) { 14755 if (param_buf->num_channels[count] > 14756 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 14757 wmi_err_rl("%u exceeded max scan channels %u", 14758 param_buf->num_channels[count], 14759 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 14760 goto error; 14761 } 14762 chan_info_sum += param_buf->num_channels[count]; 14763 } 14764 14765 if (param_buf->chan_info && 14766 param_buf->num_chan_info == chan_info_sum) 14767 chan_info = param_buf->chan_info; 14768 } 14769 14770 if (param_buf->num_roam_candidates && 14771 param_buf->num_num_roam_candidates == num_scans) { 14772 uint32_t cnt, roam_cand_sum = 0; 14773 14774 num_roam_candidates = param_buf->num_roam_candidates; 14775 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 14776 if (param_buf->num_roam_candidates[cnt] > 14777 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 14778 wmi_err_rl("%u exceeded max scan cand %u", 14779 param_buf->num_roam_candidates[cnt], 14780 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 14781 goto error; 14782 } 14783 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 14784 } 14785 14786 if (param_buf->bssid && 14787 param_buf->num_bssid == roam_cand_sum) 14788 bssid = param_buf->bssid; 14789 14790 if (param_buf->score && 14791 param_buf->num_score == roam_cand_sum) 14792 score = param_buf->score; 14793 14794 if (param_buf->channel && 14795 param_buf->num_channel == roam_cand_sum) 14796 channel = param_buf->channel; 14797 14798 if (param_buf->rssi && 14799 param_buf->num_rssi == roam_cand_sum) 14800 rssi = param_buf->rssi; 14801 } 14802 14803 res->num_roam_scans = num_scans; 14804 for (i = 0; i < num_scans; i++) { 14805 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 14806 14807 if (timestamp) 14808 roam->time_stamp = timestamp[i].lower32bit | 14809 (timestamp[i].upper32bit << 31); 14810 14811 if (client_id) 14812 roam->client_id = client_id[i]; 14813 14814 if (num_channels) { 14815 roam->num_scan_chans = num_channels[i]; 14816 if (chan_info) { 14817 for (j = 0; j < num_channels[i]; j++) 14818 roam->scan_freqs[j] = 14819 chan_info[chan_idx++]; 14820 } 14821 } 14822 14823 if (is_roaming_success) 14824 roam->is_roam_successful = is_roaming_success[i]; 14825 14826 if (roam_reason) { 14827 roam->trigger_id = roam_reason[i].trigger_id; 14828 roam->trigger_value = roam_reason[i].trigger_value; 14829 } 14830 14831 if (num_roam_candidates) { 14832 roam->num_roam_candidates = num_roam_candidates[i]; 14833 14834 for (j = 0; j < num_roam_candidates[i]; j++) { 14835 if (score) 14836 roam->cand[j].score = score[cand_idx]; 14837 if (rssi) 14838 roam->cand[j].rssi = rssi[cand_idx]; 14839 if (channel) 14840 roam->cand[j].freq = 14841 channel[cand_idx]; 14842 14843 if (bssid) 14844 WMI_MAC_ADDR_TO_CHAR_ARRAY( 14845 &bssid[cand_idx], 14846 roam->cand[j].bssid); 14847 14848 cand_idx++; 14849 } 14850 } 14851 14852 if (old_bssid) 14853 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 14854 roam->old_bssid); 14855 14856 if (new_bssid) 14857 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 14858 roam->new_bssid); 14859 } 14860 14861 *res_param = res; 14862 14863 return QDF_STATUS_SUCCESS; 14864 error: 14865 qdf_mem_free(res); 14866 return QDF_STATUS_E_FAILURE; 14867 } 14868 14869 /** 14870 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 14871 * @wmi_handle: wmi handle 14872 * @evt_buf: pointer to event buffer 14873 * @vdev_id: output pointer to hold vdev id 14874 * @tx_status: output pointer to hold the tx_status 14875 * 14876 * Return: QDF_STATUS 14877 */ 14878 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 14879 void *evt_buf, 14880 uint32_t *vdev_id, 14881 uint32_t *tx_status) { 14882 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 14883 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 14884 14885 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 14886 if (!param_buf) { 14887 wmi_err("Invalid offload bcn tx status event buffer"); 14888 return QDF_STATUS_E_INVAL; 14889 } 14890 14891 bcn_tx_status_event = param_buf->fixed_param; 14892 *vdev_id = bcn_tx_status_event->vdev_id; 14893 *tx_status = bcn_tx_status_event->tx_status; 14894 14895 return QDF_STATUS_SUCCESS; 14896 } 14897 14898 #ifdef WLAN_SUPPORT_GREEN_AP 14899 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 14900 uint8_t *evt_buf, 14901 struct wlan_green_ap_egap_status_info *egap_status_info_params) 14902 { 14903 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 14904 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 14905 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 14906 14907 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 14908 if (!param_buf) { 14909 wmi_err("Invalid EGAP Info status event buffer"); 14910 return QDF_STATUS_E_INVAL; 14911 } 14912 14913 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 14914 param_buf->fixed_param; 14915 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 14916 param_buf->chainmask_list; 14917 14918 if (!egap_info_event || !chainmask_event) { 14919 wmi_err("Invalid EGAP Info event or chainmask event"); 14920 return QDF_STATUS_E_INVAL; 14921 } 14922 14923 egap_status_info_params->status = egap_info_event->status; 14924 egap_status_info_params->mac_id = chainmask_event->mac_id; 14925 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 14926 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 14927 14928 return QDF_STATUS_SUCCESS; 14929 } 14930 #endif 14931 14932 /* 14933 * extract_comb_phyerr_tlv() - extract comb phy error from event 14934 * @wmi_handle: wmi handle 14935 * @evt_buf: pointer to event buffer 14936 * @datalen: data length of event buffer 14937 * @buf_offset: Pointer to hold value of current event buffer offset 14938 * post extraction 14939 * @phyerr: Pointer to hold phyerr 14940 * 14941 * Return: QDF_STATUS 14942 */ 14943 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 14944 void *evt_buf, 14945 uint16_t datalen, 14946 uint16_t *buf_offset, 14947 wmi_host_phyerr_t *phyerr) 14948 { 14949 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 14950 wmi_comb_phyerr_rx_hdr *pe_hdr; 14951 14952 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 14953 if (!param_tlvs) { 14954 wmi_debug("Received null data from FW"); 14955 return QDF_STATUS_E_FAILURE; 14956 } 14957 14958 pe_hdr = param_tlvs->hdr; 14959 if (!pe_hdr) { 14960 wmi_debug("Received Data PE Header is NULL"); 14961 return QDF_STATUS_E_FAILURE; 14962 } 14963 14964 /* Ensure it's at least the size of the header */ 14965 if (datalen < sizeof(*pe_hdr)) { 14966 wmi_debug("Expected minimum size %zu, received %d", 14967 sizeof(*pe_hdr), datalen); 14968 return QDF_STATUS_E_FAILURE; 14969 } 14970 14971 phyerr->pdev_id = wmi_handle->ops-> 14972 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 14973 phyerr->tsf64 = pe_hdr->tsf_l32; 14974 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 14975 phyerr->bufp = param_tlvs->bufp; 14976 14977 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 14978 wmi_debug("Invalid buf_len %d, num_bufp %d", 14979 pe_hdr->buf_len, param_tlvs->num_bufp); 14980 return QDF_STATUS_E_FAILURE; 14981 } 14982 14983 phyerr->buf_len = pe_hdr->buf_len; 14984 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 14985 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 14986 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 14987 14988 return QDF_STATUS_SUCCESS; 14989 } 14990 14991 /** 14992 * extract_single_phyerr_tlv() - extract single phy error from event 14993 * @wmi_handle: wmi handle 14994 * @evt_buf: pointer to event buffer 14995 * @datalen: data length of event buffer 14996 * @buf_offset: Pointer to hold value of current event buffer offset 14997 * post extraction 14998 * @phyerr: Pointer to hold phyerr 14999 * 15000 * Return: QDF_STATUS 15001 */ 15002 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 15003 void *evt_buf, 15004 uint16_t datalen, 15005 uint16_t *buf_offset, 15006 wmi_host_phyerr_t *phyerr) 15007 { 15008 wmi_single_phyerr_rx_event *ev; 15009 uint16_t n = *buf_offset; 15010 uint8_t *data = (uint8_t *)evt_buf; 15011 15012 if (n < datalen) { 15013 if ((datalen - n) < sizeof(ev->hdr)) { 15014 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 15015 datalen, n, sizeof(ev->hdr)); 15016 return QDF_STATUS_E_FAILURE; 15017 } 15018 15019 /* 15020 * Obtain a pointer to the beginning of the current event. 15021 * data[0] is the beginning of the WMI payload. 15022 */ 15023 ev = (wmi_single_phyerr_rx_event *)&data[n]; 15024 15025 /* 15026 * Sanity check the buffer length of the event against 15027 * what we currently have. 15028 * 15029 * Since buf_len is 32 bits, we check if it overflows 15030 * a large 32 bit value. It's not 0x7fffffff because 15031 * we increase n by (buf_len + sizeof(hdr)), which would 15032 * in itself cause n to overflow. 15033 * 15034 * If "int" is 64 bits then this becomes a moot point. 15035 */ 15036 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 15037 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 15038 return QDF_STATUS_E_FAILURE; 15039 } 15040 15041 if ((n + ev->hdr.buf_len) > datalen) { 15042 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 15043 n, ev->hdr.buf_len, datalen); 15044 return QDF_STATUS_E_FAILURE; 15045 } 15046 15047 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 15048 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 15049 phyerr->bufp = &ev->bufp[0]; 15050 phyerr->buf_len = ev->hdr.buf_len; 15051 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 15052 15053 /* 15054 * Advance the buffer pointer to the next PHY error. 15055 * buflen is the length of this payload, so we need to 15056 * advance past the current header _AND_ the payload. 15057 */ 15058 n += sizeof(*ev) + ev->hdr.buf_len; 15059 } 15060 *buf_offset = n; 15061 15062 return QDF_STATUS_SUCCESS; 15063 } 15064 15065 /** 15066 * extract_esp_estimation_ev_param_tlv() - extract air time from event 15067 * @wmi_handle: wmi handle 15068 * @evt_buf: pointer to event buffer 15069 * @param: Pointer to hold esp event 15070 * 15071 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 15072 */ 15073 static QDF_STATUS 15074 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 15075 void *evt_buf, 15076 struct esp_estimation_event *param) 15077 { 15078 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 15079 wmi_esp_estimate_event_fixed_param *esp_event; 15080 15081 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 15082 if (!param_buf) { 15083 wmi_err("Invalid ESP Estimate Event buffer"); 15084 return QDF_STATUS_E_INVAL; 15085 } 15086 esp_event = param_buf->fixed_param; 15087 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 15088 15089 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 15090 wmi_handle, 15091 esp_event->pdev_id); 15092 15093 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 15094 return QDF_STATUS_E_FAILURE; 15095 15096 return QDF_STATUS_SUCCESS; 15097 } 15098 15099 /* 15100 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 15101 * updating bss color change within firmware when AP announces bss color change. 15102 * @wmi_handle: wmi handle 15103 * @vdev_id: vdev ID 15104 * @enable: enable bss color change within firmware 15105 * 15106 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 15107 * 15108 * Return: QDF_STATUS 15109 */ 15110 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 15111 uint32_t vdev_id, 15112 bool enable) 15113 { 15114 wmi_buf_t buf; 15115 wmi_bss_color_change_enable_fixed_param *cmd; 15116 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 15117 15118 buf = wmi_buf_alloc(wmi_handle, len); 15119 if (!buf) 15120 return QDF_STATUS_E_NOMEM; 15121 15122 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 15123 WMITLV_SET_HDR(&cmd->tlv_header, 15124 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 15125 WMITLV_GET_STRUCT_TLVLEN 15126 (wmi_bss_color_change_enable_fixed_param)); 15127 cmd->vdev_id = vdev_id; 15128 cmd->enable = enable; 15129 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 15130 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15131 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 15132 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 15133 wmi_buf_free(buf); 15134 return QDF_STATUS_E_FAILURE; 15135 } 15136 15137 return QDF_STATUS_SUCCESS; 15138 } 15139 15140 /** 15141 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 15142 * configurations to firmware. 15143 * @wmi_handle: wmi handle 15144 * @cfg_param: obss detection configurations 15145 * 15146 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 15147 * 15148 * Return: QDF_STATUS 15149 */ 15150 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 15151 wmi_unified_t wmi_handle, 15152 struct wmi_obss_color_collision_cfg_param *cfg_param) 15153 { 15154 wmi_buf_t buf; 15155 wmi_obss_color_collision_det_config_fixed_param *cmd; 15156 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 15157 15158 buf = wmi_buf_alloc(wmi_handle, len); 15159 if (!buf) 15160 return QDF_STATUS_E_NOMEM; 15161 15162 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 15163 buf); 15164 WMITLV_SET_HDR(&cmd->tlv_header, 15165 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 15166 WMITLV_GET_STRUCT_TLVLEN 15167 (wmi_obss_color_collision_det_config_fixed_param)); 15168 cmd->vdev_id = cfg_param->vdev_id; 15169 cmd->flags = cfg_param->flags; 15170 cmd->current_bss_color = cfg_param->current_bss_color; 15171 cmd->detection_period_ms = cfg_param->detection_period_ms; 15172 cmd->scan_period_ms = cfg_param->scan_period_ms; 15173 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 15174 15175 switch (cfg_param->evt_type) { 15176 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 15177 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 15178 break; 15179 case OBSS_COLOR_COLLISION_DETECTION: 15180 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 15181 break; 15182 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 15183 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 15184 break; 15185 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 15186 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 15187 break; 15188 default: 15189 wmi_err("Invalid event type: %d", cfg_param->evt_type); 15190 wmi_buf_free(buf); 15191 return QDF_STATUS_E_FAILURE; 15192 } 15193 15194 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 15195 "detection_period_ms: %d scan_period_ms: %d " 15196 "free_slot_expiry_timer_ms: %d", 15197 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 15198 cmd->detection_period_ms, cmd->scan_period_ms, 15199 cmd->free_slot_expiry_time_ms); 15200 15201 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 15202 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15203 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 15204 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 15205 cfg_param->vdev_id); 15206 wmi_buf_free(buf); 15207 return QDF_STATUS_E_FAILURE; 15208 } 15209 15210 return QDF_STATUS_SUCCESS; 15211 } 15212 15213 /** 15214 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 15215 * received from firmware. 15216 * @evt_buf: pointer to event buffer 15217 * @info: Pointer to hold bss collision info 15218 * 15219 * Return: QDF_STATUS 15220 */ 15221 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 15222 struct wmi_obss_color_collision_info *info) 15223 { 15224 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 15225 wmi_obss_color_collision_evt_fixed_param *fix_param; 15226 15227 if (!info) { 15228 wmi_err("Invalid obss color buffer"); 15229 return QDF_STATUS_E_INVAL; 15230 } 15231 15232 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 15233 evt_buf; 15234 if (!param_buf) { 15235 wmi_err("Invalid evt_buf"); 15236 return QDF_STATUS_E_INVAL; 15237 } 15238 15239 fix_param = param_buf->fixed_param; 15240 info->vdev_id = fix_param->vdev_id; 15241 info->obss_color_bitmap_bit0to31 = 15242 fix_param->bss_color_bitmap_bit0to31; 15243 info->obss_color_bitmap_bit32to63 = 15244 fix_param->bss_color_bitmap_bit32to63; 15245 15246 switch (fix_param->evt_type) { 15247 case WMI_BSS_COLOR_COLLISION_DISABLE: 15248 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 15249 break; 15250 case WMI_BSS_COLOR_COLLISION_DETECTION: 15251 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 15252 break; 15253 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 15254 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 15255 break; 15256 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 15257 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 15258 break; 15259 default: 15260 wmi_err("Invalid event type: %d, vdev_id: %d", 15261 fix_param->evt_type, fix_param->vdev_id); 15262 return QDF_STATUS_E_FAILURE; 15263 } 15264 15265 return QDF_STATUS_SUCCESS; 15266 } 15267 15268 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 15269 { 15270 struct wmi_ops *ops = wmi_handle->ops; 15271 15272 ops->send_obss_color_collision_cfg_cmd = 15273 send_obss_color_collision_cfg_cmd_tlv; 15274 ops->extract_obss_color_collision_info = 15275 extract_obss_color_collision_info_tlv; 15276 } 15277 15278 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 15279 static QDF_STATUS 15280 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 15281 struct config_fils_params *param) 15282 { 15283 wmi_buf_t buf; 15284 wmi_enable_fils_cmd_fixed_param *cmd; 15285 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 15286 15287 buf = wmi_buf_alloc(wmi_handle, len); 15288 if (!buf) 15289 return QDF_STATUS_E_NOMEM; 15290 15291 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 15292 buf); 15293 WMITLV_SET_HDR(&cmd->tlv_header, 15294 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 15295 WMITLV_GET_STRUCT_TLVLEN 15296 (wmi_enable_fils_cmd_fixed_param)); 15297 cmd->vdev_id = param->vdev_id; 15298 cmd->fd_period = param->fd_period; 15299 if (param->send_prb_rsp_frame) 15300 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 15301 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 15302 cmd->vdev_id, cmd->fd_period, cmd->flags); 15303 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 15304 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15305 WMI_ENABLE_FILS_CMDID)) { 15306 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 15307 wmi_buf_free(buf); 15308 return QDF_STATUS_E_FAILURE; 15309 } 15310 15311 return QDF_STATUS_SUCCESS; 15312 } 15313 #endif 15314 15315 #ifdef WLAN_MWS_INFO_DEBUGFS 15316 /** 15317 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 15318 * 15319 * @wmi_handle: wmi handle 15320 * @vdev_id: vdev id 15321 * @cmd_id: Coex command id 15322 * 15323 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 15324 * 15325 * Return: QDF_STATUS 15326 */ 15327 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 15328 uint32_t vdev_id, 15329 uint32_t cmd_id) 15330 { 15331 wmi_buf_t buf; 15332 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 15333 uint16_t len = sizeof(*cmd); 15334 int ret; 15335 15336 buf = wmi_buf_alloc(wmi_handle, len); 15337 if (!buf) { 15338 wmi_err("Failed to allocate wmi buffer"); 15339 return QDF_STATUS_E_NOMEM; 15340 } 15341 15342 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 15343 WMITLV_SET_HDR(&cmd->tlv_header, 15344 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 15345 WMITLV_GET_STRUCT_TLVLEN 15346 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 15347 cmd->vdev_id = vdev_id; 15348 cmd->cmd_id = cmd_id; 15349 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 15350 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15351 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 15352 if (QDF_IS_STATUS_ERROR(ret)) { 15353 wmi_err("Failed to send set param command ret = %d", ret); 15354 wmi_buf_free(buf); 15355 } 15356 return ret; 15357 } 15358 #endif 15359 15360 #ifdef FEATURE_MEC_OFFLOAD 15361 static QDF_STATUS 15362 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 15363 struct set_mec_timer_params *param) 15364 { 15365 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 15366 wmi_buf_t buf; 15367 int32_t len = sizeof(*cmd); 15368 15369 buf = wmi_buf_alloc(wmi_handle, len); 15370 if (!buf) { 15371 wmi_err("wmi_buf_alloc failed"); 15372 return QDF_STATUS_E_FAILURE; 15373 } 15374 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 15375 wmi_buf_data(buf); 15376 WMITLV_SET_HDR(&cmd->tlv_header, 15377 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 15378 WMITLV_GET_STRUCT_TLVLEN( 15379 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 15380 cmd->pdev_id = param->pdev_id; 15381 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 15382 15383 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 15384 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15385 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 15386 wmi_err("Failed to set mec aging timer param"); 15387 wmi_buf_free(buf); 15388 return QDF_STATUS_E_FAILURE; 15389 } 15390 15391 return QDF_STATUS_SUCCESS; 15392 } 15393 #endif 15394 15395 #ifdef WIFI_POS_CONVERGED 15396 /** 15397 * extract_oem_response_param_tlv() - Extract oem response params 15398 * @wmi_handle: wmi handle 15399 * @resp_buf: response buffer 15400 * @oem_resp_param: pointer to hold oem response params 15401 * 15402 * Return: QDF_STATUS_SUCCESS on success or proper error code. 15403 */ 15404 static QDF_STATUS 15405 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 15406 struct wmi_oem_response_param *oem_resp_param) 15407 { 15408 uint64_t temp_addr; 15409 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 15410 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 15411 15412 if (!param_buf) { 15413 wmi_err("Invalid OEM response"); 15414 return QDF_STATUS_E_INVAL; 15415 } 15416 15417 if (param_buf->num_data) { 15418 oem_resp_param->num_data1 = param_buf->num_data; 15419 oem_resp_param->data_1 = param_buf->data; 15420 } 15421 15422 if (param_buf->num_data2) { 15423 oem_resp_param->num_data2 = param_buf->num_data2; 15424 oem_resp_param->data_2 = param_buf->data2; 15425 } 15426 15427 if (param_buf->indirect_data) { 15428 oem_resp_param->indirect_data.pdev_id = 15429 param_buf->indirect_data->pdev_id; 15430 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 15431 oem_resp_param->indirect_data.addr = 15432 param_buf->indirect_data->addr_lo + 15433 ((uint64_t)temp_addr << 32); 15434 oem_resp_param->indirect_data.len = 15435 param_buf->indirect_data->len; 15436 } 15437 15438 return QDF_STATUS_SUCCESS; 15439 } 15440 #endif /* WIFI_POS_CONVERGED */ 15441 15442 /** 15443 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 15444 * @wmi_handle: wmi handle 15445 * @event_buf: pointer to event buffer 15446 * @cmd_status: status of HW mode change command 15447 * 15448 * Return QDF_STATUS_SUCCESS on success or proper error code. 15449 */ 15450 static QDF_STATUS 15451 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15452 uint32_t *cmd_status) 15453 { 15454 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 15455 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 15456 15457 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 15458 if (!param_buf) { 15459 wmi_err("Invalid mode change event buffer"); 15460 return QDF_STATUS_E_INVAL; 15461 } 15462 15463 fixed_param = param_buf->fixed_param; 15464 if (!fixed_param) { 15465 wmi_err("Invalid fixed param"); 15466 return QDF_STATUS_E_INVAL; 15467 } 15468 15469 *cmd_status = fixed_param->status; 15470 return QDF_STATUS_SUCCESS; 15471 } 15472 15473 #ifdef FEATURE_ANI_LEVEL_REQUEST 15474 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 15475 uint32_t *freqs, 15476 uint8_t num_freqs) 15477 { 15478 wmi_buf_t buf; 15479 wmi_get_channel_ani_cmd_fixed_param *cmd; 15480 QDF_STATUS ret; 15481 uint32_t len; 15482 A_UINT32 *chan_list; 15483 uint8_t i, *buf_ptr; 15484 15485 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 15486 WMI_TLV_HDR_SIZE + 15487 num_freqs * sizeof(A_UINT32); 15488 15489 buf = wmi_buf_alloc(wmi_handle, len); 15490 if (!buf) 15491 return QDF_STATUS_E_FAILURE; 15492 15493 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15494 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 15495 WMITLV_SET_HDR(&cmd->tlv_header, 15496 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 15497 WMITLV_GET_STRUCT_TLVLEN( 15498 wmi_get_channel_ani_cmd_fixed_param)); 15499 15500 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 15501 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 15502 (num_freqs * sizeof(A_UINT32))); 15503 15504 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 15505 for (i = 0; i < num_freqs; i++) { 15506 chan_list[i] = freqs[i]; 15507 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 15508 } 15509 15510 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15511 WMI_GET_CHANNEL_ANI_CMDID); 15512 15513 if (QDF_IS_STATUS_ERROR(ret)) { 15514 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 15515 wmi_buf_free(buf); 15516 } 15517 15518 return ret; 15519 } 15520 15521 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 15522 struct wmi_host_ani_level_event **info, 15523 uint32_t *num_freqs) 15524 { 15525 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 15526 wmi_get_channel_ani_event_fixed_param *fixed_param; 15527 wmi_channel_ani_info_tlv_param *tlv_params; 15528 uint8_t *buf_ptr, i; 15529 15530 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 15531 if (!param_buf) { 15532 wmi_err("Invalid ani level event buffer"); 15533 return QDF_STATUS_E_INVAL; 15534 } 15535 15536 fixed_param = 15537 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 15538 if (!fixed_param) { 15539 wmi_err("Invalid fixed param"); 15540 return QDF_STATUS_E_INVAL; 15541 } 15542 15543 buf_ptr = (uint8_t *)fixed_param; 15544 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 15545 buf_ptr += WMI_TLV_HDR_SIZE; 15546 15547 *num_freqs = param_buf->num_ani_info; 15548 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 15549 wmi_err("Invalid number of freqs received"); 15550 return QDF_STATUS_E_INVAL; 15551 } 15552 15553 *info = qdf_mem_malloc(*num_freqs * 15554 sizeof(struct wmi_host_ani_level_event)); 15555 if (!(*info)) 15556 return QDF_STATUS_E_NOMEM; 15557 15558 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 15559 for (i = 0; i < param_buf->num_ani_info; i++) { 15560 (*info)[i].ani_level = tlv_params->ani_level; 15561 (*info)[i].chan_freq = tlv_params->chan_freq; 15562 tlv_params++; 15563 } 15564 15565 return QDF_STATUS_SUCCESS; 15566 } 15567 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 15568 15569 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 15570 /** 15571 * convert_wtc_scan_mode() - Function to convert TLV specific 15572 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 15573 * @scan_mode: scan freq scheme coming from firmware 15574 * 15575 * Return: ROAM_TRIGGER_SCAN_MODE 15576 */ 15577 static enum roam_scan_freq_scheme 15578 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 15579 { 15580 switch (scan_mode) { 15581 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 15582 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 15583 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 15584 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 15585 case ROAM_TRIGGER_SCAN_MODE_FULL: 15586 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 15587 default: 15588 return ROAM_SCAN_FREQ_SCHEME_NONE; 15589 } 15590 } 15591 15592 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 15593 { 15594 switch (fw_trig_reason) { 15595 case WMI_ROAM_TRIGGER_REASON_NONE: 15596 return ROAM_TRIGGER_REASON_NONE; 15597 case WMI_ROAM_TRIGGER_REASON_PER: 15598 return ROAM_TRIGGER_REASON_PER; 15599 case WMI_ROAM_TRIGGER_REASON_BMISS: 15600 return ROAM_TRIGGER_REASON_BMISS; 15601 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 15602 return ROAM_TRIGGER_REASON_LOW_RSSI; 15603 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 15604 return ROAM_TRIGGER_REASON_HIGH_RSSI; 15605 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 15606 return ROAM_TRIGGER_REASON_PERIODIC; 15607 case WMI_ROAM_TRIGGER_REASON_MAWC: 15608 return ROAM_TRIGGER_REASON_MAWC; 15609 case WMI_ROAM_TRIGGER_REASON_DENSE: 15610 return ROAM_TRIGGER_REASON_DENSE; 15611 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 15612 return ROAM_TRIGGER_REASON_BACKGROUND; 15613 case WMI_ROAM_TRIGGER_REASON_FORCED: 15614 return ROAM_TRIGGER_REASON_FORCED; 15615 case WMI_ROAM_TRIGGER_REASON_BTM: 15616 return ROAM_TRIGGER_REASON_BTM; 15617 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 15618 return ROAM_TRIGGER_REASON_UNIT_TEST; 15619 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 15620 return ROAM_TRIGGER_REASON_BSS_LOAD; 15621 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 15622 return ROAM_TRIGGER_REASON_DEAUTH; 15623 case WMI_ROAM_TRIGGER_REASON_IDLE: 15624 return ROAM_TRIGGER_REASON_IDLE; 15625 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 15626 return ROAM_TRIGGER_REASON_STA_KICKOUT; 15627 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 15628 return ROAM_TRIGGER_REASON_ESS_RSSI; 15629 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 15630 return ROAM_TRIGGER_REASON_WTC_BTM; 15631 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 15632 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 15633 case WMI_ROAM_TRIGGER_REASON_BTC: 15634 return ROAM_TRIGGER_REASON_BTC; 15635 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 15636 return ROAM_TRIGGER_REASON_MAX; 15637 default: 15638 return ROAM_TRIGGER_REASON_NONE; 15639 } 15640 } 15641 15642 /** 15643 * extract_roam_11kv_candidate_info - Extract btm candidate info 15644 * @wmi_handle: wmi_handle 15645 * @evt_buf: Event buffer 15646 * @dst_info: Destination buffer 15647 * 15648 * Return: QDF_STATUS 15649 */ 15650 static QDF_STATUS 15651 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 15652 struct wmi_btm_req_candidate_info *dst_info, 15653 uint8_t btm_idx, uint16_t num_cand) 15654 { 15655 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15656 wmi_roam_btm_request_candidate_info *src_data; 15657 uint8_t i; 15658 15659 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15660 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 15661 !param_buf->num_roam_btm_request_candidate_info || 15662 (btm_idx + 15663 num_cand) > param_buf->num_roam_btm_request_candidate_info) 15664 return QDF_STATUS_SUCCESS; 15665 15666 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 15667 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 15668 num_cand = WLAN_MAX_BTM_CANDIDATE; 15669 for (i = 0; i < num_cand; i++) { 15670 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 15671 dst_info->candidate_bssid.bytes); 15672 dst_info->preference = src_data->preference; 15673 src_data++; 15674 dst_info++; 15675 } 15676 15677 return QDF_STATUS_SUCCESS; 15678 } 15679 15680 static enum roam_trigger_sub_reason 15681 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 15682 { 15683 switch (subreason) { 15684 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 15685 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 15686 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 15687 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 15688 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 15689 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 15690 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 15691 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 15692 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 15693 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 15694 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 15695 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 15696 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 15697 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 15698 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 15699 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 15700 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 15701 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 15702 default: 15703 break; 15704 } 15705 15706 return 0; 15707 } 15708 15709 /** 15710 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 15711 * from the WMI_ROAM_STATS_EVENTID 15712 * @wmi_handle: wmi handle 15713 * @evt_buf: Pointer to the event buffer 15714 * @trig: Pointer to destination structure to fill data 15715 * @idx: TLV id 15716 */ 15717 static QDF_STATUS 15718 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15719 struct wmi_roam_trigger_info *trig, uint8_t idx, 15720 uint8_t btm_idx) 15721 { 15722 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15723 wmi_roam_trigger_reason *src_data = NULL; 15724 uint32_t trig_reason; 15725 15726 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15727 if (!param_buf || !param_buf->roam_trigger_reason) 15728 return QDF_STATUS_E_FAILURE; 15729 15730 src_data = ¶m_buf->roam_trigger_reason[idx]; 15731 15732 trig->present = true; 15733 trig_reason = src_data->trigger_reason; 15734 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 15735 trig->trigger_sub_reason = 15736 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 15737 trig->current_rssi = src_data->current_rssi; 15738 trig->timestamp = src_data->timestamp; 15739 15740 switch (trig_reason) { 15741 case WMI_ROAM_TRIGGER_REASON_PER: 15742 case WMI_ROAM_TRIGGER_REASON_BMISS: 15743 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 15744 case WMI_ROAM_TRIGGER_REASON_MAWC: 15745 case WMI_ROAM_TRIGGER_REASON_DENSE: 15746 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 15747 case WMI_ROAM_TRIGGER_REASON_IDLE: 15748 case WMI_ROAM_TRIGGER_REASON_FORCED: 15749 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 15750 case WMI_ROAM_TRIGGER_REASON_BTC: 15751 return QDF_STATUS_SUCCESS; 15752 15753 case WMI_ROAM_TRIGGER_REASON_BTM: 15754 trig->btm_trig_data.btm_request_mode = 15755 src_data->btm_request_mode; 15756 trig->btm_trig_data.disassoc_timer = 15757 src_data->disassoc_imminent_timer; 15758 trig->btm_trig_data.validity_interval = 15759 src_data->validity_internal; 15760 trig->btm_trig_data.candidate_list_count = 15761 src_data->candidate_list_count; 15762 trig->btm_trig_data.btm_resp_status = 15763 src_data->btm_response_status_code; 15764 trig->btm_trig_data.btm_bss_termination_timeout = 15765 src_data->btm_bss_termination_timeout; 15766 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 15767 src_data->btm_mbo_assoc_retry_timeout; 15768 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 15769 if ((btm_idx + trig->btm_trig_data.candidate_list_count) < 15770 param_buf->num_roam_btm_request_candidate_info) 15771 extract_roam_11kv_candidate_info( 15772 wmi_handle, evt_buf, 15773 trig->btm_trig_data.btm_cand, 15774 btm_idx, 15775 src_data->candidate_list_count); 15776 15777 return QDF_STATUS_SUCCESS; 15778 15779 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 15780 trig->cu_trig_data.cu_load = src_data->cu_load; 15781 return QDF_STATUS_SUCCESS; 15782 15783 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 15784 trig->deauth_trig_data.type = src_data->deauth_type; 15785 trig->deauth_trig_data.reason = src_data->deauth_reason; 15786 return QDF_STATUS_SUCCESS; 15787 15788 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 15789 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 15790 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 15791 return QDF_STATUS_SUCCESS; 15792 15793 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 15794 trig->wtc_btm_trig_data.roaming_mode = 15795 src_data->vendor_specific1[0]; 15796 trig->wtc_btm_trig_data.vsie_trigger_reason = 15797 src_data->vendor_specific1[1]; 15798 trig->wtc_btm_trig_data.sub_code = 15799 src_data->vendor_specific1[2]; 15800 trig->wtc_btm_trig_data.wtc_mode = 15801 src_data->vendor_specific1[3]; 15802 trig->wtc_btm_trig_data.wtc_scan_mode = 15803 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 15804 trig->wtc_btm_trig_data.wtc_rssi_th = 15805 src_data->vendor_specific1[5]; 15806 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 15807 src_data->vendor_specific1[6]; 15808 15809 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 15810 src_data->vendor_specific2[0]; 15811 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 15812 src_data->vendor_specific2[1]; 15813 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 15814 src_data->vendor_specific2[2]; 15815 trig->wtc_btm_trig_data.duration = 15816 src_data->vendor_specific2[3]; 15817 15818 return QDF_STATUS_SUCCESS; 15819 default: 15820 return QDF_STATUS_SUCCESS; 15821 } 15822 15823 return QDF_STATUS_SUCCESS; 15824 } 15825 15826 /** 15827 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 15828 * from the WMI_ROAM_STATS_EVENTID 15829 * @wmi_handle: wmi handle 15830 * @evt_buf: Pointer to the event buffer 15831 * @dst: Pointer to destination structure to fill data 15832 * @ap_idx: TLV index for this roam scan 15833 * @num_cand: number of candidates list in the roam scan 15834 */ 15835 static QDF_STATUS 15836 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15837 struct wmi_roam_candidate_info *dst, 15838 uint8_t ap_idx, uint16_t num_cand) 15839 { 15840 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15841 wmi_roam_ap_info *src = NULL; 15842 uint8_t i; 15843 15844 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15845 if (!param_buf) { 15846 wmi_err("Param buf is NULL"); 15847 return QDF_STATUS_E_FAILURE; 15848 } 15849 15850 if (ap_idx >= param_buf->num_roam_ap_info) { 15851 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 15852 ap_idx, param_buf->num_roam_ap_info); 15853 return QDF_STATUS_E_FAILURE; 15854 } 15855 15856 src = ¶m_buf->roam_ap_info[ap_idx]; 15857 15858 for (i = 0; i < num_cand; i++) { 15859 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 15860 dst->type = src->candidate_type; 15861 dst->freq = src->channel; 15862 dst->etp = src->etp; 15863 dst->rssi = src->rssi; 15864 dst->rssi_score = src->rssi_score; 15865 dst->cu_load = src->cu_load; 15866 dst->cu_score = src->cu_score; 15867 dst->total_score = src->total_score; 15868 dst->timestamp = src->timestamp; 15869 dst->bl_reason = src->bl_reason; 15870 dst->bl_source = src->bl_source; 15871 dst->bl_timestamp = src->bl_timestamp; 15872 dst->bl_original_timeout = src->bl_original_timeout; 15873 15874 src++; 15875 dst++; 15876 } 15877 15878 return QDF_STATUS_SUCCESS; 15879 } 15880 15881 /** 15882 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 15883 * from the WMI_ROAM_STATS_EVENTID 15884 * @wmi_handle: wmi handle 15885 * @evt_buf: Pointer to the event buffer 15886 * @dst: Pointer to destination structure to fill data 15887 * @idx: TLV id 15888 * @chan_idx: Index of the channel tlv for the current roam trigger 15889 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 15890 */ 15891 static QDF_STATUS 15892 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15893 struct wmi_roam_scan_data *dst, uint8_t idx, 15894 uint8_t chan_idx, uint8_t ap_idx) 15895 { 15896 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15897 wmi_roam_scan_info *src_data = NULL; 15898 wmi_roam_scan_channel_info *src_chan = NULL; 15899 QDF_STATUS status; 15900 uint8_t i; 15901 15902 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15903 if (!param_buf || !param_buf->roam_scan_info || 15904 idx >= param_buf->num_roam_scan_info) 15905 return QDF_STATUS_E_FAILURE; 15906 15907 src_data = ¶m_buf->roam_scan_info[idx]; 15908 15909 dst->present = true; 15910 dst->type = src_data->roam_scan_type; 15911 dst->num_chan = src_data->roam_scan_channel_count; 15912 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 15913 dst->frame_info_count = src_data->frame_info_count; 15914 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 15915 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 15916 15917 /* Read the channel data only for dst->type is 0 (partial scan) */ 15918 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 15919 chan_idx < param_buf->num_roam_scan_chan_info) { 15920 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 15921 dst->num_chan = MAX_ROAM_SCAN_CHAN; 15922 15923 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 15924 for (i = 0; i < dst->num_chan; i++) { 15925 dst->chan_freq[i] = src_chan->channel; 15926 src_chan++; 15927 } 15928 } 15929 15930 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 15931 return QDF_STATUS_SUCCESS; 15932 15933 dst->num_ap = src_data->roam_ap_count; 15934 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 15935 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 15936 15937 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 15938 ap_idx, dst->num_ap); 15939 if (QDF_IS_STATUS_ERROR(status)) { 15940 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 15941 return status; 15942 } 15943 15944 return QDF_STATUS_SUCCESS; 15945 } 15946 15947 /** 15948 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 15949 * from the WMI_ROAM_STATS_EVENTID 15950 * @wmi_handle: wmi handle 15951 * @evt_buf: Pointer to the event buffer 15952 * @dst: Pointer to destination structure to fill data 15953 * @idx: TLV id 15954 */ 15955 static QDF_STATUS 15956 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15957 struct wmi_roam_result *dst, uint8_t idx) 15958 { 15959 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15960 wmi_roam_result *src_data = NULL; 15961 15962 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15963 if (!param_buf || !param_buf->roam_result || 15964 idx >= param_buf->num_roam_result) 15965 return QDF_STATUS_E_FAILURE; 15966 15967 src_data = ¶m_buf->roam_result[idx]; 15968 15969 dst->present = true; 15970 dst->status = src_data->roam_status; 15971 dst->timestamp = src_data->timestamp; 15972 dst->fail_reason = src_data->roam_fail_reason; 15973 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 15974 15975 return QDF_STATUS_SUCCESS; 15976 } 15977 15978 /** 15979 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 15980 * from the WMI_ROAM_STATS_EVENTID 15981 * @wmi_handle: wmi handle 15982 * @evt_buf: Pointer to the event buffer 15983 * @dst: Pointer to destination structure to fill data 15984 * @idx: TLV id 15985 * @rpt_idx: Neighbor report Channel index 15986 */ 15987 static QDF_STATUS 15988 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15989 struct wmi_neighbor_report_data *dst, 15990 uint8_t idx, uint8_t rpt_idx) 15991 { 15992 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15993 wmi_roam_neighbor_report_info *src_data = NULL; 15994 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 15995 uint8_t i; 15996 15997 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15998 if (!param_buf || !param_buf->roam_neighbor_report_info || 15999 !param_buf->num_roam_neighbor_report_info || 16000 idx >= param_buf->num_roam_neighbor_report_info) { 16001 wmi_debug("Invalid 1kv param buf"); 16002 return QDF_STATUS_E_FAILURE; 16003 } 16004 16005 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 16006 16007 dst->present = true; 16008 dst->req_type = src_data->request_type; 16009 dst->num_freq = src_data->neighbor_report_channel_count; 16010 dst->req_time = src_data->neighbor_report_request_timestamp; 16011 dst->resp_time = src_data->neighbor_report_response_timestamp; 16012 dst->btm_query_token = src_data->btm_query_token; 16013 dst->btm_query_reason = src_data->btm_query_reason_code; 16014 16015 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 16016 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 16017 return QDF_STATUS_SUCCESS; 16018 16019 if (!param_buf->roam_neighbor_report_chan_info) { 16020 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 16021 dst->num_freq); 16022 dst->num_freq = 0; 16023 /* return success as its optional tlv and we can print neighbor 16024 * report received info 16025 */ 16026 return QDF_STATUS_SUCCESS; 16027 } 16028 16029 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 16030 16031 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 16032 dst->num_freq = MAX_ROAM_SCAN_CHAN; 16033 16034 for (i = 0; i < dst->num_freq; i++) { 16035 dst->freq[i] = src_freq->channel; 16036 src_freq++; 16037 } 16038 16039 return QDF_STATUS_SUCCESS; 16040 } 16041 16042 /** 16043 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 16044 * @wmi_handle : handle to WMI. 16045 * @roam_param : pointer to hold roam set parameter 16046 * 16047 * Return: 0 on success and -ve on failure. 16048 */ 16049 static QDF_STATUS 16050 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 16051 struct vdev_set_params *roam_param) 16052 { 16053 QDF_STATUS ret; 16054 wmi_roam_set_param_cmd_fixed_param *cmd; 16055 wmi_buf_t buf; 16056 uint16_t len = sizeof(*cmd); 16057 16058 buf = wmi_buf_alloc(wmi_handle, len); 16059 if (!buf) 16060 return QDF_STATUS_E_NOMEM; 16061 16062 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 16063 WMITLV_SET_HDR(&cmd->tlv_header, 16064 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 16065 WMITLV_GET_STRUCT_TLVLEN 16066 (wmi_roam_set_param_cmd_fixed_param)); 16067 cmd->vdev_id = roam_param->vdev_id; 16068 cmd->param_id = roam_param->param_id; 16069 cmd->param_value = roam_param->param_value; 16070 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 16071 cmd->vdev_id, cmd->param_id, cmd->param_value); 16072 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 16073 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16074 WMI_ROAM_SET_PARAM_CMDID); 16075 if (QDF_IS_STATUS_ERROR(ret)) { 16076 wmi_err("Failed to send roam set param command, ret = %d", ret); 16077 wmi_buf_free(buf); 16078 } 16079 16080 return ret; 16081 } 16082 #else 16083 static inline QDF_STATUS 16084 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16085 struct wmi_roam_trigger_info *trig, uint8_t idx, 16086 uint8_t btm_idx) 16087 { 16088 return QDF_STATUS_E_NOSUPPORT; 16089 } 16090 16091 static inline QDF_STATUS 16092 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16093 struct wmi_roam_result *dst, uint8_t idx) 16094 { 16095 return QDF_STATUS_E_NOSUPPORT; 16096 } 16097 16098 static QDF_STATUS 16099 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16100 struct wmi_neighbor_report_data *dst, 16101 uint8_t idx, uint8_t rpt_idx) 16102 { 16103 return QDF_STATUS_E_NOSUPPORT; 16104 } 16105 16106 static QDF_STATUS 16107 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16108 struct wmi_roam_scan_data *dst, uint8_t idx, 16109 uint8_t chan_idx, uint8_t ap_idx) 16110 { 16111 return QDF_STATUS_E_NOSUPPORT; 16112 } 16113 #endif 16114 16115 #ifdef WLAN_FEATURE_PKT_CAPTURE 16116 static QDF_STATUS 16117 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 16118 struct mgmt_offload_event_params *params) 16119 { 16120 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 16121 wmi_mgmt_hdr *hdr; 16122 16123 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 16124 if (!param_tlvs) 16125 return QDF_STATUS_E_INVAL; 16126 16127 hdr = param_tlvs->fixed_param; 16128 if (!hdr) 16129 return QDF_STATUS_E_INVAL; 16130 16131 if (hdr->buf_len > param_tlvs->num_bufp) 16132 return QDF_STATUS_E_INVAL; 16133 16134 params->tsf_l32 = hdr->tsf_l32; 16135 params->chan_freq = hdr->chan_freq; 16136 params->rate_kbps = hdr->rate_kbps; 16137 params->rssi = hdr->rssi; 16138 params->buf_len = hdr->buf_len; 16139 params->tx_status = hdr->tx_status; 16140 params->buf = param_tlvs->bufp; 16141 params->tx_retry_cnt = hdr->tx_retry_cnt; 16142 return QDF_STATUS_SUCCESS; 16143 } 16144 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 16145 16146 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 16147 static QDF_STATUS 16148 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 16149 struct smu_event_params *params) 16150 { 16151 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 16152 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 16153 16154 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 16155 if (!param_buf) { 16156 wmi_err("Invalid smart monitor event"); 16157 return QDF_STATUS_E_INVAL; 16158 } 16159 16160 smu_event = param_buf->fixed_param; 16161 if (!smu_event) { 16162 wmi_err("smart monitor event fixed param is NULL"); 16163 return QDF_STATUS_E_INVAL; 16164 } 16165 16166 params->vdev_id = smu_event->vdev_id; 16167 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 16168 return QDF_STATUS_E_INVAL; 16169 16170 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 16171 16172 return QDF_STATUS_SUCCESS; 16173 } 16174 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 16175 16176 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 16177 /** 16178 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 16179 * 16180 * @wmi: wmi handle 16181 * @vdev_id: vdev id 16182 * @burst_mode: Indicates whether relation derived using FTM is needed for 16183 * each FTM frame or only aggregated result is required. 16184 * 16185 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 16186 * 16187 * Return: QDF_STATUS 16188 */ 16189 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 16190 uint32_t vdev_id, 16191 bool burst_mode) 16192 { 16193 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 16194 wmi_buf_t buf; 16195 int32_t len = sizeof(*cmd); 16196 16197 buf = wmi_buf_alloc(wmi, len); 16198 if (!buf) { 16199 wmi_err("wmi_buf_alloc failed"); 16200 return QDF_STATUS_E_NOMEM; 16201 } 16202 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 16203 WMITLV_SET_HDR(&cmd->tlv_header, 16204 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 16205 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 16206 cmd->vdev_id = vdev_id; 16207 cmd->agg_relation = burst_mode ? false : true; 16208 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 16209 wmi_err("Failed to send audio sync trigger cmd"); 16210 wmi_buf_free(buf); 16211 return QDF_STATUS_E_FAILURE; 16212 } 16213 16214 return QDF_STATUS_SUCCESS; 16215 } 16216 16217 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 16218 uint32_t vdev_id, 16219 uint64_t lpass_ts) 16220 { 16221 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 16222 wmi_buf_t buf; 16223 int32_t len = sizeof(*cmd); 16224 16225 buf = wmi_buf_alloc(wmi, len); 16226 if (!buf) { 16227 wmi_err("wmi_buf_alloc failed"); 16228 return QDF_STATUS_E_NOMEM; 16229 } 16230 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 16231 WMITLV_SET_HDR(&cmd->tlv_header, 16232 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 16233 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 16234 cmd->vdev_id = vdev_id; 16235 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 16236 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 16237 16238 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 16239 wmi_err("Failed to send audio qtime command"); 16240 wmi_buf_free(buf); 16241 return QDF_STATUS_E_FAILURE; 16242 } 16243 16244 return QDF_STATUS_SUCCESS; 16245 } 16246 16247 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 16248 wmi_unified_t wmi, void *buf, 16249 struct ftm_time_sync_start_stop_params *param) 16250 { 16251 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 16252 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 16253 16254 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 16255 if (!param_buf) { 16256 wmi_err("Invalid audio sync start stop event buffer"); 16257 return QDF_STATUS_E_FAILURE; 16258 } 16259 16260 resp_event = param_buf->fixed_param; 16261 if (!resp_event) { 16262 wmi_err("Invalid audio sync start stop fixed param buffer"); 16263 return QDF_STATUS_E_FAILURE; 16264 } 16265 16266 param->vdev_id = resp_event->vdev_id; 16267 param->timer_interval = resp_event->periodicity; 16268 param->num_reads = resp_event->reads_needed; 16269 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 16270 resp_event->qtimer_l32; 16271 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 16272 resp_event->mac_timer_l32; 16273 16274 wmi_debug("FTM time sync time_interval %d, num_reads %d", 16275 param->timer_interval, param->num_reads); 16276 16277 return QDF_STATUS_SUCCESS; 16278 } 16279 16280 static QDF_STATUS 16281 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 16282 struct ftm_time_sync_offset *param) 16283 { 16284 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 16285 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 16286 wmi_audio_sync_q_master_slave_times *q_pair; 16287 int iter; 16288 16289 param_buf = 16290 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 16291 if (!param_buf) { 16292 wmi_err("Invalid timesync ftm offset event buffer"); 16293 return QDF_STATUS_E_FAILURE; 16294 } 16295 16296 resp_event = param_buf->fixed_param; 16297 if (!resp_event) { 16298 wmi_err("Invalid timesync ftm offset fixed param buffer"); 16299 return QDF_STATUS_E_FAILURE; 16300 } 16301 16302 param->vdev_id = resp_event->vdev_id; 16303 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 16304 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 16305 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 16306 16307 q_pair = param_buf->audio_sync_q_master_slave_times; 16308 if (!q_pair) { 16309 wmi_err("Invalid q_master_slave_times buffer"); 16310 return QDF_STATUS_E_FAILURE; 16311 } 16312 16313 for (iter = 0; iter < param->num_qtime; iter++) { 16314 param->pairs[iter].qtime_master = ( 16315 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 16316 q_pair[iter].qmaster_l32; 16317 param->pairs[iter].qtime_slave = ( 16318 (uint64_t)q_pair[iter].qslave_u32 << 32) | 16319 q_pair[iter].qslave_l32; 16320 } 16321 return QDF_STATUS_SUCCESS; 16322 } 16323 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 16324 16325 /** 16326 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 16327 * @wmi: wmi handle 16328 * @vdev_id: vdev id 16329 * 16330 * TSF_TSTAMP_READ_VALUE is the only operation supported 16331 * Return: QDF_STATUS_SUCCESS for success or erro code 16332 */ 16333 static QDF_STATUS 16334 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 16335 { 16336 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 16337 wmi_buf_t buf; 16338 int32_t len = sizeof(*cmd); 16339 16340 buf = wmi_buf_alloc(wmi, len); 16341 if (!buf) 16342 return QDF_STATUS_E_NOMEM; 16343 16344 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 16345 WMITLV_SET_HDR(&cmd->tlv_header, 16346 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 16347 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 16348 cmd->vdev_id = vdev_id; 16349 cmd->tsf_action = TSF_TSTAMP_READ_VALUE; 16350 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 16351 if (wmi_unified_cmd_send(wmi, buf, len, 16352 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 16353 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 16354 __func__); 16355 wmi_buf_free(buf); 16356 return QDF_STATUS_E_FAILURE; 16357 } 16358 16359 return QDF_STATUS_SUCCESS; 16360 } 16361 16362 /** 16363 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 16364 * @wmi_handle: wmi handle 16365 * @param evt_buf: pointer to event buffer 16366 * @wmi_host_tsf_event param: Pointer to struct to hold event info 16367 * 16368 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 16369 */ 16370 static QDF_STATUS 16371 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16372 struct wmi_host_tsf_event *param) 16373 { 16374 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 16375 wmi_vdev_tsf_report_event_fixed_param *evt; 16376 16377 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 16378 if (!param_buf) { 16379 wmi_err("Invalid tsf report event buffer"); 16380 return QDF_STATUS_E_INVAL; 16381 } 16382 16383 evt = param_buf->fixed_param; 16384 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 16385 param->vdev_id = evt->vdev_id; 16386 16387 return QDF_STATUS_SUCCESS; 16388 } 16389 16390 /** 16391 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 16392 * status tlv 16393 * @wmi_handle: wmi handle 16394 * @param evt_buf: pointer to event buffer 16395 * @param param: Pointer to hold csa switch count status event param 16396 * 16397 * Return: QDF_STATUS_SUCCESS for success or error code 16398 */ 16399 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 16400 wmi_unified_t wmi_handle, 16401 void *evt_buf, 16402 struct pdev_csa_switch_count_status *param) 16403 { 16404 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 16405 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 16406 16407 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 16408 evt_buf; 16409 if (!param_buf) { 16410 wmi_err("Invalid CSA status event"); 16411 return QDF_STATUS_E_INVAL; 16412 } 16413 16414 csa_status = param_buf->fixed_param; 16415 16416 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16417 wmi_handle, 16418 csa_status->pdev_id); 16419 param->current_switch_count = csa_status->current_switch_count; 16420 param->num_vdevs = csa_status->num_vdevs; 16421 param->vdev_ids = param_buf->vdev_ids; 16422 16423 return QDF_STATUS_SUCCESS; 16424 } 16425 16426 #ifdef CONFIG_AFC_SUPPORT 16427 /** 16428 * send_afc_cmd_tlv() - Sends the AFC indication to FW 16429 * @wmi_handle: wmi handle 16430 * @pdev_id: Pdev id 16431 * @param: Pointer to hold AFC indication. 16432 * 16433 * Return: QDF_STATUS_SUCCESS for success or error code 16434 */ 16435 static 16436 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 16437 uint8_t pdev_id, 16438 struct reg_afc_resp_rx_ind_info *param) 16439 { 16440 wmi_buf_t buf; 16441 wmi_afc_cmd_fixed_param *cmd; 16442 uint32_t len; 16443 uint8_t *buf_ptr; 16444 QDF_STATUS ret; 16445 16446 len = sizeof(wmi_afc_cmd_fixed_param); 16447 buf = wmi_buf_alloc(wmi_handle, len); 16448 if (!buf) 16449 return QDF_STATUS_E_NOMEM; 16450 16451 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16452 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 16453 16454 WMITLV_SET_HDR(&cmd->tlv_header, 16455 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 16456 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 16457 16458 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16459 wmi_handle, 16460 pdev_id); 16461 cmd->cmd_type = param->cmd_type; 16462 cmd->serv_resp_format = param->serv_resp_format; 16463 16464 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 16465 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 16466 if (QDF_IS_STATUS_ERROR(ret)) { 16467 wmi_err("Failed to send WMI_AFC_CMDID"); 16468 wmi_buf_free(buf); 16469 return QDF_STATUS_E_FAILURE; 16470 } 16471 16472 return QDF_STATUS_SUCCESS; 16473 } 16474 #endif 16475 16476 /** 16477 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 16478 * @wmi_handle: wmi handle 16479 * @param: Pointer to hold TX power info 16480 * 16481 * Return: QDF_STATUS_SUCCESS for success or error code 16482 */ 16483 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 16484 uint8_t vdev_id, 16485 struct reg_tpc_power_info *param) 16486 { 16487 wmi_buf_t buf; 16488 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 16489 wmi_vdev_ch_power_info *ch_power_info; 16490 uint8_t *buf_ptr; 16491 uint16_t idx; 16492 uint32_t len; 16493 QDF_STATUS ret; 16494 16495 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 16496 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 16497 16498 buf = wmi_buf_alloc(wmi_handle, len); 16499 if (!buf) 16500 return QDF_STATUS_E_NOMEM; 16501 16502 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16503 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 16504 16505 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 16506 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 16507 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 16508 16509 tpc_power_info_param->vdev_id = vdev_id; 16510 tpc_power_info_param->psd_power = param->is_psd_power; 16511 tpc_power_info_param->eirp_power = param->eirp_power; 16512 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 16513 16514 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 16515 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 16516 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 16517 16518 buf_ptr += WMI_TLV_HDR_SIZE; 16519 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 16520 16521 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 16522 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 16523 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 16524 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 16525 ch_power_info[idx].chan_cfreq = 16526 param->chan_power_info[idx].chan_cfreq; 16527 ch_power_info[idx].tx_power = 16528 param->chan_power_info[idx].tx_power; 16529 buf_ptr += sizeof(wmi_vdev_ch_power_info); 16530 } 16531 16532 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 16533 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16534 WMI_VDEV_SET_TPC_POWER_CMDID); 16535 if (QDF_IS_STATUS_ERROR(ret)) 16536 wmi_buf_free(buf); 16537 16538 16539 return ret; 16540 } 16541 16542 /** 16543 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 16544 * @wmi_handle: wmi handle 16545 * @evt_buf: event buffer 16546 * @param: dpd status info 16547 * 16548 * Return: QDF_STATUS_SUCCESS for success or error code 16549 */ 16550 static QDF_STATUS 16551 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 16552 void *evt_buf, 16553 struct wmi_host_pdev_get_dpd_status_event *param) 16554 { 16555 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 16556 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 16557 16558 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 16559 if (!param_buf) { 16560 wmi_err("Invalid get dpd_status event"); 16561 return QDF_STATUS_E_INVAL; 16562 } 16563 16564 dpd_status = param_buf->fixed_param; 16565 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 16566 (wmi_handle, dpd_status->pdev_id); 16567 param->dpd_status = dpd_status->dpd_status; 16568 16569 return QDF_STATUS_SUCCESS; 16570 } 16571 16572 static int 16573 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 16574 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 16575 { 16576 if (status->halphy_cal_valid_bmap && valid_bit) 16577 return (status->halphy_cal_status && valid_bit); 16578 16579 return 0; 16580 } 16581 16582 static QDF_STATUS 16583 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 16584 void *evt_buf, 16585 struct wmi_host_pdev_get_halphy_cal_status_event *param) 16586 { 16587 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 16588 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 16589 16590 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 16591 if (!param_buf) { 16592 wmi_err("Invalid get halphy cal status event"); 16593 return QDF_STATUS_E_INVAL; 16594 } 16595 16596 halphy_cal_status = param_buf->fixed_param; 16597 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 16598 (wmi_handle, halphy_cal_status->pdev_id); 16599 param->halphy_cal_adc_status = 16600 convert_halphy_status(halphy_cal_status, 16601 WMI_HALPHY_CAL_ADC_BMAP); 16602 param->halphy_cal_bwfilter_status = 16603 convert_halphy_status(halphy_cal_status, 16604 WMI_HALPHY_CAL_BWFILTER_BMAP); 16605 param->halphy_cal_pdet_and_pal_status = 16606 convert_halphy_status(halphy_cal_status, 16607 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 16608 param->halphy_cal_rxdco_status = 16609 convert_halphy_status(halphy_cal_status, 16610 WMI_HALPHY_CAL_RXDCO_BMAP); 16611 param->halphy_cal_comb_txiq_rxiq_status = 16612 convert_halphy_status(halphy_cal_status, 16613 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 16614 param->halphy_cal_ibf_status = 16615 convert_halphy_status(halphy_cal_status, 16616 WMI_HALPHY_CAL_IBF_BMAP); 16617 param->halphy_cal_pa_droop_status = 16618 convert_halphy_status(halphy_cal_status, 16619 WMI_HALPHY_CAL_PA_DROOP_BMAP); 16620 param->halphy_cal_dac_status = 16621 convert_halphy_status(halphy_cal_status, 16622 WMI_HALPHY_CAL_DAC_BMAP); 16623 param->halphy_cal_ani_status = 16624 convert_halphy_status(halphy_cal_status, 16625 WMI_HALPHY_CAL_ANI_BMAP); 16626 param->halphy_cal_noise_floor_status = 16627 convert_halphy_status(halphy_cal_status, 16628 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 16629 16630 return QDF_STATUS_SUCCESS; 16631 } 16632 16633 /** 16634 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 16635 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 16636 * 16637 * Return: host_set_halphy_cal_status 16638 */ 16639 static enum wmi_host_set_halphy_cal_status 16640 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 16641 { 16642 if (fw_status == 0) 16643 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 16644 else if (fw_status == 1) 16645 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 16646 16647 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 16648 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 16649 } 16650 16651 /** 16652 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 16653 * @wmi_handle: wmi handle 16654 * @evt_buf: event buffer 16655 * @param: set halphy cal status info 16656 * 16657 * Return: QDF_STATUS_SUCCESS for success or error code 16658 */ 16659 static QDF_STATUS 16660 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 16661 void *evt_buf, 16662 struct wmi_host_pdev_set_halphy_cal_event *param) 16663 { 16664 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 16665 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 16666 16667 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 16668 if (!param_buf) { 16669 wmi_err("Invalid set halphy_status event"); 16670 return QDF_STATUS_E_INVAL; 16671 } 16672 16673 set_halphy_status = param_buf->fixed_param; 16674 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 16675 (wmi_handle, set_halphy_status->pdev_id); 16676 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 16677 16678 return QDF_STATUS_SUCCESS; 16679 } 16680 16681 /** 16682 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 16683 * @wmi_handle: wmi handle 16684 * @evt_buf: pointer to event buffer 16685 * @len: length of the event buffer 16686 * @param: Pointer to hold install key complete event param 16687 * 16688 * Return: QDF_STATUS_SUCCESS for success or error code 16689 */ 16690 static QDF_STATUS 16691 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 16692 void *evt_buf, uint32_t len, 16693 struct wmi_install_key_comp_event *param) 16694 { 16695 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 16696 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 16697 16698 if (len < sizeof(*param_buf)) { 16699 wmi_err("invalid event buf len %d", len); 16700 return QDF_STATUS_E_INVAL; 16701 } 16702 16703 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16704 if (!param_buf) { 16705 wmi_err("received null buf from target"); 16706 return QDF_STATUS_E_INVAL; 16707 } 16708 16709 key_fp = param_buf->fixed_param; 16710 if (!key_fp) { 16711 wmi_err("received null event data from target"); 16712 return QDF_STATUS_E_INVAL; 16713 } 16714 16715 param->vdev_id = key_fp->vdev_id; 16716 param->key_ix = key_fp->key_ix; 16717 param->key_flags = key_fp->key_flags; 16718 param->status = key_fp->status; 16719 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 16720 param->peer_macaddr); 16721 16722 return QDF_STATUS_SUCCESS; 16723 } 16724 16725 static QDF_STATUS 16726 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 16727 struct wmi_host_send_set_halphy_cal_info *param) 16728 { 16729 wmi_buf_t buf; 16730 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 16731 QDF_STATUS ret; 16732 uint32_t len; 16733 16734 len = sizeof(*cmd); 16735 16736 buf = wmi_buf_alloc(wmi_handle, len); 16737 if (!buf) 16738 return QDF_STATUS_E_FAILURE; 16739 16740 cmd = (void *)wmi_buf_data(buf); 16741 16742 WMITLV_SET_HDR(&cmd->tlv_header, 16743 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 16744 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 16745 16746 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 16747 param->pdev_id); 16748 cmd->online_halphy_cals_bmap = param->value; 16749 cmd->home_scan_channel = param->chan_sel; 16750 16751 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16752 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 16753 if (QDF_IS_STATUS_ERROR(ret)) { 16754 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 16755 wmi_buf_free(buf); 16756 } 16757 16758 return ret; 16759 } 16760 16761 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 16762 /** 16763 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 16764 * @wmi: wmi handle 16765 * @params: set MAC address command params 16766 * 16767 * Return: QDF_STATUS_SUCCESS for success or error code 16768 */ 16769 static QDF_STATUS 16770 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 16771 struct set_mac_addr_params *params) 16772 { 16773 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 16774 wmi_buf_t buf; 16775 int32_t len = sizeof(*cmd); 16776 16777 buf = wmi_buf_alloc(wmi, len); 16778 if (!buf) 16779 return QDF_STATUS_E_NOMEM; 16780 16781 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 16782 WMITLV_SET_HDR( 16783 &cmd->tlv_header, 16784 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 16785 WMITLV_GET_STRUCT_TLVLEN 16786 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 16787 cmd->vdev_id = params->vdev_id; 16788 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 16789 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 16790 16791 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 16792 QDF_MAC_ADDR_FMT, cmd->vdev_id, 16793 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 16794 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 16795 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 16796 if (wmi_unified_cmd_send(wmi, buf, len, 16797 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 16798 wmi_buf_free(buf); 16799 return QDF_STATUS_E_FAILURE; 16800 } 16801 16802 return QDF_STATUS_SUCCESS; 16803 } 16804 #endif 16805 16806 struct wmi_ops tlv_ops = { 16807 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 16808 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 16809 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 16810 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 16811 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 16812 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 16813 .send_peer_param_cmd = send_peer_param_cmd_tlv, 16814 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 16815 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 16816 .send_peer_create_cmd = send_peer_create_cmd_tlv, 16817 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 16818 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 16819 .send_peer_rx_reorder_queue_setup_cmd = 16820 send_peer_rx_reorder_queue_setup_cmd_tlv, 16821 .send_peer_rx_reorder_queue_remove_cmd = 16822 send_peer_rx_reorder_queue_remove_cmd_tlv, 16823 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 16824 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 16825 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 16826 .send_suspend_cmd = send_suspend_cmd_tlv, 16827 .send_resume_cmd = send_resume_cmd_tlv, 16828 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 16829 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 16830 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 16831 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 16832 .send_dbglog_cmd = send_dbglog_cmd_tlv, 16833 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 16834 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 16835 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 16836 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 16837 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 16838 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 16839 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 16840 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 16841 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 16842 .send_scan_start_cmd = send_scan_start_cmd_tlv, 16843 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 16844 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 16845 .send_mgmt_cmd = send_mgmt_cmd_tlv, 16846 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 16847 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 16848 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 16849 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 16850 .send_set_sta_uapsd_auto_trig_cmd = 16851 send_set_sta_uapsd_auto_trig_cmd_tlv, 16852 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 16853 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 16854 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 16855 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 16856 .send_lro_config_cmd = send_lro_config_cmd_tlv, 16857 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 16858 .send_probe_rsp_tmpl_send_cmd = 16859 send_probe_rsp_tmpl_send_cmd_tlv, 16860 .send_p2p_go_set_beacon_ie_cmd = 16861 send_p2p_go_set_beacon_ie_cmd_tlv, 16862 .send_setup_install_key_cmd = 16863 send_setup_install_key_cmd_tlv, 16864 .send_scan_probe_setoui_cmd = 16865 send_scan_probe_setoui_cmd_tlv, 16866 #ifdef IPA_OFFLOAD 16867 .send_ipa_offload_control_cmd = 16868 send_ipa_offload_control_cmd_tlv, 16869 #endif 16870 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 16871 .send_pno_start_cmd = send_pno_start_cmd_tlv, 16872 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 16873 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 16874 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 16875 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 16876 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 16877 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 16878 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 16879 .send_unified_ll_stats_get_sta_cmd = 16880 send_unified_ll_stats_get_sta_cmd_tlv, 16881 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 16882 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 16883 .send_congestion_cmd = send_congestion_cmd_tlv, 16884 .send_snr_request_cmd = send_snr_request_cmd_tlv, 16885 .send_snr_cmd = send_snr_cmd_tlv, 16886 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 16887 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 16888 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 16889 #endif 16890 #ifdef WLAN_SUPPORT_GREEN_AP 16891 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 16892 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 16893 .extract_green_ap_egap_status_info = 16894 extract_green_ap_egap_status_info_tlv, 16895 #endif 16896 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 16897 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 16898 #ifdef FEATURE_OEM_DATA 16899 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 16900 #endif 16901 #ifdef WLAN_FEATURE_CIF_CFR 16902 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 16903 #endif 16904 .send_dfs_phyerr_filter_offload_en_cmd = 16905 send_dfs_phyerr_filter_offload_en_cmd_tlv, 16906 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 16907 .send_process_dhcpserver_offload_cmd = 16908 send_process_dhcpserver_offload_cmd_tlv, 16909 .send_pdev_set_regdomain_cmd = 16910 send_pdev_set_regdomain_cmd_tlv, 16911 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 16912 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 16913 .save_fw_version_cmd = save_fw_version_cmd_tlv, 16914 .check_and_update_fw_version = 16915 check_and_update_fw_version_cmd_tlv, 16916 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 16917 .send_enable_specific_fw_logs_cmd = 16918 send_enable_specific_fw_logs_cmd_tlv, 16919 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 16920 .send_unit_test_cmd = send_unit_test_cmd_tlv, 16921 #ifdef FEATURE_WLAN_APF 16922 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 16923 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 16924 .send_apf_write_work_memory_cmd = 16925 wmi_send_apf_write_work_memory_cmd_tlv, 16926 .send_apf_read_work_memory_cmd = 16927 wmi_send_apf_read_work_memory_cmd_tlv, 16928 .extract_apf_read_memory_resp_event = 16929 wmi_extract_apf_read_memory_resp_event_tlv, 16930 #endif /* FEATURE_WLAN_APF */ 16931 .init_cmd_send = init_cmd_send_tlv, 16932 .send_vdev_set_custom_aggr_size_cmd = 16933 send_vdev_set_custom_aggr_size_cmd_tlv, 16934 .send_vdev_set_qdepth_thresh_cmd = 16935 send_vdev_set_qdepth_thresh_cmd_tlv, 16936 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 16937 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 16938 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 16939 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 16940 .send_periodic_chan_stats_config_cmd = 16941 send_periodic_chan_stats_config_cmd_tlv, 16942 #ifdef WLAN_IOT_SIM_SUPPORT 16943 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 16944 #endif 16945 .send_vdev_spectral_configure_cmd = 16946 send_vdev_spectral_configure_cmd_tlv, 16947 .send_vdev_spectral_enable_cmd = 16948 send_vdev_spectral_enable_cmd_tlv, 16949 #ifdef WLAN_CONV_SPECTRAL_ENABLE 16950 .extract_pdev_sscan_fw_cmd_fixed_param = 16951 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 16952 .extract_pdev_sscan_fft_bin_index = 16953 extract_pdev_sscan_fft_bin_index_tlv, 16954 #ifdef SPECTRAL_BERYLLIUM 16955 .extract_pdev_spectral_session_chan_info = 16956 extract_pdev_spectral_session_chan_info_tlv, 16957 .extract_pdev_spectral_session_detector_info = 16958 extract_pdev_spectral_session_detector_info_tlv, 16959 #endif /* SPECTRAL_BERYLLIUM */ 16960 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 16961 .send_thermal_mitigation_param_cmd = 16962 send_thermal_mitigation_param_cmd_tlv, 16963 .send_process_update_edca_param_cmd = 16964 send_process_update_edca_param_cmd_tlv, 16965 .send_bss_color_change_enable_cmd = 16966 send_bss_color_change_enable_cmd_tlv, 16967 .send_coex_config_cmd = send_coex_config_cmd_tlv, 16968 .send_set_country_cmd = send_set_country_cmd_tlv, 16969 .send_addba_send_cmd = send_addba_send_cmd_tlv, 16970 .send_delba_send_cmd = send_delba_send_cmd_tlv, 16971 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 16972 .get_target_cap_from_service_ready = extract_service_ready_tlv, 16973 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 16974 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 16975 .extract_host_mem_req = extract_host_mem_req_tlv, 16976 .save_service_bitmap = save_service_bitmap_tlv, 16977 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 16978 .is_service_enabled = is_service_enabled_tlv, 16979 .save_fw_version = save_fw_version_in_service_ready_tlv, 16980 .ready_extract_init_status = ready_extract_init_status_tlv, 16981 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 16982 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 16983 .extract_ready_event_params = extract_ready_event_params_tlv, 16984 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 16985 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 16986 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 16987 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 16988 #ifdef FEATURE_WLAN_SCAN_PNO 16989 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 16990 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 16991 #endif 16992 .extract_unit_test = extract_unit_test_tlv, 16993 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 16994 .extract_bcn_stats = extract_bcn_stats_tlv, 16995 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 16996 .extract_chan_stats = extract_chan_stats_tlv, 16997 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 16998 .extract_profile_ctx = extract_profile_ctx_tlv, 16999 .extract_profile_data = extract_profile_data_tlv, 17000 .send_fw_test_cmd = send_fw_test_cmd_tlv, 17001 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 17002 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 17003 .extract_service_ready_ext = extract_service_ready_ext_tlv, 17004 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 17005 .extract_dbs_or_sbs_service_ready_ext2 = 17006 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 17007 .extract_hw_mode_cap_service_ready_ext = 17008 extract_hw_mode_cap_service_ready_ext_tlv, 17009 .extract_mac_phy_cap_service_ready_ext = 17010 extract_mac_phy_cap_service_ready_ext_tlv, 17011 .extract_mac_phy_cap_service_ready_ext2 = 17012 extract_mac_phy_cap_service_ready_ext2_tlv, 17013 .extract_reg_cap_service_ready_ext = 17014 extract_reg_cap_service_ready_ext_tlv, 17015 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 17016 .extract_dbr_ring_cap_service_ready_ext = 17017 extract_dbr_ring_cap_service_ready_ext_tlv, 17018 .extract_dbr_ring_cap_service_ready_ext2 = 17019 extract_dbr_ring_cap_service_ready_ext2_tlv, 17020 .extract_scan_radio_cap_service_ready_ext2 = 17021 extract_scan_radio_cap_service_ready_ext2_tlv, 17022 .extract_sar_cap_service_ready_ext = 17023 extract_sar_cap_service_ready_ext_tlv, 17024 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 17025 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 17026 .extract_fips_event_data = extract_fips_event_data_tlv, 17027 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 17028 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 17029 #endif 17030 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17031 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 17032 #endif 17033 #ifdef WLAN_FEATURE_DISA 17034 .extract_encrypt_decrypt_resp_event = 17035 extract_encrypt_decrypt_resp_event_tlv, 17036 #endif 17037 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 17038 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 17039 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 17040 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 17041 #endif 17042 .extract_get_pn_data = extract_get_pn_data_tlv, 17043 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 17044 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 17045 #ifdef WLAN_FEATURE_DISA 17046 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 17047 #endif 17048 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 17049 .send_wlan_profile_hist_intvl_cmd = 17050 send_wlan_profile_hist_intvl_cmd_tlv, 17051 .is_management_record = is_management_record_tlv, 17052 .is_diag_event = is_diag_event_tlv, 17053 #ifdef WLAN_FEATURE_ACTION_OUI 17054 .send_action_oui_cmd = send_action_oui_cmd_tlv, 17055 #endif 17056 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 17057 #ifdef QCA_SUPPORT_AGILE_DFS 17058 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 17059 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 17060 #endif 17061 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 17062 .extract_reg_chan_list_update_event = 17063 extract_reg_chan_list_update_event_tlv, 17064 #ifdef CONFIG_BAND_6GHZ 17065 .extract_reg_chan_list_ext_update_event = 17066 extract_reg_chan_list_ext_update_event_tlv, 17067 #ifdef CONFIG_AFC_SUPPORT 17068 .extract_afc_event = extract_afc_event_tlv, 17069 #endif 17070 #endif 17071 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 17072 .extract_num_rf_characterization_entries = 17073 extract_num_rf_characterization_entries_tlv, 17074 .extract_rf_characterization_entries = 17075 extract_rf_characterization_entries_tlv, 17076 #endif 17077 .extract_chainmask_tables = 17078 extract_chainmask_tables_tlv, 17079 .extract_thermal_stats = extract_thermal_stats_tlv, 17080 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 17081 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 17082 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 17083 #ifdef DFS_COMPONENT_ENABLE 17084 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 17085 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 17086 .extract_dfs_radar_detection_event = 17087 extract_dfs_radar_detection_event_tlv, 17088 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 17089 #endif 17090 .convert_pdev_id_host_to_target = 17091 convert_host_pdev_id_to_target_pdev_id_legacy, 17092 .convert_pdev_id_target_to_host = 17093 convert_target_pdev_id_to_host_pdev_id_legacy, 17094 17095 .convert_host_pdev_id_to_target = 17096 convert_host_pdev_id_to_target_pdev_id, 17097 .convert_target_pdev_id_to_host = 17098 convert_target_pdev_id_to_host_pdev_id, 17099 17100 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 17101 17102 .convert_phy_id_host_to_target = 17103 convert_host_phy_id_to_target_phy_id_legacy, 17104 .convert_phy_id_target_to_host = 17105 convert_target_phy_id_to_host_phy_id_legacy, 17106 17107 .convert_host_phy_id_to_target = 17108 convert_host_phy_id_to_target_phy_id, 17109 .convert_target_phy_id_to_host = 17110 convert_target_phy_id_to_host_phy_id, 17111 17112 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 17113 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 17114 .extract_reg_11d_new_country_event = 17115 extract_reg_11d_new_country_event_tlv, 17116 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 17117 .extract_reg_ch_avoid_event = 17118 extract_reg_ch_avoid_event_tlv, 17119 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 17120 .extract_obss_detection_info = extract_obss_detection_info_tlv, 17121 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 17122 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 17123 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 17124 .wmi_check_command_params = wmitlv_check_command_tlv_params, 17125 .extract_comb_phyerr = extract_comb_phyerr_tlv, 17126 .extract_single_phyerr = extract_single_phyerr_tlv, 17127 #ifdef QCA_SUPPORT_CP_STATS 17128 .extract_cca_stats = extract_cca_stats_tlv, 17129 #endif 17130 .extract_esp_estimation_ev_param = 17131 extract_esp_estimation_ev_param_tlv, 17132 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 17133 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 17134 #ifdef OBSS_PD 17135 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 17136 .send_obss_spatial_reuse_set_def_thresh = 17137 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 17138 .send_self_srg_bss_color_bitmap_set = 17139 send_self_srg_bss_color_bitmap_set_cmd_tlv, 17140 .send_self_srg_partial_bssid_bitmap_set = 17141 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 17142 .send_self_srg_obss_color_enable_bitmap = 17143 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 17144 .send_self_srg_obss_bssid_enable_bitmap = 17145 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 17146 .send_self_non_srg_obss_color_enable_bitmap = 17147 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 17148 .send_self_non_srg_obss_bssid_enable_bitmap = 17149 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 17150 #endif 17151 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 17152 .extract_ctl_failsafe_check_ev_param = 17153 extract_ctl_failsafe_check_ev_param_tlv, 17154 #ifdef WIFI_POS_CONVERGED 17155 .extract_oem_response_param = extract_oem_response_param_tlv, 17156 #endif /* WIFI_POS_CONVERGED */ 17157 #ifdef WLAN_MWS_INFO_DEBUGFS 17158 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 17159 #endif 17160 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 17161 #ifdef FEATURE_ANI_LEVEL_REQUEST 17162 .send_ani_level_cmd = send_ani_level_cmd_tlv, 17163 .extract_ani_level = extract_ani_level_tlv, 17164 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 17165 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 17166 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 17167 .extract_roam_result_stats = extract_roam_result_stats_tlv, 17168 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 17169 #ifdef WLAN_FEATURE_PKT_CAPTURE 17170 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 17171 #endif 17172 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 17173 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 17174 #endif 17175 17176 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 17177 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 17178 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 17179 .extract_time_sync_ftm_start_stop_event = 17180 extract_time_sync_ftm_start_stop_event_tlv, 17181 .extract_time_sync_ftm_offset_event = 17182 extract_time_sync_ftm_offset_event_tlv, 17183 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 17184 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 17185 .send_injector_config_cmd = send_injector_config_cmd_tlv, 17186 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 17187 #ifdef FEATURE_MEC_OFFLOAD 17188 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 17189 #endif 17190 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 17191 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 17192 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 17193 .extract_cp_stats_more_pending = 17194 extract_cp_stats_more_pending_tlv, 17195 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 17196 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 17197 .extract_pdev_csa_switch_count_status = 17198 extract_pdev_csa_switch_count_status_tlv, 17199 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 17200 #ifdef CONFIG_AFC_SUPPORT 17201 .send_afc_cmd = send_afc_cmd_tlv, 17202 #endif 17203 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 17204 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 17205 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 17206 .send_set_halphy_cal = send_set_halphy_cal_tlv, 17207 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 17208 #ifdef WLAN_MGMT_RX_REO_SUPPORT 17209 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 17210 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 17211 .send_mgmt_rx_reo_filter_config_cmd = 17212 send_mgmt_rx_reo_filter_config_cmd_tlv, 17213 #endif 17214 17215 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 17216 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 17217 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 17218 17219 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 17220 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 17221 #endif 17222 }; 17223 17224 /** 17225 * populate_tlv_event_id() - populates wmi event ids 17226 * 17227 * @param event_ids: Pointer to hold event ids 17228 * Return: None 17229 */ 17230 static void populate_tlv_events_id(uint32_t *event_ids) 17231 { 17232 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 17233 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 17234 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 17235 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 17236 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 17237 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 17238 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 17239 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 17240 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 17241 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 17242 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 17243 event_ids[wmi_service_ready_ext_event_id] = 17244 WMI_SERVICE_READY_EXT_EVENTID; 17245 event_ids[wmi_service_ready_ext2_event_id] = 17246 WMI_SERVICE_READY_EXT2_EVENTID; 17247 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 17248 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 17249 event_ids[wmi_vdev_install_key_complete_event_id] = 17250 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 17251 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 17252 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 17253 17254 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 17255 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 17256 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 17257 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 17258 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 17259 event_ids[wmi_peer_estimated_linkspeed_event_id] = 17260 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 17261 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 17262 event_ids[wmi_peer_create_conf_event_id] = 17263 WMI_PEER_CREATE_CONF_EVENTID; 17264 event_ids[wmi_peer_delete_response_event_id] = 17265 WMI_PEER_DELETE_RESP_EVENTID; 17266 event_ids[wmi_peer_delete_all_response_event_id] = 17267 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 17268 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 17269 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 17270 event_ids[wmi_tbttoffset_update_event_id] = 17271 WMI_TBTTOFFSET_UPDATE_EVENTID; 17272 event_ids[wmi_ext_tbttoffset_update_event_id] = 17273 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 17274 event_ids[wmi_offload_bcn_tx_status_event_id] = 17275 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 17276 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 17277 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 17278 event_ids[wmi_mgmt_tx_completion_event_id] = 17279 WMI_MGMT_TX_COMPLETION_EVENTID; 17280 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 17281 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 17282 event_ids[wmi_tx_delba_complete_event_id] = 17283 WMI_TX_DELBA_COMPLETE_EVENTID; 17284 event_ids[wmi_tx_addba_complete_event_id] = 17285 WMI_TX_ADDBA_COMPLETE_EVENTID; 17286 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 17287 17288 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 17289 17290 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 17291 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 17292 17293 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 17294 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 17295 17296 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 17297 17298 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 17299 event_ids[wmi_p2p_lo_stop_event_id] = 17300 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 17301 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 17302 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 17303 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 17304 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 17305 event_ids[wmi_d0_wow_disable_ack_event_id] = 17306 WMI_D0_WOW_DISABLE_ACK_EVENTID; 17307 event_ids[wmi_wow_initial_wakeup_event_id] = 17308 WMI_WOW_INITIAL_WAKEUP_EVENTID; 17309 17310 event_ids[wmi_rtt_meas_report_event_id] = 17311 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 17312 event_ids[wmi_tsf_meas_report_event_id] = 17313 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 17314 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 17315 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 17316 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 17317 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 17318 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 17319 event_ids[wmi_diag_event_id_log_supported_event_id] = 17320 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 17321 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 17322 event_ids[wmi_nlo_scan_complete_event_id] = 17323 WMI_NLO_SCAN_COMPLETE_EVENTID; 17324 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 17325 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 17326 17327 event_ids[wmi_gtk_offload_status_event_id] = 17328 WMI_GTK_OFFLOAD_STATUS_EVENTID; 17329 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 17330 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 17331 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 17332 17333 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 17334 17335 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 17336 17337 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 17338 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 17339 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 17340 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 17341 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 17342 event_ids[wmi_wlan_profile_data_event_id] = 17343 WMI_WLAN_PROFILE_DATA_EVENTID; 17344 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 17345 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 17346 event_ids[wmi_vdev_get_keepalive_event_id] = 17347 WMI_VDEV_GET_KEEPALIVE_EVENTID; 17348 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 17349 17350 event_ids[wmi_diag_container_event_id] = 17351 WMI_DIAG_DATA_CONTAINER_EVENTID; 17352 17353 event_ids[wmi_host_auto_shutdown_event_id] = 17354 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 17355 17356 event_ids[wmi_update_whal_mib_stats_event_id] = 17357 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 17358 17359 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 17360 event_ids[wmi_update_vdev_rate_stats_event_id] = 17361 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 17362 17363 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 17364 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 17365 17366 /** Set OCB Sched Response, deprecated */ 17367 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 17368 17369 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 17370 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 17371 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 17372 17373 /* GPIO Event */ 17374 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 17375 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 17376 17377 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 17378 event_ids[wmi_rfkill_state_change_event_id] = 17379 WMI_RFKILL_STATE_CHANGE_EVENTID; 17380 17381 /* TDLS Event */ 17382 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 17383 17384 event_ids[wmi_batch_scan_enabled_event_id] = 17385 WMI_BATCH_SCAN_ENABLED_EVENTID; 17386 event_ids[wmi_batch_scan_result_event_id] = 17387 WMI_BATCH_SCAN_RESULT_EVENTID; 17388 /* OEM Event */ 17389 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 17390 event_ids[wmi_oem_meas_report_event_id] = 17391 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 17392 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 17393 17394 /* NAN Event */ 17395 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 17396 17397 /* LPI Event */ 17398 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 17399 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 17400 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 17401 17402 /* ExtScan events */ 17403 event_ids[wmi_extscan_start_stop_event_id] = 17404 WMI_EXTSCAN_START_STOP_EVENTID; 17405 event_ids[wmi_extscan_operation_event_id] = 17406 WMI_EXTSCAN_OPERATION_EVENTID; 17407 event_ids[wmi_extscan_table_usage_event_id] = 17408 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 17409 event_ids[wmi_extscan_cached_results_event_id] = 17410 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 17411 event_ids[wmi_extscan_wlan_change_results_event_id] = 17412 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 17413 event_ids[wmi_extscan_hotlist_match_event_id] = 17414 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 17415 event_ids[wmi_extscan_capabilities_event_id] = 17416 WMI_EXTSCAN_CAPABILITIES_EVENTID; 17417 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 17418 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 17419 17420 /* mDNS offload events */ 17421 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 17422 17423 /* SAP Authentication offload events */ 17424 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 17425 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 17426 17427 /** Out-of-context-of-bss (OCB) events */ 17428 event_ids[wmi_ocb_set_config_resp_event_id] = 17429 WMI_OCB_SET_CONFIG_RESP_EVENTID; 17430 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 17431 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 17432 event_ids[wmi_dcc_get_stats_resp_event_id] = 17433 WMI_DCC_GET_STATS_RESP_EVENTID; 17434 event_ids[wmi_dcc_update_ndl_resp_event_id] = 17435 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 17436 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 17437 /* System-On-Chip events */ 17438 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 17439 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 17440 event_ids[wmi_soc_hw_mode_transition_event_id] = 17441 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 17442 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 17443 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 17444 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 17445 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 17446 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 17447 #endif 17448 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 17449 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 17450 event_ids[wmi_vdev_ocac_complete_event_id] = 17451 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 17452 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 17453 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 17454 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 17455 #ifdef CONFIG_AFC_SUPPORT 17456 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 17457 #endif 17458 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 17459 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 17460 event_ids[wmi_peer_sta_ps_statechg_event_id] = 17461 WMI_PEER_STA_PS_STATECHG_EVENTID; 17462 event_ids[wmi_pdev_channel_hopping_event_id] = 17463 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 17464 event_ids[wmi_offchan_data_tx_completion_event] = 17465 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 17466 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 17467 event_ids[wmi_dfs_radar_detection_event_id] = 17468 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 17469 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 17470 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 17471 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 17472 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 17473 event_ids[wmi_service_available_event_id] = 17474 WMI_SERVICE_AVAILABLE_EVENTID; 17475 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 17476 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 17477 /* NDP events */ 17478 event_ids[wmi_ndp_initiator_rsp_event_id] = 17479 WMI_NDP_INITIATOR_RSP_EVENTID; 17480 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 17481 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 17482 event_ids[wmi_ndp_responder_rsp_event_id] = 17483 WMI_NDP_RESPONDER_RSP_EVENTID; 17484 event_ids[wmi_ndp_end_indication_event_id] = 17485 WMI_NDP_END_INDICATION_EVENTID; 17486 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 17487 event_ids[wmi_ndl_schedule_update_event_id] = 17488 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 17489 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 17490 17491 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 17492 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 17493 event_ids[wmi_pdev_chip_power_stats_event_id] = 17494 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 17495 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 17496 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 17497 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 17498 event_ids[wmi_apf_capability_info_event_id] = 17499 WMI_BPF_CAPABILIY_INFO_EVENTID; 17500 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 17501 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 17502 event_ids[wmi_report_rx_aggr_failure_event_id] = 17503 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 17504 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 17505 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 17506 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 17507 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 17508 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 17509 event_ids[wmi_pdev_hw_mode_transition_event_id] = 17510 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 17511 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 17512 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 17513 event_ids[wmi_coex_bt_activity_event_id] = 17514 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 17515 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 17516 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 17517 event_ids[wmi_radio_tx_power_level_stats_event_id] = 17518 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 17519 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 17520 event_ids[wmi_dma_buf_release_event_id] = 17521 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 17522 event_ids[wmi_sap_obss_detection_report_event_id] = 17523 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 17524 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 17525 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 17526 event_ids[wmi_obss_color_collision_report_event_id] = 17527 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 17528 event_ids[wmi_pdev_div_rssi_antid_event_id] = 17529 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 17530 #ifdef WLAN_SUPPORT_TWT 17531 event_ids[wmi_twt_enable_complete_event_id] = 17532 WMI_TWT_ENABLE_COMPLETE_EVENTID; 17533 event_ids[wmi_twt_disable_complete_event_id] = 17534 WMI_TWT_DISABLE_COMPLETE_EVENTID; 17535 event_ids[wmi_twt_add_dialog_complete_event_id] = 17536 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 17537 event_ids[wmi_twt_del_dialog_complete_event_id] = 17538 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 17539 event_ids[wmi_twt_pause_dialog_complete_event_id] = 17540 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 17541 event_ids[wmi_twt_resume_dialog_complete_event_id] = 17542 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 17543 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 17544 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 17545 event_ids[wmi_twt_session_stats_event_id] = 17546 WMI_TWT_SESSION_STATS_EVENTID; 17547 event_ids[wmi_twt_notify_event_id] = 17548 WMI_TWT_NOTIFY_EVENTID; 17549 event_ids[wmi_twt_ack_complete_event_id] = 17550 WMI_TWT_ACK_EVENTID; 17551 #endif 17552 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 17553 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 17554 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 17555 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 17556 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 17557 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 17558 event_ids[wmi_pdev_interop_issues_ap_event_id] = 17559 WMI_PDEV_RAP_INFO_EVENTID; 17560 #endif 17561 #ifdef AST_HKV1_WORKAROUND 17562 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 17563 #endif 17564 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 17565 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 17566 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 17567 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 17568 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 17569 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 17570 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 17571 event_ids[wmi_pdev_cold_boot_cal_event_id] = 17572 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 17573 #ifdef WLAN_MWS_INFO_DEBUGFS 17574 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 17575 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 17576 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 17577 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 17578 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 17579 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 17580 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 17581 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 17582 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 17583 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 17584 #endif 17585 event_ids[wmi_coex_report_antenna_isolation_event_id] = 17586 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 17587 event_ids[wmi_peer_ratecode_list_event_id] = 17588 WMI_PEER_RATECODE_LIST_EVENTID; 17589 event_ids[wmi_chan_rf_characterization_info_event_id] = 17590 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 17591 event_ids[wmi_roam_auth_offload_event_id] = 17592 WMI_ROAM_PREAUTH_START_EVENTID; 17593 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 17594 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 17595 event_ids[wmi_motion_det_base_line_host_eventid] = 17596 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 17597 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 17598 event_ids[wmi_peer_tx_pn_response_event_id] = 17599 WMI_PEER_TX_PN_RESPONSE_EVENTID; 17600 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 17601 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 17602 event_ids[wmi_mgmt_offload_data_event_id] = 17603 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 17604 event_ids[wmi_nan_dmesg_event_id] = 17605 WMI_NAN_DMESG_EVENTID; 17606 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 17607 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 17608 event_ids[wmi_roam_pmkid_request_event_id] = 17609 WMI_ROAM_PMKID_REQUEST_EVENTID; 17610 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 17611 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 17612 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 17613 event_ids[wmi_wlan_time_sync_q_master_slave_offset_eventid] = 17614 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 17615 #endif 17616 event_ids[wmi_roam_scan_chan_list_id] = 17617 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 17618 event_ids[wmi_muedca_params_config_eventid] = 17619 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 17620 event_ids[wmi_pdev_sscan_fw_param_eventid] = 17621 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 17622 event_ids[wmi_roam_cap_report_event_id] = 17623 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 17624 event_ids[wmi_vdev_bcn_latency_event_id] = 17625 WMI_VDEV_BCN_LATENCY_EVENTID; 17626 event_ids[wmi_vdev_disconnect_event_id] = 17627 WMI_VDEV_DISCONNECT_EVENTID; 17628 event_ids[wmi_peer_create_conf_event_id] = 17629 WMI_PEER_CREATE_CONF_EVENTID; 17630 event_ids[wmi_pdev_cp_fwstats_eventid] = 17631 WMI_CTRL_PATH_STATS_EVENTID; 17632 event_ids[wmi_vdev_send_big_data_p2_eventid] = 17633 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 17634 event_ids[wmi_pdev_get_dpd_status_event_id] = 17635 WMI_PDEV_GET_DPD_STATUS_EVENTID; 17636 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 17637 event_ids[wmi_vdev_smart_monitor_event_id] = 17638 WMI_VDEV_SMART_MONITOR_EVENTID; 17639 #endif 17640 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 17641 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 17642 event_ids[wmi_pdev_set_halphy_cal_event_id] = 17643 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 17644 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 17645 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 17646 #ifdef WLAN_MGMT_RX_REO_SUPPORT 17647 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 17648 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 17649 #endif 17650 #ifdef WLAN_FEATURE_11BE_MLO 17651 event_ids[wmi_mlo_setup_complete_event_id] = 17652 WMI_MLO_SETUP_COMPLETE_EVENTID; 17653 event_ids[wmi_mlo_teardown_complete_event_id] = 17654 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 17655 event_ids[wmi_mlo_link_set_active_resp_eventid] = 17656 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 17657 #endif 17658 event_ids[wmi_roam_frame_event_id] = 17659 WMI_ROAM_FRAME_EVENTID; 17660 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 17661 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 17662 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 17663 #endif 17664 } 17665 17666 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 17667 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 17668 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 17669 { 17670 wmi_service[wmi_service_get_station_in_ll_stats_req] = 17671 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 17672 } 17673 #else 17674 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 17675 { 17676 } 17677 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 17678 #else 17679 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 17680 { 17681 } 17682 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 17683 17684 /** 17685 * populate_tlv_service() - populates wmi services 17686 * 17687 * @param wmi_service: Pointer to hold wmi_service 17688 * Return: None 17689 */ 17690 static void populate_tlv_service(uint32_t *wmi_service) 17691 { 17692 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 17693 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 17694 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 17695 wmi_service[wmi_service_roam_scan_offload] = 17696 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 17697 wmi_service[wmi_service_bcn_miss_offload] = 17698 WMI_SERVICE_BCN_MISS_OFFLOAD; 17699 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 17700 wmi_service[wmi_service_sta_advanced_pwrsave] = 17701 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 17702 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 17703 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 17704 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 17705 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 17706 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 17707 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 17708 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 17709 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 17710 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 17711 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 17712 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 17713 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 17714 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 17715 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 17716 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 17717 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 17718 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 17719 wmi_service[wmi_service_packet_power_save] = 17720 WMI_SERVICE_PACKET_POWER_SAVE; 17721 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 17722 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 17723 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 17724 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 17725 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 17726 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 17727 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 17728 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 17729 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 17730 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 17731 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 17732 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 17733 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 17734 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 17735 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 17736 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 17737 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 17738 wmi_service[wmi_service_mcc_bcn_interval_change] = 17739 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 17740 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 17741 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 17742 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 17743 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 17744 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 17745 wmi_service[wmi_service_lte_ant_share_support] = 17746 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 17747 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 17748 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 17749 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 17750 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 17751 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 17752 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 17753 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 17754 wmi_service[wmi_service_bcn_txrate_override] = 17755 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 17756 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 17757 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 17758 wmi_service[wmi_service_estimate_linkspeed] = 17759 WMI_SERVICE_ESTIMATE_LINKSPEED; 17760 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 17761 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 17762 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 17763 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 17764 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 17765 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 17766 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 17767 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 17768 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 17769 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 17770 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 17771 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 17772 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 17773 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 17774 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 17775 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 17776 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 17777 wmi_service[wmi_service_sap_auth_offload] = 17778 WMI_SERVICE_SAP_AUTH_OFFLOAD; 17779 wmi_service[wmi_service_dual_band_simultaneous_support] = 17780 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 17781 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 17782 wmi_service[wmi_service_ap_arpns_offload] = 17783 WMI_SERVICE_AP_ARPNS_OFFLOAD; 17784 wmi_service[wmi_service_per_band_chainmask_support] = 17785 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 17786 wmi_service[wmi_service_packet_filter_offload] = 17787 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 17788 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 17789 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 17790 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 17791 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 17792 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 17793 wmi_service[wmi_service_multiple_vdev_restart] = 17794 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 17795 wmi_service[wmi_service_smart_antenna_sw_support] = 17796 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 17797 wmi_service[wmi_service_smart_antenna_hw_support] = 17798 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 17799 17800 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 17801 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 17802 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 17803 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 17804 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 17805 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 17806 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 17807 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 17808 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 17809 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 17810 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 17811 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 17812 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 17813 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 17814 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 17815 wmi_service[wmi_service_periodic_chan_stat_support] = 17816 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 17817 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 17818 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 17819 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 17820 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 17821 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 17822 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 17823 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 17824 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 17825 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 17826 wmi_service[wmi_service_unified_wow_capability] = 17827 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 17828 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 17829 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 17830 wmi_service[wmi_service_sync_delete_cmds] = 17831 WMI_SERVICE_SYNC_DELETE_CMDS; 17832 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 17833 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 17834 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 17835 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 17836 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 17837 wmi_service[wmi_service_deprecated_replace] = 17838 WMI_SERVICE_DEPRECATED_REPLACE; 17839 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 17840 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 17841 wmi_service[wmi_service_enhanced_mcast_filter] = 17842 WMI_SERVICE_ENHANCED_MCAST_FILTER; 17843 wmi_service[wmi_service_half_rate_quarter_rate_support] = 17844 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 17845 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 17846 wmi_service[wmi_service_p2p_listen_offload_support] = 17847 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 17848 wmi_service[wmi_service_mark_first_wakeup_packet] = 17849 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 17850 wmi_service[wmi_service_multiple_mcast_filter_set] = 17851 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 17852 wmi_service[wmi_service_host_managed_rx_reorder] = 17853 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 17854 wmi_service[wmi_service_flash_rdwr_support] = 17855 WMI_SERVICE_FLASH_RDWR_SUPPORT; 17856 wmi_service[wmi_service_wlan_stats_report] = 17857 WMI_SERVICE_WLAN_STATS_REPORT; 17858 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 17859 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 17860 wmi_service[wmi_service_dfs_phyerr_offload] = 17861 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 17862 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 17863 wmi_service[wmi_service_fw_mem_dump_support] = 17864 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 17865 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 17866 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 17867 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 17868 wmi_service[wmi_service_hw_data_filtering] = 17869 WMI_SERVICE_HW_DATA_FILTERING; 17870 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 17871 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 17872 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 17873 wmi_service[wmi_service_extended_nss_support] = 17874 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 17875 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 17876 wmi_service[wmi_service_bcn_offload_start_stop_support] = 17877 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 17878 wmi_service[wmi_service_offchan_data_tid_support] = 17879 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 17880 wmi_service[wmi_service_support_dma] = 17881 WMI_SERVICE_SUPPORT_DIRECT_DMA; 17882 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 17883 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 17884 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 17885 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 17886 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 17887 wmi_service[wmi_service_11k_neighbour_report_support] = 17888 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 17889 wmi_service[wmi_service_ap_obss_detection_offload] = 17890 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 17891 wmi_service[wmi_service_bss_color_offload] = 17892 WMI_SERVICE_BSS_COLOR_OFFLOAD; 17893 wmi_service[wmi_service_gmac_offload_support] = 17894 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 17895 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 17896 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 17897 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 17898 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 17899 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 17900 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 17901 wmi_service[wmi_service_listen_interval_offload_support] = 17902 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 17903 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 17904 wmi_service[wmi_service_obss_spatial_reuse] = 17905 WMI_SERVICE_OBSS_SPATIAL_REUSE; 17906 wmi_service[wmi_service_per_vdev_chain_support] = 17907 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 17908 wmi_service[wmi_service_new_htt_msg_format] = 17909 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 17910 wmi_service[wmi_service_peer_unmap_cnf_support] = 17911 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 17912 wmi_service[wmi_service_beacon_reception_stats] = 17913 WMI_SERVICE_BEACON_RECEPTION_STATS; 17914 wmi_service[wmi_service_vdev_latency_config] = 17915 WMI_SERVICE_VDEV_LATENCY_CONFIG; 17916 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 17917 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 17918 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 17919 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 17920 wmi_service[wmi_service_nan_disable_support] = 17921 WMI_SERVICE_NAN_DISABLE_SUPPORT; 17922 wmi_service[wmi_service_sta_plus_sta_support] = 17923 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 17924 wmi_service[wmi_service_hw_db2dbm_support] = 17925 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 17926 wmi_service[wmi_service_wlm_stats_support] = 17927 WMI_SERVICE_WLM_STATS_REQUEST; 17928 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 17929 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 17930 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 17931 wmi_service[wmi_service_cfr_capture_support] = 17932 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 17933 wmi_service[wmi_service_bcast_twt_support] = 17934 WMI_SERVICE_BROADCAST_TWT; 17935 wmi_service[wmi_service_wpa3_ft_sae_support] = 17936 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 17937 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 17938 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 17939 wmi_service[wmi_service_ft_fils] = 17940 WMI_SERVICE_WPA3_FT_FILS; 17941 wmi_service[wmi_service_adaptive_11r_support] = 17942 WMI_SERVICE_ADAPTIVE_11R_ROAM; 17943 wmi_service[wmi_service_tx_compl_tsf64] = 17944 WMI_SERVICE_TX_COMPL_TSF64; 17945 wmi_service[wmi_service_data_stall_recovery_support] = 17946 WMI_SERVICE_DSM_ROAM_FILTER; 17947 wmi_service[wmi_service_vdev_delete_all_peer] = 17948 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 17949 wmi_service[wmi_service_three_way_coex_config_legacy] = 17950 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 17951 wmi_service[wmi_service_rx_fse_support] = 17952 WMI_SERVICE_RX_FSE_SUPPORT; 17953 wmi_service[wmi_service_sae_roam_support] = 17954 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 17955 wmi_service[wmi_service_owe_roam_support] = 17956 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 17957 wmi_service[wmi_service_6ghz_support] = 17958 WMI_SERVICE_6GHZ_SUPPORT; 17959 wmi_service[wmi_service_bw_165mhz_support] = 17960 WMI_SERVICE_BW_165MHZ_SUPPORT; 17961 wmi_service[wmi_service_bw_restricted_80p80_support] = 17962 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 17963 wmi_service[wmi_service_packet_capture_support] = 17964 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 17965 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 17966 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 17967 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 17968 wmi_service[wmi_service_multiple_vdev_restart_ext] = 17969 WMI_SERVICE_UNAVAILABLE; 17970 wmi_service[wmi_service_time_sync_ftm] = 17971 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 17972 wmi_service[wmi_service_nss_ratio_to_host_support] = 17973 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 17974 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 17975 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 17976 wmi_service[wmi_beacon_protection_support] = 17977 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 17978 wmi_service[wmi_service_sta_nan_ndi_four_port] = 17979 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 17980 wmi_service[wmi_service_host_scan_stop_vdev_all] = 17981 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 17982 wmi_service[wmi_support_extend_address] = 17983 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 17984 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 17985 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 17986 wmi_service[wmi_service_suiteb_roam_support] = 17987 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 17988 wmi_service[wmi_service_no_interband_mcc_support] = 17989 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 17990 wmi_service[wmi_service_dual_sta_roam_support] = 17991 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 17992 wmi_service[wmi_service_peer_create_conf] = 17993 WMI_SERVICE_PEER_CREATE_CONF; 17994 wmi_service[wmi_service_configure_roam_trigger_param_support] = 17995 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 17996 wmi_service[wmi_service_5dot9_ghz_support] = 17997 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 17998 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 17999 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 18000 wmi_service[wmi_service_cfr_capture_count_support] = 18001 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 18002 wmi_service[wmi_service_ocv_support] = 18003 WMI_SERVICE_OCV_SUPPORT; 18004 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 18005 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 18006 wmi_service[wmi_service_thermal_multi_client_support] = 18007 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 18008 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 18009 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 18010 wmi_service[wmi_service_fse_cmem_alloc_support] = 18011 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 18012 wmi_service[wmi_service_scan_conf_per_ch_support] = 18013 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 18014 wmi_service[wmi_service_csa_beacon_template] = 18015 WMI_SERVICE_CSA_BEACON_TEMPLATE; 18016 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 18017 wmi_service[wmi_service_igmp_offload_support] = 18018 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 18019 #endif 18020 #ifdef WLAN_FEATURE_11AX 18021 #ifdef FEATURE_WLAN_TDLS 18022 wmi_service[wmi_service_tdls_ax_support] = 18023 WMI_SERVICE_11AX_TDLS_SUPPORT; 18024 #endif 18025 #endif 18026 #ifdef WLAN_SUPPORT_TWT 18027 wmi_service[wmi_service_twt_bcast_req_support] = 18028 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 18029 wmi_service[wmi_service_twt_bcast_resp_support] = 18030 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 18031 wmi_service[wmi_service_twt_nudge] = 18032 WMI_SERVICE_TWT_NUDGE; 18033 wmi_service[wmi_service_all_twt] = 18034 WMI_SERVICE_TWT_ALL_DIALOG_ID; 18035 wmi_service[wmi_service_twt_statistics] = 18036 WMI_SERVICE_TWT_STATS; 18037 #endif 18038 wmi_service[wmi_service_spectral_scan_disabled] = 18039 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 18040 wmi_service[wmi_service_sae_eapol_offload_support] = 18041 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 18042 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 18043 18044 wmi_service[wmi_service_wapi_concurrency_supported] = 18045 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 18046 wmi_service[wmi_service_sap_connected_d3_wow] = 18047 WMI_SERVICE_SAP_CONNECTED_D3WOW; 18048 wmi_service[wmi_service_go_connected_d3_wow] = 18049 WMI_SERVICE_SAP_CONNECTED_D3WOW; 18050 wmi_service[wmi_service_ext_tpc_reg_support] = 18051 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 18052 wmi_service[wmi_service_ndi_txbf_support] = 18053 WMI_SERVICE_NDI_TXBF_SUPPORT; 18054 wmi_service[wmi_service_reg_cc_ext_event_support] = 18055 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 18056 #if defined(CONFIG_BAND_6GHZ) 18057 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 18058 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 18059 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 18060 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 18061 #endif 18062 wmi_service[wmi_service_dcs_awgn_int_support] = 18063 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 18064 wmi_populate_service_11be(wmi_service); 18065 18066 #ifdef WLAN_FEATURE_BIG_DATA_STATS 18067 wmi_service[wmi_service_big_data_support] = 18068 WMI_SERVICE_BIG_DATA_SUPPORT; 18069 #endif 18070 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 18071 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 18072 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 18073 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 18074 wmi_service[wmi_service_halphy_cal_status] = 18075 WMI_SERVICE_HALPHY_CAL_STATUS; 18076 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 18077 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 18078 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 18079 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 18080 wmi_service[wmi_service_ema_multiple_group_supported] = 18081 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 18082 wmi_service[wmi_service_large_beacon_supported] = 18083 WMI_SERVICE_LARGE_BEACON_SUPPORT; 18084 wmi_service[wmi_service_aoa_for_rcc_supported] = 18085 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 18086 #ifdef WLAN_FEATURE_P2P_P2P_STA 18087 wmi_service[wmi_service_p2p_p2p_cc_support] = 18088 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 18089 #endif 18090 #ifdef THERMAL_STATS_SUPPORT 18091 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 18092 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 18093 #endif 18094 wmi_service[wmi_service_hw_mode_policy_offload_support] = 18095 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 18096 wmi_service[wmi_service_mgmt_rx_reo_supported] = 18097 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 18098 wmi_service[wmi_service_phy_dma_byte_swap_support] = 18099 WMI_SERVICE_UNAVAILABLE; 18100 wmi_service[wmi_service_spectral_session_info_support] = 18101 WMI_SERVICE_UNAVAILABLE; 18102 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 18103 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18104 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 18105 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 18106 #endif 18107 } 18108 18109 /** 18110 * wmi_ocb_ut_attach() - Attach OCB test framework 18111 * @wmi_handle: wmi handle 18112 * 18113 * Return: None 18114 */ 18115 #ifdef WLAN_OCB_UT 18116 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 18117 #else 18118 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 18119 { 18120 return; 18121 } 18122 #endif 18123 18124 /** 18125 * wmi_tlv_attach() - Attach TLV APIs 18126 * 18127 * Return: None 18128 */ 18129 void wmi_tlv_attach(wmi_unified_t wmi_handle) 18130 { 18131 wmi_handle->ops = &tlv_ops; 18132 wmi_ocb_ut_attach(wmi_handle); 18133 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 18134 #ifdef WMI_INTERFACE_EVENT_LOGGING 18135 /* Skip saving WMI_CMD_HDR and TLV HDR */ 18136 wmi_handle->soc->buf_offset_command = 8; 18137 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 18138 wmi_handle->soc->buf_offset_event = 4; 18139 #endif 18140 populate_tlv_events_id(wmi_handle->wmi_events); 18141 populate_tlv_service(wmi_handle->services); 18142 wmi_wds_attach_tlv(wmi_handle); 18143 wmi_twt_attach_tlv(wmi_handle); 18144 wmi_extscan_attach_tlv(wmi_handle); 18145 wmi_smart_ant_attach_tlv(wmi_handle); 18146 wmi_dbr_attach_tlv(wmi_handle); 18147 wmi_atf_attach_tlv(wmi_handle); 18148 wmi_ap_attach_tlv(wmi_handle); 18149 wmi_bcn_attach_tlv(wmi_handle); 18150 wmi_ocb_attach_tlv(wmi_handle); 18151 wmi_nan_attach_tlv(wmi_handle); 18152 wmi_p2p_attach_tlv(wmi_handle); 18153 wmi_interop_issues_ap_attach_tlv(wmi_handle); 18154 wmi_dcs_attach_tlv(wmi_handle); 18155 wmi_roam_attach_tlv(wmi_handle); 18156 wmi_concurrency_attach_tlv(wmi_handle); 18157 wmi_pmo_attach_tlv(wmi_handle); 18158 wmi_sta_attach_tlv(wmi_handle); 18159 wmi_11ax_bss_color_attach_tlv(wmi_handle); 18160 wmi_fwol_attach_tlv(wmi_handle); 18161 wmi_vdev_attach_tlv(wmi_handle); 18162 wmi_cfr_attach_tlv(wmi_handle); 18163 wmi_cp_stats_attach_tlv(wmi_handle); 18164 wmi_gpio_attach_tlv(wmi_handle); 18165 wmi_11be_attach_tlv(wmi_handle); 18166 } 18167 qdf_export_symbol(wmi_tlv_attach); 18168 18169 /** 18170 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 18171 * 18172 * Return: None 18173 */ 18174 void wmi_tlv_init(void) 18175 { 18176 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 18177 } 18178