1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 /* 72 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 73 * then channel_list may fill the upper 12 bits with channel flags, 74 * while using only the lower 20 bits for channel frequency. 75 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 76 * then channel_list only holds the frequency value. 77 */ 78 #define CHAN_LIST_FLAG_MASK_POS 20 79 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 80 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 81 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 82 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 83 84 /* HTC service ids for WMI for multi-radio */ 85 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 86 WMI_CONTROL_SVC_WMAC1, 87 WMI_CONTROL_SVC_WMAC2}; 88 89 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 90 /*Populate peer_param array whose index as host id and 91 *value as target id 92 */ 93 static const uint32_t peer_param_tlv[] = { 94 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 95 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 96 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 97 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 98 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 99 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 100 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 101 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 102 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 103 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 104 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 105 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 106 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 107 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 108 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 109 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 110 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 111 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_WHITELIST, 112 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 113 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 114 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 115 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 116 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 117 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 120 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 121 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 122 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 123 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 124 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 125 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 126 }; 127 128 /** 129 * Populate pdev_param_value whose index is host param and value is target 130 * param 131 */ 132 static const uint32_t pdev_param_tlv[] = { 133 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 134 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 135 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 136 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 137 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 138 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 139 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 140 [wmi_pdev_param_resmgr_offchan_mode] = 141 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 142 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 143 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 144 [wmi_pdev_param_non_agg_sw_retry_th] = 145 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 146 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 147 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 148 [wmi_pdev_param_ac_aggrsize_scaling] = 149 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 150 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 151 [wmi_pdev_param_ltr_ac_latency_be] = 152 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 153 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 154 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 155 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 156 [wmi_pdev_param_ltr_ac_latency_timeout] = 157 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 158 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 159 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 160 [wmi_pdev_param_ltr_tx_activity_timeout] = 161 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 162 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 163 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 164 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 165 [wmi_pdev_param_pcielp_txbuf_watermark] = 166 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 167 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 168 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 169 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 170 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 171 [wmi_pdev_param_pdev_stats_update_period] = 172 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 173 [wmi_pdev_param_vdev_stats_update_period] = 174 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_peer_stats_update_period] = 176 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 177 [wmi_pdev_param_bcnflt_stats_update_period] = 178 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 179 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 180 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 181 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 182 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 183 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 184 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 185 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 186 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 187 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 188 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 189 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 190 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 191 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 192 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 193 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 194 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 195 [wmi_pdev_param_low_power_rf_enable] = 196 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 197 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 198 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 199 [wmi_pdev_param_power_collapse_enable] = 200 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 201 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 202 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 203 [wmi_pdev_param_audio_over_wlan_latency] = 204 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 205 [wmi_pdev_param_audio_over_wlan_enable] = 206 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 207 [wmi_pdev_param_whal_mib_stats_update_enable] = 208 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 209 [wmi_pdev_param_vdev_rate_stats_update_period] = 210 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 211 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 212 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 213 [wmi_pdev_param_adaptive_early_rx_enable] = 214 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 215 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 216 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 217 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 218 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 219 [wmi_pdev_param_early_rx_fix_sleep_slop] = 220 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 221 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 222 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 223 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 224 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 225 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 226 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 227 [wmi_pdev_param_bto_fix_bcn_timeout] = 228 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 229 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 230 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 231 [wmi_pdev_param_ce_bto_combo_ce_value] = 232 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 233 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 234 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 235 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 236 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 237 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 238 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 239 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 240 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 241 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 242 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 243 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 244 [wmi_pdev_peer_sta_ps_statechg_enable] = 245 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 246 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 247 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 248 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 249 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 250 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 251 [wmi_pdev_param_set_mcast_bcast_echo] = 252 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 253 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 254 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 255 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 256 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 257 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 258 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 259 [wmi_pdev_param_enable_per_tid_amsdu] = 260 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 261 [wmi_pdev_param_enable_per_tid_ampdu] = 262 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 263 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 264 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 265 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 266 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 267 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 268 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 269 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 270 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 271 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 272 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 273 [wmi_pdev_param_atf_obss_noise_sch] = 274 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 275 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 276 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 277 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 278 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 279 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 280 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 281 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 282 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 283 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 284 [wmi_pdev_param_set_disable_reset_cmdid] = 285 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 286 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 287 [wmi_pdev_param_txbf_sound_period_cmdid] = 288 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 289 [wmi_pdev_param_set_burst_mode_cmdid] = 290 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 291 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 292 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 293 [wmi_pdev_param_set_promisc_mode_cmdid] = 294 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 295 [wmi_pdev_param_set_ppdu_duration_cmdid] = 296 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 297 [wmi_pdev_param_remove_mcast2ucast_buffer] = 298 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 299 [wmi_pdev_param_set_mcast2ucast_buffer] = 300 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 301 [wmi_pdev_param_set_mcast2ucast_mode] = 302 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 303 [wmi_pdev_param_smart_antenna_default_antenna] = 304 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 305 [wmi_pdev_param_fast_channel_reset] = 306 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 307 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 308 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 309 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 310 [wmi_pdev_param_antenna_gain_half_db] = 311 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 312 [wmi_pdev_param_esp_indication_period] = 313 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 314 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 315 [wmi_pdev_param_esp_airtime_fraction] = 316 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 317 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 318 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 319 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 320 /* Trigger interval for all trigger types. */ 321 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 322 [wmi_pdev_param_sub_channel_marking] = 323 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 324 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 325 [wmi_pdev_param_equal_ru_allocation_enable] = 326 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 327 [wmi_pdev_param_per_peer_prd_cfr_enable] = 328 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 329 [wmi_pdev_param_nav_override_config] = 330 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 331 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 332 [wmi_pdev_param_set_prb_rsp_ttl] = 333 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 334 [wmi_pdev_param_set_mu_ppdu_duration] = 335 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 336 [wmi_pdev_param_set_tbtt_ctrl] = 337 WMI_PDEV_PARAM_SET_TBTT_CTRL, 338 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 339 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 340 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 341 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 342 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 343 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 344 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 345 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 346 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 347 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 348 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 349 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 350 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 351 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 352 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 353 [wmi_pdev_param_low_latency_mode] = 354 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 355 [wmi_pdev_param_scan_radio_tx_on_dfs] = 356 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 357 [wmi_pdev_param_en_probe_all_bw] = 358 WMI_PDEV_PARAM_EN_PROBE_ALL_BW, 359 [wmi_pdev_param_obss_min_duration_check_for_sr] = 360 WMI_PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR, 361 [wmi_pdev_param_truncate_sr] = WMI_PDEV_PARAM_TRUNCATE_SR, 362 [wmi_pdev_param_ctrl_frame_obss_pd_threshold] = 363 WMI_PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD, 364 [wmi_pdev_param_rate_upper_cap] = WMI_PDEV_PARAM_RATE_UPPER_CAP, 365 [wmi_pdev_param_rate_retry_mcs_drop] = 366 WMI_PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH, 367 [wmi_pdev_param_mcs_probe_intvl] = 368 WMI_PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL, 369 [wmi_pdev_param_nss_probe_intvl] = 370 WMI_PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL, 371 }; 372 373 /** 374 * Populate vdev_param_value_tlv array whose index is host param 375 * and value is target param 376 */ 377 static const uint32_t vdev_param_tlv[] = { 378 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 379 [wmi_vdev_param_fragmentation_threshold] = 380 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 381 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 382 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 383 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 384 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 385 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 386 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 387 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 388 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 389 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 390 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 391 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 392 [wmi_vdev_oc_scheduler_air_time_limit] = 393 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 394 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 395 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 396 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 397 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 398 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 399 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 400 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 401 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 402 [wmi_vdev_param_disable_htprotection] = 403 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 404 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 405 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 406 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 407 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 408 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 409 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 410 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 411 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 412 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 413 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 414 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 415 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 416 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 417 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 418 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 419 [wmi_vdev_param_unknown_dest_indicate] = 420 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 421 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 422 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 423 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 424 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 425 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 426 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 427 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 428 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 429 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 430 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 431 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 432 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 433 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 434 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 435 [wmi_vdev_param_early_rx_adjust_enable] = 436 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 437 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 438 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 439 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 440 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 441 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 442 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 443 [wmi_vdev_param_early_rx_adjust_pause] = 444 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 445 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 446 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 447 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 448 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 449 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 450 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 451 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 452 [wmi_vdev_param_early_rx_drift_sample] = 453 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 454 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 455 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 456 [wmi_vdev_param_ebt_resync_timeout] = 457 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 458 [wmi_vdev_param_aggr_trig_event_enable] = 459 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 460 [wmi_vdev_param_is_ibss_power_save_allowed] = 461 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 462 [wmi_vdev_param_is_power_collapse_allowed] = 463 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 464 [wmi_vdev_param_is_awake_on_txrx_enabled] = 465 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 466 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 467 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 468 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 469 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 470 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 471 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 472 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 473 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 474 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 475 [wmi_vdev_param_stats_avg_factor] = 476 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 477 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 478 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 479 [wmi_vdev_param_mcc_rtscts_protection_enable] = 480 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 481 [wmi_vdev_param_mcc_broadcast_probe_enable] = 482 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 483 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 484 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 485 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 486 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 487 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 488 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 489 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 490 [wmi_vdev_param_set_he_sounding_mode] = 491 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 492 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 493 #ifdef WLAN_FEATURE_11BE 494 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 495 [wmi_vdev_param_set_eht_mu_mode] = WMI_VDEV_PARAM_SET_EHT_MU_MODE, 496 [wmi_vdev_param_set_eht_puncturing_mode] = 497 WMI_VDEV_PARAM_SET_EHT_PUNCTURING_MODE, 498 [wmi_vdev_param_set_eht_ltf] = WMI_VDEV_PARAM_EHT_LTF, 499 [wmi_vdev_param_set_ul_eht_ltf] = WMI_VDEV_PARAM_UL_EHT_LTF, 500 [wmi_vdev_param_set_eht_dcm] = WMI_VDEV_PARAM_EHT_DCM, 501 [wmi_vdev_param_set_eht_range_ext] = WMI_VDEV_PARAM_EHT_RANGE_EXT, 502 [wmi_vdev_param_set_non_data_eht_range_ext] = 503 WMI_VDEV_PARAM_NON_DATA_EHT_RANGE_EXT, 504 #endif 505 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 506 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 507 [wmi_vdev_param_atf_ssid_sched_policy] = 508 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 509 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 510 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 511 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 512 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 513 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 514 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 515 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 516 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 517 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 518 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 519 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 520 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 521 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 522 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 523 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 524 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 525 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 526 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 527 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 528 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 529 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 530 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 531 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 532 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 533 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 534 [wmi_vdev_param_mcast_rc_stale_period] = 535 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 536 [wmi_vdev_param_enable_multi_group_key] = 537 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 538 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 539 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 540 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 541 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 542 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 543 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 544 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 545 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 546 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 547 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 548 [wmi_vdev_param_nan_config_features] = 549 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 550 [wmi_vdev_param_enable_disable_rtt_responder_role] = 551 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 552 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 553 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 554 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 555 #ifdef MULTI_CLIENT_LL_SUPPORT 556 [wmi_vdev_param_set_normal_latency_flags_config] = 557 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 558 [wmi_vdev_param_set_xr_latency_flags_config] = 559 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 560 [wmi_vdev_param_set_low_latency_flags_config] = 561 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 562 [wmi_vdev_param_set_ultra_low_latency_flags_config] = 563 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 564 [wmi_vdev_param_set_normal_latency_ul_dl_config] = 565 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 566 [wmi_vdev_param_set_xr_latency_ul_dl_config] = 567 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 568 [wmi_vdev_param_set_low_latency_ul_dl_config] = 569 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 570 [wmi_vdev_param_set_ultra_low_latency_ul_dl_config] = 571 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 572 [wmi_vdev_param_set_default_ll_config] = 573 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 574 [wmi_vdev_param_set_multi_client_ll_feature_config] = 575 WMI_VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION, 576 #endif 577 [wmi_vdev_param_set_traffic_config] = 578 WMI_VDEV_PARAM_VDEV_TRAFFIC_CONFIG, 579 }; 580 #endif 581 582 #ifndef WMI_PKTLOG_EVENT_CBF 583 #define WMI_PKTLOG_EVENT_CBF 0x100 584 #endif 585 586 /** 587 * Populate the pktlog event tlv array, where 588 * the values are the FW WMI events, which host 589 * uses to communicate with FW for pktlog 590 */ 591 592 static const uint32_t pktlog_event_tlv[] = { 593 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 594 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 595 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 596 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 597 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 598 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 599 WMI_PKTLOG_EVENT_SMART_ANTENNA, 600 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 601 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 602 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 603 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 604 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 605 #ifdef BE_PKTLOG_SUPPORT 606 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 607 #endif 608 }; 609 610 /** 611 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 612 * host to target defines. 613 * @wmi_handle: pointer to wmi_handle 614 * @param pdev_id: host pdev_id to be converted. 615 * Return: target pdev_id after conversion. 616 */ 617 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 618 uint32_t pdev_id) 619 { 620 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 621 if (!wmi_handle->soc->is_pdev_is_map_enable) { 622 switch (pdev_id) { 623 case WMI_HOST_PDEV_ID_0: 624 return WMI_PDEV_ID_1ST; 625 case WMI_HOST_PDEV_ID_1: 626 return WMI_PDEV_ID_2ND; 627 case WMI_HOST_PDEV_ID_2: 628 return WMI_PDEV_ID_3RD; 629 } 630 } else { 631 return wmi_handle->cmd_pdev_id_map[pdev_id]; 632 } 633 } else { 634 return WMI_PDEV_ID_SOC; 635 } 636 637 QDF_ASSERT(0); 638 639 return WMI_PDEV_ID_SOC; 640 } 641 642 /** 643 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 644 * target to host defines. 645 * @wmi_handle: pointer to wmi_handle 646 * @param pdev_id: target pdev_id to be converted. 647 * Return: host pdev_id after conversion. 648 */ 649 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 650 uint32_t pdev_id) 651 { 652 653 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 654 if (!wmi_handle->soc->is_pdev_is_map_enable) { 655 switch (pdev_id) { 656 case WMI_PDEV_ID_1ST: 657 return WMI_HOST_PDEV_ID_0; 658 case WMI_PDEV_ID_2ND: 659 return WMI_HOST_PDEV_ID_1; 660 case WMI_PDEV_ID_3RD: 661 return WMI_HOST_PDEV_ID_2; 662 } 663 } else { 664 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 665 } 666 } else if (pdev_id == WMI_PDEV_ID_SOC) { 667 return WMI_HOST_PDEV_ID_SOC; 668 } else { 669 wmi_err("Invalid pdev_id"); 670 } 671 672 return WMI_HOST_PDEV_ID_INVALID; 673 } 674 675 /** 676 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 677 * host to target defines. 678 * @wmi_handle: pointer to wmi_handle 679 * @param phy_id: host pdev_id to be converted. 680 * Return: target phy_id after conversion. 681 */ 682 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 683 uint32_t phy_id) 684 { 685 if (!wmi_handle->soc->is_phy_id_map_enable || 686 phy_id >= WMI_MAX_RADIOS) { 687 return phy_id; 688 } 689 690 return wmi_handle->cmd_phy_id_map[phy_id]; 691 } 692 693 /** 694 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 695 * target to host defines. 696 * @wmi_handle: pointer to wmi_handle 697 * @param phy_id: target phy_id to be converted. 698 * Return: host phy_id after conversion. 699 */ 700 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 701 uint32_t phy_id) 702 { 703 if (!wmi_handle->soc->is_phy_id_map_enable || 704 phy_id >= WMI_MAX_RADIOS) { 705 return phy_id; 706 } 707 708 return wmi_handle->evt_phy_id_map[phy_id]; 709 } 710 711 /** 712 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 713 * 714 * Return None. 715 */ 716 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 717 uint32_t *pdev_id_map, 718 uint8_t size) 719 { 720 int i = 0; 721 722 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 723 for (i = 0; i < size; i++) { 724 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 725 wmi_handle->evt_pdev_id_map[i] = 726 WMI_HOST_PDEV_ID_INVALID; 727 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 728 wmi_handle->evt_phy_id_map[i] = 729 WMI_HOST_PDEV_ID_INVALID; 730 } 731 732 for (i = 0; i < size; i++) { 733 if (wmi_handle->cmd_pdev_id_map[i] != 734 WMI_HOST_PDEV_ID_INVALID) { 735 wmi_handle->evt_pdev_id_map 736 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 737 } 738 if (wmi_handle->cmd_phy_id_map[i] != 739 WMI_HOST_PDEV_ID_INVALID) { 740 wmi_handle->evt_phy_id_map 741 [wmi_handle->cmd_phy_id_map[i]] = i; 742 } 743 } 744 wmi_handle->soc->is_pdev_is_map_enable = true; 745 wmi_handle->soc->is_phy_id_map_enable = true; 746 } else { 747 wmi_handle->soc->is_pdev_is_map_enable = false; 748 wmi_handle->soc->is_phy_id_map_enable = false; 749 } 750 751 wmi_handle->ops->convert_pdev_id_host_to_target = 752 convert_host_pdev_id_to_target_pdev_id; 753 wmi_handle->ops->convert_pdev_id_target_to_host = 754 convert_target_pdev_id_to_host_pdev_id; 755 756 /* phy_id convert function assignments */ 757 wmi_handle->ops->convert_phy_id_host_to_target = 758 convert_host_phy_id_to_target_phy_id; 759 wmi_handle->ops->convert_phy_id_target_to_host = 760 convert_target_phy_id_to_host_phy_id; 761 } 762 763 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 764 * buffer. 765 * @wmi_handle: pointer to wmi_handle 766 * @cmd: pointer target vdev create command buffer 767 * @param: pointer host params for vdev create 768 * 769 * Return: None 770 */ 771 static inline void copy_vdev_create_pdev_id( 772 struct wmi_unified *wmi_handle, 773 wmi_vdev_create_cmd_fixed_param * cmd, 774 struct vdev_create_params *param) 775 { 776 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 777 wmi_handle, 778 param->pdev_id); 779 } 780 781 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 782 { 783 uint16_t mtrace_message_id; 784 785 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 786 (QDF_WMI_MTRACE_GRP_ID(message_id) << 787 QDF_WMI_MTRACE_CMD_NUM_BITS); 788 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 789 mtrace_message_id, vdev_id, data); 790 } 791 qdf_export_symbol(wmi_mtrace); 792 793 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 794 wmi_buf_t buf, 795 uint32_t buflen, uint32_t cmd_id, 796 bool is_qmi_send_support) 797 { 798 if (!is_qmi_send_support) 799 goto send_over_wmi; 800 801 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 802 goto send_over_wmi; 803 804 if (wmi_is_target_suspend_acked(wmi_handle)) { 805 if (QDF_IS_STATUS_SUCCESS( 806 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 807 buflen, cmd_id))) 808 return QDF_STATUS_SUCCESS; 809 } 810 811 send_over_wmi: 812 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 813 814 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 815 } 816 817 /** 818 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 819 * @wmi_handle: wmi handle 820 * @param: pointer to hold vdev create parameter 821 * @macaddr: vdev mac address 822 * 823 * Return: QDF_STATUS_SUCCESS for success or error code 824 */ 825 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 826 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 827 struct vdev_create_params *param) 828 { 829 wmi_vdev_create_cmd_fixed_param *cmd; 830 wmi_buf_t buf; 831 int32_t len = sizeof(*cmd); 832 QDF_STATUS ret; 833 int num_bands = 2; 834 uint8_t *buf_ptr; 835 wmi_vdev_txrx_streams *txrx_streams; 836 837 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 838 len += vdev_create_mlo_params_size(param); 839 840 buf = wmi_buf_alloc(wmi_handle, len); 841 if (!buf) 842 return QDF_STATUS_E_NOMEM; 843 844 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 845 WMITLV_SET_HDR(&cmd->tlv_header, 846 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 847 WMITLV_GET_STRUCT_TLVLEN 848 (wmi_vdev_create_cmd_fixed_param)); 849 cmd->vdev_id = param->vdev_id; 850 cmd->vdev_type = param->type; 851 cmd->vdev_subtype = param->subtype; 852 cmd->flags = param->mbssid_flags; 853 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 854 cmd->vdevid_trans = param->vdevid_trans; 855 cmd->num_cfg_txrx_streams = num_bands; 856 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 857 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 858 cmd->vdev_stats_id = param->vdev_stats_id; 859 #endif 860 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 861 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 862 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 863 param->vdev_id, cmd->pdev_id, 864 QDF_MAC_ADDR_REF(macaddr)); 865 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 866 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 867 (num_bands * sizeof(wmi_vdev_txrx_streams))); 868 buf_ptr += WMI_TLV_HDR_SIZE; 869 870 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 871 param->type, param->subtype, 872 param->nss_2g, param->nss_5g); 873 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 874 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 875 txrx_streams->supported_tx_streams = param->nss_2g; 876 txrx_streams->supported_rx_streams = param->nss_2g; 877 WMITLV_SET_HDR(&txrx_streams->tlv_header, 878 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 879 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 880 881 txrx_streams++; 882 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 883 txrx_streams->supported_tx_streams = param->nss_5g; 884 txrx_streams->supported_rx_streams = param->nss_5g; 885 WMITLV_SET_HDR(&txrx_streams->tlv_header, 886 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 887 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 888 889 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 890 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 891 892 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 893 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 894 if (QDF_IS_STATUS_ERROR(ret)) { 895 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 896 wmi_buf_free(buf); 897 } 898 899 return ret; 900 } 901 902 /** 903 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 904 * @wmi_handle: wmi handle 905 * @if_id: vdev id 906 * 907 * Return: QDF_STATUS_SUCCESS for success or error code 908 */ 909 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 910 uint8_t if_id) 911 { 912 wmi_vdev_delete_cmd_fixed_param *cmd; 913 wmi_buf_t buf; 914 QDF_STATUS ret; 915 916 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 917 if (!buf) 918 return QDF_STATUS_E_NOMEM; 919 920 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 921 WMITLV_SET_HDR(&cmd->tlv_header, 922 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 923 WMITLV_GET_STRUCT_TLVLEN 924 (wmi_vdev_delete_cmd_fixed_param)); 925 cmd->vdev_id = if_id; 926 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 927 ret = wmi_unified_cmd_send(wmi_handle, buf, 928 sizeof(wmi_vdev_delete_cmd_fixed_param), 929 WMI_VDEV_DELETE_CMDID); 930 if (QDF_IS_STATUS_ERROR(ret)) { 931 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 932 wmi_buf_free(buf); 933 } 934 wmi_debug("vdev id = %d", if_id); 935 936 return ret; 937 } 938 939 /** 940 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 941 * @wmi_handle: wmi handle 942 * @vdev_id: vdev id 943 * @nss_chains_user_cfg: user configured nss chain params 944 * 945 * Return: QDF_STATUS_SUCCESS for success or error code 946 */ 947 static QDF_STATUS 948 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 949 uint8_t vdev_id, 950 struct vdev_nss_chains *user_cfg) 951 { 952 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 953 wmi_buf_t buf; 954 QDF_STATUS ret; 955 956 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 957 if (!buf) 958 return QDF_STATUS_E_NOMEM; 959 960 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 961 WMITLV_SET_HDR(&cmd->tlv_header, 962 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 963 WMITLV_GET_STRUCT_TLVLEN 964 (wmi_vdev_chainmask_config_cmd_fixed_param)); 965 cmd->vdev_id = vdev_id; 966 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 967 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 968 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 969 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 970 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 971 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 972 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 973 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 974 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 975 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 976 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 977 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 978 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 979 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 980 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 981 982 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 983 ret = wmi_unified_cmd_send(wmi_handle, buf, 984 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 985 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 986 if (QDF_IS_STATUS_ERROR(ret)) { 987 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 988 wmi_buf_free(buf); 989 } 990 wmi_debug("vdev_id %d", vdev_id); 991 992 return ret; 993 } 994 995 /** 996 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 997 * @wmi: wmi handle 998 * @vdev_id: vdev id 999 * 1000 * Return: QDF_STATUS_SUCCESS for success or erro code 1001 */ 1002 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1003 uint8_t vdev_id) 1004 { 1005 wmi_vdev_stop_cmd_fixed_param *cmd; 1006 wmi_buf_t buf; 1007 int32_t len = sizeof(*cmd); 1008 1009 buf = wmi_buf_alloc(wmi, len); 1010 if (!buf) 1011 return QDF_STATUS_E_NOMEM; 1012 1013 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1014 WMITLV_SET_HDR(&cmd->tlv_header, 1015 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1016 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1017 cmd->vdev_id = vdev_id; 1018 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1019 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1020 wmi_err("Failed to send vdev stop command"); 1021 wmi_buf_free(buf); 1022 return QDF_STATUS_E_FAILURE; 1023 } 1024 wmi_debug("vdev id = %d", vdev_id); 1025 1026 return 0; 1027 } 1028 1029 /** 1030 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1031 * @wmi: wmi handle 1032 * @vdev_id: vdev id 1033 * 1034 * Return: QDF_STATUS_SUCCESS for success or error code 1035 */ 1036 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1037 { 1038 wmi_vdev_down_cmd_fixed_param *cmd; 1039 wmi_buf_t buf; 1040 int32_t len = sizeof(*cmd); 1041 1042 buf = wmi_buf_alloc(wmi, len); 1043 if (!buf) 1044 return QDF_STATUS_E_NOMEM; 1045 1046 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1047 WMITLV_SET_HDR(&cmd->tlv_header, 1048 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1049 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1050 cmd->vdev_id = vdev_id; 1051 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1052 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1053 wmi_err("Failed to send vdev down"); 1054 wmi_buf_free(buf); 1055 return QDF_STATUS_E_FAILURE; 1056 } 1057 wmi_debug("vdev_id %d", vdev_id); 1058 1059 return 0; 1060 } 1061 1062 static inline void copy_channel_info( 1063 wmi_vdev_start_request_cmd_fixed_param * cmd, 1064 wmi_channel *chan, 1065 struct vdev_start_params *req) 1066 { 1067 chan->mhz = req->channel.mhz; 1068 1069 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1070 1071 chan->band_center_freq1 = req->channel.cfreq1; 1072 chan->band_center_freq2 = req->channel.cfreq2; 1073 1074 if (req->channel.half_rate) 1075 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1076 else if (req->channel.quarter_rate) 1077 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1078 1079 if (req->channel.dfs_set) { 1080 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1081 cmd->disable_hw_ack = req->disable_hw_ack; 1082 } 1083 1084 if (req->channel.dfs_set_cfreq2) 1085 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1086 1087 if (req->channel.is_stadfs_en) 1088 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1089 1090 /* According to firmware both reg power and max tx power 1091 * on set channel power is used and set it to max reg 1092 * power from regulatory. 1093 */ 1094 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1095 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1096 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1097 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1098 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1099 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1100 1101 } 1102 1103 /** 1104 * vdev_start_cmd_fill_11be() - 11be information fiiling in vdev_ststart 1105 * @cmd: wmi cmd 1106 * @req: vdev start params 1107 * 1108 * Return: QDF status 1109 */ 1110 #ifdef WLAN_FEATURE_11BE 1111 static void 1112 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1113 struct vdev_start_params *req) 1114 { 1115 cmd->eht_ops = req->eht_ops; 1116 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1117 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1118 req->eht_ops, req->channel.puncture_bitmap, 1119 cmd->puncture_20mhz_bitmap); 1120 } 1121 #else 1122 static void 1123 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1124 struct vdev_start_params *req) 1125 { 1126 } 1127 #endif 1128 1129 /** 1130 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1131 * @wmi_handle: wmi handle 1132 * @req: vdev start params 1133 * 1134 * Return: QDF status 1135 */ 1136 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1137 struct vdev_start_params *req) 1138 { 1139 wmi_vdev_start_request_cmd_fixed_param *cmd; 1140 wmi_buf_t buf; 1141 wmi_channel *chan; 1142 int32_t len, ret; 1143 uint8_t *buf_ptr; 1144 1145 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1146 if (!req->is_restart) 1147 len += vdev_start_mlo_params_size(req); 1148 buf = wmi_buf_alloc(wmi_handle, len); 1149 if (!buf) 1150 return QDF_STATUS_E_NOMEM; 1151 1152 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1153 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1154 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1155 WMITLV_SET_HDR(&cmd->tlv_header, 1156 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1157 WMITLV_GET_STRUCT_TLVLEN 1158 (wmi_vdev_start_request_cmd_fixed_param)); 1159 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1160 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1161 cmd->vdev_id = req->vdev_id; 1162 1163 /* Fill channel info */ 1164 copy_channel_info(cmd, chan, req); 1165 cmd->beacon_interval = req->beacon_interval; 1166 cmd->dtim_period = req->dtim_period; 1167 1168 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1169 if (req->bcn_tx_rate_code) 1170 wmi_enable_bcn_ratecode(&cmd->flags); 1171 1172 if (!req->is_restart) { 1173 if (req->pmf_enabled) 1174 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1175 1176 cmd->mbss_capability_flags = req->mbssid_flags; 1177 cmd->vdevid_trans = req->vdevid_trans; 1178 } 1179 1180 /* Copy the SSID */ 1181 if (req->ssid.length) { 1182 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1183 cmd->ssid.ssid_len = req->ssid.length; 1184 else 1185 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1186 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1187 cmd->ssid.ssid_len); 1188 } 1189 1190 if (req->hidden_ssid) 1191 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1192 1193 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1194 cmd->num_noa_descriptors = req->num_noa_descriptors; 1195 cmd->preferred_rx_streams = req->preferred_rx_streams; 1196 cmd->preferred_tx_streams = req->preferred_tx_streams; 1197 cmd->cac_duration_ms = req->cac_duration_ms; 1198 cmd->regdomain = req->regdomain; 1199 cmd->he_ops = req->he_ops; 1200 1201 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1202 sizeof(wmi_channel)); 1203 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1204 cmd->num_noa_descriptors * 1205 sizeof(wmi_p2p_noa_descriptor)); 1206 if (!req->is_restart) { 1207 buf_ptr += WMI_TLV_HDR_SIZE + 1208 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1209 1210 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1211 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1212 } 1213 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1214 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1215 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1216 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1217 "req->dis_hw_ack: %d ", req->vdev_id, 1218 chan->mhz, req->channel.phy_mode, chan->info, 1219 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1220 chan->band_center_freq1, chan->band_center_freq2, 1221 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1222 req->preferred_tx_streams, req->preferred_rx_streams, 1223 req->ldpc_rx_enabled, req->cac_duration_ms, 1224 req->regdomain, req->he_ops, 1225 req->disable_hw_ack); 1226 1227 vdev_start_cmd_fill_11be(cmd, req); 1228 1229 if (req->is_restart) { 1230 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1231 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1232 WMI_VDEV_RESTART_REQUEST_CMDID); 1233 } else { 1234 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1235 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1236 WMI_VDEV_START_REQUEST_CMDID); 1237 } 1238 if (ret) { 1239 wmi_err("Failed to send vdev start command"); 1240 wmi_buf_free(buf); 1241 return QDF_STATUS_E_FAILURE; 1242 } 1243 1244 return QDF_STATUS_SUCCESS; 1245 } 1246 1247 /** 1248 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1249 * @wmi: wmi handle 1250 * @peer_addr: peer mac address 1251 * @param: pointer to hold peer flush tid parameter 1252 * 1253 * Return: 0 for success or error code 1254 */ 1255 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1256 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1257 struct peer_flush_params *param) 1258 { 1259 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1260 wmi_buf_t buf; 1261 int32_t len = sizeof(*cmd); 1262 1263 buf = wmi_buf_alloc(wmi, len); 1264 if (!buf) 1265 return QDF_STATUS_E_NOMEM; 1266 1267 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1268 WMITLV_SET_HDR(&cmd->tlv_header, 1269 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1270 WMITLV_GET_STRUCT_TLVLEN 1271 (wmi_peer_flush_tids_cmd_fixed_param)); 1272 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1273 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1274 cmd->vdev_id = param->vdev_id; 1275 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1276 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1277 param->peer_tid_bitmap); 1278 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1279 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1280 wmi_err("Failed to send flush tid command"); 1281 wmi_buf_free(buf); 1282 return QDF_STATUS_E_FAILURE; 1283 } 1284 1285 return 0; 1286 } 1287 1288 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1289 /** 1290 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1291 * @policy: The target i/f flush policy value 1292 * 1293 * Return: WMI layer flush policy 1294 */ 1295 static wmi_peer_flush_policy 1296 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1297 { 1298 switch (policy) { 1299 case PEER_TXQ_FLUSH_POLICY_NONE: 1300 return WMI_NO_FLUSH; 1301 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1302 return WMI_TWT_FLUSH; 1303 default: 1304 return WMI_MAX_FLUSH_POLICY; 1305 } 1306 } 1307 1308 /** 1309 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1310 * @wmi: wmi handle 1311 * @para: Peer txq flush configuration 1312 * 1313 * Return: QDF status 1314 */ 1315 static QDF_STATUS 1316 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1317 struct peer_txq_flush_config_params *param) 1318 { 1319 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1320 wmi_buf_t buf; 1321 int32_t len = sizeof(*cmd); 1322 1323 buf = wmi_buf_alloc(wmi, len); 1324 if (!buf) 1325 return QDF_STATUS_E_NOMEM; 1326 1327 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1328 1329 WMITLV_SET_HDR(&cmd->tlv_header, 1330 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1331 WMITLV_GET_STRUCT_TLVLEN 1332 (wmi_peer_flush_policy_cmd_fixed_param)); 1333 1334 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1335 cmd->peer_tid_bitmap = param->tid_mask; 1336 cmd->vdev_id = param->vdev_id; 1337 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1338 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1339 wmi_buf_free(buf); 1340 wmi_err("Invalid policy"); 1341 return QDF_STATUS_E_INVAL; 1342 } 1343 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1344 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1345 param->tid_mask, param->policy); 1346 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1347 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1348 wmi_err("Failed to send flush policy command"); 1349 wmi_buf_free(buf); 1350 return QDF_STATUS_E_FAILURE; 1351 } 1352 1353 return QDF_STATUS_SUCCESS; 1354 } 1355 #endif 1356 /** 1357 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1358 * @wmi: wmi handle 1359 * @peer_addr: peer mac addr 1360 * @param: peer delete parameters 1361 * 1362 * Return: QDF_STATUS_SUCCESS for success or error code 1363 */ 1364 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1365 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1366 struct peer_delete_cmd_params *param) 1367 { 1368 wmi_peer_delete_cmd_fixed_param *cmd; 1369 wmi_buf_t buf; 1370 int32_t len = sizeof(*cmd); 1371 uint8_t *buf_ptr; 1372 1373 len += peer_delete_mlo_params_size(param); 1374 buf = wmi_buf_alloc(wmi, len); 1375 if (!buf) 1376 return QDF_STATUS_E_NOMEM; 1377 1378 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1379 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1380 WMITLV_SET_HDR(&cmd->tlv_header, 1381 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1382 WMITLV_GET_STRUCT_TLVLEN 1383 (wmi_peer_delete_cmd_fixed_param)); 1384 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1385 cmd->vdev_id = param->vdev_id; 1386 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1387 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1388 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1389 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1390 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1391 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1392 wmi_err("Failed to send peer delete command"); 1393 wmi_buf_free(buf); 1394 return QDF_STATUS_E_FAILURE; 1395 } 1396 return 0; 1397 } 1398 1399 static void 1400 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1401 { 1402 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1403 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1404 WMI_PEER_TYPE_DEFAULT); 1405 1406 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1407 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1408 WMI_PEER_TYPE_BSS); 1409 1410 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1411 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1412 WMI_PEER_TYPE_TDLS); 1413 1414 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1415 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1416 WMI_PEER_TYPE_NAN_DATA); 1417 1418 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1419 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1420 WMI_PEER_TYPE_PASN); 1421 } 1422 1423 /** 1424 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1425 * @wmi: wmi handle 1426 * @param: pointer to hold peer delete all parameter 1427 * 1428 * Return: QDF_STATUS_SUCCESS for success or error code 1429 */ 1430 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1431 wmi_unified_t wmi, 1432 struct peer_delete_all_params *param) 1433 { 1434 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1435 wmi_buf_t buf; 1436 int32_t len = sizeof(*cmd); 1437 1438 buf = wmi_buf_alloc(wmi, len); 1439 if (!buf) 1440 return QDF_STATUS_E_NOMEM; 1441 1442 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1443 WMITLV_SET_HDR( 1444 &cmd->tlv_header, 1445 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1446 WMITLV_GET_STRUCT_TLVLEN 1447 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1448 cmd->vdev_id = param->vdev_id; 1449 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1450 cmd->peer_type_bitmap); 1451 1452 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1453 param->peer_type_bitmap); 1454 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1455 if (wmi_unified_cmd_send(wmi, buf, len, 1456 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1457 wmi_err("Failed to send peer del all command"); 1458 wmi_buf_free(buf); 1459 return QDF_STATUS_E_FAILURE; 1460 } 1461 1462 return QDF_STATUS_SUCCESS; 1463 } 1464 1465 /** 1466 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1467 * to target id. 1468 * @peer_param_id: host param id. 1469 * 1470 * Return: Target param id. 1471 */ 1472 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1473 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1474 uint32_t peer_param_id) 1475 { 1476 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1477 return peer_param_tlv[peer_param_id]; 1478 return WMI_UNAVAILABLE_PARAM; 1479 } 1480 #else 1481 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1482 uint32_t peer_param_id) 1483 { 1484 return peer_param_id; 1485 } 1486 #endif 1487 1488 #ifdef WLAN_SUPPORT_PPEDS 1489 /** 1490 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1491 * @wmi: wmi handle 1492 * @param: pointer to hold PPE DS config 1493 * 1494 * Return: QDF_STATUS_SUCCESS for success or error code 1495 */ 1496 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1497 struct peer_ppe_ds_param *param) 1498 { 1499 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1500 wmi_buf_t buf; 1501 int32_t err; 1502 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1503 1504 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1505 if (!buf) 1506 return QDF_STATUS_E_NOMEM; 1507 1508 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1509 WMITLV_SET_HDR(&cmd->tlv_header, 1510 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1511 WMITLV_GET_STRUCT_TLVLEN 1512 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1513 1514 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1515 1516 if (param->ppe_routing_enabled) 1517 cmd->ppe_routing_enable = param->use_ppe ? 1518 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1519 else 1520 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1521 1522 cmd->service_code = param->service_code; 1523 cmd->priority_valid = param->priority_valid; 1524 cmd->src_info = param->src_info; 1525 cmd->vdev_id = param->vdev_id; 1526 1527 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1528 "ppe_routing_enable: %u service_code: %u\n" 1529 "priority_valid:%d src_info:%u", 1530 param->vdev_id, 1531 QDF_MAC_ADDR_REF(param->peer_macaddr), 1532 param->ppe_routing_enabled, 1533 param->service_code, 1534 param->priority_valid, 1535 param->src_info); 1536 1537 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1538 err = wmi_unified_cmd_send(wmi, buf, 1539 len, 1540 WMI_PEER_CONFIG_PPE_DS_CMDID); 1541 if (err) { 1542 wmi_err("Failed to send ppeds config cmd"); 1543 wmi_buf_free(buf); 1544 return QDF_STATUS_E_FAILURE; 1545 } 1546 1547 return 0; 1548 } 1549 #endif /* WLAN_SUPPORT_PPEDS */ 1550 1551 /** 1552 * send_peer_param_cmd_tlv() - set peer parameter in fw 1553 * @wmi: wmi handle 1554 * @peer_addr: peer mac address 1555 * @param : pointer to hold peer set parameter 1556 * 1557 * Return: QDF_STATUS_SUCCESS for success or error code 1558 */ 1559 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1560 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1561 struct peer_set_params *param) 1562 { 1563 wmi_peer_set_param_cmd_fixed_param *cmd; 1564 wmi_buf_t buf; 1565 int32_t err; 1566 uint32_t param_id; 1567 1568 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1569 if (param_id == WMI_UNAVAILABLE_PARAM) { 1570 wmi_err("Unavailable param %d", param->param_id); 1571 return QDF_STATUS_E_NOSUPPORT; 1572 } 1573 1574 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1575 if (!buf) 1576 return QDF_STATUS_E_NOMEM; 1577 1578 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1579 WMITLV_SET_HDR(&cmd->tlv_header, 1580 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1581 WMITLV_GET_STRUCT_TLVLEN 1582 (wmi_peer_set_param_cmd_fixed_param)); 1583 cmd->vdev_id = param->vdev_id; 1584 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1585 cmd->param_id = param_id; 1586 cmd->param_value = param->param_value; 1587 1588 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1589 cmd->vdev_id, 1590 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1591 cmd->param_value); 1592 1593 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1594 err = wmi_unified_cmd_send(wmi, buf, 1595 sizeof(wmi_peer_set_param_cmd_fixed_param), 1596 WMI_PEER_SET_PARAM_CMDID); 1597 if (err) { 1598 wmi_err("Failed to send set_param cmd"); 1599 wmi_buf_free(buf); 1600 return QDF_STATUS_E_FAILURE; 1601 } 1602 1603 return 0; 1604 } 1605 1606 /** 1607 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1608 * @wmi: wmi handle 1609 * @bssid: bssid 1610 * @vdev_up_params: pointer to hold vdev up parameter 1611 * 1612 * Return: QDF_STATUS_SUCCESS for success or error code 1613 */ 1614 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1615 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1616 struct vdev_up_params *params) 1617 { 1618 wmi_vdev_up_cmd_fixed_param *cmd; 1619 wmi_buf_t buf; 1620 int32_t len = sizeof(*cmd); 1621 1622 wmi_debug("VDEV_UP"); 1623 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1624 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1625 buf = wmi_buf_alloc(wmi, len); 1626 if (!buf) 1627 return QDF_STATUS_E_NOMEM; 1628 1629 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1630 WMITLV_SET_HDR(&cmd->tlv_header, 1631 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1632 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1633 cmd->vdev_id = params->vdev_id; 1634 cmd->vdev_assoc_id = params->assoc_id; 1635 cmd->profile_idx = params->profile_idx; 1636 cmd->profile_num = params->profile_num; 1637 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1638 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1639 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1640 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1641 wmi_err("Failed to send vdev up command"); 1642 wmi_buf_free(buf); 1643 return QDF_STATUS_E_FAILURE; 1644 } 1645 1646 return 0; 1647 } 1648 1649 /** 1650 * send_peer_create_cmd_tlv() - send peer create command to fw 1651 * @wmi: wmi handle 1652 * @peer_addr: peer mac address 1653 * @peer_type: peer type 1654 * @vdev_id: vdev id 1655 * 1656 * Return: QDF_STATUS_SUCCESS for success or error code 1657 */ 1658 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1659 struct peer_create_params *param) 1660 { 1661 wmi_peer_create_cmd_fixed_param *cmd; 1662 wmi_buf_t buf; 1663 uint8_t *buf_ptr; 1664 int32_t len = sizeof(*cmd); 1665 1666 len += peer_create_mlo_params_size(param); 1667 buf = wmi_buf_alloc(wmi, len); 1668 if (!buf) 1669 return QDF_STATUS_E_NOMEM; 1670 1671 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1672 WMITLV_SET_HDR(&cmd->tlv_header, 1673 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1674 WMITLV_GET_STRUCT_TLVLEN 1675 (wmi_peer_create_cmd_fixed_param)); 1676 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1677 cmd->peer_type = param->peer_type; 1678 cmd->vdev_id = param->vdev_id; 1679 1680 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1681 buf_ptr += sizeof(*cmd); 1682 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1683 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1684 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1685 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1686 wmi_buf_free(buf); 1687 return QDF_STATUS_E_FAILURE; 1688 } 1689 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1690 QDF_MAC_ADDR_REF(param->peer_addr), 1691 param->vdev_id); 1692 1693 return 0; 1694 } 1695 1696 /** 1697 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1698 * command to fw 1699 * @wmi: wmi handle 1700 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1701 * 1702 * Return: 0 for success or error code 1703 */ 1704 static 1705 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1706 struct rx_reorder_queue_setup_params *param) 1707 { 1708 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1709 wmi_buf_t buf; 1710 int32_t len = sizeof(*cmd); 1711 1712 buf = wmi_buf_alloc(wmi, len); 1713 if (!buf) 1714 return QDF_STATUS_E_NOMEM; 1715 1716 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1717 WMITLV_SET_HDR(&cmd->tlv_header, 1718 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1719 WMITLV_GET_STRUCT_TLVLEN 1720 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1721 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1722 cmd->vdev_id = param->vdev_id; 1723 cmd->tid = param->tid; 1724 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1725 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1726 cmd->queue_no = param->queue_no; 1727 cmd->ba_window_size_valid = param->ba_window_size_valid; 1728 cmd->ba_window_size = param->ba_window_size; 1729 1730 1731 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1732 if (wmi_unified_cmd_send(wmi, buf, len, 1733 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1734 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1735 wmi_buf_free(buf); 1736 return QDF_STATUS_E_FAILURE; 1737 } 1738 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1739 QDF_MAC_ADDR_REF(param->peer_macaddr), 1740 param->vdev_id, param->tid); 1741 1742 return QDF_STATUS_SUCCESS; 1743 } 1744 1745 /** 1746 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1747 * command to fw 1748 * @wmi: wmi handle 1749 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1750 * 1751 * Return: 0 for success or error code 1752 */ 1753 static 1754 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1755 struct rx_reorder_queue_remove_params *param) 1756 { 1757 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1758 wmi_buf_t buf; 1759 int32_t len = sizeof(*cmd); 1760 1761 buf = wmi_buf_alloc(wmi, len); 1762 if (!buf) 1763 return QDF_STATUS_E_NOMEM; 1764 1765 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1766 wmi_buf_data(buf); 1767 WMITLV_SET_HDR(&cmd->tlv_header, 1768 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1769 WMITLV_GET_STRUCT_TLVLEN 1770 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1771 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1772 cmd->vdev_id = param->vdev_id; 1773 cmd->tid_mask = param->peer_tid_bitmap; 1774 1775 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1776 if (wmi_unified_cmd_send(wmi, buf, len, 1777 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1778 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1779 wmi_buf_free(buf); 1780 return QDF_STATUS_E_FAILURE; 1781 } 1782 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1783 QDF_MAC_ADDR_REF(param->peer_macaddr), 1784 param->vdev_id, param->peer_tid_bitmap); 1785 1786 return QDF_STATUS_SUCCESS; 1787 } 1788 1789 #ifdef WLAN_SUPPORT_GREEN_AP 1790 /** 1791 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1792 * @wmi_handle: wmi handle 1793 * @value: value 1794 * @pdev_id: pdev id to have radio context 1795 * 1796 * Return: QDF_STATUS_SUCCESS for success or error code 1797 */ 1798 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1799 uint32_t value, uint8_t pdev_id) 1800 { 1801 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1802 wmi_buf_t buf; 1803 int32_t len = sizeof(*cmd); 1804 1805 wmi_debug("Set Green AP PS val %d", value); 1806 1807 buf = wmi_buf_alloc(wmi_handle, len); 1808 if (!buf) 1809 return QDF_STATUS_E_NOMEM; 1810 1811 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1812 WMITLV_SET_HDR(&cmd->tlv_header, 1813 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1814 WMITLV_GET_STRUCT_TLVLEN 1815 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1816 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1817 wmi_handle, 1818 pdev_id); 1819 cmd->enable = value; 1820 1821 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1822 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1823 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1824 wmi_err("Set Green AP PS param Failed val %d", value); 1825 wmi_buf_free(buf); 1826 return QDF_STATUS_E_FAILURE; 1827 } 1828 1829 return 0; 1830 } 1831 #endif 1832 1833 /** 1834 * send_pdev_utf_cmd_tlv() - send utf command to fw 1835 * @wmi_handle: wmi handle 1836 * @param: pointer to pdev_utf_params 1837 * @mac_id: mac id to have radio context 1838 * 1839 * Return: QDF_STATUS_SUCCESS for success or error code 1840 */ 1841 static QDF_STATUS 1842 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1843 struct pdev_utf_params *param, 1844 uint8_t mac_id) 1845 { 1846 wmi_buf_t buf; 1847 uint8_t *cmd; 1848 /* if param->len is 0 no data is sent, return error */ 1849 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1850 static uint8_t msgref = 1; 1851 uint8_t segNumber = 0, segInfo, numSegments; 1852 uint16_t chunk_len, total_bytes; 1853 uint8_t *bufpos; 1854 struct seg_hdr_info segHdrInfo; 1855 1856 bufpos = param->utf_payload; 1857 total_bytes = param->len; 1858 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1859 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1860 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1861 1862 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1863 numSegments++; 1864 1865 while (param->len) { 1866 if (param->len > MAX_WMI_UTF_LEN) 1867 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1868 else 1869 chunk_len = param->len; 1870 1871 buf = wmi_buf_alloc(wmi_handle, 1872 (chunk_len + sizeof(segHdrInfo) + 1873 WMI_TLV_HDR_SIZE)); 1874 if (!buf) 1875 return QDF_STATUS_E_NOMEM; 1876 1877 cmd = (uint8_t *) wmi_buf_data(buf); 1878 1879 segHdrInfo.len = total_bytes; 1880 segHdrInfo.msgref = msgref; 1881 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1882 segHdrInfo.segmentInfo = segInfo; 1883 segHdrInfo.pad = 0; 1884 1885 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1886 " segHdrInfo.segmentInfo = %d", 1887 segHdrInfo.len, segHdrInfo.msgref, 1888 segHdrInfo.segmentInfo); 1889 1890 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 1891 " chunk len %d", total_bytes, segNumber, 1892 numSegments, chunk_len); 1893 1894 segNumber++; 1895 1896 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1897 (chunk_len + sizeof(segHdrInfo))); 1898 cmd += WMI_TLV_HDR_SIZE; 1899 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1900 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 1901 bufpos, chunk_len); 1902 1903 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1904 ret = wmi_unified_cmd_send(wmi_handle, buf, 1905 (chunk_len + sizeof(segHdrInfo) + 1906 WMI_TLV_HDR_SIZE), 1907 WMI_PDEV_UTF_CMDID); 1908 1909 if (QDF_IS_STATUS_ERROR(ret)) { 1910 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 1911 wmi_buf_free(buf); 1912 break; 1913 } 1914 1915 param->len -= chunk_len; 1916 bufpos += chunk_len; 1917 } 1918 1919 msgref++; 1920 1921 return ret; 1922 } 1923 1924 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1925 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1926 { 1927 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1928 return pdev_param_tlv[host_param]; 1929 return WMI_UNAVAILABLE_PARAM; 1930 } 1931 #else 1932 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1933 { 1934 return host_param; 1935 } 1936 #endif 1937 1938 /** 1939 * send_pdev_param_cmd_tlv() - set pdev parameters 1940 * @wmi_handle: wmi handle 1941 * @param: pointer to pdev parameter 1942 * @mac_id: radio context 1943 * 1944 * Return: 0 on success, errno on failure 1945 */ 1946 static QDF_STATUS 1947 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1948 struct pdev_params *param, 1949 uint8_t mac_id) 1950 { 1951 QDF_STATUS ret; 1952 wmi_pdev_set_param_cmd_fixed_param *cmd; 1953 wmi_buf_t buf; 1954 uint16_t len = sizeof(*cmd); 1955 uint32_t pdev_param; 1956 1957 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1958 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1959 wmi_err("Unavailable param %d", param->param_id); 1960 return QDF_STATUS_E_INVAL; 1961 } 1962 1963 buf = wmi_buf_alloc(wmi_handle, len); 1964 if (!buf) 1965 return QDF_STATUS_E_NOMEM; 1966 1967 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1968 WMITLV_SET_HDR(&cmd->tlv_header, 1969 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1970 WMITLV_GET_STRUCT_TLVLEN 1971 (wmi_pdev_set_param_cmd_fixed_param)); 1972 if (param->is_host_pdev_id) 1973 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1974 wmi_handle, 1975 mac_id); 1976 else 1977 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1978 wmi_handle, 1979 mac_id); 1980 cmd->param_id = pdev_param; 1981 cmd->param_value = param->param_value; 1982 wmi_debug("Setting pdev param = %x, value = %u", param->param_id, 1983 param->param_value); 1984 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1985 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1986 WMI_PDEV_SET_PARAM_CMDID); 1987 if (QDF_IS_STATUS_ERROR(ret)) { 1988 wmi_err("Failed to send set param command ret = %d", ret); 1989 wmi_buf_free(buf); 1990 } 1991 return ret; 1992 } 1993 1994 /** 1995 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1996 * @wmi_handle: wmi handle 1997 * @msg: Structure containing the following parameters 1998 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1999 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2000 * 2001 * Provides notification to the WLAN firmware that host driver is requesting a 2002 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2003 * configurations that include the Dual Band Simultaneous (DBS) feature. 2004 * 2005 * Return: Success if the cmd is sent successfully to the firmware 2006 */ 2007 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2008 uint32_t hw_mode_index) 2009 { 2010 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2011 wmi_buf_t buf; 2012 uint32_t len; 2013 2014 len = sizeof(*cmd); 2015 2016 buf = wmi_buf_alloc(wmi_handle, len); 2017 if (!buf) 2018 return QDF_STATUS_E_NOMEM; 2019 2020 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2021 WMITLV_SET_HDR(&cmd->tlv_header, 2022 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2023 WMITLV_GET_STRUCT_TLVLEN( 2024 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2025 2026 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2027 wmi_handle, 2028 WMI_HOST_PDEV_ID_SOC); 2029 cmd->hw_mode_index = hw_mode_index; 2030 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2031 2032 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2033 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2034 WMI_PDEV_SET_HW_MODE_CMDID)) { 2035 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2036 wmi_buf_free(buf); 2037 return QDF_STATUS_E_FAILURE; 2038 } 2039 2040 return QDF_STATUS_SUCCESS; 2041 } 2042 2043 /** 2044 * send_suspend_cmd_tlv() - WMI suspend function 2045 * @param wmi_handle : handle to WMI. 2046 * @param param : pointer to hold suspend parameter 2047 * @mac_id: radio context 2048 * 2049 * Return 0 on success and -ve on failure. 2050 */ 2051 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2052 struct suspend_params *param, 2053 uint8_t mac_id) 2054 { 2055 wmi_pdev_suspend_cmd_fixed_param *cmd; 2056 wmi_buf_t wmibuf; 2057 uint32_t len = sizeof(*cmd); 2058 int32_t ret; 2059 2060 /* 2061 * send the command to Target to ignore the 2062 * PCIE reset so as to ensure that Host and target 2063 * states are in sync 2064 */ 2065 wmibuf = wmi_buf_alloc(wmi_handle, len); 2066 if (!wmibuf) 2067 return QDF_STATUS_E_NOMEM; 2068 2069 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2070 WMITLV_SET_HDR(&cmd->tlv_header, 2071 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2072 WMITLV_GET_STRUCT_TLVLEN 2073 (wmi_pdev_suspend_cmd_fixed_param)); 2074 if (param->disable_target_intr) 2075 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2076 else 2077 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2078 2079 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2080 wmi_handle, 2081 mac_id); 2082 2083 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2084 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2085 WMI_PDEV_SUSPEND_CMDID); 2086 if (ret) { 2087 wmi_buf_free(wmibuf); 2088 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2089 } 2090 2091 return ret; 2092 } 2093 2094 /** 2095 * send_resume_cmd_tlv() - WMI resume function 2096 * @param wmi_handle : handle to WMI. 2097 * @mac_id: radio context 2098 * 2099 * Return: 0 on success and -ve on failure. 2100 */ 2101 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2102 uint8_t mac_id) 2103 { 2104 wmi_buf_t wmibuf; 2105 wmi_pdev_resume_cmd_fixed_param *cmd; 2106 QDF_STATUS ret; 2107 2108 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2109 if (!wmibuf) 2110 return QDF_STATUS_E_NOMEM; 2111 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2112 WMITLV_SET_HDR(&cmd->tlv_header, 2113 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2114 WMITLV_GET_STRUCT_TLVLEN 2115 (wmi_pdev_resume_cmd_fixed_param)); 2116 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2117 wmi_handle, 2118 mac_id); 2119 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2120 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2121 WMI_PDEV_RESUME_CMDID); 2122 if (QDF_IS_STATUS_ERROR(ret)) { 2123 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2124 wmi_buf_free(wmibuf); 2125 } 2126 2127 return ret; 2128 } 2129 2130 /** 2131 * send_wow_enable_cmd_tlv() - WMI wow enable function 2132 * @param wmi_handle : handle to WMI. 2133 * @param param : pointer to hold wow enable parameter 2134 * @mac_id: radio context 2135 * 2136 * Return: 0 on success and -ve on failure. 2137 */ 2138 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2139 struct wow_cmd_params *param, 2140 uint8_t mac_id) 2141 { 2142 wmi_wow_enable_cmd_fixed_param *cmd; 2143 wmi_buf_t buf; 2144 int32_t len; 2145 int32_t ret; 2146 2147 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2148 2149 buf = wmi_buf_alloc(wmi_handle, len); 2150 if (!buf) 2151 return QDF_STATUS_E_NOMEM; 2152 2153 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2154 WMITLV_SET_HDR(&cmd->tlv_header, 2155 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2156 WMITLV_GET_STRUCT_TLVLEN 2157 (wmi_wow_enable_cmd_fixed_param)); 2158 cmd->enable = param->enable; 2159 if (param->can_suspend_link) 2160 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2161 else 2162 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2163 cmd->flags = param->flags; 2164 2165 wmi_debug("suspend type: %s flag is 0x%x", 2166 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2167 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2168 cmd->flags); 2169 2170 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2171 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2172 WMI_WOW_ENABLE_CMDID); 2173 if (ret) 2174 wmi_buf_free(buf); 2175 2176 return ret; 2177 } 2178 2179 /** 2180 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2181 * @wmi_handle: wmi handle 2182 * @peer_addr: peer mac address 2183 * @param: pointer to ap_ps parameter structure 2184 * 2185 * Return: QDF_STATUS_SUCCESS for success or error code 2186 */ 2187 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2188 uint8_t *peer_addr, 2189 struct ap_ps_params *param) 2190 { 2191 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2192 wmi_buf_t buf; 2193 int32_t err; 2194 2195 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2196 if (!buf) 2197 return QDF_STATUS_E_NOMEM; 2198 2199 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2200 WMITLV_SET_HDR(&cmd->tlv_header, 2201 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2202 WMITLV_GET_STRUCT_TLVLEN 2203 (wmi_ap_ps_peer_cmd_fixed_param)); 2204 cmd->vdev_id = param->vdev_id; 2205 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2206 cmd->param = param->param; 2207 cmd->value = param->value; 2208 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2209 err = wmi_unified_cmd_send(wmi_handle, buf, 2210 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2211 if (err) { 2212 wmi_err("Failed to send set_ap_ps_param cmd"); 2213 wmi_buf_free(buf); 2214 return QDF_STATUS_E_FAILURE; 2215 } 2216 2217 return 0; 2218 } 2219 2220 /** 2221 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2222 * @wmi_handle: wmi handle 2223 * @peer_addr: peer mac address 2224 * @param: pointer to sta_ps parameter structure 2225 * 2226 * Return: QDF_STATUS_SUCCESS for success or error code 2227 */ 2228 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2229 struct sta_ps_params *param) 2230 { 2231 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2232 wmi_buf_t buf; 2233 int32_t len = sizeof(*cmd); 2234 2235 buf = wmi_buf_alloc(wmi_handle, len); 2236 if (!buf) 2237 return QDF_STATUS_E_NOMEM; 2238 2239 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2240 WMITLV_SET_HDR(&cmd->tlv_header, 2241 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2242 WMITLV_GET_STRUCT_TLVLEN 2243 (wmi_sta_powersave_param_cmd_fixed_param)); 2244 cmd->vdev_id = param->vdev_id; 2245 cmd->param = param->param_id; 2246 cmd->value = param->value; 2247 2248 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2249 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2250 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2251 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2252 param->vdev_id, param->param_id, param->value); 2253 wmi_buf_free(buf); 2254 return QDF_STATUS_E_FAILURE; 2255 } 2256 2257 return 0; 2258 } 2259 2260 /** 2261 * send_crash_inject_cmd_tlv() - inject fw crash 2262 * @wmi_handle: wmi handle 2263 * @param: ponirt to crash inject parameter structure 2264 * 2265 * Return: QDF_STATUS_SUCCESS for success or return error 2266 */ 2267 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2268 struct crash_inject *param) 2269 { 2270 int32_t ret = 0; 2271 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2272 uint16_t len = sizeof(*cmd); 2273 wmi_buf_t buf; 2274 2275 buf = wmi_buf_alloc(wmi_handle, len); 2276 if (!buf) 2277 return QDF_STATUS_E_NOMEM; 2278 2279 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2280 WMITLV_SET_HDR(&cmd->tlv_header, 2281 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2282 WMITLV_GET_STRUCT_TLVLEN 2283 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2284 cmd->type = param->type; 2285 cmd->delay_time_ms = param->delay_time_ms; 2286 2287 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2288 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2289 WMI_FORCE_FW_HANG_CMDID); 2290 if (ret) { 2291 wmi_err("Failed to send set param command, ret = %d", ret); 2292 wmi_buf_free(buf); 2293 } 2294 2295 return ret; 2296 } 2297 2298 /** 2299 * send_dbglog_cmd_tlv() - set debug log level 2300 * @param wmi_handle : handle to WMI. 2301 * @param param : pointer to hold dbglog level parameter 2302 * 2303 * Return: 0 on success and -ve on failure. 2304 */ 2305 static QDF_STATUS 2306 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2307 struct dbglog_params *dbglog_param) 2308 { 2309 wmi_buf_t buf; 2310 wmi_debug_log_config_cmd_fixed_param *configmsg; 2311 QDF_STATUS status; 2312 int32_t i; 2313 int32_t len; 2314 int8_t *buf_ptr; 2315 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2316 2317 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2318 2319 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2320 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2321 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2322 buf = wmi_buf_alloc(wmi_handle, len); 2323 if (!buf) 2324 return QDF_STATUS_E_NOMEM; 2325 2326 configmsg = 2327 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2328 buf_ptr = (int8_t *) configmsg; 2329 WMITLV_SET_HDR(&configmsg->tlv_header, 2330 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2331 WMITLV_GET_STRUCT_TLVLEN 2332 (wmi_debug_log_config_cmd_fixed_param)); 2333 configmsg->dbg_log_param = dbglog_param->param; 2334 configmsg->value = dbglog_param->val; 2335 /* Filling in the data part of second tlv -- should 2336 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2337 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2338 sizeof 2339 (wmi_debug_log_config_cmd_fixed_param) 2340 + WMI_TLV_HDR_SIZE); 2341 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2342 WMITLV_TAG_ARRAY_UINT32, 2343 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2344 if (dbglog_param->module_id_bitmap) { 2345 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2346 module_id_bitmap_array[i] = 2347 dbglog_param->module_id_bitmap[i]; 2348 } 2349 } 2350 2351 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2352 status = wmi_unified_cmd_send(wmi_handle, buf, 2353 len, WMI_DBGLOG_CFG_CMDID); 2354 2355 if (status != QDF_STATUS_SUCCESS) 2356 wmi_buf_free(buf); 2357 2358 return status; 2359 } 2360 2361 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2362 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2363 { 2364 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2365 return vdev_param_tlv[host_param]; 2366 return WMI_UNAVAILABLE_PARAM; 2367 } 2368 #else 2369 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2370 { 2371 return host_param; 2372 } 2373 #endif 2374 2375 /** 2376 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2377 * @param wmi_handle : handle to WMI. 2378 * @param macaddr : MAC address 2379 * @param param : pointer to hold vdev set parameter 2380 * 2381 * Return: 0 on success and -ve on failure. 2382 */ 2383 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2384 struct vdev_set_params *param) 2385 { 2386 QDF_STATUS ret; 2387 wmi_vdev_set_param_cmd_fixed_param *cmd; 2388 wmi_buf_t buf; 2389 uint16_t len = sizeof(*cmd); 2390 uint32_t vdev_param; 2391 2392 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2393 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2394 wmi_err("Vdev param %d not available", param->param_id); 2395 return QDF_STATUS_E_INVAL; 2396 2397 } 2398 2399 buf = wmi_buf_alloc(wmi_handle, len); 2400 if (!buf) 2401 return QDF_STATUS_E_NOMEM; 2402 2403 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2404 WMITLV_SET_HDR(&cmd->tlv_header, 2405 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2406 WMITLV_GET_STRUCT_TLVLEN 2407 (wmi_vdev_set_param_cmd_fixed_param)); 2408 cmd->vdev_id = param->vdev_id; 2409 cmd->param_id = vdev_param; 2410 cmd->param_value = param->param_value; 2411 wmi_debug("Setting vdev %d param = %x, value = %u", 2412 cmd->vdev_id, cmd->param_id, cmd->param_value); 2413 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2415 WMI_VDEV_SET_PARAM_CMDID); 2416 if (QDF_IS_STATUS_ERROR(ret)) { 2417 wmi_err("Failed to send set param command ret = %d", ret); 2418 wmi_buf_free(buf); 2419 } 2420 2421 return ret; 2422 } 2423 2424 /** 2425 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2426 * @param wmi_handle : handle to WMI. 2427 * @param param : pointer to hold mu sniffer parameter 2428 * 2429 * Return: 0 on success and -ve on failure. 2430 */ 2431 static 2432 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2433 struct vdev_set_mu_snif_param *param) 2434 { 2435 QDF_STATUS ret; 2436 wmi_vdev_set_mu_snif_cmd_param *cmd; 2437 wmi_buf_t buf; 2438 uint32_t *tmp_ptr; 2439 uint16_t len = sizeof(*cmd); 2440 uint8_t *buf_ptr; 2441 uint32_t i; 2442 2443 /* Length TLV placeholder for array of uint32_t */ 2444 len += WMI_TLV_HDR_SIZE; 2445 2446 if (param->num_aid) 2447 len += param->num_aid * sizeof(uint32_t); 2448 2449 buf = wmi_buf_alloc(wmi_handle, len); 2450 if (!buf) 2451 return QDF_STATUS_E_NOMEM; 2452 2453 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2454 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2455 2456 WMITLV_SET_HDR(&cmd->tlv_header, 2457 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2458 WMITLV_GET_STRUCT_TLVLEN 2459 (wmi_vdev_set_mu_snif_cmd_param)); 2460 2461 cmd->vdev_id = param->vdev_id; 2462 cmd->mode = param->mode; 2463 cmd->max_num_user = param->num_user; 2464 2465 buf_ptr += sizeof(*cmd); 2466 2467 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2468 2469 for (i = 0; i < param->num_aid; ++i) 2470 tmp_ptr[i] = param->aid[i]; 2471 2472 WMITLV_SET_HDR(buf_ptr, 2473 WMITLV_TAG_ARRAY_UINT32, 2474 (param->num_aid * sizeof(uint32_t))); 2475 2476 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2477 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2478 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2479 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2480 WMI_VDEV_SET_MU_SNIF_CMDID); 2481 if (QDF_IS_STATUS_ERROR(ret)) { 2482 wmi_err("Failed to send set param command ret = %d", ret); 2483 wmi_buf_free(buf); 2484 } 2485 2486 return ret; 2487 } 2488 2489 /** 2490 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2491 * @wmi_handle: handle to WMI. 2492 * @macaddr: Peer mac address to be filter 2493 * @mac_id: mac id to have radio context 2494 * @enb_dsb: Enable MAC based filtering or Disable 2495 * 2496 * Return: QDF_STATUS 2497 */ 2498 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2499 uint8_t *macaddr, 2500 uint8_t mac_id, 2501 uint8_t enb_dsb) 2502 { 2503 int32_t ret; 2504 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2505 wmi_pdev_pktlog_filter_info *mac_info; 2506 wmi_buf_t buf; 2507 uint8_t *buf_ptr; 2508 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2509 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2510 2511 buf = wmi_buf_alloc(wmi_handle, len); 2512 if (!buf) 2513 return QDF_STATUS_E_NOMEM; 2514 2515 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2516 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2517 WMITLV_SET_HDR(&cmd->tlv_header, 2518 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2519 WMITLV_GET_STRUCT_TLVLEN 2520 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2521 cmd->pdev_id = mac_id; 2522 cmd->enable = enb_dsb; 2523 cmd->num_of_mac_addresses = 1; 2524 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2525 2526 buf_ptr += sizeof(*cmd); 2527 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2528 sizeof(wmi_pdev_pktlog_filter_info)); 2529 buf_ptr += WMI_TLV_HDR_SIZE; 2530 2531 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2532 2533 WMITLV_SET_HDR(&mac_info->tlv_header, 2534 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2535 WMITLV_GET_STRUCT_TLVLEN 2536 (wmi_pdev_pktlog_filter_info)); 2537 2538 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2539 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2540 WMI_PDEV_PKTLOG_FILTER_CMDID); 2541 if (ret) { 2542 wmi_err("Failed to send peer based pktlog command to FW =%d" 2543 , ret); 2544 wmi_buf_free(buf); 2545 } 2546 2547 return ret; 2548 } 2549 2550 /** 2551 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2552 * @param wmi_handle : handle to WMI. 2553 * @param PKTLOG_EVENT : packet log event 2554 * @mac_id: mac id to have radio context 2555 * 2556 * Return: 0 on success and -ve on failure. 2557 */ 2558 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2559 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2560 { 2561 int32_t ret, idx, max_idx; 2562 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2563 wmi_buf_t buf; 2564 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2565 2566 buf = wmi_buf_alloc(wmi_handle, len); 2567 if (!buf) 2568 return -QDF_STATUS_E_NOMEM; 2569 2570 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2571 WMITLV_SET_HDR(&cmd->tlv_header, 2572 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2573 WMITLV_GET_STRUCT_TLVLEN 2574 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2575 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2576 cmd->evlist = 0; 2577 for (idx = 0; idx < max_idx; idx++) { 2578 if (PKTLOG_EVENT & (1 << idx)) 2579 cmd->evlist |= pktlog_event_tlv[idx]; 2580 } 2581 cmd->pdev_id = mac_id; 2582 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2583 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2584 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2585 if (ret) { 2586 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2587 wmi_buf_free(buf); 2588 } 2589 2590 return ret; 2591 } 2592 2593 /** 2594 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2595 * @param wmi_handle : handle to WMI. 2596 * @mac_id: mac id to have radio context 2597 * 2598 * Return: 0 on success and -ve on failure. 2599 */ 2600 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2601 uint8_t mac_id) 2602 { 2603 int32_t ret; 2604 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2605 wmi_buf_t buf; 2606 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2607 2608 buf = wmi_buf_alloc(wmi_handle, len); 2609 if (!buf) 2610 return -QDF_STATUS_E_NOMEM; 2611 2612 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2613 WMITLV_SET_HDR(&cmd->tlv_header, 2614 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2615 WMITLV_GET_STRUCT_TLVLEN 2616 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2617 cmd->pdev_id = mac_id; 2618 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2619 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2620 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2621 if (ret) { 2622 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 2623 wmi_buf_free(buf); 2624 } 2625 2626 return ret; 2627 } 2628 2629 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2630 /** 2631 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2632 * sync time between bwtween host and firmware 2633 * @param wmi_handle : handle to WMI. 2634 * 2635 * Return: None 2636 */ 2637 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2638 { 2639 wmi_buf_t buf; 2640 QDF_STATUS status = QDF_STATUS_SUCCESS; 2641 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2642 int32_t len; 2643 qdf_time_t time_ms; 2644 2645 len = sizeof(*time_stamp); 2646 buf = wmi_buf_alloc(wmi_handle, len); 2647 2648 if (!buf) 2649 return; 2650 2651 time_stamp = 2652 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2653 (wmi_buf_data(buf)); 2654 WMITLV_SET_HDR(&time_stamp->tlv_header, 2655 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2656 WMITLV_GET_STRUCT_TLVLEN( 2657 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2658 2659 time_ms = qdf_get_time_of_the_day_ms(); 2660 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2661 time_stamp->time_stamp_low = time_ms & 2662 WMI_FW_TIME_STAMP_LOW_MASK; 2663 /* 2664 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2665 * wont exceed 27 bit 2666 */ 2667 time_stamp->time_stamp_high = 0; 2668 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 2669 time_stamp->mode, time_stamp->time_stamp_low, 2670 time_stamp->time_stamp_high); 2671 2672 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2673 status = wmi_unified_cmd_send(wmi_handle, buf, 2674 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2675 if (status) { 2676 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2677 wmi_buf_free(buf); 2678 } 2679 2680 } 2681 2682 /** 2683 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2684 * @param wmi_handle : handle to WMI. 2685 * @param param : pointer to hold FILS Discovery send cmd parameter 2686 * 2687 * Return: 0 on success and -ve on failure. 2688 */ 2689 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2690 struct fils_discovery_tmpl_params *param) 2691 { 2692 int32_t ret; 2693 wmi_fd_tmpl_cmd_fixed_param *cmd; 2694 wmi_buf_t wmi_buf; 2695 uint8_t *buf_ptr; 2696 uint32_t wmi_buf_len; 2697 2698 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2699 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2700 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2701 if (!wmi_buf) 2702 return QDF_STATUS_E_NOMEM; 2703 2704 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2705 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2706 WMITLV_SET_HDR(&cmd->tlv_header, 2707 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2708 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2709 cmd->vdev_id = param->vdev_id; 2710 cmd->buf_len = param->tmpl_len; 2711 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2712 2713 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2714 buf_ptr += WMI_TLV_HDR_SIZE; 2715 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2716 2717 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2718 ret = wmi_unified_cmd_send(wmi_handle, 2719 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2720 2721 if (ret) { 2722 wmi_err("Failed to send fd tmpl: %d", ret); 2723 wmi_buf_free(wmi_buf); 2724 return ret; 2725 } 2726 2727 return 0; 2728 } 2729 2730 /** 2731 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2732 * @param wmi_handle : handle to WMI. 2733 * @param param : pointer to hold beacon send cmd parameter 2734 * 2735 * Return: 0 on success and -ve on failure. 2736 */ 2737 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2738 struct beacon_tmpl_params *param) 2739 { 2740 int32_t ret; 2741 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2742 wmi_bcn_prb_info *bcn_prb_info; 2743 wmi_buf_t wmi_buf; 2744 uint8_t *buf_ptr; 2745 uint32_t wmi_buf_len; 2746 2747 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2748 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2749 param->tmpl_len_aligned + 2750 bcn_tmpl_mlo_param_size(param) + 2751 bcn_tmpl_ml_info_size(param); 2752 2753 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2754 if (!wmi_buf) 2755 return QDF_STATUS_E_NOMEM; 2756 2757 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2758 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2759 WMITLV_SET_HDR(&cmd->tlv_header, 2760 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2761 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2762 cmd->vdev_id = param->vdev_id; 2763 cmd->tim_ie_offset = param->tim_ie_offset; 2764 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2765 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2766 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2767 cmd->esp_ie_offset = param->esp_ie_offset; 2768 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2769 cmd->ema_params = param->ema_params; 2770 cmd->buf_len = param->tmpl_len; 2771 cmd->csa_event_bitmap = param->csa_event_bitmap; 2772 2773 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2774 param->enable_bigtk); 2775 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2776 2777 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2778 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2779 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2780 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2781 bcn_prb_info->caps = 0; 2782 bcn_prb_info->erp = 0; 2783 buf_ptr += sizeof(wmi_bcn_prb_info); 2784 2785 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2786 buf_ptr += WMI_TLV_HDR_SIZE; 2787 2788 /* for big endian host, copy engine byte_swap is enabled 2789 * But the frame content is in network byte order 2790 * Need to byte swap the frame content - so when copy engine 2791 * does byte_swap - target gets frame content in the correct order 2792 */ 2793 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 2794 param->tmpl_len); 2795 2796 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 2797 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 2798 2799 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 2800 2801 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2802 ret = wmi_unified_cmd_send(wmi_handle, 2803 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2804 if (ret) { 2805 wmi_err("Failed to send bcn tmpl: %d", ret); 2806 wmi_buf_free(wmi_buf); 2807 } 2808 2809 return 0; 2810 } 2811 2812 #ifdef WLAN_FEATURE_11BE 2813 static inline void copy_peer_flags_tlv_11be( 2814 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2815 struct peer_assoc_params *param) 2816 { 2817 if (param->bw_320) 2818 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 2819 if (param->eht_flag) 2820 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 2821 2822 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 2823 } 2824 #else 2825 static inline void copy_peer_flags_tlv_11be( 2826 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2827 struct peer_assoc_params *param) 2828 { 2829 } 2830 #endif 2831 2832 static inline void copy_peer_flags_tlv( 2833 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2834 struct peer_assoc_params *param) 2835 { 2836 /* 2837 * The target only needs a subset of the flags maintained in the host. 2838 * Just populate those flags and send it down 2839 */ 2840 cmd->peer_flags = 0; 2841 if (param->peer_dms_capable) 2842 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 2843 /* 2844 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2845 */ 2846 if (param->is_wme_set) { 2847 2848 if (param->qos_flag) 2849 cmd->peer_flags |= WMI_PEER_QOS; 2850 if (param->apsd_flag) 2851 cmd->peer_flags |= WMI_PEER_APSD; 2852 if (param->ht_flag) 2853 cmd->peer_flags |= WMI_PEER_HT; 2854 if (param->bw_40) 2855 cmd->peer_flags |= WMI_PEER_40MHZ; 2856 if (param->bw_80) 2857 cmd->peer_flags |= WMI_PEER_80MHZ; 2858 if (param->bw_160) 2859 cmd->peer_flags |= WMI_PEER_160MHZ; 2860 2861 copy_peer_flags_tlv_11be(cmd, param); 2862 2863 /* Typically if STBC is enabled for VHT it should be enabled 2864 * for HT as well 2865 **/ 2866 if (param->stbc_flag) 2867 cmd->peer_flags |= WMI_PEER_STBC; 2868 2869 /* Typically if LDPC is enabled for VHT it should be enabled 2870 * for HT as well 2871 **/ 2872 if (param->ldpc_flag) 2873 cmd->peer_flags |= WMI_PEER_LDPC; 2874 2875 if (param->static_mimops_flag) 2876 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2877 if (param->dynamic_mimops_flag) 2878 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2879 if (param->spatial_mux_flag) 2880 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2881 if (param->vht_flag) 2882 cmd->peer_flags |= WMI_PEER_VHT; 2883 if (param->he_flag) 2884 cmd->peer_flags |= WMI_PEER_HE; 2885 if (param->p2p_capable_sta) 2886 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2887 } 2888 2889 if (param->is_pmf_enabled) 2890 cmd->peer_flags |= WMI_PEER_PMF; 2891 /* 2892 * Suppress authorization for all AUTH modes that need 4-way handshake 2893 * (during re-association). 2894 * Authorization will be done for these modes on key installation. 2895 */ 2896 if (param->auth_flag) 2897 cmd->peer_flags |= WMI_PEER_AUTH; 2898 if (param->need_ptk_4_way) 2899 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2900 else 2901 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2902 if (param->need_gtk_2_way) 2903 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2904 /* safe mode bypass the 4-way handshake */ 2905 if (param->safe_mode_enabled) 2906 cmd->peer_flags &= 2907 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2908 /* inter BSS peer */ 2909 if (param->inter_bss_peer) 2910 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2911 /* Disable AMSDU for station transmit, if user configures it */ 2912 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2913 * it 2914 * if (param->amsdu_disable) Add after FW support 2915 **/ 2916 2917 /* Target asserts if node is marked HT and all MCS is set to 0. 2918 * Mark the node as non-HT if all the mcs rates are disabled through 2919 * iwpriv 2920 **/ 2921 if (param->peer_ht_rates.num_rates == 0) 2922 cmd->peer_flags &= ~WMI_PEER_HT; 2923 2924 if (param->twt_requester) 2925 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2926 2927 if (param->twt_responder) 2928 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2929 } 2930 2931 static inline void copy_peer_mac_addr_tlv( 2932 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2933 struct peer_assoc_params *param) 2934 { 2935 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2936 } 2937 2938 #ifdef WLAN_FEATURE_11BE 2939 static uint8_t *update_peer_flags_tlv_ehtinfo( 2940 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2941 struct peer_assoc_params *param, uint8_t *buf_ptr) 2942 { 2943 wmi_eht_rate_set *eht_mcs; 2944 int i; 2945 2946 cmd->peer_eht_ops = param->peer_eht_ops; 2947 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 2948 2949 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 2950 sizeof(param->peer_eht_cap_macinfo)); 2951 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 2952 sizeof(param->peer_eht_cap_phyinfo)); 2953 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 2954 sizeof(param->peer_eht_ppet)); 2955 2956 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2957 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 2958 buf_ptr += WMI_TLV_HDR_SIZE; 2959 2960 /* Loop through the EHT rate set */ 2961 for (i = 0; i < param->peer_eht_mcs_count; i++) { 2962 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 2963 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 2964 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 2965 2966 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 2967 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 2968 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 2969 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 2970 buf_ptr += sizeof(wmi_eht_rate_set); 2971 } 2972 2973 wmi_debug("nss %d ru mask 0x%x", 2974 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 2975 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 2976 wmi_debug("ppet idx %d ppet %x ", 2977 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 2978 } 2979 2980 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 2981 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2982 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 2983 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2984 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2985 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 2986 param->peer_eht_tx_mcs_set 2987 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2988 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 2989 param->peer_eht_rx_mcs_set 2990 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2991 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2992 QDF_MAC_ADDR_REF(param->peer_mac)); 2993 } 2994 2995 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 2996 cmd->peer_eht_cap_mac[0], 2997 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 2998 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 2999 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3000 3001 return buf_ptr; 3002 } 3003 #else 3004 static uint8_t *update_peer_flags_tlv_ehtinfo( 3005 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3006 struct peer_assoc_params *param, uint8_t *buf_ptr) 3007 { 3008 return buf_ptr; 3009 } 3010 #endif 3011 3012 #ifdef WLAN_FEATURE_11BE 3013 static 3014 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3015 { 3016 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3017 + WMI_TLV_HDR_SIZE); 3018 } 3019 3020 static void wmi_populate_service_11be(uint32_t *wmi_service) 3021 { 3022 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3023 } 3024 3025 #else 3026 static 3027 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3028 { 3029 return 0; 3030 } 3031 3032 static void wmi_populate_service_11be(uint32_t *wmi_service) 3033 { 3034 } 3035 3036 #endif 3037 3038 /** 3039 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3040 * @param wmi_handle : handle to WMI. 3041 * @param param : pointer to peer assoc parameter 3042 * 3043 * Return: 0 on success and -ve on failure. 3044 */ 3045 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3046 struct peer_assoc_params *param) 3047 { 3048 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3049 wmi_vht_rate_set *mcs; 3050 wmi_he_rate_set *he_mcs; 3051 wmi_buf_t buf; 3052 int32_t len; 3053 uint8_t *buf_ptr; 3054 QDF_STATUS ret; 3055 uint32_t peer_legacy_rates_align; 3056 uint32_t peer_ht_rates_align; 3057 int32_t i; 3058 3059 3060 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3061 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3062 3063 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3064 (peer_legacy_rates_align * sizeof(uint8_t)) + 3065 WMI_TLV_HDR_SIZE + 3066 (peer_ht_rates_align * sizeof(uint8_t)) + 3067 sizeof(wmi_vht_rate_set) + 3068 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3069 + WMI_TLV_HDR_SIZE) 3070 + wmi_eht_peer_assoc_params_len(param) + 3071 peer_assoc_mlo_params_size(param) + 3072 peer_assoc_t2lm_params_size(param); 3073 3074 buf = wmi_buf_alloc(wmi_handle, len); 3075 if (!buf) 3076 return QDF_STATUS_E_NOMEM; 3077 3078 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3079 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3080 WMITLV_SET_HDR(&cmd->tlv_header, 3081 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3082 WMITLV_GET_STRUCT_TLVLEN 3083 (wmi_peer_assoc_complete_cmd_fixed_param)); 3084 3085 cmd->vdev_id = param->vdev_id; 3086 3087 cmd->peer_new_assoc = param->peer_new_assoc; 3088 cmd->peer_associd = param->peer_associd; 3089 3090 copy_peer_flags_tlv(cmd, param); 3091 copy_peer_mac_addr_tlv(cmd, param); 3092 3093 cmd->peer_rate_caps = param->peer_rate_caps; 3094 cmd->peer_caps = param->peer_caps; 3095 cmd->peer_listen_intval = param->peer_listen_intval; 3096 cmd->peer_ht_caps = param->peer_ht_caps; 3097 cmd->peer_max_mpdu = param->peer_max_mpdu; 3098 cmd->peer_mpdu_density = param->peer_mpdu_density; 3099 cmd->peer_vht_caps = param->peer_vht_caps; 3100 cmd->peer_phymode = param->peer_phymode; 3101 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3102 3103 /* Update 11ax capabilities */ 3104 cmd->peer_he_cap_info = 3105 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3106 cmd->peer_he_cap_info_ext = 3107 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3108 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3109 cmd->peer_he_ops = param->peer_he_ops; 3110 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3111 sizeof(param->peer_he_cap_phyinfo)); 3112 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3113 sizeof(param->peer_ppet)); 3114 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3115 3116 /* Update peer legacy rate information */ 3117 buf_ptr += sizeof(*cmd); 3118 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3119 peer_legacy_rates_align); 3120 buf_ptr += WMI_TLV_HDR_SIZE; 3121 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3122 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3123 param->peer_legacy_rates.num_rates); 3124 3125 /* Update peer HT rate information */ 3126 buf_ptr += peer_legacy_rates_align; 3127 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3128 peer_ht_rates_align); 3129 buf_ptr += WMI_TLV_HDR_SIZE; 3130 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3131 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3132 param->peer_ht_rates.num_rates); 3133 3134 /* VHT Rates */ 3135 buf_ptr += peer_ht_rates_align; 3136 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3137 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3138 3139 cmd->auth_mode = param->akm; 3140 cmd->peer_nss = param->peer_nss; 3141 3142 /* Update bandwidth-NSS mapping */ 3143 cmd->peer_bw_rxnss_override = 0; 3144 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3145 3146 mcs = (wmi_vht_rate_set *) buf_ptr; 3147 if (param->vht_capable) { 3148 mcs->rx_max_rate = param->rx_max_rate; 3149 mcs->rx_mcs_set = param->rx_mcs_set; 3150 mcs->tx_max_rate = param->tx_max_rate; 3151 mcs->tx_mcs_set = param->tx_mcs_set; 3152 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3153 } 3154 3155 /* HE Rates */ 3156 cmd->min_data_rate = param->min_data_rate; 3157 cmd->peer_he_mcs = param->peer_he_mcs_count; 3158 buf_ptr += sizeof(wmi_vht_rate_set); 3159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3160 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3161 buf_ptr += WMI_TLV_HDR_SIZE; 3162 3163 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3164 /* Loop through the HE rate set */ 3165 for (i = 0; i < param->peer_he_mcs_count; i++) { 3166 he_mcs = (wmi_he_rate_set *) buf_ptr; 3167 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3168 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3169 3170 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3171 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3172 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3173 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3174 buf_ptr += sizeof(wmi_he_rate_set); 3175 } 3176 3177 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3178 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3179 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3180 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3181 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3182 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3183 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3184 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3185 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3186 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3187 QDF_MAC_ADDR_REF(param->peer_mac)); 3188 } 3189 3190 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3191 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3192 "nss %d phymode %d peer_mpdu_density %d " 3193 "cmd->peer_vht_caps %x " 3194 "HE cap_info %x ops %x " 3195 "HE cap_info_ext %x " 3196 "HE phy %x %x %x " 3197 "peer_bw_rxnss_override %x", 3198 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3199 cmd->peer_rate_caps, cmd->peer_caps, 3200 cmd->peer_listen_intval, cmd->peer_ht_caps, 3201 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3202 cmd->peer_mpdu_density, 3203 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3204 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3205 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3206 cmd->peer_he_cap_phy[2], 3207 cmd->peer_bw_rxnss_override); 3208 3209 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3210 3211 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3212 3213 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3214 3215 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3216 3217 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3218 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3219 WMI_PEER_ASSOC_CMDID); 3220 if (QDF_IS_STATUS_ERROR(ret)) { 3221 wmi_err("Failed to send peer assoc command ret = %d", ret); 3222 wmi_buf_free(buf); 3223 } 3224 3225 return ret; 3226 } 3227 3228 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3229 */ 3230 static inline void copy_scan_event_cntrl_flags( 3231 wmi_start_scan_cmd_fixed_param * cmd, 3232 struct scan_req_params *param) 3233 { 3234 3235 /* Scan events subscription */ 3236 if (param->scan_ev_started) 3237 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3238 if (param->scan_ev_completed) 3239 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3240 if (param->scan_ev_bss_chan) 3241 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3242 if (param->scan_ev_foreign_chan) 3243 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3244 if (param->scan_ev_dequeued) 3245 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3246 if (param->scan_ev_preempted) 3247 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3248 if (param->scan_ev_start_failed) 3249 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3250 if (param->scan_ev_restarted) 3251 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3252 if (param->scan_ev_foreign_chn_exit) 3253 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3254 if (param->scan_ev_suspended) 3255 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3256 if (param->scan_ev_resumed) 3257 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3258 3259 /** Set scan control flags */ 3260 cmd->scan_ctrl_flags = 0; 3261 if (param->scan_f_passive) 3262 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3263 if (param->scan_f_strict_passive_pch) 3264 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3265 if (param->scan_f_promisc_mode) 3266 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3267 if (param->scan_f_capture_phy_err) 3268 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3269 if (param->scan_f_half_rate) 3270 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3271 if (param->scan_f_quarter_rate) 3272 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3273 if (param->scan_f_cck_rates) 3274 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3275 if (param->scan_f_ofdm_rates) 3276 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3277 if (param->scan_f_chan_stat_evnt) 3278 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3279 if (param->scan_f_filter_prb_req) 3280 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3281 if (param->scan_f_bcast_probe) 3282 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3283 if (param->scan_f_offchan_mgmt_tx) 3284 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3285 if (param->scan_f_offchan_data_tx) 3286 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3287 if (param->scan_f_force_active_dfs_chn) 3288 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3289 if (param->scan_f_add_tpc_ie_in_probe) 3290 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3291 if (param->scan_f_add_ds_ie_in_probe) 3292 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3293 if (param->scan_f_add_spoofed_mac_in_probe) 3294 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3295 if (param->scan_f_add_rand_seq_in_probe) 3296 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3297 if (param->scan_f_en_ie_allowlist_in_probe) 3298 cmd->scan_ctrl_flags |= 3299 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3300 3301 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3302 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3303 param->adaptive_dwell_time_mode); 3304 } 3305 3306 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3307 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3308 struct scan_req_params *params) 3309 { 3310 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3311 } 3312 3313 /** 3314 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3315 * @mac: random mac addr 3316 * @mask: random mac mask 3317 * @mac_addr: wmi random mac 3318 * @mac_mask: wmi random mac mask 3319 * 3320 * Return None. 3321 */ 3322 static inline 3323 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3324 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3325 { 3326 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3327 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3328 } 3329 3330 /* 3331 * wmi_fill_vendor_oui() - fill vendor OUIs 3332 * @buf_ptr: pointer to wmi tlv buffer 3333 * @num_vendor_oui: number of vendor OUIs to be filled 3334 * @param_voui: pointer to OUI buffer 3335 * 3336 * This function populates the wmi tlv buffer when vendor specific OUIs are 3337 * present. 3338 * 3339 * Return: None 3340 */ 3341 static inline 3342 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3343 uint32_t *pvoui) 3344 { 3345 wmi_vendor_oui *voui = NULL; 3346 uint32_t i; 3347 3348 voui = (wmi_vendor_oui *)buf_ptr; 3349 3350 for (i = 0; i < num_vendor_oui; i++) { 3351 WMITLV_SET_HDR(&voui[i].tlv_header, 3352 WMITLV_TAG_STRUC_wmi_vendor_oui, 3353 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3354 voui[i].oui_type_subtype = pvoui[i]; 3355 } 3356 } 3357 3358 /* 3359 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3360 * @ie_bitmap: output pointer to ie bit map in cmd 3361 * @num_vendor_oui: output pointer to num vendor OUIs 3362 * @ie_allowlist: input parameter 3363 * 3364 * This function populates the IE allowlist attrs of scan, pno and 3365 * scan oui commands for ie_allowlist parameter. 3366 * 3367 * Return: None 3368 */ 3369 static inline 3370 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3371 uint32_t *num_vendor_oui, 3372 struct probe_req_allowlist_attr *ie_allowlist) 3373 { 3374 uint32_t i = 0; 3375 3376 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3377 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3378 3379 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3380 } 3381 3382 /** 3383 * send_scan_start_cmd_tlv() - WMI scan start function 3384 * @param wmi_handle : handle to WMI. 3385 * @param param : pointer to hold scan start cmd parameter 3386 * 3387 * Return: 0 on success and -ve on failure. 3388 */ 3389 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3390 struct scan_req_params *params) 3391 { 3392 int32_t ret = 0; 3393 int32_t i; 3394 wmi_buf_t wmi_buf; 3395 wmi_start_scan_cmd_fixed_param *cmd; 3396 uint8_t *buf_ptr; 3397 uint32_t *tmp_ptr; 3398 wmi_ssid *ssid = NULL; 3399 wmi_mac_addr *bssid; 3400 size_t len = sizeof(*cmd); 3401 uint16_t extraie_len_with_pad = 0; 3402 uint8_t phymode_roundup = 0; 3403 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3404 wmi_hint_freq_short_ssid *s_ssid = NULL; 3405 wmi_hint_freq_bssid *hint_bssid = NULL; 3406 3407 /* Length TLV placeholder for array of uint32_t */ 3408 len += WMI_TLV_HDR_SIZE; 3409 /* calculate the length of buffer required */ 3410 if (params->chan_list.num_chan) 3411 len += params->chan_list.num_chan * sizeof(uint32_t); 3412 3413 /* Length TLV placeholder for array of wmi_ssid structures */ 3414 len += WMI_TLV_HDR_SIZE; 3415 if (params->num_ssids) 3416 len += params->num_ssids * sizeof(wmi_ssid); 3417 3418 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3419 len += WMI_TLV_HDR_SIZE; 3420 if (params->num_bssid) 3421 len += sizeof(wmi_mac_addr) * params->num_bssid; 3422 3423 /* Length TLV placeholder for array of bytes */ 3424 len += WMI_TLV_HDR_SIZE; 3425 if (params->extraie.len) 3426 extraie_len_with_pad = 3427 roundup(params->extraie.len, sizeof(uint32_t)); 3428 len += extraie_len_with_pad; 3429 3430 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3431 if (ie_allowlist->num_vendor_oui) 3432 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3433 3434 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3435 if (params->scan_f_wide_band) 3436 phymode_roundup = 3437 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3438 sizeof(uint32_t)); 3439 len += phymode_roundup; 3440 3441 len += WMI_TLV_HDR_SIZE; 3442 if (params->num_hint_bssid) 3443 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3444 3445 len += WMI_TLV_HDR_SIZE; 3446 if (params->num_hint_s_ssid) 3447 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3448 3449 /* Allocate the memory */ 3450 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3451 if (!wmi_buf) 3452 return QDF_STATUS_E_FAILURE; 3453 3454 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3455 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3456 WMITLV_SET_HDR(&cmd->tlv_header, 3457 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3458 WMITLV_GET_STRUCT_TLVLEN 3459 (wmi_start_scan_cmd_fixed_param)); 3460 3461 cmd->scan_id = params->scan_id; 3462 cmd->scan_req_id = params->scan_req_id; 3463 cmd->vdev_id = params->vdev_id; 3464 cmd->scan_priority = params->scan_priority; 3465 3466 copy_scan_event_cntrl_flags(cmd, params); 3467 3468 cmd->dwell_time_active = params->dwell_time_active; 3469 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3470 cmd->dwell_time_passive = params->dwell_time_passive; 3471 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3472 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3473 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3474 cmd->scan_start_offset = params->scan_offset_time; 3475 cmd->min_rest_time = params->min_rest_time; 3476 cmd->max_rest_time = params->max_rest_time; 3477 cmd->repeat_probe_time = params->repeat_probe_time; 3478 cmd->probe_spacing_time = params->probe_spacing_time; 3479 cmd->idle_time = params->idle_time; 3480 cmd->max_scan_time = params->max_scan_time; 3481 cmd->probe_delay = params->probe_delay; 3482 cmd->burst_duration = params->burst_duration; 3483 cmd->num_chan = params->chan_list.num_chan; 3484 cmd->num_bssid = params->num_bssid; 3485 cmd->num_ssids = params->num_ssids; 3486 cmd->ie_len = params->extraie.len; 3487 cmd->n_probes = params->n_probes; 3488 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3489 3490 if (params->scan_random.randomize) 3491 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3492 params->scan_random.mac_mask, 3493 &cmd->mac_addr, 3494 &cmd->mac_mask); 3495 3496 if (ie_allowlist->allow_list) 3497 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 3498 &cmd->num_vendor_oui, 3499 ie_allowlist); 3500 3501 buf_ptr += sizeof(*cmd); 3502 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3503 for (i = 0; i < params->chan_list.num_chan; ++i) { 3504 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 3505 params->chan_list.chan[i].freq); 3506 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3507 params->chan_list.chan[i].flags); 3508 } 3509 3510 WMITLV_SET_HDR(buf_ptr, 3511 WMITLV_TAG_ARRAY_UINT32, 3512 (params->chan_list.num_chan * sizeof(uint32_t))); 3513 buf_ptr += WMI_TLV_HDR_SIZE + 3514 (params->chan_list.num_chan * sizeof(uint32_t)); 3515 3516 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3517 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3518 goto error; 3519 } 3520 3521 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3522 (params->num_ssids * sizeof(wmi_ssid))); 3523 3524 if (params->num_ssids) { 3525 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3526 for (i = 0; i < params->num_ssids; ++i) { 3527 ssid->ssid_len = params->ssid[i].length; 3528 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3529 params->ssid[i].length); 3530 ssid++; 3531 } 3532 } 3533 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3534 3535 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3536 (params->num_bssid * sizeof(wmi_mac_addr))); 3537 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3538 3539 if (params->num_bssid) { 3540 for (i = 0; i < params->num_bssid; ++i) { 3541 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3542 ¶ms->bssid_list[i].bytes[0], bssid); 3543 bssid++; 3544 } 3545 } 3546 3547 buf_ptr += WMI_TLV_HDR_SIZE + 3548 (params->num_bssid * sizeof(wmi_mac_addr)); 3549 3550 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3551 if (params->extraie.len) 3552 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3553 params); 3554 3555 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3556 3557 /* probe req ie allowlisting */ 3558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3559 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3560 3561 buf_ptr += WMI_TLV_HDR_SIZE; 3562 3563 if (cmd->num_vendor_oui) { 3564 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3565 ie_allowlist->voui); 3566 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3567 } 3568 3569 /* Add phy mode TLV if it's a wide band scan */ 3570 if (params->scan_f_wide_band) { 3571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3572 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3573 for (i = 0; i < params->chan_list.num_chan; ++i) 3574 buf_ptr[i] = 3575 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3576 buf_ptr += phymode_roundup; 3577 } else { 3578 /* Add ZERO legth phy mode TLV */ 3579 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3580 buf_ptr += WMI_TLV_HDR_SIZE; 3581 } 3582 3583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3584 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3585 if (params->num_hint_s_ssid) { 3586 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3587 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3588 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3589 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3590 s_ssid++; 3591 } 3592 } 3593 buf_ptr += WMI_TLV_HDR_SIZE + 3594 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3595 3596 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3597 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3598 if (params->num_hint_bssid) { 3599 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3600 for (i = 0; i < params->num_hint_bssid; ++i) { 3601 hint_bssid->freq_flags = 3602 params->hint_bssid[i].freq_flags; 3603 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3604 &hint_bssid->bssid); 3605 hint_bssid++; 3606 } 3607 } 3608 3609 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3610 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3611 len, WMI_START_SCAN_CMDID); 3612 if (ret) { 3613 wmi_err("Failed to start scan: %d", ret); 3614 wmi_buf_free(wmi_buf); 3615 } 3616 return ret; 3617 error: 3618 wmi_buf_free(wmi_buf); 3619 return QDF_STATUS_E_FAILURE; 3620 } 3621 3622 /** 3623 * send_scan_stop_cmd_tlv() - WMI scan start function 3624 * @param wmi_handle : handle to WMI. 3625 * @param param : pointer to hold scan cancel cmd parameter 3626 * 3627 * Return: 0 on success and -ve on failure. 3628 */ 3629 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3630 struct scan_cancel_param *param) 3631 { 3632 wmi_stop_scan_cmd_fixed_param *cmd; 3633 int ret; 3634 int len = sizeof(*cmd); 3635 wmi_buf_t wmi_buf; 3636 3637 /* Allocate the memory */ 3638 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3639 if (!wmi_buf) { 3640 ret = QDF_STATUS_E_NOMEM; 3641 goto error; 3642 } 3643 3644 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3645 WMITLV_SET_HDR(&cmd->tlv_header, 3646 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3647 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3648 cmd->vdev_id = param->vdev_id; 3649 cmd->requestor = param->requester; 3650 cmd->scan_id = param->scan_id; 3651 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3652 wmi_handle, 3653 param->pdev_id); 3654 /* stop the scan with the corresponding scan_id */ 3655 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3656 /* Cancelling all scans */ 3657 cmd->req_type = WMI_SCAN_STOP_ALL; 3658 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3659 /* Cancelling VAP scans */ 3660 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3661 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3662 /* Cancelling specific scan */ 3663 cmd->req_type = WMI_SCAN_STOP_ONE; 3664 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3665 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3666 } else { 3667 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 3668 wmi_buf_free(wmi_buf); 3669 return QDF_STATUS_E_INVAL; 3670 } 3671 3672 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3673 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3674 len, WMI_STOP_SCAN_CMDID); 3675 if (ret) { 3676 wmi_err("Failed to send stop scan: %d", ret); 3677 wmi_buf_free(wmi_buf); 3678 } 3679 3680 error: 3681 return ret; 3682 } 3683 3684 #define WMI_MAX_CHAN_INFO_LOG 192 3685 3686 /** 3687 * wmi_scan_chanlist_dump() - Dump scan channel list info 3688 * @scan_chan_list: scan channel list 3689 * 3690 * Return: void 3691 */ 3692 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3693 { 3694 uint32_t i; 3695 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3696 uint32_t len = 0; 3697 struct channel_param *chan; 3698 int ret; 3699 3700 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3701 for (i = 0; i < scan_chan_list->nallchans; i++) { 3702 chan = &scan_chan_list->ch_param[i]; 3703 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3704 " %d[%d][%d][%d]", chan->mhz, 3705 chan->maxregpower, 3706 chan->dfs_set, chan->nan_disabled); 3707 if (ret <= 0) 3708 break; 3709 len += ret; 3710 if (len >= (sizeof(info) - 20)) { 3711 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 3712 info); 3713 len = 0; 3714 } 3715 } 3716 if (len) 3717 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3718 } 3719 3720 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3721 struct scan_chan_list_params *chan_list) 3722 { 3723 wmi_buf_t buf; 3724 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3725 wmi_scan_chan_list_cmd_fixed_param *cmd; 3726 int i; 3727 uint8_t *buf_ptr; 3728 wmi_channel *chan_info; 3729 struct channel_param *tchan_info; 3730 uint16_t len; 3731 uint16_t num_send_chans, num_sends = 0; 3732 3733 wmi_scan_chanlist_dump(chan_list); 3734 tchan_info = &chan_list->ch_param[0]; 3735 while (chan_list->nallchans) { 3736 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3737 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3738 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3739 else 3740 num_send_chans = chan_list->nallchans; 3741 3742 chan_list->nallchans -= num_send_chans; 3743 len += sizeof(wmi_channel) * num_send_chans; 3744 buf = wmi_buf_alloc(wmi_handle, len); 3745 if (!buf) { 3746 qdf_status = QDF_STATUS_E_NOMEM; 3747 goto end; 3748 } 3749 3750 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3751 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3752 WMITLV_SET_HDR(&cmd->tlv_header, 3753 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3754 WMITLV_GET_STRUCT_TLVLEN 3755 (wmi_scan_chan_list_cmd_fixed_param)); 3756 3757 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 3758 3759 if (num_sends) 3760 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3761 3762 if (chan_list->max_bw_support_present) 3763 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3764 3765 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3766 wmi_handle, 3767 chan_list->pdev_id); 3768 3769 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3770 3771 cmd->num_scan_chans = num_send_chans; 3772 WMITLV_SET_HDR((buf_ptr + 3773 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3774 WMITLV_TAG_ARRAY_STRUC, 3775 sizeof(wmi_channel) * num_send_chans); 3776 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3777 WMI_TLV_HDR_SIZE); 3778 3779 for (i = 0; i < num_send_chans; ++i) { 3780 WMITLV_SET_HDR(&chan_info->tlv_header, 3781 WMITLV_TAG_STRUC_wmi_channel, 3782 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3783 chan_info->mhz = tchan_info->mhz; 3784 chan_info->band_center_freq1 = 3785 tchan_info->cfreq1; 3786 chan_info->band_center_freq2 = 3787 tchan_info->cfreq2; 3788 3789 if (tchan_info->is_chan_passive) 3790 WMI_SET_CHANNEL_FLAG(chan_info, 3791 WMI_CHAN_FLAG_PASSIVE); 3792 if (tchan_info->dfs_set) 3793 WMI_SET_CHANNEL_FLAG(chan_info, 3794 WMI_CHAN_FLAG_DFS); 3795 3796 if (tchan_info->dfs_set_cfreq2) 3797 WMI_SET_CHANNEL_FLAG(chan_info, 3798 WMI_CHAN_FLAG_DFS_CFREQ2); 3799 3800 if (tchan_info->allow_he) 3801 WMI_SET_CHANNEL_FLAG(chan_info, 3802 WMI_CHAN_FLAG_ALLOW_HE); 3803 3804 if (tchan_info->allow_eht) 3805 WMI_SET_CHANNEL_FLAG(chan_info, 3806 WMI_CHAN_FLAG_ALLOW_EHT); 3807 3808 if (tchan_info->allow_vht) 3809 WMI_SET_CHANNEL_FLAG(chan_info, 3810 WMI_CHAN_FLAG_ALLOW_VHT); 3811 3812 if (tchan_info->allow_ht) 3813 WMI_SET_CHANNEL_FLAG(chan_info, 3814 WMI_CHAN_FLAG_ALLOW_HT); 3815 WMI_SET_CHANNEL_MODE(chan_info, 3816 tchan_info->phy_mode); 3817 3818 if (tchan_info->half_rate) 3819 WMI_SET_CHANNEL_FLAG(chan_info, 3820 WMI_CHAN_FLAG_HALF_RATE); 3821 3822 if (tchan_info->quarter_rate) 3823 WMI_SET_CHANNEL_FLAG(chan_info, 3824 WMI_CHAN_FLAG_QUARTER_RATE); 3825 3826 if (tchan_info->psc_channel) 3827 WMI_SET_CHANNEL_FLAG(chan_info, 3828 WMI_CHAN_FLAG_PSC); 3829 3830 if (tchan_info->nan_disabled) 3831 WMI_SET_CHANNEL_FLAG(chan_info, 3832 WMI_CHAN_FLAG_NAN_DISABLED); 3833 3834 /* also fill in power information */ 3835 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3836 tchan_info->minpower); 3837 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3838 tchan_info->maxpower); 3839 WMI_SET_CHANNEL_REG_POWER(chan_info, 3840 tchan_info->maxregpower); 3841 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3842 tchan_info->antennamax); 3843 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3844 tchan_info->reg_class_id); 3845 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3846 tchan_info->maxregpower); 3847 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3848 tchan_info->max_bw_supported); 3849 3850 tchan_info++; 3851 chan_info++; 3852 } 3853 3854 qdf_status = wmi_unified_cmd_send( 3855 wmi_handle, 3856 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3857 3858 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3859 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3860 wmi_buf_free(buf); 3861 goto end; 3862 } 3863 num_sends++; 3864 } 3865 3866 end: 3867 return qdf_status; 3868 } 3869 3870 /** 3871 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3872 * 3873 * @bufp: Pointer to buffer 3874 * @param: Pointer to tx param 3875 * 3876 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3877 */ 3878 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3879 struct tx_send_params param) 3880 { 3881 wmi_tx_send_params *tx_param; 3882 QDF_STATUS status = QDF_STATUS_SUCCESS; 3883 3884 if (!bufp) { 3885 status = QDF_STATUS_E_FAILURE; 3886 return status; 3887 } 3888 tx_param = (wmi_tx_send_params *)bufp; 3889 WMITLV_SET_HDR(&tx_param->tlv_header, 3890 WMITLV_TAG_STRUC_wmi_tx_send_params, 3891 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3892 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3893 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3894 param.mcs_mask); 3895 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3896 param.nss_mask); 3897 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3898 param.retry_limit); 3899 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3900 param.chain_mask); 3901 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3902 param.bw_mask); 3903 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3904 param.preamble_type); 3905 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3906 param.frame_type); 3907 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3908 param.cfr_enable); 3909 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 3910 param.en_beamforming); 3911 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 3912 param.retry_limit_ext); 3913 3914 return status; 3915 } 3916 3917 #ifdef CONFIG_HL_SUPPORT 3918 /** 3919 * send_mgmt_cmd_tlv() - WMI scan start function 3920 * @wmi_handle : handle to WMI. 3921 * @param : pointer to hold mgmt cmd parameter 3922 * 3923 * Return: 0 on success and -ve on failure. 3924 */ 3925 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3926 struct wmi_mgmt_params *param) 3927 { 3928 wmi_buf_t buf; 3929 uint8_t *bufp; 3930 int32_t cmd_len; 3931 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3932 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3933 mgmt_tx_dl_frm_len; 3934 3935 if (param->frm_len > mgmt_tx_dl_frm_len) { 3936 wmi_err("mgmt frame len %u exceeds %u", 3937 param->frm_len, mgmt_tx_dl_frm_len); 3938 return QDF_STATUS_E_INVAL; 3939 } 3940 3941 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3942 WMI_TLV_HDR_SIZE + 3943 roundup(bufp_len, sizeof(uint32_t)); 3944 3945 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3946 if (!buf) 3947 return QDF_STATUS_E_NOMEM; 3948 3949 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3950 bufp = (uint8_t *) cmd; 3951 WMITLV_SET_HDR(&cmd->tlv_header, 3952 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3953 WMITLV_GET_STRUCT_TLVLEN 3954 (wmi_mgmt_tx_send_cmd_fixed_param)); 3955 3956 cmd->vdev_id = param->vdev_id; 3957 3958 cmd->desc_id = param->desc_id; 3959 cmd->chanfreq = param->chanfreq; 3960 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3961 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3962 sizeof(uint32_t))); 3963 bufp += WMI_TLV_HDR_SIZE; 3964 qdf_mem_copy(bufp, param->pdata, bufp_len); 3965 3966 cmd->frame_len = param->frm_len; 3967 cmd->buf_len = bufp_len; 3968 cmd->tx_params_valid = param->tx_params_valid; 3969 cmd->tx_flags = param->tx_flags; 3970 cmd->peer_rssi = param->peer_rssi; 3971 3972 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3973 bufp, cmd->vdev_id, cmd->chanfreq); 3974 3975 bufp += roundup(bufp_len, sizeof(uint32_t)); 3976 if (param->tx_params_valid) { 3977 if (populate_tx_send_params(bufp, param->tx_param) != 3978 QDF_STATUS_SUCCESS) { 3979 wmi_err("Populate TX send params failed"); 3980 goto free_buf; 3981 } 3982 cmd_len += sizeof(wmi_tx_send_params); 3983 } 3984 3985 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3986 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3987 WMI_MGMT_TX_SEND_CMDID)) { 3988 wmi_err("Failed to send mgmt Tx"); 3989 goto free_buf; 3990 } 3991 return QDF_STATUS_SUCCESS; 3992 3993 free_buf: 3994 wmi_buf_free(buf); 3995 return QDF_STATUS_E_FAILURE; 3996 } 3997 #else 3998 /** 3999 * send_mgmt_cmd_tlv() - WMI scan start function 4000 * @wmi_handle : handle to WMI. 4001 * @param : pointer to hold mgmt cmd parameter 4002 * 4003 * Return: 0 on success and -ve on failure. 4004 */ 4005 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4006 struct wmi_mgmt_params *param) 4007 { 4008 wmi_buf_t buf; 4009 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4010 int32_t cmd_len; 4011 uint64_t dma_addr; 4012 void *qdf_ctx = param->qdf_ctx; 4013 uint8_t *bufp; 4014 QDF_STATUS status = QDF_STATUS_SUCCESS; 4015 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4016 mgmt_tx_dl_frm_len; 4017 4018 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4019 WMI_TLV_HDR_SIZE + 4020 roundup(bufp_len, sizeof(uint32_t)); 4021 4022 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4023 if (!buf) 4024 return QDF_STATUS_E_NOMEM; 4025 4026 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4027 bufp = (uint8_t *) cmd; 4028 WMITLV_SET_HDR(&cmd->tlv_header, 4029 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4030 WMITLV_GET_STRUCT_TLVLEN 4031 (wmi_mgmt_tx_send_cmd_fixed_param)); 4032 4033 cmd->vdev_id = param->vdev_id; 4034 4035 cmd->desc_id = param->desc_id; 4036 cmd->chanfreq = param->chanfreq; 4037 cmd->peer_rssi = param->peer_rssi; 4038 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4039 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4040 sizeof(uint32_t))); 4041 bufp += WMI_TLV_HDR_SIZE; 4042 4043 /* for big endian host, copy engine byte_swap is enabled 4044 * But the frame content is in network byte order 4045 * Need to byte swap the frame content - so when copy engine 4046 * does byte_swap - target gets frame content in the correct order 4047 */ 4048 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4049 4050 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4051 QDF_DMA_TO_DEVICE); 4052 if (status != QDF_STATUS_SUCCESS) { 4053 wmi_err("wmi buf map failed"); 4054 goto free_buf; 4055 } 4056 4057 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4058 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4059 #if defined(HTT_PADDR64) 4060 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4061 #endif 4062 cmd->frame_len = param->frm_len; 4063 cmd->buf_len = bufp_len; 4064 cmd->tx_params_valid = param->tx_params_valid; 4065 cmd->tx_flags = param->tx_flags; 4066 4067 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4068 bufp, cmd->vdev_id, cmd->chanfreq); 4069 4070 bufp += roundup(bufp_len, sizeof(uint32_t)); 4071 if (param->tx_params_valid) { 4072 status = populate_tx_send_params(bufp, param->tx_param); 4073 if (status != QDF_STATUS_SUCCESS) { 4074 wmi_err("Populate TX send params failed"); 4075 goto unmap_tx_frame; 4076 } 4077 cmd_len += sizeof(wmi_tx_send_params); 4078 } 4079 4080 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4081 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4082 WMI_MGMT_TX_SEND_CMDID)) { 4083 wmi_err("Failed to send mgmt Tx"); 4084 goto unmap_tx_frame; 4085 } 4086 return QDF_STATUS_SUCCESS; 4087 4088 unmap_tx_frame: 4089 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4090 QDF_DMA_TO_DEVICE); 4091 free_buf: 4092 wmi_buf_free(buf); 4093 return QDF_STATUS_E_FAILURE; 4094 } 4095 #endif /* CONFIG_HL_SUPPORT */ 4096 4097 /** 4098 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 4099 * @wmi_handle : handle to WMI. 4100 * @param : pointer to offchan data tx cmd parameter 4101 * 4102 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4103 */ 4104 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4105 struct wmi_offchan_data_tx_params *param) 4106 { 4107 wmi_buf_t buf; 4108 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4109 int32_t cmd_len; 4110 uint64_t dma_addr; 4111 void *qdf_ctx = param->qdf_ctx; 4112 uint8_t *bufp; 4113 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4114 param->frm_len : mgmt_tx_dl_frm_len; 4115 QDF_STATUS status = QDF_STATUS_SUCCESS; 4116 4117 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4118 WMI_TLV_HDR_SIZE + 4119 roundup(bufp_len, sizeof(uint32_t)); 4120 4121 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4122 if (!buf) 4123 return QDF_STATUS_E_NOMEM; 4124 4125 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4126 bufp = (uint8_t *) cmd; 4127 WMITLV_SET_HDR(&cmd->tlv_header, 4128 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4129 WMITLV_GET_STRUCT_TLVLEN 4130 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4131 4132 cmd->vdev_id = param->vdev_id; 4133 4134 cmd->desc_id = param->desc_id; 4135 cmd->chanfreq = param->chanfreq; 4136 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4137 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4138 sizeof(uint32_t))); 4139 bufp += WMI_TLV_HDR_SIZE; 4140 qdf_mem_copy(bufp, param->pdata, bufp_len); 4141 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4142 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4143 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4144 #if defined(HTT_PADDR64) 4145 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4146 #endif 4147 cmd->frame_len = param->frm_len; 4148 cmd->buf_len = bufp_len; 4149 cmd->tx_params_valid = param->tx_params_valid; 4150 4151 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4152 bufp, cmd->vdev_id, cmd->chanfreq); 4153 4154 bufp += roundup(bufp_len, sizeof(uint32_t)); 4155 if (param->tx_params_valid) { 4156 status = populate_tx_send_params(bufp, param->tx_param); 4157 if (status != QDF_STATUS_SUCCESS) { 4158 wmi_err("Populate TX send params failed"); 4159 goto err1; 4160 } 4161 cmd_len += sizeof(wmi_tx_send_params); 4162 } 4163 4164 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4165 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4166 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4167 wmi_err("Failed to offchan data Tx"); 4168 goto err1; 4169 } 4170 4171 return QDF_STATUS_SUCCESS; 4172 4173 err1: 4174 wmi_buf_free(buf); 4175 return QDF_STATUS_E_FAILURE; 4176 } 4177 4178 /** 4179 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4180 * @wmi_handle: wmi handle 4181 * @param_value: parameter value 4182 * 4183 * Return: QDF_STATUS_SUCCESS for success or error code 4184 */ 4185 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4186 uint32_t param_value) 4187 { 4188 QDF_STATUS ret; 4189 wmi_modem_power_state_cmd_param *cmd; 4190 wmi_buf_t buf; 4191 uint16_t len = sizeof(*cmd); 4192 4193 buf = wmi_buf_alloc(wmi_handle, len); 4194 if (!buf) 4195 return QDF_STATUS_E_NOMEM; 4196 4197 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4198 WMITLV_SET_HDR(&cmd->tlv_header, 4199 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4200 WMITLV_GET_STRUCT_TLVLEN 4201 (wmi_modem_power_state_cmd_param)); 4202 cmd->modem_power_state = param_value; 4203 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4204 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4205 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4206 WMI_MODEM_POWER_STATE_CMDID); 4207 if (QDF_IS_STATUS_ERROR(ret)) { 4208 wmi_err("Failed to send notify cmd ret = %d", ret); 4209 wmi_buf_free(buf); 4210 } 4211 4212 return ret; 4213 } 4214 4215 /** 4216 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4217 * @wmi_handle: wmi handle 4218 * @vdev_id: vdev id 4219 * @val: value 4220 * 4221 * Return: QDF_STATUS_SUCCESS for success or error code. 4222 */ 4223 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4224 uint32_t vdev_id, uint8_t val) 4225 { 4226 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4227 wmi_buf_t buf; 4228 int32_t len = sizeof(*cmd); 4229 4230 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4231 4232 buf = wmi_buf_alloc(wmi_handle, len); 4233 if (!buf) 4234 return QDF_STATUS_E_NOMEM; 4235 4236 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4237 WMITLV_SET_HDR(&cmd->tlv_header, 4238 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4239 WMITLV_GET_STRUCT_TLVLEN 4240 (wmi_sta_powersave_mode_cmd_fixed_param)); 4241 cmd->vdev_id = vdev_id; 4242 if (val) 4243 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4244 else 4245 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4246 4247 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4248 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4249 WMI_STA_POWERSAVE_MODE_CMDID)) { 4250 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4251 vdev_id, val); 4252 wmi_buf_free(buf); 4253 return QDF_STATUS_E_FAILURE; 4254 } 4255 return QDF_STATUS_SUCCESS; 4256 } 4257 4258 /** 4259 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4260 * @wmi_handle: wmi handle 4261 * @vdev_id: vdev id 4262 * 4263 * Return: QDF_STATUS_SUCCESS for success or error code. 4264 */ 4265 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4266 uint8_t val) 4267 { 4268 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4269 wmi_buf_t buf; 4270 size_t len = sizeof(*cmd); 4271 4272 buf = wmi_buf_alloc(wmi_handle, len); 4273 if (!buf) 4274 return QDF_STATUS_E_NOMEM; 4275 4276 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4277 WMITLV_SET_HDR(&cmd->tlv_header, 4278 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4279 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4280 4281 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4282 WMI_IDLE_TRIGGER_MONITOR_OFF); 4283 4284 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4285 4286 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4287 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4288 wmi_buf_free(buf); 4289 return QDF_STATUS_E_FAILURE; 4290 } 4291 return QDF_STATUS_SUCCESS; 4292 } 4293 4294 /** 4295 * send_set_mimops_cmd_tlv() - set MIMO powersave 4296 * @wmi_handle: wmi handle 4297 * @vdev_id: vdev id 4298 * @value: value 4299 * 4300 * Return: QDF_STATUS_SUCCESS for success or error code. 4301 */ 4302 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4303 uint8_t vdev_id, int value) 4304 { 4305 QDF_STATUS ret; 4306 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4307 wmi_buf_t buf; 4308 uint16_t len = sizeof(*cmd); 4309 4310 buf = wmi_buf_alloc(wmi_handle, len); 4311 if (!buf) 4312 return QDF_STATUS_E_NOMEM; 4313 4314 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4315 WMITLV_SET_HDR(&cmd->tlv_header, 4316 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4317 WMITLV_GET_STRUCT_TLVLEN 4318 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4319 4320 cmd->vdev_id = vdev_id; 4321 4322 /* WMI_SMPS_FORCED_MODE values do not directly map 4323 * to SM power save values defined in the specification. 4324 * Make sure to send the right mapping. 4325 */ 4326 switch (value) { 4327 case 0: 4328 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4329 break; 4330 case 1: 4331 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4332 break; 4333 case 2: 4334 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4335 break; 4336 case 3: 4337 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4338 break; 4339 default: 4340 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4341 wmi_buf_free(buf); 4342 return QDF_STATUS_E_FAILURE; 4343 } 4344 4345 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4346 4347 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4348 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4349 WMI_STA_SMPS_FORCE_MODE_CMDID); 4350 if (QDF_IS_STATUS_ERROR(ret)) { 4351 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4352 wmi_buf_free(buf); 4353 } 4354 4355 return ret; 4356 } 4357 4358 /** 4359 * send_set_smps_params_cmd_tlv() - set smps params 4360 * @wmi_handle: wmi handle 4361 * @vdev_id: vdev id 4362 * @value: value 4363 * 4364 * Return: QDF_STATUS_SUCCESS for success or error code. 4365 */ 4366 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4367 int value) 4368 { 4369 QDF_STATUS ret; 4370 wmi_sta_smps_param_cmd_fixed_param *cmd; 4371 wmi_buf_t buf; 4372 uint16_t len = sizeof(*cmd); 4373 4374 buf = wmi_buf_alloc(wmi_handle, len); 4375 if (!buf) 4376 return QDF_STATUS_E_NOMEM; 4377 4378 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4379 WMITLV_SET_HDR(&cmd->tlv_header, 4380 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4381 WMITLV_GET_STRUCT_TLVLEN 4382 (wmi_sta_smps_param_cmd_fixed_param)); 4383 4384 cmd->vdev_id = vdev_id; 4385 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4386 cmd->param = 4387 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4388 4389 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4390 cmd->param); 4391 4392 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4393 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4394 WMI_STA_SMPS_PARAM_CMDID); 4395 if (QDF_IS_STATUS_ERROR(ret)) { 4396 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4397 wmi_buf_free(buf); 4398 } 4399 4400 return ret; 4401 } 4402 4403 /** 4404 * send_get_temperature_cmd_tlv() - get pdev temperature req 4405 * @wmi_handle: wmi handle 4406 * 4407 * Return: QDF_STATUS_SUCCESS for success or error code. 4408 */ 4409 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4410 { 4411 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4412 wmi_buf_t wmi_buf; 4413 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4414 uint8_t *buf_ptr; 4415 4416 if (!wmi_handle) { 4417 wmi_err("WMI is closed, can not issue cmd"); 4418 return QDF_STATUS_E_INVAL; 4419 } 4420 4421 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4422 if (!wmi_buf) 4423 return QDF_STATUS_E_NOMEM; 4424 4425 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4426 4427 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4428 WMITLV_SET_HDR(&cmd->tlv_header, 4429 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4430 WMITLV_GET_STRUCT_TLVLEN 4431 (wmi_pdev_get_temperature_cmd_fixed_param)); 4432 4433 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4434 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4435 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4436 wmi_err("Failed to send get temperature command"); 4437 wmi_buf_free(wmi_buf); 4438 return QDF_STATUS_E_FAILURE; 4439 } 4440 4441 return QDF_STATUS_SUCCESS; 4442 } 4443 4444 /** 4445 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4446 * @wmi_handle: wmi handle 4447 * @vdevid: vdev id 4448 * @peer_addr: peer mac address 4449 * @auto_triggerparam: auto trigger parameters 4450 * @num_ac: number of access category 4451 * 4452 * This function sets the trigger 4453 * uapsd params such as service interval, delay interval 4454 * and suspend interval which will be used by the firmware 4455 * to send trigger frames periodically when there is no 4456 * traffic on the transmit side. 4457 * 4458 * Return: QDF_STATUS_SUCCESS for success or error code. 4459 */ 4460 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4461 struct sta_uapsd_trig_params *param) 4462 { 4463 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4464 QDF_STATUS ret; 4465 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4466 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4467 uint32_t i; 4468 wmi_buf_t buf; 4469 uint8_t *buf_ptr; 4470 struct sta_uapsd_params *uapsd_param; 4471 wmi_sta_uapsd_auto_trig_param *trig_param; 4472 4473 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4474 if (!buf) 4475 return QDF_STATUS_E_NOMEM; 4476 4477 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4478 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4479 WMITLV_SET_HDR(&cmd->tlv_header, 4480 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4481 WMITLV_GET_STRUCT_TLVLEN 4482 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4483 cmd->vdev_id = param->vdevid; 4484 cmd->num_ac = param->num_ac; 4485 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4486 4487 /* TLV indicating array of structures to follow */ 4488 buf_ptr += sizeof(*cmd); 4489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4490 4491 buf_ptr += WMI_TLV_HDR_SIZE; 4492 4493 /* 4494 * Update tag and length for uapsd auto trigger params (this will take 4495 * care of updating tag and length if it is not pre-filled by caller). 4496 */ 4497 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4498 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4499 for (i = 0; i < param->num_ac; i++) { 4500 WMITLV_SET_HDR((buf_ptr + 4501 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4502 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4503 WMITLV_GET_STRUCT_TLVLEN 4504 (wmi_sta_uapsd_auto_trig_param)); 4505 trig_param->wmm_ac = uapsd_param->wmm_ac; 4506 trig_param->user_priority = uapsd_param->user_priority; 4507 trig_param->service_interval = uapsd_param->service_interval; 4508 trig_param->suspend_interval = uapsd_param->suspend_interval; 4509 trig_param->delay_interval = uapsd_param->delay_interval; 4510 trig_param++; 4511 uapsd_param++; 4512 } 4513 4514 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4515 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4516 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4517 if (QDF_IS_STATUS_ERROR(ret)) { 4518 wmi_err("Failed to send set uapsd param ret = %d", ret); 4519 wmi_buf_free(buf); 4520 } 4521 4522 return ret; 4523 } 4524 4525 /** 4526 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4527 * @wmi_handle: Pointer to wmi handle 4528 * @thermal_info: Thermal command information 4529 * 4530 * This function sends the thermal management command 4531 * to the firmware 4532 * 4533 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4534 */ 4535 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4536 struct thermal_cmd_params *thermal_info) 4537 { 4538 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4539 wmi_buf_t buf = NULL; 4540 QDF_STATUS status; 4541 uint32_t len = 0; 4542 uint8_t action; 4543 4544 switch (thermal_info->thermal_action) { 4545 case THERMAL_MGMT_ACTION_DEFAULT: 4546 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4547 break; 4548 4549 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4550 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4551 break; 4552 4553 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4554 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4555 break; 4556 4557 case THERMAL_MGMT_ACTION_CHAINSCALING: 4558 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4559 break; 4560 4561 default: 4562 wmi_err("Invalid thermal_action code %d", 4563 thermal_info->thermal_action); 4564 return QDF_STATUS_E_FAILURE; 4565 } 4566 4567 len = sizeof(*cmd); 4568 4569 buf = wmi_buf_alloc(wmi_handle, len); 4570 if (!buf) 4571 return QDF_STATUS_E_FAILURE; 4572 4573 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4574 4575 WMITLV_SET_HDR(&cmd->tlv_header, 4576 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4577 WMITLV_GET_STRUCT_TLVLEN 4578 (wmi_thermal_mgmt_cmd_fixed_param)); 4579 4580 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4581 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4582 cmd->enable = thermal_info->thermal_enable; 4583 cmd->action = action; 4584 4585 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 4586 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 4587 cmd->enable, cmd->action); 4588 4589 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4590 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4591 WMI_THERMAL_MGMT_CMDID); 4592 if (QDF_IS_STATUS_ERROR(status)) { 4593 wmi_buf_free(buf); 4594 wmi_err("Failed to send thermal mgmt command"); 4595 } 4596 4597 return status; 4598 } 4599 4600 /** 4601 * send_lro_config_cmd_tlv() - process the LRO config command 4602 * @wmi_handle: Pointer to WMI handle 4603 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4604 * 4605 * This function sends down the LRO configuration parameters to 4606 * the firmware to enable LRO, sets the TCP flags and sets the 4607 * seed values for the toeplitz hash generation 4608 * 4609 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4610 */ 4611 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4612 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4613 { 4614 wmi_lro_info_cmd_fixed_param *cmd; 4615 wmi_buf_t buf; 4616 QDF_STATUS status; 4617 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4618 4619 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4620 if (!buf) 4621 return QDF_STATUS_E_FAILURE; 4622 4623 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4624 4625 WMITLV_SET_HDR(&cmd->tlv_header, 4626 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4627 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4628 4629 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4630 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4631 wmi_lro_cmd->tcp_flag); 4632 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4633 wmi_lro_cmd->tcp_flag_mask); 4634 cmd->toeplitz_hash_ipv4_0_3 = 4635 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4636 cmd->toeplitz_hash_ipv4_4_7 = 4637 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4638 cmd->toeplitz_hash_ipv4_8_11 = 4639 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4640 cmd->toeplitz_hash_ipv4_12_15 = 4641 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4642 cmd->toeplitz_hash_ipv4_16 = 4643 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4644 4645 cmd->toeplitz_hash_ipv6_0_3 = 4646 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4647 cmd->toeplitz_hash_ipv6_4_7 = 4648 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4649 cmd->toeplitz_hash_ipv6_8_11 = 4650 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4651 cmd->toeplitz_hash_ipv6_12_15 = 4652 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4653 cmd->toeplitz_hash_ipv6_16_19 = 4654 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4655 cmd->toeplitz_hash_ipv6_20_23 = 4656 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4657 cmd->toeplitz_hash_ipv6_24_27 = 4658 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4659 cmd->toeplitz_hash_ipv6_28_31 = 4660 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4661 cmd->toeplitz_hash_ipv6_32_35 = 4662 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4663 cmd->toeplitz_hash_ipv6_36_39 = 4664 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4665 cmd->toeplitz_hash_ipv6_40 = 4666 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4667 4668 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4669 wmi_handle, 4670 pdev_id); 4671 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4672 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4673 4674 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4675 status = wmi_unified_cmd_send(wmi_handle, buf, 4676 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4677 if (QDF_IS_STATUS_ERROR(status)) { 4678 wmi_buf_free(buf); 4679 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 4680 } 4681 4682 return status; 4683 } 4684 4685 /** 4686 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4687 * @wmi_handle: Pointer to wmi handle 4688 * @rate_report_params: Pointer to peer rate report parameters 4689 * 4690 * 4691 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4692 */ 4693 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4694 struct wmi_peer_rate_report_params *rate_report_params) 4695 { 4696 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4697 wmi_buf_t buf = NULL; 4698 QDF_STATUS status = 0; 4699 uint32_t len = 0; 4700 uint32_t i, j; 4701 4702 len = sizeof(*cmd); 4703 4704 buf = wmi_buf_alloc(wmi_handle, len); 4705 if (!buf) 4706 return QDF_STATUS_E_FAILURE; 4707 4708 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4709 wmi_buf_data(buf); 4710 4711 WMITLV_SET_HDR( 4712 &cmd->tlv_header, 4713 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4714 WMITLV_GET_STRUCT_TLVLEN( 4715 wmi_peer_set_rate_report_condition_fixed_param)); 4716 4717 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4718 cmd->report_backoff_time = rate_report_params->backoff_time; 4719 cmd->report_timer_period = rate_report_params->timer_period; 4720 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4721 cmd->cond_per_phy[i].val_cond_flags = 4722 rate_report_params->report_per_phy[i].cond_flags; 4723 cmd->cond_per_phy[i].rate_delta.min_delta = 4724 rate_report_params->report_per_phy[i].delta.delta_min; 4725 cmd->cond_per_phy[i].rate_delta.percentage = 4726 rate_report_params->report_per_phy[i].delta.percent; 4727 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4728 cmd->cond_per_phy[i].rate_threshold[j] = 4729 rate_report_params->report_per_phy[i]. 4730 report_rate_threshold[j]; 4731 } 4732 } 4733 4734 wmi_debug("enable %d backoff_time %d period %d", 4735 cmd->enable_rate_report, 4736 cmd->report_backoff_time, cmd->report_timer_period); 4737 4738 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4739 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4740 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4741 if (QDF_IS_STATUS_ERROR(status)) { 4742 wmi_buf_free(buf); 4743 wmi_err("Failed to send peer_set_report_cond command"); 4744 } 4745 return status; 4746 } 4747 4748 /** 4749 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4750 * @wmi_handle: wmi handle 4751 * @vdev_id: vdev id. 4752 * @wmm_vparams: edca parameters 4753 * 4754 * This function updates EDCA parameters to the target 4755 * 4756 * Return: CDF Status 4757 */ 4758 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4759 uint8_t vdev_id, bool mu_edca_param, 4760 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4761 { 4762 uint8_t *buf_ptr; 4763 wmi_buf_t buf; 4764 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4765 wmi_wmm_vparams *wmm_param; 4766 struct wmi_host_wme_vparams *twmm_param; 4767 int len = sizeof(*cmd); 4768 int ac; 4769 4770 buf = wmi_buf_alloc(wmi_handle, len); 4771 4772 if (!buf) 4773 return QDF_STATUS_E_NOMEM; 4774 4775 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4776 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4777 WMITLV_SET_HDR(&cmd->tlv_header, 4778 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4779 WMITLV_GET_STRUCT_TLVLEN 4780 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4781 cmd->vdev_id = vdev_id; 4782 cmd->wmm_param_type = mu_edca_param; 4783 4784 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4785 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4786 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4787 WMITLV_SET_HDR(&wmm_param->tlv_header, 4788 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4789 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4790 wmm_param->cwmin = twmm_param->cwmin; 4791 wmm_param->cwmax = twmm_param->cwmax; 4792 wmm_param->aifs = twmm_param->aifs; 4793 if (mu_edca_param) 4794 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4795 else 4796 wmm_param->txoplimit = twmm_param->txoplimit; 4797 wmm_param->acm = twmm_param->acm; 4798 wmm_param->no_ack = twmm_param->noackpolicy; 4799 } 4800 4801 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4802 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4803 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4804 goto fail; 4805 4806 return QDF_STATUS_SUCCESS; 4807 4808 fail: 4809 wmi_buf_free(buf); 4810 wmi_err("Failed to set WMM Parameters"); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 4814 /** 4815 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4816 * @wmi_handle: wmi handle 4817 * @vdev_id: vdev id 4818 * @probe_rsp_info: probe response info 4819 * 4820 * Return: QDF_STATUS_SUCCESS for success or error code 4821 */ 4822 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4823 uint8_t vdev_id, 4824 struct wmi_probe_resp_params *probe_rsp_info) 4825 { 4826 wmi_prb_tmpl_cmd_fixed_param *cmd; 4827 wmi_bcn_prb_info *bcn_prb_info; 4828 wmi_buf_t wmi_buf; 4829 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4830 uint8_t *buf_ptr; 4831 QDF_STATUS ret; 4832 4833 wmi_debug("Send probe response template for vdev %d", vdev_id); 4834 4835 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4836 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4837 4838 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4839 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4840 tmpl_len_aligned; 4841 4842 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4843 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 4844 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4845 return QDF_STATUS_E_INVAL; 4846 } 4847 4848 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4849 if (!wmi_buf) 4850 return QDF_STATUS_E_NOMEM; 4851 4852 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4853 4854 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4855 WMITLV_SET_HDR(&cmd->tlv_header, 4856 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4857 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4858 cmd->vdev_id = vdev_id; 4859 cmd->buf_len = tmpl_len; 4860 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4861 4862 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4863 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4864 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4865 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4866 bcn_prb_info->caps = 0; 4867 bcn_prb_info->erp = 0; 4868 buf_ptr += sizeof(wmi_bcn_prb_info); 4869 4870 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4871 buf_ptr += WMI_TLV_HDR_SIZE; 4872 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4873 4874 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4875 ret = wmi_unified_cmd_send(wmi_handle, 4876 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4877 if (QDF_IS_STATUS_ERROR(ret)) { 4878 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 4879 wmi_buf_free(wmi_buf); 4880 } 4881 4882 return ret; 4883 } 4884 4885 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4886 #define WPI_IV_LEN 16 4887 4888 /** 4889 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4890 * 4891 * @dest_tx: destination address of tsc key counter 4892 * @src_tx: source address of tsc key counter 4893 * @dest_rx: destination address of rsc key counter 4894 * @src_rx: source address of rsc key counter 4895 * 4896 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4897 * 4898 * Return: None 4899 * 4900 */ 4901 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4902 uint8_t *dest_rx, uint8_t *src_rx) 4903 { 4904 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4905 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4906 } 4907 #else 4908 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4909 uint8_t *dest_rx, uint8_t *src_rx) 4910 { 4911 return; 4912 } 4913 #endif 4914 4915 /** 4916 * send_setup_install_key_cmd_tlv() - set key parameters 4917 * @wmi_handle: wmi handle 4918 * @key_params: key parameters 4919 * 4920 * This function fills structure from information 4921 * passed in key_params. 4922 * 4923 * Return: QDF_STATUS_SUCCESS - success 4924 * QDF_STATUS_E_FAILURE - failure 4925 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4926 */ 4927 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4928 struct set_key_params *key_params) 4929 { 4930 wmi_vdev_install_key_cmd_fixed_param *cmd; 4931 wmi_buf_t buf; 4932 uint8_t *buf_ptr; 4933 uint32_t len; 4934 uint8_t *key_data; 4935 QDF_STATUS status; 4936 4937 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4938 WMI_TLV_HDR_SIZE; 4939 4940 buf = wmi_buf_alloc(wmi_handle, len); 4941 if (!buf) 4942 return QDF_STATUS_E_NOMEM; 4943 4944 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4945 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4946 WMITLV_SET_HDR(&cmd->tlv_header, 4947 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4948 WMITLV_GET_STRUCT_TLVLEN 4949 (wmi_vdev_install_key_cmd_fixed_param)); 4950 cmd->vdev_id = key_params->vdev_id; 4951 cmd->key_ix = key_params->key_idx; 4952 if (key_params->group_key_idx) { 4953 cmd->is_group_key_ix_valid = 1; 4954 cmd->group_key_ix = key_params->group_key_idx; 4955 } 4956 4957 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4958 cmd->key_flags |= key_params->key_flags; 4959 cmd->key_cipher = key_params->key_cipher; 4960 if ((key_params->key_txmic_len) && 4961 (key_params->key_rxmic_len)) { 4962 cmd->key_txmic_len = key_params->key_txmic_len; 4963 cmd->key_rxmic_len = key_params->key_rxmic_len; 4964 } 4965 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4966 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4967 key_params->tx_iv, 4968 cmd->wpi_key_rsc_counter, 4969 key_params->rx_iv); 4970 #endif 4971 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4972 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4973 roundup(key_params->key_len, sizeof(uint32_t))); 4974 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4975 4976 /* for big endian host, copy engine byte_swap is enabled 4977 * But key_data is in network byte order 4978 * Need to byte swap the key_data - so when copy engine 4979 * does byte_swap - target gets key_data in the correct order 4980 */ 4981 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 4982 (const void *)key_params->key_data, 4983 key_params->key_len); 4984 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4985 sizeof(wmi_key_seq_counter)); 4986 cmd->key_len = key_params->key_len; 4987 4988 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4989 sizeof(wmi_key_seq_counter)); 4990 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4991 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4992 WMI_VDEV_INSTALL_KEY_CMDID); 4993 if (QDF_IS_STATUS_ERROR(status)) { 4994 qdf_mem_zero(wmi_buf_data(buf), len); 4995 wmi_buf_free(buf); 4996 } 4997 return status; 4998 } 4999 5000 /** 5001 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5002 * @wmi_handle: wmi handle 5003 * @vdev_id: vdev id 5004 * @p2p_ie: p2p IE 5005 * 5006 * Return: QDF_STATUS_SUCCESS for success or error code 5007 */ 5008 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5009 uint32_t vdev_id, uint8_t *p2p_ie) 5010 { 5011 QDF_STATUS ret; 5012 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5013 wmi_buf_t wmi_buf; 5014 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5015 uint8_t *buf_ptr; 5016 5017 ie_len = (uint32_t) (p2p_ie[1] + 2); 5018 5019 /* More than one P2P IE may be included in a single frame. 5020 If multiple P2P IEs are present, the complete P2P attribute 5021 data consists of the concatenation of the P2P Attribute 5022 fields of the P2P IEs. The P2P Attributes field of each 5023 P2P IE may be any length up to the maximum (251 octets). 5024 In this case host sends one P2P IE to firmware so the length 5025 should not exceed more than 251 bytes 5026 */ 5027 if (ie_len > 251) { 5028 wmi_err("Invalid p2p ie length %u", ie_len); 5029 return QDF_STATUS_E_INVAL; 5030 } 5031 5032 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5033 5034 wmi_buf_len = 5035 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5036 WMI_TLV_HDR_SIZE; 5037 5038 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5039 if (!wmi_buf) 5040 return QDF_STATUS_E_NOMEM; 5041 5042 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5043 5044 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5045 WMITLV_SET_HDR(&cmd->tlv_header, 5046 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5047 WMITLV_GET_STRUCT_TLVLEN 5048 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5049 cmd->vdev_id = vdev_id; 5050 cmd->ie_buf_len = ie_len; 5051 5052 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5053 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5054 buf_ptr += WMI_TLV_HDR_SIZE; 5055 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5056 5057 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5058 5059 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5060 ret = wmi_unified_cmd_send(wmi_handle, 5061 wmi_buf, wmi_buf_len, 5062 WMI_P2P_GO_SET_BEACON_IE); 5063 if (QDF_IS_STATUS_ERROR(ret)) { 5064 wmi_err("Failed to send bcn tmpl: %d", ret); 5065 wmi_buf_free(wmi_buf); 5066 } 5067 5068 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5069 return ret; 5070 } 5071 5072 /** 5073 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5074 * @wmi_handle: wmi handle 5075 * @psetoui: OUI parameters 5076 * 5077 * set scan probe OUI parameters in firmware 5078 * 5079 * Return: CDF status 5080 */ 5081 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5082 struct scan_mac_oui *psetoui) 5083 { 5084 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5085 wmi_buf_t wmi_buf; 5086 uint32_t len; 5087 uint8_t *buf_ptr; 5088 uint32_t *oui_buf; 5089 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5090 5091 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5092 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5093 5094 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5095 if (!wmi_buf) 5096 return QDF_STATUS_E_NOMEM; 5097 5098 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5099 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5100 WMITLV_SET_HDR(&cmd->tlv_header, 5101 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5102 WMITLV_GET_STRUCT_TLVLEN 5103 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5104 5105 oui_buf = &cmd->prob_req_oui; 5106 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5107 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5108 | psetoui->oui[2]; 5109 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5110 5111 cmd->vdev_id = psetoui->vdev_id; 5112 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5113 if (psetoui->enb_probe_req_sno_randomization) 5114 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5115 5116 if (ie_allowlist->allow_list) { 5117 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5118 &cmd->num_vendor_oui, 5119 ie_allowlist); 5120 cmd->flags |= 5121 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5122 } 5123 5124 buf_ptr += sizeof(*cmd); 5125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5126 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5127 buf_ptr += WMI_TLV_HDR_SIZE; 5128 5129 if (cmd->num_vendor_oui != 0) { 5130 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5131 ie_allowlist->voui); 5132 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5133 } 5134 5135 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5136 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5137 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5138 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5139 wmi_buf_free(wmi_buf); 5140 return QDF_STATUS_E_FAILURE; 5141 } 5142 return QDF_STATUS_SUCCESS; 5143 } 5144 5145 #ifdef IPA_OFFLOAD 5146 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5147 * @wmi_handle: wmi handle 5148 * @ipa_offload: ipa offload control parameter 5149 * 5150 * Returns: 0 on success, error number otherwise 5151 */ 5152 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5153 struct ipa_uc_offload_control_params *ipa_offload) 5154 { 5155 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5156 wmi_buf_t wmi_buf; 5157 uint32_t len; 5158 u_int8_t *buf_ptr; 5159 5160 len = sizeof(*cmd); 5161 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5162 if (!wmi_buf) 5163 return QDF_STATUS_E_NOMEM; 5164 5165 wmi_debug("offload_type=%d, enable=%d", 5166 ipa_offload->offload_type, ipa_offload->enable); 5167 5168 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5169 5170 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5171 WMITLV_SET_HDR(&cmd->tlv_header, 5172 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5173 WMITLV_GET_STRUCT_TLVLEN( 5174 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5175 5176 cmd->offload_type = ipa_offload->offload_type; 5177 cmd->vdev_id = ipa_offload->vdev_id; 5178 cmd->enable = ipa_offload->enable; 5179 5180 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5181 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5182 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5183 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5184 wmi_buf_free(wmi_buf); 5185 return QDF_STATUS_E_FAILURE; 5186 } 5187 5188 return QDF_STATUS_SUCCESS; 5189 } 5190 #endif 5191 5192 /** 5193 * send_pno_stop_cmd_tlv() - PNO stop request 5194 * @wmi_handle: wmi handle 5195 * @vdev_id: vdev id 5196 * 5197 * This function request FW to stop ongoing PNO operation. 5198 * 5199 * Return: CDF status 5200 */ 5201 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5202 { 5203 wmi_nlo_config_cmd_fixed_param *cmd; 5204 int32_t len = sizeof(*cmd); 5205 wmi_buf_t buf; 5206 uint8_t *buf_ptr; 5207 int ret; 5208 5209 /* 5210 * TLV place holder for array of structures nlo_configured_parameters 5211 * TLV place holder for array of uint32_t channel_list 5212 * TLV place holder for chnl prediction cfg 5213 */ 5214 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5215 buf = wmi_buf_alloc(wmi_handle, len); 5216 if (!buf) 5217 return QDF_STATUS_E_NOMEM; 5218 5219 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5220 buf_ptr = (uint8_t *) cmd; 5221 5222 WMITLV_SET_HDR(&cmd->tlv_header, 5223 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5224 WMITLV_GET_STRUCT_TLVLEN 5225 (wmi_nlo_config_cmd_fixed_param)); 5226 5227 cmd->vdev_id = vdev_id; 5228 cmd->flags = WMI_NLO_CONFIG_STOP; 5229 buf_ptr += sizeof(*cmd); 5230 5231 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5232 buf_ptr += WMI_TLV_HDR_SIZE; 5233 5234 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5235 buf_ptr += WMI_TLV_HDR_SIZE; 5236 5237 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5238 buf_ptr += WMI_TLV_HDR_SIZE; 5239 5240 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5241 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5242 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5243 if (ret) { 5244 wmi_err("Failed to send nlo wmi cmd"); 5245 wmi_buf_free(buf); 5246 return QDF_STATUS_E_FAILURE; 5247 } 5248 5249 return QDF_STATUS_SUCCESS; 5250 } 5251 5252 /** 5253 * send_obss_disable_cmd_tlv() - disable obss scan request 5254 * @wmi_handle: wmi handle 5255 * @vdev_id: vdev id 5256 * 5257 * This function request FW to disable ongoing obss scan operation. 5258 * 5259 * Return: QDF status 5260 */ 5261 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5262 uint8_t vdev_id) 5263 { 5264 QDF_STATUS status; 5265 wmi_buf_t buf; 5266 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5267 int len = sizeof(*cmd); 5268 5269 buf = wmi_buf_alloc(wmi_handle, len); 5270 if (!buf) 5271 return QDF_STATUS_E_NOMEM; 5272 5273 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5274 5275 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5276 WMITLV_SET_HDR(&cmd->tlv_header, 5277 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5278 WMITLV_GET_STRUCT_TLVLEN( 5279 wmi_obss_scan_disable_cmd_fixed_param)); 5280 5281 cmd->vdev_id = vdev_id; 5282 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5283 WMI_OBSS_SCAN_DISABLE_CMDID); 5284 if (QDF_IS_STATUS_ERROR(status)) 5285 wmi_buf_free(buf); 5286 5287 return status; 5288 } 5289 5290 /** 5291 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5292 * @buf_ptr: Buffer passed by upper layers 5293 * @pno: Buffer to be sent to the firmware 5294 * 5295 * Copy the PNO Channel prediction configuration parameters 5296 * passed by the upper layers to a WMI format TLV and send it 5297 * down to the firmware. 5298 * 5299 * Return: None 5300 */ 5301 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5302 struct pno_scan_req_params *pno) 5303 { 5304 nlo_channel_prediction_cfg *channel_prediction_cfg = 5305 (nlo_channel_prediction_cfg *) buf_ptr; 5306 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5307 WMITLV_TAG_ARRAY_BYTE, 5308 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5309 #ifdef FEATURE_WLAN_SCAN_PNO 5310 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5311 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5312 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5313 channel_prediction_cfg->full_scan_period_ms = 5314 pno->channel_prediction_full_scan; 5315 #endif 5316 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5317 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5318 channel_prediction_cfg->enable, 5319 channel_prediction_cfg->top_k_num, 5320 channel_prediction_cfg->stationary_threshold, 5321 channel_prediction_cfg->full_scan_period_ms); 5322 } 5323 5324 /** 5325 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5326 * @wmi_handle: wmi handle 5327 * @buf_ptr: Buffer passed by upper layers 5328 * @buf_len: Length of passed buffer by upper layer 5329 * 5330 * Copy the buffer passed by the upper layers and send it 5331 * down to the firmware. 5332 * 5333 * Return: None 5334 */ 5335 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5336 void *buf_ptr, uint32_t buf_len) 5337 { 5338 wmi_buf_t buf = NULL; 5339 QDF_STATUS status; 5340 int len; 5341 uint8_t *data_ptr; 5342 5343 len = buf_len; 5344 buf = wmi_buf_alloc(wmi_handle, len); 5345 if (!buf) 5346 return QDF_STATUS_E_NOMEM; 5347 5348 data_ptr = (uint8_t *)wmi_buf_data(buf); 5349 qdf_mem_copy(data_ptr, buf_ptr, len); 5350 5351 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5352 status = wmi_unified_cmd_send(wmi_handle, buf, 5353 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5354 5355 if (QDF_IS_STATUS_ERROR(status)) { 5356 wmi_buf_free(buf); 5357 return QDF_STATUS_E_FAILURE; 5358 } 5359 return QDF_STATUS_SUCCESS; 5360 } 5361 5362 /** 5363 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 5364 * @wmi_handle: wmi handle 5365 * @buf_ptr: Buffer passed by upper layers 5366 * @buf_len: Length of passed buffer by upper layer 5367 * 5368 * Copy the buffer passed by the upper layers and send it 5369 * down to the firmware. 5370 * 5371 * Return: None 5372 */ 5373 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 5374 void *buf_ptr, uint32_t buf_len) 5375 { 5376 wmi_buf_t buf = NULL; 5377 QDF_STATUS status; 5378 int len; 5379 uint8_t *data_ptr; 5380 5381 len = buf_len; 5382 buf = wmi_buf_alloc(wmi_handle, len); 5383 if (!buf) 5384 return QDF_STATUS_E_NOMEM; 5385 5386 data_ptr = (uint8_t *)wmi_buf_data(buf); 5387 qdf_mem_copy(data_ptr, buf_ptr, len); 5388 5389 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5390 status = wmi_unified_cmd_send(wmi_handle, buf, 5391 len, 5392 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 5393 5394 if (QDF_IS_STATUS_ERROR(status)) { 5395 wmi_buf_free(buf); 5396 return QDF_STATUS_E_FAILURE; 5397 } 5398 return QDF_STATUS_SUCCESS; 5399 } 5400 5401 /** 5402 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5403 * @wmi_handle: wmi handle 5404 * @evt_buf: event buffer 5405 * @more_flag: buffer to populate more flag 5406 * 5407 * Return: status of operation 5408 */ 5409 static QDF_STATUS 5410 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5411 uint32_t *more_flag) 5412 { 5413 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5414 wmi_ctrl_path_stats_event_fixed_param *ev; 5415 5416 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5417 if (!param_buf) { 5418 wmi_err_rl("param_buf is NULL"); 5419 return QDF_STATUS_E_FAILURE; 5420 } 5421 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5422 5423 *more_flag = ev->more; 5424 return QDF_STATUS_SUCCESS; 5425 } 5426 5427 /** 5428 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 5429 * from event data 5430 * @wmi_handle: wmi handle 5431 * @evt_buf: event buffer 5432 * @end_of_event_flag: buffer to populate end_of_event flag 5433 * 5434 * Return: status of operation 5435 */ 5436 static QDF_STATUS 5437 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi, void *evt_buf, 5438 uint32_t *end_of_event_flag) 5439 { 5440 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5441 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5442 5443 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5444 if (!param_buf) { 5445 wmi_err_rl("param_buf is NULL"); 5446 return QDF_STATUS_E_FAILURE; 5447 } 5448 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5449 param_buf->fixed_param; 5450 5451 *end_of_event_flag = ev->end_of_event; 5452 return QDF_STATUS_SUCCESS; 5453 } 5454 5455 /** 5456 * extract_halphy_stats_event_count - api to extract event count flag from 5457 * event data 5458 * @wmi_handle: wmi handle 5459 * @evt_buf: event buffer 5460 * @event_count_flag: buffer to populate event_count flag 5461 * 5462 * Return: status of operation 5463 */ 5464 static QDF_STATUS 5465 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi, void *evt_buf, 5466 uint32_t *event_count_flag) 5467 { 5468 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5469 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5470 5471 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5472 if (!param_buf) { 5473 wmi_err_rl("param_buf is NULL"); 5474 return QDF_STATUS_E_FAILURE; 5475 } 5476 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5477 param_buf->fixed_param; 5478 5479 *event_count_flag = ev->event_count; 5480 return QDF_STATUS_SUCCESS; 5481 } 5482 5483 /** 5484 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 5485 * @wmi_handle: wmi handle 5486 * @params: configuration parameters 5487 * 5488 * Return: QDF_STATUS 5489 */ 5490 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 5491 struct nlo_mawc_params *params) 5492 { 5493 wmi_buf_t buf = NULL; 5494 QDF_STATUS status; 5495 int len; 5496 uint8_t *buf_ptr; 5497 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 5498 5499 len = sizeof(*wmi_nlo_mawc_params); 5500 buf = wmi_buf_alloc(wmi_handle, len); 5501 if (!buf) 5502 return QDF_STATUS_E_NOMEM; 5503 5504 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5505 wmi_nlo_mawc_params = 5506 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 5507 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 5508 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 5509 WMITLV_GET_STRUCT_TLVLEN 5510 (wmi_nlo_configure_mawc_cmd_fixed_param)); 5511 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 5512 if (params->enable) 5513 wmi_nlo_mawc_params->enable = 1; 5514 else 5515 wmi_nlo_mawc_params->enable = 0; 5516 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 5517 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 5518 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 5519 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 5520 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 5521 wmi_nlo_mawc_params->exp_backoff_ratio, 5522 wmi_nlo_mawc_params->init_scan_interval, 5523 wmi_nlo_mawc_params->max_scan_interval); 5524 5525 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 5526 status = wmi_unified_cmd_send(wmi_handle, buf, 5527 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 5528 if (QDF_IS_STATUS_ERROR(status)) { 5529 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 5530 status); 5531 wmi_buf_free(buf); 5532 return QDF_STATUS_E_FAILURE; 5533 } 5534 5535 return QDF_STATUS_SUCCESS; 5536 } 5537 5538 /** 5539 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 5540 * scan 5541 * @scan_freq_list: frequency list for pno scan 5542 * 5543 * Return: void 5544 */ 5545 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 5546 { 5547 uint32_t i; 5548 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 5549 uint32_t len = 0; 5550 struct chan_info *chan_info; 5551 int ret; 5552 5553 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 5554 for (i = 0; i < scan_freq_list->num_chan; i++) { 5555 chan_info = &scan_freq_list->chan[i]; 5556 ret = qdf_scnprintf(info + len, sizeof(info) - len, 5557 " %d[%d]", chan_info->freq, 5558 chan_info->flags); 5559 if (ret <= 0) 5560 break; 5561 len += ret; 5562 if (len >= (sizeof(info) - 20)) { 5563 wmi_nofl_debug("Freq[flag]:%s", 5564 info); 5565 len = 0; 5566 } 5567 } 5568 if (len) 5569 wmi_nofl_debug("Freq[flag]:%s", info); 5570 } 5571 5572 /** 5573 * send_pno_start_cmd_tlv() - PNO start request 5574 * @wmi_handle: wmi handle 5575 * @pno: PNO request 5576 * 5577 * This function request FW to start PNO request. 5578 * Request: CDF status 5579 */ 5580 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 5581 struct pno_scan_req_params *pno) 5582 { 5583 wmi_nlo_config_cmd_fixed_param *cmd; 5584 nlo_configured_parameters *nlo_list; 5585 uint32_t *channel_list; 5586 int32_t len; 5587 qdf_freq_t freq; 5588 wmi_buf_t buf; 5589 uint8_t *buf_ptr; 5590 uint8_t i; 5591 int ret; 5592 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 5593 connected_nlo_rssi_params *nlo_relative_rssi; 5594 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 5595 5596 /* 5597 * TLV place holder for array nlo_configured_parameters(nlo_list) 5598 * TLV place holder for array of uint32_t channel_list 5599 * TLV place holder for chnnl prediction cfg 5600 * TLV place holder for array of wmi_vendor_oui 5601 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 5602 */ 5603 len = sizeof(*cmd) + 5604 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 5605 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5606 5607 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 5608 len += sizeof(nlo_configured_parameters) * 5609 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5610 len += sizeof(nlo_channel_prediction_cfg); 5611 len += sizeof(enlo_candidate_score_params); 5612 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 5613 len += sizeof(connected_nlo_rssi_params); 5614 len += sizeof(connected_nlo_bss_band_rssi_pref); 5615 5616 buf = wmi_buf_alloc(wmi_handle, len); 5617 if (!buf) 5618 return QDF_STATUS_E_NOMEM; 5619 5620 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5621 5622 buf_ptr = (uint8_t *) cmd; 5623 WMITLV_SET_HDR(&cmd->tlv_header, 5624 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5625 WMITLV_GET_STRUCT_TLVLEN 5626 (wmi_nlo_config_cmd_fixed_param)); 5627 cmd->vdev_id = pno->vdev_id; 5628 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 5629 5630 #ifdef FEATURE_WLAN_SCAN_PNO 5631 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 5632 pno->adaptive_dwell_mode); 5633 #endif 5634 /* Current FW does not support min-max range for dwell time */ 5635 cmd->active_dwell_time = pno->active_dwell_time; 5636 cmd->passive_dwell_time = pno->passive_dwell_time; 5637 5638 if (pno->do_passive_scan) 5639 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 5640 /* Copy scan interval */ 5641 cmd->fast_scan_period = pno->fast_scan_period; 5642 cmd->slow_scan_period = pno->slow_scan_period; 5643 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 5644 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 5645 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 5646 5647 /* mac randomization attributes */ 5648 if (pno->scan_random.randomize) { 5649 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 5650 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 5651 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 5652 pno->scan_random.mac_mask, 5653 &cmd->mac_addr, 5654 &cmd->mac_mask); 5655 } 5656 5657 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 5658 5659 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5660 5661 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5662 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 5663 buf_ptr += WMI_TLV_HDR_SIZE; 5664 5665 nlo_list = (nlo_configured_parameters *) buf_ptr; 5666 for (i = 0; i < cmd->no_of_ssids; i++) { 5667 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 5668 WMITLV_TAG_ARRAY_BYTE, 5669 WMITLV_GET_STRUCT_TLVLEN 5670 (nlo_configured_parameters)); 5671 /* Copy ssid and it's length */ 5672 nlo_list[i].ssid.valid = true; 5673 nlo_list[i].ssid.ssid.ssid_len = 5674 pno->networks_list[i].ssid.length; 5675 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 5676 pno->networks_list[i].ssid.ssid, 5677 nlo_list[i].ssid.ssid.ssid_len); 5678 5679 /* Copy rssi threshold */ 5680 if (pno->networks_list[i].rssi_thresh && 5681 pno->networks_list[i].rssi_thresh > 5682 WMI_RSSI_THOLD_DEFAULT) { 5683 nlo_list[i].rssi_cond.valid = true; 5684 nlo_list[i].rssi_cond.rssi = 5685 pno->networks_list[i].rssi_thresh; 5686 } 5687 nlo_list[i].bcast_nw_type.valid = true; 5688 nlo_list[i].bcast_nw_type.bcast_nw_type = 5689 pno->networks_list[i].bc_new_type; 5690 } 5691 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 5692 5693 /* Copy channel info */ 5694 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 5695 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5696 (cmd->num_of_channels * sizeof(uint32_t))); 5697 buf_ptr += WMI_TLV_HDR_SIZE; 5698 5699 channel_list = (uint32_t *) buf_ptr; 5700 for (i = 0; i < cmd->num_of_channels; i++) { 5701 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 5702 pno->networks_list[0].pno_chan_list.chan[i].freq); 5703 5704 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 5705 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 5706 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 5707 wlan_chan_to_freq(freq)); 5708 } 5709 5710 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 5711 pno->networks_list[0].pno_chan_list.chan[i].flags); 5712 } 5713 5714 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 5715 5716 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 5717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5718 sizeof(nlo_channel_prediction_cfg)); 5719 buf_ptr += WMI_TLV_HDR_SIZE; 5720 wmi_set_pno_channel_prediction(buf_ptr, pno); 5721 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5722 /** TODO: Discrete firmware doesn't have command/option to configure 5723 * App IE which comes from wpa_supplicant as of part PNO start request. 5724 */ 5725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 5726 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 5727 buf_ptr += sizeof(enlo_candidate_score_params); 5728 5729 if (ie_allowlist->allow_list) { 5730 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5731 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5732 &cmd->num_vendor_oui, 5733 ie_allowlist); 5734 } 5735 5736 /* ie allow list */ 5737 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5738 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5739 buf_ptr += WMI_TLV_HDR_SIZE; 5740 if (cmd->num_vendor_oui != 0) { 5741 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5742 ie_allowlist->voui); 5743 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5744 } 5745 5746 if (pno->relative_rssi_set) 5747 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 5748 5749 /* 5750 * Firmware calculation using connected PNO params: 5751 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 5752 * deduction of rssi_pref for chosen band_pref and 5753 * addition of rssi_pref for remaining bands (other than chosen band). 5754 */ 5755 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 5756 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 5757 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 5758 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 5759 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 5760 buf_ptr += sizeof(*nlo_relative_rssi); 5761 5762 /* 5763 * As of now Kernel and Host supports one band and rssi preference. 5764 * Firmware supports array of band and rssi preferences 5765 */ 5766 cmd->num_cnlo_band_pref = 1; 5767 WMITLV_SET_HDR(buf_ptr, 5768 WMITLV_TAG_ARRAY_STRUC, 5769 cmd->num_cnlo_band_pref * 5770 sizeof(connected_nlo_bss_band_rssi_pref)); 5771 buf_ptr += WMI_TLV_HDR_SIZE; 5772 5773 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 5774 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 5775 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5776 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5777 WMITLV_GET_STRUCT_TLVLEN( 5778 connected_nlo_bss_band_rssi_pref)); 5779 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5780 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5781 } 5782 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5783 5784 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5785 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5786 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5787 if (ret) { 5788 wmi_err("Failed to send nlo wmi cmd"); 5789 wmi_buf_free(buf); 5790 return QDF_STATUS_E_FAILURE; 5791 } 5792 5793 return QDF_STATUS_SUCCESS; 5794 } 5795 5796 /** 5797 * is_service_enabled_tlv() - Check if service enabled 5798 * @param wmi_handle: wmi handle 5799 * @param service_id: service identifier 5800 * 5801 * Return: 1 enabled, 0 disabled 5802 */ 5803 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 5804 uint32_t service_id) 5805 { 5806 struct wmi_soc *soc = wmi_handle->soc; 5807 5808 if (!soc->wmi_service_bitmap) { 5809 wmi_err("WMI service bit map is not saved yet"); 5810 return false; 5811 } 5812 5813 /* if wmi_service_enabled was received with extended2 bitmap, 5814 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 5815 */ 5816 if (soc->wmi_ext2_service_bitmap) { 5817 if (!soc->wmi_ext_service_bitmap) { 5818 wmi_err("WMI service ext bit map is not saved yet"); 5819 return false; 5820 } 5821 5822 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 5823 soc->wmi_ext_service_bitmap, 5824 soc->wmi_ext2_service_bitmap, 5825 service_id); 5826 } 5827 5828 if (service_id >= WMI_MAX_EXT_SERVICE) { 5829 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 5830 service_id); 5831 return false; 5832 } 5833 /* if wmi_service_enabled was received with extended bitmap, 5834 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 5835 */ 5836 if (soc->wmi_ext_service_bitmap) 5837 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 5838 soc->wmi_ext_service_bitmap, 5839 service_id); 5840 5841 if (service_id >= WMI_MAX_SERVICE) { 5842 wmi_err("Service id %d but WMI ext service bitmap is NULL", 5843 service_id); 5844 return false; 5845 } 5846 5847 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 5848 service_id); 5849 } 5850 5851 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5852 /** 5853 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5854 * @wmi_handle: wmi handle 5855 * @clear_req: ll stats clear request command params 5856 * 5857 * Return: QDF_STATUS_SUCCESS for success or error code 5858 */ 5859 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5860 const struct ll_stats_clear_params *clear_req) 5861 { 5862 wmi_clear_link_stats_cmd_fixed_param *cmd; 5863 int32_t len; 5864 wmi_buf_t buf; 5865 uint8_t *buf_ptr; 5866 int ret; 5867 5868 len = sizeof(*cmd); 5869 buf = wmi_buf_alloc(wmi_handle, len); 5870 5871 if (!buf) 5872 return QDF_STATUS_E_NOMEM; 5873 5874 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5875 qdf_mem_zero(buf_ptr, len); 5876 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5877 5878 WMITLV_SET_HDR(&cmd->tlv_header, 5879 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5880 WMITLV_GET_STRUCT_TLVLEN 5881 (wmi_clear_link_stats_cmd_fixed_param)); 5882 5883 cmd->stop_stats_collection_req = clear_req->stop_req; 5884 cmd->vdev_id = clear_req->vdev_id; 5885 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5886 5887 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5888 &cmd->peer_macaddr); 5889 5890 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 5891 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 5892 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5893 cmd->stop_stats_collection_req, 5894 cmd->vdev_id, cmd->stats_clear_req_mask, 5895 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 5896 5897 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5898 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5899 WMI_CLEAR_LINK_STATS_CMDID); 5900 if (ret) { 5901 wmi_err("Failed to send clear link stats req"); 5902 wmi_buf_free(buf); 5903 return QDF_STATUS_E_FAILURE; 5904 } 5905 5906 wmi_debug("Clear Link Layer Stats request sent successfully"); 5907 return QDF_STATUS_SUCCESS; 5908 } 5909 5910 /** 5911 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5912 * @wmi_handle: wmi handle 5913 * @set_req: ll stats set request command params 5914 * 5915 * Return: QDF_STATUS_SUCCESS for success or error code 5916 */ 5917 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5918 const struct ll_stats_set_params *set_req) 5919 { 5920 wmi_start_link_stats_cmd_fixed_param *cmd; 5921 int32_t len; 5922 wmi_buf_t buf; 5923 uint8_t *buf_ptr; 5924 int ret; 5925 5926 len = sizeof(*cmd); 5927 buf = wmi_buf_alloc(wmi_handle, len); 5928 5929 if (!buf) 5930 return QDF_STATUS_E_NOMEM; 5931 5932 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5933 qdf_mem_zero(buf_ptr, len); 5934 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5935 5936 WMITLV_SET_HDR(&cmd->tlv_header, 5937 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5938 WMITLV_GET_STRUCT_TLVLEN 5939 (wmi_start_link_stats_cmd_fixed_param)); 5940 5941 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5942 cmd->aggressive_statistics_gathering = 5943 set_req->aggressive_statistics_gathering; 5944 5945 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5946 cmd->mpdu_size_threshold, 5947 cmd->aggressive_statistics_gathering); 5948 5949 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5950 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5951 WMI_START_LINK_STATS_CMDID); 5952 if (ret) { 5953 wmi_err("Failed to send set link stats request"); 5954 wmi_buf_free(buf); 5955 return QDF_STATUS_E_FAILURE; 5956 } 5957 5958 return QDF_STATUS_SUCCESS; 5959 } 5960 5961 /** 5962 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5963 * @wmi_handle: wmi handle 5964 * @get_req: ll stats get request command params 5965 * 5966 * Return: QDF_STATUS_SUCCESS for success or error code 5967 */ 5968 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5969 const struct ll_stats_get_params *get_req) 5970 { 5971 wmi_request_link_stats_cmd_fixed_param *cmd; 5972 int32_t len; 5973 wmi_buf_t buf; 5974 uint8_t *buf_ptr; 5975 int ret; 5976 5977 len = sizeof(*cmd); 5978 buf = wmi_buf_alloc(wmi_handle, len); 5979 5980 if (!buf) 5981 return QDF_STATUS_E_NOMEM; 5982 5983 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5984 qdf_mem_zero(buf_ptr, len); 5985 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5986 5987 WMITLV_SET_HDR(&cmd->tlv_header, 5988 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5989 WMITLV_GET_STRUCT_TLVLEN 5990 (wmi_request_link_stats_cmd_fixed_param)); 5991 5992 cmd->request_id = get_req->req_id; 5993 cmd->stats_type = get_req->param_id_mask; 5994 cmd->vdev_id = get_req->vdev_id; 5995 5996 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5997 &cmd->peer_macaddr); 5998 5999 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6000 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6001 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6002 6003 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6004 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6005 WMI_REQUEST_LINK_STATS_CMDID, true); 6006 if (ret) { 6007 wmi_buf_free(buf); 6008 return QDF_STATUS_E_FAILURE; 6009 } 6010 6011 return QDF_STATUS_SUCCESS; 6012 } 6013 6014 #ifdef WLAN_FEATURE_11BE_MLO 6015 static int 6016 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6017 { 6018 int32_t len = 0; 6019 6020 /* In case of MLO connection, update the length of the buffer. 6021 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6022 * hence just update the TLV header, but allocate no memory for it. 6023 */ 6024 if (!get_req->is_mlo_req) 6025 return len; 6026 6027 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6028 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6029 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6030 6031 return len; 6032 } 6033 6034 static void 6035 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6036 void *buf_ptr) 6037 { 6038 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6039 uint32_t *vdev_id_bitmap; 6040 wmi_mac_addr *mld_mac; 6041 6042 /* In case of MLO connection, update the TLV Headers */ 6043 if (!get_req->is_mlo_req) 6044 return; 6045 6046 buf_ptr += sizeof(*unified_cmd); 6047 6048 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6050 buf_ptr += WMI_TLV_HDR_SIZE; 6051 6052 /* Adding vdev_bitmap_id array TLV */ 6053 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6054 sizeof(*vdev_id_bitmap)); 6055 buf_ptr += WMI_TLV_HDR_SIZE; 6056 vdev_id_bitmap = buf_ptr; 6057 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6058 buf_ptr += sizeof(*vdev_id_bitmap); 6059 6060 /* Adding mld_macaddr array TLV */ 6061 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6062 sizeof(*mld_mac)); 6063 buf_ptr += WMI_TLV_HDR_SIZE; 6064 mld_mac = buf_ptr; 6065 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6066 6067 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6068 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6069 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6070 } 6071 #else 6072 static inline int 6073 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6074 { 6075 return 0; 6076 } 6077 6078 static inline void 6079 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6080 void *buf_ptr) 6081 { 6082 } 6083 #endif 6084 6085 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6086 /** 6087 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6088 * station request 6089 * @wmi_handle: wmi handle 6090 * @get_req: ll stats get request command params 6091 * 6092 * Return: QDF_STATUS_SUCCESS for success or error code 6093 */ 6094 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6095 wmi_unified_t wmi_handle, 6096 const struct ll_stats_get_params *get_req) 6097 { 6098 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6099 int32_t len; 6100 wmi_buf_t buf; 6101 void *buf_ptr; 6102 QDF_STATUS ret; 6103 bool is_ll_get_sta_stats_over_qmi; 6104 6105 len = sizeof(*unified_cmd); 6106 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6107 6108 buf = wmi_buf_alloc(wmi_handle, len); 6109 if (!buf) 6110 return QDF_STATUS_E_NOMEM; 6111 6112 buf_ptr = wmi_buf_data(buf); 6113 6114 unified_cmd = buf_ptr; 6115 WMITLV_SET_HDR( 6116 &unified_cmd->tlv_header, 6117 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6118 WMITLV_GET_STRUCT_TLVLEN 6119 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6120 6121 unified_cmd->link_stats_type = get_req->param_id_mask; 6122 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6123 WMI_REQUEST_PEER_STAT | 6124 WMI_REQUEST_VDEV_STAT | 6125 WMI_REQUEST_PDEV_STAT | 6126 WMI_REQUEST_PEER_EXTD2_STAT | 6127 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6128 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6129 wmi_handle, 6130 WMI_HOST_PDEV_ID_SOC); 6131 6132 unified_cmd->vdev_id = get_req->vdev_id; 6133 unified_cmd->request_id = get_req->req_id; 6134 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6135 &unified_cmd->peer_macaddr); 6136 6137 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6138 QDF_MAC_ADDR_FMT, 6139 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6140 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6141 6142 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6143 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6144 6145 /** 6146 * FW support for LL_get_sta command. True represents the unified 6147 * ll_get_sta command should be sent over QMI always irrespective of 6148 * WOW state. 6149 */ 6150 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6151 wmi_handle, 6152 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6153 6154 if (is_ll_get_sta_stats_over_qmi) { 6155 ret = wmi_unified_cmd_send_over_qmi( 6156 wmi_handle, buf, len, 6157 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6158 } else { 6159 ret = wmi_unified_cmd_send_pm_chk( 6160 wmi_handle, buf, len, 6161 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6162 true); 6163 } 6164 6165 if (QDF_IS_STATUS_ERROR(ret)) { 6166 wmi_buf_free(buf); 6167 return QDF_STATUS_E_FAILURE; 6168 } 6169 6170 return ret; 6171 } 6172 #endif 6173 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6174 6175 /** 6176 * send_congestion_cmd_tlv() - send request to fw to get CCA 6177 * @wmi_handle: wmi handle 6178 * @vdev_id: vdev id 6179 * 6180 * Return: CDF status 6181 */ 6182 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6183 uint8_t vdev_id) 6184 { 6185 wmi_buf_t buf; 6186 wmi_request_stats_cmd_fixed_param *cmd; 6187 uint8_t len; 6188 uint8_t *buf_ptr; 6189 6190 len = sizeof(*cmd); 6191 buf = wmi_buf_alloc(wmi_handle, len); 6192 if (!buf) 6193 return QDF_STATUS_E_FAILURE; 6194 6195 buf_ptr = wmi_buf_data(buf); 6196 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6197 WMITLV_SET_HDR(&cmd->tlv_header, 6198 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6199 WMITLV_GET_STRUCT_TLVLEN 6200 (wmi_request_stats_cmd_fixed_param)); 6201 6202 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6203 cmd->vdev_id = vdev_id; 6204 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6205 cmd->vdev_id, cmd->stats_id); 6206 6207 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6208 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6209 WMI_REQUEST_STATS_CMDID)) { 6210 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6211 wmi_buf_free(buf); 6212 return QDF_STATUS_E_FAILURE; 6213 } 6214 6215 return QDF_STATUS_SUCCESS; 6216 } 6217 6218 /** 6219 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6220 * @wmi_handle: wmi handle 6221 * @rssi_req: get RSSI request 6222 * 6223 * Return: CDF status 6224 */ 6225 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6226 { 6227 wmi_buf_t buf; 6228 wmi_request_stats_cmd_fixed_param *cmd; 6229 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6230 6231 buf = wmi_buf_alloc(wmi_handle, len); 6232 if (!buf) 6233 return QDF_STATUS_E_FAILURE; 6234 6235 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6236 WMITLV_SET_HDR(&cmd->tlv_header, 6237 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6238 WMITLV_GET_STRUCT_TLVLEN 6239 (wmi_request_stats_cmd_fixed_param)); 6240 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6241 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6242 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6243 WMI_REQUEST_STATS_CMDID)) { 6244 wmi_err("Failed to send host stats request to fw"); 6245 wmi_buf_free(buf); 6246 return QDF_STATUS_E_FAILURE; 6247 } 6248 6249 return QDF_STATUS_SUCCESS; 6250 } 6251 6252 /** 6253 * send_snr_cmd_tlv() - get RSSI from fw 6254 * @wmi_handle: wmi handle 6255 * @vdev_id: vdev id 6256 * 6257 * Return: CDF status 6258 */ 6259 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6260 { 6261 wmi_buf_t buf; 6262 wmi_request_stats_cmd_fixed_param *cmd; 6263 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6264 6265 buf = wmi_buf_alloc(wmi_handle, len); 6266 if (!buf) 6267 return QDF_STATUS_E_FAILURE; 6268 6269 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6270 cmd->vdev_id = vdev_id; 6271 6272 WMITLV_SET_HDR(&cmd->tlv_header, 6273 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6274 WMITLV_GET_STRUCT_TLVLEN 6275 (wmi_request_stats_cmd_fixed_param)); 6276 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6277 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6278 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6279 WMI_REQUEST_STATS_CMDID)) { 6280 wmi_err("Failed to send host stats request to fw"); 6281 wmi_buf_free(buf); 6282 return QDF_STATUS_E_FAILURE; 6283 } 6284 6285 return QDF_STATUS_SUCCESS; 6286 } 6287 6288 /** 6289 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6290 * @wmi_handle: wmi handle 6291 * @link_status: get link params 6292 * 6293 * Return: CDF status 6294 */ 6295 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6296 struct link_status_params *link_status) 6297 { 6298 wmi_buf_t buf; 6299 wmi_request_stats_cmd_fixed_param *cmd; 6300 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6301 6302 buf = wmi_buf_alloc(wmi_handle, len); 6303 if (!buf) 6304 return QDF_STATUS_E_FAILURE; 6305 6306 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6307 WMITLV_SET_HDR(&cmd->tlv_header, 6308 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6309 WMITLV_GET_STRUCT_TLVLEN 6310 (wmi_request_stats_cmd_fixed_param)); 6311 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6312 cmd->vdev_id = link_status->vdev_id; 6313 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6314 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6315 WMI_REQUEST_STATS_CMDID)) { 6316 wmi_err("Failed to send WMI link status request to fw"); 6317 wmi_buf_free(buf); 6318 return QDF_STATUS_E_FAILURE; 6319 } 6320 6321 return QDF_STATUS_SUCCESS; 6322 } 6323 6324 #ifdef WLAN_SUPPORT_GREEN_AP 6325 /** 6326 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6327 * @wmi_handle: wmi handler 6328 * @egap_params: pointer to egap_params 6329 * 6330 * Return: 0 for success, otherwise appropriate error code 6331 */ 6332 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 6333 struct wlan_green_ap_egap_params *egap_params) 6334 { 6335 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 6336 wmi_buf_t buf; 6337 int32_t err; 6338 6339 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6340 if (!buf) 6341 return QDF_STATUS_E_NOMEM; 6342 6343 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 6344 WMITLV_SET_HDR(&cmd->tlv_header, 6345 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 6346 WMITLV_GET_STRUCT_TLVLEN( 6347 wmi_ap_ps_egap_param_cmd_fixed_param)); 6348 6349 cmd->enable = egap_params->host_enable_egap; 6350 cmd->inactivity_time = egap_params->egap_inactivity_time; 6351 cmd->wait_time = egap_params->egap_wait_time; 6352 cmd->flags = egap_params->egap_feature_flags; 6353 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 6354 err = wmi_unified_cmd_send(wmi_handle, buf, 6355 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 6356 if (err) { 6357 wmi_err("Failed to send ap_ps_egap cmd"); 6358 wmi_buf_free(buf); 6359 return QDF_STATUS_E_FAILURE; 6360 } 6361 6362 return QDF_STATUS_SUCCESS; 6363 } 6364 #endif 6365 6366 /** 6367 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 6368 * @wmi_handle: wmi handle 6369 * @vdev_id: vdev id 6370 * 6371 * Return: QDF_STATUS_SUCCESS for success or error code 6372 */ 6373 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 6374 uint8_t vdev_id) 6375 { 6376 wmi_csa_offload_enable_cmd_fixed_param *cmd; 6377 wmi_buf_t buf; 6378 int32_t len = sizeof(*cmd); 6379 6380 wmi_debug("vdev_id %d", vdev_id); 6381 buf = wmi_buf_alloc(wmi_handle, len); 6382 if (!buf) 6383 return QDF_STATUS_E_NOMEM; 6384 6385 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 6386 WMITLV_SET_HDR(&cmd->tlv_header, 6387 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 6388 WMITLV_GET_STRUCT_TLVLEN 6389 (wmi_csa_offload_enable_cmd_fixed_param)); 6390 cmd->vdev_id = vdev_id; 6391 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 6392 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 6393 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6394 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 6395 wmi_err("Failed to send CSA offload enable command"); 6396 wmi_buf_free(buf); 6397 return QDF_STATUS_E_FAILURE; 6398 } 6399 6400 return 0; 6401 } 6402 6403 #ifdef WLAN_FEATURE_CIF_CFR 6404 /** 6405 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 6406 * @wmi_handle: wmi handle 6407 * @data_len: len of dma cfg req 6408 * @data: dma cfg req 6409 * 6410 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 6411 */ 6412 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 6413 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 6414 { 6415 wmi_buf_t buf; 6416 uint8_t *cmd; 6417 QDF_STATUS ret; 6418 6419 WMITLV_SET_HDR(cfg, 6420 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 6421 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 6422 6423 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 6424 if (!buf) 6425 return QDF_STATUS_E_FAILURE; 6426 6427 cmd = (uint8_t *) wmi_buf_data(buf); 6428 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 6429 wmi_debug("Sending OEM Data Request to target, data len %lu", 6430 sizeof(*cfg)); 6431 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 6432 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6433 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6434 if (QDF_IS_STATUS_ERROR(ret)) { 6435 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6436 wmi_buf_free(buf); 6437 } 6438 6439 return ret; 6440 } 6441 #endif 6442 6443 /** 6444 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6445 * @wmi_handle: wmi handle 6446 * @start_11d_scan: 11d scan start request parameters 6447 * 6448 * This function request FW to start 11d scan. 6449 * 6450 * Return: QDF status 6451 */ 6452 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6453 struct reg_start_11d_scan_req *start_11d_scan) 6454 { 6455 wmi_11d_scan_start_cmd_fixed_param *cmd; 6456 int32_t len; 6457 wmi_buf_t buf; 6458 int ret; 6459 6460 len = sizeof(*cmd); 6461 buf = wmi_buf_alloc(wmi_handle, len); 6462 if (!buf) 6463 return QDF_STATUS_E_NOMEM; 6464 6465 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6466 6467 WMITLV_SET_HDR(&cmd->tlv_header, 6468 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6469 WMITLV_GET_STRUCT_TLVLEN 6470 (wmi_11d_scan_start_cmd_fixed_param)); 6471 6472 cmd->vdev_id = start_11d_scan->vdev_id; 6473 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6474 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6475 6476 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6477 6478 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 6479 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6480 WMI_11D_SCAN_START_CMDID); 6481 if (ret) { 6482 wmi_err("Failed to send start 11d scan wmi cmd"); 6483 wmi_buf_free(buf); 6484 return QDF_STATUS_E_FAILURE; 6485 } 6486 6487 return QDF_STATUS_SUCCESS; 6488 } 6489 6490 /** 6491 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 6492 * @wmi_handle: wmi handle 6493 * @start_11d_scan: 11d scan stop request parameters 6494 * 6495 * This function request FW to stop 11d scan. 6496 * 6497 * Return: QDF status 6498 */ 6499 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6500 struct reg_stop_11d_scan_req *stop_11d_scan) 6501 { 6502 wmi_11d_scan_stop_cmd_fixed_param *cmd; 6503 int32_t len; 6504 wmi_buf_t buf; 6505 int ret; 6506 6507 len = sizeof(*cmd); 6508 buf = wmi_buf_alloc(wmi_handle, len); 6509 if (!buf) 6510 return QDF_STATUS_E_NOMEM; 6511 6512 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 6513 6514 WMITLV_SET_HDR(&cmd->tlv_header, 6515 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 6516 WMITLV_GET_STRUCT_TLVLEN 6517 (wmi_11d_scan_stop_cmd_fixed_param)); 6518 6519 cmd->vdev_id = stop_11d_scan->vdev_id; 6520 6521 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 6522 6523 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 6524 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6525 WMI_11D_SCAN_STOP_CMDID); 6526 if (ret) { 6527 wmi_err("Failed to send stop 11d scan wmi cmd"); 6528 wmi_buf_free(buf); 6529 return QDF_STATUS_E_FAILURE; 6530 } 6531 6532 return QDF_STATUS_SUCCESS; 6533 } 6534 6535 /** 6536 * send_start_oem_data_cmd_tlv() - start OEM data request to target 6537 * @wmi_handle: wmi handle 6538 * @data_len: the length of @data 6539 * @data: the pointer to data buf 6540 * 6541 * Return: CDF status 6542 */ 6543 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 6544 uint32_t data_len, 6545 uint8_t *data) 6546 { 6547 wmi_buf_t buf; 6548 uint8_t *cmd; 6549 QDF_STATUS ret; 6550 6551 buf = wmi_buf_alloc(wmi_handle, 6552 (data_len + WMI_TLV_HDR_SIZE)); 6553 if (!buf) 6554 return QDF_STATUS_E_FAILURE; 6555 6556 cmd = (uint8_t *) wmi_buf_data(buf); 6557 6558 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 6559 cmd += WMI_TLV_HDR_SIZE; 6560 qdf_mem_copy(cmd, data, 6561 data_len); 6562 6563 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 6564 6565 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 6566 ret = wmi_unified_cmd_send(wmi_handle, buf, 6567 (data_len + 6568 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 6569 6570 if (QDF_IS_STATUS_ERROR(ret)) { 6571 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 6572 wmi_buf_free(buf); 6573 } 6574 6575 return ret; 6576 } 6577 6578 #ifdef FEATURE_OEM_DATA 6579 /** 6580 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 6581 * @wmi_handle: wmi handle 6582 * @oem_data: the pointer to oem data 6583 * 6584 * Return: QDF status 6585 */ 6586 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 6587 struct oem_data *oem_data) 6588 { 6589 QDF_STATUS ret; 6590 wmi_oem_data_cmd_fixed_param *cmd; 6591 struct wmi_ops *ops; 6592 wmi_buf_t buf; 6593 uint16_t len = sizeof(*cmd); 6594 uint16_t oem_data_len_aligned; 6595 uint8_t *buf_ptr; 6596 uint32_t pdev_id; 6597 6598 if (!oem_data || !oem_data->data) { 6599 wmi_err_rl("oem data is not valid"); 6600 return QDF_STATUS_E_FAILURE; 6601 } 6602 6603 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 6604 if (oem_data_len_aligned < oem_data->data_len) { 6605 wmi_err_rl("integer overflow while rounding up data_len"); 6606 return QDF_STATUS_E_FAILURE; 6607 } 6608 6609 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 6610 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 6611 return QDF_STATUS_E_FAILURE; 6612 } 6613 6614 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 6615 buf = wmi_buf_alloc(wmi_handle, len); 6616 if (!buf) 6617 return QDF_STATUS_E_NOMEM; 6618 6619 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6620 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 6621 WMITLV_SET_HDR(&cmd->tlv_header, 6622 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 6623 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 6624 6625 pdev_id = oem_data->pdev_id; 6626 if (oem_data->pdev_vdev_flag) { 6627 ops = wmi_handle->ops; 6628 if (oem_data->is_host_pdev_id) 6629 pdev_id = 6630 ops->convert_host_pdev_id_to_target(wmi_handle, 6631 pdev_id); 6632 else 6633 pdev_id = 6634 ops->convert_pdev_id_host_to_target(wmi_handle, 6635 pdev_id); 6636 } 6637 6638 cmd->vdev_id = oem_data->vdev_id; 6639 cmd->data_len = oem_data->data_len; 6640 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 6641 cmd->pdev_id = pdev_id; 6642 6643 buf_ptr += sizeof(*cmd); 6644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 6645 buf_ptr += WMI_TLV_HDR_SIZE; 6646 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 6647 6648 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 6649 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 6650 if (QDF_IS_STATUS_ERROR(ret)) { 6651 wmi_err_rl("Failed with ret = %d", ret); 6652 wmi_buf_free(buf); 6653 } 6654 6655 return ret; 6656 } 6657 #endif 6658 6659 /** 6660 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 6661 * @wmi_handle: wmi handle 6662 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 6663 * 6664 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 6665 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 6666 * to firmware based on phyerr filtering 6667 * offload status. 6668 * 6669 * Return: 1 success, 0 failure 6670 */ 6671 static QDF_STATUS 6672 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 6673 bool dfs_phyerr_filter_offload) 6674 { 6675 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 6676 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 6677 wmi_buf_t buf; 6678 uint16_t len; 6679 QDF_STATUS ret; 6680 6681 6682 if (false == dfs_phyerr_filter_offload) { 6683 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 6684 len = sizeof(*disable_phyerr_offload_cmd); 6685 buf = wmi_buf_alloc(wmi_handle, len); 6686 if (!buf) 6687 return 0; 6688 6689 disable_phyerr_offload_cmd = 6690 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 6691 wmi_buf_data(buf); 6692 6693 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 6694 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 6695 WMITLV_GET_STRUCT_TLVLEN 6696 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 6697 6698 /* 6699 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 6700 * to the firmware to disable the phyerror 6701 * filtering offload. 6702 */ 6703 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 6704 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6705 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 6706 if (QDF_IS_STATUS_ERROR(ret)) { 6707 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 6708 ret); 6709 wmi_buf_free(buf); 6710 return QDF_STATUS_E_FAILURE; 6711 } 6712 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 6713 } else { 6714 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 6715 6716 len = sizeof(*enable_phyerr_offload_cmd); 6717 buf = wmi_buf_alloc(wmi_handle, len); 6718 if (!buf) 6719 return QDF_STATUS_E_FAILURE; 6720 6721 enable_phyerr_offload_cmd = 6722 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 6723 wmi_buf_data(buf); 6724 6725 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 6726 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 6727 WMITLV_GET_STRUCT_TLVLEN 6728 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 6729 6730 /* 6731 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 6732 * to the firmware to enable the phyerror 6733 * filtering offload. 6734 */ 6735 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 6736 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6737 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 6738 6739 if (QDF_IS_STATUS_ERROR(ret)) { 6740 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 6741 wmi_buf_free(buf); 6742 return QDF_STATUS_E_FAILURE; 6743 } 6744 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 6745 } 6746 6747 return QDF_STATUS_SUCCESS; 6748 } 6749 6750 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 6751 /** 6752 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 6753 * @wmi_handle: wmi handle 6754 * @pktlog_event: pktlog event 6755 * @cmd_id: pktlog cmd id 6756 * @user_triggered: user triggered input for PKTLOG enable mode 6757 * 6758 * Return: CDF status 6759 */ 6760 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 6761 WMI_PKTLOG_EVENT pktlog_event, 6762 WMI_CMD_ID cmd_id, uint8_t user_triggered) 6763 { 6764 WMI_PKTLOG_EVENT PKTLOG_EVENT; 6765 WMI_CMD_ID CMD_ID; 6766 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 6767 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 6768 int len = 0; 6769 wmi_buf_t buf; 6770 int32_t idx, max_idx; 6771 6772 PKTLOG_EVENT = pktlog_event; 6773 CMD_ID = cmd_id; 6774 6775 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 6776 switch (CMD_ID) { 6777 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 6778 len = sizeof(*cmd); 6779 buf = wmi_buf_alloc(wmi_handle, len); 6780 if (!buf) 6781 return QDF_STATUS_E_NOMEM; 6782 6783 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 6784 wmi_buf_data(buf); 6785 WMITLV_SET_HDR(&cmd->tlv_header, 6786 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 6787 WMITLV_GET_STRUCT_TLVLEN 6788 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 6789 cmd->evlist = 0; 6790 for (idx = 0; idx < max_idx; idx++) { 6791 if (PKTLOG_EVENT & (1 << idx)) 6792 cmd->evlist |= pktlog_event_tlv[idx]; 6793 } 6794 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 6795 : WMI_PKTLOG_ENABLE_AUTO; 6796 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6797 wmi_handle, 6798 WMI_HOST_PDEV_ID_SOC); 6799 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 6800 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6801 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 6802 wmi_err("Failed to send pktlog enable cmdid"); 6803 goto wmi_send_failed; 6804 } 6805 break; 6806 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 6807 len = sizeof(*disable_cmd); 6808 buf = wmi_buf_alloc(wmi_handle, len); 6809 if (!buf) 6810 return QDF_STATUS_E_NOMEM; 6811 6812 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 6813 wmi_buf_data(buf); 6814 WMITLV_SET_HDR(&disable_cmd->tlv_header, 6815 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 6816 WMITLV_GET_STRUCT_TLVLEN 6817 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 6818 disable_cmd->pdev_id = 6819 wmi_handle->ops->convert_pdev_id_host_to_target( 6820 wmi_handle, 6821 WMI_HOST_PDEV_ID_SOC); 6822 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 6823 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6824 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 6825 wmi_err("failed to send pktlog disable cmdid"); 6826 goto wmi_send_failed; 6827 } 6828 break; 6829 default: 6830 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 6831 break; 6832 } 6833 6834 return QDF_STATUS_SUCCESS; 6835 6836 wmi_send_failed: 6837 wmi_buf_free(buf); 6838 return QDF_STATUS_E_FAILURE; 6839 } 6840 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 6841 6842 /** 6843 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 6844 * @wmi_handle: wmi handle 6845 * @preq: stats ext params 6846 * 6847 * Return: CDF status 6848 */ 6849 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 6850 struct stats_ext_params *preq) 6851 { 6852 QDF_STATUS ret; 6853 wmi_req_stats_ext_cmd_fixed_param *cmd; 6854 wmi_buf_t buf; 6855 size_t len; 6856 uint8_t *buf_ptr; 6857 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 6858 uint32_t *vdev_bitmap; 6859 6860 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 6861 sizeof(*cmd))) { 6862 wmi_err("Data length=%d is greater than max wmi msg size", 6863 preq->request_data_len); 6864 return QDF_STATUS_E_FAILURE; 6865 } 6866 6867 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 6868 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 6869 6870 buf = wmi_buf_alloc(wmi_handle, len); 6871 if (!buf) 6872 return QDF_STATUS_E_NOMEM; 6873 6874 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6875 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 6876 6877 WMITLV_SET_HDR(&cmd->tlv_header, 6878 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 6879 WMITLV_GET_STRUCT_TLVLEN 6880 (wmi_req_stats_ext_cmd_fixed_param)); 6881 cmd->vdev_id = preq->vdev_id; 6882 cmd->data_len = preq->request_data_len; 6883 6884 wmi_debug("The data len value is %u and vdev id set is %u", 6885 preq->request_data_len, preq->vdev_id); 6886 6887 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 6888 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 6889 6890 buf_ptr += WMI_TLV_HDR_SIZE; 6891 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 6892 6893 buf_ptr += cmd->data_len; 6894 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 6895 6896 buf_ptr += WMI_TLV_HDR_SIZE; 6897 6898 vdev_bitmap = (A_UINT32 *)buf_ptr; 6899 6900 vdev_bitmap[0] = preq->vdev_id_bitmap; 6901 6902 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 6903 6904 buf_ptr += sizeof(uint32_t); 6905 6906 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 6907 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6908 WMI_REQUEST_STATS_EXT_CMDID); 6909 if (QDF_IS_STATUS_ERROR(ret)) { 6910 wmi_err("Failed to send notify cmd ret = %d", ret); 6911 wmi_buf_free(buf); 6912 } 6913 6914 return ret; 6915 } 6916 6917 /** 6918 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 6919 * @wmi_handle: wmi handle 6920 * @params: DHCP server offload info 6921 * 6922 * Return: QDF_STATUS_SUCCESS for success or error code 6923 */ 6924 static QDF_STATUS 6925 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 6926 struct dhcp_offload_info_params *params) 6927 { 6928 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 6929 wmi_buf_t buf; 6930 QDF_STATUS status; 6931 6932 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6933 if (!buf) 6934 return QDF_STATUS_E_NOMEM; 6935 6936 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 6937 6938 WMITLV_SET_HDR(&cmd->tlv_header, 6939 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 6940 WMITLV_GET_STRUCT_TLVLEN 6941 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 6942 cmd->vdev_id = params->vdev_id; 6943 cmd->enable = params->dhcp_offload_enabled; 6944 cmd->num_client = params->dhcp_client_num; 6945 cmd->srv_ipv4 = params->dhcp_srv_addr; 6946 cmd->start_lsb = 0; 6947 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 6948 status = wmi_unified_cmd_send(wmi_handle, buf, 6949 sizeof(*cmd), 6950 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 6951 if (QDF_IS_STATUS_ERROR(status)) { 6952 wmi_err("Failed to send set_dhcp_server_offload cmd"); 6953 wmi_buf_free(buf); 6954 return QDF_STATUS_E_FAILURE; 6955 } 6956 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 6957 6958 return status; 6959 } 6960 6961 /** 6962 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 6963 * @wmi_handle: wmi handle 6964 * @param: pointer to pdev regdomain params 6965 * 6966 * Return: 0 for success or error code 6967 */ 6968 static QDF_STATUS 6969 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 6970 struct pdev_set_regdomain_params *param) 6971 { 6972 wmi_buf_t buf; 6973 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6974 int32_t len = sizeof(*cmd); 6975 6976 buf = wmi_buf_alloc(wmi_handle, len); 6977 if (!buf) 6978 return QDF_STATUS_E_NOMEM; 6979 6980 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6981 WMITLV_SET_HDR(&cmd->tlv_header, 6982 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6983 WMITLV_GET_STRUCT_TLVLEN 6984 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6985 6986 cmd->reg_domain = param->currentRDinuse; 6987 cmd->reg_domain_2G = param->currentRD2G; 6988 cmd->reg_domain_5G = param->currentRD5G; 6989 cmd->conformance_test_limit_2G = param->ctl_2G; 6990 cmd->conformance_test_limit_5G = param->ctl_5G; 6991 cmd->dfs_domain = param->dfsDomain; 6992 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6993 wmi_handle, 6994 param->pdev_id); 6995 6996 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6997 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6998 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6999 wmi_err("Failed to send pdev set regdomain command"); 7000 wmi_buf_free(buf); 7001 return QDF_STATUS_E_FAILURE; 7002 } 7003 7004 return QDF_STATUS_SUCCESS; 7005 } 7006 7007 /** 7008 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7009 * @wmi_handle: wmi handle 7010 * @reg_dmn: reg domain 7011 * @regdmn2G: 2G reg domain 7012 * @regdmn5G: 5G reg domain 7013 * @ctl2G: 2G test limit 7014 * @ctl5G: 5G test limit 7015 * 7016 * Return: none 7017 */ 7018 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7019 uint32_t reg_dmn, uint16_t regdmn2G, 7020 uint16_t regdmn5G, uint8_t ctl2G, 7021 uint8_t ctl5G) 7022 { 7023 wmi_buf_t buf; 7024 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7025 int32_t len = sizeof(*cmd); 7026 7027 7028 buf = wmi_buf_alloc(wmi_handle, len); 7029 if (!buf) 7030 return QDF_STATUS_E_NOMEM; 7031 7032 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7033 WMITLV_SET_HDR(&cmd->tlv_header, 7034 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7035 WMITLV_GET_STRUCT_TLVLEN 7036 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7037 cmd->reg_domain = reg_dmn; 7038 cmd->reg_domain_2G = regdmn2G; 7039 cmd->reg_domain_5G = regdmn5G; 7040 cmd->conformance_test_limit_2G = ctl2G; 7041 cmd->conformance_test_limit_5G = ctl5G; 7042 7043 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7044 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7045 cmd->conformance_test_limit_2G, 7046 cmd->conformance_test_limit_5G); 7047 7048 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7049 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7050 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7051 wmi_err("Failed to send pdev set regdomain command"); 7052 wmi_buf_free(buf); 7053 return QDF_STATUS_E_FAILURE; 7054 } 7055 7056 return QDF_STATUS_SUCCESS; 7057 } 7058 7059 /** 7060 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7061 * @param: param sent from the host side 7062 * @cmd: param to be sent to the fw side 7063 */ 7064 static inline void copy_custom_aggr_bitmap( 7065 struct set_custom_aggr_size_params *param, 7066 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7067 { 7068 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7069 param->ac); 7070 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7071 param->aggr_type); 7072 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7073 param->tx_aggr_size_disable); 7074 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7075 param->rx_aggr_size_disable); 7076 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7077 param->tx_ac_enable); 7078 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7079 param->aggr_ba_enable); 7080 } 7081 7082 /** 7083 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7084 * @wmi_handle: wmi handle 7085 * @param: pointer to hold custom aggr size params 7086 * 7087 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7088 */ 7089 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7090 wmi_unified_t wmi_handle, 7091 struct set_custom_aggr_size_params *param) 7092 { 7093 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7094 wmi_buf_t buf; 7095 int32_t len = sizeof(*cmd); 7096 7097 buf = wmi_buf_alloc(wmi_handle, len); 7098 if (!buf) 7099 return QDF_STATUS_E_FAILURE; 7100 7101 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7102 wmi_buf_data(buf); 7103 WMITLV_SET_HDR(&cmd->tlv_header, 7104 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7105 WMITLV_GET_STRUCT_TLVLEN( 7106 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7107 cmd->vdev_id = param->vdev_id; 7108 cmd->tx_aggr_size = param->tx_aggr_size; 7109 cmd->rx_aggr_size = param->rx_aggr_size; 7110 copy_custom_aggr_bitmap(param, cmd); 7111 7112 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7113 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7114 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7115 "tx_ac_enable=0x%X", 7116 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7117 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7118 param->rx_aggr_size_disable, param->tx_ac_enable); 7119 7120 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7121 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7122 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7123 wmi_err("Setting custom aggregation size failed"); 7124 wmi_buf_free(buf); 7125 return QDF_STATUS_E_FAILURE; 7126 } 7127 7128 return QDF_STATUS_SUCCESS; 7129 } 7130 7131 /** 7132 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7133 * @param wmi_handle : handle to WMI. 7134 * @param param : pointer to tx antenna param 7135 * 7136 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7137 */ 7138 7139 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7140 struct set_qdepth_thresh_params *param) 7141 { 7142 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7143 wmi_msduq_qdepth_thresh_update *cmd_update; 7144 wmi_buf_t buf; 7145 int32_t len = 0; 7146 int i; 7147 uint8_t *buf_ptr; 7148 QDF_STATUS ret; 7149 7150 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7151 wmi_err("Invalid Update Count!"); 7152 return QDF_STATUS_E_INVAL; 7153 } 7154 7155 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7156 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7157 param->num_of_msduq_updates); 7158 buf = wmi_buf_alloc(wmi_handle, len); 7159 7160 if (!buf) 7161 return QDF_STATUS_E_NOMEM; 7162 7163 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7164 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7165 buf_ptr; 7166 7167 WMITLV_SET_HDR(&cmd->tlv_header, 7168 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7169 , WMITLV_GET_STRUCT_TLVLEN( 7170 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7171 7172 cmd->pdev_id = 7173 wmi_handle->ops->convert_pdev_id_host_to_target( 7174 wmi_handle, 7175 param->pdev_id); 7176 cmd->vdev_id = param->vdev_id; 7177 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7178 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7179 7180 buf_ptr += sizeof( 7181 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7182 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7183 param->num_of_msduq_updates * 7184 sizeof(wmi_msduq_qdepth_thresh_update)); 7185 buf_ptr += WMI_TLV_HDR_SIZE; 7186 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7187 7188 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7189 WMITLV_SET_HDR(&cmd_update->tlv_header, 7190 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7191 WMITLV_GET_STRUCT_TLVLEN( 7192 wmi_msduq_qdepth_thresh_update)); 7193 cmd_update->tid_num = param->update_params[i].tid_num; 7194 cmd_update->msduq_update_mask = 7195 param->update_params[i].msduq_update_mask; 7196 cmd_update->qdepth_thresh_value = 7197 param->update_params[i].qdepth_thresh_value; 7198 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7199 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7200 " update mask=0x%X thresh val=0x%X", 7201 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7202 cmd->peer_mac_address.mac_addr31to0, 7203 cmd->peer_mac_address.mac_addr47to32, 7204 cmd_update->msduq_update_mask, 7205 cmd_update->qdepth_thresh_value); 7206 cmd_update++; 7207 } 7208 7209 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7210 cmd->vdev_id, 0); 7211 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7212 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7213 7214 if (ret != 0) { 7215 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7216 wmi_buf_free(buf); 7217 } 7218 7219 return ret; 7220 } 7221 7222 /** 7223 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7224 * @wmi_handle: wmi handle 7225 * @param: pointer to hold vap dscp tid map param 7226 * 7227 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7228 */ 7229 static QDF_STATUS 7230 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7231 struct vap_dscp_tid_map_params *param) 7232 { 7233 wmi_buf_t buf; 7234 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7235 int32_t len = sizeof(*cmd); 7236 7237 buf = wmi_buf_alloc(wmi_handle, len); 7238 if (!buf) 7239 return QDF_STATUS_E_FAILURE; 7240 7241 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7242 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7243 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7244 7245 cmd->vdev_id = param->vdev_id; 7246 cmd->enable_override = 0; 7247 7248 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7249 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7250 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7251 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7252 wmi_err("Failed to set dscp cmd"); 7253 wmi_buf_free(buf); 7254 return QDF_STATUS_E_FAILURE; 7255 } 7256 7257 return QDF_STATUS_SUCCESS; 7258 } 7259 7260 /** 7261 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7262 * @wmi_handle: wmi handle 7263 * @param: pointer to hold fwtest param 7264 * 7265 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7266 */ 7267 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7268 struct set_fwtest_params *param) 7269 { 7270 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7271 wmi_buf_t buf; 7272 int32_t len = sizeof(*cmd); 7273 7274 buf = wmi_buf_alloc(wmi_handle, len); 7275 7276 if (!buf) 7277 return QDF_STATUS_E_FAILURE; 7278 7279 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7280 WMITLV_SET_HDR(&cmd->tlv_header, 7281 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7282 WMITLV_GET_STRUCT_TLVLEN( 7283 wmi_fwtest_set_param_cmd_fixed_param)); 7284 cmd->param_id = param->arg; 7285 cmd->param_value = param->value; 7286 7287 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7288 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7289 wmi_err("Setting FW test param failed"); 7290 wmi_buf_free(buf); 7291 return QDF_STATUS_E_FAILURE; 7292 } 7293 7294 return QDF_STATUS_SUCCESS; 7295 } 7296 7297 /** 7298 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7299 * 7300 * @param wmi_handle : handle to WMI. 7301 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7302 */ 7303 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7304 { 7305 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7306 wmi_buf_t buf; 7307 QDF_STATUS ret; 7308 int32_t len; 7309 7310 len = sizeof(*cmd); 7311 7312 buf = wmi_buf_alloc(wmi_handle, len); 7313 if (!buf) 7314 return QDF_STATUS_E_FAILURE; 7315 7316 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7317 WMITLV_SET_HDR(&cmd->tlv_header, 7318 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7319 WMITLV_GET_STRUCT_TLVLEN( 7320 wmi_pdev_dfs_disable_cmd_fixed_param)); 7321 /* Filling it with WMI_PDEV_ID_SOC for now */ 7322 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7323 wmi_handle, 7324 WMI_HOST_PDEV_ID_SOC); 7325 7326 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7327 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7328 WMI_PDEV_DFS_DISABLE_CMDID); 7329 7330 if (ret != 0) { 7331 wmi_err("Sending PDEV DFS disable cmd failed"); 7332 wmi_buf_free(buf); 7333 } 7334 7335 return ret; 7336 } 7337 7338 /** 7339 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 7340 * 7341 * @param wmi_handle : handle to WMI. 7342 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7343 */ 7344 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 7345 { 7346 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 7347 wmi_buf_t buf; 7348 QDF_STATUS ret; 7349 int32_t len; 7350 7351 len = sizeof(*cmd); 7352 7353 buf = wmi_buf_alloc(wmi_handle, len); 7354 if (!buf) 7355 return QDF_STATUS_E_FAILURE; 7356 7357 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 7358 WMITLV_SET_HDR(&cmd->tlv_header, 7359 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 7360 WMITLV_GET_STRUCT_TLVLEN( 7361 wmi_pdev_dfs_enable_cmd_fixed_param)); 7362 /* Reserved for future use */ 7363 cmd->reserved0 = 0; 7364 7365 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 7366 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7367 WMI_PDEV_DFS_ENABLE_CMDID); 7368 7369 if (ret != 0) { 7370 wmi_err("Sending PDEV DFS enable cmd failed"); 7371 wmi_buf_free(buf); 7372 } 7373 7374 return ret; 7375 } 7376 7377 /** 7378 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 7379 * to fw 7380 * @wmi_handle: wmi handle 7381 * @param: pointer to hold periodic chan stats param 7382 * 7383 * Return: 0 for success or error code 7384 */ 7385 static QDF_STATUS 7386 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 7387 struct periodic_chan_stats_params *param) 7388 { 7389 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 7390 wmi_buf_t buf; 7391 QDF_STATUS ret; 7392 int32_t len; 7393 7394 len = sizeof(*cmd); 7395 7396 buf = wmi_buf_alloc(wmi_handle, len); 7397 if (!buf) 7398 return QDF_STATUS_E_FAILURE; 7399 7400 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 7401 wmi_buf_data(buf); 7402 WMITLV_SET_HDR(&cmd->tlv_header, 7403 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 7404 WMITLV_GET_STRUCT_TLVLEN( 7405 wmi_set_periodic_channel_stats_config_fixed_param)); 7406 cmd->enable = param->enable; 7407 cmd->stats_period = param->stats_period; 7408 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7409 wmi_handle, 7410 param->pdev_id); 7411 7412 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 7413 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7414 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 7415 7416 if (ret != 0) { 7417 wmi_err("Sending periodic chan stats config failed"); 7418 wmi_buf_free(buf); 7419 } 7420 7421 return ret; 7422 } 7423 7424 #ifdef WLAN_IOT_SIM_SUPPORT 7425 /** 7426 * send_simulation_test_cmd_tlv() - send simulation test command to fw 7427 * 7428 * @wmi_handle: wmi handle 7429 * @param: pointer to hold simulation test parameter 7430 * 7431 * Return: 0 for success or error code 7432 */ 7433 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 7434 struct simulation_test_params 7435 *param) 7436 { 7437 wmi_simulation_test_cmd_fixed_param *cmd; 7438 u32 wmi_buf_len; 7439 wmi_buf_t buf; 7440 u8 *buf_ptr; 7441 u32 aligned_len = 0; 7442 7443 wmi_buf_len = sizeof(*cmd); 7444 if (param->buf_len) { 7445 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 7446 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 7447 } 7448 7449 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7450 if (!buf) { 7451 wmi_err("wmi_buf_alloc failed"); 7452 return QDF_STATUS_E_NOMEM; 7453 } 7454 7455 buf_ptr = wmi_buf_data(buf); 7456 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7457 WMITLV_SET_HDR(&cmd->tlv_header, 7458 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7459 WMITLV_GET_STRUCT_TLVLEN( 7460 wmi_simulation_test_cmd_fixed_param)); 7461 cmd->pdev_id = param->pdev_id; 7462 cmd->vdev_id = param->vdev_id; 7463 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7464 cmd->test_cmd_type = param->test_cmd_type; 7465 cmd->test_subcmd_type = param->test_subcmd_type; 7466 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7467 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7468 param->frame_subtype); 7469 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7470 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7471 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7472 cmd->buf_len = param->buf_len; 7473 7474 if (param->buf_len) { 7475 buf_ptr += sizeof(*cmd); 7476 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7477 buf_ptr += WMI_TLV_HDR_SIZE; 7478 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 7479 } 7480 7481 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 7482 WMI_SIMULATION_TEST_CMDID)) { 7483 wmi_err("Failed to send test simulation cmd"); 7484 wmi_buf_free(buf); 7485 return QDF_STATUS_E_FAILURE; 7486 } 7487 7488 return QDF_STATUS_SUCCESS; 7489 } 7490 #endif 7491 7492 #ifdef WLAN_FEATURE_11BE 7493 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 7494 #else 7495 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 7496 #endif 7497 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 7498 { 7499 switch (wmi_width) { 7500 case WMI_CHAN_WIDTH_20: 7501 return CH_WIDTH_20MHZ; 7502 case WMI_CHAN_WIDTH_40: 7503 return CH_WIDTH_40MHZ; 7504 case WMI_CHAN_WIDTH_80: 7505 return CH_WIDTH_80MHZ; 7506 case WMI_CHAN_WIDTH_160: 7507 return CH_WIDTH_160MHZ; 7508 case WMI_CHAN_WIDTH_80P80: 7509 return CH_WIDTH_80P80MHZ; 7510 case WMI_CHAN_WIDTH_5: 7511 return CH_WIDTH_5MHZ; 7512 case WMI_CHAN_WIDTH_10: 7513 return CH_WIDTH_10MHZ; 7514 case WMI_CHAN_WIDTH_320: 7515 return WLAN_PHY_CH_WIDTH_320MHZ; 7516 default: 7517 return CH_WIDTH_INVALID; 7518 } 7519 } 7520 7521 /** 7522 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 7523 * command to fw 7524 * @wmi_handle: wmi handle 7525 * @param: pointer to hold spectral config parameter 7526 * 7527 * Return: 0 for success or error code 7528 */ 7529 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 7530 struct vdev_spectral_configure_params *param) 7531 { 7532 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 7533 wmi_buf_t buf; 7534 QDF_STATUS ret; 7535 int32_t len; 7536 7537 len = sizeof(*cmd); 7538 buf = wmi_buf_alloc(wmi_handle, len); 7539 if (!buf) 7540 return QDF_STATUS_E_FAILURE; 7541 7542 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 7543 WMITLV_SET_HDR(&cmd->tlv_header, 7544 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 7545 WMITLV_GET_STRUCT_TLVLEN( 7546 wmi_vdev_spectral_configure_cmd_fixed_param)); 7547 7548 cmd->vdev_id = param->vdev_id; 7549 cmd->spectral_scan_count = param->count; 7550 cmd->spectral_scan_period = param->period; 7551 cmd->spectral_scan_priority = param->spectral_pri; 7552 cmd->spectral_scan_fft_size = param->fft_size; 7553 cmd->spectral_scan_gc_ena = param->gc_enable; 7554 cmd->spectral_scan_restart_ena = param->restart_enable; 7555 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 7556 cmd->spectral_scan_init_delay = param->init_delay; 7557 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 7558 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 7559 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 7560 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 7561 cmd->spectral_scan_rssi_thr = param->rssi_thr; 7562 cmd->spectral_scan_pwr_format = param->pwr_format; 7563 cmd->spectral_scan_rpt_mode = param->rpt_mode; 7564 cmd->spectral_scan_bin_scale = param->bin_scale; 7565 cmd->spectral_scan_dBm_adj = param->dbm_adj; 7566 cmd->spectral_scan_chn_mask = param->chn_mask; 7567 cmd->spectral_scan_mode = param->mode; 7568 cmd->spectral_scan_center_freq1 = param->center_freq1; 7569 cmd->spectral_scan_center_freq2 = param->center_freq2; 7570 cmd->spectral_scan_chan_width = param->chan_width; 7571 cmd->recapture_sample_on_gain_change = param->fft_recap; 7572 /* Not used, fill with zeros */ 7573 cmd->spectral_scan_chan_freq = 0; 7574 7575 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 7576 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7577 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 7578 7579 if (ret != 0) { 7580 wmi_err("Sending set quiet cmd failed"); 7581 wmi_buf_free(buf); 7582 } 7583 7584 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 7585 wmi_debug("vdev_id: %u spectral_scan_count: %u", 7586 param->vdev_id, param->count); 7587 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 7588 param->period, param->spectral_pri); 7589 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 7590 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 7591 param->fft_size, param->gc_enable); 7592 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 7593 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 7594 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 7595 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 7596 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 7597 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 7598 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 7599 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 7600 param->rssi_thr, param->pwr_format); 7601 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 7602 param->rpt_mode, param->bin_scale); 7603 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 7604 param->dbm_adj, param->chn_mask); 7605 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 7606 param->mode, param->center_freq1); 7607 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 7608 param->center_freq2, param->chan_freq); 7609 wmi_debug("spectral_scan_chan_width: %u Status: %d", 7610 param->chan_width, ret); 7611 7612 return ret; 7613 } 7614 7615 /** 7616 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 7617 * command to fw 7618 * @wmi_handle: wmi handle 7619 * @param: pointer to hold spectral enable parameter 7620 * 7621 * Return: 0 for success or error code 7622 */ 7623 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 7624 struct vdev_spectral_enable_params *param) 7625 { 7626 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 7627 wmi_buf_t buf; 7628 QDF_STATUS ret; 7629 int32_t len; 7630 7631 len = sizeof(*cmd); 7632 buf = wmi_buf_alloc(wmi_handle, len); 7633 if (!buf) 7634 return QDF_STATUS_E_FAILURE; 7635 7636 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 7637 WMITLV_SET_HDR(&cmd->tlv_header, 7638 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 7639 WMITLV_GET_STRUCT_TLVLEN( 7640 wmi_vdev_spectral_enable_cmd_fixed_param)); 7641 7642 cmd->vdev_id = param->vdev_id; 7643 7644 if (param->active_valid) { 7645 cmd->trigger_cmd = param->active ? 1 : 2; 7646 /* 1: Trigger, 2: Clear Trigger */ 7647 } else { 7648 cmd->trigger_cmd = 0; /* 0: Ignore */ 7649 } 7650 7651 if (param->enabled_valid) { 7652 cmd->enable_cmd = param->enabled ? 1 : 2; 7653 /* 1: Enable 2: Disable */ 7654 } else { 7655 cmd->enable_cmd = 0; /* 0: Ignore */ 7656 } 7657 cmd->spectral_scan_mode = param->mode; 7658 7659 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 7660 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 7661 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 7662 7663 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 7664 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7665 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 7666 7667 if (ret != 0) { 7668 wmi_err("Sending scan enable CMD failed"); 7669 wmi_buf_free(buf); 7670 } 7671 7672 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 7673 ret); 7674 7675 return ret; 7676 } 7677 7678 #ifdef WLAN_CONV_SPECTRAL_ENABLE 7679 static QDF_STATUS 7680 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 7681 wmi_unified_t wmi_handle, 7682 uint8_t *event, struct spectral_startscan_resp_params *param) 7683 { 7684 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7685 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 7686 7687 if (!wmi_handle) { 7688 wmi_err("WMI handle is null"); 7689 return QDF_STATUS_E_INVAL; 7690 } 7691 7692 if (!event) { 7693 wmi_err("WMI event is null"); 7694 return QDF_STATUS_E_INVAL; 7695 } 7696 7697 if (!param) { 7698 wmi_err("Spectral startscan response params is null"); 7699 return QDF_STATUS_E_INVAL; 7700 } 7701 7702 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7703 if (!param_buf) 7704 return QDF_STATUS_E_INVAL; 7705 7706 ev = param_buf->fixed_param; 7707 if (!ev) 7708 return QDF_STATUS_E_INVAL; 7709 7710 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 7711 wmi_handle, 7712 ev->pdev_id); 7713 param->smode = ev->spectral_scan_mode; 7714 param->num_fft_bin_index = param_buf->num_fft_bin_index; 7715 param->num_det_info = param_buf->num_det_info; 7716 7717 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 7718 ev->pdev_id, ev->spectral_scan_mode, 7719 param_buf->num_fft_bin_index, param_buf->num_det_info); 7720 7721 return QDF_STATUS_SUCCESS; 7722 } 7723 7724 static QDF_STATUS 7725 extract_pdev_sscan_fft_bin_index_tlv( 7726 wmi_unified_t wmi_handle, uint8_t *event, 7727 struct spectral_fft_bin_markers_160_165mhz *param) 7728 { 7729 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7730 wmi_pdev_sscan_fft_bin_index *ev; 7731 7732 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7733 if (!param_buf) 7734 return QDF_STATUS_E_INVAL; 7735 7736 ev = param_buf->fft_bin_index; 7737 if (!ev) 7738 return QDF_STATUS_E_INVAL; 7739 7740 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 7741 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 7742 param->start_pri80 + 1; 7743 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 7744 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 7745 param->start_sec80 + 1; 7746 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 7747 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 7748 param->start_5mhz + 1; 7749 param->is_valid = true; 7750 7751 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 7752 param->start_pri80, param->num_pri80, 7753 param->start_sec80, param->num_sec80, 7754 param->start_5mhz, param->num_5mhz); 7755 7756 return QDF_STATUS_SUCCESS; 7757 } 7758 7759 /** 7760 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 7761 * for a spectral scan session 7762 * @wmi_handle: handle to WMI. 7763 * @event: Event buffer 7764 * @chan_info: Spectral session channel information data structure to be filled 7765 * by this API 7766 * 7767 * Return: QDF_STATUS of operation 7768 */ 7769 static QDF_STATUS 7770 extract_pdev_spectral_session_chan_info_tlv( 7771 wmi_unified_t wmi_handle, void *event, 7772 struct spectral_session_chan_info *chan_info) 7773 { 7774 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7775 wmi_pdev_sscan_chan_info *chan_info_tlv; 7776 7777 if (!param_buf) { 7778 wmi_err("param_buf is NULL"); 7779 return QDF_STATUS_E_NULL_VALUE; 7780 } 7781 7782 if (!chan_info) { 7783 wmi_err("chan_info is NULL"); 7784 return QDF_STATUS_E_NULL_VALUE; 7785 } 7786 7787 chan_info_tlv = param_buf->chan_info; 7788 if (!chan_info_tlv) { 7789 wmi_err("chan_info tlv is not present in the event"); 7790 return QDF_STATUS_E_NULL_VALUE; 7791 } 7792 7793 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 7794 "operating_cfreq2:%u operating_bw:%u" 7795 "operating_puncture_20mhz_bitmap:%u" 7796 "sscan_cfreq1:%u sscan_cfreq2:%u" 7797 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 7798 chan_info_tlv->operating_pri20_freq, 7799 chan_info_tlv->operating_cfreq1, 7800 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 7801 chan_info_tlv->operating_puncture_20mhz_bitmap, 7802 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 7803 chan_info_tlv->sscan_bw, 7804 chan_info_tlv->sscan_puncture_20mhz_bitmap); 7805 7806 chan_info->operating_pri20_freq = 7807 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 7808 chan_info->operating_cfreq1 = 7809 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 7810 chan_info->operating_cfreq2 = 7811 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 7812 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 7813 chan_info->operating_puncture_20mhz_bitmap = 7814 chan_info_tlv->operating_puncture_20mhz_bitmap; 7815 7816 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 7817 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 7818 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 7819 chan_info->sscan_puncture_20mhz_bitmap = 7820 chan_info_tlv->sscan_puncture_20mhz_bitmap; 7821 7822 return QDF_STATUS_SUCCESS; 7823 } 7824 7825 static QDF_STATUS 7826 extract_pdev_spectral_session_detector_info_tlv( 7827 wmi_unified_t wmi_handle, void *event, 7828 struct spectral_session_det_info *det_info, uint8_t idx) 7829 { 7830 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7831 wmi_pdev_sscan_per_detector_info *det_info_tlv; 7832 7833 if (!param_buf) { 7834 wmi_err("param_buf is NULL"); 7835 return QDF_STATUS_E_NULL_VALUE; 7836 } 7837 7838 if (!det_info) { 7839 wmi_err("chan_info is NULL"); 7840 return QDF_STATUS_E_NULL_VALUE; 7841 } 7842 7843 if (!param_buf->det_info) { 7844 wmi_err("det_info tlv is not present in the event"); 7845 return QDF_STATUS_E_NULL_VALUE; 7846 } 7847 7848 if (idx >= param_buf->num_det_info) { 7849 wmi_err("det_info index(%u) is greater than or equal to %u", 7850 idx, param_buf->num_det_info); 7851 return QDF_STATUS_E_FAILURE; 7852 } 7853 7854 det_info_tlv = ¶m_buf->det_info[idx]; 7855 7856 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 7857 idx, det_info_tlv->detector_id, 7858 det_info_tlv->start_freq, det_info_tlv->end_freq); 7859 7860 det_info->det_id = det_info_tlv->detector_id; 7861 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 7862 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 7863 7864 return QDF_STATUS_SUCCESS; 7865 } 7866 7867 /** 7868 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 7869 * capabilities WMI event 7870 * @wmi_handle: handle to WMI. 7871 * @event: Event buffer 7872 * @param: Spectral capabilities event parameters data structure to be filled 7873 * by this API 7874 * 7875 * Return: QDF_STATUS of operation 7876 */ 7877 static QDF_STATUS 7878 extract_spectral_caps_fixed_param_tlv( 7879 wmi_unified_t wmi_handle, void *event, 7880 struct spectral_capabilities_event_params *params) 7881 { 7882 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7883 7884 if (!param_buf) { 7885 wmi_err("param_buf is NULL"); 7886 return QDF_STATUS_E_NULL_VALUE; 7887 } 7888 7889 if (!params) { 7890 wmi_err("event parameters is NULL"); 7891 return QDF_STATUS_E_NULL_VALUE; 7892 } 7893 7894 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 7895 params->num_fft_size_caps = param_buf->num_fft_size_caps; 7896 7897 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 7898 params->num_sscan_bw_caps, params->num_fft_size_caps); 7899 7900 return QDF_STATUS_SUCCESS; 7901 } 7902 7903 /** 7904 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 7905 * Spectral capabilities WMI event 7906 * @wmi_handle: handle to WMI. 7907 * @event: Event buffer 7908 * @bw_caps: Data structure to be populated by this API after extraction 7909 * 7910 * Return: QDF_STATUS of operation 7911 */ 7912 static QDF_STATUS 7913 extract_spectral_scan_bw_caps_tlv( 7914 wmi_unified_t wmi_handle, void *event, 7915 struct spectral_scan_bw_capabilities *bw_caps) 7916 { 7917 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7918 int idx; 7919 7920 if (!param_buf) { 7921 wmi_err("param_buf is NULL"); 7922 return QDF_STATUS_E_NULL_VALUE; 7923 } 7924 7925 if (!bw_caps) { 7926 wmi_err("bw_caps is null"); 7927 return QDF_STATUS_E_NULL_VALUE; 7928 } 7929 7930 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 7931 bw_caps[idx].pdev_id = 7932 wmi_handle->ops->convert_pdev_id_target_to_host( 7933 wmi_handle, 7934 param_buf->sscan_bw_caps[idx].pdev_id); 7935 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 7936 bw_caps[idx].operating_bw = wmi_map_ch_width( 7937 param_buf->sscan_bw_caps[idx].operating_bw); 7938 bw_caps[idx].supported_bws = 7939 param_buf->sscan_bw_caps[idx].supported_flags; 7940 7941 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 7942 "operating_bw:%u supported_flags:0x%x", 7943 idx, param_buf->sscan_bw_caps[idx].pdev_id, 7944 param_buf->sscan_bw_caps[idx].sscan_mode, 7945 param_buf->sscan_bw_caps[idx].operating_bw, 7946 param_buf->sscan_bw_caps[idx].supported_flags); 7947 } 7948 7949 return QDF_STATUS_SUCCESS; 7950 } 7951 7952 /** 7953 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 7954 * Spectral capabilities WMI event 7955 * @wmi_handle: handle to WMI. 7956 * @event: Event buffer 7957 * @fft_size_caps: Data structure to be populated by this API after extraction 7958 * 7959 * Return: QDF_STATUS of operation 7960 */ 7961 static QDF_STATUS 7962 extract_spectral_fft_size_caps_tlv( 7963 wmi_unified_t wmi_handle, void *event, 7964 struct spectral_fft_size_capabilities *fft_size_caps) 7965 { 7966 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7967 int idx; 7968 7969 if (!param_buf) { 7970 wmi_err("param_buf is NULL"); 7971 return QDF_STATUS_E_NULL_VALUE; 7972 } 7973 7974 if (!fft_size_caps) { 7975 wmi_err("fft size caps is NULL"); 7976 return QDF_STATUS_E_NULL_VALUE; 7977 } 7978 7979 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 7980 fft_size_caps[idx].pdev_id = 7981 wmi_handle->ops->convert_pdev_id_target_to_host( 7982 wmi_handle, 7983 param_buf->fft_size_caps[idx].pdev_id); 7984 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 7985 param_buf->fft_size_caps[idx].sscan_bw); 7986 fft_size_caps[idx].supports_fft_sizes = 7987 param_buf->fft_size_caps[idx].supported_flags; 7988 7989 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 7990 "supported_flags:0x%x", 7991 idx, param_buf->fft_size_caps[idx].pdev_id, 7992 param_buf->fft_size_caps[idx].sscan_bw, 7993 param_buf->fft_size_caps[idx].supported_flags); 7994 } 7995 7996 return QDF_STATUS_SUCCESS; 7997 } 7998 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 7999 8000 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8001 static inline void 8002 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8003 struct thermal_mitigation_params *param) 8004 { 8005 tt_conf->client_id = param->client_id; 8006 tt_conf->priority = param->priority; 8007 } 8008 #else 8009 static inline void 8010 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8011 struct thermal_mitigation_params *param) 8012 { 8013 } 8014 #endif 8015 8016 /** 8017 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8018 * @param wmi_handle : handle to WMI. 8019 * @param param : pointer to hold thermal mitigation param 8020 * 8021 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 8022 */ 8023 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8024 wmi_unified_t wmi_handle, 8025 struct thermal_mitigation_params *param) 8026 { 8027 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8028 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8029 wmi_buf_t buf = NULL; 8030 uint8_t *buf_ptr = NULL; 8031 int error; 8032 int32_t len; 8033 int i; 8034 8035 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8036 param->num_thermal_conf * 8037 sizeof(wmi_therm_throt_level_config_info); 8038 8039 buf = wmi_buf_alloc(wmi_handle, len); 8040 if (!buf) 8041 return QDF_STATUS_E_NOMEM; 8042 8043 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8044 8045 /* init fixed params */ 8046 WMITLV_SET_HDR(tt_conf, 8047 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8048 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8049 8050 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8051 wmi_handle, 8052 param->pdev_id); 8053 tt_conf->enable = param->enable; 8054 tt_conf->dc = param->dc; 8055 tt_conf->dc_per_event = param->dc_per_event; 8056 tt_conf->therm_throt_levels = param->num_thermal_conf; 8057 wmi_fill_client_id_priority(tt_conf, param); 8058 buf_ptr = (uint8_t *) ++tt_conf; 8059 /* init TLV params */ 8060 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8061 (param->num_thermal_conf * 8062 sizeof(wmi_therm_throt_level_config_info))); 8063 8064 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8065 for (i = 0; i < param->num_thermal_conf; i++) { 8066 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8067 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8068 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8069 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8070 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8071 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8072 lvl_conf->prio = param->levelconf[i].priority; 8073 lvl_conf++; 8074 } 8075 8076 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8077 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8078 WMI_THERM_THROT_SET_CONF_CMDID); 8079 if (QDF_IS_STATUS_ERROR(error)) { 8080 wmi_buf_free(buf); 8081 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8082 } 8083 8084 return error; 8085 } 8086 8087 /** 8088 * send_coex_config_cmd_tlv() - send coex config command to fw 8089 * @wmi_handle: wmi handle 8090 * @param: pointer to coex config param 8091 * 8092 * Return: 0 for success or error code 8093 */ 8094 static QDF_STATUS 8095 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8096 struct coex_config_params *param) 8097 { 8098 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8099 wmi_buf_t buf; 8100 QDF_STATUS ret; 8101 int32_t len; 8102 8103 len = sizeof(*cmd); 8104 buf = wmi_buf_alloc(wmi_handle, len); 8105 if (!buf) 8106 return QDF_STATUS_E_FAILURE; 8107 8108 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8109 WMITLV_SET_HDR(&cmd->tlv_header, 8110 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8111 WMITLV_GET_STRUCT_TLVLEN( 8112 WMI_COEX_CONFIG_CMD_fixed_param)); 8113 8114 cmd->vdev_id = param->vdev_id; 8115 cmd->config_type = param->config_type; 8116 cmd->config_arg1 = param->config_arg1; 8117 cmd->config_arg2 = param->config_arg2; 8118 cmd->config_arg3 = param->config_arg3; 8119 cmd->config_arg4 = param->config_arg4; 8120 cmd->config_arg5 = param->config_arg5; 8121 cmd->config_arg6 = param->config_arg6; 8122 8123 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8124 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8125 WMI_COEX_CONFIG_CMDID); 8126 8127 if (ret != 0) { 8128 wmi_err("Sending COEX CONFIG CMD failed"); 8129 wmi_buf_free(buf); 8130 } 8131 8132 return ret; 8133 } 8134 8135 #ifdef WLAN_FEATURE_DBAM_CONFIG 8136 8137 static enum wmi_coex_dbam_mode_type 8138 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8139 { 8140 switch (mode) { 8141 case COEX_DBAM_ENABLE: 8142 return WMI_COEX_DBAM_ENABLE; 8143 case COEX_DBAM_FORCE_ENABLE: 8144 return WMI_COEX_DBAM_FORCED; 8145 case COEX_DBAM_DISABLE: 8146 default: 8147 return WMI_COEX_DBAM_DISABLE; 8148 } 8149 } 8150 8151 /** 8152 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8153 * @wmi_handle: wmi handle 8154 * @param: pointer to coex dbam config param 8155 * 8156 * Return: 0 for success or error code 8157 */ 8158 static QDF_STATUS 8159 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8160 struct coex_dbam_config_params *param) 8161 { 8162 wmi_coex_dbam_cmd_fixed_param *cmd; 8163 wmi_buf_t buf; 8164 void *buf_ptr; 8165 QDF_STATUS ret; 8166 int32_t len; 8167 8168 len = sizeof(*cmd); 8169 buf = wmi_buf_alloc(wmi_handle, len); 8170 if (!buf) { 8171 wmi_err_rl("Failed to allocate wmi buffer"); 8172 return QDF_STATUS_E_NOMEM; 8173 } 8174 8175 buf_ptr = wmi_buf_data(buf); 8176 cmd = buf_ptr; 8177 WMITLV_SET_HDR(&cmd->tlv_header, 8178 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8179 WMITLV_GET_STRUCT_TLVLEN( 8180 wmi_coex_dbam_cmd_fixed_param)); 8181 8182 cmd->vdev_id = param->vdev_id; 8183 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8184 8185 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8186 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8187 WMI_COEX_DBAM_CMDID); 8188 8189 if (QDF_IS_STATUS_ERROR(ret)) { 8190 wmi_err("Sending DBAM CONFIG CMD failed"); 8191 wmi_buf_free(buf); 8192 return QDF_STATUS_E_FAILURE; 8193 } 8194 8195 return ret; 8196 } 8197 8198 static enum coex_dbam_comp_status 8199 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8200 { 8201 switch (status) { 8202 case WMI_COEX_DBAM_COMP_SUCCESS: 8203 case WMI_COEX_DBAM_COMP_ONGOING: 8204 case WMI_COEX_DBAM_COMP_DELAYED: 8205 return COEX_DBAM_COMP_SUCCESS; 8206 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8207 return COEX_DBAM_COMP_NOT_SUPPORT; 8208 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8209 case WMI_COEX_DBAM_COMP_FAIL: 8210 default: 8211 return COEX_DBAM_COMP_FAIL; 8212 } 8213 } 8214 8215 /** 8216 * extract_dbam_comp_status_event_tlv() - extract dbam complete status event 8217 * @wmi_handle: WMI handle 8218 * @evt_buf: event buffer 8219 * @resp: pointer to coex dbam config response 8220 * 8221 * Return: QDF_STATUS 8222 */ 8223 static QDF_STATUS 8224 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8225 struct coex_dbam_config_resp *resp) 8226 { 8227 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8228 wmi_coex_dbam_complete_event_fixed_param *event; 8229 8230 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8231 8232 event = param_buf->fixed_param; 8233 8234 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8235 8236 return QDF_STATUS_SUCCESS; 8237 } 8238 #endif 8239 8240 #ifdef WLAN_SUPPORT_TWT 8241 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8242 target_resource_config *tgt_res_cfg) 8243 { 8244 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8245 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8246 } 8247 #else 8248 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8249 target_resource_config *tgt_res_cfg) 8250 { 8251 resource_cfg->twt_ap_pdev_count = 0; 8252 resource_cfg->twt_ap_sta_count = 0; 8253 } 8254 #endif 8255 8256 #ifdef WLAN_FEATURE_NAN 8257 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8258 { 8259 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8260 resource_cfg->host_service_flags, 1); 8261 } 8262 #else 8263 static inline 8264 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8265 { 8266 } 8267 #endif 8268 8269 #if defined(CONFIG_AFC_SUPPORT) 8270 static 8271 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8272 target_resource_config *tgt_res_cfg) 8273 { 8274 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8275 resource_cfg->host_service_flags, 8276 tgt_res_cfg->afc_indoor_support); 8277 8278 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8279 resource_cfg->host_service_flags, 8280 tgt_res_cfg->afc_outdoor_support); 8281 } 8282 #else 8283 static 8284 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8285 target_resource_config *tgt_res_cfg) 8286 { 8287 } 8288 #endif 8289 8290 static 8291 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8292 target_resource_config *tgt_res_cfg) 8293 { 8294 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 8295 resource_cfg->num_peers = tgt_res_cfg->num_peers; 8296 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 8297 resource_cfg->num_offload_reorder_buffs = 8298 tgt_res_cfg->num_offload_reorder_buffs; 8299 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 8300 resource_cfg->num_tids = tgt_res_cfg->num_tids; 8301 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 8302 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 8303 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 8304 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 8305 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 8306 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 8307 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 8308 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 8309 resource_cfg->scan_max_pending_req = 8310 tgt_res_cfg->scan_max_pending_req; 8311 resource_cfg->bmiss_offload_max_vdev = 8312 tgt_res_cfg->bmiss_offload_max_vdev; 8313 resource_cfg->roam_offload_max_vdev = 8314 tgt_res_cfg->roam_offload_max_vdev; 8315 resource_cfg->roam_offload_max_ap_profiles = 8316 tgt_res_cfg->roam_offload_max_ap_profiles; 8317 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 8318 resource_cfg->num_mcast_table_elems = 8319 tgt_res_cfg->num_mcast_table_elems; 8320 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 8321 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 8322 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 8323 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 8324 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 8325 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 8326 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 8327 resource_cfg->vow_config = tgt_res_cfg->vow_config; 8328 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 8329 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 8330 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 8331 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 8332 resource_cfg->num_tdls_conn_table_entries = 8333 tgt_res_cfg->num_tdls_conn_table_entries; 8334 resource_cfg->beacon_tx_offload_max_vdev = 8335 tgt_res_cfg->beacon_tx_offload_max_vdev; 8336 resource_cfg->num_multicast_filter_entries = 8337 tgt_res_cfg->num_multicast_filter_entries; 8338 resource_cfg->num_wow_filters = 8339 tgt_res_cfg->num_wow_filters; 8340 resource_cfg->num_keep_alive_pattern = 8341 tgt_res_cfg->num_keep_alive_pattern; 8342 resource_cfg->keep_alive_pattern_size = 8343 tgt_res_cfg->keep_alive_pattern_size; 8344 resource_cfg->max_tdls_concurrent_sleep_sta = 8345 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 8346 resource_cfg->max_tdls_concurrent_buffer_sta = 8347 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 8348 resource_cfg->wmi_send_separate = 8349 tgt_res_cfg->wmi_send_separate; 8350 resource_cfg->num_ocb_vdevs = 8351 tgt_res_cfg->num_ocb_vdevs; 8352 resource_cfg->num_ocb_channels = 8353 tgt_res_cfg->num_ocb_channels; 8354 resource_cfg->num_ocb_schedules = 8355 tgt_res_cfg->num_ocb_schedules; 8356 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 8357 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 8358 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 8359 resource_cfg->max_num_dbs_scan_duty_cycle = 8360 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 8361 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 8362 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 8363 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 8364 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 8365 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 8366 /* Deferred AI: Max rnr neighbors supported in multisoc case 8367 * where in SoC can support 6ghz. During WMI init of a SoC 8368 * currently there is no way to figure if another SOC is plugged in 8369 * and it can support 6Ghz. 8370 */ 8371 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 8372 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 8373 resource_cfg->ema_max_profile_period = 8374 tgt_res_cfg->ema_max_profile_period; 8375 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 8376 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 8377 8378 if (tgt_res_cfg->max_ndp_sessions) 8379 resource_cfg->max_ndp_sessions = 8380 tgt_res_cfg->max_ndp_sessions; 8381 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 8382 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 8383 8384 if (tgt_res_cfg->atf_config) 8385 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 8386 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 8387 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 8388 resource_cfg->flag1, 1); 8389 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 8390 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 8391 resource_cfg->flag1, 1); 8392 if (tgt_res_cfg->cce_disable) 8393 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 8394 if (tgt_res_cfg->enable_pci_gen) 8395 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 8396 resource_cfg->flag1, 1); 8397 if (tgt_res_cfg->eapol_minrate_set) { 8398 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 8399 resource_cfg->flag1, 1); 8400 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 8401 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 8402 resource_cfg->flag1, 1); 8403 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 8404 resource_cfg->flag1, 8405 tgt_res_cfg->eapol_minrate_ac_set); 8406 } 8407 } 8408 if (tgt_res_cfg->new_htt_msg_format) { 8409 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 8410 resource_cfg->flag1, 1); 8411 } 8412 8413 if (tgt_res_cfg->peer_unmap_conf_support) 8414 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 8415 resource_cfg->flag1, 1); 8416 8417 if (tgt_res_cfg->tstamp64_en) 8418 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 8419 resource_cfg->flag1, 1); 8420 8421 if (tgt_res_cfg->three_way_coex_config_legacy_en) 8422 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 8423 resource_cfg->flag1, 1); 8424 if (tgt_res_cfg->pktcapture_support) 8425 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 8426 resource_cfg->flag1, 1); 8427 8428 /* 8429 * Control padding using config param/ini of iphdr_pad_config 8430 */ 8431 if (tgt_res_cfg->iphdr_pad_config) 8432 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 8433 resource_cfg->flag1, 1); 8434 8435 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 8436 tgt_res_cfg->ipa_disable); 8437 8438 if (tgt_res_cfg->time_sync_ftm) 8439 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 8440 1); 8441 8442 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 8443 resource_cfg->peer_map_unmap_versions = 8444 tgt_res_cfg->peer_map_unmap_version; 8445 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 8446 if (tgt_res_cfg->re_ul_resp) 8447 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 8448 tgt_res_cfg->re_ul_resp); 8449 8450 /* 8451 * Enable Service Aware Wifi 8452 */ 8453 if (tgt_res_cfg->sawf) 8454 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 8455 tgt_res_cfg->sawf); 8456 8457 /* 8458 * Enable ast flow override per peer 8459 */ 8460 resource_cfg->msdu_flow_override_config0 = 0; 8461 WMI_MSDU_FLOW_AST_ENABLE_SET( 8462 resource_cfg->msdu_flow_override_config0, 8463 WMI_CONFIG_MSDU_AST_INDEX_1, 8464 tgt_res_cfg->ast_1_valid_mask_enable); 8465 8466 WMI_MSDU_FLOW_AST_ENABLE_SET( 8467 resource_cfg->msdu_flow_override_config0, 8468 WMI_CONFIG_MSDU_AST_INDEX_2, 8469 tgt_res_cfg->ast_2_valid_mask_enable); 8470 8471 WMI_MSDU_FLOW_AST_ENABLE_SET( 8472 resource_cfg->msdu_flow_override_config0, 8473 WMI_CONFIG_MSDU_AST_INDEX_3, 8474 tgt_res_cfg->ast_3_valid_mask_enable); 8475 8476 /* 8477 * Enable ast flow mask and TID valid mask configurations 8478 */ 8479 resource_cfg->msdu_flow_override_config1 = 0; 8480 8481 /*Enable UDP flow for Ast index 0*/ 8482 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8483 resource_cfg->msdu_flow_override_config1, 8484 WMI_CONFIG_MSDU_AST_INDEX_0, 8485 tgt_res_cfg->ast_0_flow_mask_enable); 8486 8487 /*Enable Non UDP flow for Ast index 1*/ 8488 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8489 resource_cfg->msdu_flow_override_config1, 8490 WMI_CONFIG_MSDU_AST_INDEX_1, 8491 tgt_res_cfg->ast_1_flow_mask_enable); 8492 8493 /*Enable Hi-Priority flow for Ast index 2*/ 8494 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8495 resource_cfg->msdu_flow_override_config1, 8496 WMI_CONFIG_MSDU_AST_INDEX_2, 8497 tgt_res_cfg->ast_2_flow_mask_enable); 8498 8499 /*Enable Low-Priority flow for Ast index 3*/ 8500 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8501 resource_cfg->msdu_flow_override_config1, 8502 WMI_CONFIG_MSDU_AST_INDEX_3, 8503 tgt_res_cfg->ast_3_flow_mask_enable); 8504 8505 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 8506 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 8507 resource_cfg->msdu_flow_override_config1, 8508 tgt_res_cfg->ast_tid_high_mask_enable); 8509 8510 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 8511 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 8512 resource_cfg->msdu_flow_override_config1, 8513 tgt_res_cfg->ast_tid_low_mask_enable); 8514 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 8515 resource_cfg->host_service_flags, 8516 tgt_res_cfg->nan_separate_iface_support); 8517 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 8518 resource_cfg->host_service_flags, 1); 8519 8520 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 8521 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 8522 8523 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 8524 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 8525 resource_cfg->flags2, 1); 8526 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 8527 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 8528 resource_cfg->flags2, 1); 8529 8530 if (tgt_res_cfg->sae_eapol_offload) 8531 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 8532 resource_cfg->host_service_flags, 1); 8533 8534 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 8535 resource_cfg->host_service_flags, 8536 tgt_res_cfg->is_reg_cc_ext_event_supported); 8537 8538 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 8539 resource_cfg->host_service_flags, 8540 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 8541 8542 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 8543 resource_cfg->host_service_flags, 8544 tgt_res_cfg->afc_timer_check_disable); 8545 8546 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 8547 resource_cfg->host_service_flags, 8548 tgt_res_cfg->afc_req_id_check_disable); 8549 8550 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 8551 8552 wmi_set_nan_channel_support(resource_cfg); 8553 8554 if (tgt_res_cfg->twt_ack_support_cap) 8555 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 8556 resource_cfg->host_service_flags, 1); 8557 8558 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 8559 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 8560 resource_cfg->host_service_flags, 1); 8561 8562 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 8563 tgt_res_cfg->target_cap_flags); 8564 if (tgt_res_cfg->notify_frame_support) 8565 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 8566 resource_cfg->flags2, 1); 8567 8568 } 8569 8570 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 8571 * @wmi_handle: pointer to wmi handle 8572 * @buf_ptr: pointer to current position in init command buffer 8573 * @len: pointer to length. This will be updated with current length of cmd 8574 * @param: point host parameters for init command 8575 * 8576 * Return: Updated pointer of buf_ptr. 8577 */ 8578 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 8579 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 8580 { 8581 uint16_t idx; 8582 8583 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 8584 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 8585 wmi_pdev_band_to_mac *band_to_mac; 8586 8587 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 8588 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 8589 sizeof(wmi_resource_config) + 8590 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 8591 sizeof(wlan_host_memory_chunk))); 8592 8593 WMITLV_SET_HDR(&hw_mode->tlv_header, 8594 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 8595 (WMITLV_GET_STRUCT_TLVLEN 8596 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 8597 8598 hw_mode->hw_mode_index = param->hw_mode_id; 8599 hw_mode->num_band_to_mac = param->num_band_to_mac; 8600 8601 buf_ptr = (uint8_t *) (hw_mode + 1); 8602 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 8603 WMI_TLV_HDR_SIZE); 8604 for (idx = 0; idx < param->num_band_to_mac; idx++) { 8605 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 8606 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 8607 WMITLV_GET_STRUCT_TLVLEN 8608 (wmi_pdev_band_to_mac)); 8609 band_to_mac[idx].pdev_id = 8610 wmi_handle->ops->convert_pdev_id_host_to_target( 8611 wmi_handle, 8612 param->band_to_mac[idx].pdev_id); 8613 band_to_mac[idx].start_freq = 8614 param->band_to_mac[idx].start_freq; 8615 band_to_mac[idx].end_freq = 8616 param->band_to_mac[idx].end_freq; 8617 } 8618 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 8619 (param->num_band_to_mac * 8620 sizeof(wmi_pdev_band_to_mac)) + 8621 WMI_TLV_HDR_SIZE; 8622 8623 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8624 (param->num_band_to_mac * 8625 sizeof(wmi_pdev_band_to_mac))); 8626 } 8627 8628 return buf_ptr; 8629 } 8630 8631 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 8632 wmi_init_cmd_fixed_param *cmd) 8633 { 8634 int num_allowlist; 8635 wmi_abi_version my_vers; 8636 8637 num_allowlist = sizeof(version_whitelist) / 8638 sizeof(wmi_whitelist_version_info); 8639 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 8640 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 8641 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 8642 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 8643 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 8644 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 8645 8646 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 8647 &my_vers, 8648 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 8649 &cmd->host_abi_vers); 8650 8651 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 8652 __func__, 8653 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 8654 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 8655 cmd->host_abi_vers.abi_version_ns_0, 8656 cmd->host_abi_vers.abi_version_ns_1, 8657 cmd->host_abi_vers.abi_version_ns_2, 8658 cmd->host_abi_vers.abi_version_ns_3); 8659 8660 /* Save version sent from host - 8661 * Will be used to check ready event 8662 */ 8663 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 8664 sizeof(wmi_abi_version)); 8665 } 8666 8667 /* 8668 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 8669 * @wmi_handle: Pointer to WMi handle 8670 * @ie_data: Pointer for ie data 8671 * 8672 * This function sends action frame tb ppdu cfg to FW 8673 * 8674 * Return: QDF_STATUS_SUCCESS for success otherwise failure 8675 * 8676 */ 8677 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 8678 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 8679 { 8680 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 8681 wmi_buf_t buf; 8682 uint8_t *buf_ptr; 8683 uint32_t len, frm_len_aligned; 8684 QDF_STATUS ret; 8685 8686 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 8687 /* Allocate memory for the WMI command */ 8688 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 8689 8690 buf = wmi_buf_alloc(wmi_handle, len); 8691 if (!buf) 8692 return QDF_STATUS_E_NOMEM; 8693 8694 buf_ptr = wmi_buf_data(buf); 8695 qdf_mem_zero(buf_ptr, len); 8696 8697 /* Populate the WMI command */ 8698 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 8699 8700 WMITLV_SET_HDR(&cmd->tlv_header, 8701 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 8702 WMITLV_GET_STRUCT_TLVLEN( 8703 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 8704 cmd->enable = cfg_msg->cfg; 8705 cmd->data_len = cfg_msg->frm_len; 8706 8707 buf_ptr += sizeof(*cmd); 8708 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 8709 buf_ptr += WMI_TLV_HDR_SIZE; 8710 8711 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 8712 8713 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8714 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 8715 if (QDF_IS_STATUS_ERROR(ret)) { 8716 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 8717 wmi_buf_free(buf); 8718 } 8719 8720 return ret; 8721 } 8722 8723 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 8724 { 8725 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8726 wmi_service_ready_event_fixed_param *ev; 8727 8728 8729 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8730 8731 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 8732 if (!ev) 8733 return QDF_STATUS_E_FAILURE; 8734 8735 /*Save fw version from service ready message */ 8736 /*This will be used while sending INIT message */ 8737 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8738 sizeof(wmi_handle->fw_abi_version)); 8739 8740 return QDF_STATUS_SUCCESS; 8741 } 8742 8743 /** 8744 * wmi_unified_save_fw_version_cmd() - save fw version 8745 * @wmi_handle: pointer to wmi handle 8746 * @res_cfg: resource config 8747 * @num_mem_chunks: no of mem chunck 8748 * @mem_chunk: pointer to mem chunck structure 8749 * 8750 * This function sends IE information to firmware 8751 * 8752 * Return: QDF_STATUS_SUCCESS for success otherwise failure 8753 * 8754 */ 8755 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 8756 void *evt_buf) 8757 { 8758 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8759 wmi_ready_event_fixed_param *ev = NULL; 8760 8761 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8762 ev = param_buf->fixed_param; 8763 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 8764 &wmi_handle->final_abi_vers, 8765 &ev->fw_abi_vers)) { 8766 /* 8767 * Error: Our host version and the given firmware version 8768 * are incompatible. 8769 **/ 8770 wmi_debug("Error: Incompatible WMI version." 8771 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 8772 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 8773 abi_version_0), 8774 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 8775 abi_version_0), 8776 wmi_handle->final_abi_vers.abi_version_ns_0, 8777 wmi_handle->final_abi_vers.abi_version_ns_1, 8778 wmi_handle->final_abi_vers.abi_version_ns_2, 8779 wmi_handle->final_abi_vers.abi_version_ns_3, 8780 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 8781 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 8782 ev->fw_abi_vers.abi_version_ns_0, 8783 ev->fw_abi_vers.abi_version_ns_1, 8784 ev->fw_abi_vers.abi_version_ns_2, 8785 ev->fw_abi_vers.abi_version_ns_3); 8786 8787 return QDF_STATUS_E_FAILURE; 8788 } 8789 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 8790 sizeof(wmi_abi_version)); 8791 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8792 sizeof(wmi_abi_version)); 8793 8794 return QDF_STATUS_SUCCESS; 8795 } 8796 8797 /** 8798 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 8799 * @handle: wmi handle 8800 * @event: Event received from FW 8801 * @len: Length of the event 8802 * 8803 * Enables the low frequency events and disables the high frequency 8804 * events. Bit 17 indicates if the event if low/high frequency. 8805 * 1 - high frequency, 0 - low frequency 8806 * 8807 * Return: 0 on successfully enabling/disabling the events 8808 */ 8809 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 8810 uint8_t *event, 8811 uint32_t len) 8812 { 8813 uint32_t num_of_diag_events_logs; 8814 wmi_diag_event_log_config_fixed_param *cmd; 8815 wmi_buf_t buf; 8816 uint8_t *buf_ptr; 8817 uint32_t *cmd_args, *evt_args; 8818 uint32_t buf_len, i; 8819 8820 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 8821 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 8822 8823 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 8824 8825 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 8826 if (!param_buf) { 8827 wmi_err("Invalid log supported event buffer"); 8828 return QDF_STATUS_E_INVAL; 8829 } 8830 wmi_event = param_buf->fixed_param; 8831 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 8832 8833 if (num_of_diag_events_logs > 8834 param_buf->num_diag_events_logs_list) { 8835 wmi_err("message number of events %d is more than tlv hdr content %d", 8836 num_of_diag_events_logs, 8837 param_buf->num_diag_events_logs_list); 8838 return QDF_STATUS_E_INVAL; 8839 } 8840 8841 evt_args = param_buf->diag_events_logs_list; 8842 if (!evt_args) { 8843 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 8844 num_of_diag_events_logs); 8845 return QDF_STATUS_E_INVAL; 8846 } 8847 8848 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 8849 8850 /* Free any previous allocation */ 8851 if (wmi_handle->events_logs_list) { 8852 qdf_mem_free(wmi_handle->events_logs_list); 8853 wmi_handle->events_logs_list = NULL; 8854 } 8855 8856 if (num_of_diag_events_logs > 8857 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 8858 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 8859 QDF_ASSERT(0); 8860 return QDF_STATUS_E_INVAL; 8861 } 8862 /* Store the event list for run time enable/disable */ 8863 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 8864 sizeof(uint32_t)); 8865 if (!wmi_handle->events_logs_list) 8866 return QDF_STATUS_E_NOMEM; 8867 8868 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 8869 8870 /* Prepare the send buffer */ 8871 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8872 (num_of_diag_events_logs * sizeof(uint32_t)); 8873 8874 buf = wmi_buf_alloc(wmi_handle, buf_len); 8875 if (!buf) { 8876 qdf_mem_free(wmi_handle->events_logs_list); 8877 wmi_handle->events_logs_list = NULL; 8878 return QDF_STATUS_E_NOMEM; 8879 } 8880 8881 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8882 buf_ptr = (uint8_t *) cmd; 8883 8884 WMITLV_SET_HDR(&cmd->tlv_header, 8885 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8886 WMITLV_GET_STRUCT_TLVLEN( 8887 wmi_diag_event_log_config_fixed_param)); 8888 8889 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 8890 8891 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8892 8893 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8894 (num_of_diag_events_logs * sizeof(uint32_t))); 8895 8896 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8897 8898 /* Populate the events */ 8899 for (i = 0; i < num_of_diag_events_logs; i++) { 8900 /* Low freq (0) - Enable (1) the event 8901 * High freq (1) - Disable (0) the event 8902 */ 8903 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 8904 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 8905 /* Set the event ID */ 8906 WMI_DIAG_ID_SET(cmd_args[i], 8907 WMI_DIAG_ID_GET(evt_args[i])); 8908 /* Set the type */ 8909 WMI_DIAG_TYPE_SET(cmd_args[i], 8910 WMI_DIAG_TYPE_GET(evt_args[i])); 8911 /* Storing the event/log list in WMI */ 8912 wmi_handle->events_logs_list[i] = evt_args[i]; 8913 } 8914 8915 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8916 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 8917 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8918 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8919 wmi_buf_free(buf); 8920 /* Not clearing events_logs_list, though wmi cmd failed. 8921 * Host can still have this list 8922 */ 8923 return QDF_STATUS_E_INVAL; 8924 } 8925 8926 return 0; 8927 } 8928 8929 /** 8930 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 8931 * @wmi_handle: wmi handle 8932 * @start_log: Start logging related parameters 8933 * 8934 * Send the command to the FW based on which specific logging of diag 8935 * event/log id can be started/stopped 8936 * 8937 * Return: None 8938 */ 8939 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 8940 struct wmi_wifi_start_log *start_log) 8941 { 8942 wmi_diag_event_log_config_fixed_param *cmd; 8943 wmi_buf_t buf; 8944 uint8_t *buf_ptr; 8945 uint32_t len, count, log_level, i; 8946 uint32_t *cmd_args; 8947 uint32_t total_len; 8948 count = 0; 8949 8950 if (!wmi_handle->events_logs_list) { 8951 wmi_debug("Not received event/log list from FW, yet"); 8952 return QDF_STATUS_E_NOMEM; 8953 } 8954 /* total_len stores the number of events where BITS 17 and 18 are set. 8955 * i.e., events of high frequency (17) and for extended debugging (18) 8956 */ 8957 total_len = 0; 8958 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8959 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 8960 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 8961 total_len++; 8962 } 8963 8964 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8965 (total_len * sizeof(uint32_t)); 8966 8967 buf = wmi_buf_alloc(wmi_handle, len); 8968 if (!buf) 8969 return QDF_STATUS_E_NOMEM; 8970 8971 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8972 buf_ptr = (uint8_t *) cmd; 8973 8974 WMITLV_SET_HDR(&cmd->tlv_header, 8975 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8976 WMITLV_GET_STRUCT_TLVLEN( 8977 wmi_diag_event_log_config_fixed_param)); 8978 8979 cmd->num_of_diag_events_logs = total_len; 8980 8981 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8982 8983 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8984 (total_len * sizeof(uint32_t))); 8985 8986 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8987 8988 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 8989 log_level = 1; 8990 else 8991 log_level = 0; 8992 8993 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 8994 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8995 uint32_t val = wmi_handle->events_logs_list[i]; 8996 if ((WMI_DIAG_FREQUENCY_GET(val)) && 8997 (WMI_DIAG_EXT_FEATURE_GET(val))) { 8998 8999 WMI_DIAG_ID_SET(cmd_args[count], 9000 WMI_DIAG_ID_GET(val)); 9001 WMI_DIAG_TYPE_SET(cmd_args[count], 9002 WMI_DIAG_TYPE_GET(val)); 9003 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 9004 log_level); 9005 wmi_debug("Idx:%d, val:%x", i, val); 9006 count++; 9007 } 9008 } 9009 9010 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9011 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9012 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9013 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9014 wmi_buf_free(buf); 9015 return QDF_STATUS_E_INVAL; 9016 } 9017 9018 return QDF_STATUS_SUCCESS; 9019 } 9020 9021 /** 9022 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 9023 * @wmi_handle: WMI handle 9024 * 9025 * This function is used to send the flush command to the FW, 9026 * that will flush the fw logs that are residue in the FW 9027 * 9028 * Return: None 9029 */ 9030 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9031 { 9032 wmi_debug_mesg_flush_fixed_param *cmd; 9033 wmi_buf_t buf; 9034 int len = sizeof(*cmd); 9035 QDF_STATUS ret; 9036 9037 buf = wmi_buf_alloc(wmi_handle, len); 9038 if (!buf) 9039 return QDF_STATUS_E_NOMEM; 9040 9041 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 9042 WMITLV_SET_HDR(&cmd->tlv_header, 9043 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 9044 WMITLV_GET_STRUCT_TLVLEN( 9045 wmi_debug_mesg_flush_fixed_param)); 9046 cmd->reserved0 = 0; 9047 9048 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 9049 ret = wmi_unified_cmd_send(wmi_handle, 9050 buf, 9051 len, 9052 WMI_DEBUG_MESG_FLUSH_CMDID); 9053 if (QDF_IS_STATUS_ERROR(ret)) { 9054 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 9055 wmi_buf_free(buf); 9056 return QDF_STATUS_E_INVAL; 9057 } 9058 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 9059 9060 return ret; 9061 } 9062 9063 #ifdef BIG_ENDIAN_HOST 9064 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9065 /** 9066 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 9067 * @param - fips extend param related parameters 9068 * 9069 * Return: QDF_STATUS - success or error status 9070 */ 9071 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9072 struct fips_extend_params *param) 9073 { 9074 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 9075 int c; 9076 u_int8_t *key_aligned = NULL; 9077 u_int8_t *nonce_iv_aligned = NULL; 9078 u_int8_t *data_aligned = NULL; 9079 int ret = QDF_STATUS_SUCCESS; 9080 9081 /* Assigning unaligned space to copy the key */ 9082 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9083 param->cmd_params.key_len + FIPS_ALIGN); 9084 /* Checking if kmalloc is successful to allocate space */ 9085 if (!key_unaligned) 9086 return QDF_STATUS_E_INVAL; 9087 9088 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 9089 FIPS_ALIGN); 9090 /* Checking if kmalloc is successful to allocate space */ 9091 if (!data_unaligned) { 9092 ret = QDF_STATUS_E_INVAL; 9093 goto fips_align_fail_data; 9094 } 9095 9096 /* Checking if space is aligned */ 9097 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9098 /* align to 4 */ 9099 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9100 FIPS_ALIGN); 9101 } else { 9102 key_aligned = (u_int8_t *)key_unaligned; 9103 } 9104 9105 /* memset and copy content from key to key aligned */ 9106 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 9107 OS_MEMCPY(key_aligned, param->cmd_params.key, 9108 param->cmd_params.key_len); 9109 9110 /* print a hexdump for host debug */ 9111 wmi_debug("Aligned and Copied Key: "); 9112 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9113 key_aligned, param->cmd_params.key_len); 9114 9115 /* Checking of space is aligned */ 9116 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9117 /* align to 4 */ 9118 data_aligned = 9119 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 9120 } else { 9121 data_aligned = (u_int8_t *)data_unaligned; 9122 } 9123 9124 /* memset and copy content from data to data aligned */ 9125 OS_MEMSET(data_aligned, 0, param->data_len); 9126 OS_MEMCPY(data_aligned, param->data, param->data_len); 9127 9128 /* print a hexdump for host debug */ 9129 wmi_debug("\t Properly Aligned and Copied Data: "); 9130 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9131 data_aligned, param->data_len); 9132 9133 /* converting to little Endian */ 9134 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 9135 *((u_int32_t *)key_aligned + c) = 9136 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 9137 } 9138 for (c = 0; c < param->data_len / 4; c++) { 9139 *((u_int32_t *)data_aligned + c) = 9140 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 9141 } 9142 9143 /* update endian data */ 9144 OS_MEMCPY(param->cmd_params.key, key_aligned, 9145 param->cmd_params.key_len); 9146 OS_MEMCPY(param->data, data_aligned, param->data_len); 9147 9148 if (param->cmd_params.nonce_iv_len) { 9149 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9150 param->cmd_params.nonce_iv_len + 9151 FIPS_ALIGN); 9152 9153 /* Checking if kmalloc is successful to allocate space */ 9154 if (!nonce_iv_unaligned) { 9155 ret = QDF_STATUS_E_INVAL; 9156 goto fips_align_fail_nonce_iv; 9157 } 9158 /* Checking if space is aligned */ 9159 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 9160 /* align to 4 */ 9161 nonce_iv_aligned = 9162 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 9163 FIPS_ALIGN); 9164 } else { 9165 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 9166 } 9167 9168 /* memset and copy content from iv to iv aligned */ 9169 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 9170 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 9171 param->cmd_params.nonce_iv_len); 9172 9173 /* print a hexdump for host debug */ 9174 wmi_debug("\t Aligned and Copied Nonce_IV: "); 9175 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9176 nonce_iv_aligned, 9177 param->cmd_params.nonce_iv_len); 9178 9179 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 9180 *((u_int32_t *)nonce_iv_aligned + c) = 9181 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 9182 } 9183 } 9184 9185 /* clean up allocated spaces */ 9186 qdf_mem_free(nonce_iv_unaligned); 9187 nonce_iv_unaligned = NULL; 9188 nonce_iv_aligned = NULL; 9189 9190 fips_align_fail_nonce_iv: 9191 qdf_mem_free(data_unaligned); 9192 data_unaligned = NULL; 9193 data_aligned = NULL; 9194 9195 fips_align_fail_data: 9196 qdf_mem_free(key_unaligned); 9197 key_unaligned = NULL; 9198 key_aligned = NULL; 9199 9200 return ret; 9201 } 9202 #endif 9203 9204 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 9205 struct fips_params *param) 9206 { 9207 unsigned char *key_unaligned, *data_unaligned; 9208 int c; 9209 u_int8_t *key_aligned = NULL; 9210 u_int8_t *data_aligned = NULL; 9211 9212 /* Assigning unaligned space to copy the key */ 9213 key_unaligned = qdf_mem_malloc( 9214 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 9215 data_unaligned = qdf_mem_malloc( 9216 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 9217 9218 /* Checking if kmalloc is successful to allocate space */ 9219 if (!key_unaligned) 9220 return QDF_STATUS_SUCCESS; 9221 /* Checking if space is aligned */ 9222 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9223 /* align to 4 */ 9224 key_aligned = 9225 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9226 FIPS_ALIGN); 9227 } else { 9228 key_aligned = (u_int8_t *)key_unaligned; 9229 } 9230 9231 /* memset and copy content from key to key aligned */ 9232 OS_MEMSET(key_aligned, 0, param->key_len); 9233 OS_MEMCPY(key_aligned, param->key, param->key_len); 9234 9235 /* print a hexdump for host debug */ 9236 print_hex_dump(KERN_DEBUG, 9237 "\t Aligned and Copied Key:@@@@ ", 9238 DUMP_PREFIX_NONE, 9239 16, 1, key_aligned, param->key_len, true); 9240 9241 /* Checking if kmalloc is successful to allocate space */ 9242 if (!data_unaligned) 9243 return QDF_STATUS_SUCCESS; 9244 /* Checking of space is aligned */ 9245 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9246 /* align to 4 */ 9247 data_aligned = 9248 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 9249 FIPS_ALIGN); 9250 } else { 9251 data_aligned = (u_int8_t *)data_unaligned; 9252 } 9253 9254 /* memset and copy content from data to data aligned */ 9255 OS_MEMSET(data_aligned, 0, param->data_len); 9256 OS_MEMCPY(data_aligned, param->data, param->data_len); 9257 9258 /* print a hexdump for host debug */ 9259 print_hex_dump(KERN_DEBUG, 9260 "\t Properly Aligned and Copied Data:@@@@ ", 9261 DUMP_PREFIX_NONE, 9262 16, 1, data_aligned, param->data_len, true); 9263 9264 /* converting to little Endian both key_aligned and 9265 * data_aligned*/ 9266 for (c = 0; c < param->key_len/4; c++) { 9267 *((u_int32_t *)key_aligned+c) = 9268 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 9269 } 9270 for (c = 0; c < param->data_len/4; c++) { 9271 *((u_int32_t *)data_aligned+c) = 9272 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 9273 } 9274 9275 /* update endian data to key and data vectors */ 9276 OS_MEMCPY(param->key, key_aligned, param->key_len); 9277 OS_MEMCPY(param->data, data_aligned, param->data_len); 9278 9279 /* clean up allocated spaces */ 9280 qdf_mem_free(key_unaligned); 9281 key_unaligned = NULL; 9282 key_aligned = NULL; 9283 9284 qdf_mem_free(data_unaligned); 9285 data_unaligned = NULL; 9286 data_aligned = NULL; 9287 9288 return QDF_STATUS_SUCCESS; 9289 } 9290 #else 9291 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9292 /** 9293 * fips_extend_align_data_be() - DUMMY for LE platform 9294 * 9295 * Return: QDF_STATUS - success 9296 */ 9297 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9298 struct fips_extend_params *param) 9299 { 9300 return QDF_STATUS_SUCCESS; 9301 } 9302 #endif 9303 9304 /** 9305 * fips_align_data_be() - DUMMY for LE platform 9306 * 9307 * Return: QDF_STATUS - success 9308 */ 9309 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 9310 struct fips_params *param) 9311 { 9312 return QDF_STATUS_SUCCESS; 9313 } 9314 #endif 9315 9316 #ifdef WLAN_FEATURE_DISA 9317 /** 9318 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 9319 * @wmi_handle: wmi handle 9320 * @params: encrypt/decrypt params 9321 * 9322 * Return: QDF_STATUS_SUCCESS for success or error code 9323 */ 9324 static QDF_STATUS 9325 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 9326 struct disa_encrypt_decrypt_req_params 9327 *encrypt_decrypt_params) 9328 { 9329 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 9330 wmi_buf_t wmi_buf; 9331 uint8_t *buf_ptr; 9332 QDF_STATUS ret; 9333 uint32_t len; 9334 9335 wmi_debug("Send encrypt decrypt cmd"); 9336 9337 len = sizeof(*cmd) + 9338 encrypt_decrypt_params->data_len + 9339 WMI_TLV_HDR_SIZE; 9340 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9341 if (!wmi_buf) 9342 return QDF_STATUS_E_NOMEM; 9343 9344 buf_ptr = wmi_buf_data(wmi_buf); 9345 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 9346 9347 WMITLV_SET_HDR(&cmd->tlv_header, 9348 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 9349 WMITLV_GET_STRUCT_TLVLEN( 9350 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 9351 9352 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 9353 cmd->key_flag = encrypt_decrypt_params->key_flag; 9354 cmd->key_idx = encrypt_decrypt_params->key_idx; 9355 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 9356 cmd->key_len = encrypt_decrypt_params->key_len; 9357 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 9358 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 9359 9360 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 9361 encrypt_decrypt_params->key_len); 9362 9363 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 9364 MAX_MAC_HEADER_LEN); 9365 9366 cmd->data_len = encrypt_decrypt_params->data_len; 9367 9368 if (cmd->data_len) { 9369 buf_ptr += sizeof(*cmd); 9370 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 9371 roundup(encrypt_decrypt_params->data_len, 9372 sizeof(uint32_t))); 9373 buf_ptr += WMI_TLV_HDR_SIZE; 9374 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 9375 encrypt_decrypt_params->data_len); 9376 } 9377 9378 /* This conversion is to facilitate data to FW in little endian */ 9379 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 9380 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 9381 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 9382 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 9383 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 9384 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 9385 9386 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 9387 ret = wmi_unified_cmd_send(wmi_handle, 9388 wmi_buf, len, 9389 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 9390 if (QDF_IS_STATUS_ERROR(ret)) { 9391 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 9392 wmi_buf_free(wmi_buf); 9393 } 9394 9395 return ret; 9396 } 9397 #endif /* WLAN_FEATURE_DISA */ 9398 9399 /** 9400 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 9401 * @wmi_handle: wmi handle 9402 * @param: pointer to hold pdev fips param 9403 * 9404 * Return: 0 for success or error code 9405 */ 9406 static QDF_STATUS 9407 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 9408 struct fips_params *param) 9409 { 9410 wmi_pdev_fips_cmd_fixed_param *cmd; 9411 wmi_buf_t buf; 9412 uint8_t *buf_ptr; 9413 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 9414 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9415 9416 /* Length TLV placeholder for array of bytes */ 9417 len += WMI_TLV_HDR_SIZE; 9418 if (param->data_len) 9419 len += (param->data_len*sizeof(uint8_t)); 9420 9421 /* 9422 * Data length must be multiples of 16 bytes - checked against 0xF - 9423 * and must be less than WMI_SVC_MSG_SIZE - static size of 9424 * wmi_pdev_fips_cmd structure 9425 */ 9426 9427 /* do sanity on the input */ 9428 if (!(((param->data_len & 0xF) == 0) && 9429 ((param->data_len > 0) && 9430 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 9431 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 9432 return QDF_STATUS_E_INVAL; 9433 } 9434 9435 buf = wmi_buf_alloc(wmi_handle, len); 9436 if (!buf) 9437 return QDF_STATUS_E_FAILURE; 9438 9439 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9440 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 9441 WMITLV_SET_HDR(&cmd->tlv_header, 9442 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 9443 WMITLV_GET_STRUCT_TLVLEN 9444 (wmi_pdev_fips_cmd_fixed_param)); 9445 9446 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9447 wmi_handle, 9448 param->pdev_id); 9449 if (param->key && param->data) { 9450 cmd->key_len = param->key_len; 9451 cmd->data_len = param->data_len; 9452 cmd->fips_cmd = !!(param->op); 9453 9454 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 9455 return QDF_STATUS_E_FAILURE; 9456 9457 qdf_mem_copy(cmd->key, param->key, param->key_len); 9458 9459 if (param->mode == FIPS_ENGINE_AES_CTR || 9460 param->mode == FIPS_ENGINE_AES_MIC) { 9461 cmd->mode = param->mode; 9462 } else { 9463 cmd->mode = FIPS_ENGINE_AES_CTR; 9464 } 9465 qdf_print("Key len = %d, Data len = %d", 9466 cmd->key_len, cmd->data_len); 9467 9468 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 9469 cmd->key, cmd->key_len, true); 9470 buf_ptr += sizeof(*cmd); 9471 9472 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 9473 9474 buf_ptr += WMI_TLV_HDR_SIZE; 9475 if (param->data_len) 9476 qdf_mem_copy(buf_ptr, 9477 (uint8_t *) param->data, param->data_len); 9478 9479 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 9480 16, 1, buf_ptr, cmd->data_len, true); 9481 9482 buf_ptr += param->data_len; 9483 9484 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 9485 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9486 WMI_PDEV_FIPS_CMDID); 9487 qdf_print("%s return value %d", __func__, retval); 9488 } else { 9489 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 9490 wmi_buf_free(buf); 9491 retval = -QDF_STATUS_E_BADMSG; 9492 } 9493 9494 return retval; 9495 } 9496 9497 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9498 /** 9499 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 9500 * @wmi_handle: wmi handle 9501 * @param: pointer to hold pdev fips param 9502 * 9503 * Return: 0 for success or error code 9504 */ 9505 static QDF_STATUS 9506 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 9507 struct fips_extend_params *param) 9508 { 9509 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 9510 wmi_buf_t buf; 9511 uint8_t *buf_ptr; 9512 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 9513 uint32_t data_len_aligned; 9514 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9515 9516 len += WMI_TLV_HDR_SIZE; 9517 if (param->frag_idx == 0) 9518 len += sizeof(wmi_fips_extend_cmd_init_params); 9519 9520 /* Length TLV placeholder for array of bytes */ 9521 len += WMI_TLV_HDR_SIZE; 9522 if (param->data_len) { 9523 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 9524 len += (data_len_aligned * sizeof(uint8_t)); 9525 } 9526 9527 buf = wmi_buf_alloc(wmi_handle, len); 9528 if (!buf) 9529 return QDF_STATUS_E_FAILURE; 9530 9531 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9532 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 9533 WMITLV_SET_HDR(&cmd->tlv_header, 9534 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 9535 WMITLV_GET_STRUCT_TLVLEN 9536 (wmi_pdev_fips_extend_cmd_fixed_param)); 9537 9538 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9539 wmi_handle, 9540 param->pdev_id); 9541 9542 cmd->fips_cookie = param->cookie; 9543 cmd->frag_idx = param->frag_idx; 9544 cmd->more_bit = param->more_bit; 9545 cmd->data_len = param->data_len; 9546 9547 if (fips_extend_align_data_be(wmi_handle, param) != 9548 QDF_STATUS_SUCCESS) { 9549 wmi_buf_free(buf); 9550 return QDF_STATUS_E_FAILURE; 9551 } 9552 9553 buf_ptr = (uint8_t *)(cmd + 1); 9554 if (cmd->frag_idx == 0) { 9555 wmi_fips_extend_cmd_init_params *cmd_params; 9556 9557 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9558 sizeof(wmi_fips_extend_cmd_init_params)); 9559 buf_ptr += WMI_TLV_HDR_SIZE; 9560 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 9561 WMITLV_SET_HDR(buf_ptr, 9562 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 9563 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 9564 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 9565 cmd_params->key_cipher = param->cmd_params.key_cipher; 9566 cmd_params->key_len = param->cmd_params.key_len; 9567 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 9568 cmd_params->tag_len = param->cmd_params.tag_len; 9569 cmd_params->aad_len = param->cmd_params.aad_len; 9570 cmd_params->payload_len = param->cmd_params.payload_len; 9571 9572 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 9573 param->cmd_params.key_len); 9574 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 9575 param->cmd_params.nonce_iv_len); 9576 9577 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 9578 cmd_params->key_len, cmd_params->nonce_iv_len, 9579 cmd_params->tag_len, cmd_params->aad_len, 9580 cmd_params->payload_len); 9581 9582 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 9583 } else { 9584 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9585 buf_ptr += WMI_TLV_HDR_SIZE; 9586 } 9587 9588 if (param->data_len && param->data) { 9589 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 9590 data_len_aligned); 9591 9592 buf_ptr += WMI_TLV_HDR_SIZE; 9593 if (param->data_len) 9594 qdf_mem_copy(buf_ptr, 9595 (uint8_t *)param->data, param->data_len); 9596 9597 wmi_debug("Data: "); 9598 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9599 buf_ptr, cmd->data_len); 9600 9601 if (param->data_len) 9602 buf_ptr += param->data_len; 9603 } else { 9604 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 9605 buf_ptr += WMI_TLV_HDR_SIZE; 9606 } 9607 9608 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 9609 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9610 WMI_PDEV_FIPS_EXTEND_CMDID); 9611 9612 if (retval) { 9613 wmi_err("Failed to send FIPS cmd"); 9614 wmi_buf_free(buf); 9615 } 9616 9617 return retval; 9618 } 9619 9620 /** 9621 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 9622 * @wmi_handle: wmi handle 9623 * @param: pointer to hold pdev fips param 9624 * 9625 * Return: 0 for success or error code 9626 */ 9627 static QDF_STATUS 9628 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 9629 struct fips_mode_set_params *param) 9630 { 9631 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 9632 wmi_buf_t buf; 9633 uint8_t *buf_ptr; 9634 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 9635 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9636 9637 buf = wmi_buf_alloc(wmi_handle, len); 9638 if (!buf) 9639 return QDF_STATUS_E_FAILURE; 9640 9641 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9642 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 9643 WMITLV_SET_HDR(&cmd->tlv_header, 9644 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 9645 WMITLV_GET_STRUCT_TLVLEN 9646 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 9647 9648 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9649 wmi_handle, 9650 param->pdev_id); 9651 9652 cmd->fips_mode_set = param->mode; 9653 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 9654 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9655 WMI_PDEV_FIPS_MODE_SET_CMDID); 9656 if (retval) { 9657 wmi_err("Failed to send FIPS mode enable cmd"); 9658 wmi_buf_free(buf); 9659 } 9660 return retval; 9661 } 9662 #endif 9663 9664 /** 9665 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 9666 * to fw 9667 * @wmi_handle: wmi handle 9668 * @param: pointer to wlan profile param 9669 * 9670 * Return: 0 for success or error code 9671 */ 9672 static QDF_STATUS 9673 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 9674 struct wlan_profile_params *param) 9675 { 9676 wmi_buf_t buf; 9677 uint16_t len; 9678 QDF_STATUS ret; 9679 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 9680 9681 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 9682 buf = wmi_buf_alloc(wmi_handle, len); 9683 if (!buf) { 9684 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 9685 return QDF_STATUS_E_NOMEM; 9686 } 9687 9688 profile_enable_cmd = 9689 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 9690 wmi_buf_data(buf); 9691 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 9692 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 9693 WMITLV_GET_STRUCT_TLVLEN 9694 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 9695 9696 profile_enable_cmd->profile_id = param->profile_id; 9697 profile_enable_cmd->enable = param->enable; 9698 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 9699 NO_SESSION, 0); 9700 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9701 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 9702 if (ret) { 9703 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 9704 wmi_buf_free(buf); 9705 } 9706 return ret; 9707 } 9708 9709 /** 9710 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 9711 * to fw 9712 * @wmi_handle: wmi handle 9713 * @param: pointer to wlan profile param 9714 * 9715 * Return: 0 for success or error code 9716 */ 9717 static QDF_STATUS 9718 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 9719 struct wlan_profile_params *param) 9720 { 9721 wmi_buf_t buf; 9722 uint16_t len; 9723 QDF_STATUS ret; 9724 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 9725 9726 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 9727 buf = wmi_buf_alloc(wmi_handle, len); 9728 if (!buf) { 9729 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 9730 return QDF_STATUS_E_NOMEM; 9731 } 9732 9733 prof_trig_cmd = 9734 (wmi_wlan_profile_trigger_cmd_fixed_param *) 9735 wmi_buf_data(buf); 9736 9737 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 9738 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 9739 WMITLV_GET_STRUCT_TLVLEN 9740 (wmi_wlan_profile_trigger_cmd_fixed_param)); 9741 9742 prof_trig_cmd->enable = param->enable; 9743 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 9744 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9745 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9746 if (ret) { 9747 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 9748 wmi_buf_free(buf); 9749 } 9750 return ret; 9751 } 9752 9753 /** 9754 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 9755 * to fw 9756 * @wmi_handle: wmi handle 9757 * @param: pointer to wlan profile param 9758 * 9759 * Return: 0 for success or error code 9760 */ 9761 static QDF_STATUS 9762 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 9763 struct wlan_profile_params *param) 9764 { 9765 wmi_buf_t buf; 9766 int32_t len = 0; 9767 QDF_STATUS ret; 9768 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9769 9770 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9771 buf = wmi_buf_alloc(wmi_handle, len); 9772 if (!buf) { 9773 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 9774 return QDF_STATUS_E_NOMEM; 9775 } 9776 9777 hist_intvl_cmd = 9778 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9779 wmi_buf_data(buf); 9780 9781 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9782 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9783 WMITLV_GET_STRUCT_TLVLEN 9784 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9785 9786 hist_intvl_cmd->profile_id = param->profile_id; 9787 hist_intvl_cmd->value = param->enable; 9788 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 9789 NO_SESSION, 0); 9790 9791 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9792 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9793 if (ret) { 9794 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 9795 wmi_buf_free(buf); 9796 } 9797 return ret; 9798 } 9799 9800 /** 9801 * send_fw_test_cmd_tlv() - send fw test command to fw. 9802 * @wmi_handle: wmi handle 9803 * @wmi_fwtest: fw test command 9804 * 9805 * This function sends fw test command to fw. 9806 * 9807 * Return: CDF STATUS 9808 */ 9809 static 9810 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 9811 struct set_fwtest_params *wmi_fwtest) 9812 { 9813 wmi_fwtest_set_param_cmd_fixed_param *cmd; 9814 wmi_buf_t wmi_buf; 9815 uint16_t len; 9816 9817 len = sizeof(*cmd); 9818 9819 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9820 if (!wmi_buf) 9821 return QDF_STATUS_E_NOMEM; 9822 9823 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9824 WMITLV_SET_HDR(&cmd->tlv_header, 9825 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 9826 WMITLV_GET_STRUCT_TLVLEN( 9827 wmi_fwtest_set_param_cmd_fixed_param)); 9828 cmd->param_id = wmi_fwtest->arg; 9829 cmd->param_value = wmi_fwtest->value; 9830 9831 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 9832 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9833 WMI_FWTEST_CMDID)) { 9834 wmi_err("Failed to send fw test command"); 9835 wmi_buf_free(wmi_buf); 9836 return QDF_STATUS_E_FAILURE; 9837 } 9838 9839 return QDF_STATUS_SUCCESS; 9840 } 9841 9842 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 9843 { 9844 uint16_t len = 0; 9845 9846 if (config == WFA_CONFIG_RXNE) 9847 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 9848 else 9849 len += WMI_TLV_HDR_SIZE; 9850 9851 if (config == WFA_CONFIG_CSA) 9852 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 9853 else 9854 len += WMI_TLV_HDR_SIZE; 9855 9856 if (config == WFA_CONFIG_OCV) 9857 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 9858 else 9859 len += WMI_TLV_HDR_SIZE; 9860 9861 if (config == WFA_CONFIG_SA_QUERY) 9862 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 9863 else 9864 len += WMI_TLV_HDR_SIZE; 9865 9866 return len; 9867 } 9868 9869 /** 9870 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 9871 * @host_frmtype: Host defined OCV frame type 9872 * @ocv_frmtype: Pointer to hold WMI OCV frame type 9873 * 9874 * This function converts and fills host defined OCV frame type into WMI OCV 9875 * frame type. 9876 * 9877 * Return: CDF STATUS 9878 */ 9879 static QDF_STATUS 9880 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 9881 { 9882 switch (host_frmtype) { 9883 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 9884 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 9885 break; 9886 9887 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 9888 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 9889 break; 9890 9891 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 9892 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 9893 break; 9894 9895 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 9896 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 9897 break; 9898 9899 default: 9900 wmi_err("Invalid command type cmd %d", host_frmtype); 9901 return QDF_STATUS_E_FAILURE; 9902 } 9903 9904 return QDF_STATUS_SUCCESS; 9905 } 9906 9907 /** 9908 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 9909 * @wmi_handle: wmi handle 9910 * @wmi_wfatest: wfa test command 9911 * 9912 * This function sends wfa test command to fw. 9913 * 9914 * Return: CDF STATUS 9915 */ 9916 static 9917 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 9918 struct set_wfatest_params *wmi_wfatest) 9919 { 9920 wmi_wfa_config_cmd_fixed_param *cmd; 9921 wmi_wfa_config_rsnxe *rxne; 9922 wmi_wfa_config_csa *csa; 9923 wmi_wfa_config_ocv *ocv; 9924 wmi_wfa_config_saquery *saquery; 9925 wmi_buf_t wmi_buf; 9926 uint16_t len = sizeof(*cmd); 9927 uint8_t *buf_ptr; 9928 9929 len += wfa_config_param_len(wmi_wfatest->cmd); 9930 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9931 if (!wmi_buf) 9932 return QDF_STATUS_E_NOMEM; 9933 9934 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 9935 WMITLV_SET_HDR(&cmd->tlv_header, 9936 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 9937 WMITLV_GET_STRUCT_TLVLEN( 9938 wmi_wfa_config_cmd_fixed_param)); 9939 9940 cmd->vdev_id = wmi_wfatest->vdev_id; 9941 buf_ptr = (uint8_t *)(cmd + 1); 9942 9943 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 9944 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9945 sizeof(wmi_wfa_config_rsnxe)); 9946 buf_ptr += WMI_TLV_HDR_SIZE; 9947 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 9948 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 9949 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 9950 rxne->rsnxe_param = wmi_wfatest->value; 9951 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 9952 } else { 9953 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9954 buf_ptr += WMI_TLV_HDR_SIZE; 9955 } 9956 9957 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 9958 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9959 sizeof(wmi_wfa_config_csa)); 9960 buf_ptr += WMI_TLV_HDR_SIZE; 9961 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 9962 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 9963 csa = (wmi_wfa_config_csa *)buf_ptr; 9964 csa->ignore_csa = wmi_wfatest->value; 9965 buf_ptr += sizeof(wmi_wfa_config_csa); 9966 } else { 9967 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9968 buf_ptr += WMI_TLV_HDR_SIZE; 9969 } 9970 9971 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 9972 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9973 sizeof(wmi_wfa_config_ocv)); 9974 buf_ptr += WMI_TLV_HDR_SIZE; 9975 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 9976 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 9977 ocv = (wmi_wfa_config_ocv *)buf_ptr; 9978 9979 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 9980 &ocv->frame_types)) 9981 goto error; 9982 9983 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 9984 buf_ptr += sizeof(wmi_wfa_config_ocv); 9985 } else { 9986 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9987 buf_ptr += WMI_TLV_HDR_SIZE; 9988 } 9989 9990 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 9991 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9992 sizeof(wmi_wfa_config_saquery)); 9993 buf_ptr += WMI_TLV_HDR_SIZE; 9994 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 9995 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 9996 9997 saquery = (wmi_wfa_config_saquery *)buf_ptr; 9998 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 9999 } else { 10000 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10001 buf_ptr += WMI_TLV_HDR_SIZE; 10002 } 10003 10004 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 10005 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10006 WMI_WFA_CONFIG_CMDID)) { 10007 wmi_err("Failed to send wfa test command"); 10008 goto error; 10009 } 10010 10011 return QDF_STATUS_SUCCESS; 10012 10013 error: 10014 wmi_buf_free(wmi_buf); 10015 return QDF_STATUS_E_FAILURE; 10016 } 10017 10018 /** 10019 * send_unit_test_cmd_tlv() - send unit test command to fw. 10020 * @wmi_handle: wmi handle 10021 * @wmi_utest: unit test command 10022 * 10023 * This function send unit test command to fw. 10024 * 10025 * Return: CDF STATUS 10026 */ 10027 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 10028 struct wmi_unit_test_cmd *wmi_utest) 10029 { 10030 wmi_unit_test_cmd_fixed_param *cmd; 10031 wmi_buf_t wmi_buf; 10032 uint8_t *buf_ptr; 10033 int i; 10034 uint16_t len, args_tlv_len; 10035 uint32_t *unit_test_cmd_args; 10036 10037 args_tlv_len = 10038 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 10039 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 10040 10041 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10042 if (!wmi_buf) 10043 return QDF_STATUS_E_NOMEM; 10044 10045 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10046 buf_ptr = (uint8_t *) cmd; 10047 WMITLV_SET_HDR(&cmd->tlv_header, 10048 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 10049 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 10050 cmd->vdev_id = wmi_utest->vdev_id; 10051 cmd->module_id = wmi_utest->module_id; 10052 cmd->num_args = wmi_utest->num_args; 10053 cmd->diag_token = wmi_utest->diag_token; 10054 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 10055 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10056 (wmi_utest->num_args * sizeof(uint32_t))); 10057 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10058 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 10059 cmd->vdev_id, cmd->module_id, cmd->diag_token); 10060 wmi_debug("%d num of args = ", wmi_utest->num_args); 10061 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 10062 unit_test_cmd_args[i] = wmi_utest->args[i]; 10063 wmi_debug("%d,", wmi_utest->args[i]); 10064 } 10065 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 10066 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10067 WMI_UNIT_TEST_CMDID)) { 10068 wmi_err("Failed to send unit test command"); 10069 wmi_buf_free(wmi_buf); 10070 return QDF_STATUS_E_FAILURE; 10071 } 10072 10073 return QDF_STATUS_SUCCESS; 10074 } 10075 10076 /** 10077 * send_power_dbg_cmd_tlv() - send power debug commands 10078 * @wmi_handle: wmi handle 10079 * @param: wmi power debug parameter 10080 * 10081 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 10082 * 10083 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10084 */ 10085 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 10086 struct wmi_power_dbg_params *param) 10087 { 10088 wmi_buf_t buf = NULL; 10089 QDF_STATUS status; 10090 int len, args_tlv_len; 10091 uint8_t *buf_ptr; 10092 uint8_t i; 10093 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 10094 uint32_t *cmd_args; 10095 10096 /* Prepare and send power debug cmd parameters */ 10097 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 10098 len = sizeof(*cmd) + args_tlv_len; 10099 buf = wmi_buf_alloc(wmi_handle, len); 10100 if (!buf) 10101 return QDF_STATUS_E_NOMEM; 10102 10103 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10104 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 10105 WMITLV_SET_HDR(&cmd->tlv_header, 10106 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 10107 WMITLV_GET_STRUCT_TLVLEN 10108 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 10109 10110 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10111 wmi_handle, 10112 param->pdev_id); 10113 cmd->module_id = param->module_id; 10114 cmd->num_args = param->num_args; 10115 buf_ptr += sizeof(*cmd); 10116 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10117 (param->num_args * sizeof(uint32_t))); 10118 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10119 wmi_debug("%d num of args = ", param->num_args); 10120 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 10121 cmd_args[i] = param->args[i]; 10122 wmi_debug("%d,", param->args[i]); 10123 } 10124 10125 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 10126 status = wmi_unified_cmd_send(wmi_handle, buf, 10127 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 10128 if (QDF_IS_STATUS_ERROR(status)) { 10129 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 10130 status); 10131 goto error; 10132 } 10133 10134 return QDF_STATUS_SUCCESS; 10135 error: 10136 wmi_buf_free(buf); 10137 10138 return status; 10139 } 10140 10141 /** 10142 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 10143 * @wmi_handle: wmi handle 10144 * @pdev_id: pdev id 10145 * 10146 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 10147 * 10148 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10149 */ 10150 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 10151 uint32_t pdev_id) 10152 { 10153 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 10154 wmi_buf_t buf; 10155 uint16_t len; 10156 QDF_STATUS ret; 10157 10158 len = sizeof(*cmd); 10159 buf = wmi_buf_alloc(wmi_handle, len); 10160 10161 wmi_debug("pdev_id=%d", pdev_id); 10162 10163 if (!buf) 10164 return QDF_STATUS_E_NOMEM; 10165 10166 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 10167 wmi_buf_data(buf); 10168 10169 WMITLV_SET_HDR(&cmd->tlv_header, 10170 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 10171 WMITLV_GET_STRUCT_TLVLEN( 10172 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 10173 10174 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10175 wmi_handle, 10176 pdev_id); 10177 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 10178 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10179 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 10180 if (QDF_IS_STATUS_ERROR(ret)) { 10181 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 10182 ret, pdev_id); 10183 wmi_buf_free(buf); 10184 return QDF_STATUS_E_FAILURE; 10185 } 10186 10187 return QDF_STATUS_SUCCESS; 10188 } 10189 10190 /** 10191 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 10192 * @wmi_handle: wmi handle 10193 * @pdev_id: pdev id 10194 * 10195 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 10196 * 10197 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10198 */ 10199 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 10200 uint32_t pdev_id) 10201 { 10202 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 10203 wmi_buf_t buf; 10204 uint16_t len; 10205 QDF_STATUS ret; 10206 10207 len = sizeof(*cmd); 10208 buf = wmi_buf_alloc(wmi_handle, len); 10209 10210 wmi_debug("pdev_id=%d", pdev_id); 10211 10212 if (!buf) 10213 return QDF_STATUS_E_NOMEM; 10214 10215 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 10216 wmi_buf_data(buf); 10217 10218 WMITLV_SET_HDR(&cmd->tlv_header, 10219 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 10220 WMITLV_GET_STRUCT_TLVLEN( 10221 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 10222 10223 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10224 wmi_handle, 10225 pdev_id); 10226 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 10227 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10228 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 10229 if (QDF_IS_STATUS_ERROR(ret)) { 10230 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 10231 ret, pdev_id); 10232 wmi_buf_free(buf); 10233 return QDF_STATUS_E_FAILURE; 10234 } 10235 10236 return QDF_STATUS_SUCCESS; 10237 } 10238 10239 #ifdef QCA_SUPPORT_AGILE_DFS 10240 static 10241 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 10242 struct vdev_adfs_ch_cfg_params *param) 10243 { 10244 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 10245 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 10246 wmi_buf_t buf; 10247 QDF_STATUS ret; 10248 uint16_t len; 10249 10250 len = sizeof(*cmd); 10251 buf = wmi_buf_alloc(wmi_handle, len); 10252 10253 if (!buf) { 10254 wmi_err("wmi_buf_alloc failed"); 10255 return QDF_STATUS_E_NOMEM; 10256 } 10257 10258 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 10259 wmi_buf_data(buf); 10260 10261 WMITLV_SET_HDR(&cmd->tlv_header, 10262 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 10263 WMITLV_GET_STRUCT_TLVLEN 10264 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 10265 10266 cmd->vdev_id = param->vdev_id; 10267 cmd->ocac_mode = param->ocac_mode; 10268 cmd->center_freq1 = param->center_freq1; 10269 cmd->center_freq2 = param->center_freq2; 10270 cmd->chan_freq = param->chan_freq; 10271 cmd->chan_width = param->chan_width; 10272 cmd->min_duration_ms = param->min_duration_ms; 10273 cmd->max_duration_ms = param->max_duration_ms; 10274 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 10275 cmd->vdev_id, cmd->ocac_mode, 10276 cmd->center_freq); 10277 10278 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 10279 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10280 WMI_VDEV_ADFS_CH_CFG_CMDID); 10281 10282 if (QDF_IS_STATUS_ERROR(ret)) { 10283 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10284 wmi_buf_free(buf); 10285 return QDF_STATUS_E_FAILURE; 10286 } 10287 10288 return QDF_STATUS_SUCCESS; 10289 } 10290 10291 static 10292 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 10293 struct vdev_adfs_abort_params *param) 10294 { 10295 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 10296 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 10297 wmi_buf_t buf; 10298 QDF_STATUS ret; 10299 uint16_t len; 10300 10301 len = sizeof(*cmd); 10302 buf = wmi_buf_alloc(wmi_handle, len); 10303 10304 if (!buf) { 10305 wmi_err("wmi_buf_alloc failed"); 10306 return QDF_STATUS_E_NOMEM; 10307 } 10308 10309 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 10310 wmi_buf_data(buf); 10311 10312 WMITLV_SET_HDR 10313 (&cmd->tlv_header, 10314 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 10315 WMITLV_GET_STRUCT_TLVLEN 10316 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 10317 10318 cmd->vdev_id = param->vdev_id; 10319 10320 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 10321 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10322 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 10323 10324 if (QDF_IS_STATUS_ERROR(ret)) { 10325 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10326 wmi_buf_free(buf); 10327 return QDF_STATUS_E_FAILURE; 10328 } 10329 10330 return QDF_STATUS_SUCCESS; 10331 } 10332 #endif 10333 10334 /** 10335 * init_cmd_send_tlv() - send initialization cmd to fw 10336 * @wmi_handle: wmi handle 10337 * @param param: pointer to wmi init param 10338 * 10339 * Return: QDF_STATUS_SUCCESS for success or error code 10340 */ 10341 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 10342 struct wmi_init_cmd_param *param) 10343 { 10344 wmi_buf_t buf; 10345 wmi_init_cmd_fixed_param *cmd; 10346 uint8_t *buf_ptr; 10347 wmi_resource_config *resource_cfg; 10348 wlan_host_memory_chunk *host_mem_chunks; 10349 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 10350 uint16_t idx; 10351 int len; 10352 QDF_STATUS ret; 10353 10354 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 10355 WMI_TLV_HDR_SIZE; 10356 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 10357 10358 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 10359 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10360 WMI_TLV_HDR_SIZE + 10361 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 10362 10363 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 10364 if (!buf) 10365 return QDF_STATUS_E_FAILURE; 10366 10367 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10368 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 10369 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 10370 10371 host_mem_chunks = (wlan_host_memory_chunk *) 10372 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 10373 + WMI_TLV_HDR_SIZE); 10374 10375 WMITLV_SET_HDR(&cmd->tlv_header, 10376 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 10377 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 10378 wmi_copy_resource_config(resource_cfg, param->res_cfg); 10379 WMITLV_SET_HDR(&resource_cfg->tlv_header, 10380 WMITLV_TAG_STRUC_wmi_resource_config, 10381 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 10382 10383 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 10384 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 10385 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 10386 WMITLV_GET_STRUCT_TLVLEN 10387 (wlan_host_memory_chunk)); 10388 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 10389 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 10390 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 10391 if (is_service_enabled_tlv(wmi_handle, 10392 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 10393 host_mem_chunks[idx].ptr_high = 10394 qdf_get_upper_32_bits( 10395 param->mem_chunks[idx].paddr); 10396 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 10397 "chunk %d len %d requested ,ptr 0x%x ", 10398 idx, host_mem_chunks[idx].size, 10399 host_mem_chunks[idx].ptr); 10400 } 10401 cmd->num_host_mem_chunks = param->num_mem_chunks; 10402 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 10403 10404 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 10405 WMITLV_TAG_ARRAY_STRUC, 10406 (sizeof(wlan_host_memory_chunk) * 10407 param->num_mem_chunks)); 10408 10409 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", 10410 resource_cfg->num_peers, resource_cfg->num_offload_peers, 10411 resource_cfg->num_vdevs, resource_cfg->num_tids, 10412 resource_cfg->num_tdls_conn_table_entries, 10413 resource_cfg->num_tdls_vdevs); 10414 10415 /* Fill hw mode id config */ 10416 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 10417 10418 /* Fill fw_abi_vers */ 10419 copy_fw_abi_version_tlv(wmi_handle, cmd); 10420 10421 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 10422 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 10423 if (QDF_IS_STATUS_ERROR(ret)) { 10424 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 10425 ret); 10426 wmi_buf_free(buf); 10427 } 10428 10429 return ret; 10430 10431 } 10432 10433 /** 10434 * send_addba_send_cmd_tlv() - send addba send command to fw 10435 * @wmi_handle: wmi handle 10436 * @param: pointer to delba send params 10437 * @macaddr: peer mac address 10438 * 10439 * Send WMI_ADDBA_SEND_CMDID command to firmware 10440 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 10441 */ 10442 static QDF_STATUS 10443 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 10444 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10445 struct addba_send_params *param) 10446 { 10447 wmi_addba_send_cmd_fixed_param *cmd; 10448 wmi_buf_t buf; 10449 uint16_t len; 10450 QDF_STATUS ret; 10451 10452 len = sizeof(*cmd); 10453 10454 buf = wmi_buf_alloc(wmi_handle, len); 10455 if (!buf) 10456 return QDF_STATUS_E_NOMEM; 10457 10458 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 10459 10460 WMITLV_SET_HDR(&cmd->tlv_header, 10461 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 10462 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 10463 10464 cmd->vdev_id = param->vdev_id; 10465 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10466 cmd->tid = param->tidno; 10467 cmd->buffersize = param->buffersize; 10468 10469 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 10470 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 10471 if (QDF_IS_STATUS_ERROR(ret)) { 10472 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10473 wmi_buf_free(buf); 10474 return QDF_STATUS_E_FAILURE; 10475 } 10476 10477 return QDF_STATUS_SUCCESS; 10478 } 10479 10480 /** 10481 * send_delba_send_cmd_tlv() - send delba send command to fw 10482 * @wmi_handle: wmi handle 10483 * @param: pointer to delba send params 10484 * @macaddr: peer mac address 10485 * 10486 * Send WMI_DELBA_SEND_CMDID command to firmware 10487 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 10488 */ 10489 static QDF_STATUS 10490 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 10491 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10492 struct delba_send_params *param) 10493 { 10494 wmi_delba_send_cmd_fixed_param *cmd; 10495 wmi_buf_t buf; 10496 uint16_t len; 10497 QDF_STATUS ret; 10498 10499 len = sizeof(*cmd); 10500 10501 buf = wmi_buf_alloc(wmi_handle, len); 10502 if (!buf) 10503 return QDF_STATUS_E_NOMEM; 10504 10505 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 10506 10507 WMITLV_SET_HDR(&cmd->tlv_header, 10508 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 10509 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 10510 10511 cmd->vdev_id = param->vdev_id; 10512 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10513 cmd->tid = param->tidno; 10514 cmd->initiator = param->initiator; 10515 cmd->reasoncode = param->reasoncode; 10516 10517 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 10518 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 10519 if (QDF_IS_STATUS_ERROR(ret)) { 10520 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10521 wmi_buf_free(buf); 10522 return QDF_STATUS_E_FAILURE; 10523 } 10524 10525 return QDF_STATUS_SUCCESS; 10526 } 10527 10528 /** 10529 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 10530 * to fw 10531 * @wmi_handle: wmi handle 10532 * @param: pointer to addba clearresp params 10533 * @macaddr: peer mac address 10534 * Return: 0 for success or error code 10535 */ 10536 static QDF_STATUS 10537 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 10538 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10539 struct addba_clearresponse_params *param) 10540 { 10541 wmi_addba_clear_resp_cmd_fixed_param *cmd; 10542 wmi_buf_t buf; 10543 uint16_t len; 10544 QDF_STATUS ret; 10545 10546 len = sizeof(*cmd); 10547 10548 buf = wmi_buf_alloc(wmi_handle, len); 10549 if (!buf) 10550 return QDF_STATUS_E_FAILURE; 10551 10552 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 10553 10554 WMITLV_SET_HDR(&cmd->tlv_header, 10555 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 10556 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 10557 10558 cmd->vdev_id = param->vdev_id; 10559 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10560 10561 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 10562 ret = wmi_unified_cmd_send(wmi_handle, 10563 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 10564 if (QDF_IS_STATUS_ERROR(ret)) { 10565 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10566 wmi_buf_free(buf); 10567 return QDF_STATUS_E_FAILURE; 10568 } 10569 10570 return QDF_STATUS_SUCCESS; 10571 } 10572 10573 #ifdef OBSS_PD 10574 /** 10575 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 10576 * def thresh to fw 10577 * @wmi_handle: wmi handle 10578 * @thresh: pointer to obss_spatial_reuse_def_thresh 10579 * 10580 * Return: QDF_STATUS_SUCCESS for success or error code 10581 */ 10582 static 10583 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 10584 wmi_unified_t wmi_handle, 10585 struct wmi_host_obss_spatial_reuse_set_def_thresh 10586 *thresh) 10587 { 10588 wmi_buf_t buf; 10589 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 10590 QDF_STATUS ret; 10591 uint32_t cmd_len; 10592 uint32_t tlv_len; 10593 10594 cmd_len = sizeof(*cmd); 10595 10596 buf = wmi_buf_alloc(wmi_handle, cmd_len); 10597 if (!buf) 10598 return QDF_STATUS_E_NOMEM; 10599 10600 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 10601 wmi_buf_data(buf); 10602 10603 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 10604 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 10605 10606 WMITLV_SET_HDR(&cmd->tlv_header, 10607 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 10608 tlv_len); 10609 10610 cmd->obss_min = thresh->obss_min; 10611 cmd->obss_max = thresh->obss_max; 10612 cmd->vdev_type = thresh->vdev_type; 10613 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 10614 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 10615 if (QDF_IS_STATUS_ERROR(ret)) 10616 wmi_buf_free(buf); 10617 10618 return ret; 10619 } 10620 10621 /** 10622 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 10623 * @wmi_handle: wmi handle 10624 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 10625 * 10626 * Return: QDF_STATUS_SUCCESS for success or error code 10627 */ 10628 static 10629 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 10630 struct wmi_host_obss_spatial_reuse_set_param 10631 *obss_spatial_reuse_param) 10632 { 10633 wmi_buf_t buf; 10634 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 10635 QDF_STATUS ret; 10636 uint32_t len; 10637 10638 len = sizeof(*cmd); 10639 10640 buf = wmi_buf_alloc(wmi_handle, len); 10641 if (!buf) 10642 return QDF_STATUS_E_FAILURE; 10643 10644 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 10645 WMITLV_SET_HDR(&cmd->tlv_header, 10646 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 10647 WMITLV_GET_STRUCT_TLVLEN 10648 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 10649 10650 cmd->enable = obss_spatial_reuse_param->enable; 10651 cmd->obss_min = obss_spatial_reuse_param->obss_min; 10652 cmd->obss_max = obss_spatial_reuse_param->obss_max; 10653 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 10654 10655 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10656 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 10657 10658 if (QDF_IS_STATUS_ERROR(ret)) { 10659 wmi_err( 10660 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 10661 ret); 10662 wmi_buf_free(buf); 10663 } 10664 10665 return ret; 10666 } 10667 10668 /** 10669 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 10670 * to be used by SRG based Spatial Reuse feature to the FW 10671 * @wmi_handle: wmi handle 10672 * @bitmap_0: lower 32 bits in BSS color bitmap 10673 * @bitmap_1: upper 32 bits in BSS color bitmap 10674 * @pdev_id: pdev ID 10675 * 10676 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10677 */ 10678 static QDF_STATUS 10679 send_self_srg_bss_color_bitmap_set_cmd_tlv( 10680 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10681 uint32_t bitmap_1, uint8_t pdev_id) 10682 { 10683 wmi_buf_t buf; 10684 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 10685 QDF_STATUS ret; 10686 uint32_t len; 10687 10688 len = sizeof(*cmd); 10689 10690 buf = wmi_buf_alloc(wmi_handle, len); 10691 if (!buf) 10692 return QDF_STATUS_E_FAILURE; 10693 10694 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 10695 wmi_buf_data(buf); 10696 10697 WMITLV_SET_HDR( 10698 &cmd->tlv_header, 10699 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 10700 WMITLV_GET_STRUCT_TLVLEN 10701 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 10702 10703 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10704 wmi_handle, pdev_id); 10705 cmd->srg_bss_color_bitmap[0] = bitmap_0; 10706 cmd->srg_bss_color_bitmap[1] = bitmap_1; 10707 10708 ret = wmi_unified_cmd_send( 10709 wmi_handle, buf, len, 10710 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 10711 10712 if (QDF_IS_STATUS_ERROR(ret)) { 10713 wmi_err( 10714 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 10715 ret); 10716 wmi_buf_free(buf); 10717 } 10718 10719 return ret; 10720 } 10721 10722 /** 10723 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 10724 * bitmap to be used by SRG based Spatial Reuse feature to the FW 10725 * @wmi_handle: wmi handle 10726 * @bitmap_0: lower 32 bits in partial BSSID bitmap 10727 * @bitmap_1: upper 32 bits in partial BSSID bitmap 10728 * @pdev_id: pdev ID 10729 * 10730 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10731 */ 10732 static QDF_STATUS 10733 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 10734 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10735 uint32_t bitmap_1, uint8_t pdev_id) 10736 { 10737 wmi_buf_t buf; 10738 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 10739 QDF_STATUS ret; 10740 uint32_t len; 10741 10742 len = sizeof(*cmd); 10743 10744 buf = wmi_buf_alloc(wmi_handle, len); 10745 if (!buf) 10746 return QDF_STATUS_E_FAILURE; 10747 10748 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 10749 wmi_buf_data(buf); 10750 10751 WMITLV_SET_HDR( 10752 &cmd->tlv_header, 10753 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 10754 WMITLV_GET_STRUCT_TLVLEN 10755 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 10756 10757 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10758 wmi_handle, pdev_id); 10759 10760 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 10761 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 10762 10763 ret = wmi_unified_cmd_send( 10764 wmi_handle, buf, len, 10765 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 10766 10767 if (QDF_IS_STATUS_ERROR(ret)) { 10768 wmi_err( 10769 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 10770 ret); 10771 wmi_buf_free(buf); 10772 } 10773 10774 return ret; 10775 } 10776 10777 /** 10778 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10779 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10780 * @wmi_handle: wmi handle 10781 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10782 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10783 * @pdev_id: pdev ID 10784 * 10785 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10786 */ 10787 static QDF_STATUS 10788 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 10789 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10790 uint32_t bitmap_1, uint8_t pdev_id) 10791 { 10792 wmi_buf_t buf; 10793 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10794 QDF_STATUS ret; 10795 uint32_t len; 10796 10797 len = sizeof(*cmd); 10798 10799 buf = wmi_buf_alloc(wmi_handle, len); 10800 if (!buf) 10801 return QDF_STATUS_E_FAILURE; 10802 10803 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10804 wmi_buf_data(buf); 10805 10806 WMITLV_SET_HDR( 10807 &cmd->tlv_header, 10808 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 10809 WMITLV_GET_STRUCT_TLVLEN 10810 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10811 10812 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10813 wmi_handle, pdev_id); 10814 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 10815 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 10816 10817 ret = wmi_unified_cmd_send( 10818 wmi_handle, buf, len, 10819 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10820 10821 if (QDF_IS_STATUS_ERROR(ret)) { 10822 wmi_err( 10823 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10824 ret); 10825 wmi_buf_free(buf); 10826 } 10827 10828 return ret; 10829 } 10830 10831 /** 10832 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10833 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10834 * @wmi_handle: wmi handle 10835 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10836 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10837 * @pdev_id: pdev ID 10838 * 10839 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10840 */ 10841 static QDF_STATUS 10842 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 10843 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10844 uint32_t bitmap_1, uint8_t pdev_id) 10845 { 10846 wmi_buf_t buf; 10847 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10848 QDF_STATUS ret; 10849 uint32_t len; 10850 10851 len = sizeof(*cmd); 10852 10853 buf = wmi_buf_alloc(wmi_handle, len); 10854 if (!buf) 10855 return QDF_STATUS_E_FAILURE; 10856 10857 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10858 wmi_buf_data(buf); 10859 10860 WMITLV_SET_HDR( 10861 &cmd->tlv_header, 10862 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10863 WMITLV_GET_STRUCT_TLVLEN 10864 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10865 10866 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10867 wmi_handle, pdev_id); 10868 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 10869 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 10870 10871 ret = wmi_unified_cmd_send( 10872 wmi_handle, buf, len, 10873 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10874 10875 if (QDF_IS_STATUS_ERROR(ret)) { 10876 wmi_err( 10877 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10878 ret); 10879 wmi_buf_free(buf); 10880 } 10881 10882 return ret; 10883 } 10884 10885 /** 10886 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10887 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10888 * @wmi_handle: wmi handle 10889 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10890 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10891 * @pdev_id: pdev ID 10892 * 10893 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10894 */ 10895 static QDF_STATUS 10896 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 10897 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10898 uint32_t bitmap_1, uint8_t pdev_id) 10899 { 10900 wmi_buf_t buf; 10901 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10902 QDF_STATUS ret; 10903 uint32_t len; 10904 10905 len = sizeof(*cmd); 10906 10907 buf = wmi_buf_alloc(wmi_handle, len); 10908 if (!buf) 10909 return QDF_STATUS_E_FAILURE; 10910 10911 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10912 wmi_buf_data(buf); 10913 10914 WMITLV_SET_HDR( 10915 &cmd->tlv_header, 10916 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 10917 WMITLV_GET_STRUCT_TLVLEN 10918 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10919 10920 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10921 wmi_handle, pdev_id); 10922 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 10923 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 10924 10925 ret = wmi_unified_cmd_send( 10926 wmi_handle, buf, len, 10927 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10928 10929 if (QDF_IS_STATUS_ERROR(ret)) { 10930 wmi_err( 10931 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10932 ret); 10933 wmi_buf_free(buf); 10934 } 10935 10936 return ret; 10937 } 10938 10939 /** 10940 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10941 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10942 * @wmi_handle: wmi handle 10943 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10944 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10945 * @pdev_id: pdev ID 10946 * 10947 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10948 */ 10949 static QDF_STATUS 10950 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 10951 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10952 uint32_t bitmap_1, uint8_t pdev_id) 10953 { 10954 wmi_buf_t buf; 10955 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10956 QDF_STATUS ret; 10957 uint32_t len; 10958 10959 len = sizeof(*cmd); 10960 10961 buf = wmi_buf_alloc(wmi_handle, len); 10962 if (!buf) 10963 return QDF_STATUS_E_FAILURE; 10964 10965 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10966 wmi_buf_data(buf); 10967 10968 WMITLV_SET_HDR( 10969 &cmd->tlv_header, 10970 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10971 WMITLV_GET_STRUCT_TLVLEN 10972 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10973 10974 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10975 wmi_handle, pdev_id); 10976 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 10977 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 10978 10979 ret = wmi_unified_cmd_send( 10980 wmi_handle, buf, len, 10981 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10982 10983 if (QDF_IS_STATUS_ERROR(ret)) { 10984 wmi_err( 10985 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10986 ret); 10987 wmi_buf_free(buf); 10988 } 10989 10990 return ret; 10991 } 10992 #endif 10993 10994 static 10995 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 10996 struct wmi_host_injector_frame_params *inject_config_params) 10997 { 10998 wmi_buf_t buf; 10999 wmi_frame_inject_cmd_fixed_param *cmd; 11000 QDF_STATUS ret; 11001 uint32_t len; 11002 11003 len = sizeof(*cmd); 11004 11005 buf = wmi_buf_alloc(wmi_handle, len); 11006 if (!buf) 11007 return QDF_STATUS_E_NOMEM; 11008 11009 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 11010 WMITLV_SET_HDR(&cmd->tlv_header, 11011 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 11012 WMITLV_GET_STRUCT_TLVLEN 11013 (wmi_frame_inject_cmd_fixed_param)); 11014 11015 cmd->vdev_id = inject_config_params->vdev_id; 11016 cmd->enable = inject_config_params->enable; 11017 cmd->frame_type = inject_config_params->frame_type; 11018 cmd->frame_inject_period = inject_config_params->frame_inject_period; 11019 cmd->fc_duration = inject_config_params->frame_duration; 11020 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 11021 &cmd->frame_addr1); 11022 11023 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11024 WMI_PDEV_FRAME_INJECT_CMDID); 11025 11026 if (QDF_IS_STATUS_ERROR(ret)) { 11027 wmi_err( 11028 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 11029 ret); 11030 wmi_buf_free(buf); 11031 } 11032 11033 return ret; 11034 } 11035 #ifdef QCA_SUPPORT_CP_STATS 11036 /** 11037 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 11038 * @wmi_handle: wma handle 11039 * @evt_buf: event buffer 11040 * @out_buff: buffer to populated after stats extraction 11041 * 11042 * Return: status of operation 11043 */ 11044 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 11045 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 11046 { 11047 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11048 wmi_congestion_stats *congestion_stats; 11049 11050 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11051 congestion_stats = param_buf->congestion_stats; 11052 if (!congestion_stats) 11053 return QDF_STATUS_E_INVAL; 11054 11055 out_buff->vdev_id = congestion_stats->vdev_id; 11056 out_buff->congestion = congestion_stats->congestion; 11057 11058 wmi_debug("cca stats event processed"); 11059 return QDF_STATUS_SUCCESS; 11060 } 11061 #endif /* QCA_SUPPORT_CP_STATS */ 11062 11063 /** 11064 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 11065 * event 11066 * @wmi_handle: wmi handle 11067 * @param evt_buf: pointer to event buffer 11068 * @param param: Pointer to hold peer ctl data 11069 * 11070 * Return: QDF_STATUS_SUCCESS for success or error code 11071 */ 11072 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 11073 wmi_unified_t wmi_handle, 11074 void *evt_buf, 11075 struct wmi_host_pdev_ctl_failsafe_event *param) 11076 { 11077 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 11078 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 11079 11080 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 11081 if (!param_buf) { 11082 wmi_err("Invalid ctl_failsafe event buffer"); 11083 return QDF_STATUS_E_INVAL; 11084 } 11085 11086 fix_param = param_buf->fixed_param; 11087 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 11088 11089 return QDF_STATUS_SUCCESS; 11090 } 11091 11092 /** 11093 * save_service_bitmap_tlv() - save service bitmap 11094 * @wmi_handle: wmi handle 11095 * @param evt_buf: pointer to event buffer 11096 * @param bitmap_buf: bitmap buffer, for converged legacy support 11097 * 11098 * Return: QDF_STATUS 11099 */ 11100 static 11101 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11102 void *bitmap_buf) 11103 { 11104 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11105 struct wmi_soc *soc = wmi_handle->soc; 11106 11107 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11108 11109 /* If it is already allocated, use that buffer. This can happen 11110 * during target stop/start scenarios where host allocation is skipped. 11111 */ 11112 if (!soc->wmi_service_bitmap) { 11113 soc->wmi_service_bitmap = 11114 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 11115 if (!soc->wmi_service_bitmap) 11116 return QDF_STATUS_E_NOMEM; 11117 } 11118 11119 qdf_mem_copy(soc->wmi_service_bitmap, 11120 param_buf->wmi_service_bitmap, 11121 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11122 11123 if (bitmap_buf) 11124 qdf_mem_copy(bitmap_buf, 11125 param_buf->wmi_service_bitmap, 11126 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11127 11128 return QDF_STATUS_SUCCESS; 11129 } 11130 11131 /** 11132 * save_ext_service_bitmap_tlv() - save extendend service bitmap 11133 * @wmi_handle: wmi handle 11134 * @param evt_buf: pointer to event buffer 11135 * @param bitmap_buf: bitmap buffer, for converged legacy support 11136 * 11137 * Return: QDF_STATUS 11138 */ 11139 static 11140 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11141 void *bitmap_buf) 11142 { 11143 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 11144 wmi_service_available_event_fixed_param *ev; 11145 struct wmi_soc *soc = wmi_handle->soc; 11146 uint32_t i = 0; 11147 11148 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 11149 11150 ev = param_buf->fixed_param; 11151 11152 /* If it is already allocated, use that buffer. This can happen 11153 * during target stop/start scenarios where host allocation is skipped. 11154 */ 11155 if (!soc->wmi_ext_service_bitmap) { 11156 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 11157 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 11158 if (!soc->wmi_ext_service_bitmap) 11159 return QDF_STATUS_E_NOMEM; 11160 } 11161 11162 qdf_mem_copy(soc->wmi_ext_service_bitmap, 11163 ev->wmi_service_segment_bitmap, 11164 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 11165 11166 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 11167 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 11168 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 11169 11170 if (bitmap_buf) 11171 qdf_mem_copy(bitmap_buf, 11172 soc->wmi_ext_service_bitmap, 11173 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 11174 11175 if (!param_buf->wmi_service_ext_bitmap) { 11176 wmi_debug("wmi_service_ext_bitmap not available"); 11177 return QDF_STATUS_SUCCESS; 11178 } 11179 11180 if (!soc->wmi_ext2_service_bitmap) { 11181 soc->wmi_ext2_service_bitmap = 11182 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 11183 sizeof(uint32_t)); 11184 if (!soc->wmi_ext2_service_bitmap) 11185 return QDF_STATUS_E_NOMEM; 11186 } 11187 11188 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 11189 param_buf->wmi_service_ext_bitmap, 11190 (param_buf->num_wmi_service_ext_bitmap * 11191 sizeof(uint32_t))); 11192 11193 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 11194 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 11195 i, soc->wmi_ext2_service_bitmap[i]); 11196 } 11197 11198 return QDF_STATUS_SUCCESS; 11199 } 11200 11201 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 11202 struct wlan_psoc_target_capability_info *cap) 11203 { 11204 /* except LDPC all flags are common betwen legacy and here 11205 * also IBFEER is not defined for TLV 11206 */ 11207 cap->ht_cap_info |= ev_target_cap & ( 11208 WMI_HT_CAP_ENABLED 11209 | WMI_HT_CAP_HT20_SGI 11210 | WMI_HT_CAP_DYNAMIC_SMPS 11211 | WMI_HT_CAP_TX_STBC 11212 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 11213 | WMI_HT_CAP_RX_STBC 11214 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 11215 | WMI_HT_CAP_LDPC 11216 | WMI_HT_CAP_L_SIG_TXOP_PROT 11217 | WMI_HT_CAP_MPDU_DENSITY 11218 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 11219 | WMI_HT_CAP_HT40_SGI); 11220 if (ev_target_cap & WMI_HT_CAP_LDPC) 11221 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 11222 WMI_HOST_HT_CAP_TX_LDPC; 11223 } 11224 /** 11225 * extract_service_ready_tlv() - extract service ready event 11226 * @wmi_handle: wmi handle 11227 * @param evt_buf: pointer to received event buffer 11228 * @param cap: pointer to hold target capability information extracted from even 11229 * 11230 * Return: QDF_STATUS_SUCCESS for success or error code 11231 */ 11232 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 11233 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 11234 { 11235 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11236 wmi_service_ready_event_fixed_param *ev; 11237 11238 11239 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11240 11241 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11242 if (!ev) { 11243 qdf_print("%s: wmi_buf_alloc failed", __func__); 11244 return QDF_STATUS_E_FAILURE; 11245 } 11246 11247 cap->phy_capability = ev->phy_capability; 11248 cap->max_frag_entry = ev->max_frag_entry; 11249 cap->num_rf_chains = ev->num_rf_chains; 11250 copy_ht_cap_info(ev->ht_cap_info, cap); 11251 cap->vht_cap_info = ev->vht_cap_info; 11252 cap->vht_supp_mcs = ev->vht_supp_mcs; 11253 cap->hw_min_tx_power = ev->hw_min_tx_power; 11254 cap->hw_max_tx_power = ev->hw_max_tx_power; 11255 cap->sys_cap_info = ev->sys_cap_info; 11256 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 11257 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 11258 cap->max_num_scan_channels = ev->max_num_scan_channels; 11259 cap->max_supported_macs = ev->max_supported_macs; 11260 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 11261 cap->txrx_chainmask = ev->txrx_chainmask; 11262 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 11263 cap->num_msdu_desc = ev->num_msdu_desc; 11264 cap->fw_version = ev->fw_build_vers; 11265 /* fw_version_1 is not available in TLV. */ 11266 cap->fw_version_1 = 0; 11267 11268 return QDF_STATUS_SUCCESS; 11269 } 11270 11271 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 11272 * to host internal HOST_REGDMN_MODE values. 11273 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 11274 * host currently. Add this in the future if required. 11275 * 11AX (Phase II) : 11ax related values are not currently 11276 * advertised separately by FW. As part of phase II regulatory bring-up, 11277 * finalize the advertisement mechanism. 11278 * @target_wireless_mode: target wireless mode received in message 11279 * 11280 * Return: returns the host internal wireless mode. 11281 */ 11282 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 11283 { 11284 11285 uint32_t wireless_modes = 0; 11286 11287 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 11288 11289 if (target_wireless_mode & REGDMN_MODE_11A) 11290 wireless_modes |= HOST_REGDMN_MODE_11A; 11291 11292 if (target_wireless_mode & REGDMN_MODE_TURBO) 11293 wireless_modes |= HOST_REGDMN_MODE_TURBO; 11294 11295 if (target_wireless_mode & REGDMN_MODE_11B) 11296 wireless_modes |= HOST_REGDMN_MODE_11B; 11297 11298 if (target_wireless_mode & REGDMN_MODE_PUREG) 11299 wireless_modes |= HOST_REGDMN_MODE_PUREG; 11300 11301 if (target_wireless_mode & REGDMN_MODE_11G) 11302 wireless_modes |= HOST_REGDMN_MODE_11G; 11303 11304 if (target_wireless_mode & REGDMN_MODE_108G) 11305 wireless_modes |= HOST_REGDMN_MODE_108G; 11306 11307 if (target_wireless_mode & REGDMN_MODE_108A) 11308 wireless_modes |= HOST_REGDMN_MODE_108A; 11309 11310 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 11311 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 11312 11313 if (target_wireless_mode & REGDMN_MODE_XR) 11314 wireless_modes |= HOST_REGDMN_MODE_XR; 11315 11316 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 11317 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 11318 11319 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 11320 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 11321 11322 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 11323 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 11324 11325 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 11326 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 11327 11328 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 11329 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 11330 11331 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 11332 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 11333 11334 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 11335 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 11336 11337 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 11338 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 11339 11340 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 11341 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 11342 11343 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 11344 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 11345 11346 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 11347 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 11348 11349 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 11350 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 11351 11352 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 11353 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 11354 11355 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 11356 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 11357 11358 return wireless_modes; 11359 } 11360 11361 /** 11362 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 11363 * to regulatory flags. 11364 * @target_phybitmap: target phybitmap. 11365 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 11366 * phybitmap. 11367 * 11368 * Return: None 11369 */ 11370 11371 #ifdef WLAN_FEATURE_11BE 11372 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 11373 uint32_t *phybitmap) 11374 { 11375 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 11376 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 11377 } 11378 #else 11379 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 11380 uint32_t *phybitmap) 11381 { 11382 } 11383 #endif 11384 11385 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 11386 * target to host internal REGULATORY_PHYMODE values. 11387 * 11388 * @target_target_phybitmap: target phybitmap received in the message. 11389 * 11390 * Return: returns the host internal REGULATORY_PHYMODE. 11391 */ 11392 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 11393 { 11394 uint32_t phybitmap = 0; 11395 11396 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 11397 11398 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 11399 phybitmap |= REGULATORY_PHYMODE_NO11A; 11400 11401 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 11402 phybitmap |= REGULATORY_PHYMODE_NO11B; 11403 11404 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 11405 phybitmap |= REGULATORY_PHYMODE_NO11G; 11406 11407 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 11408 phybitmap |= REGULATORY_CHAN_NO11N; 11409 11410 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 11411 phybitmap |= REGULATORY_PHYMODE_NO11AC; 11412 11413 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 11414 phybitmap |= REGULATORY_PHYMODE_NO11AX; 11415 11416 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 11417 11418 return phybitmap; 11419 } 11420 11421 /** 11422 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 11423 * advertised by the target to wireless mode ext flags. 11424 * @target_wireless_modes_ext: Target wireless mode 11425 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 11426 * 11427 * Return: None 11428 */ 11429 #ifdef WLAN_FEATURE_11BE 11430 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 11431 uint64_t *wireless_modes_ext) 11432 { 11433 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 11434 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 11435 11436 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 11437 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 11438 11439 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 11440 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 11441 11442 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 11443 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 11444 11445 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 11446 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 11447 11448 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 11449 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 11450 11451 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 11452 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 11453 11454 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 11455 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 11456 11457 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 11458 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 11459 } 11460 #else 11461 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 11462 uint64_t *wireless_modes_ext) 11463 { 11464 } 11465 #endif 11466 11467 static inline uint64_t convert_wireless_modes_ext_tlv( 11468 uint32_t target_wireless_modes_ext) 11469 { 11470 uint64_t wireless_modes_ext = 0; 11471 11472 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 11473 11474 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 11475 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 11476 11477 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 11478 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 11479 11480 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 11481 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 11482 11483 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 11484 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 11485 11486 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 11487 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 11488 11489 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 11490 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 11491 11492 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 11493 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 11494 11495 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 11496 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 11497 11498 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 11499 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 11500 11501 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 11502 &wireless_modes_ext); 11503 11504 return wireless_modes_ext; 11505 } 11506 11507 /** 11508 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 11509 * @wmi_handle: wmi handle 11510 * @param evt_buf: Pointer to event buffer 11511 * @param cap: pointer to hold HAL reg capabilities 11512 * 11513 * Return: QDF_STATUS_SUCCESS for success or error code 11514 */ 11515 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 11516 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 11517 { 11518 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11519 11520 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11521 if (!param_buf || !param_buf->hal_reg_capabilities) { 11522 wmi_err("Invalid arguments"); 11523 return QDF_STATUS_E_FAILURE; 11524 } 11525 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 11526 sizeof(uint32_t)), 11527 sizeof(struct wlan_psoc_hal_reg_capability)); 11528 11529 cap->wireless_modes = convert_wireless_modes_tlv( 11530 param_buf->hal_reg_capabilities->wireless_modes); 11531 11532 return QDF_STATUS_SUCCESS; 11533 } 11534 11535 /** 11536 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 11537 * @wmi_handle: wmi handle 11538 * @param evt_buf: Pointer to event buffer 11539 * @param cap: pointer to hold HAL reg capabilities 11540 * 11541 * Return: QDF_STATUS_SUCCESS for success or error code 11542 */ 11543 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 11544 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 11545 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 11546 { 11547 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11548 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 11549 11550 if (!evt_buf) { 11551 wmi_err("null evt_buf"); 11552 return QDF_STATUS_E_INVAL; 11553 } 11554 11555 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 11556 11557 if (!param_buf->num_hal_reg_caps) 11558 return QDF_STATUS_SUCCESS; 11559 11560 if (phy_idx >= param_buf->num_hal_reg_caps) 11561 return QDF_STATUS_E_INVAL; 11562 11563 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 11564 11565 param->phy_id = reg_caps->phy_id; 11566 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 11567 reg_caps->wireless_modes_ext); 11568 11569 return QDF_STATUS_SUCCESS; 11570 } 11571 11572 /** 11573 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 11574 * @wmi_handle: wmi handle 11575 * @evt_buf: pointer to event buffer 11576 * 11577 * Return: Number of entries requested 11578 */ 11579 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 11580 void *evt_buf) 11581 { 11582 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11583 wmi_service_ready_event_fixed_param *ev; 11584 11585 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11586 11587 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11588 if (!ev) { 11589 qdf_print("%s: wmi_buf_alloc failed", __func__); 11590 return 0; 11591 } 11592 11593 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 11594 wmi_err("Invalid num_mem_reqs %d:%d", 11595 ev->num_mem_reqs, param_buf->num_mem_reqs); 11596 return 0; 11597 } 11598 11599 return ev->num_mem_reqs; 11600 } 11601 11602 /** 11603 * extract_host_mem_req_tlv() - Extract host memory required from 11604 * service ready event 11605 * @wmi_handle: wmi handle 11606 * @evt_buf: pointer to event buffer 11607 * @mem_reqs: pointer to host memory request structure 11608 * @num_active_peers: number of active peers for peer cache 11609 * @num_peers: number of peers 11610 * @fw_prio: FW priority 11611 * @idx: index for memory request 11612 * 11613 * Return: Host memory request parameters requested by target 11614 */ 11615 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 11616 void *evt_buf, 11617 host_mem_req *mem_reqs, 11618 uint32_t num_active_peers, 11619 uint32_t num_peers, 11620 enum wmi_fw_mem_prio fw_prio, 11621 uint16_t idx) 11622 { 11623 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11624 11625 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 11626 11627 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 11628 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 11629 mem_reqs->num_unit_info = 11630 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 11631 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 11632 mem_reqs->tgt_num_units = 0; 11633 11634 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 11635 (mem_reqs->num_unit_info & 11636 REQ_TO_HOST_FOR_CONT_MEMORY)) || 11637 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 11638 (!(mem_reqs->num_unit_info & 11639 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 11640 /* First allocate the memory that requires contiguous memory */ 11641 mem_reqs->tgt_num_units = mem_reqs->num_units; 11642 if (mem_reqs->num_unit_info) { 11643 if (mem_reqs->num_unit_info & 11644 NUM_UNITS_IS_NUM_PEERS) { 11645 /* 11646 * number of units allocated is equal to number 11647 * of peers, 1 extra for self peer on target. 11648 * this needs to be fixed, host and target can 11649 * get out of sync 11650 */ 11651 mem_reqs->tgt_num_units = num_peers + 1; 11652 } 11653 if (mem_reqs->num_unit_info & 11654 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 11655 /* 11656 * Requesting allocation of memory using 11657 * num_active_peers in qcache. if qcache is 11658 * disabled in host, then it should allocate 11659 * memory for num_peers instead of 11660 * num_active_peers. 11661 */ 11662 if (num_active_peers) 11663 mem_reqs->tgt_num_units = 11664 num_active_peers + 1; 11665 else 11666 mem_reqs->tgt_num_units = 11667 num_peers + 1; 11668 } 11669 } 11670 11671 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 11672 "unit size %d actual units %d", 11673 idx, mem_reqs->req_id, 11674 mem_reqs->num_units, 11675 mem_reqs->num_unit_info, 11676 mem_reqs->unit_size, 11677 mem_reqs->tgt_num_units); 11678 } 11679 11680 return QDF_STATUS_SUCCESS; 11681 } 11682 11683 /** 11684 * save_fw_version_in_service_ready_tlv() - Save fw version in service 11685 * ready function 11686 * @wmi_handle: wmi handle 11687 * @param evt_buf: pointer to event buffer 11688 * 11689 * Return: QDF_STATUS_SUCCESS for success or error code 11690 */ 11691 static QDF_STATUS 11692 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 11693 { 11694 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11695 wmi_service_ready_event_fixed_param *ev; 11696 11697 11698 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11699 11700 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11701 if (!ev) { 11702 qdf_print("%s: wmi_buf_alloc failed", __func__); 11703 return QDF_STATUS_E_FAILURE; 11704 } 11705 11706 /*Save fw version from service ready message */ 11707 /*This will be used while sending INIT message */ 11708 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 11709 sizeof(wmi_handle->fw_abi_version)); 11710 11711 return QDF_STATUS_SUCCESS; 11712 } 11713 11714 /** 11715 * ready_extract_init_status_tlv() - Extract init status from ready event 11716 * @wmi_handle: wmi handle 11717 * @param evt_buf: Pointer to event buffer 11718 * 11719 * Return: ready status 11720 */ 11721 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 11722 void *evt_buf) 11723 { 11724 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11725 wmi_ready_event_fixed_param *ev = NULL; 11726 11727 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11728 ev = param_buf->fixed_param; 11729 11730 qdf_print("%s:%d", __func__, ev->status); 11731 11732 return ev->status; 11733 } 11734 11735 /** 11736 * ready_extract_mac_addr_tlv() - extract mac address from ready event 11737 * @wmi_handle: wmi handle 11738 * @param evt_buf: pointer to event buffer 11739 * @param macaddr: Pointer to hold MAC address 11740 * 11741 * Return: QDF_STATUS_SUCCESS for success or error code 11742 */ 11743 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 11744 void *evt_buf, uint8_t *macaddr) 11745 { 11746 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11747 wmi_ready_event_fixed_param *ev = NULL; 11748 11749 11750 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11751 ev = param_buf->fixed_param; 11752 11753 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 11754 11755 return QDF_STATUS_SUCCESS; 11756 } 11757 11758 /** 11759 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 11760 * @wmi_handle: wmi handle 11761 * @param evt_buf: pointer to event buffer 11762 * @param macaddr: Pointer to hold number of MAC addresses 11763 * 11764 * Return: Pointer to addr list 11765 */ 11766 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 11767 void *evt_buf, uint8_t *num_mac) 11768 { 11769 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11770 wmi_ready_event_fixed_param *ev = NULL; 11771 11772 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11773 ev = param_buf->fixed_param; 11774 11775 *num_mac = ev->num_extra_mac_addr; 11776 11777 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 11778 } 11779 11780 /** 11781 * extract_ready_params_tlv() - Extract data from ready event apart from 11782 * status, macaddr and version. 11783 * @wmi_handle: Pointer to WMI handle. 11784 * @evt_buf: Pointer to Ready event buffer. 11785 * @ev_param: Pointer to host defined struct to copy the data from event. 11786 * 11787 * Return: QDF_STATUS_SUCCESS on success. 11788 */ 11789 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 11790 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 11791 { 11792 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11793 wmi_ready_event_fixed_param *ev = NULL; 11794 11795 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11796 ev = param_buf->fixed_param; 11797 11798 ev_param->status = ev->status; 11799 ev_param->num_dscp_table = ev->num_dscp_table; 11800 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 11801 ev_param->num_total_peer = ev->num_total_peers; 11802 ev_param->num_extra_peer = ev->num_extra_peers; 11803 /* Agile_capability in ready event is supported in TLV target, 11804 * as per aDFS FR 11805 */ 11806 ev_param->max_ast_index = ev->max_ast_index; 11807 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 11808 ev_param->agile_capability = 1; 11809 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 11810 11811 return QDF_STATUS_SUCCESS; 11812 } 11813 11814 /** 11815 * extract_dbglog_data_len_tlv() - extract debuglog data length 11816 * @wmi_handle: wmi handle 11817 * @param evt_buf: pointer to event buffer 11818 * 11819 * Return: length 11820 */ 11821 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 11822 void *evt_buf, uint32_t *len) 11823 { 11824 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 11825 11826 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 11827 11828 *len = param_buf->num_bufp; 11829 11830 return param_buf->bufp; 11831 } 11832 11833 11834 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 11835 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 11836 #else 11837 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 11838 ((_status) & WMI_RXERR_DECRYPT) 11839 #endif 11840 11841 /** 11842 * extract_mgmt_rx_params_tlv() - extract management rx params from event 11843 * @wmi_handle: wmi handle 11844 * @param evt_buf: pointer to event buffer 11845 * @param hdr: Pointer to hold header 11846 * @param bufp: Pointer to hold pointer to rx param buffer 11847 * 11848 * Return: QDF_STATUS_SUCCESS for success or error code 11849 */ 11850 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 11851 void *evt_buf, struct mgmt_rx_event_params *hdr, 11852 uint8_t **bufp) 11853 { 11854 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 11855 wmi_mgmt_rx_hdr *ev_hdr = NULL; 11856 int i; 11857 11858 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 11859 if (!param_tlvs) { 11860 wmi_err("Get NULL point message from FW"); 11861 return QDF_STATUS_E_INVAL; 11862 } 11863 11864 ev_hdr = param_tlvs->hdr; 11865 if (!hdr) { 11866 wmi_err("Rx event is NULL"); 11867 return QDF_STATUS_E_INVAL; 11868 } 11869 11870 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 11871 wmi_err("RX mgmt frame decrypt error, discard it"); 11872 return QDF_STATUS_E_INVAL; 11873 } 11874 11875 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 11876 wmi_err("Rx mgmt frame length mismatch, discard it"); 11877 return QDF_STATUS_E_INVAL; 11878 } 11879 11880 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11881 wmi_handle, 11882 ev_hdr->pdev_id); 11883 hdr->chan_freq = ev_hdr->chan_freq; 11884 hdr->channel = ev_hdr->channel; 11885 hdr->snr = ev_hdr->snr; 11886 hdr->rate = ev_hdr->rate; 11887 hdr->phy_mode = ev_hdr->phy_mode; 11888 hdr->buf_len = ev_hdr->buf_len; 11889 hdr->status = ev_hdr->status; 11890 hdr->flags = ev_hdr->flags; 11891 hdr->rssi = ev_hdr->rssi; 11892 hdr->tsf_delta = ev_hdr->tsf_delta; 11893 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 11894 for (i = 0; i < ATH_MAX_ANTENNA; i++) 11895 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 11896 11897 *bufp = param_tlvs->bufp; 11898 11899 return QDF_STATUS_SUCCESS; 11900 } 11901 11902 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 11903 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 11904 { 11905 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 11906 wmi_mgmt_rx_params_ext *ext_params_tlv; 11907 wmi_mgmt_rx_hdr *ev_hdr; 11908 11909 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 11910 if (!param_tlvs) { 11911 wmi_err("param_tlvs is NULL"); 11912 return QDF_STATUS_E_INVAL; 11913 } 11914 11915 ev_hdr = param_tlvs->hdr; 11916 if (!ev_hdr) { 11917 wmi_err("Rx event is NULL"); 11918 return QDF_STATUS_E_INVAL; 11919 } 11920 11921 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 11922 if (ext_params_tlv) { 11923 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 11924 ext_params_tlv->mgmt_rx_params_ext_dword1); 11925 if (ext_params->ba_win_size > 1024) { 11926 wmi_err("ba win size from TLV is Invalid"); 11927 return QDF_STATUS_E_INVAL; 11928 } 11929 11930 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 11931 ext_params_tlv->mgmt_rx_params_ext_dword1); 11932 if (ext_params->reo_win_size > 2048) { 11933 wmi_err("reo win size from TLV is Invalid"); 11934 return QDF_STATUS_E_INVAL; 11935 } 11936 } else { 11937 ext_params->ba_win_size = 0; 11938 ext_params->reo_win_size = 0; 11939 } 11940 11941 return QDF_STATUS_SUCCESS; 11942 } 11943 11944 #ifdef WLAN_MGMT_RX_REO_SUPPORT 11945 /** 11946 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 11947 * @wmi_handle: wmi handle 11948 * @evt_buf: pointer to event buffer 11949 * @params: Pointer to MGMT Rx REO parameters 11950 * 11951 * Return: QDF_STATUS_SUCCESS for success or error code 11952 */ 11953 static QDF_STATUS 11954 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 11955 void *evt_buf, 11956 struct mgmt_rx_reo_params *params) 11957 { 11958 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 11959 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 11960 11961 param_tlvs = evt_buf; 11962 if (!param_tlvs) { 11963 wmi_err("param_tlvs is NULL"); 11964 return QDF_STATUS_E_INVAL; 11965 } 11966 11967 ev_hdr = param_tlvs->hdr; 11968 if (!params) { 11969 wmi_err("Rx REO parameters is NULL"); 11970 return QDF_STATUS_E_INVAL; 11971 } 11972 11973 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11974 wmi_handle, 11975 ev_hdr->pdev_id); 11976 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 11977 ev_hdr->mgmt_pkt_ctr_info); 11978 params->global_timestamp = ev_hdr->global_timestamp; 11979 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 11980 ev_hdr->mgmt_pkt_ctr_info); 11981 params->duration_us = ev_hdr->rx_ppdu_duration_us; 11982 params->start_timestamp = params->global_timestamp; 11983 params->end_timestamp = params->start_timestamp + 11984 params->duration_us; 11985 11986 return QDF_STATUS_SUCCESS; 11987 } 11988 11989 /** 11990 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 11991 * MGMT_RX_EVENT_ID 11992 * @wmi_handle: wmi handle 11993 * @evt_buf: pointer to event buffer 11994 * @params: Pointer to MGMT Rx REO parameters 11995 * 11996 * Return: QDF_STATUS_SUCCESS for success or error code 11997 */ 11998 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 11999 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 12000 { 12001 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12002 wmi_mgmt_rx_reo_params *reo_params_tlv; 12003 wmi_mgmt_rx_hdr *ev_hdr; 12004 12005 param_tlvs = evt_buf; 12006 if (!param_tlvs) { 12007 wmi_err("param_tlvs is NULL"); 12008 return QDF_STATUS_E_INVAL; 12009 } 12010 12011 ev_hdr = param_tlvs->hdr; 12012 if (!ev_hdr) { 12013 wmi_err("Rx event is NULL"); 12014 return QDF_STATUS_E_INVAL; 12015 } 12016 12017 reo_params_tlv = param_tlvs->reo_params; 12018 if (!reo_params_tlv) { 12019 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 12020 return QDF_STATUS_E_INVAL; 12021 } 12022 12023 if (!reo_params) { 12024 wmi_err("MGMT Rx REO params is NULL"); 12025 return QDF_STATUS_E_INVAL; 12026 } 12027 12028 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12029 wmi_handle, 12030 ev_hdr->pdev_id); 12031 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 12032 reo_params_tlv->mgmt_pkt_ctr_link_info); 12033 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 12034 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 12035 reo_params_tlv->mgmt_pkt_ctr_link_info); 12036 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 12037 reo_params->start_timestamp = reo_params->global_timestamp; 12038 reo_params->end_timestamp = reo_params->start_timestamp + 12039 reo_params->duration_us; 12040 12041 return QDF_STATUS_SUCCESS; 12042 } 12043 12044 /** 12045 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 12046 * configuration command 12047 * @wmi_handle: wmi handle 12048 * @pdev_id: pdev ID of the radio 12049 * @filter: Pointer to MGMT Rx REO filter 12050 * 12051 * Return: QDF_STATUS_SUCCESS for success or error code 12052 */ 12053 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 12054 wmi_unified_t wmi_handle, 12055 uint8_t pdev_id, 12056 struct mgmt_rx_reo_filter *filter) 12057 { 12058 QDF_STATUS ret; 12059 wmi_buf_t buf; 12060 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 12061 size_t len = sizeof(*cmd); 12062 12063 if (!filter) { 12064 wmi_err("mgmt_rx_reo_filter is NULL"); 12065 return QDF_STATUS_E_INVAL; 12066 } 12067 12068 buf = wmi_buf_alloc(wmi_handle, len); 12069 if (!buf) { 12070 wmi_err("wmi_buf_alloc failed"); 12071 return QDF_STATUS_E_NOMEM; 12072 } 12073 12074 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 12075 wmi_buf_data(buf); 12076 12077 WMITLV_SET_HDR(&cmd->tlv_header, 12078 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 12079 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 12080 12081 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12082 wmi_handle, 12083 pdev_id); 12084 cmd->filter_low = filter->low; 12085 cmd->filter_high = filter->high; 12086 12087 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 12088 ret = wmi_unified_cmd_send( 12089 wmi_handle, buf, len, 12090 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 12091 12092 if (QDF_IS_STATUS_ERROR(ret)) { 12093 wmi_err("Failed to send WMI command"); 12094 wmi_buf_free(buf); 12095 } 12096 12097 return ret; 12098 } 12099 #endif 12100 12101 /** 12102 * extract_frame_pn_params_tlv() - extract PN params from event 12103 * @wmi_handle: wmi handle 12104 * @evt_buf: pointer to event buffer 12105 * @pn_params: Pointer to Frame PN params 12106 * 12107 * Return: QDF_STATUS_SUCCESS for success or error code 12108 */ 12109 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 12110 void *evt_buf, 12111 struct frame_pn_params *pn_params) 12112 { 12113 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12114 wmi_frame_pn_params *pn_params_tlv; 12115 12116 if (!is_service_enabled_tlv(wmi_handle, 12117 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 12118 return QDF_STATUS_SUCCESS; 12119 12120 param_tlvs = evt_buf; 12121 if (!param_tlvs) { 12122 wmi_err("Got NULL point message from FW"); 12123 return QDF_STATUS_E_INVAL; 12124 } 12125 12126 if (!pn_params) { 12127 wmi_err("PN Params is NULL"); 12128 return QDF_STATUS_E_INVAL; 12129 } 12130 12131 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 12132 * found by target 12133 */ 12134 pn_params_tlv = param_tlvs->pn_params; 12135 if (!pn_params_tlv) 12136 return QDF_STATUS_SUCCESS; 12137 12138 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 12139 sizeof(pn_params->curr_pn)); 12140 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 12141 sizeof(pn_params->prev_pn)); 12142 12143 return QDF_STATUS_SUCCESS; 12144 } 12145 12146 /** 12147 * extract_is_conn_ap_param_tlv() - extract is_conn_ap_frame param from event 12148 * @wmi_handle: wmi handle 12149 * @evt_buf: pointer to event buffer 12150 * @is_conn_ap: Pointer for is_conn_ap frame 12151 * 12152 * Return: QDF_STATUS_SUCCESS for success or error code 12153 */ 12154 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 12155 wmi_unified_t wmi_handle, 12156 void *evt_buf, 12157 struct frm_conn_ap *is_conn_ap) 12158 { 12159 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12160 wmi_is_my_mgmt_frame *my_frame_tlv; 12161 12162 param_tlvs = evt_buf; 12163 if (!param_tlvs) { 12164 wmi_err("Got NULL point message from FW"); 12165 return QDF_STATUS_E_INVAL; 12166 } 12167 12168 if (!is_conn_ap) { 12169 wmi_err(" is connected ap param is NULL"); 12170 return QDF_STATUS_E_INVAL; 12171 } 12172 12173 my_frame_tlv = param_tlvs->my_frame; 12174 if (!my_frame_tlv) 12175 return QDF_STATUS_SUCCESS; 12176 12177 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 12178 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 12179 12180 return QDF_STATUS_SUCCESS; 12181 } 12182 12183 /** 12184 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 12185 * @wmi_handle: wmi handle 12186 * @param evt_buf: pointer to event buffer 12187 * @param param: Pointer to hold roam param 12188 * 12189 * Return: QDF_STATUS_SUCCESS for success or error code 12190 */ 12191 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 12192 void *evt_buf, wmi_host_roam_event *param) 12193 { 12194 WMI_ROAM_EVENTID_param_tlvs *param_buf; 12195 wmi_roam_event_fixed_param *evt; 12196 12197 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 12198 if (!param_buf) { 12199 wmi_err("Invalid roam event buffer"); 12200 return QDF_STATUS_E_INVAL; 12201 } 12202 12203 evt = param_buf->fixed_param; 12204 qdf_mem_zero(param, sizeof(*param)); 12205 12206 param->vdev_id = evt->vdev_id; 12207 param->reason = evt->reason; 12208 param->rssi = evt->rssi; 12209 12210 return QDF_STATUS_SUCCESS; 12211 } 12212 12213 /** 12214 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 12215 * @wmi_handle: wmi handle 12216 * @param evt_buf: pointer to event buffer 12217 * @param param: Pointer to hold vdev scan param 12218 * 12219 * Return: QDF_STATUS_SUCCESS for success or error code 12220 */ 12221 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 12222 void *evt_buf, struct scan_event *param) 12223 { 12224 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 12225 wmi_scan_event_fixed_param *evt = NULL; 12226 12227 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 12228 evt = param_buf->fixed_param; 12229 12230 qdf_mem_zero(param, sizeof(*param)); 12231 12232 switch (evt->event) { 12233 case WMI_SCAN_EVENT_STARTED: 12234 param->type = SCAN_EVENT_TYPE_STARTED; 12235 break; 12236 case WMI_SCAN_EVENT_COMPLETED: 12237 param->type = SCAN_EVENT_TYPE_COMPLETED; 12238 break; 12239 case WMI_SCAN_EVENT_BSS_CHANNEL: 12240 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 12241 break; 12242 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 12243 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 12244 break; 12245 case WMI_SCAN_EVENT_DEQUEUED: 12246 param->type = SCAN_EVENT_TYPE_DEQUEUED; 12247 break; 12248 case WMI_SCAN_EVENT_PREEMPTED: 12249 param->type = SCAN_EVENT_TYPE_PREEMPTED; 12250 break; 12251 case WMI_SCAN_EVENT_START_FAILED: 12252 param->type = SCAN_EVENT_TYPE_START_FAILED; 12253 break; 12254 case WMI_SCAN_EVENT_RESTARTED: 12255 param->type = SCAN_EVENT_TYPE_RESTARTED; 12256 break; 12257 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 12258 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 12259 break; 12260 case WMI_SCAN_EVENT_MAX: 12261 default: 12262 param->type = SCAN_EVENT_TYPE_MAX; 12263 break; 12264 }; 12265 12266 switch (evt->reason) { 12267 case WMI_SCAN_REASON_NONE: 12268 param->reason = SCAN_REASON_NONE; 12269 break; 12270 case WMI_SCAN_REASON_COMPLETED: 12271 param->reason = SCAN_REASON_COMPLETED; 12272 break; 12273 case WMI_SCAN_REASON_CANCELLED: 12274 param->reason = SCAN_REASON_CANCELLED; 12275 break; 12276 case WMI_SCAN_REASON_PREEMPTED: 12277 param->reason = SCAN_REASON_PREEMPTED; 12278 break; 12279 case WMI_SCAN_REASON_TIMEDOUT: 12280 param->reason = SCAN_REASON_TIMEDOUT; 12281 break; 12282 case WMI_SCAN_REASON_INTERNAL_FAILURE: 12283 param->reason = SCAN_REASON_INTERNAL_FAILURE; 12284 break; 12285 case WMI_SCAN_REASON_SUSPENDED: 12286 param->reason = SCAN_REASON_SUSPENDED; 12287 break; 12288 case WMI_SCAN_REASON_DFS_VIOLATION: 12289 param->reason = SCAN_REASON_DFS_VIOLATION; 12290 break; 12291 case WMI_SCAN_REASON_MAX: 12292 param->reason = SCAN_REASON_MAX; 12293 break; 12294 default: 12295 param->reason = SCAN_REASON_MAX; 12296 break; 12297 }; 12298 12299 param->chan_freq = evt->channel_freq; 12300 param->requester = evt->requestor; 12301 param->scan_id = evt->scan_id; 12302 param->vdev_id = evt->vdev_id; 12303 param->timestamp = evt->tsf_timestamp; 12304 12305 return QDF_STATUS_SUCCESS; 12306 } 12307 12308 #ifdef FEATURE_WLAN_SCAN_PNO 12309 /** 12310 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 12311 * @wmi_handle: pointer to WMI handle 12312 * @evt_buf: pointer to WMI event buffer 12313 * @param: pointer to scan event param for NLO match 12314 * 12315 * Return: QDF_STATUS_SUCCESS for success or error code 12316 */ 12317 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 12318 void *evt_buf, 12319 struct scan_event *param) 12320 { 12321 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 12322 wmi_nlo_event *evt = param_buf->fixed_param; 12323 12324 qdf_mem_zero(param, sizeof(*param)); 12325 12326 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 12327 param->vdev_id = evt->vdev_id; 12328 12329 return QDF_STATUS_SUCCESS; 12330 } 12331 12332 /** 12333 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 12334 * @wmi_handle: pointer to WMI handle 12335 * @evt_buf: pointer to WMI event buffer 12336 * @param: pointer to scan event param for NLO complete 12337 * 12338 * Return: QDF_STATUS_SUCCESS for success or error code 12339 */ 12340 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 12341 void *evt_buf, 12342 struct scan_event *param) 12343 { 12344 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 12345 wmi_nlo_event *evt = param_buf->fixed_param; 12346 12347 qdf_mem_zero(param, sizeof(*param)); 12348 12349 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 12350 param->vdev_id = evt->vdev_id; 12351 12352 return QDF_STATUS_SUCCESS; 12353 } 12354 #endif 12355 12356 /** 12357 * extract_unit_test_tlv() - extract unit test data 12358 * @wmi_handle: wmi handle 12359 * @param evt_buf: pointer to event buffer 12360 * @param unit_test: pointer to hold unit test data 12361 * @param maxspace: Amount of space in evt_buf 12362 * 12363 * Return: QDF_STATUS_SUCCESS for success or error code 12364 */ 12365 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 12366 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 12367 { 12368 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 12369 wmi_unit_test_event_fixed_param *ev_param; 12370 uint32_t num_bufp; 12371 uint32_t copy_size; 12372 uint8_t *bufp; 12373 12374 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 12375 ev_param = param_buf->fixed_param; 12376 bufp = param_buf->bufp; 12377 num_bufp = param_buf->num_bufp; 12378 unit_test->vdev_id = ev_param->vdev_id; 12379 unit_test->module_id = ev_param->module_id; 12380 unit_test->diag_token = ev_param->diag_token; 12381 unit_test->flag = ev_param->flag; 12382 unit_test->payload_len = ev_param->payload_len; 12383 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 12384 ev_param->vdev_id, 12385 ev_param->module_id, 12386 ev_param->diag_token, 12387 ev_param->flag); 12388 wmi_debug("Unit-test data given below %d", num_bufp); 12389 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 12390 bufp, num_bufp); 12391 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 12392 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 12393 unit_test->buffer_len = copy_size; 12394 12395 return QDF_STATUS_SUCCESS; 12396 } 12397 12398 /** 12399 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 12400 * @wmi_handle: wmi handle 12401 * @param evt_buf: pointer to event buffer 12402 * @param index: Index into extended pdev stats 12403 * @param pdev_ext_stats: Pointer to hold extended pdev stats 12404 * 12405 * Return: QDF_STATUS_SUCCESS for success or error code 12406 */ 12407 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 12408 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 12409 { 12410 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12411 wmi_pdev_extd_stats *ev; 12412 12413 param_buf = evt_buf; 12414 if (!param_buf) 12415 return QDF_STATUS_E_FAILURE; 12416 12417 if (!param_buf->pdev_extd_stats) 12418 return QDF_STATUS_E_FAILURE; 12419 12420 ev = param_buf->pdev_extd_stats + index; 12421 12422 pdev_ext_stats->pdev_id = 12423 wmi_handle->ops->convert_target_pdev_id_to_host( 12424 wmi_handle, 12425 ev->pdev_id); 12426 pdev_ext_stats->my_rx_count = ev->my_rx_count; 12427 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 12428 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 12429 12430 return QDF_STATUS_SUCCESS; 12431 } 12432 12433 /** 12434 * extract_bcn_stats_tlv() - extract bcn stats from event 12435 * @wmi_handle: wmi handle 12436 * @param evt_buf: pointer to event buffer 12437 * @param index: Index into vdev stats 12438 * @param bcn_stats: Pointer to hold bcn stats 12439 * 12440 * Return: QDF_STATUS_SUCCESS for success or error code 12441 */ 12442 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 12443 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 12444 { 12445 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12446 wmi_stats_event_fixed_param *ev_param; 12447 uint8_t *data; 12448 12449 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 12450 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 12451 data = (uint8_t *) param_buf->data; 12452 12453 if (index < ev_param->num_bcn_stats) { 12454 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 12455 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 12456 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 12457 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 12458 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 12459 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 12460 (index * sizeof(wmi_bcn_stats))); 12461 12462 bcn_stats->vdev_id = ev->vdev_id; 12463 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 12464 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 12465 } 12466 12467 return QDF_STATUS_SUCCESS; 12468 } 12469 12470 /** 12471 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 12472 * stats from event 12473 * @wmi_handle: wmi handle 12474 * @param evt_buf: pointer to event buffer 12475 * @param index: Index into vdev stats 12476 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 12477 * 12478 * Return: QDF_STATUS_SUCCESS for success or error code 12479 */ 12480 static QDF_STATUS 12481 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 12482 void *evt_buf, uint32_t index, 12483 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 12484 { 12485 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12486 wmi_vdev_extd_stats *ev; 12487 12488 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12489 12490 if (param_buf->vdev_extd_stats) { 12491 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 12492 index); 12493 vdev_stats->vdev_id = ev->vdev_id; 12494 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 12495 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 12496 vdev_stats->unsolicited_prb_succ_cnt = 12497 ev->unsolicited_prb_succ_cnt; 12498 vdev_stats->unsolicited_prb_fail_cnt = 12499 ev->unsolicited_prb_fail_cnt; 12500 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 12501 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 12502 ev->unsolicited_prb_succ_cnt, 12503 ev->unsolicited_prb_fail_cnt); 12504 } 12505 12506 return QDF_STATUS_SUCCESS; 12507 } 12508 12509 /** 12510 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 12511 * @wmi_handle: wmi handle 12512 * @param evt_buf: pointer to event buffer 12513 * @param index: Index into bcn fault stats 12514 * @param bcnflt_stats: Pointer to hold bcn fault stats 12515 * 12516 * Return: QDF_STATUS_SUCCESS for success or error code 12517 */ 12518 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 12519 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 12520 { 12521 return QDF_STATUS_SUCCESS; 12522 } 12523 12524 /** 12525 * extract_chan_stats_tlv() - extract chan stats from event 12526 * @wmi_handle: wmi handle 12527 * @param evt_buf: pointer to event buffer 12528 * @param index: Index into chan stats 12529 * @param vdev_extd_stats: Pointer to hold chan stats 12530 * 12531 * Return: QDF_STATUS_SUCCESS for success or error code 12532 */ 12533 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 12534 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 12535 { 12536 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12537 wmi_stats_event_fixed_param *ev_param; 12538 uint8_t *data; 12539 12540 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 12541 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 12542 data = (uint8_t *) param_buf->data; 12543 12544 if (index < ev_param->num_chan_stats) { 12545 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 12546 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 12547 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 12548 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 12549 (index * sizeof(wmi_chan_stats))); 12550 12551 12552 /* Non-TLV doesn't have num_chan_stats */ 12553 chan_stats->chan_mhz = ev->chan_mhz; 12554 chan_stats->sampling_period_us = ev->sampling_period_us; 12555 chan_stats->rx_clear_count = ev->rx_clear_count; 12556 chan_stats->tx_duration_us = ev->tx_duration_us; 12557 chan_stats->rx_duration_us = ev->rx_duration_us; 12558 } 12559 12560 return QDF_STATUS_SUCCESS; 12561 } 12562 12563 /** 12564 * extract_profile_ctx_tlv() - extract profile context from event 12565 * @wmi_handle: wmi handle 12566 * @param evt_buf: pointer to event buffer 12567 * @idx: profile stats index to extract 12568 * @param profile_ctx: Pointer to hold profile context 12569 * 12570 * Return: QDF_STATUS_SUCCESS for success or error code 12571 */ 12572 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 12573 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 12574 { 12575 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 12576 12577 wmi_wlan_profile_ctx_t *ev; 12578 12579 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 12580 if (!param_buf) { 12581 wmi_err("Invalid profile data event buf"); 12582 return QDF_STATUS_E_INVAL; 12583 } 12584 12585 ev = param_buf->profile_ctx; 12586 12587 profile_ctx->tot = ev->tot; 12588 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 12589 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 12590 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 12591 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 12592 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 12593 profile_ctx->bin_count = ev->bin_count; 12594 12595 return QDF_STATUS_SUCCESS; 12596 } 12597 12598 /** 12599 * extract_profile_data_tlv() - extract profile data from event 12600 * @wmi_handle: wmi handle 12601 * @param evt_buf: pointer to event buffer 12602 * @param profile_data: Pointer to hold profile data 12603 * 12604 * Return: QDF_STATUS_SUCCESS for success or error code 12605 */ 12606 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 12607 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 12608 { 12609 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 12610 wmi_wlan_profile_t *ev; 12611 12612 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 12613 if (!param_buf) { 12614 wmi_err("Invalid profile data event buf"); 12615 return QDF_STATUS_E_INVAL; 12616 } 12617 12618 ev = ¶m_buf->profile_data[idx]; 12619 profile_data->id = ev->id; 12620 profile_data->cnt = ev->cnt; 12621 profile_data->tot = ev->tot; 12622 profile_data->min = ev->min; 12623 profile_data->max = ev->max; 12624 profile_data->hist_intvl = ev->hist_intvl; 12625 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 12626 12627 return QDF_STATUS_SUCCESS; 12628 } 12629 12630 /** 12631 * extract_pdev_utf_event_tlv() - extract UTF data info from event 12632 * @wmi_handle: WMI handle 12633 * @param evt_buf: Pointer to event buffer 12634 * @param param: Pointer to hold data 12635 * 12636 * Return : QDF_STATUS_SUCCESS for success or error code 12637 */ 12638 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 12639 uint8_t *evt_buf, 12640 struct wmi_host_pdev_utf_event *event) 12641 { 12642 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 12643 struct wmi_host_utf_seg_header_info *seg_hdr; 12644 12645 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 12646 event->data = param_buf->data; 12647 event->datalen = param_buf->num_data; 12648 12649 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 12650 wmi_err("Invalid datalen: %d", event->datalen); 12651 return QDF_STATUS_E_INVAL; 12652 } 12653 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 12654 /* Set pdev_id=1 until FW adds support to include pdev_id */ 12655 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12656 wmi_handle, 12657 seg_hdr->pdev_id); 12658 12659 return QDF_STATUS_SUCCESS; 12660 } 12661 12662 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 12663 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 12664 uint8_t *event, 12665 uint32_t *num_rf_characterization_entries) 12666 { 12667 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 12668 12669 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 12670 if (!param_buf) 12671 return QDF_STATUS_E_INVAL; 12672 12673 *num_rf_characterization_entries = 12674 param_buf->num_wmi_chan_rf_characterization_info; 12675 12676 return QDF_STATUS_SUCCESS; 12677 } 12678 12679 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 12680 uint8_t *event, 12681 uint32_t num_rf_characterization_entries, 12682 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 12683 { 12684 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 12685 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 12686 uint8_t ix; 12687 12688 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 12689 if (!param_buf) 12690 return QDF_STATUS_E_INVAL; 12691 12692 wmi_rf_characterization_entry = 12693 param_buf->wmi_chan_rf_characterization_info; 12694 if (!wmi_rf_characterization_entry) 12695 return QDF_STATUS_E_INVAL; 12696 12697 /* 12698 * Using num_wmi_chan_rf_characterization instead of param_buf value 12699 * since memory for rf_characterization_entries was allocated using 12700 * the former. 12701 */ 12702 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 12703 rf_characterization_entries[ix].freq = 12704 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 12705 &wmi_rf_characterization_entry[ix]); 12706 12707 rf_characterization_entries[ix].bw = 12708 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 12709 &wmi_rf_characterization_entry[ix]); 12710 12711 rf_characterization_entries[ix].chan_metric = 12712 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 12713 &wmi_rf_characterization_entry[ix]); 12714 12715 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 12716 "bw: %u, chan_metric: %u", 12717 ix, rf_characterization_entries[ix].freq, 12718 rf_characterization_entries[ix].bw, 12719 rf_characterization_entries[ix].chan_metric); 12720 } 12721 12722 return QDF_STATUS_SUCCESS; 12723 } 12724 #endif 12725 12726 #ifdef WLAN_FEATURE_11BE 12727 static void 12728 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 12729 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 12730 { 12731 cap->supports_chan_width_320 = 12732 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 12733 } 12734 #else 12735 static void 12736 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 12737 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 12738 { 12739 } 12740 #endif /* WLAN_FEATURE_11BE */ 12741 12742 /** 12743 * extract_chainmask_tables_tlv() - extract chain mask tables from event 12744 * @wmi_handle: wmi handle 12745 * @param evt_buf: pointer to event buffer 12746 * @param param: Pointer to hold evt buf 12747 * 12748 * Return: QDF_STATUS_SUCCESS for success or error code 12749 */ 12750 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 12751 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 12752 { 12753 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12754 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 12755 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12756 uint8_t i = 0, j = 0; 12757 uint32_t num_mac_phy_chainmask_caps = 0; 12758 12759 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12760 if (!param_buf) 12761 return QDF_STATUS_E_INVAL; 12762 12763 hw_caps = param_buf->soc_hw_mode_caps; 12764 if (!hw_caps) 12765 return QDF_STATUS_E_INVAL; 12766 12767 if ((!hw_caps->num_chainmask_tables) || 12768 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 12769 (hw_caps->num_chainmask_tables > 12770 param_buf->num_mac_phy_chainmask_combo)) 12771 return QDF_STATUS_E_INVAL; 12772 12773 chainmask_caps = param_buf->mac_phy_chainmask_caps; 12774 12775 if (!chainmask_caps) 12776 return QDF_STATUS_E_INVAL; 12777 12778 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 12779 if (chainmask_table[i].num_valid_chainmasks > 12780 (UINT_MAX - num_mac_phy_chainmask_caps)) { 12781 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 12782 num_mac_phy_chainmask_caps, i, 12783 chainmask_table[i].num_valid_chainmasks); 12784 return QDF_STATUS_E_INVAL; 12785 } 12786 num_mac_phy_chainmask_caps += 12787 chainmask_table[i].num_valid_chainmasks; 12788 } 12789 12790 if (num_mac_phy_chainmask_caps > 12791 param_buf->num_mac_phy_chainmask_caps) { 12792 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 12793 num_mac_phy_chainmask_caps, 12794 param_buf->num_mac_phy_chainmask_caps); 12795 return QDF_STATUS_E_INVAL; 12796 } 12797 12798 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 12799 12800 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 12801 i); 12802 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 12803 12804 chainmask_table[i].cap_list[j].chainmask = 12805 chainmask_caps->chainmask; 12806 12807 chainmask_table[i].cap_list[j].supports_chan_width_20 = 12808 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 12809 12810 chainmask_table[i].cap_list[j].supports_chan_width_40 = 12811 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 12812 12813 chainmask_table[i].cap_list[j].supports_chan_width_80 = 12814 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 12815 12816 chainmask_table[i].cap_list[j].supports_chan_width_160 = 12817 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 12818 12819 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 12820 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 12821 12822 chainmask_table[i].cap_list[j].chain_mask_2G = 12823 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 12824 12825 chainmask_table[i].cap_list[j].chain_mask_5G = 12826 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 12827 12828 chainmask_table[i].cap_list[j].chain_mask_tx = 12829 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 12830 12831 chainmask_table[i].cap_list[j].chain_mask_rx = 12832 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 12833 12834 chainmask_table[i].cap_list[j].supports_aDFS = 12835 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 12836 12837 chainmask_table[i].cap_list[j].supports_aSpectral = 12838 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 12839 12840 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 12841 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 12842 12843 chainmask_table[i].cap_list[j].supports_aDFS_160 = 12844 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 12845 12846 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 12847 chainmask_caps); 12848 12849 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 12850 chainmask_caps->supported_flags, 12851 chainmask_caps->chainmask); 12852 chainmask_caps++; 12853 } 12854 } 12855 12856 return QDF_STATUS_SUCCESS; 12857 } 12858 12859 /** 12860 * extract_service_ready_ext_tlv() - extract basic extended service ready params 12861 * from event 12862 * @wmi_handle: wmi handle 12863 * @param evt_buf: pointer to event buffer 12864 * @param param: Pointer to hold evt buf 12865 * 12866 * Return: QDF_STATUS_SUCCESS for success or error code 12867 */ 12868 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 12869 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 12870 { 12871 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12872 wmi_service_ready_ext_event_fixed_param *ev; 12873 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12874 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 12875 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 12876 uint8_t i = 0; 12877 12878 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12879 if (!param_buf) 12880 return QDF_STATUS_E_INVAL; 12881 12882 ev = param_buf->fixed_param; 12883 if (!ev) 12884 return QDF_STATUS_E_INVAL; 12885 12886 /* Move this to host based bitmap */ 12887 param->default_conc_scan_config_bits = 12888 ev->default_conc_scan_config_bits; 12889 param->default_fw_config_bits = ev->default_fw_config_bits; 12890 param->he_cap_info = ev->he_cap_info; 12891 param->mpdu_density = ev->mpdu_density; 12892 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 12893 param->fw_build_vers_ext = ev->fw_build_vers_ext; 12894 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 12895 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 12896 param->max_bssid_indicator = ev->max_bssid_indicator; 12897 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 12898 12899 hw_caps = param_buf->soc_hw_mode_caps; 12900 if (hw_caps) 12901 param->num_hw_modes = hw_caps->num_hw_modes; 12902 else 12903 param->num_hw_modes = 0; 12904 12905 reg_caps = param_buf->soc_hal_reg_caps; 12906 if (reg_caps) 12907 param->num_phy = reg_caps->num_phy; 12908 else 12909 param->num_phy = 0; 12910 12911 if (hw_caps) { 12912 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 12913 wmi_nofl_debug("Num chain mask tables: %d", 12914 hw_caps->num_chainmask_tables); 12915 } else 12916 param->num_chainmask_tables = 0; 12917 12918 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 12919 param->num_chainmask_tables > 12920 param_buf->num_mac_phy_chainmask_combo) { 12921 wmi_err_rl("num_chainmask_tables is OOB: %u", 12922 param->num_chainmask_tables); 12923 return QDF_STATUS_E_INVAL; 12924 } 12925 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 12926 12927 if (!chain_mask_combo) 12928 return QDF_STATUS_SUCCESS; 12929 12930 wmi_nofl_debug("Dumping chain mask combo data"); 12931 12932 for (i = 0; i < param->num_chainmask_tables; i++) { 12933 12934 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 12935 chain_mask_combo->chainmask_table_id, 12936 chain_mask_combo->num_valid_chainmask); 12937 12938 param->chainmask_table[i].table_id = 12939 chain_mask_combo->chainmask_table_id; 12940 param->chainmask_table[i].num_valid_chainmasks = 12941 chain_mask_combo->num_valid_chainmask; 12942 chain_mask_combo++; 12943 } 12944 wmi_nofl_debug("chain mask combo end"); 12945 12946 return QDF_STATUS_SUCCESS; 12947 } 12948 12949 #if defined(CONFIG_AFC_SUPPORT) 12950 /** 12951 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 12952 * type from event 12953 * @ev: pointer to event fixed param 12954 * @param: Pointer to hold the params 12955 * 12956 * Return: void 12957 */ 12958 static void 12959 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 12960 struct wlan_psoc_host_service_ext2_param *param) 12961 { 12962 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 12963 enum reg_afc_dev_deploy_type reg_afc_dev_type; 12964 12965 tgt_afc_dev_type = ev->afc_deployment_type; 12966 switch (tgt_afc_dev_type) { 12967 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 12968 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 12969 break; 12970 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 12971 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 12972 break; 12973 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 12974 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 12975 break; 12976 default: 12977 wmi_err("invalid afc deloyment %d", tgt_afc_dev_type); 12978 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 12979 break; 12980 } 12981 param->afc_dev_type = reg_afc_dev_type; 12982 12983 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 12984 } 12985 #else 12986 static inline void 12987 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 12988 struct wlan_psoc_host_service_ext2_param *param) 12989 { 12990 } 12991 #endif 12992 12993 /** 12994 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 12995 * event 12996 * @wmi_handle: wmi handle 12997 * @event: pointer to event buffer 12998 * @param: Pointer to hold the params 12999 * 13000 * Return: QDF_STATUS_SUCCESS for success or error code 13001 */ 13002 static QDF_STATUS 13003 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 13004 struct wlan_psoc_host_service_ext2_param *param) 13005 { 13006 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13007 wmi_service_ready_ext2_event_fixed_param *ev; 13008 13009 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13010 if (!param_buf) 13011 return QDF_STATUS_E_INVAL; 13012 13013 ev = param_buf->fixed_param; 13014 if (!ev) 13015 return QDF_STATUS_E_INVAL; 13016 13017 param->reg_db_version_major = 13018 WMI_REG_DB_VERSION_MAJOR_GET( 13019 ev->reg_db_version); 13020 param->reg_db_version_minor = 13021 WMI_REG_DB_VERSION_MINOR_GET( 13022 ev->reg_db_version); 13023 param->bdf_reg_db_version_major = 13024 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 13025 ev->reg_db_version); 13026 param->bdf_reg_db_version_minor = 13027 WMI_BDF_REG_DB_VERSION_MINOR_GET( 13028 ev->reg_db_version); 13029 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 13030 13031 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13032 13033 if (param_buf->nan_cap) 13034 param->max_ndp_sessions = 13035 param_buf->nan_cap->max_ndp_sessions; 13036 else 13037 param->max_ndp_sessions = 0; 13038 13039 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 13040 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 13041 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 13042 ev->max_user_per_ppdu_ofdma); 13043 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 13044 ev->max_user_per_ppdu_ofdma); 13045 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 13046 ev->max_user_per_ppdu_mumimo); 13047 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 13048 ev->max_user_per_ppdu_mumimo); 13049 param->target_cap_flags = ev->target_cap_flags; 13050 wmi_debug("htt peer data :%d", ev->target_cap_flags); 13051 13052 extract_svc_rdy_ext2_afc_tlv(ev, param); 13053 13054 return QDF_STATUS_SUCCESS; 13055 } 13056 13057 /* 13058 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 13059 * service ready ext 2 13060 * 13061 * @wmi_handle: wmi handle 13062 * @event: pointer to event buffer 13063 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 13064 * it indicates async SBS mode is supported, and 13065 * lower-band/higher band to MAC mapping is 13066 * switch-able. unit: mhz. examples 5180, 5320 13067 * 13068 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 13069 */ 13070 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 13071 wmi_unified_t wmi_handle, uint8_t *event, 13072 uint32_t *sbs_lower_band_end_freq) 13073 { 13074 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13075 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 13076 13077 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13078 if (!param_buf) 13079 return QDF_STATUS_E_INVAL; 13080 13081 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 13082 if (!dbs_or_sbs_caps) 13083 return QDF_STATUS_E_INVAL; 13084 13085 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 13086 13087 return QDF_STATUS_SUCCESS; 13088 } 13089 13090 /** 13091 * extract_sar_cap_service_ready_ext_tlv() - 13092 * extract SAR cap from service ready event 13093 * @wmi_handle: wmi handle 13094 * @event: pointer to event buffer 13095 * @ext_param: extended target info 13096 * 13097 * Return: QDF_STATUS_SUCCESS for success or error code 13098 */ 13099 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 13100 wmi_unified_t wmi_handle, 13101 uint8_t *event, 13102 struct wlan_psoc_host_service_ext_param *ext_param) 13103 { 13104 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13105 WMI_SAR_CAPABILITIES *sar_caps; 13106 13107 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 13108 13109 if (!param_buf) 13110 return QDF_STATUS_E_INVAL; 13111 13112 sar_caps = param_buf->sar_caps; 13113 if (sar_caps) 13114 ext_param->sar_version = sar_caps->active_version; 13115 else 13116 ext_param->sar_version = 0; 13117 13118 return QDF_STATUS_SUCCESS; 13119 } 13120 13121 /** 13122 * extract_hw_mode_cap_service_ready_ext_tlv() - 13123 * extract HW mode cap from service ready event 13124 * @wmi_handle: wmi handle 13125 * @param evt_buf: pointer to event buffer 13126 * @param param: Pointer to hold evt buf 13127 * @param hw_mode_idx: hw mode idx should be less than num_mode 13128 * 13129 * Return: QDF_STATUS_SUCCESS for success or error code 13130 */ 13131 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 13132 wmi_unified_t wmi_handle, 13133 uint8_t *event, uint8_t hw_mode_idx, 13134 struct wlan_psoc_host_hw_mode_caps *param) 13135 { 13136 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13137 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13138 13139 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13140 if (!param_buf) 13141 return QDF_STATUS_E_INVAL; 13142 13143 hw_caps = param_buf->soc_hw_mode_caps; 13144 if (!hw_caps) 13145 return QDF_STATUS_E_INVAL; 13146 13147 if (!hw_caps->num_hw_modes || 13148 !param_buf->hw_mode_caps || 13149 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 13150 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 13151 return QDF_STATUS_E_INVAL; 13152 13153 if (hw_mode_idx >= hw_caps->num_hw_modes) 13154 return QDF_STATUS_E_INVAL; 13155 13156 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 13157 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 13158 13159 param->hw_mode_config_type = 13160 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 13161 13162 return QDF_STATUS_SUCCESS; 13163 } 13164 13165 /** 13166 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 13167 * @param param: host mac phy capabilities 13168 * @param mac_phy_caps: mac phy capabilities 13169 * 13170 * Return: void 13171 */ 13172 #ifdef WLAN_FEATURE_11BE 13173 static void 13174 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 13175 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13176 { 13177 param->supports_11be = 13178 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 13179 13180 wmi_debug("11be support %d", param->supports_11be); 13181 } 13182 #else 13183 static void 13184 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 13185 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13186 { 13187 } 13188 #endif 13189 13190 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 13191 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 13192 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13193 { 13194 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 13195 } 13196 #else 13197 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 13198 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13199 { 13200 } 13201 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 13202 13203 /** 13204 * extract_mac_phy_cap_service_ready_ext_tlv() - 13205 * extract MAC phy cap from service ready event 13206 * @wmi_handle: wmi handle 13207 * @param evt_buf: pointer to event buffer 13208 * @param param: Pointer to hold evt buf 13209 * @param hw_mode_idx: hw mode idx should be less than num_mode 13210 * @param phy_id: phy id within hw_mode 13211 * 13212 * Return: QDF_STATUS_SUCCESS for success or error code 13213 */ 13214 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 13215 wmi_unified_t wmi_handle, 13216 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 13217 struct wlan_psoc_host_mac_phy_caps *param) 13218 { 13219 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13220 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 13221 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13222 uint32_t phy_map; 13223 uint8_t hw_idx, phy_idx = 0, pdev_id; 13224 13225 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13226 if (!param_buf) 13227 return QDF_STATUS_E_INVAL; 13228 13229 hw_caps = param_buf->soc_hw_mode_caps; 13230 if (!hw_caps) 13231 return QDF_STATUS_E_INVAL; 13232 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 13233 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 13234 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 13235 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 13236 return QDF_STATUS_E_INVAL; 13237 } 13238 13239 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 13240 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 13241 break; 13242 13243 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 13244 while (phy_map) { 13245 phy_map >>= 1; 13246 phy_idx++; 13247 } 13248 } 13249 13250 if (hw_idx == hw_caps->num_hw_modes) 13251 return QDF_STATUS_E_INVAL; 13252 13253 phy_idx += phy_id; 13254 if (phy_idx >= param_buf->num_mac_phy_caps) 13255 return QDF_STATUS_E_INVAL; 13256 13257 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 13258 13259 param->hw_mode_id = mac_phy_caps->hw_mode_id; 13260 param->phy_idx = phy_idx; 13261 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 13262 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13263 wmi_handle, 13264 pdev_id); 13265 param->tgt_pdev_id = pdev_id; 13266 extract_hw_link_id(param, mac_phy_caps); 13267 param->phy_id = mac_phy_caps->phy_id; 13268 param->supports_11b = 13269 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 13270 param->supports_11g = 13271 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 13272 param->supports_11a = 13273 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 13274 param->supports_11n = 13275 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 13276 param->supports_11ac = 13277 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 13278 param->supports_11ax = 13279 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 13280 13281 extract_service_ready_11be_support(param, mac_phy_caps); 13282 13283 param->supported_bands = mac_phy_caps->supported_bands; 13284 param->ampdu_density = mac_phy_caps->ampdu_density; 13285 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 13286 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 13287 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 13288 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 13289 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 13290 mac_phy_caps->he_cap_info_2G; 13291 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 13292 mac_phy_caps->he_cap_info_2G_ext; 13293 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 13294 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 13295 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 13296 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 13297 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 13298 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 13299 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 13300 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 13301 mac_phy_caps->he_cap_info_5G; 13302 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 13303 mac_phy_caps->he_cap_info_5G_ext; 13304 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 13305 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 13306 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 13307 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 13308 qdf_mem_copy(¶m->he_cap_phy_info_2G, 13309 &mac_phy_caps->he_cap_phy_info_2G, 13310 sizeof(param->he_cap_phy_info_2G)); 13311 qdf_mem_copy(¶m->he_cap_phy_info_5G, 13312 &mac_phy_caps->he_cap_phy_info_5G, 13313 sizeof(param->he_cap_phy_info_5G)); 13314 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 13315 sizeof(param->he_ppet2G)); 13316 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 13317 sizeof(param->he_ppet5G)); 13318 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 13319 param->lmac_id = mac_phy_caps->lmac_id; 13320 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 13321 (mac_phy_caps->wireless_modes); 13322 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 13323 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 13324 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 13325 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 13326 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 13327 mac_phy_caps->nss_ratio); 13328 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 13329 13330 return QDF_STATUS_SUCCESS; 13331 } 13332 13333 #ifdef WLAN_FEATURE_11BE_MLO 13334 /** 13335 * extract_mac_phy_emlcap() - API to extract EML Capabilities 13336 * @param: host ext2 mac phy capabilities 13337 * @mac_phy_caps: ext mac phy capabilities 13338 * 13339 * Return: void 13340 */ 13341 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13342 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13343 { 13344 if (!param || !mac_phy_caps) 13345 return; 13346 13347 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 13348 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 13349 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 13350 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 13351 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 13352 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 13353 } 13354 13355 /** 13356 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 13357 * @param: host ext2 mac phy capabilities 13358 * @mac_phy_caps: ext mac phy capabilities 13359 * 13360 * Return: void 13361 */ 13362 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13363 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13364 { 13365 if (!param || !mac_phy_caps) 13366 return; 13367 13368 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 13369 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 13370 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 13371 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 13372 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 13373 } 13374 #else 13375 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13376 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13377 { 13378 } 13379 13380 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13381 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13382 { 13383 } 13384 #endif 13385 13386 /** 13387 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 13388 * @param param: host ext2 mac phy capabilities 13389 * @param mac_phy_caps: ext mac phy capabilities 13390 * 13391 * Return: void 13392 */ 13393 #ifdef WLAN_FEATURE_11BE 13394 static void extract_mac_phy_cap_ehtcaps( 13395 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13396 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13397 { 13398 uint32_t i; 13399 13400 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 13401 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 13402 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 13403 13404 qdf_mem_copy(¶m->eht_cap_info_2G, 13405 &mac_phy_caps->eht_cap_mac_info_2G, 13406 sizeof(param->eht_cap_info_2G)); 13407 qdf_mem_copy(¶m->eht_cap_info_5G, 13408 &mac_phy_caps->eht_cap_mac_info_5G, 13409 sizeof(param->eht_cap_info_5G)); 13410 13411 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 13412 &mac_phy_caps->eht_cap_phy_info_2G, 13413 sizeof(param->eht_cap_phy_info_2G)); 13414 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 13415 &mac_phy_caps->eht_cap_phy_info_5G, 13416 sizeof(param->eht_cap_phy_info_5G)); 13417 13418 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 13419 &mac_phy_caps->eht_supp_mcs_ext_2G, 13420 sizeof(param->eht_supp_mcs_ext_2G)); 13421 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 13422 &mac_phy_caps->eht_supp_mcs_ext_5G, 13423 sizeof(param->eht_supp_mcs_ext_5G)); 13424 13425 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 13426 sizeof(param->eht_ppet2G)); 13427 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 13428 sizeof(param->eht_ppet5G)); 13429 13430 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", 13431 mac_phy_caps->eht_cap_mac_info_2G[0], 13432 mac_phy_caps->eht_cap_mac_info_5G[0], 13433 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 13434 mac_phy_caps->eht_cap_info_internal); 13435 13436 wmi_nofl_debug("EHT phy caps: "); 13437 13438 wmi_nofl_debug("2G:"); 13439 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 13440 wmi_nofl_debug("index %d value %x", 13441 i, param->eht_cap_phy_info_2G[i]); 13442 } 13443 wmi_nofl_debug("5G:"); 13444 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 13445 wmi_nofl_debug("index %d value %x", 13446 i, param->eht_cap_phy_info_5G[i]); 13447 } 13448 wmi_nofl_debug("2G MCS ext Map:"); 13449 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 13450 wmi_nofl_debug("index %d value %x", 13451 i, param->eht_supp_mcs_ext_2G[i]); 13452 } 13453 wmi_nofl_debug("5G MCS ext Map:"); 13454 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 13455 wmi_nofl_debug("index %d value %x", 13456 i, param->eht_supp_mcs_ext_5G[i]); 13457 } 13458 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 13459 param->eht_ppet2G.numss_m1, 13460 param->eht_ppet2G.ru_bit_mask); 13461 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 13462 wmi_nofl_debug("index %d value %x", 13463 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 13464 } 13465 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 13466 param->eht_ppet5G.numss_m1, 13467 param->eht_ppet5G.ru_bit_mask); 13468 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 13469 wmi_nofl_debug("index %d value %x", 13470 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 13471 } 13472 } 13473 #else 13474 static void extract_mac_phy_cap_ehtcaps( 13475 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13476 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13477 { 13478 } 13479 #endif 13480 13481 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 13482 wmi_unified_t wmi_handle, 13483 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 13484 uint8_t phy_idx, 13485 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 13486 { 13487 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13488 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 13489 13490 if (!event) { 13491 wmi_err("null evt_buf"); 13492 return QDF_STATUS_E_INVAL; 13493 } 13494 13495 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13496 13497 if (!param_buf->num_mac_phy_caps) 13498 return QDF_STATUS_SUCCESS; 13499 13500 if (phy_idx >= param_buf->num_mac_phy_caps) 13501 return QDF_STATUS_E_INVAL; 13502 13503 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 13504 13505 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 13506 (phy_id != mac_phy_caps->phy_id)) 13507 return QDF_STATUS_E_INVAL; 13508 13509 param->hw_mode_id = mac_phy_caps->hw_mode_id; 13510 param->phy_id = mac_phy_caps->phy_id; 13511 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13512 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 13513 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13514 mac_phy_caps->wireless_modes_ext); 13515 13516 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 13517 extract_mac_phy_emlcap(param, mac_phy_caps); 13518 extract_mac_phy_mldcap(param, mac_phy_caps); 13519 13520 return QDF_STATUS_SUCCESS; 13521 } 13522 13523 /** 13524 * extract_reg_cap_service_ready_ext_tlv() - 13525 * extract REG cap from service ready event 13526 * @wmi_handle: wmi handle 13527 * @param evt_buf: pointer to event buffer 13528 * @param param: Pointer to hold evt buf 13529 * @param phy_idx: phy idx should be less than num_mode 13530 * 13531 * Return: QDF_STATUS_SUCCESS for success or error code 13532 */ 13533 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 13534 wmi_unified_t wmi_handle, 13535 uint8_t *event, uint8_t phy_idx, 13536 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 13537 { 13538 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13539 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13540 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 13541 13542 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13543 if (!param_buf) 13544 return QDF_STATUS_E_INVAL; 13545 13546 reg_caps = param_buf->soc_hal_reg_caps; 13547 if (!reg_caps) 13548 return QDF_STATUS_E_INVAL; 13549 13550 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 13551 return QDF_STATUS_E_INVAL; 13552 13553 if (phy_idx >= reg_caps->num_phy) 13554 return QDF_STATUS_E_INVAL; 13555 13556 if (!param_buf->hal_reg_caps) 13557 return QDF_STATUS_E_INVAL; 13558 13559 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 13560 13561 param->phy_id = ext_reg_cap->phy_id; 13562 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 13563 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 13564 param->regcap1 = ext_reg_cap->regcap1; 13565 param->regcap2 = ext_reg_cap->regcap2; 13566 param->wireless_modes = convert_wireless_modes_tlv( 13567 ext_reg_cap->wireless_modes); 13568 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 13569 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 13570 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 13571 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 13572 13573 return QDF_STATUS_SUCCESS; 13574 } 13575 13576 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 13577 uint8_t num_dma_ring_caps) 13578 { 13579 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 13580 if (!num_dma_ring_caps) { 13581 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 13582 return QDF_STATUS_E_INVAL; 13583 } 13584 if (idx >= num_dma_ring_caps) { 13585 wmi_err("Index %d exceeds range", idx); 13586 return QDF_STATUS_E_INVAL; 13587 } 13588 return QDF_STATUS_SUCCESS; 13589 } 13590 13591 static void 13592 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 13593 struct wlan_psoc_host_dbr_ring_caps *param, 13594 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 13595 { 13596 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 13597 wmi_handle, 13598 dbr_ring_caps->pdev_id); 13599 param->mod_id = dbr_ring_caps->mod_id; 13600 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 13601 param->min_buf_size = dbr_ring_caps->min_buf_size; 13602 param->min_buf_align = dbr_ring_caps->min_buf_align; 13603 } 13604 13605 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 13606 wmi_unified_t wmi_handle, 13607 uint8_t *event, uint8_t idx, 13608 struct wlan_psoc_host_dbr_ring_caps *param) 13609 { 13610 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13611 QDF_STATUS status; 13612 13613 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 13614 if (!param_buf) 13615 return QDF_STATUS_E_INVAL; 13616 13617 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 13618 if (status != QDF_STATUS_SUCCESS) 13619 return status; 13620 13621 populate_dbr_ring_cap_elems(wmi_handle, param, 13622 ¶m_buf->dma_ring_caps[idx]); 13623 return QDF_STATUS_SUCCESS; 13624 } 13625 13626 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 13627 wmi_unified_t wmi_handle, 13628 uint8_t *event, uint8_t idx, 13629 struct wlan_psoc_host_dbr_ring_caps *param) 13630 { 13631 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13632 QDF_STATUS status; 13633 13634 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13635 if (!param_buf) 13636 return QDF_STATUS_E_INVAL; 13637 13638 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 13639 if (status != QDF_STATUS_SUCCESS) 13640 return status; 13641 13642 populate_dbr_ring_cap_elems(wmi_handle, param, 13643 ¶m_buf->dma_ring_caps[idx]); 13644 return QDF_STATUS_SUCCESS; 13645 } 13646 13647 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 13648 wmi_unified_t wmi_handle, 13649 uint8_t *event, uint8_t idx, 13650 struct wlan_psoc_host_scan_radio_caps *param) 13651 { 13652 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13653 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 13654 13655 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13656 if (!param_buf) 13657 return QDF_STATUS_E_INVAL; 13658 13659 if (idx >= param_buf->num_wmi_scan_radio_caps) 13660 return QDF_STATUS_E_INVAL; 13661 13662 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 13663 param->phy_id = scan_radio_caps->phy_id; 13664 param->scan_radio_supported = 13665 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 13666 param->dfs_en = 13667 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 13668 13669 return QDF_STATUS_SUCCESS; 13670 } 13671 13672 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 13673 uint8_t *event, 13674 struct wmi_host_sw_cal_ver *cal) 13675 { 13676 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13677 wmi_sw_cal_ver_cap *fw_cap; 13678 13679 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13680 if (!param_buf) 13681 return QDF_STATUS_E_INVAL; 13682 13683 fw_cap = param_buf->sw_cal_ver_cap; 13684 if (!fw_cap) 13685 return QDF_STATUS_E_INVAL; 13686 13687 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 13688 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 13689 cal->status = fw_cap->status; 13690 13691 return QDF_STATUS_SUCCESS; 13692 } 13693 13694 /** 13695 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 13696 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 13697 * 13698 * Return: host thermal throt level 13699 */ 13700 static enum thermal_throttle_level 13701 wmi_tgt_thermal_level_to_host(uint32_t level) 13702 { 13703 switch (level) { 13704 case WMI_THERMAL_FULLPERF: 13705 return THERMAL_FULLPERF; 13706 case WMI_THERMAL_MITIGATION: 13707 return THERMAL_MITIGATION; 13708 case WMI_THERMAL_SHUTOFF: 13709 return THERMAL_SHUTOFF; 13710 case WMI_THERMAL_SHUTDOWN_TGT: 13711 return THERMAL_SHUTDOWN_TARGET; 13712 default: 13713 return THERMAL_UNKNOWN; 13714 } 13715 } 13716 13717 #ifdef THERMAL_STATS_SUPPORT 13718 static void 13719 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 13720 uint32_t *therm_throt_levels, 13721 struct thermal_throt_level_stats *tt_temp_range_stats) 13722 { 13723 uint8_t lvl_idx; 13724 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 13725 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 13726 13727 tt_stats_event = param_buf->fixed_param; 13728 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 13729 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 13730 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 13731 tt_stats_event->therm_throt_levels; 13732 13733 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 13734 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 13735 *therm_throt_levels, 13736 param_buf->num_temp_range_stats); 13737 return; 13738 } 13739 13740 wmi_tt_stats = param_buf->temp_range_stats; 13741 if (!wmi_tt_stats) { 13742 wmi_err("wmi_tt_stats Null"); 13743 return; 13744 } 13745 13746 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 13747 tt_temp_range_stats[lvl_idx].start_temp_level = 13748 wmi_tt_stats[lvl_idx].start_temp_level; 13749 tt_temp_range_stats[lvl_idx].end_temp_level = 13750 wmi_tt_stats[lvl_idx].end_temp_level; 13751 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 13752 wmi_tt_stats[lvl_idx].total_time_ms_lo; 13753 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 13754 wmi_tt_stats[lvl_idx].total_time_ms_hi; 13755 tt_temp_range_stats[lvl_idx].num_entry = 13756 wmi_tt_stats[lvl_idx].num_entry; 13757 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 13758 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 13759 wmi_tt_stats[lvl_idx].end_temp_level, 13760 wmi_tt_stats[lvl_idx].total_time_ms_lo, 13761 wmi_tt_stats[lvl_idx].total_time_ms_hi, 13762 wmi_tt_stats[lvl_idx].num_entry); 13763 } 13764 } 13765 #else 13766 static void 13767 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 13768 uint32_t *therm_throt_levels, 13769 struct thermal_throt_level_stats *tt_temp_range_stats) 13770 { 13771 } 13772 #endif 13773 13774 /** 13775 * extract_thermal_stats_tlv() - extract thermal stats from event 13776 * @wmi_handle: wmi handle 13777 * @param evt_buf: Pointer to event buffer 13778 * @param temp: Pointer to hold extracted temperature 13779 * @param level: Pointer to hold extracted level in host enum 13780 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 13781 * range 13782 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 13783 * every level 13784 * 13785 * Return: 0 for success or error code 13786 */ 13787 static QDF_STATUS 13788 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 13789 void *evt_buf, uint32_t *temp, 13790 enum thermal_throttle_level *level, 13791 uint32_t *therm_throt_levels, 13792 struct thermal_throt_level_stats *tt_temp_range_stats_event, 13793 uint32_t *pdev_id) 13794 { 13795 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 13796 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 13797 13798 param_buf = 13799 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 13800 if (!param_buf) 13801 return QDF_STATUS_E_INVAL; 13802 13803 tt_stats_event = param_buf->fixed_param; 13804 wmi_debug("thermal temperature %d level %d", 13805 tt_stats_event->temp, tt_stats_event->level); 13806 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13807 wmi_handle, 13808 tt_stats_event->pdev_id); 13809 *temp = tt_stats_event->temp; 13810 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 13811 13812 if (tt_stats_event->therm_throt_levels) 13813 populate_thermal_stats(param_buf, therm_throt_levels, 13814 tt_temp_range_stats_event); 13815 13816 return QDF_STATUS_SUCCESS; 13817 } 13818 13819 /** 13820 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 13821 * @wmi_handle: wmi handle 13822 * @param evt_buf: pointer to event buffer 13823 * @param idx: Index to level stats 13824 * @param levelcount: Pointer to hold levelcount 13825 * @param dccount: Pointer to hold dccount 13826 * 13827 * Return: 0 for success or error code 13828 */ 13829 static QDF_STATUS 13830 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 13831 void *evt_buf, uint8_t idx, uint32_t *levelcount, 13832 uint32_t *dccount) 13833 { 13834 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 13835 wmi_therm_throt_level_stats_info *tt_level_info; 13836 13837 param_buf = 13838 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 13839 if (!param_buf) 13840 return QDF_STATUS_E_INVAL; 13841 13842 tt_level_info = param_buf->therm_throt_level_stats_info; 13843 13844 if (idx < THERMAL_LEVELS) { 13845 *levelcount = tt_level_info[idx].level_count; 13846 *dccount = tt_level_info[idx].dc_count; 13847 return QDF_STATUS_SUCCESS; 13848 } 13849 13850 return QDF_STATUS_E_FAILURE; 13851 } 13852 #ifdef BIG_ENDIAN_HOST 13853 /** 13854 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13855 * @param data_len - data length 13856 * @param data - pointer to data 13857 * 13858 * Return: QDF_STATUS - success or error status 13859 */ 13860 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 13861 { 13862 uint8_t *data_aligned = NULL; 13863 int c; 13864 unsigned char *data_unaligned; 13865 13866 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 13867 FIPS_ALIGN)); 13868 /* Assigning unaligned space to copy the data */ 13869 /* Checking if kmalloc does successful allocation */ 13870 if (!data_unaligned) 13871 return QDF_STATUS_E_FAILURE; 13872 13873 /* Checking if space is alligned */ 13874 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13875 /* align the data space */ 13876 data_aligned = 13877 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 13878 } else { 13879 data_aligned = (u_int8_t *)data_unaligned; 13880 } 13881 13882 /* memset and copy content from data to data aligned */ 13883 OS_MEMSET(data_aligned, 0, data_len); 13884 OS_MEMCPY(data_aligned, data, data_len); 13885 /* Endianness to LE */ 13886 for (c = 0; c < data_len/4; c++) { 13887 *((u_int32_t *)data_aligned + c) = 13888 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 13889 } 13890 13891 /* Copy content to event->data */ 13892 OS_MEMCPY(data, data_aligned, data_len); 13893 13894 /* clean up allocated space */ 13895 qdf_mem_free(data_unaligned); 13896 data_aligned = NULL; 13897 data_unaligned = NULL; 13898 13899 /*************************************************************/ 13900 13901 return QDF_STATUS_SUCCESS; 13902 } 13903 #else 13904 /** 13905 * fips_conv_data_be() - DUMMY for LE platform 13906 * 13907 * Return: QDF_STATUS - success 13908 */ 13909 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 13910 { 13911 return QDF_STATUS_SUCCESS; 13912 } 13913 #endif 13914 13915 /** 13916 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 13917 * @wmi_handle - wmi handle 13918 * @params - PN request params for peer 13919 * 13920 * Return: QDF_STATUS - success or error status 13921 */ 13922 static QDF_STATUS 13923 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 13924 struct peer_request_pn_param *params) 13925 { 13926 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 13927 wmi_buf_t buf; 13928 uint8_t *buf_ptr; 13929 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 13930 13931 buf = wmi_buf_alloc(wmi_handle, len); 13932 if (!buf) { 13933 wmi_err("wmi_buf_alloc failed"); 13934 return QDF_STATUS_E_FAILURE; 13935 } 13936 13937 buf_ptr = (uint8_t *)wmi_buf_data(buf); 13938 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 13939 13940 WMITLV_SET_HDR(&cmd->tlv_header, 13941 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 13942 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 13943 13944 cmd->vdev_id = params->vdev_id; 13945 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 13946 cmd->key_type = params->key_type; 13947 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13948 WMI_PEER_TX_PN_REQUEST_CMDID)) { 13949 wmi_err("Failed to send WMI command"); 13950 wmi_buf_free(buf); 13951 return QDF_STATUS_E_FAILURE; 13952 } 13953 return QDF_STATUS_SUCCESS; 13954 } 13955 13956 /** 13957 * extract_get_pn_data_tlv() - extract pn resp 13958 * @wmi_handle - wmi handle 13959 * @params - PN response params for peer 13960 * 13961 * Return: QDF_STATUS - success or error status 13962 */ 13963 static QDF_STATUS 13964 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13965 struct wmi_host_get_pn_event *param) 13966 { 13967 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 13968 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 13969 13970 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 13971 event = 13972 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 13973 13974 param->vdev_id = event->vdev_id; 13975 param->key_type = event->key_type; 13976 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 13977 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 13978 13979 return QDF_STATUS_SUCCESS; 13980 } 13981 13982 /** 13983 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 13984 * @wmi_handle: wmi handle 13985 * @params: Rx PN request params for peer 13986 * 13987 * Return: QDF_STATUS - success or error status 13988 */ 13989 static QDF_STATUS 13990 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 13991 struct peer_request_rxpn_param *params) 13992 { 13993 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 13994 wmi_buf_t buf; 13995 uint8_t *buf_ptr; 13996 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 13997 13998 if (!is_service_enabled_tlv(wmi_handle, 13999 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 14000 wmi_err("Rx PN Replay Check not supported by target"); 14001 return QDF_STATUS_E_NOSUPPORT; 14002 } 14003 14004 buf = wmi_buf_alloc(wmi_handle, len); 14005 if (!buf) { 14006 wmi_err("wmi_buf_alloc failed"); 14007 return QDF_STATUS_E_FAILURE; 14008 } 14009 14010 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14011 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 14012 14013 WMITLV_SET_HDR(&cmd->tlv_header, 14014 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 14015 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 14016 14017 cmd->vdev_id = params->vdev_id; 14018 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14019 cmd->key_ix = params->keyix; 14020 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14021 WMI_PEER_RX_PN_REQUEST_CMDID)) { 14022 wmi_err("Failed to send WMI command"); 14023 wmi_buf_free(buf); 14024 return QDF_STATUS_E_FAILURE; 14025 } 14026 return QDF_STATUS_SUCCESS; 14027 } 14028 14029 /** 14030 * extract_get_rxpn_data_tlv() - extract Rx PN resp 14031 * @wmi_handle: wmi handle 14032 * @params: Rx PN response params for peer 14033 * 14034 * Return: QDF_STATUS - success or error status 14035 */ 14036 static QDF_STATUS 14037 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14038 struct wmi_host_get_rxpn_event *params) 14039 { 14040 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14041 wmi_peer_rx_pn_response_event_fixed_param *event; 14042 14043 param_buf = evt_buf; 14044 event = param_buf->fixed_param; 14045 14046 params->vdev_id = event->vdev_id; 14047 params->keyix = event->key_idx; 14048 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 14049 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 14050 14051 return QDF_STATUS_SUCCESS; 14052 } 14053 14054 /** 14055 * extract_fips_event_data_tlv() - extract fips event data 14056 * @wmi_handle: wmi handle 14057 * @param evt_buf: pointer to event buffer 14058 * @param param: pointer FIPS event params 14059 * 14060 * Return: 0 for success or error code 14061 */ 14062 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 14063 void *evt_buf, struct wmi_host_fips_event_param *param) 14064 { 14065 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 14066 wmi_pdev_fips_event_fixed_param *event; 14067 14068 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 14069 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 14070 14071 if (event->data_len > param_buf->num_data) 14072 return QDF_STATUS_E_FAILURE; 14073 14074 if (fips_conv_data_be(event->data_len, param_buf->data) != 14075 QDF_STATUS_SUCCESS) 14076 return QDF_STATUS_E_FAILURE; 14077 14078 param->data = (uint32_t *)param_buf->data; 14079 param->data_len = event->data_len; 14080 param->error_status = event->error_status; 14081 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14082 wmi_handle, 14083 event->pdev_id); 14084 14085 return QDF_STATUS_SUCCESS; 14086 } 14087 14088 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 14089 /** 14090 * extract_fips_extend_event_data_tlv() - extract fips event data 14091 * @wmi_handle: wmi handle 14092 * @param evt_buf: pointer to event buffer 14093 * @param param: pointer FIPS event params 14094 * 14095 * Return: 0 for success or error code 14096 */ 14097 static QDF_STATUS 14098 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 14099 void *evt_buf, 14100 struct wmi_host_fips_extend_event_param 14101 *param) 14102 { 14103 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 14104 wmi_pdev_fips_extend_event_fixed_param *event; 14105 14106 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 14107 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 14108 14109 if (fips_conv_data_be(event->data_len, param_buf->data) != 14110 QDF_STATUS_SUCCESS) 14111 return QDF_STATUS_E_FAILURE; 14112 14113 param->data = (uint32_t *)param_buf->data; 14114 param->data_len = event->data_len; 14115 param->error_status = event->error_status; 14116 param->fips_cookie = event->fips_cookie; 14117 param->cmd_frag_idx = event->cmd_frag_idx; 14118 param->more_bit = event->more_bit; 14119 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14120 wmi_handle, 14121 event->pdev_id); 14122 14123 return QDF_STATUS_SUCCESS; 14124 } 14125 #endif 14126 14127 #ifdef WLAN_FEATURE_DISA 14128 /** 14129 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 14130 * params from event 14131 * @wmi_handle: wmi handle 14132 * @evt_buf: pointer to event buffer 14133 * @resp: Pointer to hold resp parameters 14134 * 14135 * Return: QDF_STATUS_SUCCESS for success or error code 14136 */ 14137 static QDF_STATUS 14138 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 14139 void *evt_buf, 14140 struct disa_encrypt_decrypt_resp_params 14141 *resp) 14142 { 14143 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 14144 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 14145 14146 param_buf = evt_buf; 14147 if (!param_buf) { 14148 wmi_err("encrypt decrypt resp evt_buf is NULL"); 14149 return QDF_STATUS_E_INVAL; 14150 } 14151 14152 data_event = param_buf->fixed_param; 14153 14154 resp->vdev_id = data_event->vdev_id; 14155 resp->status = data_event->status; 14156 14157 if ((data_event->data_length > param_buf->num_enc80211_frame) || 14158 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 14159 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 14160 wmi_err("FW msg data_len %d more than TLV hdr %d", 14161 data_event->data_length, 14162 param_buf->num_enc80211_frame); 14163 return QDF_STATUS_E_INVAL; 14164 } 14165 14166 resp->data_len = data_event->data_length; 14167 14168 if (resp->data_len) 14169 resp->data = (uint8_t *)param_buf->enc80211_frame; 14170 14171 return QDF_STATUS_SUCCESS; 14172 } 14173 #endif /* WLAN_FEATURE_DISA */ 14174 14175 static bool is_management_record_tlv(uint32_t cmd_id) 14176 { 14177 switch (cmd_id) { 14178 case WMI_MGMT_TX_SEND_CMDID: 14179 case WMI_MGMT_TX_COMPLETION_EVENTID: 14180 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 14181 case WMI_MGMT_RX_EVENTID: 14182 return true; 14183 default: 14184 return false; 14185 } 14186 } 14187 14188 static bool is_diag_event_tlv(uint32_t event_id) 14189 { 14190 if (WMI_DIAG_EVENTID == event_id) 14191 return true; 14192 14193 return false; 14194 } 14195 14196 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 14197 { 14198 uint16_t tag = 0; 14199 14200 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 14201 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 14202 __func__); 14203 return tag; 14204 } 14205 14206 if (wmi_handle->tag_crash_inject) 14207 tag = HTC_TX_PACKET_TAG_AUTO_PM; 14208 14209 wmi_handle->tag_crash_inject = false; 14210 return tag; 14211 } 14212 14213 /** 14214 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 14215 * @wmi_handle: WMI handle 14216 * @buf: WMI buffer 14217 * @cmd_id: WMI command Id 14218 * 14219 * Return htc_tx_tag 14220 */ 14221 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 14222 wmi_buf_t buf, 14223 uint32_t cmd_id) 14224 { 14225 uint16_t htc_tx_tag = 0; 14226 14227 switch (cmd_id) { 14228 case WMI_WOW_ENABLE_CMDID: 14229 case WMI_PDEV_SUSPEND_CMDID: 14230 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 14231 case WMI_PDEV_RESUME_CMDID: 14232 case WMI_HB_SET_ENABLE_CMDID: 14233 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 14234 #ifdef FEATURE_WLAN_D0WOW 14235 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 14236 #endif 14237 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 14238 break; 14239 case WMI_FORCE_FW_HANG_CMDID: 14240 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 14241 break; 14242 default: 14243 break; 14244 } 14245 14246 return htc_tx_tag; 14247 } 14248 14249 #ifdef CONFIG_BAND_6GHZ 14250 static struct cur_reg_rule 14251 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 14252 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 14253 { 14254 struct cur_reg_rule *reg_rule_ptr; 14255 uint32_t count; 14256 14257 if (!num_reg_rules) 14258 return NULL; 14259 14260 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 14261 sizeof(*reg_rule_ptr)); 14262 14263 if (!reg_rule_ptr) 14264 return NULL; 14265 14266 for (count = 0; count < num_reg_rules; count++) { 14267 reg_rule_ptr[count].start_freq = 14268 WMI_REG_RULE_START_FREQ_GET( 14269 wmi_reg_rule[count].freq_info); 14270 reg_rule_ptr[count].end_freq = 14271 WMI_REG_RULE_END_FREQ_GET( 14272 wmi_reg_rule[count].freq_info); 14273 reg_rule_ptr[count].max_bw = 14274 WMI_REG_RULE_MAX_BW_GET( 14275 wmi_reg_rule[count].bw_pwr_info); 14276 reg_rule_ptr[count].reg_power = 14277 WMI_REG_RULE_REG_POWER_GET( 14278 wmi_reg_rule[count].bw_pwr_info); 14279 reg_rule_ptr[count].ant_gain = 14280 WMI_REG_RULE_ANTENNA_GAIN_GET( 14281 wmi_reg_rule[count].bw_pwr_info); 14282 reg_rule_ptr[count].flags = 14283 WMI_REG_RULE_FLAGS_GET( 14284 wmi_reg_rule[count].flag_info); 14285 reg_rule_ptr[count].psd_flag = 14286 WMI_REG_RULE_PSD_FLAG_GET( 14287 wmi_reg_rule[count].psd_power_info); 14288 reg_rule_ptr[count].psd_eirp = 14289 WMI_REG_RULE_PSD_EIRP_GET( 14290 wmi_reg_rule[count].psd_power_info); 14291 } 14292 14293 return reg_rule_ptr; 14294 } 14295 #endif 14296 14297 static struct cur_reg_rule 14298 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 14299 wmi_regulatory_rule_struct *wmi_reg_rule) 14300 { 14301 struct cur_reg_rule *reg_rule_ptr; 14302 uint32_t count; 14303 14304 if (!num_reg_rules) 14305 return NULL; 14306 14307 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 14308 sizeof(*reg_rule_ptr)); 14309 14310 if (!reg_rule_ptr) 14311 return NULL; 14312 14313 for (count = 0; count < num_reg_rules; count++) { 14314 reg_rule_ptr[count].start_freq = 14315 WMI_REG_RULE_START_FREQ_GET( 14316 wmi_reg_rule[count].freq_info); 14317 reg_rule_ptr[count].end_freq = 14318 WMI_REG_RULE_END_FREQ_GET( 14319 wmi_reg_rule[count].freq_info); 14320 reg_rule_ptr[count].max_bw = 14321 WMI_REG_RULE_MAX_BW_GET( 14322 wmi_reg_rule[count].bw_pwr_info); 14323 reg_rule_ptr[count].reg_power = 14324 WMI_REG_RULE_REG_POWER_GET( 14325 wmi_reg_rule[count].bw_pwr_info); 14326 reg_rule_ptr[count].ant_gain = 14327 WMI_REG_RULE_ANTENNA_GAIN_GET( 14328 wmi_reg_rule[count].bw_pwr_info); 14329 reg_rule_ptr[count].flags = 14330 WMI_REG_RULE_FLAGS_GET( 14331 wmi_reg_rule[count].flag_info); 14332 } 14333 14334 return reg_rule_ptr; 14335 } 14336 14337 static enum cc_setting_code wmi_reg_status_to_reg_status( 14338 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 14339 { 14340 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 14341 return REG_SET_CC_STATUS_PASS; 14342 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 14343 return REG_CURRENT_ALPHA2_NOT_FOUND; 14344 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 14345 return REG_INIT_ALPHA2_NOT_FOUND; 14346 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 14347 return REG_SET_CC_CHANGE_NOT_ALLOWED; 14348 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 14349 return REG_SET_CC_STATUS_NO_MEMORY; 14350 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 14351 return REG_SET_CC_STATUS_FAIL; 14352 14353 wmi_debug("Unknown reg status code from WMI"); 14354 return REG_SET_CC_STATUS_FAIL; 14355 } 14356 14357 #ifdef CONFIG_BAND_6GHZ 14358 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 14359 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14360 struct cur_regulatory_info *reg_info, uint32_t len) 14361 { 14362 uint32_t i, j, k; 14363 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 14364 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 14365 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 14366 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 14367 uint32_t num_2g_reg_rules, num_5g_reg_rules; 14368 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 14369 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 14370 uint32_t total_reg_rules = 0; 14371 14372 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 14373 if (!param_buf) { 14374 wmi_err("invalid channel list event buf"); 14375 return QDF_STATUS_E_FAILURE; 14376 } 14377 14378 ext_chan_list_event_hdr = param_buf->fixed_param; 14379 ext_wmi_chan_priority = param_buf->reg_chan_priority; 14380 14381 if (ext_wmi_chan_priority) 14382 reg_info->reg_6g_thresh_priority_freq = 14383 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 14384 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 14385 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 14386 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 14387 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 14388 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 14389 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 14390 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 14391 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 14392 14393 wmi_debug("num reg rules from fw"); 14394 wmi_debug("AP SP %d, LPI %d, VLP %d", 14395 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14396 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 14397 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14398 14399 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14400 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 14401 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 14402 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 14403 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 14404 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 14405 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 14406 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 14407 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 14408 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 14409 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 14410 } 14411 14412 num_2g_reg_rules = reg_info->num_2g_reg_rules; 14413 total_reg_rules += num_2g_reg_rules; 14414 num_5g_reg_rules = reg_info->num_5g_reg_rules; 14415 total_reg_rules += num_5g_reg_rules; 14416 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 14417 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 14418 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 14419 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 14420 num_6g_reg_rules_ap[i]); 14421 return QDF_STATUS_E_FAILURE; 14422 } 14423 total_reg_rules += num_6g_reg_rules_ap[i]; 14424 num_6g_reg_rules_client[i] = 14425 reg_info->num_6g_reg_rules_client[i]; 14426 } 14427 14428 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14429 total_reg_rules += 14430 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 14431 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 14432 total_reg_rules += 14433 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 14434 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 14435 MAX_6G_REG_RULES) || 14436 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 14437 MAX_6G_REG_RULES) || 14438 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 14439 MAX_6G_REG_RULES)) { 14440 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", 14441 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 14442 num_6g_reg_rules_client[REG_INDOOR_AP][i], 14443 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 14444 i); 14445 return QDF_STATUS_E_FAILURE; 14446 } 14447 } 14448 14449 if (total_reg_rules != param_buf->num_reg_rule_array) { 14450 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 14451 total_reg_rules, param_buf->num_reg_rule_array); 14452 return QDF_STATUS_E_FAILURE; 14453 } 14454 14455 if ((num_2g_reg_rules > MAX_REG_RULES) || 14456 (num_5g_reg_rules > MAX_REG_RULES)) { 14457 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 14458 num_2g_reg_rules, num_5g_reg_rules); 14459 return QDF_STATUS_E_FAILURE; 14460 } 14461 14462 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 14463 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 14464 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 14465 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", 14466 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14467 num_6g_reg_rules_ap[REG_INDOOR_AP], 14468 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14469 return QDF_STATUS_E_FAILURE; 14470 } 14471 14472 if (param_buf->num_reg_rule_array > 14473 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 14474 sizeof(*ext_wmi_reg_rule)) { 14475 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 14476 param_buf->num_reg_rule_array); 14477 return QDF_STATUS_E_FAILURE; 14478 } 14479 14480 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 14481 REG_ALPHA2_LEN); 14482 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 14483 reg_info->phybitmap = convert_phybitmap_tlv( 14484 ext_chan_list_event_hdr->phybitmap); 14485 reg_info->offload_enabled = true; 14486 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 14487 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 14488 wmi_handle, ext_chan_list_event_hdr->phy_id); 14489 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 14490 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 14491 14492 reg_info->status_code = 14493 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 14494 status_code); 14495 14496 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 14497 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 14498 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 14499 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 14500 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 14501 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 14502 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 14503 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 14504 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 14505 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 14506 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 14507 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 14508 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 14509 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 14510 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 14511 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 14512 14513 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14514 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 14515 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 14516 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 14517 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 14518 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 14519 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 14520 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 14521 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 14522 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 14523 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 14524 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 14525 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 14526 } 14527 14528 wmi_debug("num_phys = %u and phy_id = %u", 14529 reg_info->num_phy, reg_info->phy_id); 14530 14531 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 14532 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 14533 reg_info->max_bw_2g, reg_info->min_bw_5g, 14534 reg_info->max_bw_5g); 14535 14536 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", 14537 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 14538 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 14539 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 14540 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 14541 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 14542 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 14543 14544 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", 14545 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14546 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14547 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14548 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14549 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 14550 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 14551 14552 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", 14553 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14554 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14555 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14556 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14557 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 14558 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 14559 14560 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 14561 num_2g_reg_rules, num_5g_reg_rules); 14562 14563 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 14564 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14565 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 14566 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14567 14568 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", 14569 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14570 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14571 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 14572 14573 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", 14574 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14575 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14576 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 14577 14578 ext_wmi_reg_rule = 14579 (wmi_regulatory_rule_ext_struct *) 14580 ((uint8_t *)ext_chan_list_event_hdr + 14581 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 14582 WMI_TLV_HDR_SIZE); 14583 reg_info->reg_rules_2g_ptr = 14584 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 14585 ext_wmi_reg_rule); 14586 ext_wmi_reg_rule += num_2g_reg_rules; 14587 for (i = 0; i < num_2g_reg_rules; i++) { 14588 if (!reg_info->reg_rules_2g_ptr) 14589 break; 14590 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 14591 i, reg_info->reg_rules_2g_ptr[i].start_freq, 14592 reg_info->reg_rules_2g_ptr[i].end_freq, 14593 reg_info->reg_rules_2g_ptr[i].flags); 14594 } 14595 reg_info->reg_rules_5g_ptr = 14596 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 14597 ext_wmi_reg_rule); 14598 ext_wmi_reg_rule += num_5g_reg_rules; 14599 for (i = 0; i < num_5g_reg_rules; i++) { 14600 if (!reg_info->reg_rules_5g_ptr) 14601 break; 14602 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 14603 i, reg_info->reg_rules_5g_ptr[i].start_freq, 14604 reg_info->reg_rules_5g_ptr[i].end_freq, 14605 reg_info->reg_rules_5g_ptr[i].flags); 14606 } 14607 14608 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 14609 reg_info->reg_rules_6g_ap_ptr[i] = 14610 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 14611 ext_wmi_reg_rule); 14612 14613 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 14614 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 14615 if (!reg_info->reg_rules_6g_ap_ptr[i]) 14616 break; 14617 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 14618 i, j, 14619 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 14620 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 14621 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 14622 } 14623 } 14624 14625 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 14626 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14627 reg_info->reg_rules_6g_client_ptr[j][i] = 14628 create_ext_reg_rules_from_wmi( 14629 num_6g_reg_rules_client[j][i], 14630 ext_wmi_reg_rule); 14631 14632 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 14633 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 14634 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 14635 break; 14636 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 14637 j, i, k, 14638 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 14639 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 14640 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 14641 } 14642 } 14643 } 14644 14645 reg_info->client_type = ext_chan_list_event_hdr->client_type; 14646 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 14647 reg_info->unspecified_ap_usable = 14648 ext_chan_list_event_hdr->unspecified_ap_usable; 14649 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 14650 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 14651 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 14652 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 14653 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 14654 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 14655 14656 wmi_debug("client type %d", reg_info->client_type); 14657 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 14658 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 14659 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 14660 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 14661 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 14662 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 14663 14664 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14665 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 14666 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 14667 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 14668 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 14669 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 14670 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 14671 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 14672 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 14673 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 14674 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 14675 } 14676 14677 reg_info->domain_code_6g_super_id = 14678 ext_chan_list_event_hdr->domain_code_6g_super_id; 14679 14680 wmi_debug("processed regulatory extended channel list"); 14681 14682 return QDF_STATUS_SUCCESS; 14683 } 14684 14685 #ifdef CONFIG_AFC_SUPPORT 14686 /** 14687 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 14688 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 14689 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 14690 * an index pointer required to store the current index of 14691 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 14692 * @chan_eirp_info: pointer to chan_eirp_info 14693 * @num_chans: Number of channels 14694 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 14695 * @index: Pointer to index 14696 * 14697 * Return: void 14698 */ 14699 static void 14700 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 14701 uint8_t num_chans, 14702 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 14703 uint8_t *index) 14704 { 14705 uint8_t chan_idx; 14706 14707 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 14708 chan_eirp_info[chan_idx].cfi = 14709 chan_eirp_power_info_hdr[*index].channel_cfi; 14710 chan_eirp_info[chan_idx].eirp_power = 14711 chan_eirp_power_info_hdr[*index].eirp_pwr; 14712 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 14713 chan_idx, 14714 chan_eirp_info[chan_idx].cfi, 14715 chan_eirp_info[chan_idx].eirp_power); 14716 } 14717 } 14718 14719 /** 14720 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 14721 * to the internal buffer afc_chan_info. 14722 * @afc_chan_info: pointer to afc_chan_info 14723 * @num_chan_objs: Number of channel objects 14724 * @channel_info_hdr: Pointer to channel_info_hdr 14725 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 14726 * 14727 * Return: void 14728 */ 14729 static void 14730 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 14731 uint8_t num_chan_objs, 14732 wmi_6g_afc_channel_info *channel_info_hdr, 14733 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 14734 { 14735 uint8_t count; 14736 uint8_t src_pwr_index = 0; 14737 14738 for (count = 0; count < num_chan_objs; count++) { 14739 afc_chan_info[count].global_opclass = 14740 channel_info_hdr[count].global_operating_class; 14741 afc_chan_info[count].num_chans = 14742 channel_info_hdr[count].num_channels; 14743 wmi_debug("Chan object count = %d global opclasss = %d", 14744 count, 14745 afc_chan_info[count].global_opclass); 14746 wmi_debug("Number of Channel EIRP objects = %d", 14747 afc_chan_info[count].num_chans); 14748 14749 if (afc_chan_info[count].num_chans > 0) { 14750 struct chan_eirp_obj *chan_eirp_info; 14751 14752 chan_eirp_info = 14753 qdf_mem_malloc(afc_chan_info[count].num_chans * 14754 sizeof(*chan_eirp_info)); 14755 14756 if (!chan_eirp_info) 14757 return; 14758 14759 copy_afc_chan_eirp_info(chan_eirp_info, 14760 afc_chan_info[count].num_chans, 14761 chan_eirp_power_info_hdr, 14762 &src_pwr_index); 14763 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 14764 } else { 14765 wmi_err("Number of channels is zero in object idx %d", 14766 count); 14767 } 14768 } 14769 } 14770 14771 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 14772 uint8_t num_freq_objs, 14773 wmi_6g_afc_frequency_info *freq_info_hdr) 14774 { 14775 uint8_t count; 14776 14777 for (count = 0; count < num_freq_objs; count++) { 14778 afc_freq_info[count].low_freq = 14779 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 14780 afc_freq_info[count].high_freq = 14781 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 14782 afc_freq_info[count].max_psd = 14783 freq_info_hdr[count].psd_power_info; 14784 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 14785 count, 14786 afc_freq_info[count].low_freq, 14787 afc_freq_info[count].high_freq, 14788 afc_freq_info[count].max_psd); 14789 } 14790 } 14791 14792 /** 14793 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 14794 * the power event info from the WMI AFC event buffer to the internal buffer 14795 * power_info. 14796 * @power_info: pointer to power_info 14797 * @afc_power_event_hdr: pointer to afc_power_event_hdr 14798 * 14799 * Return: void 14800 */ 14801 static void 14802 copy_afc_event_fixed_hdr_power_info( 14803 struct reg_fw_afc_power_event *power_info, 14804 wmi_afc_power_event_param *afc_power_event_hdr) 14805 { 14806 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 14807 power_info->resp_id = afc_power_event_hdr->resp_id; 14808 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 14809 power_info->afc_wfa_version = 14810 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 14811 power_info->afc_wfa_version |= 14812 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 14813 14814 power_info->avail_exp_time_d = 14815 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 14816 power_info->avail_exp_time_d |= 14817 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 14818 power_info->avail_exp_time_d |= 14819 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 14820 14821 power_info->avail_exp_time_t = 14822 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 14823 power_info->avail_exp_time_t |= 14824 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 14825 power_info->avail_exp_time_t |= 14826 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 14827 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 14828 power_info->fw_status_code, 14829 power_info->resp_id, 14830 power_info->serv_resp_code); 14831 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 14832 power_info->afc_wfa_version, 14833 power_info->avail_exp_time_d, 14834 power_info->avail_exp_time_t); 14835 } 14836 14837 /** 14838 * copy_power_event() - Copy the power event parameters from the AFC event 14839 * buffer to the power_info within the afc_info. 14840 * @afc_info: pointer to afc_info 14841 * @param_buf: pointer to param_buf 14842 * 14843 * Return: void 14844 */ 14845 static void copy_power_event(struct afc_regulatory_info *afc_info, 14846 WMI_AFC_EVENTID_param_tlvs *param_buf) 14847 { 14848 struct reg_fw_afc_power_event *power_info; 14849 wmi_afc_power_event_param *afc_power_event_hdr; 14850 struct afc_freq_obj *afc_freq_info; 14851 14852 power_info = qdf_mem_malloc(sizeof(*power_info)); 14853 14854 if (!power_info) 14855 return; 14856 14857 afc_power_event_hdr = param_buf->afc_power_event_param; 14858 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 14859 afc_info->power_info = power_info; 14860 14861 power_info->num_freq_objs = param_buf->num_freq_info_array; 14862 wmi_debug("Number of frequency objects = %d", 14863 power_info->num_freq_objs); 14864 if (power_info->num_freq_objs > 0) { 14865 wmi_6g_afc_frequency_info *freq_info_hdr; 14866 14867 freq_info_hdr = param_buf->freq_info_array; 14868 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 14869 sizeof(*afc_freq_info)); 14870 14871 if (!afc_freq_info) 14872 return; 14873 14874 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 14875 freq_info_hdr); 14876 power_info->afc_freq_info = afc_freq_info; 14877 } else { 14878 wmi_err("Number of frequency objects is zero"); 14879 } 14880 14881 power_info->num_chan_objs = param_buf->num_channel_info_array; 14882 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 14883 if (power_info->num_chan_objs > 0) { 14884 struct afc_chan_obj *afc_chan_info; 14885 wmi_6g_afc_channel_info *channel_info_hdr; 14886 14887 channel_info_hdr = param_buf->channel_info_array; 14888 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 14889 sizeof(*afc_chan_info)); 14890 14891 if (!afc_chan_info) 14892 return; 14893 14894 copy_afc_chan_obj_info(afc_chan_info, 14895 power_info->num_chan_objs, 14896 channel_info_hdr, 14897 param_buf->chan_eirp_power_info_array); 14898 power_info->afc_chan_info = afc_chan_info; 14899 } else { 14900 wmi_err("Number of channel objects is zero"); 14901 } 14902 } 14903 14904 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 14905 WMI_AFC_EVENTID_param_tlvs *param_buf) 14906 { 14907 struct reg_afc_expiry_event *expiry_info; 14908 14909 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 14910 14911 if (!expiry_info) 14912 return; 14913 14914 expiry_info->request_id = 14915 param_buf->expiry_event_param->request_id; 14916 expiry_info->event_subtype = 14917 param_buf->expiry_event_param->event_subtype; 14918 wmi_debug("Event subtype %d request ID %d", 14919 expiry_info->event_subtype, 14920 expiry_info->request_id); 14921 afc_info->expiry_info = expiry_info; 14922 } 14923 14924 /** 14925 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 14926 * in the AFC event. 'Common' indicates that these parameters are common for 14927 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 14928 * @wmi_handle: wmi handle 14929 * @afc_info: pointer to afc_info 14930 * @event_fixed_hdr: pointer to event_fixed_hdr 14931 * 14932 * Return: void 14933 */ 14934 static void 14935 copy_afc_event_common_info(wmi_unified_t wmi_handle, 14936 struct afc_regulatory_info *afc_info, 14937 wmi_afc_event_fixed_param *event_fixed_hdr) 14938 { 14939 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 14940 wmi_handle, event_fixed_hdr->phy_id); 14941 wmi_debug("phy_id %d", afc_info->phy_id); 14942 afc_info->event_type = event_fixed_hdr->event_type; 14943 } 14944 14945 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 14946 uint8_t *evt_buf, 14947 struct afc_regulatory_info *afc_info, 14948 uint32_t len) 14949 { 14950 WMI_AFC_EVENTID_param_tlvs *param_buf; 14951 wmi_afc_event_fixed_param *event_fixed_hdr; 14952 14953 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 14954 if (!param_buf) { 14955 wmi_err("Invalid AFC event buf"); 14956 return QDF_STATUS_E_FAILURE; 14957 } 14958 14959 event_fixed_hdr = param_buf->fixed_param; 14960 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 14961 wmi_debug("AFC event type %d received", afc_info->event_type); 14962 14963 switch (afc_info->event_type) { 14964 case WMI_AFC_EVENT_POWER_INFO: 14965 copy_power_event(afc_info, param_buf); 14966 break; 14967 case WMI_AFC_EVENT_TIMER_EXPIRY: 14968 copy_expiry_event(afc_info, param_buf); 14969 return QDF_STATUS_SUCCESS; 14970 default: 14971 wmi_err("Invalid event type"); 14972 return QDF_STATUS_E_FAILURE; 14973 } 14974 14975 return QDF_STATUS_SUCCESS; 14976 } 14977 #endif 14978 #endif 14979 14980 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 14981 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14982 struct cur_regulatory_info *reg_info, uint32_t len) 14983 { 14984 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 14985 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 14986 wmi_regulatory_rule_struct *wmi_reg_rule; 14987 uint32_t num_2g_reg_rules, num_5g_reg_rules; 14988 14989 wmi_debug("processing regulatory channel list"); 14990 14991 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 14992 if (!param_buf) { 14993 wmi_err("invalid channel list event buf"); 14994 return QDF_STATUS_E_FAILURE; 14995 } 14996 14997 chan_list_event_hdr = param_buf->fixed_param; 14998 14999 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 15000 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 15001 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15002 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15003 if ((num_2g_reg_rules > MAX_REG_RULES) || 15004 (num_5g_reg_rules > MAX_REG_RULES) || 15005 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 15006 (num_2g_reg_rules + num_5g_reg_rules != 15007 param_buf->num_reg_rule_array)) { 15008 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15009 num_2g_reg_rules, num_5g_reg_rules); 15010 return QDF_STATUS_E_FAILURE; 15011 } 15012 if (param_buf->num_reg_rule_array > 15013 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 15014 sizeof(*wmi_reg_rule)) { 15015 wmi_err_rl("Invalid num_reg_rule_array: %u", 15016 param_buf->num_reg_rule_array); 15017 return QDF_STATUS_E_FAILURE; 15018 } 15019 15020 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 15021 REG_ALPHA2_LEN); 15022 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 15023 reg_info->phybitmap = convert_phybitmap_tlv( 15024 chan_list_event_hdr->phybitmap); 15025 reg_info->offload_enabled = true; 15026 reg_info->num_phy = chan_list_event_hdr->num_phy; 15027 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15028 wmi_handle, chan_list_event_hdr->phy_id); 15029 reg_info->ctry_code = chan_list_event_hdr->country_id; 15030 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 15031 15032 reg_info->status_code = 15033 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 15034 15035 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 15036 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 15037 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 15038 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 15039 15040 wmi_debug("num_phys = %u and phy_id = %u", 15041 reg_info->num_phy, reg_info->phy_id); 15042 15043 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 15044 reg_info->alpha2, reg_info->dfs_region, 15045 reg_info->min_bw_2g, reg_info->max_bw_2g, 15046 reg_info->min_bw_5g, reg_info->max_bw_5g); 15047 15048 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15049 num_2g_reg_rules, num_5g_reg_rules); 15050 wmi_reg_rule = 15051 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 15052 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 15053 + WMI_TLV_HDR_SIZE); 15054 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 15055 wmi_reg_rule); 15056 wmi_reg_rule += num_2g_reg_rules; 15057 15058 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 15059 wmi_reg_rule); 15060 15061 wmi_debug("processed regulatory channel list"); 15062 15063 return QDF_STATUS_SUCCESS; 15064 } 15065 15066 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 15067 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15068 struct reg_11d_new_country *reg_11d_country, uint32_t len) 15069 { 15070 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 15071 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 15072 15073 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 15074 if (!param_buf) { 15075 wmi_err("invalid 11d country event buf"); 15076 return QDF_STATUS_E_FAILURE; 15077 } 15078 15079 reg_11d_country_event = param_buf->fixed_param; 15080 15081 qdf_mem_copy(reg_11d_country->alpha2, 15082 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 15083 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 15084 15085 wmi_debug("processed 11d country event, new cc %s", 15086 reg_11d_country->alpha2); 15087 15088 return QDF_STATUS_SUCCESS; 15089 } 15090 15091 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 15092 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15093 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 15094 { 15095 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 15096 wmi_avoid_freq_range_desc *afr_desc; 15097 uint32_t num_freq_ranges, freq_range_idx; 15098 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 15099 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 15100 15101 if (!param_buf) { 15102 wmi_err("Invalid channel avoid event buffer"); 15103 return QDF_STATUS_E_INVAL; 15104 } 15105 15106 afr_fixed_param = param_buf->fixed_param; 15107 if (!afr_fixed_param) { 15108 wmi_err("Invalid channel avoid event fixed param buffer"); 15109 return QDF_STATUS_E_INVAL; 15110 } 15111 15112 if (!ch_avoid_ind) { 15113 wmi_err("Invalid channel avoid indication buffer"); 15114 return QDF_STATUS_E_INVAL; 15115 } 15116 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 15117 wmi_err("no.of freq ranges exceeded the limit"); 15118 return QDF_STATUS_E_INVAL; 15119 } 15120 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 15121 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 15122 afr_fixed_param->num_freq_ranges; 15123 15124 wmi_debug("Channel avoid event received with %d ranges", 15125 num_freq_ranges); 15126 15127 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 15128 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 15129 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 15130 freq_range_idx++) { 15131 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 15132 afr_desc->start_freq; 15133 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 15134 afr_desc->end_freq; 15135 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 15136 freq_range_idx, afr_desc->tlv_header, 15137 afr_desc->start_freq, afr_desc->end_freq); 15138 afr_desc++; 15139 } 15140 15141 return QDF_STATUS_SUCCESS; 15142 } 15143 15144 #ifdef DFS_COMPONENT_ENABLE 15145 /** 15146 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 15147 * @wmi_handle: wma handle 15148 * @evt_buf: event buffer 15149 * @vdev_id: vdev id 15150 * @len: length of buffer 15151 * 15152 * Return: 0 for success or error code 15153 */ 15154 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 15155 uint8_t *evt_buf, 15156 uint32_t *vdev_id, 15157 uint32_t len) 15158 { 15159 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 15160 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 15161 15162 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 15163 if (!param_tlvs) { 15164 wmi_err("invalid cac complete event buf"); 15165 return QDF_STATUS_E_FAILURE; 15166 } 15167 15168 cac_event = param_tlvs->fixed_param; 15169 *vdev_id = cac_event->vdev_id; 15170 wmi_debug("processed cac complete event vdev %d", *vdev_id); 15171 15172 return QDF_STATUS_SUCCESS; 15173 } 15174 15175 /** 15176 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 15177 * @wmi_handle: wma handle 15178 * @evt_buf: event buffer 15179 * @vdev_id: vdev id 15180 * @len: length of buffer 15181 * 15182 * Return: 0 for success or error code 15183 */ 15184 static QDF_STATUS 15185 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 15186 uint8_t *evt_buf, 15187 struct vdev_adfs_complete_status *param) 15188 { 15189 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 15190 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 15191 15192 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 15193 if (!param_tlvs) { 15194 wmi_err("invalid ocac complete event buf"); 15195 return QDF_STATUS_E_FAILURE; 15196 } 15197 15198 if (!param_tlvs->fixed_param) { 15199 wmi_err("invalid param_tlvs->fixed_param"); 15200 return QDF_STATUS_E_FAILURE; 15201 } 15202 15203 ocac_complete_status = param_tlvs->fixed_param; 15204 param->vdev_id = ocac_complete_status->vdev_id; 15205 param->chan_freq = ocac_complete_status->chan_freq; 15206 param->center_freq1 = ocac_complete_status->center_freq1; 15207 param->center_freq2 = ocac_complete_status->center_freq2; 15208 param->ocac_status = ocac_complete_status->status; 15209 param->chan_width = ocac_complete_status->chan_width; 15210 wmi_debug("processed ocac complete event vdev %d" 15211 " agile chan %d %d width %d status %d", 15212 param->vdev_id, 15213 param->center_freq1, 15214 param->center_freq2, 15215 param->chan_width, 15216 param->ocac_status); 15217 15218 return QDF_STATUS_SUCCESS; 15219 } 15220 15221 /** 15222 * extract_dfs_radar_detection_event_tlv() - extract radar found event 15223 * @wmi_handle: wma handle 15224 * @evt_buf: event buffer 15225 * @radar_found: radar found event info 15226 * @len: length of buffer 15227 * 15228 * Return: 0 for success or error code 15229 */ 15230 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 15231 wmi_unified_t wmi_handle, 15232 uint8_t *evt_buf, 15233 struct radar_found_info *radar_found, 15234 uint32_t len) 15235 { 15236 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 15237 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 15238 15239 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 15240 if (!param_tlv) { 15241 wmi_err("invalid radar detection event buf"); 15242 return QDF_STATUS_E_FAILURE; 15243 } 15244 15245 radar_event = param_tlv->fixed_param; 15246 15247 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 15248 wmi_handle, 15249 radar_event->pdev_id); 15250 15251 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 15252 return QDF_STATUS_E_FAILURE; 15253 15254 radar_found->detection_mode = radar_event->detection_mode; 15255 radar_found->chan_freq = radar_event->chan_freq; 15256 radar_found->chan_width = radar_event->chan_width; 15257 radar_found->detector_id = radar_event->detector_id; 15258 radar_found->segment_id = radar_event->segment_id; 15259 radar_found->timestamp = radar_event->timestamp; 15260 radar_found->is_chirp = radar_event->is_chirp; 15261 radar_found->freq_offset = radar_event->freq_offset; 15262 radar_found->sidx = radar_event->sidx; 15263 15264 wmi_debug("processed radar found event pdev %d," 15265 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 15266 "chan_width (RSSI) %d,detector_id (false_radar) %d," 15267 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 15268 "is_chirp %d,detection mode %d", 15269 radar_event->pdev_id, radar_found->pdev_id, 15270 radar_event->timestamp, radar_event->chan_freq, 15271 radar_event->chan_width, radar_event->detector_id, 15272 radar_event->freq_offset, radar_event->segment_id, 15273 radar_event->sidx, radar_event->is_chirp, 15274 radar_event->detection_mode); 15275 15276 return QDF_STATUS_SUCCESS; 15277 } 15278 15279 #ifdef MOBILE_DFS_SUPPORT 15280 /** 15281 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 15282 * @wmi_handle: wma handle 15283 * @evt_buf: event buffer 15284 * @wlan_radar_event: Pointer to struct radar_event_info 15285 * @len: length of buffer 15286 * 15287 * Return: QDF_STATUS 15288 */ 15289 static QDF_STATUS extract_wlan_radar_event_info_tlv( 15290 wmi_unified_t wmi_handle, 15291 uint8_t *evt_buf, 15292 struct radar_event_info *wlan_radar_event, 15293 uint32_t len) 15294 { 15295 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 15296 wmi_dfs_radar_event_fixed_param *radar_event; 15297 15298 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 15299 if (!param_tlv) { 15300 wmi_err("invalid wlan radar event buf"); 15301 return QDF_STATUS_E_FAILURE; 15302 } 15303 15304 radar_event = param_tlv->fixed_param; 15305 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 15306 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 15307 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 15308 wlan_radar_event->rssi = radar_event->rssi; 15309 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 15310 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 15311 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 15312 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 15313 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 15314 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 15315 if (radar_event->pulse_flags & 15316 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 15317 wlan_radar_event->is_psidx_diff_valid = true; 15318 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 15319 } else { 15320 wlan_radar_event->is_psidx_diff_valid = false; 15321 } 15322 15323 wlan_radar_event->pdev_id = radar_event->pdev_id; 15324 15325 return QDF_STATUS_SUCCESS; 15326 } 15327 #else 15328 static QDF_STATUS extract_wlan_radar_event_info_tlv( 15329 wmi_unified_t wmi_handle, 15330 uint8_t *evt_buf, 15331 struct radar_event_info *wlan_radar_event, 15332 uint32_t len) 15333 { 15334 return QDF_STATUS_SUCCESS; 15335 } 15336 #endif 15337 #endif 15338 15339 /** 15340 * send_get_rcpi_cmd_tlv() - send request for rcpi value 15341 * @wmi_handle: wmi handle 15342 * @get_rcpi_param: rcpi params 15343 * 15344 * Return: QDF status 15345 */ 15346 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 15347 struct rcpi_req *get_rcpi_param) 15348 { 15349 wmi_buf_t buf; 15350 wmi_request_rcpi_cmd_fixed_param *cmd; 15351 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 15352 15353 buf = wmi_buf_alloc(wmi_handle, len); 15354 if (!buf) 15355 return QDF_STATUS_E_NOMEM; 15356 15357 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 15358 WMITLV_SET_HDR(&cmd->tlv_header, 15359 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 15360 WMITLV_GET_STRUCT_TLVLEN 15361 (wmi_request_rcpi_cmd_fixed_param)); 15362 15363 cmd->vdev_id = get_rcpi_param->vdev_id; 15364 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 15365 &cmd->peer_macaddr); 15366 15367 switch (get_rcpi_param->measurement_type) { 15368 15369 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 15370 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15371 break; 15372 15373 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 15374 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 15375 break; 15376 15377 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 15378 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 15379 break; 15380 15381 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 15382 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 15383 break; 15384 15385 default: 15386 /* 15387 * invalid rcpi measurement type, fall back to 15388 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 15389 */ 15390 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15391 break; 15392 } 15393 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 15394 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 15395 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15396 WMI_REQUEST_RCPI_CMDID)) { 15397 15398 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 15399 wmi_buf_free(buf); 15400 return QDF_STATUS_E_FAILURE; 15401 } 15402 15403 return QDF_STATUS_SUCCESS; 15404 } 15405 15406 /** 15407 * extract_rcpi_response_event_tlv() - Extract RCPI event params 15408 * @wmi_handle: wmi handle 15409 * @evt_buf: pointer to event buffer 15410 * @res: pointer to hold rcpi response from firmware 15411 * 15412 * Return: QDF_STATUS_SUCCESS for successful event parse 15413 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 15414 */ 15415 static QDF_STATUS 15416 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 15417 void *evt_buf, struct rcpi_res *res) 15418 { 15419 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 15420 wmi_update_rcpi_event_fixed_param *event; 15421 15422 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 15423 if (!param_buf) { 15424 wmi_err("Invalid rcpi event"); 15425 return QDF_STATUS_E_INVAL; 15426 } 15427 15428 event = param_buf->fixed_param; 15429 res->vdev_id = event->vdev_id; 15430 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 15431 15432 switch (event->measurement_type) { 15433 15434 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 15435 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15436 break; 15437 15438 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 15439 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 15440 break; 15441 15442 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 15443 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 15444 break; 15445 15446 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 15447 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 15448 break; 15449 15450 default: 15451 wmi_err("Invalid rcpi measurement type from firmware"); 15452 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 15453 return QDF_STATUS_E_FAILURE; 15454 } 15455 15456 if (event->status) 15457 return QDF_STATUS_E_FAILURE; 15458 else 15459 return QDF_STATUS_SUCCESS; 15460 } 15461 15462 /** 15463 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 15464 * host to target defines. For legacy there is not conversion 15465 * required. Just return pdev_id as it is. 15466 * @param pdev_id: host pdev_id to be converted. 15467 * Return: target pdev_id after conversion. 15468 */ 15469 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 15470 wmi_unified_t wmi_handle, 15471 uint32_t pdev_id) 15472 { 15473 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 15474 return WMI_PDEV_ID_SOC; 15475 15476 /*No conversion required*/ 15477 return pdev_id; 15478 } 15479 15480 /** 15481 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 15482 * target to host defines. For legacy there is not conversion 15483 * required. Just return pdev_id as it is. 15484 * @param pdev_id: target pdev_id to be converted. 15485 * Return: host pdev_id after conversion. 15486 */ 15487 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 15488 wmi_unified_t wmi_handle, 15489 uint32_t pdev_id) 15490 { 15491 /*No conversion required*/ 15492 return pdev_id; 15493 } 15494 15495 /** 15496 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 15497 * host to target defines. For legacy there is not conversion 15498 * required. Just return phy_id as it is. 15499 * @param pdev_id: host phy_id to be converted. 15500 * Return: target phy_id after conversion. 15501 */ 15502 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 15503 wmi_unified_t wmi_handle, 15504 uint32_t phy_id) 15505 { 15506 /*No conversion required*/ 15507 return phy_id; 15508 } 15509 15510 /** 15511 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 15512 * target to host defines. For legacy there is not conversion 15513 * required. Just return phy_id as it is. 15514 * @param pdev_id: target phy_id to be converted. 15515 * Return: host phy_id after conversion. 15516 */ 15517 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 15518 wmi_unified_t wmi_handle, 15519 uint32_t phy_id) 15520 { 15521 /*No conversion required*/ 15522 return phy_id; 15523 } 15524 15525 /** 15526 * send_set_country_cmd_tlv() - WMI scan channel list function 15527 * @param wmi_handle : handle to WMI. 15528 * @param param : pointer to hold scan channel list parameter 15529 * 15530 * Return: 0 on success and -ve on failure. 15531 */ 15532 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 15533 struct set_country *params) 15534 { 15535 wmi_buf_t buf; 15536 QDF_STATUS qdf_status; 15537 wmi_set_current_country_cmd_fixed_param *cmd; 15538 uint16_t len = sizeof(*cmd); 15539 uint8_t pdev_id = params->pdev_id; 15540 15541 buf = wmi_buf_alloc(wmi_handle, len); 15542 if (!buf) { 15543 qdf_status = QDF_STATUS_E_NOMEM; 15544 goto end; 15545 } 15546 15547 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 15548 WMITLV_SET_HDR(&cmd->tlv_header, 15549 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 15550 WMITLV_GET_STRUCT_TLVLEN 15551 (wmi_set_current_country_cmd_fixed_param)); 15552 15553 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 15554 wmi_handle, 15555 pdev_id); 15556 wmi_debug("setting current country to %s and target pdev_id = %u", 15557 params->country, cmd->pdev_id); 15558 15559 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 15560 15561 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 15562 qdf_status = wmi_unified_cmd_send(wmi_handle, 15563 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 15564 15565 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15566 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 15567 wmi_buf_free(buf); 15568 } 15569 15570 end: 15571 return qdf_status; 15572 } 15573 15574 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 15575 WMI_SET_BITS(alpha, 0, 8, val0); \ 15576 WMI_SET_BITS(alpha, 8, 8, val1); \ 15577 WMI_SET_BITS(alpha, 16, 8, val2); \ 15578 } while (0) 15579 15580 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 15581 uint8_t pdev_id, struct cc_regdmn_s *rd) 15582 { 15583 wmi_set_init_country_cmd_fixed_param *cmd; 15584 uint16_t len; 15585 wmi_buf_t buf; 15586 int ret; 15587 15588 len = sizeof(wmi_set_init_country_cmd_fixed_param); 15589 buf = wmi_buf_alloc(wmi_handle, len); 15590 if (!buf) 15591 return QDF_STATUS_E_NOMEM; 15592 15593 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 15594 WMITLV_SET_HDR(&cmd->tlv_header, 15595 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 15596 WMITLV_GET_STRUCT_TLVLEN 15597 (wmi_set_init_country_cmd_fixed_param)); 15598 15599 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15600 wmi_handle, 15601 pdev_id); 15602 15603 if (rd->flags == CC_IS_SET) { 15604 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 15605 cmd->country_code.country_id = rd->cc.country_code; 15606 } else if (rd->flags == ALPHA_IS_SET) { 15607 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 15608 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 15609 rd->cc.alpha[0], 15610 rd->cc.alpha[1], 15611 rd->cc.alpha[2]); 15612 } else if (rd->flags == REGDMN_IS_SET) { 15613 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 15614 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 15615 rd->cc.regdmn.reg_2g_5g_pair_id); 15616 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 15617 rd->cc.regdmn.sixg_superdmn_id); 15618 } 15619 15620 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 15621 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15622 WMI_SET_INIT_COUNTRY_CMDID); 15623 if (ret) { 15624 wmi_err("Failed to config wow wakeup event"); 15625 wmi_buf_free(buf); 15626 return QDF_STATUS_E_FAILURE; 15627 } 15628 15629 return QDF_STATUS_SUCCESS; 15630 } 15631 15632 /** 15633 * send_obss_detection_cfg_cmd_tlv() - send obss detection 15634 * configurations to firmware. 15635 * @wmi_handle: wmi handle 15636 * @obss_cfg_param: obss detection configurations 15637 * 15638 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 15639 * 15640 * Return: QDF_STATUS 15641 */ 15642 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 15643 struct wmi_obss_detection_cfg_param *obss_cfg_param) 15644 { 15645 wmi_buf_t buf; 15646 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 15647 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 15648 15649 buf = wmi_buf_alloc(wmi_handle, len); 15650 if (!buf) 15651 return QDF_STATUS_E_NOMEM; 15652 15653 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 15654 WMITLV_SET_HDR(&cmd->tlv_header, 15655 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 15656 WMITLV_GET_STRUCT_TLVLEN 15657 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 15658 15659 cmd->vdev_id = obss_cfg_param->vdev_id; 15660 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 15661 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 15662 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 15663 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 15664 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 15665 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 15666 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 15667 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 15668 15669 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 15670 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15671 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 15672 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 15673 wmi_buf_free(buf); 15674 return QDF_STATUS_E_FAILURE; 15675 } 15676 15677 return QDF_STATUS_SUCCESS; 15678 } 15679 15680 /** 15681 * extract_obss_detection_info_tlv() - Extract obss detection info 15682 * received from firmware. 15683 * @evt_buf: pointer to event buffer 15684 * @obss_detection: Pointer to hold obss detection info 15685 * 15686 * Return: QDF_STATUS 15687 */ 15688 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 15689 struct wmi_obss_detect_info 15690 *obss_detection) 15691 { 15692 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 15693 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 15694 15695 if (!obss_detection) { 15696 wmi_err("Invalid obss_detection event buffer"); 15697 return QDF_STATUS_E_INVAL; 15698 } 15699 15700 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 15701 if (!param_buf) { 15702 wmi_err("Invalid evt_buf"); 15703 return QDF_STATUS_E_INVAL; 15704 } 15705 15706 fix_param = param_buf->fixed_param; 15707 obss_detection->vdev_id = fix_param->vdev_id; 15708 obss_detection->matched_detection_masks = 15709 fix_param->matched_detection_masks; 15710 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 15711 &obss_detection->matched_bssid_addr[0]); 15712 switch (fix_param->reason) { 15713 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 15714 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 15715 break; 15716 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 15717 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 15718 break; 15719 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 15720 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 15721 break; 15722 default: 15723 wmi_err("Invalid reason: %d", fix_param->reason); 15724 return QDF_STATUS_E_INVAL; 15725 } 15726 15727 return QDF_STATUS_SUCCESS; 15728 } 15729 15730 /** 15731 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 15732 * @wmi_handle: wmi handle 15733 * @params: pointer to request structure 15734 * 15735 * Return: QDF_STATUS 15736 */ 15737 static QDF_STATUS 15738 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 15739 struct wmi_roam_scan_stats_req *params) 15740 { 15741 wmi_buf_t buf; 15742 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 15743 WMITLV_TAG_ID tag; 15744 uint32_t size; 15745 uint32_t len = sizeof(*cmd); 15746 15747 buf = wmi_buf_alloc(wmi_handle, len); 15748 if (!buf) 15749 return QDF_STATUS_E_FAILURE; 15750 15751 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 15752 15753 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 15754 size = WMITLV_GET_STRUCT_TLVLEN( 15755 wmi_request_roam_scan_stats_cmd_fixed_param); 15756 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 15757 15758 cmd->vdev_id = params->vdev_id; 15759 15760 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 15761 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15762 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 15763 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 15764 wmi_buf_free(buf); 15765 return QDF_STATUS_E_FAILURE; 15766 } 15767 15768 return QDF_STATUS_SUCCESS; 15769 } 15770 15771 /** 15772 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 15773 * channel list from firmware 15774 * @wmi_handle: wmi handler 15775 * @vdev_id: vdev id 15776 * 15777 * Return: QDF_STATUS 15778 */ 15779 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 15780 uint32_t vdev_id) 15781 { 15782 wmi_buf_t buf; 15783 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 15784 uint16_t len = sizeof(*cmd); 15785 int ret; 15786 15787 buf = wmi_buf_alloc(wmi_handle, len); 15788 if (!buf) { 15789 wmi_err("Failed to allocate wmi buffer"); 15790 return QDF_STATUS_E_NOMEM; 15791 } 15792 15793 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 15794 wmi_buf_data(buf); 15795 WMITLV_SET_HDR(&cmd->tlv_header, 15796 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 15797 WMITLV_GET_STRUCT_TLVLEN( 15798 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 15799 cmd->vdev_id = vdev_id; 15800 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 15801 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15802 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 15803 if (QDF_IS_STATUS_ERROR(ret)) { 15804 wmi_err("Failed to send get roam scan channels request = %d", 15805 ret); 15806 wmi_buf_free(buf); 15807 } 15808 return ret; 15809 } 15810 15811 /** 15812 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 15813 * @wmi_handle: wmi handle 15814 * @evt_buf: pointer to event buffer 15815 * @vdev_id: output pointer to hold vdev id 15816 * @res_param: output pointer to hold the allocated response 15817 * 15818 * Return: QDF_STATUS 15819 */ 15820 static QDF_STATUS 15821 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15822 uint32_t *vdev_id, 15823 struct wmi_roam_scan_stats_res **res_param) 15824 { 15825 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 15826 wmi_roam_scan_stats_event_fixed_param *fixed_param; 15827 uint32_t *client_id = NULL; 15828 wmi_roaming_timestamp *timestamp = NULL; 15829 uint32_t *num_channels = NULL; 15830 uint32_t *chan_info = NULL; 15831 wmi_mac_addr *old_bssid = NULL; 15832 uint32_t *is_roaming_success = NULL; 15833 wmi_mac_addr *new_bssid = NULL; 15834 uint32_t *num_roam_candidates = NULL; 15835 wmi_roam_scan_trigger_reason *roam_reason = NULL; 15836 wmi_mac_addr *bssid = NULL; 15837 uint32_t *score = NULL; 15838 uint32_t *channel = NULL; 15839 uint32_t *rssi = NULL; 15840 int chan_idx = 0, cand_idx = 0; 15841 uint32_t total_len; 15842 struct wmi_roam_scan_stats_res *res; 15843 uint32_t i, j; 15844 uint32_t num_scans, scan_param_size; 15845 15846 *res_param = NULL; 15847 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 15848 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 15849 if (!param_buf) { 15850 wmi_err("Invalid roam scan stats event"); 15851 return QDF_STATUS_E_INVAL; 15852 } 15853 15854 fixed_param = param_buf->fixed_param; 15855 15856 num_scans = fixed_param->num_roam_scans; 15857 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 15858 *vdev_id = fixed_param->vdev_id; 15859 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 15860 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 15861 num_scans, WMI_ROAM_SCAN_STATS_MAX); 15862 return QDF_STATUS_E_INVAL; 15863 } 15864 15865 total_len = sizeof(*res) + num_scans * scan_param_size; 15866 15867 res = qdf_mem_malloc(total_len); 15868 if (!res) 15869 return QDF_STATUS_E_NOMEM; 15870 15871 if (!num_scans) { 15872 *res_param = res; 15873 return QDF_STATUS_SUCCESS; 15874 } 15875 15876 if (param_buf->client_id && 15877 param_buf->num_client_id == num_scans) 15878 client_id = param_buf->client_id; 15879 15880 if (param_buf->timestamp && 15881 param_buf->num_timestamp == num_scans) 15882 timestamp = param_buf->timestamp; 15883 15884 if (param_buf->old_bssid && 15885 param_buf->num_old_bssid == num_scans) 15886 old_bssid = param_buf->old_bssid; 15887 15888 if (param_buf->new_bssid && 15889 param_buf->num_new_bssid == num_scans) 15890 new_bssid = param_buf->new_bssid; 15891 15892 if (param_buf->is_roaming_success && 15893 param_buf->num_is_roaming_success == num_scans) 15894 is_roaming_success = param_buf->is_roaming_success; 15895 15896 if (param_buf->roam_reason && 15897 param_buf->num_roam_reason == num_scans) 15898 roam_reason = param_buf->roam_reason; 15899 15900 if (param_buf->num_channels && 15901 param_buf->num_num_channels == num_scans) { 15902 uint32_t count, chan_info_sum = 0; 15903 15904 num_channels = param_buf->num_channels; 15905 for (count = 0; count < param_buf->num_num_channels; count++) { 15906 if (param_buf->num_channels[count] > 15907 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 15908 wmi_err_rl("%u exceeded max scan channels %u", 15909 param_buf->num_channels[count], 15910 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 15911 goto error; 15912 } 15913 chan_info_sum += param_buf->num_channels[count]; 15914 } 15915 15916 if (param_buf->chan_info && 15917 param_buf->num_chan_info == chan_info_sum) 15918 chan_info = param_buf->chan_info; 15919 } 15920 15921 if (param_buf->num_roam_candidates && 15922 param_buf->num_num_roam_candidates == num_scans) { 15923 uint32_t cnt, roam_cand_sum = 0; 15924 15925 num_roam_candidates = param_buf->num_roam_candidates; 15926 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 15927 if (param_buf->num_roam_candidates[cnt] > 15928 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 15929 wmi_err_rl("%u exceeded max scan cand %u", 15930 param_buf->num_roam_candidates[cnt], 15931 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 15932 goto error; 15933 } 15934 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 15935 } 15936 15937 if (param_buf->bssid && 15938 param_buf->num_bssid == roam_cand_sum) 15939 bssid = param_buf->bssid; 15940 15941 if (param_buf->score && 15942 param_buf->num_score == roam_cand_sum) 15943 score = param_buf->score; 15944 15945 if (param_buf->channel && 15946 param_buf->num_channel == roam_cand_sum) 15947 channel = param_buf->channel; 15948 15949 if (param_buf->rssi && 15950 param_buf->num_rssi == roam_cand_sum) 15951 rssi = param_buf->rssi; 15952 } 15953 15954 res->num_roam_scans = num_scans; 15955 for (i = 0; i < num_scans; i++) { 15956 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 15957 15958 if (timestamp) 15959 roam->time_stamp = timestamp[i].lower32bit | 15960 (timestamp[i].upper32bit << 31); 15961 15962 if (client_id) 15963 roam->client_id = client_id[i]; 15964 15965 if (num_channels) { 15966 roam->num_scan_chans = num_channels[i]; 15967 if (chan_info) { 15968 for (j = 0; j < num_channels[i]; j++) 15969 roam->scan_freqs[j] = 15970 chan_info[chan_idx++]; 15971 } 15972 } 15973 15974 if (is_roaming_success) 15975 roam->is_roam_successful = is_roaming_success[i]; 15976 15977 if (roam_reason) { 15978 roam->trigger_id = roam_reason[i].trigger_id; 15979 roam->trigger_value = roam_reason[i].trigger_value; 15980 } 15981 15982 if (num_roam_candidates) { 15983 roam->num_roam_candidates = num_roam_candidates[i]; 15984 15985 for (j = 0; j < num_roam_candidates[i]; j++) { 15986 if (score) 15987 roam->cand[j].score = score[cand_idx]; 15988 if (rssi) 15989 roam->cand[j].rssi = rssi[cand_idx]; 15990 if (channel) 15991 roam->cand[j].freq = 15992 channel[cand_idx]; 15993 15994 if (bssid) 15995 WMI_MAC_ADDR_TO_CHAR_ARRAY( 15996 &bssid[cand_idx], 15997 roam->cand[j].bssid); 15998 15999 cand_idx++; 16000 } 16001 } 16002 16003 if (old_bssid) 16004 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 16005 roam->old_bssid); 16006 16007 if (new_bssid) 16008 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 16009 roam->new_bssid); 16010 } 16011 16012 *res_param = res; 16013 16014 return QDF_STATUS_SUCCESS; 16015 error: 16016 qdf_mem_free(res); 16017 return QDF_STATUS_E_FAILURE; 16018 } 16019 16020 /** 16021 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 16022 * @wmi_handle: wmi handle 16023 * @evt_buf: pointer to event buffer 16024 * @vdev_id: output pointer to hold vdev id 16025 * @tx_status: output pointer to hold the tx_status 16026 * 16027 * Return: QDF_STATUS 16028 */ 16029 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 16030 void *evt_buf, 16031 uint32_t *vdev_id, 16032 uint32_t *tx_status) { 16033 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 16034 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 16035 16036 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 16037 if (!param_buf) { 16038 wmi_err("Invalid offload bcn tx status event buffer"); 16039 return QDF_STATUS_E_INVAL; 16040 } 16041 16042 bcn_tx_status_event = param_buf->fixed_param; 16043 *vdev_id = bcn_tx_status_event->vdev_id; 16044 *tx_status = bcn_tx_status_event->tx_status; 16045 16046 return QDF_STATUS_SUCCESS; 16047 } 16048 16049 #ifdef WLAN_SUPPORT_GREEN_AP 16050 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 16051 uint8_t *evt_buf, 16052 struct wlan_green_ap_egap_status_info *egap_status_info_params) 16053 { 16054 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 16055 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 16056 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 16057 16058 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 16059 if (!param_buf) { 16060 wmi_err("Invalid EGAP Info status event buffer"); 16061 return QDF_STATUS_E_INVAL; 16062 } 16063 16064 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 16065 param_buf->fixed_param; 16066 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 16067 param_buf->chainmask_list; 16068 16069 if (!egap_info_event || !chainmask_event) { 16070 wmi_err("Invalid EGAP Info event or chainmask event"); 16071 return QDF_STATUS_E_INVAL; 16072 } 16073 16074 egap_status_info_params->status = egap_info_event->status; 16075 egap_status_info_params->mac_id = chainmask_event->mac_id; 16076 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 16077 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 16078 16079 return QDF_STATUS_SUCCESS; 16080 } 16081 #endif 16082 16083 /* 16084 * extract_comb_phyerr_tlv() - extract comb phy error from event 16085 * @wmi_handle: wmi handle 16086 * @evt_buf: pointer to event buffer 16087 * @datalen: data length of event buffer 16088 * @buf_offset: Pointer to hold value of current event buffer offset 16089 * post extraction 16090 * @phyerr: Pointer to hold phyerr 16091 * 16092 * Return: QDF_STATUS 16093 */ 16094 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 16095 void *evt_buf, 16096 uint16_t datalen, 16097 uint16_t *buf_offset, 16098 wmi_host_phyerr_t *phyerr) 16099 { 16100 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 16101 wmi_comb_phyerr_rx_hdr *pe_hdr; 16102 16103 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 16104 if (!param_tlvs) { 16105 wmi_debug("Received null data from FW"); 16106 return QDF_STATUS_E_FAILURE; 16107 } 16108 16109 pe_hdr = param_tlvs->hdr; 16110 if (!pe_hdr) { 16111 wmi_debug("Received Data PE Header is NULL"); 16112 return QDF_STATUS_E_FAILURE; 16113 } 16114 16115 /* Ensure it's at least the size of the header */ 16116 if (datalen < sizeof(*pe_hdr)) { 16117 wmi_debug("Expected minimum size %zu, received %d", 16118 sizeof(*pe_hdr), datalen); 16119 return QDF_STATUS_E_FAILURE; 16120 } 16121 16122 phyerr->pdev_id = wmi_handle->ops-> 16123 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 16124 phyerr->tsf64 = pe_hdr->tsf_l32; 16125 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 16126 phyerr->bufp = param_tlvs->bufp; 16127 16128 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 16129 wmi_debug("Invalid buf_len %d, num_bufp %d", 16130 pe_hdr->buf_len, param_tlvs->num_bufp); 16131 return QDF_STATUS_E_FAILURE; 16132 } 16133 16134 phyerr->buf_len = pe_hdr->buf_len; 16135 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 16136 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 16137 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 16138 16139 return QDF_STATUS_SUCCESS; 16140 } 16141 16142 /** 16143 * extract_single_phyerr_tlv() - extract single phy error from event 16144 * @wmi_handle: wmi handle 16145 * @evt_buf: pointer to event buffer 16146 * @datalen: data length of event buffer 16147 * @buf_offset: Pointer to hold value of current event buffer offset 16148 * post extraction 16149 * @phyerr: Pointer to hold phyerr 16150 * 16151 * Return: QDF_STATUS 16152 */ 16153 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 16154 void *evt_buf, 16155 uint16_t datalen, 16156 uint16_t *buf_offset, 16157 wmi_host_phyerr_t *phyerr) 16158 { 16159 wmi_single_phyerr_rx_event *ev; 16160 uint16_t n = *buf_offset; 16161 uint8_t *data = (uint8_t *)evt_buf; 16162 16163 if (n < datalen) { 16164 if ((datalen - n) < sizeof(ev->hdr)) { 16165 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 16166 datalen, n, sizeof(ev->hdr)); 16167 return QDF_STATUS_E_FAILURE; 16168 } 16169 16170 /* 16171 * Obtain a pointer to the beginning of the current event. 16172 * data[0] is the beginning of the WMI payload. 16173 */ 16174 ev = (wmi_single_phyerr_rx_event *)&data[n]; 16175 16176 /* 16177 * Sanity check the buffer length of the event against 16178 * what we currently have. 16179 * 16180 * Since buf_len is 32 bits, we check if it overflows 16181 * a large 32 bit value. It's not 0x7fffffff because 16182 * we increase n by (buf_len + sizeof(hdr)), which would 16183 * in itself cause n to overflow. 16184 * 16185 * If "int" is 64 bits then this becomes a moot point. 16186 */ 16187 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 16188 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 16189 return QDF_STATUS_E_FAILURE; 16190 } 16191 16192 if ((n + ev->hdr.buf_len) > datalen) { 16193 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 16194 n, ev->hdr.buf_len, datalen); 16195 return QDF_STATUS_E_FAILURE; 16196 } 16197 16198 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 16199 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 16200 phyerr->bufp = &ev->bufp[0]; 16201 phyerr->buf_len = ev->hdr.buf_len; 16202 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 16203 16204 /* 16205 * Advance the buffer pointer to the next PHY error. 16206 * buflen is the length of this payload, so we need to 16207 * advance past the current header _AND_ the payload. 16208 */ 16209 n += sizeof(*ev) + ev->hdr.buf_len; 16210 } 16211 *buf_offset = n; 16212 16213 return QDF_STATUS_SUCCESS; 16214 } 16215 16216 /** 16217 * extract_esp_estimation_ev_param_tlv() - extract air time from event 16218 * @wmi_handle: wmi handle 16219 * @evt_buf: pointer to event buffer 16220 * @param: Pointer to hold esp event 16221 * 16222 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 16223 */ 16224 static QDF_STATUS 16225 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 16226 void *evt_buf, 16227 struct esp_estimation_event *param) 16228 { 16229 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 16230 wmi_esp_estimate_event_fixed_param *esp_event; 16231 16232 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 16233 if (!param_buf) { 16234 wmi_err("Invalid ESP Estimate Event buffer"); 16235 return QDF_STATUS_E_INVAL; 16236 } 16237 esp_event = param_buf->fixed_param; 16238 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 16239 16240 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16241 wmi_handle, 16242 esp_event->pdev_id); 16243 16244 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16245 return QDF_STATUS_E_FAILURE; 16246 16247 return QDF_STATUS_SUCCESS; 16248 } 16249 16250 /* 16251 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 16252 * updating bss color change within firmware when AP announces bss color change. 16253 * @wmi_handle: wmi handle 16254 * @vdev_id: vdev ID 16255 * @enable: enable bss color change within firmware 16256 * 16257 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 16258 * 16259 * Return: QDF_STATUS 16260 */ 16261 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 16262 uint32_t vdev_id, 16263 bool enable) 16264 { 16265 wmi_buf_t buf; 16266 wmi_bss_color_change_enable_fixed_param *cmd; 16267 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 16268 16269 buf = wmi_buf_alloc(wmi_handle, len); 16270 if (!buf) 16271 return QDF_STATUS_E_NOMEM; 16272 16273 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 16274 WMITLV_SET_HDR(&cmd->tlv_header, 16275 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 16276 WMITLV_GET_STRUCT_TLVLEN 16277 (wmi_bss_color_change_enable_fixed_param)); 16278 cmd->vdev_id = vdev_id; 16279 cmd->enable = enable; 16280 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 16281 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16282 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 16283 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 16284 wmi_buf_free(buf); 16285 return QDF_STATUS_E_FAILURE; 16286 } 16287 16288 return QDF_STATUS_SUCCESS; 16289 } 16290 16291 /** 16292 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 16293 * configurations to firmware. 16294 * @wmi_handle: wmi handle 16295 * @cfg_param: obss detection configurations 16296 * 16297 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 16298 * 16299 * Return: QDF_STATUS 16300 */ 16301 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 16302 wmi_unified_t wmi_handle, 16303 struct wmi_obss_color_collision_cfg_param *cfg_param) 16304 { 16305 wmi_buf_t buf; 16306 wmi_obss_color_collision_det_config_fixed_param *cmd; 16307 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 16308 16309 buf = wmi_buf_alloc(wmi_handle, len); 16310 if (!buf) 16311 return QDF_STATUS_E_NOMEM; 16312 16313 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 16314 buf); 16315 WMITLV_SET_HDR(&cmd->tlv_header, 16316 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 16317 WMITLV_GET_STRUCT_TLVLEN 16318 (wmi_obss_color_collision_det_config_fixed_param)); 16319 cmd->vdev_id = cfg_param->vdev_id; 16320 cmd->flags = cfg_param->flags; 16321 cmd->current_bss_color = cfg_param->current_bss_color; 16322 cmd->detection_period_ms = cfg_param->detection_period_ms; 16323 cmd->scan_period_ms = cfg_param->scan_period_ms; 16324 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 16325 16326 switch (cfg_param->evt_type) { 16327 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 16328 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 16329 break; 16330 case OBSS_COLOR_COLLISION_DETECTION: 16331 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 16332 break; 16333 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 16334 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 16335 break; 16336 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 16337 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 16338 break; 16339 default: 16340 wmi_err("Invalid event type: %d", cfg_param->evt_type); 16341 wmi_buf_free(buf); 16342 return QDF_STATUS_E_FAILURE; 16343 } 16344 16345 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 16346 "detection_period_ms: %d scan_period_ms: %d " 16347 "free_slot_expiry_timer_ms: %d", 16348 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 16349 cmd->detection_period_ms, cmd->scan_period_ms, 16350 cmd->free_slot_expiry_time_ms); 16351 16352 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 16353 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16354 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 16355 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 16356 cfg_param->vdev_id); 16357 wmi_buf_free(buf); 16358 return QDF_STATUS_E_FAILURE; 16359 } 16360 16361 return QDF_STATUS_SUCCESS; 16362 } 16363 16364 /** 16365 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 16366 * received from firmware. 16367 * @evt_buf: pointer to event buffer 16368 * @info: Pointer to hold bss collision info 16369 * 16370 * Return: QDF_STATUS 16371 */ 16372 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 16373 struct wmi_obss_color_collision_info *info) 16374 { 16375 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 16376 wmi_obss_color_collision_evt_fixed_param *fix_param; 16377 16378 if (!info) { 16379 wmi_err("Invalid obss color buffer"); 16380 return QDF_STATUS_E_INVAL; 16381 } 16382 16383 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 16384 evt_buf; 16385 if (!param_buf) { 16386 wmi_err("Invalid evt_buf"); 16387 return QDF_STATUS_E_INVAL; 16388 } 16389 16390 fix_param = param_buf->fixed_param; 16391 info->vdev_id = fix_param->vdev_id; 16392 info->obss_color_bitmap_bit0to31 = 16393 fix_param->bss_color_bitmap_bit0to31; 16394 info->obss_color_bitmap_bit32to63 = 16395 fix_param->bss_color_bitmap_bit32to63; 16396 16397 switch (fix_param->evt_type) { 16398 case WMI_BSS_COLOR_COLLISION_DISABLE: 16399 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 16400 break; 16401 case WMI_BSS_COLOR_COLLISION_DETECTION: 16402 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 16403 break; 16404 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 16405 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 16406 break; 16407 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 16408 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 16409 break; 16410 default: 16411 wmi_err("Invalid event type: %d, vdev_id: %d", 16412 fix_param->evt_type, fix_param->vdev_id); 16413 return QDF_STATUS_E_FAILURE; 16414 } 16415 16416 return QDF_STATUS_SUCCESS; 16417 } 16418 16419 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 16420 { 16421 struct wmi_ops *ops = wmi_handle->ops; 16422 16423 ops->send_obss_color_collision_cfg_cmd = 16424 send_obss_color_collision_cfg_cmd_tlv; 16425 ops->extract_obss_color_collision_info = 16426 extract_obss_color_collision_info_tlv; 16427 } 16428 16429 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 16430 static QDF_STATUS 16431 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 16432 struct config_fils_params *param) 16433 { 16434 wmi_buf_t buf; 16435 wmi_enable_fils_cmd_fixed_param *cmd; 16436 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 16437 16438 buf = wmi_buf_alloc(wmi_handle, len); 16439 if (!buf) 16440 return QDF_STATUS_E_NOMEM; 16441 16442 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 16443 buf); 16444 WMITLV_SET_HDR(&cmd->tlv_header, 16445 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 16446 WMITLV_GET_STRUCT_TLVLEN 16447 (wmi_enable_fils_cmd_fixed_param)); 16448 cmd->vdev_id = param->vdev_id; 16449 cmd->fd_period = param->fd_period; 16450 if (param->send_prb_rsp_frame) 16451 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 16452 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 16453 cmd->vdev_id, cmd->fd_period, cmd->flags); 16454 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 16455 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16456 WMI_ENABLE_FILS_CMDID)) { 16457 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 16458 wmi_buf_free(buf); 16459 return QDF_STATUS_E_FAILURE; 16460 } 16461 16462 return QDF_STATUS_SUCCESS; 16463 } 16464 #endif 16465 16466 #ifdef WLAN_MWS_INFO_DEBUGFS 16467 /** 16468 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 16469 * 16470 * @wmi_handle: wmi handle 16471 * @vdev_id: vdev id 16472 * @cmd_id: Coex command id 16473 * 16474 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 16475 * 16476 * Return: QDF_STATUS 16477 */ 16478 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 16479 uint32_t vdev_id, 16480 uint32_t cmd_id) 16481 { 16482 wmi_buf_t buf; 16483 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 16484 uint16_t len = sizeof(*cmd); 16485 int ret; 16486 16487 buf = wmi_buf_alloc(wmi_handle, len); 16488 if (!buf) { 16489 wmi_err("Failed to allocate wmi buffer"); 16490 return QDF_STATUS_E_NOMEM; 16491 } 16492 16493 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 16494 WMITLV_SET_HDR(&cmd->tlv_header, 16495 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 16496 WMITLV_GET_STRUCT_TLVLEN 16497 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 16498 cmd->vdev_id = vdev_id; 16499 cmd->cmd_id = cmd_id; 16500 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 16501 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16502 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 16503 if (QDF_IS_STATUS_ERROR(ret)) { 16504 wmi_err("Failed to send set param command ret = %d", ret); 16505 wmi_buf_free(buf); 16506 } 16507 return ret; 16508 } 16509 #endif 16510 16511 #ifdef FEATURE_MEC_OFFLOAD 16512 static QDF_STATUS 16513 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 16514 struct set_mec_timer_params *param) 16515 { 16516 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 16517 wmi_buf_t buf; 16518 int32_t len = sizeof(*cmd); 16519 16520 buf = wmi_buf_alloc(wmi_handle, len); 16521 if (!buf) { 16522 wmi_err("wmi_buf_alloc failed"); 16523 return QDF_STATUS_E_FAILURE; 16524 } 16525 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 16526 wmi_buf_data(buf); 16527 WMITLV_SET_HDR(&cmd->tlv_header, 16528 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 16529 WMITLV_GET_STRUCT_TLVLEN( 16530 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 16531 cmd->pdev_id = param->pdev_id; 16532 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 16533 16534 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 16535 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16536 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 16537 wmi_err("Failed to set mec aging timer param"); 16538 wmi_buf_free(buf); 16539 return QDF_STATUS_E_FAILURE; 16540 } 16541 16542 return QDF_STATUS_SUCCESS; 16543 } 16544 #endif 16545 16546 #ifdef WIFI_POS_CONVERGED 16547 /** 16548 * extract_oem_response_param_tlv() - Extract oem response params 16549 * @wmi_handle: wmi handle 16550 * @resp_buf: response buffer 16551 * @oem_resp_param: pointer to hold oem response params 16552 * 16553 * Return: QDF_STATUS_SUCCESS on success or proper error code. 16554 */ 16555 static QDF_STATUS 16556 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 16557 struct wmi_oem_response_param *oem_resp_param) 16558 { 16559 uint64_t temp_addr; 16560 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 16561 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 16562 16563 if (!param_buf) { 16564 wmi_err("Invalid OEM response"); 16565 return QDF_STATUS_E_INVAL; 16566 } 16567 16568 if (param_buf->num_data) { 16569 oem_resp_param->num_data1 = param_buf->num_data; 16570 oem_resp_param->data_1 = param_buf->data; 16571 } 16572 16573 if (param_buf->num_data2) { 16574 oem_resp_param->num_data2 = param_buf->num_data2; 16575 oem_resp_param->data_2 = param_buf->data2; 16576 } 16577 16578 if (param_buf->indirect_data) { 16579 oem_resp_param->indirect_data.pdev_id = 16580 param_buf->indirect_data->pdev_id; 16581 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 16582 oem_resp_param->indirect_data.addr = 16583 param_buf->indirect_data->addr_lo + 16584 ((uint64_t)temp_addr << 32); 16585 oem_resp_param->indirect_data.len = 16586 param_buf->indirect_data->len; 16587 } 16588 16589 return QDF_STATUS_SUCCESS; 16590 } 16591 #endif /* WIFI_POS_CONVERGED */ 16592 16593 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 16594 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 16595 16596 static QDF_STATUS 16597 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16598 struct wifi_pos_pasn_peer_data *dst) 16599 { 16600 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 16601 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 16602 wmi_rtt_pasn_peer_create_req_param *buf; 16603 uint8_t security_mode, i; 16604 16605 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 16606 if (!param_buf) { 16607 wmi_err("Invalid peer_create req buffer"); 16608 return QDF_STATUS_E_INVAL; 16609 } 16610 16611 fixed_param = param_buf->fixed_param; 16612 16613 if (param_buf->num_rtt_pasn_peer_param > 16614 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 16615 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 16616 wmi_err("Invalid TLV size"); 16617 return QDF_STATUS_E_INVAL; 16618 } 16619 16620 if (!param_buf->num_rtt_pasn_peer_param || 16621 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 16622 wmi_err("Invalid num TLV:%d", 16623 param_buf->num_rtt_pasn_peer_param); 16624 return QDF_STATUS_E_INVAL; 16625 } 16626 16627 dst->vdev_id = fixed_param->vdev_id; 16628 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 16629 wmi_err("Invalid vdev id:%d", dst->vdev_id); 16630 return QDF_STATUS_E_INVAL; 16631 } 16632 16633 buf = param_buf->rtt_pasn_peer_param; 16634 if (!buf) { 16635 wmi_err("NULL peer param TLV"); 16636 return QDF_STATUS_E_INVAL; 16637 } 16638 16639 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 16640 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 16641 dst->peer_info[i].self_mac.bytes); 16642 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 16643 dst->peer_info[i].peer_mac.bytes); 16644 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 16645 buf->control_flag); 16646 if (security_mode) 16647 dst->peer_info[i].peer_type = 16648 WLAN_WIFI_POS_PASN_SECURE_PEER; 16649 else 16650 dst->peer_info[i].peer_type = 16651 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 16652 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 16653 dst->peer_info[i].is_ltf_keyseed_required = true; 16654 16655 dst->peer_info[i].force_self_mac_usage = 16656 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 16657 buf->control_flag); 16658 dst->num_peers++; 16659 buf++; 16660 } 16661 16662 return QDF_STATUS_SUCCESS; 16663 } 16664 16665 static QDF_STATUS 16666 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16667 struct wifi_pos_pasn_peer_data *dst) 16668 { 16669 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 16670 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 16671 wmi_rtt_pasn_peer_delete_param *buf; 16672 uint8_t i; 16673 16674 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 16675 if (!param_buf) { 16676 wmi_err("Invalid peer_delete evt buffer"); 16677 return QDF_STATUS_E_INVAL; 16678 } 16679 16680 fixed_param = param_buf->fixed_param; 16681 16682 if (param_buf->num_rtt_pasn_peer_param > 16683 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 16684 sizeof(wmi_rtt_pasn_peer_delete_param))) { 16685 wmi_err("Invalid TLV size"); 16686 return QDF_STATUS_E_INVAL; 16687 } 16688 16689 if (!param_buf->num_rtt_pasn_peer_param || 16690 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 16691 wmi_err("Invalid num TLV:%d", 16692 param_buf->num_rtt_pasn_peer_param); 16693 return QDF_STATUS_E_INVAL; 16694 } 16695 16696 dst->vdev_id = fixed_param->vdev_id; 16697 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 16698 wmi_err("Invalid vdev id:%d", dst->vdev_id); 16699 return QDF_STATUS_E_INVAL; 16700 } 16701 16702 buf = param_buf->rtt_pasn_peer_param; 16703 if (!buf) { 16704 wmi_err("NULL peer param TLV"); 16705 return QDF_STATUS_E_INVAL; 16706 } 16707 16708 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 16709 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 16710 dst->peer_info[i].peer_mac.bytes); 16711 dst->peer_info[i].control_flags = buf->control_flag; 16712 16713 dst->num_peers++; 16714 buf++; 16715 } 16716 16717 return QDF_STATUS_SUCCESS; 16718 } 16719 16720 static QDF_STATUS 16721 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 16722 struct wlan_pasn_auth_status *data) 16723 { 16724 QDF_STATUS status; 16725 wmi_buf_t buf; 16726 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 16727 uint8_t *buf_ptr; 16728 uint8_t i; 16729 size_t len = sizeof(*fixed_param) + 16730 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 16731 WMI_TLV_HDR_SIZE; 16732 16733 buf = wmi_buf_alloc(wmi_handle, len); 16734 if (!buf) { 16735 wmi_err("wmi_buf_alloc failed"); 16736 return QDF_STATUS_E_FAILURE; 16737 } 16738 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16739 fixed_param = 16740 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 16741 WMITLV_SET_HDR(&fixed_param->tlv_header, 16742 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 16743 WMITLV_GET_STRUCT_TLVLEN( 16744 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 16745 buf_ptr += sizeof(*fixed_param); 16746 16747 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 16748 (data->num_peers * 16749 sizeof(wmi_rtt_pasn_auth_status_param))); 16750 buf_ptr += WMI_TLV_HDR_SIZE; 16751 16752 for (i = 0; i < data->num_peers; i++) { 16753 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 16754 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 16755 16756 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 16757 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 16758 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 16759 16760 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 16761 &auth_status_tlv->peer_mac_addr); 16762 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 16763 &auth_status_tlv->source_mac_addr); 16764 auth_status_tlv->status = data->auth_status[i].status; 16765 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 16766 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 16767 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 16768 auth_status_tlv->status); 16769 16770 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 16771 } 16772 16773 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 16774 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16775 WMI_RTT_PASN_AUTH_STATUS_CMD); 16776 if (QDF_IS_STATUS_ERROR(status)) { 16777 wmi_err("Failed to send Auth status command ret = %d", status); 16778 wmi_buf_free(buf); 16779 } 16780 16781 return status; 16782 } 16783 16784 static QDF_STATUS 16785 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 16786 struct qdf_mac_addr *peer_mac) 16787 { 16788 QDF_STATUS status; 16789 wmi_buf_t buf; 16790 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 16791 size_t len = sizeof(*fixed_param); 16792 16793 buf = wmi_buf_alloc(wmi_handle, len); 16794 if (!buf) { 16795 wmi_err("wmi_buf_alloc failed"); 16796 return QDF_STATUS_E_FAILURE; 16797 } 16798 fixed_param = 16799 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 16800 WMITLV_SET_HDR(&fixed_param->tlv_header, 16801 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 16802 WMITLV_GET_STRUCT_TLVLEN( 16803 wmi_rtt_pasn_deauth_cmd_fixed_param)); 16804 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 16805 &fixed_param->peer_mac_addr); 16806 16807 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 16808 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16809 WMI_RTT_PASN_DEAUTH_CMD); 16810 if (QDF_IS_STATUS_ERROR(status)) { 16811 wmi_err("Failed to send pasn deauth command ret = %d", status); 16812 wmi_buf_free(buf); 16813 } 16814 16815 return status; 16816 } 16817 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 16818 16819 static QDF_STATUS 16820 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 16821 struct wlan_crypto_ltf_keyseed_data *data) 16822 { 16823 QDF_STATUS status; 16824 wmi_buf_t buf; 16825 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 16826 uint8_t *buf_ptr; 16827 size_t len = sizeof(*fixed_param) + data->key_seed_len + 16828 WMI_TLV_HDR_SIZE; 16829 16830 buf = wmi_buf_alloc(wmi_handle, len); 16831 if (!buf) { 16832 wmi_err("wmi_buf_alloc failed"); 16833 return QDF_STATUS_E_FAILURE; 16834 } 16835 16836 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16837 fixed_param = 16838 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 16839 WMITLV_SET_HDR(&fixed_param->tlv_header, 16840 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 16841 WMITLV_GET_STRUCT_TLVLEN( 16842 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 16843 16844 fixed_param->vdev_id = data->vdev_id; 16845 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 16846 &fixed_param->peer_macaddr); 16847 fixed_param->key_seed_len = data->key_seed_len; 16848 fixed_param->rsn_authmode = data->rsn_authmode; 16849 16850 buf_ptr += sizeof(*fixed_param); 16851 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 16852 (fixed_param->key_seed_len * sizeof(A_UINT8))); 16853 buf_ptr += WMI_TLV_HDR_SIZE; 16854 16855 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 16856 16857 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 16858 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16859 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 16860 if (QDF_IS_STATUS_ERROR(status)) { 16861 wmi_err("Failed to send ltf keyseed command ret = %d", status); 16862 wmi_buf_free(buf); 16863 } 16864 16865 return status; 16866 } 16867 16868 /** 16869 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 16870 * @wmi_handle: wmi handle 16871 * @event_buf: pointer to event buffer 16872 * @cmd_status: status of HW mode change command 16873 * 16874 * Return QDF_STATUS_SUCCESS on success or proper error code. 16875 */ 16876 static QDF_STATUS 16877 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16878 uint32_t *cmd_status) 16879 { 16880 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 16881 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 16882 16883 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 16884 if (!param_buf) { 16885 wmi_err("Invalid mode change event buffer"); 16886 return QDF_STATUS_E_INVAL; 16887 } 16888 16889 fixed_param = param_buf->fixed_param; 16890 if (!fixed_param) { 16891 wmi_err("Invalid fixed param"); 16892 return QDF_STATUS_E_INVAL; 16893 } 16894 16895 *cmd_status = fixed_param->status; 16896 return QDF_STATUS_SUCCESS; 16897 } 16898 16899 #ifdef FEATURE_ANI_LEVEL_REQUEST 16900 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 16901 uint32_t *freqs, 16902 uint8_t num_freqs) 16903 { 16904 wmi_buf_t buf; 16905 wmi_get_channel_ani_cmd_fixed_param *cmd; 16906 QDF_STATUS ret; 16907 uint32_t len; 16908 A_UINT32 *chan_list; 16909 uint8_t i, *buf_ptr; 16910 16911 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 16912 WMI_TLV_HDR_SIZE + 16913 num_freqs * sizeof(A_UINT32); 16914 16915 buf = wmi_buf_alloc(wmi_handle, len); 16916 if (!buf) 16917 return QDF_STATUS_E_FAILURE; 16918 16919 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16920 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 16921 WMITLV_SET_HDR(&cmd->tlv_header, 16922 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 16923 WMITLV_GET_STRUCT_TLVLEN( 16924 wmi_get_channel_ani_cmd_fixed_param)); 16925 16926 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 16927 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16928 (num_freqs * sizeof(A_UINT32))); 16929 16930 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 16931 for (i = 0; i < num_freqs; i++) { 16932 chan_list[i] = freqs[i]; 16933 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 16934 } 16935 16936 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16937 WMI_GET_CHANNEL_ANI_CMDID); 16938 16939 if (QDF_IS_STATUS_ERROR(ret)) { 16940 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 16941 wmi_buf_free(buf); 16942 } 16943 16944 return ret; 16945 } 16946 16947 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 16948 struct wmi_host_ani_level_event **info, 16949 uint32_t *num_freqs) 16950 { 16951 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 16952 wmi_get_channel_ani_event_fixed_param *fixed_param; 16953 wmi_channel_ani_info_tlv_param *tlv_params; 16954 uint8_t *buf_ptr, i; 16955 16956 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 16957 if (!param_buf) { 16958 wmi_err("Invalid ani level event buffer"); 16959 return QDF_STATUS_E_INVAL; 16960 } 16961 16962 fixed_param = 16963 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 16964 if (!fixed_param) { 16965 wmi_err("Invalid fixed param"); 16966 return QDF_STATUS_E_INVAL; 16967 } 16968 16969 buf_ptr = (uint8_t *)fixed_param; 16970 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 16971 buf_ptr += WMI_TLV_HDR_SIZE; 16972 16973 *num_freqs = param_buf->num_ani_info; 16974 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 16975 wmi_err("Invalid number of freqs received"); 16976 return QDF_STATUS_E_INVAL; 16977 } 16978 16979 *info = qdf_mem_malloc(*num_freqs * 16980 sizeof(struct wmi_host_ani_level_event)); 16981 if (!(*info)) 16982 return QDF_STATUS_E_NOMEM; 16983 16984 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 16985 for (i = 0; i < param_buf->num_ani_info; i++) { 16986 (*info)[i].ani_level = tlv_params->ani_level; 16987 (*info)[i].chan_freq = tlv_params->chan_freq; 16988 tlv_params++; 16989 } 16990 16991 return QDF_STATUS_SUCCESS; 16992 } 16993 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 16994 16995 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 16996 /** 16997 * convert_wtc_scan_mode() - Function to convert TLV specific 16998 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 16999 * @scan_mode: scan freq scheme coming from firmware 17000 * 17001 * Return: ROAM_TRIGGER_SCAN_MODE 17002 */ 17003 static enum roam_scan_freq_scheme 17004 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 17005 { 17006 switch (scan_mode) { 17007 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 17008 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 17009 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 17010 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 17011 case ROAM_TRIGGER_SCAN_MODE_FULL: 17012 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 17013 default: 17014 return ROAM_SCAN_FREQ_SCHEME_NONE; 17015 } 17016 } 17017 17018 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 17019 { 17020 switch (fw_trig_reason) { 17021 case WMI_ROAM_TRIGGER_REASON_NONE: 17022 return ROAM_TRIGGER_REASON_NONE; 17023 case WMI_ROAM_TRIGGER_REASON_PER: 17024 return ROAM_TRIGGER_REASON_PER; 17025 case WMI_ROAM_TRIGGER_REASON_BMISS: 17026 return ROAM_TRIGGER_REASON_BMISS; 17027 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 17028 return ROAM_TRIGGER_REASON_LOW_RSSI; 17029 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 17030 return ROAM_TRIGGER_REASON_HIGH_RSSI; 17031 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 17032 return ROAM_TRIGGER_REASON_PERIODIC; 17033 case WMI_ROAM_TRIGGER_REASON_MAWC: 17034 return ROAM_TRIGGER_REASON_MAWC; 17035 case WMI_ROAM_TRIGGER_REASON_DENSE: 17036 return ROAM_TRIGGER_REASON_DENSE; 17037 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 17038 return ROAM_TRIGGER_REASON_BACKGROUND; 17039 case WMI_ROAM_TRIGGER_REASON_FORCED: 17040 return ROAM_TRIGGER_REASON_FORCED; 17041 case WMI_ROAM_TRIGGER_REASON_BTM: 17042 return ROAM_TRIGGER_REASON_BTM; 17043 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 17044 return ROAM_TRIGGER_REASON_UNIT_TEST; 17045 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 17046 return ROAM_TRIGGER_REASON_BSS_LOAD; 17047 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 17048 return ROAM_TRIGGER_REASON_DEAUTH; 17049 case WMI_ROAM_TRIGGER_REASON_IDLE: 17050 return ROAM_TRIGGER_REASON_IDLE; 17051 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 17052 return ROAM_TRIGGER_REASON_STA_KICKOUT; 17053 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 17054 return ROAM_TRIGGER_REASON_ESS_RSSI; 17055 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 17056 return ROAM_TRIGGER_REASON_WTC_BTM; 17057 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 17058 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 17059 case WMI_ROAM_TRIGGER_REASON_BTC: 17060 return ROAM_TRIGGER_REASON_BTC; 17061 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 17062 return ROAM_TRIGGER_REASON_MAX; 17063 default: 17064 return ROAM_TRIGGER_REASON_NONE; 17065 } 17066 } 17067 17068 /** 17069 * extract_roam_11kv_candidate_info - Extract btm candidate info 17070 * @wmi_handle: wmi_handle 17071 * @evt_buf: Event buffer 17072 * @dst_info: Destination buffer 17073 * 17074 * Return: QDF_STATUS 17075 */ 17076 static QDF_STATUS 17077 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 17078 struct wmi_btm_req_candidate_info *dst_info, 17079 uint8_t btm_idx, uint16_t num_cand) 17080 { 17081 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17082 wmi_roam_btm_request_candidate_info *src_data; 17083 uint8_t i; 17084 17085 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17086 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 17087 !param_buf->num_roam_btm_request_candidate_info || 17088 (btm_idx + 17089 num_cand) > param_buf->num_roam_btm_request_candidate_info) 17090 return QDF_STATUS_SUCCESS; 17091 17092 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 17093 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 17094 num_cand = WLAN_MAX_BTM_CANDIDATE; 17095 for (i = 0; i < num_cand; i++) { 17096 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 17097 dst_info->candidate_bssid.bytes); 17098 dst_info->preference = src_data->preference; 17099 src_data++; 17100 dst_info++; 17101 } 17102 17103 return QDF_STATUS_SUCCESS; 17104 } 17105 17106 static enum roam_trigger_sub_reason 17107 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 17108 { 17109 switch (subreason) { 17110 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 17111 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 17112 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 17113 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 17114 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 17115 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 17116 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 17117 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 17118 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 17119 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 17120 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 17121 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 17122 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 17123 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 17124 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 17125 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 17126 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 17127 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 17128 default: 17129 break; 17130 } 17131 17132 return 0; 17133 } 17134 17135 /** 17136 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 17137 * from the WMI_ROAM_STATS_EVENTID 17138 * @wmi_handle: wmi handle 17139 * @evt_buf: Pointer to the event buffer 17140 * @trig: Pointer to destination structure to fill data 17141 * @idx: TLV id 17142 */ 17143 static QDF_STATUS 17144 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17145 struct wmi_roam_trigger_info *trig, uint8_t idx, 17146 uint8_t btm_idx) 17147 { 17148 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17149 wmi_roam_trigger_reason *src_data = NULL; 17150 uint32_t trig_reason; 17151 17152 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17153 if (!param_buf || !param_buf->roam_trigger_reason) 17154 return QDF_STATUS_E_FAILURE; 17155 17156 src_data = ¶m_buf->roam_trigger_reason[idx]; 17157 17158 trig->present = true; 17159 trig_reason = src_data->trigger_reason; 17160 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 17161 trig->trigger_sub_reason = 17162 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 17163 trig->current_rssi = src_data->current_rssi; 17164 trig->timestamp = src_data->timestamp; 17165 17166 switch (trig_reason) { 17167 case WMI_ROAM_TRIGGER_REASON_PER: 17168 case WMI_ROAM_TRIGGER_REASON_BMISS: 17169 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 17170 case WMI_ROAM_TRIGGER_REASON_MAWC: 17171 case WMI_ROAM_TRIGGER_REASON_DENSE: 17172 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 17173 case WMI_ROAM_TRIGGER_REASON_IDLE: 17174 case WMI_ROAM_TRIGGER_REASON_FORCED: 17175 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 17176 case WMI_ROAM_TRIGGER_REASON_BTC: 17177 return QDF_STATUS_SUCCESS; 17178 17179 case WMI_ROAM_TRIGGER_REASON_BTM: 17180 trig->btm_trig_data.btm_request_mode = 17181 src_data->btm_request_mode; 17182 trig->btm_trig_data.disassoc_timer = 17183 src_data->disassoc_imminent_timer; 17184 trig->btm_trig_data.validity_interval = 17185 src_data->validity_internal; 17186 trig->btm_trig_data.candidate_list_count = 17187 src_data->candidate_list_count; 17188 trig->btm_trig_data.btm_resp_status = 17189 src_data->btm_response_status_code; 17190 trig->btm_trig_data.btm_bss_termination_timeout = 17191 src_data->btm_bss_termination_timeout; 17192 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 17193 src_data->btm_mbo_assoc_retry_timeout; 17194 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 17195 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 17196 param_buf->num_roam_btm_request_candidate_info) 17197 extract_roam_11kv_candidate_info( 17198 wmi_handle, evt_buf, 17199 trig->btm_trig_data.btm_cand, 17200 btm_idx, 17201 src_data->candidate_list_count); 17202 17203 return QDF_STATUS_SUCCESS; 17204 17205 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 17206 trig->cu_trig_data.cu_load = src_data->cu_load; 17207 return QDF_STATUS_SUCCESS; 17208 17209 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 17210 trig->deauth_trig_data.type = src_data->deauth_type; 17211 trig->deauth_trig_data.reason = src_data->deauth_reason; 17212 return QDF_STATUS_SUCCESS; 17213 17214 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 17215 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 17216 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 17217 return QDF_STATUS_SUCCESS; 17218 17219 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 17220 trig->wtc_btm_trig_data.roaming_mode = 17221 src_data->vendor_specific1[0]; 17222 trig->wtc_btm_trig_data.vsie_trigger_reason = 17223 src_data->vendor_specific1[1]; 17224 trig->wtc_btm_trig_data.sub_code = 17225 src_data->vendor_specific1[2]; 17226 trig->wtc_btm_trig_data.wtc_mode = 17227 src_data->vendor_specific1[3]; 17228 trig->wtc_btm_trig_data.wtc_scan_mode = 17229 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 17230 trig->wtc_btm_trig_data.wtc_rssi_th = 17231 src_data->vendor_specific1[5]; 17232 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 17233 src_data->vendor_specific1[6]; 17234 17235 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 17236 src_data->vendor_specific2[0]; 17237 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 17238 src_data->vendor_specific2[1]; 17239 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 17240 src_data->vendor_specific2[2]; 17241 trig->wtc_btm_trig_data.duration = 17242 src_data->vendor_specific2[3]; 17243 17244 return QDF_STATUS_SUCCESS; 17245 default: 17246 return QDF_STATUS_SUCCESS; 17247 } 17248 17249 return QDF_STATUS_SUCCESS; 17250 } 17251 17252 /** 17253 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 17254 * from the WMI_ROAM_STATS_EVENTID 17255 * @wmi_handle: wmi handle 17256 * @evt_buf: Pointer to the event buffer 17257 * @dst: Pointer to destination structure to fill data 17258 * @ap_idx: TLV index for this roam scan 17259 * @num_cand: number of candidates list in the roam scan 17260 */ 17261 static QDF_STATUS 17262 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17263 struct wmi_roam_candidate_info *dst, 17264 uint8_t ap_idx, uint16_t num_cand) 17265 { 17266 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17267 wmi_roam_ap_info *src = NULL; 17268 uint8_t i; 17269 17270 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17271 if (!param_buf) { 17272 wmi_err("Param buf is NULL"); 17273 return QDF_STATUS_E_FAILURE; 17274 } 17275 17276 if (ap_idx >= param_buf->num_roam_ap_info) { 17277 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 17278 ap_idx, param_buf->num_roam_ap_info); 17279 return QDF_STATUS_E_FAILURE; 17280 } 17281 17282 src = ¶m_buf->roam_ap_info[ap_idx]; 17283 17284 for (i = 0; i < num_cand; i++) { 17285 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 17286 dst->type = src->candidate_type; 17287 dst->freq = src->channel; 17288 dst->etp = src->etp; 17289 dst->rssi = src->rssi; 17290 dst->rssi_score = src->rssi_score; 17291 dst->cu_load = src->cu_load; 17292 dst->cu_score = src->cu_score; 17293 dst->total_score = src->total_score; 17294 dst->timestamp = src->timestamp; 17295 dst->dl_reason = src->bl_reason; 17296 dst->dl_source = src->bl_source; 17297 dst->dl_timestamp = src->bl_timestamp; 17298 dst->dl_original_timeout = src->bl_original_timeout; 17299 17300 src++; 17301 dst++; 17302 } 17303 17304 return QDF_STATUS_SUCCESS; 17305 } 17306 17307 /** 17308 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 17309 * from the WMI_ROAM_STATS_EVENTID 17310 * @wmi_handle: wmi handle 17311 * @evt_buf: Pointer to the event buffer 17312 * @dst: Pointer to destination structure to fill data 17313 * @idx: TLV id 17314 * @chan_idx: Index of the channel tlv for the current roam trigger 17315 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 17316 */ 17317 static QDF_STATUS 17318 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17319 struct wmi_roam_scan_data *dst, uint8_t idx, 17320 uint8_t chan_idx, uint8_t ap_idx) 17321 { 17322 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17323 wmi_roam_scan_info *src_data = NULL; 17324 wmi_roam_scan_channel_info *src_chan = NULL; 17325 QDF_STATUS status; 17326 uint8_t i; 17327 17328 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17329 if (!param_buf || !param_buf->roam_scan_info || 17330 idx >= param_buf->num_roam_scan_info) 17331 return QDF_STATUS_E_FAILURE; 17332 17333 src_data = ¶m_buf->roam_scan_info[idx]; 17334 17335 dst->present = true; 17336 dst->type = src_data->roam_scan_type; 17337 dst->num_chan = src_data->roam_scan_channel_count; 17338 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 17339 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 17340 dst->frame_info_count = src_data->frame_info_count; 17341 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 17342 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 17343 17344 /* Read the channel data only for dst->type is 0 (partial scan) */ 17345 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 17346 chan_idx < param_buf->num_roam_scan_chan_info) { 17347 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 17348 dst->num_chan = MAX_ROAM_SCAN_CHAN; 17349 17350 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 17351 for (i = 0; i < dst->num_chan; i++) { 17352 dst->chan_freq[i] = src_chan->channel; 17353 src_chan++; 17354 } 17355 } 17356 17357 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 17358 return QDF_STATUS_SUCCESS; 17359 17360 dst->num_ap = src_data->roam_ap_count; 17361 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 17362 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 17363 17364 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 17365 ap_idx, dst->num_ap); 17366 if (QDF_IS_STATUS_ERROR(status)) { 17367 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 17368 return status; 17369 } 17370 17371 return QDF_STATUS_SUCCESS; 17372 } 17373 17374 /** 17375 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 17376 * @wmi_roam_fail_reason: roam fail enum 17377 * 17378 * Return: Roaming failure reason codes 17379 */ 17380 static enum wlan_roam_failure_reason_code 17381 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 17382 { 17383 switch (wmi_roam_fail_reason) { 17384 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 17385 return ROAM_FAIL_REASON_NO_SCAN_START; 17386 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 17387 return ROAM_FAIL_REASON_NO_AP_FOUND; 17388 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 17389 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 17390 case WMI_ROAM_FAIL_REASON_HOST: 17391 return ROAM_FAIL_REASON_HOST; 17392 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 17393 return ROAM_FAIL_REASON_AUTH_SEND; 17394 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 17395 return ROAM_FAIL_REASON_AUTH_RECV; 17396 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 17397 return ROAM_FAIL_REASON_NO_AUTH_RESP; 17398 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 17399 return ROAM_FAIL_REASON_REASSOC_SEND; 17400 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 17401 return ROAM_FAIL_REASON_REASSOC_RECV; 17402 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 17403 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 17404 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 17405 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 17406 case WMI_ROAM_FAIL_REASON_MLME: 17407 return ROAM_FAIL_REASON_MLME; 17408 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 17409 return ROAM_FAIL_REASON_INTERNAL_ABORT; 17410 case WMI_ROAM_FAIL_REASON_SCAN_START: 17411 return ROAM_FAIL_REASON_SCAN_START; 17412 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 17413 return ROAM_FAIL_REASON_AUTH_NO_ACK; 17414 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 17415 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 17416 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 17417 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 17418 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 17419 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 17420 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 17421 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 17422 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 17423 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 17424 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 17425 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 17426 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 17427 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 17428 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 17429 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 17430 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 17431 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 17432 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 17433 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 17434 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 17435 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 17436 case WMI_ROAM_FAIL_REASON_DISCONNECT: 17437 return ROAM_FAIL_REASON_DISCONNECT; 17438 case WMI_ROAM_FAIL_REASON_SYNC: 17439 return ROAM_FAIL_REASON_SYNC; 17440 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 17441 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 17442 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 17443 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 17444 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 17445 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 17446 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 17447 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 17448 default: 17449 return ROAM_FAIL_REASON_UNKNOWN; 17450 } 17451 } 17452 17453 /** 17454 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 17455 * from the WMI_ROAM_STATS_EVENTID 17456 * @wmi_handle: wmi handle 17457 * @evt_buf: Pointer to the event buffer 17458 * @dst: Pointer to destination structure to fill data 17459 * @idx: TLV id 17460 */ 17461 static QDF_STATUS 17462 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17463 struct wmi_roam_result *dst, uint8_t idx) 17464 { 17465 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17466 wmi_roam_result *src_data = NULL; 17467 17468 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17469 if (!param_buf || !param_buf->roam_result || 17470 idx >= param_buf->num_roam_result) 17471 return QDF_STATUS_E_FAILURE; 17472 17473 src_data = ¶m_buf->roam_result[idx]; 17474 17475 dst->present = true; 17476 dst->status = src_data->roam_status; 17477 dst->timestamp = src_data->timestamp; 17478 dst->fail_reason = 17479 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 17480 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 17481 17482 return QDF_STATUS_SUCCESS; 17483 } 17484 17485 /** 17486 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 17487 * from the WMI_ROAM_STATS_EVENTID 17488 * @wmi_handle: wmi handle 17489 * @evt_buf: Pointer to the event buffer 17490 * @dst: Pointer to destination structure to fill data 17491 * @idx: TLV id 17492 * @rpt_idx: Neighbor report Channel index 17493 */ 17494 static QDF_STATUS 17495 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17496 struct wmi_neighbor_report_data *dst, 17497 uint8_t idx, uint8_t rpt_idx) 17498 { 17499 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17500 wmi_roam_neighbor_report_info *src_data = NULL; 17501 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 17502 uint8_t i; 17503 17504 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17505 if (!param_buf || !param_buf->roam_neighbor_report_info || 17506 !param_buf->num_roam_neighbor_report_info || 17507 idx >= param_buf->num_roam_neighbor_report_info) { 17508 wmi_debug("Invalid 1kv param buf"); 17509 return QDF_STATUS_E_FAILURE; 17510 } 17511 17512 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 17513 17514 dst->present = true; 17515 dst->req_type = src_data->request_type; 17516 dst->num_freq = src_data->neighbor_report_channel_count; 17517 dst->req_time = src_data->neighbor_report_request_timestamp; 17518 dst->resp_time = src_data->neighbor_report_response_timestamp; 17519 dst->btm_query_token = src_data->btm_query_token; 17520 dst->btm_query_reason = src_data->btm_query_reason_code; 17521 17522 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 17523 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 17524 return QDF_STATUS_SUCCESS; 17525 17526 if (!param_buf->roam_neighbor_report_chan_info) { 17527 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 17528 dst->num_freq); 17529 dst->num_freq = 0; 17530 /* return success as its optional tlv and we can print neighbor 17531 * report received info 17532 */ 17533 return QDF_STATUS_SUCCESS; 17534 } 17535 17536 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 17537 17538 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 17539 dst->num_freq = MAX_ROAM_SCAN_CHAN; 17540 17541 for (i = 0; i < dst->num_freq; i++) { 17542 dst->freq[i] = src_freq->channel; 17543 src_freq++; 17544 } 17545 17546 return QDF_STATUS_SUCCESS; 17547 } 17548 17549 /** 17550 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 17551 * @wmi_handle : handle to WMI. 17552 * @roam_param : pointer to hold roam set parameter 17553 * 17554 * Return: 0 on success and -ve on failure. 17555 */ 17556 static QDF_STATUS 17557 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 17558 struct vdev_set_params *roam_param) 17559 { 17560 QDF_STATUS ret; 17561 wmi_roam_set_param_cmd_fixed_param *cmd; 17562 wmi_buf_t buf; 17563 uint16_t len = sizeof(*cmd); 17564 17565 buf = wmi_buf_alloc(wmi_handle, len); 17566 if (!buf) 17567 return QDF_STATUS_E_NOMEM; 17568 17569 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 17570 WMITLV_SET_HDR(&cmd->tlv_header, 17571 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 17572 WMITLV_GET_STRUCT_TLVLEN 17573 (wmi_roam_set_param_cmd_fixed_param)); 17574 cmd->vdev_id = roam_param->vdev_id; 17575 cmd->param_id = roam_param->param_id; 17576 cmd->param_value = roam_param->param_value; 17577 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 17578 cmd->vdev_id, cmd->param_id, cmd->param_value); 17579 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 17580 ret = wmi_unified_cmd_send_over_qmi(wmi_handle, buf, len, 17581 WMI_ROAM_SET_PARAM_CMDID); 17582 if (QDF_IS_STATUS_ERROR(ret)) { 17583 wmi_err("Failed to send roam set param command, ret = %d", ret); 17584 wmi_buf_free(buf); 17585 } 17586 17587 return ret; 17588 } 17589 #else 17590 static inline QDF_STATUS 17591 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17592 struct wmi_roam_trigger_info *trig, uint8_t idx, 17593 uint8_t btm_idx) 17594 { 17595 return QDF_STATUS_E_NOSUPPORT; 17596 } 17597 17598 static inline QDF_STATUS 17599 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17600 struct wmi_roam_result *dst, uint8_t idx) 17601 { 17602 return QDF_STATUS_E_NOSUPPORT; 17603 } 17604 17605 static QDF_STATUS 17606 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17607 struct wmi_neighbor_report_data *dst, 17608 uint8_t idx, uint8_t rpt_idx) 17609 { 17610 return QDF_STATUS_E_NOSUPPORT; 17611 } 17612 17613 static QDF_STATUS 17614 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17615 struct wmi_roam_scan_data *dst, uint8_t idx, 17616 uint8_t chan_idx, uint8_t ap_idx) 17617 { 17618 return QDF_STATUS_E_NOSUPPORT; 17619 } 17620 #endif 17621 17622 #ifdef WLAN_FEATURE_PKT_CAPTURE 17623 static QDF_STATUS 17624 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 17625 struct mgmt_offload_event_params *params) 17626 { 17627 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 17628 wmi_mgmt_hdr *hdr; 17629 17630 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 17631 if (!param_tlvs) 17632 return QDF_STATUS_E_INVAL; 17633 17634 hdr = param_tlvs->fixed_param; 17635 if (!hdr) 17636 return QDF_STATUS_E_INVAL; 17637 17638 if (hdr->buf_len > param_tlvs->num_bufp) 17639 return QDF_STATUS_E_INVAL; 17640 17641 params->tsf_l32 = hdr->tsf_l32; 17642 params->chan_freq = hdr->chan_freq; 17643 params->rate_kbps = hdr->rate_kbps; 17644 params->rssi = hdr->rssi; 17645 params->buf_len = hdr->buf_len; 17646 params->tx_status = hdr->tx_status; 17647 params->buf = param_tlvs->bufp; 17648 params->tx_retry_cnt = hdr->tx_retry_cnt; 17649 return QDF_STATUS_SUCCESS; 17650 } 17651 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 17652 17653 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 17654 static QDF_STATUS 17655 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 17656 struct smu_event_params *params) 17657 { 17658 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 17659 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 17660 17661 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 17662 if (!param_buf) { 17663 wmi_err("Invalid smart monitor event"); 17664 return QDF_STATUS_E_INVAL; 17665 } 17666 17667 smu_event = param_buf->fixed_param; 17668 if (!smu_event) { 17669 wmi_err("smart monitor event fixed param is NULL"); 17670 return QDF_STATUS_E_INVAL; 17671 } 17672 17673 params->vdev_id = smu_event->vdev_id; 17674 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 17675 return QDF_STATUS_E_INVAL; 17676 17677 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 17678 17679 return QDF_STATUS_SUCCESS; 17680 } 17681 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 17682 17683 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 17684 /** 17685 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 17686 * 17687 * @wmi: wmi handle 17688 * @vdev_id: vdev id 17689 * @burst_mode: Indicates whether relation derived using FTM is needed for 17690 * each FTM frame or only aggregated result is required. 17691 * 17692 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 17693 * 17694 * Return: QDF_STATUS 17695 */ 17696 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 17697 uint32_t vdev_id, 17698 bool burst_mode) 17699 { 17700 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 17701 wmi_buf_t buf; 17702 int32_t len = sizeof(*cmd); 17703 17704 buf = wmi_buf_alloc(wmi, len); 17705 if (!buf) { 17706 wmi_err("wmi_buf_alloc failed"); 17707 return QDF_STATUS_E_NOMEM; 17708 } 17709 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 17710 WMITLV_SET_HDR(&cmd->tlv_header, 17711 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 17712 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 17713 cmd->vdev_id = vdev_id; 17714 cmd->agg_relation = burst_mode ? false : true; 17715 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 17716 wmi_err("Failed to send audio sync trigger cmd"); 17717 wmi_buf_free(buf); 17718 return QDF_STATUS_E_FAILURE; 17719 } 17720 17721 return QDF_STATUS_SUCCESS; 17722 } 17723 17724 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 17725 uint32_t vdev_id, 17726 uint64_t lpass_ts) 17727 { 17728 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 17729 wmi_buf_t buf; 17730 int32_t len = sizeof(*cmd); 17731 17732 buf = wmi_buf_alloc(wmi, len); 17733 if (!buf) { 17734 wmi_err("wmi_buf_alloc failed"); 17735 return QDF_STATUS_E_NOMEM; 17736 } 17737 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 17738 WMITLV_SET_HDR(&cmd->tlv_header, 17739 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 17740 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 17741 cmd->vdev_id = vdev_id; 17742 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 17743 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 17744 17745 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 17746 wmi_err("Failed to send audio qtime command"); 17747 wmi_buf_free(buf); 17748 return QDF_STATUS_E_FAILURE; 17749 } 17750 17751 return QDF_STATUS_SUCCESS; 17752 } 17753 17754 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 17755 wmi_unified_t wmi, void *buf, 17756 struct ftm_time_sync_start_stop_params *param) 17757 { 17758 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 17759 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 17760 17761 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 17762 if (!param_buf) { 17763 wmi_err("Invalid audio sync start stop event buffer"); 17764 return QDF_STATUS_E_FAILURE; 17765 } 17766 17767 resp_event = param_buf->fixed_param; 17768 if (!resp_event) { 17769 wmi_err("Invalid audio sync start stop fixed param buffer"); 17770 return QDF_STATUS_E_FAILURE; 17771 } 17772 17773 param->vdev_id = resp_event->vdev_id; 17774 param->timer_interval = resp_event->periodicity; 17775 param->num_reads = resp_event->reads_needed; 17776 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 17777 resp_event->qtimer_l32; 17778 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 17779 resp_event->mac_timer_l32; 17780 17781 wmi_debug("FTM time sync time_interval %d, num_reads %d", 17782 param->timer_interval, param->num_reads); 17783 17784 return QDF_STATUS_SUCCESS; 17785 } 17786 17787 static QDF_STATUS 17788 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 17789 struct ftm_time_sync_offset *param) 17790 { 17791 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 17792 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 17793 wmi_audio_sync_q_master_slave_times *q_pair; 17794 int iter; 17795 17796 param_buf = 17797 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 17798 if (!param_buf) { 17799 wmi_err("Invalid timesync ftm offset event buffer"); 17800 return QDF_STATUS_E_FAILURE; 17801 } 17802 17803 resp_event = param_buf->fixed_param; 17804 if (!resp_event) { 17805 wmi_err("Invalid timesync ftm offset fixed param buffer"); 17806 return QDF_STATUS_E_FAILURE; 17807 } 17808 17809 param->vdev_id = resp_event->vdev_id; 17810 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 17811 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 17812 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 17813 17814 q_pair = param_buf->audio_sync_q_master_slave_times; 17815 if (!q_pair) { 17816 wmi_err("Invalid q_master_slave_times buffer"); 17817 return QDF_STATUS_E_FAILURE; 17818 } 17819 17820 for (iter = 0; iter < param->num_qtime; iter++) { 17821 param->pairs[iter].qtime_initiator = ( 17822 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 17823 q_pair[iter].qmaster_l32; 17824 param->pairs[iter].qtime_target = ( 17825 (uint64_t)q_pair[iter].qslave_u32 << 32) | 17826 q_pair[iter].qslave_l32; 17827 } 17828 return QDF_STATUS_SUCCESS; 17829 } 17830 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 17831 17832 /** 17833 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 17834 * @wmi: wmi handle 17835 * @vdev_id: vdev id 17836 * 17837 * TSF_TSTAMP_READ_VALUE is the only operation supported 17838 * Return: QDF_STATUS_SUCCESS for success or erro code 17839 */ 17840 static QDF_STATUS 17841 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 17842 { 17843 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 17844 wmi_buf_t buf; 17845 int32_t len = sizeof(*cmd); 17846 17847 buf = wmi_buf_alloc(wmi, len); 17848 if (!buf) 17849 return QDF_STATUS_E_NOMEM; 17850 17851 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 17852 WMITLV_SET_HDR(&cmd->tlv_header, 17853 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 17854 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 17855 cmd->vdev_id = vdev_id; 17856 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 17857 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 17858 if (wmi_unified_cmd_send(wmi, buf, len, 17859 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 17860 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 17861 __func__); 17862 wmi_buf_free(buf); 17863 return QDF_STATUS_E_FAILURE; 17864 } 17865 17866 return QDF_STATUS_SUCCESS; 17867 } 17868 17869 /** 17870 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 17871 * @wmi_handle: wmi handle 17872 * @param evt_buf: pointer to event buffer 17873 * @wmi_host_tsf_event param: Pointer to struct to hold event info 17874 * 17875 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 17876 */ 17877 static QDF_STATUS 17878 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17879 struct wmi_host_tsf_event *param) 17880 { 17881 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 17882 wmi_vdev_tsf_report_event_fixed_param *evt; 17883 17884 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 17885 if (!param_buf) { 17886 wmi_err("Invalid tsf report event buffer"); 17887 return QDF_STATUS_E_INVAL; 17888 } 17889 17890 evt = param_buf->fixed_param; 17891 param->vdev_id = evt->vdev_id; 17892 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 17893 param->tsf_low = evt->tsf_low; 17894 param->tsf_high = evt->tsf_high; 17895 param->qtimer_low = evt->qtimer_low; 17896 param->qtimer_high = evt->qtimer_high; 17897 param->tsf_id = evt->tsf_id; 17898 param->tsf_id_valid = evt->tsf_id_valid; 17899 param->mac_id = evt->mac_id; 17900 param->mac_id_valid = evt->mac_id_valid; 17901 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 17902 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 17903 param->tqm_timer_low = evt->tqm_timer_low; 17904 param->tqm_timer_high = evt->tqm_timer_high; 17905 param->use_tqm_timer = evt->use_tqm_timer; 17906 17907 return QDF_STATUS_SUCCESS; 17908 } 17909 17910 /** 17911 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 17912 * status tlv 17913 * @wmi_handle: wmi handle 17914 * @param evt_buf: pointer to event buffer 17915 * @param param: Pointer to hold csa switch count status event param 17916 * 17917 * Return: QDF_STATUS_SUCCESS for success or error code 17918 */ 17919 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 17920 wmi_unified_t wmi_handle, 17921 void *evt_buf, 17922 struct pdev_csa_switch_count_status *param) 17923 { 17924 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 17925 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 17926 17927 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 17928 evt_buf; 17929 if (!param_buf) { 17930 wmi_err("Invalid CSA status event"); 17931 return QDF_STATUS_E_INVAL; 17932 } 17933 17934 csa_status = param_buf->fixed_param; 17935 17936 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17937 wmi_handle, 17938 csa_status->pdev_id); 17939 param->current_switch_count = csa_status->current_switch_count; 17940 param->num_vdevs = csa_status->num_vdevs; 17941 param->vdev_ids = param_buf->vdev_ids; 17942 17943 return QDF_STATUS_SUCCESS; 17944 } 17945 17946 #ifdef CONFIG_AFC_SUPPORT 17947 /** 17948 * send_afc_cmd_tlv() - Sends the AFC indication to FW 17949 * @wmi_handle: wmi handle 17950 * @pdev_id: Pdev id 17951 * @param: Pointer to hold AFC indication. 17952 * 17953 * Return: QDF_STATUS_SUCCESS for success or error code 17954 */ 17955 static 17956 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 17957 uint8_t pdev_id, 17958 struct reg_afc_resp_rx_ind_info *param) 17959 { 17960 wmi_buf_t buf; 17961 wmi_afc_cmd_fixed_param *cmd; 17962 uint32_t len; 17963 uint8_t *buf_ptr; 17964 QDF_STATUS ret; 17965 17966 len = sizeof(wmi_afc_cmd_fixed_param); 17967 buf = wmi_buf_alloc(wmi_handle, len); 17968 if (!buf) 17969 return QDF_STATUS_E_NOMEM; 17970 17971 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17972 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 17973 17974 WMITLV_SET_HDR(&cmd->tlv_header, 17975 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 17976 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 17977 17978 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17979 wmi_handle, 17980 pdev_id); 17981 cmd->cmd_type = param->cmd_type; 17982 cmd->serv_resp_format = param->serv_resp_format; 17983 17984 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 17985 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 17986 if (QDF_IS_STATUS_ERROR(ret)) { 17987 wmi_err("Failed to send WMI_AFC_CMDID"); 17988 wmi_buf_free(buf); 17989 return QDF_STATUS_E_FAILURE; 17990 } 17991 17992 return QDF_STATUS_SUCCESS; 17993 } 17994 #endif 17995 17996 /** 17997 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 17998 * @wmi_handle: wmi handle 17999 * @param: Pointer to hold TX power info 18000 * 18001 * Return: QDF_STATUS_SUCCESS for success or error code 18002 */ 18003 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 18004 uint8_t vdev_id, 18005 struct reg_tpc_power_info *param) 18006 { 18007 wmi_buf_t buf; 18008 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 18009 wmi_vdev_ch_power_info *ch_power_info; 18010 uint8_t *buf_ptr; 18011 uint16_t idx; 18012 uint32_t len; 18013 QDF_STATUS ret; 18014 18015 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 18016 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 18017 18018 buf = wmi_buf_alloc(wmi_handle, len); 18019 if (!buf) 18020 return QDF_STATUS_E_NOMEM; 18021 18022 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18023 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 18024 18025 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 18026 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 18027 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 18028 18029 tpc_power_info_param->vdev_id = vdev_id; 18030 tpc_power_info_param->psd_power = param->is_psd_power; 18031 tpc_power_info_param->eirp_power = param->eirp_power; 18032 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 18033 wmi_debug("eirp_power = %d is_psd_power = %d power_type_6ghz = %d", 18034 tpc_power_info_param->eirp_power, 18035 tpc_power_info_param->psd_power, 18036 tpc_power_info_param->power_type_6ghz); 18037 18038 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 18039 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18040 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 18041 18042 buf_ptr += WMI_TLV_HDR_SIZE; 18043 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 18044 18045 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 18046 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 18047 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 18048 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 18049 ch_power_info[idx].chan_cfreq = 18050 param->chan_power_info[idx].chan_cfreq; 18051 ch_power_info[idx].tx_power = 18052 param->chan_power_info[idx].tx_power; 18053 wmi_debug("chan_cfreq = %d tx_power = %d", 18054 ch_power_info[idx].chan_cfreq, 18055 ch_power_info[idx].tx_power); 18056 buf_ptr += sizeof(wmi_vdev_ch_power_info); 18057 } 18058 18059 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 18060 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18061 WMI_VDEV_SET_TPC_POWER_CMDID); 18062 if (QDF_IS_STATUS_ERROR(ret)) 18063 wmi_buf_free(buf); 18064 18065 18066 return ret; 18067 } 18068 18069 /** 18070 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 18071 * @wmi_handle: wmi handle 18072 * @evt_buf: event buffer 18073 * @param: dpd status info 18074 * 18075 * Return: QDF_STATUS_SUCCESS for success or error code 18076 */ 18077 static QDF_STATUS 18078 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 18079 void *evt_buf, 18080 struct wmi_host_pdev_get_dpd_status_event *param) 18081 { 18082 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 18083 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 18084 18085 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 18086 if (!param_buf) { 18087 wmi_err("Invalid get dpd_status event"); 18088 return QDF_STATUS_E_INVAL; 18089 } 18090 18091 dpd_status = param_buf->fixed_param; 18092 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 18093 (wmi_handle, dpd_status->pdev_id); 18094 param->dpd_status = dpd_status->dpd_status; 18095 18096 return QDF_STATUS_SUCCESS; 18097 } 18098 18099 static int 18100 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 18101 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 18102 { 18103 if (status->halphy_cal_valid_bmap && valid_bit) 18104 return (status->halphy_cal_status && valid_bit); 18105 18106 return 0; 18107 } 18108 18109 static QDF_STATUS 18110 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 18111 void *evt_buf, 18112 struct wmi_host_pdev_get_halphy_cal_status_event *param) 18113 { 18114 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 18115 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 18116 18117 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 18118 if (!param_buf) { 18119 wmi_err("Invalid get halphy cal status event"); 18120 return QDF_STATUS_E_INVAL; 18121 } 18122 18123 halphy_cal_status = param_buf->fixed_param; 18124 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 18125 (wmi_handle, halphy_cal_status->pdev_id); 18126 param->halphy_cal_adc_status = 18127 convert_halphy_status(halphy_cal_status, 18128 WMI_HALPHY_CAL_ADC_BMAP); 18129 param->halphy_cal_bwfilter_status = 18130 convert_halphy_status(halphy_cal_status, 18131 WMI_HALPHY_CAL_BWFILTER_BMAP); 18132 param->halphy_cal_pdet_and_pal_status = 18133 convert_halphy_status(halphy_cal_status, 18134 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 18135 param->halphy_cal_rxdco_status = 18136 convert_halphy_status(halphy_cal_status, 18137 WMI_HALPHY_CAL_RXDCO_BMAP); 18138 param->halphy_cal_comb_txiq_rxiq_status = 18139 convert_halphy_status(halphy_cal_status, 18140 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 18141 param->halphy_cal_ibf_status = 18142 convert_halphy_status(halphy_cal_status, 18143 WMI_HALPHY_CAL_IBF_BMAP); 18144 param->halphy_cal_pa_droop_status = 18145 convert_halphy_status(halphy_cal_status, 18146 WMI_HALPHY_CAL_PA_DROOP_BMAP); 18147 param->halphy_cal_dac_status = 18148 convert_halphy_status(halphy_cal_status, 18149 WMI_HALPHY_CAL_DAC_BMAP); 18150 param->halphy_cal_ani_status = 18151 convert_halphy_status(halphy_cal_status, 18152 WMI_HALPHY_CAL_ANI_BMAP); 18153 param->halphy_cal_noise_floor_status = 18154 convert_halphy_status(halphy_cal_status, 18155 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 18156 18157 return QDF_STATUS_SUCCESS; 18158 } 18159 18160 /** 18161 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 18162 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 18163 * 18164 * Return: host_set_halphy_cal_status 18165 */ 18166 static enum wmi_host_set_halphy_cal_status 18167 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 18168 { 18169 if (fw_status == 0) 18170 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 18171 else if (fw_status == 1) 18172 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 18173 18174 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 18175 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 18176 } 18177 18178 /** 18179 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 18180 * @wmi_handle: wmi handle 18181 * @evt_buf: event buffer 18182 * @param: set halphy cal status info 18183 * 18184 * Return: QDF_STATUS_SUCCESS for success or error code 18185 */ 18186 static QDF_STATUS 18187 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 18188 void *evt_buf, 18189 struct wmi_host_pdev_set_halphy_cal_event *param) 18190 { 18191 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 18192 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 18193 18194 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 18195 if (!param_buf) { 18196 wmi_err("Invalid set halphy_status event"); 18197 return QDF_STATUS_E_INVAL; 18198 } 18199 18200 set_halphy_status = param_buf->fixed_param; 18201 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 18202 (wmi_handle, set_halphy_status->pdev_id); 18203 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 18204 18205 return QDF_STATUS_SUCCESS; 18206 } 18207 18208 /** 18209 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 18210 * @wmi_handle: wmi handle 18211 * @evt_buf: pointer to event buffer 18212 * @len: length of the event buffer 18213 * @param: Pointer to hold install key complete event param 18214 * 18215 * Return: QDF_STATUS_SUCCESS for success or error code 18216 */ 18217 static QDF_STATUS 18218 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 18219 void *evt_buf, uint32_t len, 18220 struct wmi_install_key_comp_event *param) 18221 { 18222 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 18223 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 18224 18225 if (len < sizeof(*param_buf)) { 18226 wmi_err("invalid event buf len %d", len); 18227 return QDF_STATUS_E_INVAL; 18228 } 18229 18230 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18231 if (!param_buf) { 18232 wmi_err("received null buf from target"); 18233 return QDF_STATUS_E_INVAL; 18234 } 18235 18236 key_fp = param_buf->fixed_param; 18237 if (!key_fp) { 18238 wmi_err("received null event data from target"); 18239 return QDF_STATUS_E_INVAL; 18240 } 18241 18242 param->vdev_id = key_fp->vdev_id; 18243 param->key_ix = key_fp->key_ix; 18244 param->key_flags = key_fp->key_flags; 18245 param->status = key_fp->status; 18246 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 18247 param->peer_macaddr); 18248 18249 return QDF_STATUS_SUCCESS; 18250 } 18251 18252 static QDF_STATUS 18253 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 18254 struct wmi_host_send_set_halphy_cal_info *param) 18255 { 18256 wmi_buf_t buf; 18257 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 18258 QDF_STATUS ret; 18259 uint32_t len; 18260 18261 len = sizeof(*cmd); 18262 18263 buf = wmi_buf_alloc(wmi_handle, len); 18264 if (!buf) 18265 return QDF_STATUS_E_FAILURE; 18266 18267 cmd = (void *)wmi_buf_data(buf); 18268 18269 WMITLV_SET_HDR(&cmd->tlv_header, 18270 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 18271 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 18272 18273 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 18274 param->pdev_id); 18275 cmd->online_halphy_cals_bmap = param->value; 18276 cmd->home_scan_channel = param->chan_sel; 18277 18278 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18279 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 18280 if (QDF_IS_STATUS_ERROR(ret)) { 18281 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 18282 wmi_buf_free(buf); 18283 } 18284 18285 return ret; 18286 } 18287 18288 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18289 /** 18290 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 18291 * @wmi: wmi handle 18292 * @params: set MAC address command params 18293 * 18294 * Return: QDF_STATUS_SUCCESS for success or error code 18295 */ 18296 static QDF_STATUS 18297 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 18298 struct set_mac_addr_params *params) 18299 { 18300 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 18301 wmi_buf_t buf; 18302 int32_t len = sizeof(*cmd); 18303 18304 buf = wmi_buf_alloc(wmi, len); 18305 if (!buf) 18306 return QDF_STATUS_E_NOMEM; 18307 18308 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 18309 WMITLV_SET_HDR( 18310 &cmd->tlv_header, 18311 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 18312 WMITLV_GET_STRUCT_TLVLEN 18313 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 18314 cmd->vdev_id = params->vdev_id; 18315 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 18316 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 18317 18318 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 18319 QDF_MAC_ADDR_FMT, cmd->vdev_id, 18320 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 18321 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 18322 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 18323 if (wmi_unified_cmd_send(wmi, buf, len, 18324 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 18325 wmi_buf_free(buf); 18326 return QDF_STATUS_E_FAILURE; 18327 } 18328 18329 return QDF_STATUS_SUCCESS; 18330 } 18331 18332 /** 18333 * extract_update_mac_address_event_tlv() - extract update MAC address event 18334 * @wmi_handle: WMI handle 18335 * @evt_buf: event buffer 18336 * @vdev_id: VDEV ID 18337 * @status: FW status of the set MAC address operation 18338 * 18339 * Return: QDF_STATUS 18340 */ 18341 static QDF_STATUS extract_update_mac_address_event_tlv( 18342 wmi_unified_t wmi_handle, void *evt_buf, 18343 uint8_t *vdev_id, uint8_t *status) 18344 { 18345 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 18346 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 18347 18348 param_buf = 18349 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 18350 18351 event = param_buf->fixed_param; 18352 18353 *vdev_id = event->vdev_id; 18354 *status = event->status; 18355 18356 return QDF_STATUS_SUCCESS; 18357 } 18358 #endif 18359 18360 #ifdef WLAN_FEATURE_11BE_MLO 18361 /** 18362 * extract_quiet_offload_event_tlv() - extract quiet offload event 18363 * @wmi_handle: WMI handle 18364 * @evt_buf: event buffer 18365 * @mld_mac: mld mac address 18366 * @link_mac: link mac address 18367 * @link_id: link id 18368 * @quiet_status: quiet is started or stopped 18369 * 18370 * Return: QDF_STATUS 18371 */ 18372 static QDF_STATUS extract_quiet_offload_event_tlv( 18373 wmi_unified_t wmi_handle, void *evt_buf, 18374 struct vdev_sta_quiet_event *quiet_event) 18375 { 18376 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 18377 wmi_quiet_event_fixed_param *event; 18378 18379 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 18380 18381 event = param_buf->fixed_param; 18382 18383 if (!(event->mld_mac_address_present && event->linkid_present) && 18384 !event->link_mac_address_present) { 18385 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 18386 event->mld_mac_address_present, 18387 event->linkid_present, 18388 event->link_mac_address_present); 18389 return QDF_STATUS_E_INVAL; 18390 } 18391 18392 if (event->mld_mac_address_present) 18393 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 18394 quiet_event->mld_mac.bytes); 18395 if (event->link_mac_address_present) 18396 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 18397 quiet_event->link_mac.bytes); 18398 if (event->linkid_present) 18399 quiet_event->link_id = event->linkid; 18400 quiet_event->quiet_status = (event->quiet_status == 18401 WMI_QUIET_EVENT_START); 18402 18403 return QDF_STATUS_SUCCESS; 18404 } 18405 #endif 18406 18407 /** 18408 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 18409 * @wmi_handle: wmi handle 18410 * @params: RxFilter params 18411 * 18412 * Return: QDF_STATUS_SUCCESS for success or error code 18413 */ 18414 static QDF_STATUS 18415 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 18416 struct vdev_pn_mgmt_rxfilter_params *params) 18417 { 18418 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 18419 wmi_buf_t buf; 18420 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 18421 18422 if (!is_service_enabled_tlv(wmi_handle, 18423 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 18424 wmi_err("Rx PN Replay Check not supported by target"); 18425 return QDF_STATUS_E_NOSUPPORT; 18426 } 18427 18428 buf = wmi_buf_alloc(wmi_handle, len); 18429 if (!buf) { 18430 wmi_err("wmi buf alloc failed"); 18431 return QDF_STATUS_E_NOMEM; 18432 } 18433 18434 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 18435 WMITLV_SET_HDR( 18436 &cmd->tlv_header, 18437 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 18438 WMITLV_GET_STRUCT_TLVLEN 18439 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 18440 18441 cmd->vdev_id = params->vdev_id; 18442 cmd->pn_rx_filter = params->pn_rxfilter; 18443 18444 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18445 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 18446 wmi_err("Failed to send WMI command"); 18447 wmi_buf_free(buf); 18448 return QDF_STATUS_E_FAILURE; 18449 } 18450 18451 return QDF_STATUS_SUCCESS; 18452 } 18453 18454 static QDF_STATUS 18455 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18456 uint8_t *pdev_id, uint8_t *software_image, 18457 uint8_t *chip_info, 18458 uint32_t *pktlog_json_version) 18459 { 18460 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 18461 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 18462 18463 param_buf = 18464 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 18465 18466 event = param_buf->fixed_param; 18467 18468 if ((event->software_image[0] == '\0') || 18469 (event->chip_info[0] == '\0')) { 18470 *pdev_id = event->pdev_id; 18471 return QDF_STATUS_E_INVAL; 18472 } 18473 18474 qdf_mem_copy(software_image, event->software_image, 40); 18475 qdf_mem_copy(chip_info, event->chip_info, 40); 18476 *pktlog_json_version = event->pktlog_defs_json_version; 18477 *pdev_id = event->pdev_id; 18478 return QDF_STATUS_SUCCESS; 18479 } 18480 18481 /** 18482 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 18483 * @wmi_handle: wmi handle 18484 * @evt_buf: pointer to event buffer 18485 * @pdev stats: Pointer to hold pdev telemetry stats 18486 * 18487 * Return: QDF_STATUS_SUCCESS for success or error code 18488 */ 18489 static QDF_STATUS 18490 extract_pdev_telemetry_stats_tlv( 18491 wmi_unified_t wmi_handle, void *evt_buf, 18492 struct wmi_host_pdev_telemetry_stats *pdev_stats) 18493 { 18494 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18495 wmi_pdev_telemetry_stats *ev; 18496 18497 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 18498 18499 if (param_buf->pdev_telemetry_stats) { 18500 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 18501 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 18502 ev->avg_chan_lat_per_ac, 18503 sizeof(ev->avg_chan_lat_per_ac)); 18504 pdev_stats->estimated_air_time_per_ac = 18505 ev->estimated_air_time_per_ac; 18506 } 18507 18508 return QDF_STATUS_SUCCESS; 18509 } 18510 18511 struct wmi_ops tlv_ops = { 18512 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 18513 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 18514 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 18515 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 18516 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 18517 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 18518 .send_peer_param_cmd = send_peer_param_cmd_tlv, 18519 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 18520 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 18521 .send_peer_create_cmd = send_peer_create_cmd_tlv, 18522 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 18523 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 18524 .send_peer_rx_reorder_queue_setup_cmd = 18525 send_peer_rx_reorder_queue_setup_cmd_tlv, 18526 .send_peer_rx_reorder_queue_remove_cmd = 18527 send_peer_rx_reorder_queue_remove_cmd_tlv, 18528 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 18529 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 18530 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 18531 .send_suspend_cmd = send_suspend_cmd_tlv, 18532 .send_resume_cmd = send_resume_cmd_tlv, 18533 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 18534 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 18535 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 18536 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 18537 .send_dbglog_cmd = send_dbglog_cmd_tlv, 18538 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 18539 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 18540 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 18541 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 18542 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 18543 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 18544 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 18545 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 18546 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 18547 .send_scan_start_cmd = send_scan_start_cmd_tlv, 18548 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 18549 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 18550 .send_mgmt_cmd = send_mgmt_cmd_tlv, 18551 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 18552 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 18553 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 18554 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 18555 .send_set_sta_uapsd_auto_trig_cmd = 18556 send_set_sta_uapsd_auto_trig_cmd_tlv, 18557 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 18558 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 18559 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 18560 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 18561 .send_lro_config_cmd = send_lro_config_cmd_tlv, 18562 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 18563 .send_probe_rsp_tmpl_send_cmd = 18564 send_probe_rsp_tmpl_send_cmd_tlv, 18565 .send_p2p_go_set_beacon_ie_cmd = 18566 send_p2p_go_set_beacon_ie_cmd_tlv, 18567 .send_setup_install_key_cmd = 18568 send_setup_install_key_cmd_tlv, 18569 .send_scan_probe_setoui_cmd = 18570 send_scan_probe_setoui_cmd_tlv, 18571 #ifdef IPA_OFFLOAD 18572 .send_ipa_offload_control_cmd = 18573 send_ipa_offload_control_cmd_tlv, 18574 #endif 18575 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 18576 .send_pno_start_cmd = send_pno_start_cmd_tlv, 18577 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 18578 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 18579 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 18580 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 18581 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 18582 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 18583 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 18584 .send_unified_ll_stats_get_sta_cmd = 18585 send_unified_ll_stats_get_sta_cmd_tlv, 18586 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 18587 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 18588 .send_congestion_cmd = send_congestion_cmd_tlv, 18589 .send_snr_request_cmd = send_snr_request_cmd_tlv, 18590 .send_snr_cmd = send_snr_cmd_tlv, 18591 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 18592 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 18593 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 18594 #endif 18595 #ifdef WLAN_SUPPORT_GREEN_AP 18596 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 18597 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 18598 .extract_green_ap_egap_status_info = 18599 extract_green_ap_egap_status_info_tlv, 18600 #endif 18601 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 18602 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 18603 #ifdef FEATURE_OEM_DATA 18604 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 18605 #endif 18606 #ifdef WLAN_FEATURE_CIF_CFR 18607 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 18608 #endif 18609 .send_dfs_phyerr_filter_offload_en_cmd = 18610 send_dfs_phyerr_filter_offload_en_cmd_tlv, 18611 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 18612 .send_process_dhcpserver_offload_cmd = 18613 send_process_dhcpserver_offload_cmd_tlv, 18614 .send_pdev_set_regdomain_cmd = 18615 send_pdev_set_regdomain_cmd_tlv, 18616 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 18617 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 18618 .save_fw_version_cmd = save_fw_version_cmd_tlv, 18619 .check_and_update_fw_version = 18620 check_and_update_fw_version_cmd_tlv, 18621 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 18622 .send_enable_specific_fw_logs_cmd = 18623 send_enable_specific_fw_logs_cmd_tlv, 18624 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 18625 .send_unit_test_cmd = send_unit_test_cmd_tlv, 18626 #ifdef FEATURE_WLAN_APF 18627 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 18628 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 18629 .send_apf_write_work_memory_cmd = 18630 wmi_send_apf_write_work_memory_cmd_tlv, 18631 .send_apf_read_work_memory_cmd = 18632 wmi_send_apf_read_work_memory_cmd_tlv, 18633 .extract_apf_read_memory_resp_event = 18634 wmi_extract_apf_read_memory_resp_event_tlv, 18635 #endif /* FEATURE_WLAN_APF */ 18636 .init_cmd_send = init_cmd_send_tlv, 18637 .send_vdev_set_custom_aggr_size_cmd = 18638 send_vdev_set_custom_aggr_size_cmd_tlv, 18639 .send_vdev_set_qdepth_thresh_cmd = 18640 send_vdev_set_qdepth_thresh_cmd_tlv, 18641 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 18642 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 18643 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 18644 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 18645 .send_periodic_chan_stats_config_cmd = 18646 send_periodic_chan_stats_config_cmd_tlv, 18647 #ifdef WLAN_IOT_SIM_SUPPORT 18648 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 18649 #endif 18650 .send_vdev_spectral_configure_cmd = 18651 send_vdev_spectral_configure_cmd_tlv, 18652 .send_vdev_spectral_enable_cmd = 18653 send_vdev_spectral_enable_cmd_tlv, 18654 #ifdef WLAN_CONV_SPECTRAL_ENABLE 18655 .extract_pdev_sscan_fw_cmd_fixed_param = 18656 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 18657 .extract_pdev_sscan_fft_bin_index = 18658 extract_pdev_sscan_fft_bin_index_tlv, 18659 .extract_pdev_spectral_session_chan_info = 18660 extract_pdev_spectral_session_chan_info_tlv, 18661 .extract_pdev_spectral_session_detector_info = 18662 extract_pdev_spectral_session_detector_info_tlv, 18663 .extract_spectral_caps_fixed_param = 18664 extract_spectral_caps_fixed_param_tlv, 18665 .extract_spectral_scan_bw_caps = 18666 extract_spectral_scan_bw_caps_tlv, 18667 .extract_spectral_fft_size_caps = 18668 extract_spectral_fft_size_caps_tlv, 18669 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 18670 .send_thermal_mitigation_param_cmd = 18671 send_thermal_mitigation_param_cmd_tlv, 18672 .send_process_update_edca_param_cmd = 18673 send_process_update_edca_param_cmd_tlv, 18674 .send_bss_color_change_enable_cmd = 18675 send_bss_color_change_enable_cmd_tlv, 18676 .send_coex_config_cmd = send_coex_config_cmd_tlv, 18677 .send_set_country_cmd = send_set_country_cmd_tlv, 18678 .send_addba_send_cmd = send_addba_send_cmd_tlv, 18679 .send_delba_send_cmd = send_delba_send_cmd_tlv, 18680 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 18681 .get_target_cap_from_service_ready = extract_service_ready_tlv, 18682 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 18683 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 18684 .extract_host_mem_req = extract_host_mem_req_tlv, 18685 .save_service_bitmap = save_service_bitmap_tlv, 18686 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 18687 .is_service_enabled = is_service_enabled_tlv, 18688 .save_fw_version = save_fw_version_in_service_ready_tlv, 18689 .ready_extract_init_status = ready_extract_init_status_tlv, 18690 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 18691 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 18692 .extract_ready_event_params = extract_ready_event_params_tlv, 18693 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 18694 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 18695 .extract_frame_pn_params = extract_frame_pn_params_tlv, 18696 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 18697 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 18698 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 18699 #ifdef FEATURE_WLAN_SCAN_PNO 18700 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 18701 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 18702 #endif 18703 .extract_unit_test = extract_unit_test_tlv, 18704 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 18705 .extract_bcn_stats = extract_bcn_stats_tlv, 18706 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 18707 .extract_chan_stats = extract_chan_stats_tlv, 18708 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 18709 .extract_profile_ctx = extract_profile_ctx_tlv, 18710 .extract_profile_data = extract_profile_data_tlv, 18711 .send_fw_test_cmd = send_fw_test_cmd_tlv, 18712 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 18713 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 18714 .extract_service_ready_ext = extract_service_ready_ext_tlv, 18715 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 18716 .extract_dbs_or_sbs_service_ready_ext2 = 18717 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 18718 .extract_hw_mode_cap_service_ready_ext = 18719 extract_hw_mode_cap_service_ready_ext_tlv, 18720 .extract_mac_phy_cap_service_ready_ext = 18721 extract_mac_phy_cap_service_ready_ext_tlv, 18722 .extract_mac_phy_cap_service_ready_ext2 = 18723 extract_mac_phy_cap_service_ready_ext2_tlv, 18724 .extract_reg_cap_service_ready_ext = 18725 extract_reg_cap_service_ready_ext_tlv, 18726 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 18727 .extract_dbr_ring_cap_service_ready_ext = 18728 extract_dbr_ring_cap_service_ready_ext_tlv, 18729 .extract_dbr_ring_cap_service_ready_ext2 = 18730 extract_dbr_ring_cap_service_ready_ext2_tlv, 18731 .extract_scan_radio_cap_service_ready_ext2 = 18732 extract_scan_radio_cap_service_ready_ext2_tlv, 18733 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 18734 .extract_sar_cap_service_ready_ext = 18735 extract_sar_cap_service_ready_ext_tlv, 18736 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 18737 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 18738 .extract_fips_event_data = extract_fips_event_data_tlv, 18739 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 18740 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 18741 #endif 18742 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18743 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 18744 #endif 18745 #ifdef WLAN_FEATURE_DISA 18746 .extract_encrypt_decrypt_resp_event = 18747 extract_encrypt_decrypt_resp_event_tlv, 18748 #endif 18749 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 18750 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 18751 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 18752 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 18753 #endif 18754 .extract_get_pn_data = extract_get_pn_data_tlv, 18755 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 18756 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 18757 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 18758 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 18759 #ifdef WLAN_FEATURE_DISA 18760 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 18761 #endif 18762 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 18763 .send_wlan_profile_hist_intvl_cmd = 18764 send_wlan_profile_hist_intvl_cmd_tlv, 18765 .is_management_record = is_management_record_tlv, 18766 .is_diag_event = is_diag_event_tlv, 18767 #ifdef WLAN_FEATURE_ACTION_OUI 18768 .send_action_oui_cmd = send_action_oui_cmd_tlv, 18769 #endif 18770 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 18771 #ifdef QCA_SUPPORT_AGILE_DFS 18772 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 18773 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 18774 #endif 18775 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 18776 .extract_reg_chan_list_update_event = 18777 extract_reg_chan_list_update_event_tlv, 18778 #ifdef CONFIG_BAND_6GHZ 18779 .extract_reg_chan_list_ext_update_event = 18780 extract_reg_chan_list_ext_update_event_tlv, 18781 #ifdef CONFIG_AFC_SUPPORT 18782 .extract_afc_event = extract_afc_event_tlv, 18783 #endif 18784 #endif 18785 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 18786 .extract_num_rf_characterization_entries = 18787 extract_num_rf_characterization_entries_tlv, 18788 .extract_rf_characterization_entries = 18789 extract_rf_characterization_entries_tlv, 18790 #endif 18791 .extract_chainmask_tables = 18792 extract_chainmask_tables_tlv, 18793 .extract_thermal_stats = extract_thermal_stats_tlv, 18794 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 18795 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 18796 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 18797 #ifdef DFS_COMPONENT_ENABLE 18798 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 18799 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 18800 .extract_dfs_radar_detection_event = 18801 extract_dfs_radar_detection_event_tlv, 18802 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 18803 #endif 18804 .convert_pdev_id_host_to_target = 18805 convert_host_pdev_id_to_target_pdev_id_legacy, 18806 .convert_pdev_id_target_to_host = 18807 convert_target_pdev_id_to_host_pdev_id_legacy, 18808 18809 .convert_host_pdev_id_to_target = 18810 convert_host_pdev_id_to_target_pdev_id, 18811 .convert_target_pdev_id_to_host = 18812 convert_target_pdev_id_to_host_pdev_id, 18813 18814 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 18815 18816 .convert_phy_id_host_to_target = 18817 convert_host_phy_id_to_target_phy_id_legacy, 18818 .convert_phy_id_target_to_host = 18819 convert_target_phy_id_to_host_phy_id_legacy, 18820 18821 .convert_host_phy_id_to_target = 18822 convert_host_phy_id_to_target_phy_id, 18823 .convert_target_phy_id_to_host = 18824 convert_target_phy_id_to_host_phy_id, 18825 18826 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 18827 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 18828 .extract_reg_11d_new_country_event = 18829 extract_reg_11d_new_country_event_tlv, 18830 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 18831 .extract_reg_ch_avoid_event = 18832 extract_reg_ch_avoid_event_tlv, 18833 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 18834 .extract_obss_detection_info = extract_obss_detection_info_tlv, 18835 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 18836 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 18837 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 18838 .wmi_check_command_params = wmitlv_check_command_tlv_params, 18839 .extract_comb_phyerr = extract_comb_phyerr_tlv, 18840 .extract_single_phyerr = extract_single_phyerr_tlv, 18841 #ifdef QCA_SUPPORT_CP_STATS 18842 .extract_cca_stats = extract_cca_stats_tlv, 18843 #endif 18844 .extract_esp_estimation_ev_param = 18845 extract_esp_estimation_ev_param_tlv, 18846 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 18847 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 18848 #ifdef OBSS_PD 18849 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 18850 .send_obss_spatial_reuse_set_def_thresh = 18851 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 18852 .send_self_srg_bss_color_bitmap_set = 18853 send_self_srg_bss_color_bitmap_set_cmd_tlv, 18854 .send_self_srg_partial_bssid_bitmap_set = 18855 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 18856 .send_self_srg_obss_color_enable_bitmap = 18857 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 18858 .send_self_srg_obss_bssid_enable_bitmap = 18859 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 18860 .send_self_non_srg_obss_color_enable_bitmap = 18861 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 18862 .send_self_non_srg_obss_bssid_enable_bitmap = 18863 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 18864 #endif 18865 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 18866 .extract_ctl_failsafe_check_ev_param = 18867 extract_ctl_failsafe_check_ev_param_tlv, 18868 #ifdef WIFI_POS_CONVERGED 18869 .extract_oem_response_param = extract_oem_response_param_tlv, 18870 #endif /* WIFI_POS_CONVERGED */ 18871 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18872 .extract_pasn_peer_create_req_event = 18873 extract_pasn_peer_create_req_event_tlv, 18874 .extract_pasn_peer_delete_req_event = 18875 extract_pasn_peer_delete_req_event_tlv, 18876 .send_rtt_pasn_auth_status_cmd = 18877 send_rtt_pasn_auth_status_cmd_tlv, 18878 .send_rtt_pasn_deauth_cmd = 18879 send_rtt_pasn_deauth_cmd_tlv, 18880 #endif 18881 #ifdef WLAN_MWS_INFO_DEBUGFS 18882 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 18883 #endif 18884 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 18885 #ifdef FEATURE_ANI_LEVEL_REQUEST 18886 .send_ani_level_cmd = send_ani_level_cmd_tlv, 18887 .extract_ani_level = extract_ani_level_tlv, 18888 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18889 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 18890 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 18891 .extract_roam_result_stats = extract_roam_result_stats_tlv, 18892 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 18893 #ifdef WLAN_FEATURE_PKT_CAPTURE 18894 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 18895 #endif 18896 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 18897 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 18898 #endif 18899 18900 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 18901 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 18902 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 18903 .extract_time_sync_ftm_start_stop_event = 18904 extract_time_sync_ftm_start_stop_event_tlv, 18905 .extract_time_sync_ftm_offset_event = 18906 extract_time_sync_ftm_offset_event_tlv, 18907 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 18908 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 18909 .send_injector_config_cmd = send_injector_config_cmd_tlv, 18910 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 18911 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 18912 #ifdef FEATURE_MEC_OFFLOAD 18913 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 18914 #endif 18915 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 18916 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 18917 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 18918 .extract_cp_stats_more_pending = 18919 extract_cp_stats_more_pending_tlv, 18920 .extract_halphy_stats_end_of_event = 18921 extract_halphy_stats_end_of_event_tlv, 18922 .extract_halphy_stats_event_count = 18923 extract_halphy_stats_event_count_tlv, 18924 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 18925 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 18926 .extract_pdev_csa_switch_count_status = 18927 extract_pdev_csa_switch_count_status_tlv, 18928 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 18929 #ifdef CONFIG_AFC_SUPPORT 18930 .send_afc_cmd = send_afc_cmd_tlv, 18931 #endif 18932 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 18933 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 18934 .send_vdev_set_ltf_key_seed_cmd = 18935 send_vdev_set_ltf_key_seed_cmd_tlv, 18936 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 18937 .send_set_halphy_cal = send_set_halphy_cal_tlv, 18938 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 18939 #ifdef WLAN_MGMT_RX_REO_SUPPORT 18940 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 18941 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 18942 .send_mgmt_rx_reo_filter_config_cmd = 18943 send_mgmt_rx_reo_filter_config_cmd_tlv, 18944 #endif 18945 18946 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18947 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 18948 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 18949 18950 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18951 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 18952 .extract_update_mac_address_event = 18953 extract_update_mac_address_event_tlv, 18954 #endif 18955 18956 #ifdef WLAN_FEATURE_11BE_MLO 18957 .extract_quiet_offload_event = 18958 extract_quiet_offload_event_tlv, 18959 #endif 18960 18961 #ifdef WLAN_SUPPORT_PPEDS 18962 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 18963 #endif /* WLAN_SUPPORT_PPEDS */ 18964 18965 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 18966 .extract_pktlog_decode_info_event = 18967 extract_pktlog_decode_info_event_tlv, 18968 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 18969 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 18970 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 18971 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 18972 #endif 18973 #ifdef WLAN_FEATURE_DBAM_CONFIG 18974 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 18975 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 18976 #endif 18977 }; 18978 18979 #ifdef WLAN_FEATURE_11BE_MLO 18980 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 18981 { 18982 event_ids[wmi_mlo_setup_complete_event_id] = 18983 WMI_MLO_SETUP_COMPLETE_EVENTID; 18984 event_ids[wmi_mlo_teardown_complete_event_id] = 18985 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 18986 event_ids[wmi_mlo_link_set_active_resp_eventid] = 18987 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 18988 event_ids[wmi_vdev_quiet_offload_eventid] = 18989 WMI_QUIET_HANDLING_EVENTID; 18990 } 18991 #else /* WLAN_FEATURE_11BE_MLO */ 18992 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 18993 { 18994 } 18995 #endif /* WLAN_FEATURE_11BE_MLO */ 18996 18997 /** 18998 * populate_tlv_event_id() - populates wmi event ids 18999 * 19000 * @param event_ids: Pointer to hold event ids 19001 * Return: None 19002 */ 19003 static void populate_tlv_events_id(uint32_t *event_ids) 19004 { 19005 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 19006 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 19007 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 19008 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 19009 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 19010 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 19011 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 19012 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 19013 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 19014 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 19015 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 19016 event_ids[wmi_service_ready_ext_event_id] = 19017 WMI_SERVICE_READY_EXT_EVENTID; 19018 event_ids[wmi_service_ready_ext2_event_id] = 19019 WMI_SERVICE_READY_EXT2_EVENTID; 19020 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 19021 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 19022 event_ids[wmi_vdev_install_key_complete_event_id] = 19023 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 19024 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 19025 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 19026 19027 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 19028 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 19029 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 19030 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 19031 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 19032 event_ids[wmi_peer_estimated_linkspeed_event_id] = 19033 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 19034 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 19035 event_ids[wmi_peer_create_conf_event_id] = 19036 WMI_PEER_CREATE_CONF_EVENTID; 19037 event_ids[wmi_peer_delete_response_event_id] = 19038 WMI_PEER_DELETE_RESP_EVENTID; 19039 event_ids[wmi_peer_delete_all_response_event_id] = 19040 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 19041 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 19042 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 19043 event_ids[wmi_tbttoffset_update_event_id] = 19044 WMI_TBTTOFFSET_UPDATE_EVENTID; 19045 event_ids[wmi_ext_tbttoffset_update_event_id] = 19046 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 19047 event_ids[wmi_offload_bcn_tx_status_event_id] = 19048 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 19049 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 19050 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 19051 event_ids[wmi_mgmt_tx_completion_event_id] = 19052 WMI_MGMT_TX_COMPLETION_EVENTID; 19053 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 19054 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 19055 event_ids[wmi_tx_delba_complete_event_id] = 19056 WMI_TX_DELBA_COMPLETE_EVENTID; 19057 event_ids[wmi_tx_addba_complete_event_id] = 19058 WMI_TX_ADDBA_COMPLETE_EVENTID; 19059 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 19060 19061 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 19062 19063 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 19064 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 19065 19066 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 19067 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 19068 19069 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 19070 19071 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 19072 event_ids[wmi_p2p_lo_stop_event_id] = 19073 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 19074 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 19075 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 19076 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 19077 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 19078 event_ids[wmi_d0_wow_disable_ack_event_id] = 19079 WMI_D0_WOW_DISABLE_ACK_EVENTID; 19080 event_ids[wmi_wow_initial_wakeup_event_id] = 19081 WMI_WOW_INITIAL_WAKEUP_EVENTID; 19082 19083 event_ids[wmi_rtt_meas_report_event_id] = 19084 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 19085 event_ids[wmi_tsf_meas_report_event_id] = 19086 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 19087 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 19088 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 19089 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 19090 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 19091 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 19092 event_ids[wmi_diag_event_id_log_supported_event_id] = 19093 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 19094 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 19095 event_ids[wmi_nlo_scan_complete_event_id] = 19096 WMI_NLO_SCAN_COMPLETE_EVENTID; 19097 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 19098 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 19099 19100 event_ids[wmi_gtk_offload_status_event_id] = 19101 WMI_GTK_OFFLOAD_STATUS_EVENTID; 19102 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 19103 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 19104 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 19105 19106 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 19107 19108 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 19109 19110 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 19111 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 19112 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 19113 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 19114 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 19115 event_ids[wmi_wlan_profile_data_event_id] = 19116 WMI_WLAN_PROFILE_DATA_EVENTID; 19117 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 19118 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 19119 event_ids[wmi_vdev_get_keepalive_event_id] = 19120 WMI_VDEV_GET_KEEPALIVE_EVENTID; 19121 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 19122 19123 event_ids[wmi_diag_container_event_id] = 19124 WMI_DIAG_DATA_CONTAINER_EVENTID; 19125 19126 event_ids[wmi_host_auto_shutdown_event_id] = 19127 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 19128 19129 event_ids[wmi_update_whal_mib_stats_event_id] = 19130 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 19131 19132 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 19133 event_ids[wmi_update_vdev_rate_stats_event_id] = 19134 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 19135 19136 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 19137 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 19138 19139 /** Set OCB Sched Response, deprecated */ 19140 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 19141 19142 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 19143 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 19144 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 19145 19146 /* GPIO Event */ 19147 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 19148 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 19149 19150 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 19151 event_ids[wmi_rfkill_state_change_event_id] = 19152 WMI_RFKILL_STATE_CHANGE_EVENTID; 19153 19154 /* TDLS Event */ 19155 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 19156 19157 event_ids[wmi_batch_scan_enabled_event_id] = 19158 WMI_BATCH_SCAN_ENABLED_EVENTID; 19159 event_ids[wmi_batch_scan_result_event_id] = 19160 WMI_BATCH_SCAN_RESULT_EVENTID; 19161 /* OEM Event */ 19162 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 19163 event_ids[wmi_oem_meas_report_event_id] = 19164 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 19165 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 19166 19167 /* NAN Event */ 19168 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 19169 19170 /* LPI Event */ 19171 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 19172 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 19173 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 19174 19175 /* ExtScan events */ 19176 event_ids[wmi_extscan_start_stop_event_id] = 19177 WMI_EXTSCAN_START_STOP_EVENTID; 19178 event_ids[wmi_extscan_operation_event_id] = 19179 WMI_EXTSCAN_OPERATION_EVENTID; 19180 event_ids[wmi_extscan_table_usage_event_id] = 19181 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 19182 event_ids[wmi_extscan_cached_results_event_id] = 19183 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 19184 event_ids[wmi_extscan_wlan_change_results_event_id] = 19185 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 19186 event_ids[wmi_extscan_hotlist_match_event_id] = 19187 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 19188 event_ids[wmi_extscan_capabilities_event_id] = 19189 WMI_EXTSCAN_CAPABILITIES_EVENTID; 19190 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 19191 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 19192 19193 /* mDNS offload events */ 19194 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 19195 19196 /* SAP Authentication offload events */ 19197 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 19198 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 19199 19200 /** Out-of-context-of-bss (OCB) events */ 19201 event_ids[wmi_ocb_set_config_resp_event_id] = 19202 WMI_OCB_SET_CONFIG_RESP_EVENTID; 19203 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 19204 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 19205 event_ids[wmi_dcc_get_stats_resp_event_id] = 19206 WMI_DCC_GET_STATS_RESP_EVENTID; 19207 event_ids[wmi_dcc_update_ndl_resp_event_id] = 19208 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 19209 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 19210 /* System-On-Chip events */ 19211 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 19212 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 19213 event_ids[wmi_soc_hw_mode_transition_event_id] = 19214 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 19215 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 19216 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 19217 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 19218 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19219 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 19220 #endif 19221 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 19222 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 19223 event_ids[wmi_vdev_ocac_complete_event_id] = 19224 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 19225 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 19226 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 19227 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 19228 #ifdef CONFIG_AFC_SUPPORT 19229 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 19230 #endif 19231 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 19232 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 19233 event_ids[wmi_peer_sta_ps_statechg_event_id] = 19234 WMI_PEER_STA_PS_STATECHG_EVENTID; 19235 event_ids[wmi_pdev_channel_hopping_event_id] = 19236 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 19237 event_ids[wmi_offchan_data_tx_completion_event] = 19238 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 19239 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 19240 event_ids[wmi_dfs_radar_detection_event_id] = 19241 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 19242 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 19243 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 19244 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 19245 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 19246 event_ids[wmi_service_available_event_id] = 19247 WMI_SERVICE_AVAILABLE_EVENTID; 19248 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 19249 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 19250 /* NDP events */ 19251 event_ids[wmi_ndp_initiator_rsp_event_id] = 19252 WMI_NDP_INITIATOR_RSP_EVENTID; 19253 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 19254 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 19255 event_ids[wmi_ndp_responder_rsp_event_id] = 19256 WMI_NDP_RESPONDER_RSP_EVENTID; 19257 event_ids[wmi_ndp_end_indication_event_id] = 19258 WMI_NDP_END_INDICATION_EVENTID; 19259 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 19260 event_ids[wmi_ndl_schedule_update_event_id] = 19261 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 19262 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 19263 19264 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 19265 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 19266 event_ids[wmi_pdev_chip_power_stats_event_id] = 19267 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 19268 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 19269 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 19270 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 19271 event_ids[wmi_apf_capability_info_event_id] = 19272 WMI_BPF_CAPABILIY_INFO_EVENTID; 19273 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 19274 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 19275 event_ids[wmi_report_rx_aggr_failure_event_id] = 19276 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 19277 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 19278 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 19279 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 19280 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 19281 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 19282 event_ids[wmi_pdev_hw_mode_transition_event_id] = 19283 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 19284 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 19285 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 19286 event_ids[wmi_coex_bt_activity_event_id] = 19287 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 19288 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 19289 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 19290 event_ids[wmi_radio_tx_power_level_stats_event_id] = 19291 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 19292 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 19293 event_ids[wmi_dma_buf_release_event_id] = 19294 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 19295 event_ids[wmi_sap_obss_detection_report_event_id] = 19296 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 19297 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 19298 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 19299 event_ids[wmi_obss_color_collision_report_event_id] = 19300 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 19301 event_ids[wmi_pdev_div_rssi_antid_event_id] = 19302 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 19303 #ifdef WLAN_SUPPORT_TWT 19304 event_ids[wmi_twt_enable_complete_event_id] = 19305 WMI_TWT_ENABLE_COMPLETE_EVENTID; 19306 event_ids[wmi_twt_disable_complete_event_id] = 19307 WMI_TWT_DISABLE_COMPLETE_EVENTID; 19308 event_ids[wmi_twt_add_dialog_complete_event_id] = 19309 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 19310 event_ids[wmi_twt_del_dialog_complete_event_id] = 19311 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 19312 event_ids[wmi_twt_pause_dialog_complete_event_id] = 19313 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 19314 event_ids[wmi_twt_resume_dialog_complete_event_id] = 19315 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 19316 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 19317 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 19318 event_ids[wmi_twt_session_stats_event_id] = 19319 WMI_TWT_SESSION_STATS_EVENTID; 19320 event_ids[wmi_twt_notify_event_id] = 19321 WMI_TWT_NOTIFY_EVENTID; 19322 event_ids[wmi_twt_ack_complete_event_id] = 19323 WMI_TWT_ACK_EVENTID; 19324 #endif 19325 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 19326 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 19327 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 19328 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 19329 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 19330 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 19331 event_ids[wmi_pdev_interop_issues_ap_event_id] = 19332 WMI_PDEV_RAP_INFO_EVENTID; 19333 #endif 19334 #ifdef AST_HKV1_WORKAROUND 19335 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 19336 #endif 19337 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 19338 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 19339 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 19340 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 19341 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 19342 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 19343 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 19344 event_ids[wmi_pdev_cold_boot_cal_event_id] = 19345 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 19346 #ifdef WLAN_MWS_INFO_DEBUGFS 19347 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 19348 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 19349 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 19350 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 19351 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 19352 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 19353 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 19354 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 19355 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 19356 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 19357 #endif 19358 event_ids[wmi_coex_report_antenna_isolation_event_id] = 19359 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 19360 event_ids[wmi_peer_ratecode_list_event_id] = 19361 WMI_PEER_RATECODE_LIST_EVENTID; 19362 event_ids[wmi_chan_rf_characterization_info_event_id] = 19363 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 19364 event_ids[wmi_roam_auth_offload_event_id] = 19365 WMI_ROAM_PREAUTH_START_EVENTID; 19366 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 19367 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 19368 event_ids[wmi_motion_det_base_line_host_eventid] = 19369 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 19370 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 19371 event_ids[wmi_peer_tx_pn_response_event_id] = 19372 WMI_PEER_TX_PN_RESPONSE_EVENTID; 19373 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 19374 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 19375 event_ids[wmi_mgmt_offload_data_event_id] = 19376 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 19377 event_ids[wmi_nan_dmesg_event_id] = 19378 WMI_NAN_DMESG_EVENTID; 19379 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 19380 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 19381 event_ids[wmi_roam_pmkid_request_event_id] = 19382 WMI_ROAM_PMKID_REQUEST_EVENTID; 19383 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19384 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 19385 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 19386 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 19387 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 19388 #endif 19389 event_ids[wmi_roam_scan_chan_list_id] = 19390 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 19391 event_ids[wmi_muedca_params_config_eventid] = 19392 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 19393 event_ids[wmi_pdev_sscan_fw_param_eventid] = 19394 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 19395 event_ids[wmi_roam_cap_report_event_id] = 19396 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 19397 event_ids[wmi_vdev_bcn_latency_event_id] = 19398 WMI_VDEV_BCN_LATENCY_EVENTID; 19399 event_ids[wmi_vdev_disconnect_event_id] = 19400 WMI_VDEV_DISCONNECT_EVENTID; 19401 event_ids[wmi_peer_create_conf_event_id] = 19402 WMI_PEER_CREATE_CONF_EVENTID; 19403 event_ids[wmi_pdev_cp_fwstats_eventid] = 19404 WMI_CTRL_PATH_STATS_EVENTID; 19405 event_ids[wmi_pdev_halphy_fwstats_eventid] = 19406 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 19407 event_ids[wmi_vdev_send_big_data_p2_eventid] = 19408 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 19409 event_ids[wmi_pdev_get_dpd_status_event_id] = 19410 WMI_PDEV_GET_DPD_STATUS_EVENTID; 19411 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19412 event_ids[wmi_vdev_smart_monitor_event_id] = 19413 WMI_VDEV_SMART_MONITOR_EVENTID; 19414 #endif 19415 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 19416 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 19417 event_ids[wmi_pdev_set_halphy_cal_event_id] = 19418 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 19419 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 19420 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 19421 #ifdef WLAN_MGMT_RX_REO_SUPPORT 19422 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 19423 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 19424 #endif 19425 populate_tlv_events_id_mlo(event_ids); 19426 event_ids[wmi_roam_frame_event_id] = 19427 WMI_ROAM_FRAME_EVENTID; 19428 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19429 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 19430 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 19431 #endif 19432 #ifdef WLAN_FEATURE_MCC_QUOTA 19433 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 19434 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 19435 #endif 19436 event_ids[wmi_peer_rx_pn_response_event_id] = 19437 WMI_PEER_RX_PN_RESPONSE_EVENTID; 19438 event_ids[wmi_extract_pktlog_decode_info_eventid] = 19439 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 19440 #ifdef QCA_RSSI_DB2DBM 19441 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 19442 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 19443 #endif 19444 #ifdef MULTI_CLIENT_LL_SUPPORT 19445 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 19446 #endif 19447 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19448 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 19449 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 19450 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 19451 WMI_RTT_PASN_PEER_DELETE_EVENTID; 19452 #endif 19453 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 19454 event_ids[wmi_get_roam_vendor_control_param_event_id] = 19455 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 19456 #endif 19457 #ifdef WLAN_FEATURE_DBAM_CONFIG 19458 event_ids[wmi_coex_dbam_complete_event_id] = 19459 WMI_COEX_DBAM_COMPLETE_EVENTID; 19460 #endif 19461 event_ids[wmi_spectral_capabilities_eventid] = 19462 WMI_SPECTRAL_CAPABILITIES_EVENTID; 19463 } 19464 19465 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 19466 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 19467 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19468 { 19469 wmi_service[wmi_service_get_station_in_ll_stats_req] = 19470 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 19471 } 19472 #else 19473 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19474 { 19475 } 19476 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 19477 #else 19478 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19479 { 19480 } 19481 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 19482 19483 #ifdef WLAN_FEATURE_11BE_MLO 19484 static void populate_tlv_service_mlo(uint32_t *wmi_service) 19485 { 19486 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 19487 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 19488 } 19489 #else /* WLAN_FEATURE_11BE_MLO */ 19490 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 19491 { 19492 } 19493 #endif /* WLAN_FEATURE_11BE_MLO */ 19494 19495 /** 19496 * populate_tlv_service() - populates wmi services 19497 * 19498 * @param wmi_service: Pointer to hold wmi_service 19499 * Return: None 19500 */ 19501 static void populate_tlv_service(uint32_t *wmi_service) 19502 { 19503 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 19504 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 19505 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 19506 wmi_service[wmi_service_roam_scan_offload] = 19507 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 19508 wmi_service[wmi_service_bcn_miss_offload] = 19509 WMI_SERVICE_BCN_MISS_OFFLOAD; 19510 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 19511 wmi_service[wmi_service_sta_advanced_pwrsave] = 19512 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 19513 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 19514 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 19515 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 19516 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 19517 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 19518 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 19519 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 19520 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 19521 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 19522 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 19523 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 19524 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 19525 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 19526 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 19527 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 19528 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 19529 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 19530 wmi_service[wmi_service_packet_power_save] = 19531 WMI_SERVICE_PACKET_POWER_SAVE; 19532 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 19533 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 19534 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 19535 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 19536 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 19537 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 19538 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 19539 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 19540 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 19541 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 19542 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 19543 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 19544 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 19545 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 19546 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 19547 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 19548 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 19549 wmi_service[wmi_service_mcc_bcn_interval_change] = 19550 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 19551 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 19552 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 19553 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 19554 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 19555 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 19556 wmi_service[wmi_service_lte_ant_share_support] = 19557 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 19558 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 19559 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 19560 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 19561 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 19562 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 19563 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 19564 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 19565 wmi_service[wmi_service_bcn_txrate_override] = 19566 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 19567 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 19568 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 19569 wmi_service[wmi_service_estimate_linkspeed] = 19570 WMI_SERVICE_ESTIMATE_LINKSPEED; 19571 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 19572 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 19573 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 19574 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 19575 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 19576 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 19577 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 19578 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 19579 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 19580 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 19581 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 19582 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 19583 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 19584 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 19585 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 19586 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 19587 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 19588 wmi_service[wmi_service_sap_auth_offload] = 19589 WMI_SERVICE_SAP_AUTH_OFFLOAD; 19590 wmi_service[wmi_service_dual_band_simultaneous_support] = 19591 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 19592 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 19593 wmi_service[wmi_service_ap_arpns_offload] = 19594 WMI_SERVICE_AP_ARPNS_OFFLOAD; 19595 wmi_service[wmi_service_per_band_chainmask_support] = 19596 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 19597 wmi_service[wmi_service_packet_filter_offload] = 19598 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 19599 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 19600 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 19601 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 19602 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 19603 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 19604 wmi_service[wmi_service_multiple_vdev_restart] = 19605 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 19606 wmi_service[wmi_service_smart_antenna_sw_support] = 19607 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 19608 wmi_service[wmi_service_smart_antenna_hw_support] = 19609 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 19610 19611 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 19612 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 19613 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 19614 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 19615 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 19616 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 19617 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 19618 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 19619 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 19620 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 19621 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 19622 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 19623 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 19624 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 19625 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 19626 wmi_service[wmi_service_periodic_chan_stat_support] = 19627 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 19628 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 19629 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 19630 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 19631 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 19632 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 19633 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 19634 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 19635 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 19636 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 19637 wmi_service[wmi_service_unified_wow_capability] = 19638 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 19639 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 19640 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 19641 wmi_service[wmi_service_sync_delete_cmds] = 19642 WMI_SERVICE_SYNC_DELETE_CMDS; 19643 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 19644 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 19645 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 19646 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 19647 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 19648 wmi_service[wmi_service_deprecated_replace] = 19649 WMI_SERVICE_DEPRECATED_REPLACE; 19650 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 19651 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 19652 wmi_service[wmi_service_enhanced_mcast_filter] = 19653 WMI_SERVICE_ENHANCED_MCAST_FILTER; 19654 wmi_service[wmi_service_half_rate_quarter_rate_support] = 19655 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 19656 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 19657 wmi_service[wmi_service_p2p_listen_offload_support] = 19658 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 19659 wmi_service[wmi_service_mark_first_wakeup_packet] = 19660 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 19661 wmi_service[wmi_service_multiple_mcast_filter_set] = 19662 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 19663 wmi_service[wmi_service_host_managed_rx_reorder] = 19664 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 19665 wmi_service[wmi_service_flash_rdwr_support] = 19666 WMI_SERVICE_FLASH_RDWR_SUPPORT; 19667 wmi_service[wmi_service_wlan_stats_report] = 19668 WMI_SERVICE_WLAN_STATS_REPORT; 19669 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 19670 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 19671 wmi_service[wmi_service_dfs_phyerr_offload] = 19672 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 19673 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 19674 wmi_service[wmi_service_fw_mem_dump_support] = 19675 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 19676 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 19677 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 19678 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 19679 wmi_service[wmi_service_hw_data_filtering] = 19680 WMI_SERVICE_HW_DATA_FILTERING; 19681 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 19682 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 19683 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 19684 wmi_service[wmi_service_extended_nss_support] = 19685 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 19686 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 19687 wmi_service[wmi_service_bcn_offload_start_stop_support] = 19688 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 19689 wmi_service[wmi_service_offchan_data_tid_support] = 19690 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 19691 wmi_service[wmi_service_support_dma] = 19692 WMI_SERVICE_SUPPORT_DIRECT_DMA; 19693 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 19694 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 19695 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 19696 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 19697 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 19698 wmi_service[wmi_service_11k_neighbour_report_support] = 19699 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 19700 wmi_service[wmi_service_ap_obss_detection_offload] = 19701 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 19702 wmi_service[wmi_service_bss_color_offload] = 19703 WMI_SERVICE_BSS_COLOR_OFFLOAD; 19704 wmi_service[wmi_service_gmac_offload_support] = 19705 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 19706 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 19707 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 19708 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 19709 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 19710 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 19711 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 19712 wmi_service[wmi_service_listen_interval_offload_support] = 19713 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 19714 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 19715 wmi_service[wmi_service_obss_spatial_reuse] = 19716 WMI_SERVICE_OBSS_SPATIAL_REUSE; 19717 wmi_service[wmi_service_per_vdev_chain_support] = 19718 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 19719 wmi_service[wmi_service_new_htt_msg_format] = 19720 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 19721 wmi_service[wmi_service_peer_unmap_cnf_support] = 19722 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 19723 wmi_service[wmi_service_beacon_reception_stats] = 19724 WMI_SERVICE_BEACON_RECEPTION_STATS; 19725 wmi_service[wmi_service_vdev_latency_config] = 19726 WMI_SERVICE_VDEV_LATENCY_CONFIG; 19727 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 19728 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 19729 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 19730 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 19731 wmi_service[wmi_service_nan_disable_support] = 19732 WMI_SERVICE_NAN_DISABLE_SUPPORT; 19733 wmi_service[wmi_service_sta_plus_sta_support] = 19734 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 19735 wmi_service[wmi_service_hw_db2dbm_support] = 19736 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 19737 wmi_service[wmi_service_wlm_stats_support] = 19738 WMI_SERVICE_WLM_STATS_REQUEST; 19739 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 19740 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 19741 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 19742 wmi_service[wmi_service_cfr_capture_support] = 19743 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 19744 wmi_service[wmi_service_bcast_twt_support] = 19745 WMI_SERVICE_BROADCAST_TWT; 19746 wmi_service[wmi_service_wpa3_ft_sae_support] = 19747 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 19748 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 19749 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 19750 wmi_service[wmi_service_ft_fils] = 19751 WMI_SERVICE_WPA3_FT_FILS; 19752 wmi_service[wmi_service_adaptive_11r_support] = 19753 WMI_SERVICE_ADAPTIVE_11R_ROAM; 19754 wmi_service[wmi_service_tx_compl_tsf64] = 19755 WMI_SERVICE_TX_COMPL_TSF64; 19756 wmi_service[wmi_service_data_stall_recovery_support] = 19757 WMI_SERVICE_DSM_ROAM_FILTER; 19758 wmi_service[wmi_service_vdev_delete_all_peer] = 19759 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 19760 wmi_service[wmi_service_three_way_coex_config_legacy] = 19761 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 19762 wmi_service[wmi_service_rx_fse_support] = 19763 WMI_SERVICE_RX_FSE_SUPPORT; 19764 wmi_service[wmi_service_sae_roam_support] = 19765 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 19766 wmi_service[wmi_service_owe_roam_support] = 19767 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 19768 wmi_service[wmi_service_6ghz_support] = 19769 WMI_SERVICE_6GHZ_SUPPORT; 19770 wmi_service[wmi_service_bw_165mhz_support] = 19771 WMI_SERVICE_BW_165MHZ_SUPPORT; 19772 wmi_service[wmi_service_bw_restricted_80p80_support] = 19773 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 19774 wmi_service[wmi_service_packet_capture_support] = 19775 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 19776 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 19777 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 19778 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 19779 wmi_service[wmi_service_multiple_vdev_restart_ext] = 19780 WMI_SERVICE_UNAVAILABLE; 19781 wmi_service[wmi_service_time_sync_ftm] = 19782 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 19783 wmi_service[wmi_service_nss_ratio_to_host_support] = 19784 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 19785 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 19786 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 19787 wmi_service[wmi_beacon_protection_support] = 19788 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 19789 wmi_service[wmi_service_sta_nan_ndi_four_port] = 19790 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 19791 wmi_service[wmi_service_host_scan_stop_vdev_all] = 19792 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 19793 wmi_service[wmi_support_extend_address] = 19794 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 19795 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 19796 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 19797 wmi_service[wmi_service_suiteb_roam_support] = 19798 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 19799 wmi_service[wmi_service_no_interband_mcc_support] = 19800 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 19801 wmi_service[wmi_service_dual_sta_roam_support] = 19802 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 19803 wmi_service[wmi_service_peer_create_conf] = 19804 WMI_SERVICE_PEER_CREATE_CONF; 19805 wmi_service[wmi_service_configure_roam_trigger_param_support] = 19806 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 19807 wmi_service[wmi_service_5dot9_ghz_support] = 19808 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 19809 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 19810 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 19811 wmi_service[wmi_service_cfr_capture_count_support] = 19812 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 19813 wmi_service[wmi_service_ocv_support] = 19814 WMI_SERVICE_OCV_SUPPORT; 19815 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 19816 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 19817 wmi_service[wmi_service_thermal_multi_client_support] = 19818 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 19819 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 19820 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 19821 wmi_service[wmi_service_fse_cmem_alloc_support] = 19822 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 19823 wmi_service[wmi_service_scan_conf_per_ch_support] = 19824 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 19825 wmi_service[wmi_service_csa_beacon_template] = 19826 WMI_SERVICE_CSA_BEACON_TEMPLATE; 19827 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19828 wmi_service[wmi_service_rtt_11az_ntb_support] = 19829 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 19830 wmi_service[wmi_service_rtt_11az_tb_support] = 19831 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 19832 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 19833 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 19834 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 19835 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 19836 #endif 19837 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 19838 wmi_service[wmi_service_igmp_offload_support] = 19839 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 19840 #endif 19841 19842 #ifdef FEATURE_WLAN_TDLS 19843 #ifdef WLAN_FEATURE_11AX 19844 wmi_service[wmi_service_tdls_ax_support] = 19845 WMI_SERVICE_11AX_TDLS_SUPPORT; 19846 wmi_service[wmi_service_tdls_6g_support] = 19847 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 19848 #endif 19849 wmi_service[wmi_service_tdls_wideband_support] = 19850 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 19851 #endif 19852 19853 #ifdef WLAN_SUPPORT_TWT 19854 wmi_service[wmi_service_twt_bcast_req_support] = 19855 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 19856 wmi_service[wmi_service_twt_bcast_resp_support] = 19857 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 19858 wmi_service[wmi_service_twt_nudge] = 19859 WMI_SERVICE_TWT_NUDGE; 19860 wmi_service[wmi_service_all_twt] = 19861 WMI_SERVICE_TWT_ALL_DIALOG_ID; 19862 wmi_service[wmi_service_twt_statistics] = 19863 WMI_SERVICE_TWT_STATS; 19864 #endif 19865 wmi_service[wmi_service_spectral_scan_disabled] = 19866 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 19867 wmi_service[wmi_service_sae_eapol_offload_support] = 19868 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 19869 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 19870 19871 wmi_service[wmi_service_wapi_concurrency_supported] = 19872 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 19873 wmi_service[wmi_service_sap_connected_d3_wow] = 19874 WMI_SERVICE_SAP_CONNECTED_D3WOW; 19875 wmi_service[wmi_service_go_connected_d3_wow] = 19876 WMI_SERVICE_SAP_CONNECTED_D3WOW; 19877 wmi_service[wmi_service_ext_tpc_reg_support] = 19878 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 19879 wmi_service[wmi_service_ndi_txbf_support] = 19880 WMI_SERVICE_NDI_TXBF_SUPPORT; 19881 wmi_service[wmi_service_reg_cc_ext_event_support] = 19882 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 19883 #if defined(CONFIG_BAND_6GHZ) 19884 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 19885 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 19886 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 19887 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 19888 #endif 19889 wmi_service[wmi_service_dcs_awgn_int_support] = 19890 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 19891 wmi_populate_service_11be(wmi_service); 19892 19893 #ifdef WLAN_FEATURE_BIG_DATA_STATS 19894 wmi_service[wmi_service_big_data_support] = 19895 WMI_SERVICE_BIG_DATA_SUPPORT; 19896 #endif 19897 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 19898 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 19899 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 19900 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 19901 wmi_service[wmi_service_halphy_cal_status] = 19902 WMI_SERVICE_HALPHY_CAL_STATUS; 19903 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 19904 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 19905 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 19906 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 19907 wmi_service[wmi_service_ema_multiple_group_supported] = 19908 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 19909 wmi_service[wmi_service_large_beacon_supported] = 19910 WMI_SERVICE_LARGE_BEACON_SUPPORT; 19911 wmi_service[wmi_service_aoa_for_rcc_supported] = 19912 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 19913 #ifdef WLAN_FEATURE_P2P_P2P_STA 19914 wmi_service[wmi_service_p2p_p2p_cc_support] = 19915 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 19916 #endif 19917 #ifdef THERMAL_STATS_SUPPORT 19918 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 19919 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 19920 #endif 19921 wmi_service[wmi_service_hw_mode_policy_offload_support] = 19922 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 19923 wmi_service[wmi_service_mgmt_rx_reo_supported] = 19924 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 19925 wmi_service[wmi_service_phy_dma_byte_swap_support] = 19926 WMI_SERVICE_UNAVAILABLE; 19927 wmi_service[wmi_service_spectral_session_info_support] = 19928 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 19929 wmi_service[wmi_service_umac_hang_recovery_support] = 19930 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 19931 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 19932 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19933 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 19934 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 19935 #endif 19936 wmi_service[wmi_service_probe_all_bw_support] = 19937 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 19938 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 19939 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 19940 #ifdef QCA_UNDECODED_METADATA_SUPPORT 19941 wmi_service[wmi_service_fp_phy_err_filter_support] = 19942 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 19943 #endif 19944 populate_tlv_service_mlo(wmi_service); 19945 wmi_service[wmi_service_pdev_rate_config_support] = 19946 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 19947 wmi_service[wmi_service_multi_peer_group_cmd_support] = 19948 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 19949 #ifdef WLAN_FEATURE_11BE 19950 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 19951 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 19952 #endif 19953 wmi_service[wmi_service_pn_replay_check_support] = 19954 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 19955 #ifdef QCA_RSSI_DB2DBM 19956 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 19957 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 19958 #endif 19959 wmi_service[wmi_service_pktlog_decode_info_support] = 19960 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 19961 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19962 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 19963 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 19964 #endif 19965 #ifdef MULTI_CLIENT_LL_SUPPORT 19966 wmi_service[wmi_service_configure_multi_client_ll_support] = 19967 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 19968 #endif 19969 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 19970 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 19971 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 19972 #endif 19973 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 19974 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 19975 } 19976 19977 /** 19978 * wmi_ocb_ut_attach() - Attach OCB test framework 19979 * @wmi_handle: wmi handle 19980 * 19981 * Return: None 19982 */ 19983 #ifdef WLAN_OCB_UT 19984 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 19985 #else 19986 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 19987 { 19988 return; 19989 } 19990 #endif 19991 19992 /** 19993 * wmi_tlv_attach() - Attach TLV APIs 19994 * 19995 * Return: None 19996 */ 19997 void wmi_tlv_attach(wmi_unified_t wmi_handle) 19998 { 19999 wmi_handle->ops = &tlv_ops; 20000 wmi_ocb_ut_attach(wmi_handle); 20001 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 20002 #ifdef WMI_INTERFACE_EVENT_LOGGING 20003 /* Skip saving WMI_CMD_HDR and TLV HDR */ 20004 wmi_handle->soc->buf_offset_command = 8; 20005 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 20006 wmi_handle->soc->buf_offset_event = 4; 20007 #endif 20008 populate_tlv_events_id(wmi_handle->wmi_events); 20009 populate_tlv_service(wmi_handle->services); 20010 wmi_wds_attach_tlv(wmi_handle); 20011 wmi_twt_attach_tlv(wmi_handle); 20012 wmi_extscan_attach_tlv(wmi_handle); 20013 wmi_smart_ant_attach_tlv(wmi_handle); 20014 wmi_dbr_attach_tlv(wmi_handle); 20015 wmi_atf_attach_tlv(wmi_handle); 20016 wmi_ap_attach_tlv(wmi_handle); 20017 wmi_bcn_attach_tlv(wmi_handle); 20018 wmi_ocb_attach_tlv(wmi_handle); 20019 wmi_nan_attach_tlv(wmi_handle); 20020 wmi_p2p_attach_tlv(wmi_handle); 20021 wmi_interop_issues_ap_attach_tlv(wmi_handle); 20022 wmi_dcs_attach_tlv(wmi_handle); 20023 wmi_roam_attach_tlv(wmi_handle); 20024 wmi_concurrency_attach_tlv(wmi_handle); 20025 wmi_pmo_attach_tlv(wmi_handle); 20026 wmi_sta_attach_tlv(wmi_handle); 20027 wmi_11ax_bss_color_attach_tlv(wmi_handle); 20028 wmi_fwol_attach_tlv(wmi_handle); 20029 wmi_vdev_attach_tlv(wmi_handle); 20030 wmi_cfr_attach_tlv(wmi_handle); 20031 wmi_cp_stats_attach_tlv(wmi_handle); 20032 wmi_gpio_attach_tlv(wmi_handle); 20033 wmi_11be_attach_tlv(wmi_handle); 20034 } 20035 qdf_export_symbol(wmi_tlv_attach); 20036 20037 /** 20038 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 20039 * 20040 * Return: None 20041 */ 20042 void wmi_tlv_init(void) 20043 { 20044 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 20045 } 20046