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 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 127 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 128 }; 129 130 /** 131 * Populate pdev_param_value whose index is host param and value is target 132 * param 133 */ 134 static const uint32_t pdev_param_tlv[] = { 135 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 136 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 137 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 138 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 139 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 140 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 141 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 142 [wmi_pdev_param_resmgr_offchan_mode] = 143 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 144 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 145 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 146 [wmi_pdev_param_non_agg_sw_retry_th] = 147 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 148 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 149 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 150 [wmi_pdev_param_ac_aggrsize_scaling] = 151 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 152 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 153 [wmi_pdev_param_ltr_ac_latency_be] = 154 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 155 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 156 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 157 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 158 [wmi_pdev_param_ltr_ac_latency_timeout] = 159 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 160 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 161 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 162 [wmi_pdev_param_ltr_tx_activity_timeout] = 163 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 164 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 165 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 166 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 167 [wmi_pdev_param_pcielp_txbuf_watermark] = 168 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 169 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 170 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 171 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 172 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 173 [wmi_pdev_param_pdev_stats_update_period] = 174 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_vdev_stats_update_period] = 176 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 177 [wmi_pdev_param_peer_stats_update_period] = 178 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 179 [wmi_pdev_param_bcnflt_stats_update_period] = 180 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 181 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 182 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 183 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 184 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 185 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 186 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 187 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 188 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 189 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 190 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 191 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 192 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 193 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 194 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 195 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 196 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 197 [wmi_pdev_param_low_power_rf_enable] = 198 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 199 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 200 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 201 [wmi_pdev_param_power_collapse_enable] = 202 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 203 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 204 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 205 [wmi_pdev_param_audio_over_wlan_latency] = 206 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 207 [wmi_pdev_param_audio_over_wlan_enable] = 208 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 209 [wmi_pdev_param_whal_mib_stats_update_enable] = 210 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 211 [wmi_pdev_param_vdev_rate_stats_update_period] = 212 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 213 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 214 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 215 [wmi_pdev_param_adaptive_early_rx_enable] = 216 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 217 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 218 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 219 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 220 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 221 [wmi_pdev_param_early_rx_fix_sleep_slop] = 222 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 223 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 224 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 225 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 226 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 227 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 228 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 229 [wmi_pdev_param_bto_fix_bcn_timeout] = 230 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 231 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 232 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 233 [wmi_pdev_param_ce_bto_combo_ce_value] = 234 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 235 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 236 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 237 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 238 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 239 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 240 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 241 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 242 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 243 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 244 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 245 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 246 [wmi_pdev_peer_sta_ps_statechg_enable] = 247 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 248 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 249 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 250 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 251 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 252 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 253 [wmi_pdev_param_set_mcast_bcast_echo] = 254 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 255 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 256 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 257 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 258 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 259 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 260 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 261 [wmi_pdev_param_enable_per_tid_amsdu] = 262 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 263 [wmi_pdev_param_enable_per_tid_ampdu] = 264 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 265 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 266 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 267 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 268 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 269 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 270 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 271 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 272 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 273 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 274 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 275 [wmi_pdev_param_atf_obss_noise_sch] = 276 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 277 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 278 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 279 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 280 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 281 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 282 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 283 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 284 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 285 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 286 [wmi_pdev_param_set_disable_reset_cmdid] = 287 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 288 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 289 [wmi_pdev_param_txbf_sound_period_cmdid] = 290 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 291 [wmi_pdev_param_set_burst_mode_cmdid] = 292 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 293 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 294 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 295 [wmi_pdev_param_set_promisc_mode_cmdid] = 296 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 297 [wmi_pdev_param_set_ppdu_duration_cmdid] = 298 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 299 [wmi_pdev_param_remove_mcast2ucast_buffer] = 300 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 301 [wmi_pdev_param_set_mcast2ucast_buffer] = 302 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 303 [wmi_pdev_param_set_mcast2ucast_mode] = 304 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 305 [wmi_pdev_param_smart_antenna_default_antenna] = 306 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 307 [wmi_pdev_param_fast_channel_reset] = 308 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 309 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 310 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 311 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 312 [wmi_pdev_param_antenna_gain_half_db] = 313 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 314 [wmi_pdev_param_esp_indication_period] = 315 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 316 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 317 [wmi_pdev_param_esp_airtime_fraction] = 318 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 319 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 320 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 321 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 322 /* Trigger interval for all trigger types. */ 323 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 324 [wmi_pdev_param_sub_channel_marking] = 325 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 326 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 327 [wmi_pdev_param_equal_ru_allocation_enable] = 328 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 329 [wmi_pdev_param_per_peer_prd_cfr_enable] = 330 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 331 [wmi_pdev_param_nav_override_config] = 332 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 333 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 334 [wmi_pdev_param_set_prb_rsp_ttl] = 335 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 336 [wmi_pdev_param_set_mu_ppdu_duration] = 337 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 338 [wmi_pdev_param_set_tbtt_ctrl] = 339 WMI_PDEV_PARAM_SET_TBTT_CTRL, 340 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 341 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 342 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 343 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 344 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 345 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 346 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 347 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 348 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 349 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 350 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 351 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 352 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 353 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 354 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 355 [wmi_pdev_param_low_latency_mode] = 356 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 357 [wmi_pdev_param_scan_radio_tx_on_dfs] = 358 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 359 [wmi_pdev_param_en_probe_all_bw] = 360 WMI_PDEV_PARAM_EN_PROBE_ALL_BW, 361 [wmi_pdev_param_obss_min_duration_check_for_sr] = 362 WMI_PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR, 363 [wmi_pdev_param_truncate_sr] = WMI_PDEV_PARAM_TRUNCATE_SR, 364 [wmi_pdev_param_ctrl_frame_obss_pd_threshold] = 365 WMI_PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD, 366 [wmi_pdev_param_rate_upper_cap] = WMI_PDEV_PARAM_RATE_UPPER_CAP, 367 [wmi_pdev_param_rate_retry_mcs_drop] = 368 WMI_PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH, 369 [wmi_pdev_param_mcs_probe_intvl] = 370 WMI_PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL, 371 [wmi_pdev_param_nss_probe_intvl] = 372 WMI_PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL, 373 [wmi_pdev_param_dtim_synth] = WMI_PDEV_PARAM_DTIM_SYNTH, 374 [wmi_pdev_param_1ch_dtim_optimized_chain_selection] = 375 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION, 376 [wmi_pdev_param_tx_sch_delay] = WMI_PDEV_PARAM_TX_SCH_DELAY, 377 [wmi_pdev_param_en_update_scram_seed] = 378 WMI_PDEV_PARAM_EN_UPDATE_SCRAM_SEED, 379 [wmi_pdev_param_secondary_retry_enable] = 380 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE, 381 [wmi_pdev_param_set_sap_xlna_bypass] = 382 WMI_PDEV_PARAM_SET_SAP_XLNA_BYPASS, 383 [wmi_pdev_param_set_dfs_chan_ageout_time] = 384 WMI_PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME, 385 [wmi_pdev_param_pdev_stats_tx_xretry_ext] = 386 WMI_PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT, 387 [wmi_pdev_param_smart_chainmask_scheme] = 388 WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME, 389 [wmi_pdev_param_alternative_chainmask_scheme] = 390 WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME, 391 [wmi_pdev_param_enable_rts_sifs_bursting] = 392 WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING, 393 [wmi_pdev_param_max_mpdus_in_ampdu] = WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU, 394 [wmi_pdev_param_set_iot_pattern] = WMI_PDEV_PARAM_SET_IOT_PATTERN, 395 [wmi_pdev_param_mwscoex_scc_chavd_delay] = 396 WMI_PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY, 397 [wmi_pdev_param_mwscoex_pcc_chavd_delay] = 398 WMI_PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY, 399 [wmi_pdev_param_mwscoex_set_5gnr_pwr_limit] = 400 WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT, 401 [wmi_pdev_param_mwscoex_4g_allow_quick_ftdm] = 402 WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM, 403 [wmi_pdev_param_fast_pwr_transition] = 404 WMI_PDEV_PARAM_FAST_PWR_TRANSITION, 405 [wmi_pdev_auto_detect_power_failure] = 406 WMI_PDEV_AUTO_DETECT_POWER_FAILURE, 407 [wmi_pdev_param_gcmp_support_enable] = 408 WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE, 409 [wmi_pdev_param_abg_mode_tx_chain_num] = 410 WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 411 [wmi_pdev_param_peer_stats_info_enable] = 412 WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE, 413 [wmi_pdev_param_enable_cck_txfir_override] = 414 WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE, 415 [wmi_pdev_param_twt_ac_config] = WMI_PDEV_PARAM_TWT_AC_CONFIG, 416 [wmi_pdev_param_pcie_hw_ilp] = WMI_PDEV_PARAM_PCIE_HW_ILP, 417 [wmi_pdev_param_disable_hw_assist] = WMI_PDEV_PARAM_DISABLE_HW_ASSIST, 418 [wmi_pdev_param_ant_div_usrcfg] = WMI_PDEV_PARAM_ANT_DIV_USRCFG, 419 [wmi_pdev_param_ctrl_retry_limit] = WMI_PDEV_PARAM_CTRL_RETRY_LIMIT, 420 [wmi_pdev_param_propagation_delay] = WMI_PDEV_PARAM_PROPAGATION_DELAY, 421 [wmi_pdev_param_ena_ant_div] = WMI_PDEV_PARAM_ENA_ANT_DIV, 422 [wmi_pdev_param_force_chain_ant] = WMI_PDEV_PARAM_FORCE_CHAIN_ANT, 423 [wmi_pdev_param_ant_div_selftest] = WMI_PDEV_PARAM_ANT_DIV_SELFTEST, 424 [wmi_pdev_param_ant_div_selftest_intvl] = 425 WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL, 426 [wmi_pdev_param_1ch_dtim_optimized_chain_selection] = 427 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION, 428 [wmi_pdev_param_data_stall_detect_enable] = 429 WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE, 430 [wmi_pdev_param_max_mpdus_in_ampdu] = 431 WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU, 432 [wmi_pdev_param_stats_observation_period] = 433 WMI_PDEV_PARAM_STATS_OBSERVATION_PERIOD, 434 [wmi_pdev_param_cts2self_for_p2p_go_config] = 435 WMI_PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG, 436 [wmi_pdev_param_txpower_reason_sar] = WMI_PDEV_PARAM_TXPOWER_REASON_SAR, 437 }; 438 439 /** 440 * Populate vdev_param_value_tlv array whose index is host param 441 * and value is target param 442 */ 443 static const uint32_t vdev_param_tlv[] = { 444 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 445 [wmi_vdev_param_fragmentation_threshold] = 446 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 447 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 448 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 449 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 450 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 451 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 452 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 453 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 454 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 455 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 456 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 457 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 458 [wmi_vdev_oc_scheduler_air_time_limit] = 459 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 460 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 461 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 462 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 463 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 464 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 465 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 466 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 467 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 468 [wmi_vdev_param_disable_htprotection] = 469 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 470 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 471 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 472 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 473 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 474 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 475 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 476 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 477 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 478 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 479 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 480 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 481 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 482 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 483 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 484 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 485 [wmi_vdev_param_unknown_dest_indicate] = 486 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 487 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 488 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 489 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 490 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 491 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 492 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 493 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 494 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 495 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 496 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 497 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 498 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 499 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 500 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 501 [wmi_vdev_param_early_rx_adjust_enable] = 502 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 503 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 504 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 505 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 506 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 507 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 508 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 509 [wmi_vdev_param_early_rx_adjust_pause] = 510 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 511 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 512 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 513 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 514 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 515 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 516 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 517 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 518 [wmi_vdev_param_early_rx_drift_sample] = 519 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 520 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 521 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 522 [wmi_vdev_param_ebt_resync_timeout] = 523 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 524 [wmi_vdev_param_aggr_trig_event_enable] = 525 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 526 [wmi_vdev_param_is_ibss_power_save_allowed] = 527 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 528 [wmi_vdev_param_is_power_collapse_allowed] = 529 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 530 [wmi_vdev_param_is_awake_on_txrx_enabled] = 531 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 532 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 533 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 534 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 535 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 536 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 537 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 538 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 539 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 540 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 541 [wmi_vdev_param_stats_avg_factor] = 542 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 543 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 544 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 545 [wmi_vdev_param_mcc_rtscts_protection_enable] = 546 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 547 [wmi_vdev_param_mcc_broadcast_probe_enable] = 548 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 549 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 550 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 551 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 552 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 553 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 554 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 555 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 556 [wmi_vdev_param_set_he_sounding_mode] = 557 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 558 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 559 #ifdef WLAN_FEATURE_11BE 560 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 561 [wmi_vdev_param_set_eht_mu_mode] = WMI_VDEV_PARAM_SET_EHT_MU_MODE, 562 [wmi_vdev_param_set_eht_puncturing_mode] = 563 WMI_VDEV_PARAM_SET_EHT_PUNCTURING_MODE, 564 [wmi_vdev_param_set_eht_ltf] = WMI_VDEV_PARAM_EHT_LTF, 565 [wmi_vdev_param_set_ul_eht_ltf] = WMI_VDEV_PARAM_UL_EHT_LTF, 566 [wmi_vdev_param_set_eht_dcm] = WMI_VDEV_PARAM_EHT_DCM, 567 [wmi_vdev_param_set_eht_range_ext] = WMI_VDEV_PARAM_EHT_RANGE_EXT, 568 [wmi_vdev_param_set_non_data_eht_range_ext] = 569 WMI_VDEV_PARAM_NON_DATA_EHT_RANGE_EXT, 570 #endif 571 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 572 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 573 [wmi_vdev_param_atf_ssid_sched_policy] = 574 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 575 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 576 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 577 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 578 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 579 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 580 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 581 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 582 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 583 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 584 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 585 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 586 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 587 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 588 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 589 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 590 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 591 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 592 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 593 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 594 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 595 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 596 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 597 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 598 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 599 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 600 [wmi_vdev_param_mcast_rc_stale_period] = 601 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 602 [wmi_vdev_param_enable_multi_group_key] = 603 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 604 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 605 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 606 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 607 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 608 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 609 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 610 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 611 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 612 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 613 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 614 [wmi_vdev_param_nan_config_features] = 615 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 616 [wmi_vdev_param_enable_disable_rtt_responder_role] = 617 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 618 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 619 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 620 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 621 #ifdef MULTI_CLIENT_LL_SUPPORT 622 [wmi_vdev_param_set_normal_latency_flags_config] = 623 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 624 [wmi_vdev_param_set_xr_latency_flags_config] = 625 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 626 [wmi_vdev_param_set_low_latency_flags_config] = 627 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 628 [wmi_vdev_param_set_ultra_low_latency_flags_config] = 629 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 630 [wmi_vdev_param_set_normal_latency_ul_dl_config] = 631 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 632 [wmi_vdev_param_set_xr_latency_ul_dl_config] = 633 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 634 [wmi_vdev_param_set_low_latency_ul_dl_config] = 635 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 636 [wmi_vdev_param_set_ultra_low_latency_ul_dl_config] = 637 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 638 [wmi_vdev_param_set_default_ll_config] = 639 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 640 [wmi_vdev_param_set_multi_client_ll_feature_config] = 641 WMI_VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION, 642 #endif 643 [wmi_vdev_param_set_traffic_config] = 644 WMI_VDEV_PARAM_VDEV_TRAFFIC_CONFIG, 645 [wmi_vdev_param_he_range_ext] = WMI_VDEV_PARAM_HE_RANGE_EXT, 646 [wmi_vdev_param_non_data_he_range_ext] = 647 WMI_VDEV_PARAM_NON_DATA_HE_RANGE_EXT, 648 [wmi_vdev_param_ndp_inactivity_timeout] = 649 WMI_VDEV_PARAM_NDP_INACTIVITY_TIMEOUT, 650 [wmi_vdev_param_ndp_keepalive_timeout] = 651 WMI_VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT, 652 [wmi_vdev_param_final_bmiss_time_sec] = 653 WMI_VDEV_PARAM_FINAL_BMISS_TIME_SEC, 654 [wmi_vdev_param_final_bmiss_time_wow_sec] = 655 WMI_VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC, 656 [wmi_vdev_param_ap_keepalive_max_idle_inactive_secs] = 657 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 658 [wmi_vdev_param_per_band_mgmt_tx_rate] = 659 WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE, 660 [wmi_vdev_param_max_li_of_moddtim] = 661 WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM, 662 [wmi_vdev_param_moddtim_cnt] = WMI_VDEV_PARAM_MODDTIM_CNT, 663 [wmi_vdev_param_max_li_of_moddtim_ms] = 664 WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM_MS, 665 [wmi_vdev_param_dyndtim_cnt] = WMI_VDEV_PARAM_DYNDTIM_CNT, 666 [wmi_vdev_param_wmm_txop_enable] = WMI_VDEV_PARAM_WMM_TXOP_ENABLE, 667 [wmi_vdev_param_enable_bcast_probe_response] = 668 WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, 669 [wmi_vdev_param_fils_max_channel_guard_time] = 670 WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, 671 [wmi_vdev_param_probe_delay] = WMI_VDEV_PARAM_PROBE_DELAY, 672 [wmi_vdev_param_repeat_probe_time] = WMI_VDEV_PARAM_REPEAT_PROBE_TIME, 673 [wmi_vdev_param_enable_disable_oce_features] = 674 WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES, 675 [wmi_vdev_param_enable_disable_nan_config_features] = 676 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 677 [wmi_vdev_param_rsn_capability] = WMI_VDEV_PARAM_RSN_CAPABILITY, 678 [wmi_vdev_param_smps_intolerant] = WMI_VDEV_PARAM_SMPS_INTOLERANT, 679 [wmi_vdev_param_abg_mode_tx_chain_num] = WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 680 [wmi_vdev_param_nth_beacon_to_host] = WMI_VDEV_PARAM_NTH_BEACON_TO_HOST, 681 [wmi_vdev_param_prohibit_data_mgmt] = WMI_VDEV_PARAM_PROHIBIT_DATA_MGMT, 682 [wmi_vdev_param_skip_roam_eapol_4way_handshake] = WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE, 683 [wmi_vdev_param_skip_sae_roam_4way_handshake] = WMI_VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE, 684 [wmi_vdev_param_roam_11kv_ctrl] = WMI_VDEV_PARAM_ROAM_11KV_CTRL, 685 [wmi_vdev_param_disable_noa_p2p_go] = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO, 686 [wmi_vdev_param_packet_capture_mode] = WMI_VDEV_PARAM_PACKET_CAPTURE_MODE, 687 [wmi_vdev_param_smart_monitor_config] = WMI_VDEV_PARAM_SMART_MONITOR_CONFIG, 688 [wmi_vdev_param_force_dtim_cnt] = WMI_VDEV_PARAM_FORCE_DTIM_CNT, 689 [wmi_vdev_param_sho_config] = WMI_VDEV_PARAM_SHO_CONFIG, 690 [wmi_vdev_param_gtx_enable] = WMI_VDEV_PARAM_GTX_ENABLE, 691 [wmi_vdev_param_mu_edca_fw_update_en] = WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN, 692 [wmi_vdev_param_enable_disable_rtt_initiator_random_mac] = 693 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC, 694 [wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster] = 695 WMI_VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER, 696 [wmi_vdev_param_txpower_scale_decr_db] = WMI_VDEV_PARAM_TXPOWER_SCALE_DECR_DB, 697 [wmi_vdev_param_txpower_scale] = WMI_VDEV_PARAM_TXPOWER_SCALE, 698 [wmi_vdev_param_agg_sw_retry_th] = WMI_VDEV_PARAM_AGG_SW_RETRY_TH, 699 [wmi_vdev_param_obsspd] = WMI_VDEV_PARAM_OBSSPD, 700 [wmi_vdev_param_multi_client_ll_feature_configuration] = 701 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 702 [wmi_vdev_param_normal_latency_flags_configuration] = 703 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 704 [wmi_vdev_param_xr_latency_flags_configuration] = 705 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 706 [wmi_vdev_param_low_latency_flags_configuration] = 707 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 708 [wmi_vdev_param_ultra_low_latency_flags_configuration] = 709 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 710 [wmi_vdev_param_normal_latency_ul_dl_configuration] = 711 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 712 [wmi_vdev_param_xr_latency_ul_dl_configuration] = 713 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 714 [wmi_vdev_param_low_latency_ul_dl_configuration] = 715 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 716 [wmi_vdev_param_ultra_low_latency_ul_dl_configuration] = 717 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 718 [wmi_vdev_param_default_latency_level_configuration] = 719 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 720 [wmi_vdev_param_amsdu_aggregation_size_optimization] = 721 WMI_VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION, 722 [wmi_vdev_param_non_agg_sw_retry_th] = 723 WMI_VDEV_PARAM_NON_AGG_SW_RETRY_TH, 724 }; 725 #endif 726 727 #ifndef WMI_PKTLOG_EVENT_CBF 728 #define WMI_PKTLOG_EVENT_CBF 0x100 729 #endif 730 731 /** 732 * Populate the pktlog event tlv array, where 733 * the values are the FW WMI events, which host 734 * uses to communicate with FW for pktlog 735 */ 736 737 static const uint32_t pktlog_event_tlv[] = { 738 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 739 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 740 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 741 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 742 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 743 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 744 WMI_PKTLOG_EVENT_SMART_ANTENNA, 745 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 746 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 747 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 748 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 749 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 750 #ifdef BE_PKTLOG_SUPPORT 751 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 752 #endif 753 }; 754 755 /** 756 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 757 * host to target defines. 758 * @wmi_handle: pointer to wmi_handle 759 * @param pdev_id: host pdev_id to be converted. 760 * Return: target pdev_id after conversion. 761 */ 762 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 763 uint32_t pdev_id) 764 { 765 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 766 if (!wmi_handle->soc->is_pdev_is_map_enable) { 767 switch (pdev_id) { 768 case WMI_HOST_PDEV_ID_0: 769 return WMI_PDEV_ID_1ST; 770 case WMI_HOST_PDEV_ID_1: 771 return WMI_PDEV_ID_2ND; 772 case WMI_HOST_PDEV_ID_2: 773 return WMI_PDEV_ID_3RD; 774 } 775 } else { 776 return wmi_handle->cmd_pdev_id_map[pdev_id]; 777 } 778 } else { 779 return WMI_PDEV_ID_SOC; 780 } 781 782 QDF_ASSERT(0); 783 784 return WMI_PDEV_ID_SOC; 785 } 786 787 /** 788 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 789 * target to host defines. 790 * @wmi_handle: pointer to wmi_handle 791 * @param pdev_id: target pdev_id to be converted. 792 * Return: host pdev_id after conversion. 793 */ 794 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 795 uint32_t pdev_id) 796 { 797 798 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 799 if (!wmi_handle->soc->is_pdev_is_map_enable) { 800 switch (pdev_id) { 801 case WMI_PDEV_ID_1ST: 802 return WMI_HOST_PDEV_ID_0; 803 case WMI_PDEV_ID_2ND: 804 return WMI_HOST_PDEV_ID_1; 805 case WMI_PDEV_ID_3RD: 806 return WMI_HOST_PDEV_ID_2; 807 } 808 } else { 809 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 810 } 811 } else if (pdev_id == WMI_PDEV_ID_SOC) { 812 return WMI_HOST_PDEV_ID_SOC; 813 } else { 814 wmi_err("Invalid pdev_id"); 815 } 816 817 return WMI_HOST_PDEV_ID_INVALID; 818 } 819 820 /** 821 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 822 * host to target defines. 823 * @wmi_handle: pointer to wmi_handle 824 * @param phy_id: host pdev_id to be converted. 825 * Return: target phy_id after conversion. 826 */ 827 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 828 uint32_t phy_id) 829 { 830 if (!wmi_handle->soc->is_phy_id_map_enable || 831 phy_id >= WMI_MAX_RADIOS) { 832 return phy_id; 833 } 834 835 return wmi_handle->cmd_phy_id_map[phy_id]; 836 } 837 838 /** 839 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 840 * target to host defines. 841 * @wmi_handle: pointer to wmi_handle 842 * @param phy_id: target phy_id to be converted. 843 * Return: host phy_id after conversion. 844 */ 845 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 846 uint32_t phy_id) 847 { 848 if (!wmi_handle->soc->is_phy_id_map_enable || 849 phy_id >= WMI_MAX_RADIOS) { 850 return phy_id; 851 } 852 853 return wmi_handle->evt_phy_id_map[phy_id]; 854 } 855 856 /** 857 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 858 * 859 * Return None. 860 */ 861 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 862 uint32_t *pdev_id_map, 863 uint8_t size) 864 { 865 int i = 0; 866 867 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 868 for (i = 0; i < size; i++) { 869 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 870 wmi_handle->evt_pdev_id_map[i] = 871 WMI_HOST_PDEV_ID_INVALID; 872 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 873 wmi_handle->evt_phy_id_map[i] = 874 WMI_HOST_PDEV_ID_INVALID; 875 } 876 877 for (i = 0; i < size; i++) { 878 if (wmi_handle->cmd_pdev_id_map[i] != 879 WMI_HOST_PDEV_ID_INVALID) { 880 wmi_handle->evt_pdev_id_map 881 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 882 } 883 if (wmi_handle->cmd_phy_id_map[i] != 884 WMI_HOST_PDEV_ID_INVALID) { 885 wmi_handle->evt_phy_id_map 886 [wmi_handle->cmd_phy_id_map[i]] = i; 887 } 888 } 889 wmi_handle->soc->is_pdev_is_map_enable = true; 890 wmi_handle->soc->is_phy_id_map_enable = true; 891 } else { 892 wmi_handle->soc->is_pdev_is_map_enable = false; 893 wmi_handle->soc->is_phy_id_map_enable = false; 894 } 895 896 wmi_handle->ops->convert_pdev_id_host_to_target = 897 convert_host_pdev_id_to_target_pdev_id; 898 wmi_handle->ops->convert_pdev_id_target_to_host = 899 convert_target_pdev_id_to_host_pdev_id; 900 901 /* phy_id convert function assignments */ 902 wmi_handle->ops->convert_phy_id_host_to_target = 903 convert_host_phy_id_to_target_phy_id; 904 wmi_handle->ops->convert_phy_id_target_to_host = 905 convert_target_phy_id_to_host_phy_id; 906 } 907 908 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 909 * buffer. 910 * @wmi_handle: pointer to wmi_handle 911 * @cmd: pointer target vdev create command buffer 912 * @param: pointer host params for vdev create 913 * 914 * Return: None 915 */ 916 static inline void copy_vdev_create_pdev_id( 917 struct wmi_unified *wmi_handle, 918 wmi_vdev_create_cmd_fixed_param * cmd, 919 struct vdev_create_params *param) 920 { 921 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 922 wmi_handle, 923 param->pdev_id); 924 } 925 926 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 927 { 928 uint16_t mtrace_message_id; 929 930 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 931 (QDF_WMI_MTRACE_GRP_ID(message_id) << 932 QDF_WMI_MTRACE_CMD_NUM_BITS); 933 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 934 mtrace_message_id, vdev_id, data); 935 } 936 qdf_export_symbol(wmi_mtrace); 937 938 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 939 wmi_buf_t buf, 940 uint32_t buflen, uint32_t cmd_id, 941 bool is_qmi_send_support) 942 { 943 if (!is_qmi_send_support) 944 goto send_over_wmi; 945 946 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 947 goto send_over_wmi; 948 949 if (wmi_is_target_suspend_acked(wmi_handle)) { 950 if (QDF_IS_STATUS_SUCCESS( 951 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 952 buflen, cmd_id))) 953 return QDF_STATUS_SUCCESS; 954 } 955 956 send_over_wmi: 957 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 958 959 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 960 } 961 962 /** 963 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 964 * @wmi_handle: wmi handle 965 * @param: pointer to hold vdev create parameter 966 * @macaddr: vdev mac address 967 * 968 * Return: QDF_STATUS_SUCCESS for success or error code 969 */ 970 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 971 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 972 struct vdev_create_params *param) 973 { 974 wmi_vdev_create_cmd_fixed_param *cmd; 975 wmi_buf_t buf; 976 int32_t len = sizeof(*cmd); 977 QDF_STATUS ret; 978 int num_bands = 2; 979 uint8_t *buf_ptr; 980 wmi_vdev_txrx_streams *txrx_streams; 981 982 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 983 len += vdev_create_mlo_params_size(param); 984 985 buf = wmi_buf_alloc(wmi_handle, len); 986 if (!buf) 987 return QDF_STATUS_E_NOMEM; 988 989 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 990 WMITLV_SET_HDR(&cmd->tlv_header, 991 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 992 WMITLV_GET_STRUCT_TLVLEN 993 (wmi_vdev_create_cmd_fixed_param)); 994 cmd->vdev_id = param->vdev_id; 995 cmd->vdev_type = param->type; 996 cmd->vdev_subtype = param->subtype; 997 cmd->flags = param->mbssid_flags; 998 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 999 cmd->vdevid_trans = param->vdevid_trans; 1000 cmd->num_cfg_txrx_streams = num_bands; 1001 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 1002 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 1003 cmd->vdev_stats_id = param->vdev_stats_id; 1004 #endif 1005 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 1006 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 1007 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 1008 param->vdev_id, cmd->pdev_id, 1009 QDF_MAC_ADDR_REF(macaddr)); 1010 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 1011 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1012 (num_bands * sizeof(wmi_vdev_txrx_streams))); 1013 buf_ptr += WMI_TLV_HDR_SIZE; 1014 1015 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1016 param->type, param->subtype, 1017 param->nss_2g, param->nss_5g); 1018 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1019 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1020 txrx_streams->supported_tx_streams = param->nss_2g; 1021 txrx_streams->supported_rx_streams = param->nss_2g; 1022 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1023 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1024 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1025 1026 txrx_streams++; 1027 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1028 txrx_streams->supported_tx_streams = param->nss_5g; 1029 txrx_streams->supported_rx_streams = param->nss_5g; 1030 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1031 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1032 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1033 1034 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1035 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1036 1037 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1038 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1039 if (QDF_IS_STATUS_ERROR(ret)) { 1040 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1041 wmi_buf_free(buf); 1042 } 1043 1044 return ret; 1045 } 1046 1047 /** 1048 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1049 * @wmi_handle: wmi handle 1050 * @if_id: vdev id 1051 * 1052 * Return: QDF_STATUS_SUCCESS for success or error code 1053 */ 1054 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1055 uint8_t if_id) 1056 { 1057 wmi_vdev_delete_cmd_fixed_param *cmd; 1058 wmi_buf_t buf; 1059 QDF_STATUS ret; 1060 1061 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1062 if (!buf) 1063 return QDF_STATUS_E_NOMEM; 1064 1065 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1066 WMITLV_SET_HDR(&cmd->tlv_header, 1067 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1068 WMITLV_GET_STRUCT_TLVLEN 1069 (wmi_vdev_delete_cmd_fixed_param)); 1070 cmd->vdev_id = if_id; 1071 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1072 ret = wmi_unified_cmd_send(wmi_handle, buf, 1073 sizeof(wmi_vdev_delete_cmd_fixed_param), 1074 WMI_VDEV_DELETE_CMDID); 1075 if (QDF_IS_STATUS_ERROR(ret)) { 1076 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1077 wmi_buf_free(buf); 1078 } 1079 wmi_debug("vdev id = %d", if_id); 1080 1081 return ret; 1082 } 1083 1084 /** 1085 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1086 * @wmi_handle: wmi handle 1087 * @vdev_id: vdev id 1088 * @nss_chains_user_cfg: user configured nss chain params 1089 * 1090 * Return: QDF_STATUS_SUCCESS for success or error code 1091 */ 1092 static QDF_STATUS 1093 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1094 uint8_t vdev_id, 1095 struct vdev_nss_chains *user_cfg) 1096 { 1097 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1098 wmi_buf_t buf; 1099 QDF_STATUS ret; 1100 1101 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1102 if (!buf) 1103 return QDF_STATUS_E_NOMEM; 1104 1105 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1106 WMITLV_SET_HDR(&cmd->tlv_header, 1107 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1108 WMITLV_GET_STRUCT_TLVLEN 1109 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1110 cmd->vdev_id = vdev_id; 1111 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1112 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1113 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1114 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1115 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1116 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1117 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1118 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1119 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1120 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1121 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1122 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1123 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1124 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1125 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1126 1127 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1128 ret = wmi_unified_cmd_send(wmi_handle, buf, 1129 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1130 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1131 if (QDF_IS_STATUS_ERROR(ret)) { 1132 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1133 wmi_buf_free(buf); 1134 } 1135 wmi_debug("vdev_id %d", vdev_id); 1136 1137 return ret; 1138 } 1139 1140 /** 1141 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1142 * @wmi: wmi handle 1143 * @vdev_id: vdev id 1144 * 1145 * Return: QDF_STATUS_SUCCESS for success or erro code 1146 */ 1147 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1148 uint8_t vdev_id) 1149 { 1150 wmi_vdev_stop_cmd_fixed_param *cmd; 1151 wmi_buf_t buf; 1152 int32_t len = sizeof(*cmd); 1153 1154 buf = wmi_buf_alloc(wmi, len); 1155 if (!buf) 1156 return QDF_STATUS_E_NOMEM; 1157 1158 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1159 WMITLV_SET_HDR(&cmd->tlv_header, 1160 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1161 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1162 cmd->vdev_id = vdev_id; 1163 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1164 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1165 wmi_err("Failed to send vdev stop command"); 1166 wmi_buf_free(buf); 1167 return QDF_STATUS_E_FAILURE; 1168 } 1169 wmi_debug("vdev id = %d", vdev_id); 1170 1171 return 0; 1172 } 1173 1174 /** 1175 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1176 * @wmi: wmi handle 1177 * @vdev_id: vdev id 1178 * 1179 * Return: QDF_STATUS_SUCCESS for success or error code 1180 */ 1181 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1182 { 1183 wmi_vdev_down_cmd_fixed_param *cmd; 1184 wmi_buf_t buf; 1185 int32_t len = sizeof(*cmd); 1186 1187 buf = wmi_buf_alloc(wmi, len); 1188 if (!buf) 1189 return QDF_STATUS_E_NOMEM; 1190 1191 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1192 WMITLV_SET_HDR(&cmd->tlv_header, 1193 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1194 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1195 cmd->vdev_id = vdev_id; 1196 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1197 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1198 wmi_err("Failed to send vdev down"); 1199 wmi_buf_free(buf); 1200 return QDF_STATUS_E_FAILURE; 1201 } 1202 wmi_debug("vdev_id %d", vdev_id); 1203 1204 return 0; 1205 } 1206 1207 static inline void copy_channel_info( 1208 wmi_vdev_start_request_cmd_fixed_param * cmd, 1209 wmi_channel *chan, 1210 struct vdev_start_params *req) 1211 { 1212 chan->mhz = req->channel.mhz; 1213 1214 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1215 1216 chan->band_center_freq1 = req->channel.cfreq1; 1217 chan->band_center_freq2 = req->channel.cfreq2; 1218 1219 if (req->channel.half_rate) 1220 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1221 else if (req->channel.quarter_rate) 1222 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1223 1224 if (req->channel.dfs_set) { 1225 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1226 cmd->disable_hw_ack = req->disable_hw_ack; 1227 } 1228 1229 if (req->channel.dfs_set_cfreq2) 1230 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1231 1232 if (req->channel.is_stadfs_en) 1233 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1234 1235 /* According to firmware both reg power and max tx power 1236 * on set channel power is used and set it to max reg 1237 * power from regulatory. 1238 */ 1239 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1240 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1241 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1242 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1243 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1244 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1245 1246 } 1247 1248 /** 1249 * vdev_start_cmd_fill_11be() - 11be information fiiling in vdev_ststart 1250 * @cmd: wmi cmd 1251 * @req: vdev start params 1252 * 1253 * Return: QDF status 1254 */ 1255 #ifdef WLAN_FEATURE_11BE 1256 static void 1257 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1258 struct vdev_start_params *req) 1259 { 1260 cmd->eht_ops = req->eht_ops; 1261 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1262 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1263 req->eht_ops, req->channel.puncture_bitmap, 1264 cmd->puncture_20mhz_bitmap); 1265 } 1266 #else 1267 static void 1268 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1269 struct vdev_start_params *req) 1270 { 1271 } 1272 #endif 1273 1274 /** 1275 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1276 * @wmi_handle: wmi handle 1277 * @req: vdev start params 1278 * 1279 * Return: QDF status 1280 */ 1281 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1282 struct vdev_start_params *req) 1283 { 1284 wmi_vdev_start_request_cmd_fixed_param *cmd; 1285 wmi_buf_t buf; 1286 wmi_channel *chan; 1287 int32_t len, ret; 1288 uint8_t *buf_ptr; 1289 1290 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1291 if (!req->is_restart) 1292 len += vdev_start_mlo_params_size(req); 1293 buf = wmi_buf_alloc(wmi_handle, len); 1294 if (!buf) 1295 return QDF_STATUS_E_NOMEM; 1296 1297 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1298 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1299 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1300 WMITLV_SET_HDR(&cmd->tlv_header, 1301 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1302 WMITLV_GET_STRUCT_TLVLEN 1303 (wmi_vdev_start_request_cmd_fixed_param)); 1304 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1305 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1306 cmd->vdev_id = req->vdev_id; 1307 1308 /* Fill channel info */ 1309 copy_channel_info(cmd, chan, req); 1310 cmd->beacon_interval = req->beacon_interval; 1311 cmd->dtim_period = req->dtim_period; 1312 1313 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1314 if (req->bcn_tx_rate_code) 1315 wmi_enable_bcn_ratecode(&cmd->flags); 1316 1317 if (!req->is_restart) { 1318 if (req->pmf_enabled) 1319 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1320 1321 cmd->mbss_capability_flags = req->mbssid_flags; 1322 cmd->vdevid_trans = req->vdevid_trans; 1323 } 1324 1325 /* Copy the SSID */ 1326 if (req->ssid.length) { 1327 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1328 cmd->ssid.ssid_len = req->ssid.length; 1329 else 1330 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1331 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1332 cmd->ssid.ssid_len); 1333 } 1334 1335 if (req->hidden_ssid) 1336 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1337 1338 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1339 cmd->num_noa_descriptors = req->num_noa_descriptors; 1340 cmd->preferred_rx_streams = req->preferred_rx_streams; 1341 cmd->preferred_tx_streams = req->preferred_tx_streams; 1342 cmd->cac_duration_ms = req->cac_duration_ms; 1343 cmd->regdomain = req->regdomain; 1344 cmd->he_ops = req->he_ops; 1345 1346 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1347 sizeof(wmi_channel)); 1348 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1349 cmd->num_noa_descriptors * 1350 sizeof(wmi_p2p_noa_descriptor)); 1351 if (!req->is_restart) { 1352 buf_ptr += WMI_TLV_HDR_SIZE + 1353 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1354 1355 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1356 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1357 } 1358 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1359 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1360 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1361 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1362 "req->dis_hw_ack: %d ", req->vdev_id, 1363 chan->mhz, req->channel.phy_mode, chan->info, 1364 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1365 chan->band_center_freq1, chan->band_center_freq2, 1366 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1367 req->preferred_tx_streams, req->preferred_rx_streams, 1368 req->ldpc_rx_enabled, req->cac_duration_ms, 1369 req->regdomain, req->he_ops, 1370 req->disable_hw_ack); 1371 1372 vdev_start_cmd_fill_11be(cmd, req); 1373 1374 if (req->is_restart) { 1375 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1376 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1377 WMI_VDEV_RESTART_REQUEST_CMDID); 1378 } else { 1379 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1380 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1381 WMI_VDEV_START_REQUEST_CMDID); 1382 } 1383 if (ret) { 1384 wmi_err("Failed to send vdev start command"); 1385 wmi_buf_free(buf); 1386 return QDF_STATUS_E_FAILURE; 1387 } 1388 1389 return QDF_STATUS_SUCCESS; 1390 } 1391 1392 /** 1393 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1394 * @wmi: wmi handle 1395 * @peer_addr: peer mac address 1396 * @param: pointer to hold peer flush tid parameter 1397 * 1398 * Return: 0 for success or error code 1399 */ 1400 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1401 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1402 struct peer_flush_params *param) 1403 { 1404 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1405 wmi_buf_t buf; 1406 int32_t len = sizeof(*cmd); 1407 1408 buf = wmi_buf_alloc(wmi, len); 1409 if (!buf) 1410 return QDF_STATUS_E_NOMEM; 1411 1412 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1413 WMITLV_SET_HDR(&cmd->tlv_header, 1414 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1415 WMITLV_GET_STRUCT_TLVLEN 1416 (wmi_peer_flush_tids_cmd_fixed_param)); 1417 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1418 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1419 cmd->vdev_id = param->vdev_id; 1420 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1421 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1422 param->peer_tid_bitmap); 1423 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1424 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1425 wmi_err("Failed to send flush tid command"); 1426 wmi_buf_free(buf); 1427 return QDF_STATUS_E_FAILURE; 1428 } 1429 1430 return 0; 1431 } 1432 1433 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1434 /** 1435 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1436 * @policy: The target i/f flush policy value 1437 * 1438 * Return: WMI layer flush policy 1439 */ 1440 static wmi_peer_flush_policy 1441 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1442 { 1443 switch (policy) { 1444 case PEER_TXQ_FLUSH_POLICY_NONE: 1445 return WMI_NO_FLUSH; 1446 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1447 return WMI_TWT_FLUSH; 1448 default: 1449 return WMI_MAX_FLUSH_POLICY; 1450 } 1451 } 1452 1453 /** 1454 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1455 * @wmi: wmi handle 1456 * @para: Peer txq flush configuration 1457 * 1458 * Return: QDF status 1459 */ 1460 static QDF_STATUS 1461 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1462 struct peer_txq_flush_config_params *param) 1463 { 1464 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1465 wmi_buf_t buf; 1466 int32_t len = sizeof(*cmd); 1467 1468 buf = wmi_buf_alloc(wmi, len); 1469 if (!buf) 1470 return QDF_STATUS_E_NOMEM; 1471 1472 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1473 1474 WMITLV_SET_HDR(&cmd->tlv_header, 1475 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1476 WMITLV_GET_STRUCT_TLVLEN 1477 (wmi_peer_flush_policy_cmd_fixed_param)); 1478 1479 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1480 cmd->peer_tid_bitmap = param->tid_mask; 1481 cmd->vdev_id = param->vdev_id; 1482 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1483 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1484 wmi_buf_free(buf); 1485 wmi_err("Invalid policy"); 1486 return QDF_STATUS_E_INVAL; 1487 } 1488 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1489 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1490 param->tid_mask, param->policy); 1491 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1492 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1493 wmi_err("Failed to send flush policy command"); 1494 wmi_buf_free(buf); 1495 return QDF_STATUS_E_FAILURE; 1496 } 1497 1498 return QDF_STATUS_SUCCESS; 1499 } 1500 #endif 1501 /** 1502 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1503 * @wmi: wmi handle 1504 * @peer_addr: peer mac addr 1505 * @param: peer delete parameters 1506 * 1507 * Return: QDF_STATUS_SUCCESS for success or error code 1508 */ 1509 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1510 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1511 struct peer_delete_cmd_params *param) 1512 { 1513 wmi_peer_delete_cmd_fixed_param *cmd; 1514 wmi_buf_t buf; 1515 int32_t len = sizeof(*cmd); 1516 uint8_t *buf_ptr; 1517 1518 len += peer_delete_mlo_params_size(param); 1519 buf = wmi_buf_alloc(wmi, len); 1520 if (!buf) 1521 return QDF_STATUS_E_NOMEM; 1522 1523 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1524 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1525 WMITLV_SET_HDR(&cmd->tlv_header, 1526 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1527 WMITLV_GET_STRUCT_TLVLEN 1528 (wmi_peer_delete_cmd_fixed_param)); 1529 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1530 cmd->vdev_id = param->vdev_id; 1531 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1532 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1533 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1534 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1535 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1536 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1537 wmi_err("Failed to send peer delete command"); 1538 wmi_buf_free(buf); 1539 return QDF_STATUS_E_FAILURE; 1540 } 1541 return 0; 1542 } 1543 1544 static void 1545 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1546 { 1547 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1548 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1549 WMI_PEER_TYPE_DEFAULT); 1550 1551 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1552 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1553 WMI_PEER_TYPE_BSS); 1554 1555 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1556 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1557 WMI_PEER_TYPE_TDLS); 1558 1559 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1560 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1561 WMI_PEER_TYPE_NAN_DATA); 1562 1563 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1564 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1565 WMI_PEER_TYPE_PASN); 1566 } 1567 1568 /** 1569 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1570 * @wmi: wmi handle 1571 * @param: pointer to hold peer delete all parameter 1572 * 1573 * Return: QDF_STATUS_SUCCESS for success or error code 1574 */ 1575 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1576 wmi_unified_t wmi, 1577 struct peer_delete_all_params *param) 1578 { 1579 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1580 wmi_buf_t buf; 1581 int32_t len = sizeof(*cmd); 1582 1583 buf = wmi_buf_alloc(wmi, len); 1584 if (!buf) 1585 return QDF_STATUS_E_NOMEM; 1586 1587 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1588 WMITLV_SET_HDR( 1589 &cmd->tlv_header, 1590 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1591 WMITLV_GET_STRUCT_TLVLEN 1592 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1593 cmd->vdev_id = param->vdev_id; 1594 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1595 cmd->peer_type_bitmap); 1596 1597 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1598 param->peer_type_bitmap); 1599 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1600 if (wmi_unified_cmd_send(wmi, buf, len, 1601 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1602 wmi_err("Failed to send peer del all command"); 1603 wmi_buf_free(buf); 1604 return QDF_STATUS_E_FAILURE; 1605 } 1606 1607 return QDF_STATUS_SUCCESS; 1608 } 1609 1610 /** 1611 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1612 * to target id. 1613 * @peer_param_id: host param id. 1614 * 1615 * Return: Target param id. 1616 */ 1617 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1618 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1619 uint32_t peer_param_id) 1620 { 1621 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1622 return peer_param_tlv[peer_param_id]; 1623 return WMI_UNAVAILABLE_PARAM; 1624 } 1625 #else 1626 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1627 uint32_t peer_param_id) 1628 { 1629 return peer_param_id; 1630 } 1631 #endif 1632 1633 #ifdef WLAN_SUPPORT_PPEDS 1634 /** 1635 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1636 * @wmi: wmi handle 1637 * @param: pointer to hold PPE DS config 1638 * 1639 * Return: QDF_STATUS_SUCCESS for success or error code 1640 */ 1641 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1642 struct peer_ppe_ds_param *param) 1643 { 1644 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1645 wmi_buf_t buf; 1646 int32_t err; 1647 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1648 1649 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1650 if (!buf) 1651 return QDF_STATUS_E_NOMEM; 1652 1653 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1654 WMITLV_SET_HDR(&cmd->tlv_header, 1655 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1656 WMITLV_GET_STRUCT_TLVLEN 1657 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1658 1659 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1660 1661 if (param->ppe_routing_enabled) 1662 cmd->ppe_routing_enable = param->use_ppe ? 1663 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1664 else 1665 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1666 1667 cmd->service_code = param->service_code; 1668 cmd->priority_valid = param->priority_valid; 1669 cmd->src_info = param->src_info; 1670 cmd->vdev_id = param->vdev_id; 1671 1672 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1673 "ppe_routing_enable: %u service_code: %u\n" 1674 "priority_valid:%d src_info:%u", 1675 param->vdev_id, 1676 QDF_MAC_ADDR_REF(param->peer_macaddr), 1677 param->ppe_routing_enabled, 1678 param->service_code, 1679 param->priority_valid, 1680 param->src_info); 1681 1682 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1683 err = wmi_unified_cmd_send(wmi, buf, 1684 len, 1685 WMI_PEER_CONFIG_PPE_DS_CMDID); 1686 if (err) { 1687 wmi_err("Failed to send ppeds config cmd"); 1688 wmi_buf_free(buf); 1689 return QDF_STATUS_E_FAILURE; 1690 } 1691 1692 return 0; 1693 } 1694 #endif /* WLAN_SUPPORT_PPEDS */ 1695 1696 /** 1697 * send_peer_param_cmd_tlv() - set peer parameter in fw 1698 * @wmi: wmi handle 1699 * @peer_addr: peer mac address 1700 * @param : pointer to hold peer set parameter 1701 * 1702 * Return: QDF_STATUS_SUCCESS for success or error code 1703 */ 1704 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1705 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1706 struct peer_set_params *param) 1707 { 1708 wmi_peer_set_param_cmd_fixed_param *cmd; 1709 wmi_buf_t buf; 1710 int32_t err; 1711 uint32_t param_id; 1712 1713 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1714 if (param_id == WMI_UNAVAILABLE_PARAM) { 1715 wmi_err("Unavailable param %d", param->param_id); 1716 return QDF_STATUS_E_NOSUPPORT; 1717 } 1718 1719 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1720 if (!buf) 1721 return QDF_STATUS_E_NOMEM; 1722 1723 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1724 WMITLV_SET_HDR(&cmd->tlv_header, 1725 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1726 WMITLV_GET_STRUCT_TLVLEN 1727 (wmi_peer_set_param_cmd_fixed_param)); 1728 cmd->vdev_id = param->vdev_id; 1729 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1730 cmd->param_id = param_id; 1731 cmd->param_value = param->param_value; 1732 1733 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1734 cmd->vdev_id, 1735 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1736 cmd->param_value); 1737 1738 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1739 err = wmi_unified_cmd_send(wmi, buf, 1740 sizeof(wmi_peer_set_param_cmd_fixed_param), 1741 WMI_PEER_SET_PARAM_CMDID); 1742 if (err) { 1743 wmi_err("Failed to send set_param cmd"); 1744 wmi_buf_free(buf); 1745 return QDF_STATUS_E_FAILURE; 1746 } 1747 1748 return 0; 1749 } 1750 1751 /** 1752 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1753 * @wmi: wmi handle 1754 * @bssid: bssid 1755 * @vdev_up_params: pointer to hold vdev up parameter 1756 * 1757 * Return: QDF_STATUS_SUCCESS for success or error code 1758 */ 1759 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1760 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1761 struct vdev_up_params *params) 1762 { 1763 wmi_vdev_up_cmd_fixed_param *cmd; 1764 wmi_buf_t buf; 1765 int32_t len = sizeof(*cmd); 1766 1767 wmi_debug("VDEV_UP"); 1768 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1769 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1770 buf = wmi_buf_alloc(wmi, len); 1771 if (!buf) 1772 return QDF_STATUS_E_NOMEM; 1773 1774 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1775 WMITLV_SET_HDR(&cmd->tlv_header, 1776 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1777 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1778 cmd->vdev_id = params->vdev_id; 1779 cmd->vdev_assoc_id = params->assoc_id; 1780 cmd->profile_idx = params->profile_idx; 1781 cmd->profile_num = params->profile_num; 1782 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1783 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1784 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1785 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1786 wmi_err("Failed to send vdev up command"); 1787 wmi_buf_free(buf); 1788 return QDF_STATUS_E_FAILURE; 1789 } 1790 1791 return 0; 1792 } 1793 1794 /** 1795 * send_peer_create_cmd_tlv() - send peer create command to fw 1796 * @wmi: wmi handle 1797 * @peer_addr: peer mac address 1798 * @peer_type: peer type 1799 * @vdev_id: vdev id 1800 * 1801 * Return: QDF_STATUS_SUCCESS for success or error code 1802 */ 1803 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1804 struct peer_create_params *param) 1805 { 1806 wmi_peer_create_cmd_fixed_param *cmd; 1807 wmi_buf_t buf; 1808 uint8_t *buf_ptr; 1809 int32_t len = sizeof(*cmd); 1810 1811 len += peer_create_mlo_params_size(param); 1812 buf = wmi_buf_alloc(wmi, len); 1813 if (!buf) 1814 return QDF_STATUS_E_NOMEM; 1815 1816 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1817 WMITLV_SET_HDR(&cmd->tlv_header, 1818 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1819 WMITLV_GET_STRUCT_TLVLEN 1820 (wmi_peer_create_cmd_fixed_param)); 1821 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1822 cmd->peer_type = param->peer_type; 1823 cmd->vdev_id = param->vdev_id; 1824 1825 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1826 buf_ptr += sizeof(*cmd); 1827 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1828 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1829 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1830 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1831 wmi_buf_free(buf); 1832 return QDF_STATUS_E_FAILURE; 1833 } 1834 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1835 QDF_MAC_ADDR_REF(param->peer_addr), 1836 param->vdev_id); 1837 1838 return 0; 1839 } 1840 1841 /** 1842 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1843 * command to fw 1844 * @wmi: wmi handle 1845 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1846 * 1847 * Return: 0 for success or error code 1848 */ 1849 static 1850 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1851 struct rx_reorder_queue_setup_params *param) 1852 { 1853 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1854 wmi_buf_t buf; 1855 int32_t len = sizeof(*cmd); 1856 1857 buf = wmi_buf_alloc(wmi, len); 1858 if (!buf) 1859 return QDF_STATUS_E_NOMEM; 1860 1861 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1862 WMITLV_SET_HDR(&cmd->tlv_header, 1863 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1864 WMITLV_GET_STRUCT_TLVLEN 1865 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1866 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1867 cmd->vdev_id = param->vdev_id; 1868 cmd->tid = param->tid; 1869 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1870 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1871 cmd->queue_no = param->queue_no; 1872 cmd->ba_window_size_valid = param->ba_window_size_valid; 1873 cmd->ba_window_size = param->ba_window_size; 1874 1875 1876 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1877 if (wmi_unified_cmd_send(wmi, buf, len, 1878 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1879 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1880 wmi_buf_free(buf); 1881 return QDF_STATUS_E_FAILURE; 1882 } 1883 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1884 QDF_MAC_ADDR_REF(param->peer_macaddr), 1885 param->vdev_id, param->tid); 1886 1887 return QDF_STATUS_SUCCESS; 1888 } 1889 1890 /** 1891 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1892 * command to fw 1893 * @wmi: wmi handle 1894 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1895 * 1896 * Return: 0 for success or error code 1897 */ 1898 static 1899 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1900 struct rx_reorder_queue_remove_params *param) 1901 { 1902 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1903 wmi_buf_t buf; 1904 int32_t len = sizeof(*cmd); 1905 1906 buf = wmi_buf_alloc(wmi, len); 1907 if (!buf) 1908 return QDF_STATUS_E_NOMEM; 1909 1910 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1911 wmi_buf_data(buf); 1912 WMITLV_SET_HDR(&cmd->tlv_header, 1913 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1914 WMITLV_GET_STRUCT_TLVLEN 1915 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1916 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1917 cmd->vdev_id = param->vdev_id; 1918 cmd->tid_mask = param->peer_tid_bitmap; 1919 1920 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1921 if (wmi_unified_cmd_send(wmi, buf, len, 1922 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1923 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1924 wmi_buf_free(buf); 1925 return QDF_STATUS_E_FAILURE; 1926 } 1927 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1928 QDF_MAC_ADDR_REF(param->peer_macaddr), 1929 param->vdev_id, param->peer_tid_bitmap); 1930 1931 return QDF_STATUS_SUCCESS; 1932 } 1933 1934 #ifdef WLAN_SUPPORT_GREEN_AP 1935 /** 1936 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1937 * @wmi_handle: wmi handle 1938 * @value: value 1939 * @pdev_id: pdev id to have radio context 1940 * 1941 * Return: QDF_STATUS_SUCCESS for success or error code 1942 */ 1943 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1944 uint32_t value, uint8_t pdev_id) 1945 { 1946 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1947 wmi_buf_t buf; 1948 int32_t len = sizeof(*cmd); 1949 1950 wmi_debug("Set Green AP PS val %d", value); 1951 1952 buf = wmi_buf_alloc(wmi_handle, len); 1953 if (!buf) 1954 return QDF_STATUS_E_NOMEM; 1955 1956 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1957 WMITLV_SET_HDR(&cmd->tlv_header, 1958 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1959 WMITLV_GET_STRUCT_TLVLEN 1960 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1961 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1962 wmi_handle, 1963 pdev_id); 1964 cmd->enable = value; 1965 1966 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1967 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1968 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1969 wmi_err("Set Green AP PS param Failed val %d", value); 1970 wmi_buf_free(buf); 1971 return QDF_STATUS_E_FAILURE; 1972 } 1973 1974 return 0; 1975 } 1976 #endif 1977 1978 /** 1979 * send_pdev_utf_cmd_tlv() - send utf command to fw 1980 * @wmi_handle: wmi handle 1981 * @param: pointer to pdev_utf_params 1982 * @mac_id: mac id to have radio context 1983 * 1984 * Return: QDF_STATUS_SUCCESS for success or error code 1985 */ 1986 static QDF_STATUS 1987 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1988 struct pdev_utf_params *param, 1989 uint8_t mac_id) 1990 { 1991 wmi_buf_t buf; 1992 uint8_t *cmd; 1993 /* if param->len is 0 no data is sent, return error */ 1994 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1995 static uint8_t msgref = 1; 1996 uint8_t segNumber = 0, segInfo, numSegments; 1997 uint16_t chunk_len, total_bytes; 1998 uint8_t *bufpos; 1999 struct seg_hdr_info segHdrInfo; 2000 2001 bufpos = param->utf_payload; 2002 total_bytes = param->len; 2003 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2004 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2005 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2006 2007 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2008 numSegments++; 2009 2010 while (param->len) { 2011 if (param->len > MAX_WMI_UTF_LEN) 2012 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2013 else 2014 chunk_len = param->len; 2015 2016 buf = wmi_buf_alloc(wmi_handle, 2017 (chunk_len + sizeof(segHdrInfo) + 2018 WMI_TLV_HDR_SIZE)); 2019 if (!buf) 2020 return QDF_STATUS_E_NOMEM; 2021 2022 cmd = (uint8_t *) wmi_buf_data(buf); 2023 2024 segHdrInfo.len = total_bytes; 2025 segHdrInfo.msgref = msgref; 2026 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2027 segHdrInfo.segmentInfo = segInfo; 2028 segHdrInfo.pad = 0; 2029 2030 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2031 " segHdrInfo.segmentInfo = %d", 2032 segHdrInfo.len, segHdrInfo.msgref, 2033 segHdrInfo.segmentInfo); 2034 2035 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2036 " chunk len %d", total_bytes, segNumber, 2037 numSegments, chunk_len); 2038 2039 segNumber++; 2040 2041 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2042 (chunk_len + sizeof(segHdrInfo))); 2043 cmd += WMI_TLV_HDR_SIZE; 2044 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2045 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2046 bufpos, chunk_len); 2047 2048 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2049 ret = wmi_unified_cmd_send(wmi_handle, buf, 2050 (chunk_len + sizeof(segHdrInfo) + 2051 WMI_TLV_HDR_SIZE), 2052 WMI_PDEV_UTF_CMDID); 2053 2054 if (QDF_IS_STATUS_ERROR(ret)) { 2055 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2056 wmi_buf_free(buf); 2057 break; 2058 } 2059 2060 param->len -= chunk_len; 2061 bufpos += chunk_len; 2062 } 2063 2064 msgref++; 2065 2066 return ret; 2067 } 2068 2069 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2070 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2071 { 2072 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2073 return pdev_param_tlv[host_param]; 2074 return WMI_UNAVAILABLE_PARAM; 2075 } 2076 2077 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2078 { 2079 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2080 return vdev_param_tlv[host_param]; 2081 return WMI_UNAVAILABLE_PARAM; 2082 } 2083 #else 2084 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2085 { 2086 return host_param; 2087 } 2088 2089 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2090 { 2091 return host_param; 2092 } 2093 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2094 2095 /** 2096 * send_pdev_param_cmd_tlv() - set pdev parameters 2097 * @wmi_handle: wmi handle 2098 * @param: pointer to pdev parameter 2099 * @mac_id: radio context 2100 * 2101 * Return: 0 on success, errno on failure 2102 */ 2103 static QDF_STATUS 2104 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2105 struct pdev_params *param, 2106 uint8_t mac_id) 2107 { 2108 QDF_STATUS ret; 2109 wmi_pdev_set_param_cmd_fixed_param *cmd; 2110 wmi_buf_t buf; 2111 uint16_t len = sizeof(*cmd); 2112 uint32_t pdev_param; 2113 2114 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2115 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2116 wmi_err("Unavailable param %d", param->param_id); 2117 return QDF_STATUS_E_INVAL; 2118 } 2119 2120 buf = wmi_buf_alloc(wmi_handle, len); 2121 if (!buf) 2122 return QDF_STATUS_E_NOMEM; 2123 2124 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2125 WMITLV_SET_HDR(&cmd->tlv_header, 2126 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2127 WMITLV_GET_STRUCT_TLVLEN 2128 (wmi_pdev_set_param_cmd_fixed_param)); 2129 if (param->is_host_pdev_id) 2130 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2131 wmi_handle, 2132 mac_id); 2133 else 2134 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2135 wmi_handle, 2136 mac_id); 2137 cmd->param_id = pdev_param; 2138 cmd->param_value = param->param_value; 2139 wmi_debug("Setting pdev %d param = %x, value = %u", cmd->pdev_id, 2140 cmd->param_id, cmd->param_value); 2141 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2142 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2143 WMI_PDEV_SET_PARAM_CMDID); 2144 if (QDF_IS_STATUS_ERROR(ret)) { 2145 wmi_err("Failed to send set param command ret = %d", ret); 2146 wmi_buf_free(buf); 2147 } 2148 return ret; 2149 } 2150 2151 /** 2152 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2153 * @wmi_handle: wmi handle 2154 * @params: pointer to hold set_multiple_pdev_vdev_param info 2155 * 2156 * Return: 0 on success, errno on failure 2157 */ 2158 static QDF_STATUS 2159 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2160 struct set_multiple_pdev_vdev_param *params) 2161 { 2162 uint8_t index; 2163 struct pdev_params pdevparam; 2164 uint8_t n_params = params->n_params; 2165 2166 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2167 for (index = 0; index < n_params; index++) { 2168 pdevparam.param_id = params->params[index].param_id; 2169 pdevparam.param_value = params->params[index].param_value; 2170 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2171 &pdevparam, 2172 params->dev_id))) { 2173 wmi_err("failed to send pdev setparam:%d", 2174 pdevparam.param_id); 2175 return QDF_STATUS_E_FAILURE; 2176 } 2177 } 2178 return QDF_STATUS_SUCCESS; 2179 } 2180 2181 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2182 2183 /** 2184 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2185 * @params: pointer to point set_multiple_pdev_vdev_param info 2186 * 2187 * Return: returns QDF_STATUS 2188 */ 2189 static QDF_STATUS 2190 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2191 { 2192 uint8_t index; 2193 uint32_t dev_paramid; 2194 uint8_t num = params->n_params; 2195 2196 if (params->param_type == MLME_PDEV_SETPARAM) { 2197 for (index = 0; index < num; index++) { 2198 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2199 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2200 wmi_err("pdev param %d not available", 2201 params->params[index].param_id); 2202 return QDF_STATUS_E_INVAL; 2203 } 2204 params->params[index].param_id = dev_paramid; 2205 } 2206 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2207 for (index = 0; index < num; index++) { 2208 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2209 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2210 wmi_err("vdev param %d not available", 2211 params->params[index].param_id); 2212 return QDF_STATUS_E_INVAL; 2213 } 2214 params->params[index].param_id = dev_paramid; 2215 } 2216 } else { 2217 wmi_err("invalid param type"); 2218 return QDF_STATUS_E_INVAL; 2219 } 2220 return QDF_STATUS_SUCCESS; 2221 } 2222 2223 /** 2224 * send_dev_multi_setparam_cmd_tlv()-to print the paramid and param value 2225 * @setparam: buffer pointer where host is filling paramsid and value 2226 * @params: pointer to hold set_multiple_pdev_vdev_param info 2227 * 2228 */ 2229 static void send_dev_multi_setparam_cmd_tlv(wmi_set_param_info *setparam, 2230 struct set_multiple_pdev_vdev_param *params) 2231 { 2232 if (params->param_type == MLME_VDEV_SETPARAM) { 2233 wmi_debug("Setting vdev %d param = %x value = %u", params->dev_id, 2234 setparam->param_id, setparam->param_value); 2235 } else { 2236 wmi_debug("Setting pdev %d param = %x value = %u", 2237 params->dev_id, setparam->param_id, setparam->param_value); 2238 } 2239 } 2240 2241 /** 2242 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2243 * @wmi_handle: wmi handle 2244 * @params: pointer to hold set_multiple_pdev_vdev_param info 2245 * 2246 * Return: returns QDF_STATUS 2247 */ 2248 static QDF_STATUS 2249 send_multi_pdev_vdev_set_param_cmd_tlv( 2250 wmi_unified_t wmi_handle, 2251 struct set_multiple_pdev_vdev_param *params) 2252 { 2253 uint8_t *buf_ptr; 2254 QDF_STATUS ret; 2255 wmi_buf_t buf; 2256 wmi_set_param_info *setparam; 2257 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2258 uint8_t num = params->n_params; 2259 uint16_t len; 2260 uint8_t index = 0; 2261 2262 if (convert_host_pdev_vdev_param_id_to_target(params)) 2263 return QDF_STATUS_E_INVAL; 2264 2265 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2266 buf = wmi_buf_alloc(wmi_handle, len); 2267 if (!buf) 2268 return QDF_STATUS_E_NOMEM; 2269 2270 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2271 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2272 2273 WMITLV_SET_HDR(&cmd->tlv_header, 2274 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2275 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2276 2277 cmd->is_vdev = params->param_type; 2278 if (params->param_type == MLME_PDEV_SETPARAM) { 2279 if (params->is_host_pdev_id) 2280 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2281 params->dev_id); 2282 else 2283 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2284 params->dev_id); 2285 } 2286 cmd->dev_id = params->dev_id; 2287 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2288 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2289 buf_ptr += WMI_TLV_HDR_SIZE; 2290 for (index = 0; index < num; index++) { 2291 setparam = (wmi_set_param_info *)buf_ptr; 2292 WMITLV_SET_HDR(&setparam->tlv_header, 2293 WMITLV_TAG_STRUC_wmi_set_param_info, 2294 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2295 setparam->param_id = params->params[index].param_id; 2296 setparam->param_value = params->params[index].param_value; 2297 send_dev_multi_setparam_cmd_tlv(setparam, params); 2298 buf_ptr += sizeof(*setparam); 2299 } 2300 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2301 cmd->dev_id, 0); 2302 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2303 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2304 if (QDF_IS_STATUS_ERROR(ret)) { 2305 wmi_err("failed to send WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID"); 2306 wmi_buf_free(buf); 2307 } 2308 return ret; 2309 } 2310 2311 /** 2312 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2313 * @wmi_handle: wmi handle 2314 * @params: pointer to set_multiple_pdev_vdev_param structure 2315 * 2316 * Return: 0 on success, errno on failure 2317 */ 2318 static QDF_STATUS 2319 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2320 struct set_multiple_pdev_vdev_param *params) 2321 { 2322 if (!wmi_service_enabled(wmi_handle, 2323 wmi_service_combined_set_param_support)) 2324 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2325 params); 2326 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2327 } 2328 2329 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2330 /** 2331 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2332 * @wmi_handle: wmi handle 2333 * @params: pointer to set_multiple_pdev_vdev_param structure 2334 * 2335 * Return: 0 on success, errno on failure 2336 */ 2337 static QDF_STATUS 2338 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2339 struct set_multiple_pdev_vdev_param *params) 2340 { 2341 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2342 } 2343 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2344 2345 /** 2346 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2347 * @wmi_handle: wmi handle 2348 * @msg: Structure containing the following parameters 2349 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2350 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2351 * 2352 * Provides notification to the WLAN firmware that host driver is requesting a 2353 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2354 * configurations that include the Dual Band Simultaneous (DBS) feature. 2355 * 2356 * Return: Success if the cmd is sent successfully to the firmware 2357 */ 2358 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2359 uint32_t hw_mode_index) 2360 { 2361 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2362 wmi_buf_t buf; 2363 uint32_t len; 2364 2365 len = sizeof(*cmd); 2366 2367 buf = wmi_buf_alloc(wmi_handle, len); 2368 if (!buf) 2369 return QDF_STATUS_E_NOMEM; 2370 2371 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2372 WMITLV_SET_HDR(&cmd->tlv_header, 2373 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2374 WMITLV_GET_STRUCT_TLVLEN( 2375 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2376 2377 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2378 wmi_handle, 2379 WMI_HOST_PDEV_ID_SOC); 2380 cmd->hw_mode_index = hw_mode_index; 2381 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2382 2383 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2384 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2385 WMI_PDEV_SET_HW_MODE_CMDID)) { 2386 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2387 wmi_buf_free(buf); 2388 return QDF_STATUS_E_FAILURE; 2389 } 2390 2391 return QDF_STATUS_SUCCESS; 2392 } 2393 2394 /** 2395 * send_suspend_cmd_tlv() - WMI suspend function 2396 * @param wmi_handle : handle to WMI. 2397 * @param param : pointer to hold suspend parameter 2398 * @mac_id: radio context 2399 * 2400 * Return 0 on success and -ve on failure. 2401 */ 2402 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2403 struct suspend_params *param, 2404 uint8_t mac_id) 2405 { 2406 wmi_pdev_suspend_cmd_fixed_param *cmd; 2407 wmi_buf_t wmibuf; 2408 uint32_t len = sizeof(*cmd); 2409 int32_t ret; 2410 2411 /* 2412 * send the command to Target to ignore the 2413 * PCIE reset so as to ensure that Host and target 2414 * states are in sync 2415 */ 2416 wmibuf = wmi_buf_alloc(wmi_handle, len); 2417 if (!wmibuf) 2418 return QDF_STATUS_E_NOMEM; 2419 2420 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2421 WMITLV_SET_HDR(&cmd->tlv_header, 2422 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2423 WMITLV_GET_STRUCT_TLVLEN 2424 (wmi_pdev_suspend_cmd_fixed_param)); 2425 if (param->disable_target_intr) 2426 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2427 else 2428 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2429 2430 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2431 wmi_handle, 2432 mac_id); 2433 2434 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2435 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2436 WMI_PDEV_SUSPEND_CMDID); 2437 if (ret) { 2438 wmi_buf_free(wmibuf); 2439 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2440 } 2441 2442 return ret; 2443 } 2444 2445 /** 2446 * send_resume_cmd_tlv() - WMI resume function 2447 * @param wmi_handle : handle to WMI. 2448 * @mac_id: radio context 2449 * 2450 * Return: 0 on success and -ve on failure. 2451 */ 2452 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2453 uint8_t mac_id) 2454 { 2455 wmi_buf_t wmibuf; 2456 wmi_pdev_resume_cmd_fixed_param *cmd; 2457 QDF_STATUS ret; 2458 2459 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2460 if (!wmibuf) 2461 return QDF_STATUS_E_NOMEM; 2462 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2463 WMITLV_SET_HDR(&cmd->tlv_header, 2464 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2465 WMITLV_GET_STRUCT_TLVLEN 2466 (wmi_pdev_resume_cmd_fixed_param)); 2467 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2468 wmi_handle, 2469 mac_id); 2470 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2471 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2472 WMI_PDEV_RESUME_CMDID); 2473 if (QDF_IS_STATUS_ERROR(ret)) { 2474 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2475 wmi_buf_free(wmibuf); 2476 } 2477 2478 return ret; 2479 } 2480 2481 /** 2482 * send_wow_enable_cmd_tlv() - WMI wow enable function 2483 * @param wmi_handle : handle to WMI. 2484 * @param param : pointer to hold wow enable parameter 2485 * @mac_id: radio context 2486 * 2487 * Return: 0 on success and -ve on failure. 2488 */ 2489 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2490 struct wow_cmd_params *param, 2491 uint8_t mac_id) 2492 { 2493 wmi_wow_enable_cmd_fixed_param *cmd; 2494 wmi_buf_t buf; 2495 int32_t len; 2496 int32_t ret; 2497 2498 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2499 2500 buf = wmi_buf_alloc(wmi_handle, len); 2501 if (!buf) 2502 return QDF_STATUS_E_NOMEM; 2503 2504 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2505 WMITLV_SET_HDR(&cmd->tlv_header, 2506 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2507 WMITLV_GET_STRUCT_TLVLEN 2508 (wmi_wow_enable_cmd_fixed_param)); 2509 cmd->enable = param->enable; 2510 if (param->can_suspend_link) 2511 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2512 else 2513 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2514 cmd->flags = param->flags; 2515 2516 wmi_debug("suspend type: %s flag is 0x%x", 2517 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2518 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2519 cmd->flags); 2520 2521 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2522 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2523 WMI_WOW_ENABLE_CMDID); 2524 if (ret) 2525 wmi_buf_free(buf); 2526 2527 return ret; 2528 } 2529 2530 /** 2531 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2532 * @wmi_handle: wmi handle 2533 * @peer_addr: peer mac address 2534 * @param: pointer to ap_ps parameter structure 2535 * 2536 * Return: QDF_STATUS_SUCCESS for success or error code 2537 */ 2538 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2539 uint8_t *peer_addr, 2540 struct ap_ps_params *param) 2541 { 2542 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2543 wmi_buf_t buf; 2544 int32_t err; 2545 2546 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2547 if (!buf) 2548 return QDF_STATUS_E_NOMEM; 2549 2550 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2551 WMITLV_SET_HDR(&cmd->tlv_header, 2552 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2553 WMITLV_GET_STRUCT_TLVLEN 2554 (wmi_ap_ps_peer_cmd_fixed_param)); 2555 cmd->vdev_id = param->vdev_id; 2556 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2557 cmd->param = param->param; 2558 cmd->value = param->value; 2559 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2560 err = wmi_unified_cmd_send(wmi_handle, buf, 2561 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2562 if (err) { 2563 wmi_err("Failed to send set_ap_ps_param cmd"); 2564 wmi_buf_free(buf); 2565 return QDF_STATUS_E_FAILURE; 2566 } 2567 2568 return 0; 2569 } 2570 2571 /** 2572 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2573 * @wmi_handle: wmi handle 2574 * @peer_addr: peer mac address 2575 * @param: pointer to sta_ps parameter structure 2576 * 2577 * Return: QDF_STATUS_SUCCESS for success or error code 2578 */ 2579 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2580 struct sta_ps_params *param) 2581 { 2582 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2583 wmi_buf_t buf; 2584 int32_t len = sizeof(*cmd); 2585 2586 buf = wmi_buf_alloc(wmi_handle, len); 2587 if (!buf) 2588 return QDF_STATUS_E_NOMEM; 2589 2590 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2591 WMITLV_SET_HDR(&cmd->tlv_header, 2592 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2593 WMITLV_GET_STRUCT_TLVLEN 2594 (wmi_sta_powersave_param_cmd_fixed_param)); 2595 cmd->vdev_id = param->vdev_id; 2596 cmd->param = param->param_id; 2597 cmd->value = param->value; 2598 2599 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2600 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2601 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2602 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2603 param->vdev_id, param->param_id, param->value); 2604 wmi_buf_free(buf); 2605 return QDF_STATUS_E_FAILURE; 2606 } 2607 2608 return 0; 2609 } 2610 2611 /** 2612 * send_crash_inject_cmd_tlv() - inject fw crash 2613 * @wmi_handle: wmi handle 2614 * @param: ponirt to crash inject parameter structure 2615 * 2616 * Return: QDF_STATUS_SUCCESS for success or return error 2617 */ 2618 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2619 struct crash_inject *param) 2620 { 2621 int32_t ret = 0; 2622 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2623 uint16_t len = sizeof(*cmd); 2624 wmi_buf_t buf; 2625 2626 buf = wmi_buf_alloc(wmi_handle, len); 2627 if (!buf) 2628 return QDF_STATUS_E_NOMEM; 2629 2630 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2631 WMITLV_SET_HDR(&cmd->tlv_header, 2632 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2633 WMITLV_GET_STRUCT_TLVLEN 2634 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2635 cmd->type = param->type; 2636 cmd->delay_time_ms = param->delay_time_ms; 2637 2638 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2639 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2640 WMI_FORCE_FW_HANG_CMDID); 2641 if (ret) { 2642 wmi_err("Failed to send set param command, ret = %d", ret); 2643 wmi_buf_free(buf); 2644 } 2645 2646 return ret; 2647 } 2648 2649 /** 2650 * send_dbglog_cmd_tlv() - set debug log level 2651 * @param wmi_handle : handle to WMI. 2652 * @param param : pointer to hold dbglog level parameter 2653 * 2654 * Return: 0 on success and -ve on failure. 2655 */ 2656 static QDF_STATUS 2657 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2658 struct dbglog_params *dbglog_param) 2659 { 2660 wmi_buf_t buf; 2661 wmi_debug_log_config_cmd_fixed_param *configmsg; 2662 QDF_STATUS status; 2663 int32_t i; 2664 int32_t len; 2665 int8_t *buf_ptr; 2666 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2667 2668 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2669 2670 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2671 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2672 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2673 buf = wmi_buf_alloc(wmi_handle, len); 2674 if (!buf) 2675 return QDF_STATUS_E_NOMEM; 2676 2677 configmsg = 2678 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2679 buf_ptr = (int8_t *) configmsg; 2680 WMITLV_SET_HDR(&configmsg->tlv_header, 2681 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2682 WMITLV_GET_STRUCT_TLVLEN 2683 (wmi_debug_log_config_cmd_fixed_param)); 2684 configmsg->dbg_log_param = dbglog_param->param; 2685 configmsg->value = dbglog_param->val; 2686 /* Filling in the data part of second tlv -- should 2687 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2688 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2689 sizeof 2690 (wmi_debug_log_config_cmd_fixed_param) 2691 + WMI_TLV_HDR_SIZE); 2692 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2693 WMITLV_TAG_ARRAY_UINT32, 2694 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2695 if (dbglog_param->module_id_bitmap) { 2696 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2697 module_id_bitmap_array[i] = 2698 dbglog_param->module_id_bitmap[i]; 2699 } 2700 } 2701 2702 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2703 status = wmi_unified_cmd_send(wmi_handle, buf, 2704 len, WMI_DBGLOG_CFG_CMDID); 2705 2706 if (status != QDF_STATUS_SUCCESS) 2707 wmi_buf_free(buf); 2708 2709 return status; 2710 } 2711 2712 /** 2713 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2714 * @param wmi_handle : handle to WMI. 2715 * @param macaddr : MAC address 2716 * @param param : pointer to hold vdev set parameter 2717 * 2718 * Return: 0 on success and -ve on failure. 2719 */ 2720 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2721 struct vdev_set_params *param) 2722 { 2723 QDF_STATUS ret; 2724 wmi_vdev_set_param_cmd_fixed_param *cmd; 2725 wmi_buf_t buf; 2726 uint16_t len = sizeof(*cmd); 2727 uint32_t vdev_param; 2728 2729 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2730 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2731 wmi_err("Vdev param %d not available", param->param_id); 2732 return QDF_STATUS_E_INVAL; 2733 2734 } 2735 2736 buf = wmi_buf_alloc(wmi_handle, len); 2737 if (!buf) 2738 return QDF_STATUS_E_NOMEM; 2739 2740 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2741 WMITLV_SET_HDR(&cmd->tlv_header, 2742 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2743 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2744 cmd->vdev_id = param->vdev_id; 2745 cmd->param_id = vdev_param; 2746 cmd->param_value = param->param_value; 2747 wmi_debug("Setting vdev %d param = %x, value = %u", 2748 cmd->vdev_id, cmd->param_id, cmd->param_value); 2749 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2750 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2751 if (QDF_IS_STATUS_ERROR(ret)) { 2752 wmi_err("Failed to send set param command ret = %d", ret); 2753 wmi_buf_free(buf); 2754 } 2755 2756 return ret; 2757 } 2758 2759 /** 2760 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2761 * @wmi_handle : handle to WMI. 2762 * @dev_id: device id of pdev/vdev 2763 * @params: pointer to point array of structure dev_set_param with @n_params 2764 * @n_params: total number of set params that are combined with @params 2765 * 2766 * Return: returns QDF_STATUS. 2767 */ 2768 static QDF_STATUS 2769 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2770 struct set_multiple_pdev_vdev_param *params) 2771 { 2772 uint8_t index; 2773 struct vdev_set_params vdevparam; 2774 2775 for (index = 0; index < params->n_params; index++) { 2776 vdevparam.param_id = params->params[index].param_id; 2777 vdevparam.param_value = params->params[index].param_value; 2778 vdevparam.vdev_id = params->dev_id; 2779 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2780 wmi_err("failed to send param:%d", vdevparam.param_id); 2781 return QDF_STATUS_E_FAILURE; 2782 } 2783 } 2784 return QDF_STATUS_SUCCESS; 2785 } 2786 2787 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2788 /** 2789 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2790 * @wmi_handle : handle to WMI. 2791 * @params: pointer to hold set_multiple_pdev_vdev_param info 2792 * 2793 * Return: 0 on success and errorcode on failure. 2794 */ 2795 static QDF_STATUS 2796 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2797 struct set_multiple_pdev_vdev_param *params) 2798 { 2799 if (!wmi_service_enabled(wmi_handle, 2800 wmi_service_combined_set_param_support)) 2801 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2802 params); 2803 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2804 } 2805 2806 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2807 2808 /** 2809 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2810 * @wmi_handle : handle to WMI. 2811 * @params: pointer to hold set_multiple_pdev_vdev_param info 2812 * 2813 * Return: 0 on success and errorcode on failure. 2814 */ 2815 static QDF_STATUS 2816 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2817 struct set_multiple_pdev_vdev_param *params) 2818 { 2819 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 2820 } 2821 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2822 2823 /** 2824 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2825 * @param wmi_handle : handle to WMI. 2826 * @param param : pointer to hold mu sniffer parameter 2827 * 2828 * Return: 0 on success and -ve on failure. 2829 */ 2830 static 2831 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2832 struct vdev_set_mu_snif_param *param) 2833 { 2834 QDF_STATUS ret; 2835 wmi_vdev_set_mu_snif_cmd_param *cmd; 2836 wmi_buf_t buf; 2837 uint32_t *tmp_ptr; 2838 uint16_t len = sizeof(*cmd); 2839 uint8_t *buf_ptr; 2840 uint32_t i; 2841 2842 /* Length TLV placeholder for array of uint32_t */ 2843 len += WMI_TLV_HDR_SIZE; 2844 2845 if (param->num_aid) 2846 len += param->num_aid * sizeof(uint32_t); 2847 2848 buf = wmi_buf_alloc(wmi_handle, len); 2849 if (!buf) 2850 return QDF_STATUS_E_NOMEM; 2851 2852 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2853 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2854 2855 WMITLV_SET_HDR(&cmd->tlv_header, 2856 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2857 WMITLV_GET_STRUCT_TLVLEN 2858 (wmi_vdev_set_mu_snif_cmd_param)); 2859 2860 cmd->vdev_id = param->vdev_id; 2861 cmd->mode = param->mode; 2862 cmd->max_num_user = param->num_user; 2863 2864 buf_ptr += sizeof(*cmd); 2865 2866 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2867 2868 for (i = 0; i < param->num_aid; ++i) 2869 tmp_ptr[i] = param->aid[i]; 2870 2871 WMITLV_SET_HDR(buf_ptr, 2872 WMITLV_TAG_ARRAY_UINT32, 2873 (param->num_aid * sizeof(uint32_t))); 2874 2875 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2876 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2877 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2878 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2879 WMI_VDEV_SET_MU_SNIF_CMDID); 2880 if (QDF_IS_STATUS_ERROR(ret)) { 2881 wmi_err("Failed to send set param command ret = %d", ret); 2882 wmi_buf_free(buf); 2883 } 2884 2885 return ret; 2886 } 2887 2888 /** 2889 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2890 * @wmi_handle: handle to WMI. 2891 * @macaddr: Peer mac address to be filter 2892 * @mac_id: mac id to have radio context 2893 * @enb_dsb: Enable MAC based filtering or Disable 2894 * 2895 * Return: QDF_STATUS 2896 */ 2897 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2898 uint8_t *macaddr, 2899 uint8_t mac_id, 2900 uint8_t enb_dsb) 2901 { 2902 int32_t ret; 2903 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2904 wmi_pdev_pktlog_filter_info *mac_info; 2905 wmi_buf_t buf; 2906 uint8_t *buf_ptr; 2907 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2908 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2909 2910 buf = wmi_buf_alloc(wmi_handle, len); 2911 if (!buf) 2912 return QDF_STATUS_E_NOMEM; 2913 2914 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2915 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2916 WMITLV_SET_HDR(&cmd->tlv_header, 2917 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2918 WMITLV_GET_STRUCT_TLVLEN 2919 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2920 cmd->pdev_id = mac_id; 2921 cmd->enable = enb_dsb; 2922 cmd->num_of_mac_addresses = 1; 2923 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2924 2925 buf_ptr += sizeof(*cmd); 2926 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2927 sizeof(wmi_pdev_pktlog_filter_info)); 2928 buf_ptr += WMI_TLV_HDR_SIZE; 2929 2930 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2931 2932 WMITLV_SET_HDR(&mac_info->tlv_header, 2933 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2934 WMITLV_GET_STRUCT_TLVLEN 2935 (wmi_pdev_pktlog_filter_info)); 2936 2937 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2938 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2939 WMI_PDEV_PKTLOG_FILTER_CMDID); 2940 if (ret) { 2941 wmi_err("Failed to send peer based pktlog command to FW =%d" 2942 , ret); 2943 wmi_buf_free(buf); 2944 } 2945 2946 return ret; 2947 } 2948 2949 /** 2950 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2951 * @param wmi_handle : handle to WMI. 2952 * @param PKTLOG_EVENT : packet log event 2953 * @mac_id: mac id to have radio context 2954 * 2955 * Return: 0 on success and -ve on failure. 2956 */ 2957 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2958 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2959 { 2960 int32_t ret, idx, max_idx; 2961 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2962 wmi_buf_t buf; 2963 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2964 2965 buf = wmi_buf_alloc(wmi_handle, len); 2966 if (!buf) 2967 return -QDF_STATUS_E_NOMEM; 2968 2969 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2970 WMITLV_SET_HDR(&cmd->tlv_header, 2971 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2972 WMITLV_GET_STRUCT_TLVLEN 2973 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2974 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2975 cmd->evlist = 0; 2976 for (idx = 0; idx < max_idx; idx++) { 2977 if (PKTLOG_EVENT & (1 << idx)) 2978 cmd->evlist |= pktlog_event_tlv[idx]; 2979 } 2980 cmd->pdev_id = mac_id; 2981 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2982 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2983 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2984 if (ret) { 2985 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2986 wmi_buf_free(buf); 2987 } 2988 2989 return ret; 2990 } 2991 2992 /** 2993 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2994 * @param wmi_handle : handle to WMI. 2995 * @mac_id: mac id to have radio context 2996 * 2997 * Return: 0 on success and -ve on failure. 2998 */ 2999 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3000 uint8_t mac_id) 3001 { 3002 int32_t ret; 3003 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3004 wmi_buf_t buf; 3005 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3006 3007 buf = wmi_buf_alloc(wmi_handle, len); 3008 if (!buf) 3009 return -QDF_STATUS_E_NOMEM; 3010 3011 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3012 WMITLV_SET_HDR(&cmd->tlv_header, 3013 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3014 WMITLV_GET_STRUCT_TLVLEN 3015 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3016 cmd->pdev_id = mac_id; 3017 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3018 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3019 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3020 if (ret) { 3021 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3022 wmi_buf_free(buf); 3023 } 3024 3025 return ret; 3026 } 3027 3028 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3029 /** 3030 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3031 * sync time between bwtween host and firmware 3032 * @param wmi_handle : handle to WMI. 3033 * 3034 * Return: None 3035 */ 3036 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3037 { 3038 wmi_buf_t buf; 3039 QDF_STATUS status = QDF_STATUS_SUCCESS; 3040 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3041 int32_t len; 3042 qdf_time_t time_ms; 3043 3044 len = sizeof(*time_stamp); 3045 buf = wmi_buf_alloc(wmi_handle, len); 3046 3047 if (!buf) 3048 return; 3049 3050 time_stamp = 3051 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3052 (wmi_buf_data(buf)); 3053 WMITLV_SET_HDR(&time_stamp->tlv_header, 3054 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3055 WMITLV_GET_STRUCT_TLVLEN( 3056 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3057 3058 time_ms = qdf_get_time_of_the_day_ms(); 3059 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3060 time_stamp->time_stamp_low = time_ms & 3061 WMI_FW_TIME_STAMP_LOW_MASK; 3062 /* 3063 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3064 * wont exceed 27 bit 3065 */ 3066 time_stamp->time_stamp_high = 0; 3067 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3068 time_stamp->mode, time_stamp->time_stamp_low, 3069 time_stamp->time_stamp_high); 3070 3071 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3072 status = wmi_unified_cmd_send(wmi_handle, buf, 3073 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3074 if (status) { 3075 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3076 wmi_buf_free(buf); 3077 } 3078 3079 } 3080 3081 /** 3082 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3083 * @param wmi_handle : handle to WMI. 3084 * @param param : pointer to hold FILS Discovery send cmd parameter 3085 * 3086 * Return: 0 on success and -ve on failure. 3087 */ 3088 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3089 struct fils_discovery_tmpl_params *param) 3090 { 3091 int32_t ret; 3092 wmi_fd_tmpl_cmd_fixed_param *cmd; 3093 wmi_buf_t wmi_buf; 3094 uint8_t *buf_ptr; 3095 uint32_t wmi_buf_len; 3096 3097 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3098 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3099 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3100 if (!wmi_buf) 3101 return QDF_STATUS_E_NOMEM; 3102 3103 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3104 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3105 WMITLV_SET_HDR(&cmd->tlv_header, 3106 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3107 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3108 cmd->vdev_id = param->vdev_id; 3109 cmd->buf_len = param->tmpl_len; 3110 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3111 3112 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3113 buf_ptr += WMI_TLV_HDR_SIZE; 3114 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3115 3116 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3117 ret = wmi_unified_cmd_send(wmi_handle, 3118 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3119 3120 if (ret) { 3121 wmi_err("Failed to send fd tmpl: %d", ret); 3122 wmi_buf_free(wmi_buf); 3123 return ret; 3124 } 3125 3126 return 0; 3127 } 3128 3129 /** 3130 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 3131 * @param wmi_handle : handle to WMI. 3132 * @param param : pointer to hold beacon send cmd parameter 3133 * 3134 * Return: 0 on success and -ve on failure. 3135 */ 3136 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3137 struct beacon_tmpl_params *param) 3138 { 3139 int32_t ret; 3140 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3141 wmi_bcn_prb_info *bcn_prb_info; 3142 wmi_buf_t wmi_buf; 3143 uint8_t *buf_ptr; 3144 uint32_t wmi_buf_len; 3145 3146 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3147 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3148 param->tmpl_len_aligned + 3149 bcn_tmpl_mlo_param_size(param) + 3150 bcn_tmpl_ml_info_size(param); 3151 3152 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3153 if (!wmi_buf) 3154 return QDF_STATUS_E_NOMEM; 3155 3156 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3157 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3158 WMITLV_SET_HDR(&cmd->tlv_header, 3159 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3160 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3161 cmd->vdev_id = param->vdev_id; 3162 cmd->tim_ie_offset = param->tim_ie_offset; 3163 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3164 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3165 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3166 cmd->esp_ie_offset = param->esp_ie_offset; 3167 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3168 cmd->ema_params = param->ema_params; 3169 cmd->buf_len = param->tmpl_len; 3170 cmd->csa_event_bitmap = param->csa_event_bitmap; 3171 3172 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3173 param->enable_bigtk); 3174 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3175 3176 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3177 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3178 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3179 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3180 bcn_prb_info->caps = 0; 3181 bcn_prb_info->erp = 0; 3182 buf_ptr += sizeof(wmi_bcn_prb_info); 3183 3184 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3185 buf_ptr += WMI_TLV_HDR_SIZE; 3186 3187 /* for big endian host, copy engine byte_swap is enabled 3188 * But the frame content is in network byte order 3189 * Need to byte swap the frame content - so when copy engine 3190 * does byte_swap - target gets frame content in the correct order 3191 */ 3192 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3193 param->tmpl_len); 3194 3195 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3196 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3197 3198 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3199 3200 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3201 ret = wmi_unified_cmd_send(wmi_handle, 3202 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3203 if (ret) { 3204 wmi_err("Failed to send bcn tmpl: %d", ret); 3205 wmi_buf_free(wmi_buf); 3206 } 3207 3208 return 0; 3209 } 3210 3211 #ifdef WLAN_FEATURE_11BE 3212 static inline void copy_peer_flags_tlv_11be( 3213 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3214 struct peer_assoc_params *param) 3215 { 3216 if (param->bw_320) 3217 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3218 if (param->eht_flag) 3219 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3220 3221 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3222 } 3223 #else 3224 static inline void copy_peer_flags_tlv_11be( 3225 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3226 struct peer_assoc_params *param) 3227 { 3228 } 3229 #endif 3230 3231 static inline void copy_peer_flags_tlv( 3232 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3233 struct peer_assoc_params *param) 3234 { 3235 /* 3236 * The target only needs a subset of the flags maintained in the host. 3237 * Just populate those flags and send it down 3238 */ 3239 cmd->peer_flags = 0; 3240 if (param->peer_dms_capable) 3241 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3242 /* 3243 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3244 */ 3245 if (param->is_wme_set) { 3246 3247 if (param->qos_flag) 3248 cmd->peer_flags |= WMI_PEER_QOS; 3249 if (param->apsd_flag) 3250 cmd->peer_flags |= WMI_PEER_APSD; 3251 if (param->ht_flag) 3252 cmd->peer_flags |= WMI_PEER_HT; 3253 if (param->bw_40) 3254 cmd->peer_flags |= WMI_PEER_40MHZ; 3255 if (param->bw_80) 3256 cmd->peer_flags |= WMI_PEER_80MHZ; 3257 if (param->bw_160) 3258 cmd->peer_flags |= WMI_PEER_160MHZ; 3259 3260 copy_peer_flags_tlv_11be(cmd, param); 3261 3262 /* Typically if STBC is enabled for VHT it should be enabled 3263 * for HT as well 3264 **/ 3265 if (param->stbc_flag) 3266 cmd->peer_flags |= WMI_PEER_STBC; 3267 3268 /* Typically if LDPC is enabled for VHT it should be enabled 3269 * for HT as well 3270 **/ 3271 if (param->ldpc_flag) 3272 cmd->peer_flags |= WMI_PEER_LDPC; 3273 3274 if (param->static_mimops_flag) 3275 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3276 if (param->dynamic_mimops_flag) 3277 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3278 if (param->spatial_mux_flag) 3279 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3280 if (param->vht_flag) 3281 cmd->peer_flags |= WMI_PEER_VHT; 3282 if (param->he_flag) 3283 cmd->peer_flags |= WMI_PEER_HE; 3284 if (param->p2p_capable_sta) 3285 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3286 } 3287 3288 if (param->is_pmf_enabled) 3289 cmd->peer_flags |= WMI_PEER_PMF; 3290 /* 3291 * Suppress authorization for all AUTH modes that need 4-way handshake 3292 * (during re-association). 3293 * Authorization will be done for these modes on key installation. 3294 */ 3295 if (param->auth_flag) 3296 cmd->peer_flags |= WMI_PEER_AUTH; 3297 if (param->need_ptk_4_way) 3298 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3299 else 3300 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3301 if (param->need_gtk_2_way) 3302 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3303 /* safe mode bypass the 4-way handshake */ 3304 if (param->safe_mode_enabled) 3305 cmd->peer_flags &= 3306 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3307 /* inter BSS peer */ 3308 if (param->inter_bss_peer) 3309 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3310 /* Disable AMSDU for station transmit, if user configures it */ 3311 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3312 * it 3313 * if (param->amsdu_disable) Add after FW support 3314 **/ 3315 3316 /* Target asserts if node is marked HT and all MCS is set to 0. 3317 * Mark the node as non-HT if all the mcs rates are disabled through 3318 * iwpriv 3319 **/ 3320 if (param->peer_ht_rates.num_rates == 0) 3321 cmd->peer_flags &= ~WMI_PEER_HT; 3322 3323 if (param->twt_requester) 3324 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3325 3326 if (param->twt_responder) 3327 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3328 } 3329 3330 static inline void copy_peer_mac_addr_tlv( 3331 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3332 struct peer_assoc_params *param) 3333 { 3334 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3335 } 3336 3337 #ifdef WLAN_FEATURE_11BE 3338 static uint8_t *update_peer_flags_tlv_ehtinfo( 3339 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3340 struct peer_assoc_params *param, uint8_t *buf_ptr) 3341 { 3342 wmi_eht_rate_set *eht_mcs; 3343 int i; 3344 3345 cmd->peer_eht_ops = param->peer_eht_ops; 3346 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3347 3348 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3349 sizeof(param->peer_eht_cap_macinfo)); 3350 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3351 sizeof(param->peer_eht_cap_phyinfo)); 3352 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3353 sizeof(param->peer_eht_ppet)); 3354 3355 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3356 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3357 buf_ptr += WMI_TLV_HDR_SIZE; 3358 3359 /* Loop through the EHT rate set */ 3360 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3361 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3362 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3363 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3364 3365 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3366 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3367 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3368 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3369 buf_ptr += sizeof(wmi_eht_rate_set); 3370 } 3371 3372 wmi_debug("nss %d ru mask 0x%x", 3373 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3374 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3375 wmi_debug("ppet idx %d ppet %x ", 3376 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3377 } 3378 3379 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3380 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3381 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3382 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3383 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3384 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3385 param->peer_eht_tx_mcs_set 3386 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3387 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3388 param->peer_eht_rx_mcs_set 3389 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3390 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3391 QDF_MAC_ADDR_REF(param->peer_mac)); 3392 } 3393 3394 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3395 cmd->peer_eht_cap_mac[0], 3396 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3397 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 3398 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3399 3400 return buf_ptr; 3401 } 3402 #else 3403 static uint8_t *update_peer_flags_tlv_ehtinfo( 3404 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3405 struct peer_assoc_params *param, uint8_t *buf_ptr) 3406 { 3407 return buf_ptr; 3408 } 3409 #endif 3410 3411 #ifdef WLAN_FEATURE_11BE 3412 static 3413 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3414 { 3415 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3416 + WMI_TLV_HDR_SIZE); 3417 } 3418 3419 static void wmi_populate_service_11be(uint32_t *wmi_service) 3420 { 3421 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3422 } 3423 3424 #else 3425 static 3426 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3427 { 3428 return 0; 3429 } 3430 3431 static void wmi_populate_service_11be(uint32_t *wmi_service) 3432 { 3433 } 3434 3435 #endif 3436 3437 /** 3438 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3439 * @param wmi_handle : handle to WMI. 3440 * @param param : pointer to peer assoc parameter 3441 * 3442 * Return: 0 on success and -ve on failure. 3443 */ 3444 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3445 struct peer_assoc_params *param) 3446 { 3447 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3448 wmi_vht_rate_set *mcs; 3449 wmi_he_rate_set *he_mcs; 3450 wmi_buf_t buf; 3451 int32_t len; 3452 uint8_t *buf_ptr; 3453 QDF_STATUS ret; 3454 uint32_t peer_legacy_rates_align; 3455 uint32_t peer_ht_rates_align; 3456 int32_t i; 3457 3458 3459 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3460 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3461 3462 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3463 (peer_legacy_rates_align * sizeof(uint8_t)) + 3464 WMI_TLV_HDR_SIZE + 3465 (peer_ht_rates_align * sizeof(uint8_t)) + 3466 sizeof(wmi_vht_rate_set) + 3467 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3468 + WMI_TLV_HDR_SIZE) 3469 + wmi_eht_peer_assoc_params_len(param) + 3470 peer_assoc_mlo_params_size(param) + 3471 peer_assoc_t2lm_params_size(param); 3472 3473 buf = wmi_buf_alloc(wmi_handle, len); 3474 if (!buf) 3475 return QDF_STATUS_E_NOMEM; 3476 3477 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3478 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3479 WMITLV_SET_HDR(&cmd->tlv_header, 3480 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3481 WMITLV_GET_STRUCT_TLVLEN 3482 (wmi_peer_assoc_complete_cmd_fixed_param)); 3483 3484 cmd->vdev_id = param->vdev_id; 3485 3486 cmd->peer_new_assoc = param->peer_new_assoc; 3487 cmd->peer_associd = param->peer_associd; 3488 3489 copy_peer_flags_tlv(cmd, param); 3490 copy_peer_mac_addr_tlv(cmd, param); 3491 3492 cmd->peer_rate_caps = param->peer_rate_caps; 3493 cmd->peer_caps = param->peer_caps; 3494 cmd->peer_listen_intval = param->peer_listen_intval; 3495 cmd->peer_ht_caps = param->peer_ht_caps; 3496 cmd->peer_max_mpdu = param->peer_max_mpdu; 3497 cmd->peer_mpdu_density = param->peer_mpdu_density; 3498 cmd->peer_vht_caps = param->peer_vht_caps; 3499 cmd->peer_phymode = param->peer_phymode; 3500 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3501 3502 /* Update 11ax capabilities */ 3503 cmd->peer_he_cap_info = 3504 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3505 cmd->peer_he_cap_info_ext = 3506 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3507 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3508 cmd->peer_he_ops = param->peer_he_ops; 3509 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3510 sizeof(param->peer_he_cap_phyinfo)); 3511 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3512 sizeof(param->peer_ppet)); 3513 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3514 3515 /* Update peer legacy rate information */ 3516 buf_ptr += sizeof(*cmd); 3517 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3518 peer_legacy_rates_align); 3519 buf_ptr += WMI_TLV_HDR_SIZE; 3520 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3521 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3522 param->peer_legacy_rates.num_rates); 3523 3524 /* Update peer HT rate information */ 3525 buf_ptr += peer_legacy_rates_align; 3526 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3527 peer_ht_rates_align); 3528 buf_ptr += WMI_TLV_HDR_SIZE; 3529 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3530 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3531 param->peer_ht_rates.num_rates); 3532 3533 /* VHT Rates */ 3534 buf_ptr += peer_ht_rates_align; 3535 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3536 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3537 3538 cmd->auth_mode = param->akm; 3539 cmd->peer_nss = param->peer_nss; 3540 3541 /* Update bandwidth-NSS mapping */ 3542 cmd->peer_bw_rxnss_override = 0; 3543 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3544 3545 mcs = (wmi_vht_rate_set *) buf_ptr; 3546 if (param->vht_capable) { 3547 mcs->rx_max_rate = param->rx_max_rate; 3548 mcs->rx_mcs_set = param->rx_mcs_set; 3549 mcs->tx_max_rate = param->tx_max_rate; 3550 mcs->tx_mcs_set = param->tx_mcs_set; 3551 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3552 } 3553 3554 /* HE Rates */ 3555 cmd->min_data_rate = param->min_data_rate; 3556 cmd->peer_he_mcs = param->peer_he_mcs_count; 3557 buf_ptr += sizeof(wmi_vht_rate_set); 3558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3559 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3560 buf_ptr += WMI_TLV_HDR_SIZE; 3561 3562 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3563 /* Loop through the HE rate set */ 3564 for (i = 0; i < param->peer_he_mcs_count; i++) { 3565 he_mcs = (wmi_he_rate_set *) buf_ptr; 3566 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3567 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3568 3569 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3570 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3571 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3572 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3573 buf_ptr += sizeof(wmi_he_rate_set); 3574 } 3575 3576 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3577 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3578 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3579 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3580 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3581 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3582 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3583 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3584 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3585 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3586 QDF_MAC_ADDR_REF(param->peer_mac)); 3587 } 3588 3589 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3590 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3591 "nss %d phymode %d peer_mpdu_density %d " 3592 "cmd->peer_vht_caps %x " 3593 "HE cap_info %x ops %x " 3594 "HE cap_info_ext %x " 3595 "HE phy %x %x %x " 3596 "peer_bw_rxnss_override %x", 3597 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3598 cmd->peer_rate_caps, cmd->peer_caps, 3599 cmd->peer_listen_intval, cmd->peer_ht_caps, 3600 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3601 cmd->peer_mpdu_density, 3602 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3603 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3604 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3605 cmd->peer_he_cap_phy[2], 3606 cmd->peer_bw_rxnss_override); 3607 3608 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3609 3610 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3611 3612 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3613 3614 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3615 3616 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3617 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3618 WMI_PEER_ASSOC_CMDID); 3619 if (QDF_IS_STATUS_ERROR(ret)) { 3620 wmi_err("Failed to send peer assoc command ret = %d", ret); 3621 wmi_buf_free(buf); 3622 } 3623 3624 return ret; 3625 } 3626 3627 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3628 */ 3629 static inline void copy_scan_event_cntrl_flags( 3630 wmi_start_scan_cmd_fixed_param * cmd, 3631 struct scan_req_params *param) 3632 { 3633 3634 /* Scan events subscription */ 3635 if (param->scan_ev_started) 3636 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3637 if (param->scan_ev_completed) 3638 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3639 if (param->scan_ev_bss_chan) 3640 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3641 if (param->scan_ev_foreign_chan) 3642 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3643 if (param->scan_ev_dequeued) 3644 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3645 if (param->scan_ev_preempted) 3646 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3647 if (param->scan_ev_start_failed) 3648 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3649 if (param->scan_ev_restarted) 3650 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3651 if (param->scan_ev_foreign_chn_exit) 3652 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3653 if (param->scan_ev_suspended) 3654 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3655 if (param->scan_ev_resumed) 3656 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3657 3658 /** Set scan control flags */ 3659 cmd->scan_ctrl_flags = 0; 3660 if (param->scan_f_passive) 3661 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3662 if (param->scan_f_strict_passive_pch) 3663 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3664 if (param->scan_f_promisc_mode) 3665 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3666 if (param->scan_f_capture_phy_err) 3667 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3668 if (param->scan_f_half_rate) 3669 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3670 if (param->scan_f_quarter_rate) 3671 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3672 if (param->scan_f_cck_rates) 3673 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3674 if (param->scan_f_ofdm_rates) 3675 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3676 if (param->scan_f_chan_stat_evnt) 3677 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3678 if (param->scan_f_filter_prb_req) 3679 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3680 if (param->scan_f_bcast_probe) 3681 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3682 if (param->scan_f_offchan_mgmt_tx) 3683 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3684 if (param->scan_f_offchan_data_tx) 3685 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3686 if (param->scan_f_force_active_dfs_chn) 3687 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3688 if (param->scan_f_add_tpc_ie_in_probe) 3689 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3690 if (param->scan_f_add_ds_ie_in_probe) 3691 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3692 if (param->scan_f_add_spoofed_mac_in_probe) 3693 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3694 if (param->scan_f_add_rand_seq_in_probe) 3695 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3696 if (param->scan_f_en_ie_allowlist_in_probe) 3697 cmd->scan_ctrl_flags |= 3698 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3699 3700 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3701 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3702 param->adaptive_dwell_time_mode); 3703 } 3704 3705 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3706 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3707 struct scan_req_params *params) 3708 { 3709 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3710 } 3711 3712 /** 3713 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3714 * @mac: random mac addr 3715 * @mask: random mac mask 3716 * @mac_addr: wmi random mac 3717 * @mac_mask: wmi random mac mask 3718 * 3719 * Return None. 3720 */ 3721 static inline 3722 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3723 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3724 { 3725 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3726 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3727 } 3728 3729 /* 3730 * wmi_fill_vendor_oui() - fill vendor OUIs 3731 * @buf_ptr: pointer to wmi tlv buffer 3732 * @num_vendor_oui: number of vendor OUIs to be filled 3733 * @param_voui: pointer to OUI buffer 3734 * 3735 * This function populates the wmi tlv buffer when vendor specific OUIs are 3736 * present. 3737 * 3738 * Return: None 3739 */ 3740 static inline 3741 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3742 uint32_t *pvoui) 3743 { 3744 wmi_vendor_oui *voui = NULL; 3745 uint32_t i; 3746 3747 voui = (wmi_vendor_oui *)buf_ptr; 3748 3749 for (i = 0; i < num_vendor_oui; i++) { 3750 WMITLV_SET_HDR(&voui[i].tlv_header, 3751 WMITLV_TAG_STRUC_wmi_vendor_oui, 3752 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3753 voui[i].oui_type_subtype = pvoui[i]; 3754 } 3755 } 3756 3757 /* 3758 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3759 * @ie_bitmap: output pointer to ie bit map in cmd 3760 * @num_vendor_oui: output pointer to num vendor OUIs 3761 * @ie_allowlist: input parameter 3762 * 3763 * This function populates the IE allowlist attrs of scan, pno and 3764 * scan oui commands for ie_allowlist parameter. 3765 * 3766 * Return: None 3767 */ 3768 static inline 3769 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3770 uint32_t *num_vendor_oui, 3771 struct probe_req_allowlist_attr *ie_allowlist) 3772 { 3773 uint32_t i = 0; 3774 3775 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3776 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3777 3778 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3779 } 3780 3781 /** 3782 * send_scan_start_cmd_tlv() - WMI scan start function 3783 * @param wmi_handle : handle to WMI. 3784 * @param param : pointer to hold scan start cmd parameter 3785 * 3786 * Return: 0 on success and -ve on failure. 3787 */ 3788 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3789 struct scan_req_params *params) 3790 { 3791 int32_t ret = 0; 3792 int32_t i; 3793 wmi_buf_t wmi_buf; 3794 wmi_start_scan_cmd_fixed_param *cmd; 3795 uint8_t *buf_ptr; 3796 uint32_t *tmp_ptr; 3797 wmi_ssid *ssid = NULL; 3798 wmi_mac_addr *bssid; 3799 size_t len = sizeof(*cmd); 3800 uint16_t extraie_len_with_pad = 0; 3801 uint8_t phymode_roundup = 0; 3802 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3803 wmi_hint_freq_short_ssid *s_ssid = NULL; 3804 wmi_hint_freq_bssid *hint_bssid = NULL; 3805 3806 /* Length TLV placeholder for array of uint32_t */ 3807 len += WMI_TLV_HDR_SIZE; 3808 /* calculate the length of buffer required */ 3809 if (params->chan_list.num_chan) 3810 len += params->chan_list.num_chan * sizeof(uint32_t); 3811 3812 /* Length TLV placeholder for array of wmi_ssid structures */ 3813 len += WMI_TLV_HDR_SIZE; 3814 if (params->num_ssids) 3815 len += params->num_ssids * sizeof(wmi_ssid); 3816 3817 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3818 len += WMI_TLV_HDR_SIZE; 3819 if (params->num_bssid) 3820 len += sizeof(wmi_mac_addr) * params->num_bssid; 3821 3822 /* Length TLV placeholder for array of bytes */ 3823 len += WMI_TLV_HDR_SIZE; 3824 if (params->extraie.len) 3825 extraie_len_with_pad = 3826 roundup(params->extraie.len, sizeof(uint32_t)); 3827 len += extraie_len_with_pad; 3828 3829 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3830 if (ie_allowlist->num_vendor_oui) 3831 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3832 3833 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3834 if (params->scan_f_wide_band) 3835 phymode_roundup = 3836 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3837 sizeof(uint32_t)); 3838 len += phymode_roundup; 3839 3840 len += WMI_TLV_HDR_SIZE; 3841 if (params->num_hint_bssid) 3842 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3843 3844 len += WMI_TLV_HDR_SIZE; 3845 if (params->num_hint_s_ssid) 3846 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3847 3848 /* Allocate the memory */ 3849 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3850 if (!wmi_buf) 3851 return QDF_STATUS_E_FAILURE; 3852 3853 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3854 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3855 WMITLV_SET_HDR(&cmd->tlv_header, 3856 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3857 WMITLV_GET_STRUCT_TLVLEN 3858 (wmi_start_scan_cmd_fixed_param)); 3859 3860 cmd->scan_id = params->scan_id; 3861 cmd->scan_req_id = params->scan_req_id; 3862 cmd->vdev_id = params->vdev_id; 3863 cmd->scan_priority = params->scan_priority; 3864 3865 copy_scan_event_cntrl_flags(cmd, params); 3866 3867 cmd->dwell_time_active = params->dwell_time_active; 3868 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3869 cmd->dwell_time_passive = params->dwell_time_passive; 3870 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3871 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3872 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3873 cmd->scan_start_offset = params->scan_offset_time; 3874 cmd->min_rest_time = params->min_rest_time; 3875 cmd->max_rest_time = params->max_rest_time; 3876 cmd->repeat_probe_time = params->repeat_probe_time; 3877 cmd->probe_spacing_time = params->probe_spacing_time; 3878 cmd->idle_time = params->idle_time; 3879 cmd->max_scan_time = params->max_scan_time; 3880 cmd->probe_delay = params->probe_delay; 3881 cmd->burst_duration = params->burst_duration; 3882 cmd->num_chan = params->chan_list.num_chan; 3883 cmd->num_bssid = params->num_bssid; 3884 cmd->num_ssids = params->num_ssids; 3885 cmd->ie_len = params->extraie.len; 3886 cmd->n_probes = params->n_probes; 3887 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3888 3889 if (params->scan_random.randomize) 3890 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3891 params->scan_random.mac_mask, 3892 &cmd->mac_addr, 3893 &cmd->mac_mask); 3894 3895 if (ie_allowlist->allow_list) 3896 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 3897 &cmd->num_vendor_oui, 3898 ie_allowlist); 3899 3900 buf_ptr += sizeof(*cmd); 3901 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3902 for (i = 0; i < params->chan_list.num_chan; ++i) { 3903 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 3904 params->chan_list.chan[i].freq); 3905 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3906 params->chan_list.chan[i].flags); 3907 } 3908 3909 WMITLV_SET_HDR(buf_ptr, 3910 WMITLV_TAG_ARRAY_UINT32, 3911 (params->chan_list.num_chan * sizeof(uint32_t))); 3912 buf_ptr += WMI_TLV_HDR_SIZE + 3913 (params->chan_list.num_chan * sizeof(uint32_t)); 3914 3915 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3916 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3917 goto error; 3918 } 3919 3920 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3921 (params->num_ssids * sizeof(wmi_ssid))); 3922 3923 if (params->num_ssids) { 3924 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3925 for (i = 0; i < params->num_ssids; ++i) { 3926 ssid->ssid_len = params->ssid[i].length; 3927 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3928 params->ssid[i].length); 3929 ssid++; 3930 } 3931 } 3932 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3933 3934 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3935 (params->num_bssid * sizeof(wmi_mac_addr))); 3936 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3937 3938 if (params->num_bssid) { 3939 for (i = 0; i < params->num_bssid; ++i) { 3940 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3941 ¶ms->bssid_list[i].bytes[0], bssid); 3942 bssid++; 3943 } 3944 } 3945 3946 buf_ptr += WMI_TLV_HDR_SIZE + 3947 (params->num_bssid * sizeof(wmi_mac_addr)); 3948 3949 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3950 if (params->extraie.len) 3951 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3952 params); 3953 3954 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3955 3956 /* probe req ie allowlisting */ 3957 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3958 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3959 3960 buf_ptr += WMI_TLV_HDR_SIZE; 3961 3962 if (cmd->num_vendor_oui) { 3963 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3964 ie_allowlist->voui); 3965 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3966 } 3967 3968 /* Add phy mode TLV if it's a wide band scan */ 3969 if (params->scan_f_wide_band) { 3970 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3971 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3972 for (i = 0; i < params->chan_list.num_chan; ++i) 3973 buf_ptr[i] = 3974 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3975 buf_ptr += phymode_roundup; 3976 } else { 3977 /* Add ZERO legth phy mode TLV */ 3978 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3979 buf_ptr += WMI_TLV_HDR_SIZE; 3980 } 3981 3982 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3983 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3984 if (params->num_hint_s_ssid) { 3985 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3986 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3987 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3988 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3989 s_ssid++; 3990 } 3991 } 3992 buf_ptr += WMI_TLV_HDR_SIZE + 3993 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3994 3995 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3996 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3997 if (params->num_hint_bssid) { 3998 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3999 for (i = 0; i < params->num_hint_bssid; ++i) { 4000 hint_bssid->freq_flags = 4001 params->hint_bssid[i].freq_flags; 4002 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4003 &hint_bssid->bssid); 4004 hint_bssid++; 4005 } 4006 } 4007 4008 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4009 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4010 len, WMI_START_SCAN_CMDID); 4011 if (ret) { 4012 wmi_err("Failed to start scan: %d", ret); 4013 wmi_buf_free(wmi_buf); 4014 } 4015 return ret; 4016 error: 4017 wmi_buf_free(wmi_buf); 4018 return QDF_STATUS_E_FAILURE; 4019 } 4020 4021 /** 4022 * send_scan_stop_cmd_tlv() - WMI scan start function 4023 * @param wmi_handle : handle to WMI. 4024 * @param param : pointer to hold scan cancel cmd parameter 4025 * 4026 * Return: 0 on success and -ve on failure. 4027 */ 4028 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4029 struct scan_cancel_param *param) 4030 { 4031 wmi_stop_scan_cmd_fixed_param *cmd; 4032 int ret; 4033 int len = sizeof(*cmd); 4034 wmi_buf_t wmi_buf; 4035 4036 /* Allocate the memory */ 4037 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4038 if (!wmi_buf) { 4039 ret = QDF_STATUS_E_NOMEM; 4040 goto error; 4041 } 4042 4043 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4044 WMITLV_SET_HDR(&cmd->tlv_header, 4045 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4046 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4047 cmd->vdev_id = param->vdev_id; 4048 cmd->requestor = param->requester; 4049 cmd->scan_id = param->scan_id; 4050 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4051 wmi_handle, 4052 param->pdev_id); 4053 /* stop the scan with the corresponding scan_id */ 4054 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4055 /* Cancelling all scans */ 4056 cmd->req_type = WMI_SCAN_STOP_ALL; 4057 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4058 /* Cancelling VAP scans */ 4059 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4060 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4061 /* Cancelling specific scan */ 4062 cmd->req_type = WMI_SCAN_STOP_ONE; 4063 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4064 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4065 } else { 4066 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4067 wmi_buf_free(wmi_buf); 4068 return QDF_STATUS_E_INVAL; 4069 } 4070 4071 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4072 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4073 len, WMI_STOP_SCAN_CMDID); 4074 if (ret) { 4075 wmi_err("Failed to send stop scan: %d", ret); 4076 wmi_buf_free(wmi_buf); 4077 } 4078 4079 error: 4080 return ret; 4081 } 4082 4083 #define WMI_MAX_CHAN_INFO_LOG 192 4084 4085 /** 4086 * wmi_scan_chanlist_dump() - Dump scan channel list info 4087 * @scan_chan_list: scan channel list 4088 * 4089 * Return: void 4090 */ 4091 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4092 { 4093 uint32_t i; 4094 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4095 uint32_t len = 0; 4096 struct channel_param *chan; 4097 int ret; 4098 4099 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4100 for (i = 0; i < scan_chan_list->nallchans; i++) { 4101 chan = &scan_chan_list->ch_param[i]; 4102 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4103 " %d[%d][%d][%d]", chan->mhz, 4104 chan->maxregpower, 4105 chan->dfs_set, chan->nan_disabled); 4106 if (ret <= 0) 4107 break; 4108 len += ret; 4109 if (len >= (sizeof(info) - 20)) { 4110 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4111 info); 4112 len = 0; 4113 } 4114 } 4115 if (len) 4116 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4117 } 4118 4119 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4120 struct scan_chan_list_params *chan_list) 4121 { 4122 wmi_buf_t buf; 4123 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4124 wmi_scan_chan_list_cmd_fixed_param *cmd; 4125 int i; 4126 uint8_t *buf_ptr; 4127 wmi_channel *chan_info; 4128 struct channel_param *tchan_info; 4129 uint16_t len; 4130 uint16_t num_send_chans, num_sends = 0; 4131 4132 wmi_scan_chanlist_dump(chan_list); 4133 tchan_info = &chan_list->ch_param[0]; 4134 while (chan_list->nallchans) { 4135 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4136 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4137 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4138 else 4139 num_send_chans = chan_list->nallchans; 4140 4141 chan_list->nallchans -= num_send_chans; 4142 len += sizeof(wmi_channel) * num_send_chans; 4143 buf = wmi_buf_alloc(wmi_handle, len); 4144 if (!buf) { 4145 qdf_status = QDF_STATUS_E_NOMEM; 4146 goto end; 4147 } 4148 4149 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4150 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4151 WMITLV_SET_HDR(&cmd->tlv_header, 4152 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4153 WMITLV_GET_STRUCT_TLVLEN 4154 (wmi_scan_chan_list_cmd_fixed_param)); 4155 4156 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4157 4158 if (num_sends) 4159 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4160 4161 if (chan_list->max_bw_support_present) 4162 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4163 4164 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4165 wmi_handle, 4166 chan_list->pdev_id); 4167 4168 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4169 4170 cmd->num_scan_chans = num_send_chans; 4171 WMITLV_SET_HDR((buf_ptr + 4172 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4173 WMITLV_TAG_ARRAY_STRUC, 4174 sizeof(wmi_channel) * num_send_chans); 4175 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4176 WMI_TLV_HDR_SIZE); 4177 4178 for (i = 0; i < num_send_chans; ++i) { 4179 WMITLV_SET_HDR(&chan_info->tlv_header, 4180 WMITLV_TAG_STRUC_wmi_channel, 4181 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4182 chan_info->mhz = tchan_info->mhz; 4183 chan_info->band_center_freq1 = 4184 tchan_info->cfreq1; 4185 chan_info->band_center_freq2 = 4186 tchan_info->cfreq2; 4187 4188 if (tchan_info->is_chan_passive) 4189 WMI_SET_CHANNEL_FLAG(chan_info, 4190 WMI_CHAN_FLAG_PASSIVE); 4191 if (tchan_info->dfs_set) 4192 WMI_SET_CHANNEL_FLAG(chan_info, 4193 WMI_CHAN_FLAG_DFS); 4194 4195 if (tchan_info->dfs_set_cfreq2) 4196 WMI_SET_CHANNEL_FLAG(chan_info, 4197 WMI_CHAN_FLAG_DFS_CFREQ2); 4198 4199 if (tchan_info->allow_he) 4200 WMI_SET_CHANNEL_FLAG(chan_info, 4201 WMI_CHAN_FLAG_ALLOW_HE); 4202 4203 if (tchan_info->allow_eht) 4204 WMI_SET_CHANNEL_FLAG(chan_info, 4205 WMI_CHAN_FLAG_ALLOW_EHT); 4206 4207 if (tchan_info->allow_vht) 4208 WMI_SET_CHANNEL_FLAG(chan_info, 4209 WMI_CHAN_FLAG_ALLOW_VHT); 4210 4211 if (tchan_info->allow_ht) 4212 WMI_SET_CHANNEL_FLAG(chan_info, 4213 WMI_CHAN_FLAG_ALLOW_HT); 4214 WMI_SET_CHANNEL_MODE(chan_info, 4215 tchan_info->phy_mode); 4216 4217 if (tchan_info->half_rate) 4218 WMI_SET_CHANNEL_FLAG(chan_info, 4219 WMI_CHAN_FLAG_HALF_RATE); 4220 4221 if (tchan_info->quarter_rate) 4222 WMI_SET_CHANNEL_FLAG(chan_info, 4223 WMI_CHAN_FLAG_QUARTER_RATE); 4224 4225 if (tchan_info->psc_channel) 4226 WMI_SET_CHANNEL_FLAG(chan_info, 4227 WMI_CHAN_FLAG_PSC); 4228 4229 if (tchan_info->nan_disabled) 4230 WMI_SET_CHANNEL_FLAG(chan_info, 4231 WMI_CHAN_FLAG_NAN_DISABLED); 4232 4233 /* also fill in power information */ 4234 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4235 tchan_info->minpower); 4236 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4237 tchan_info->maxpower); 4238 WMI_SET_CHANNEL_REG_POWER(chan_info, 4239 tchan_info->maxregpower); 4240 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4241 tchan_info->antennamax); 4242 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4243 tchan_info->reg_class_id); 4244 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4245 tchan_info->maxregpower); 4246 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4247 tchan_info->max_bw_supported); 4248 4249 tchan_info++; 4250 chan_info++; 4251 } 4252 4253 qdf_status = wmi_unified_cmd_send( 4254 wmi_handle, 4255 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4256 4257 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4258 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4259 wmi_buf_free(buf); 4260 goto end; 4261 } 4262 num_sends++; 4263 } 4264 4265 end: 4266 return qdf_status; 4267 } 4268 4269 /** 4270 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4271 * 4272 * @bufp: Pointer to buffer 4273 * @param: Pointer to tx param 4274 * 4275 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4276 */ 4277 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4278 struct tx_send_params param) 4279 { 4280 wmi_tx_send_params *tx_param; 4281 QDF_STATUS status = QDF_STATUS_SUCCESS; 4282 4283 if (!bufp) { 4284 status = QDF_STATUS_E_FAILURE; 4285 return status; 4286 } 4287 tx_param = (wmi_tx_send_params *)bufp; 4288 WMITLV_SET_HDR(&tx_param->tlv_header, 4289 WMITLV_TAG_STRUC_wmi_tx_send_params, 4290 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4291 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4292 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4293 param.mcs_mask); 4294 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4295 param.nss_mask); 4296 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4297 param.retry_limit); 4298 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4299 param.chain_mask); 4300 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4301 param.bw_mask); 4302 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4303 param.preamble_type); 4304 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4305 param.frame_type); 4306 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4307 param.cfr_enable); 4308 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4309 param.en_beamforming); 4310 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4311 param.retry_limit_ext); 4312 4313 return status; 4314 } 4315 4316 #ifdef CONFIG_HL_SUPPORT 4317 /** 4318 * send_mgmt_cmd_tlv() - WMI scan start function 4319 * @wmi_handle : handle to WMI. 4320 * @param : pointer to hold mgmt cmd parameter 4321 * 4322 * Return: 0 on success and -ve on failure. 4323 */ 4324 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4325 struct wmi_mgmt_params *param) 4326 { 4327 wmi_buf_t buf; 4328 uint8_t *bufp; 4329 int32_t cmd_len; 4330 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4331 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4332 mgmt_tx_dl_frm_len; 4333 4334 if (param->frm_len > mgmt_tx_dl_frm_len) { 4335 wmi_err("mgmt frame len %u exceeds %u", 4336 param->frm_len, mgmt_tx_dl_frm_len); 4337 return QDF_STATUS_E_INVAL; 4338 } 4339 4340 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4341 WMI_TLV_HDR_SIZE + 4342 roundup(bufp_len, sizeof(uint32_t)); 4343 4344 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4345 if (!buf) 4346 return QDF_STATUS_E_NOMEM; 4347 4348 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4349 bufp = (uint8_t *) cmd; 4350 WMITLV_SET_HDR(&cmd->tlv_header, 4351 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4352 WMITLV_GET_STRUCT_TLVLEN 4353 (wmi_mgmt_tx_send_cmd_fixed_param)); 4354 4355 cmd->vdev_id = param->vdev_id; 4356 4357 cmd->desc_id = param->desc_id; 4358 cmd->chanfreq = param->chanfreq; 4359 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4360 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4361 sizeof(uint32_t))); 4362 bufp += WMI_TLV_HDR_SIZE; 4363 qdf_mem_copy(bufp, param->pdata, bufp_len); 4364 4365 cmd->frame_len = param->frm_len; 4366 cmd->buf_len = bufp_len; 4367 cmd->tx_params_valid = param->tx_params_valid; 4368 cmd->tx_flags = param->tx_flags; 4369 cmd->peer_rssi = param->peer_rssi; 4370 4371 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4372 bufp, cmd->vdev_id, cmd->chanfreq); 4373 4374 bufp += roundup(bufp_len, sizeof(uint32_t)); 4375 if (param->tx_params_valid) { 4376 if (populate_tx_send_params(bufp, param->tx_param) != 4377 QDF_STATUS_SUCCESS) { 4378 wmi_err("Populate TX send params failed"); 4379 goto free_buf; 4380 } 4381 cmd_len += sizeof(wmi_tx_send_params); 4382 } 4383 4384 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4385 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4386 WMI_MGMT_TX_SEND_CMDID)) { 4387 wmi_err("Failed to send mgmt Tx"); 4388 goto free_buf; 4389 } 4390 return QDF_STATUS_SUCCESS; 4391 4392 free_buf: 4393 wmi_buf_free(buf); 4394 return QDF_STATUS_E_FAILURE; 4395 } 4396 #else 4397 /** 4398 * send_mgmt_cmd_tlv() - WMI scan start function 4399 * @wmi_handle : handle to WMI. 4400 * @param : pointer to hold mgmt cmd parameter 4401 * 4402 * Return: 0 on success and -ve on failure. 4403 */ 4404 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4405 struct wmi_mgmt_params *param) 4406 { 4407 wmi_buf_t buf; 4408 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4409 int32_t cmd_len; 4410 uint64_t dma_addr; 4411 void *qdf_ctx = param->qdf_ctx; 4412 uint8_t *bufp; 4413 QDF_STATUS status = QDF_STATUS_SUCCESS; 4414 wmi_mlo_tx_send_params *mlo_params; 4415 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4416 mgmt_tx_dl_frm_len; 4417 4418 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4419 WMI_TLV_HDR_SIZE + 4420 roundup(bufp_len, sizeof(uint32_t)); 4421 4422 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4423 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4424 if (!buf) 4425 return QDF_STATUS_E_NOMEM; 4426 4427 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4428 bufp = (uint8_t *) cmd; 4429 WMITLV_SET_HDR(&cmd->tlv_header, 4430 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4431 WMITLV_GET_STRUCT_TLVLEN 4432 (wmi_mgmt_tx_send_cmd_fixed_param)); 4433 4434 cmd->vdev_id = param->vdev_id; 4435 4436 cmd->desc_id = param->desc_id; 4437 cmd->chanfreq = param->chanfreq; 4438 cmd->peer_rssi = param->peer_rssi; 4439 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4440 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4441 sizeof(uint32_t))); 4442 bufp += WMI_TLV_HDR_SIZE; 4443 4444 /* for big endian host, copy engine byte_swap is enabled 4445 * But the frame content is in network byte order 4446 * Need to byte swap the frame content - so when copy engine 4447 * does byte_swap - target gets frame content in the correct order 4448 */ 4449 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4450 4451 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4452 QDF_DMA_TO_DEVICE); 4453 if (status != QDF_STATUS_SUCCESS) { 4454 wmi_err("wmi buf map failed"); 4455 goto free_buf; 4456 } 4457 4458 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4459 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4460 #if defined(HTT_PADDR64) 4461 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4462 #endif 4463 cmd->frame_len = param->frm_len; 4464 cmd->buf_len = bufp_len; 4465 cmd->tx_params_valid = param->tx_params_valid; 4466 cmd->tx_flags = param->tx_flags; 4467 4468 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4469 bufp, cmd->vdev_id, cmd->chanfreq); 4470 4471 bufp += roundup(bufp_len, sizeof(uint32_t)); 4472 if (param->tx_params_valid) { 4473 status = populate_tx_send_params(bufp, param->tx_param); 4474 if (status != QDF_STATUS_SUCCESS) { 4475 wmi_err("Populate TX send params failed"); 4476 goto unmap_tx_frame; 4477 } 4478 } else { 4479 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4480 WMITLV_TAG_STRUC_wmi_tx_send_params, 4481 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4482 } 4483 4484 /* Even tx_params_valid is false, still need reserve space to pass wmi 4485 * tag check */ 4486 cmd_len += sizeof(wmi_tx_send_params); 4487 bufp += sizeof(wmi_tx_send_params); 4488 /* wmi_mlo_tx_send_params */ 4489 if (param->mlo_link_agnostic) { 4490 wmi_debug("Set mlo mgmt tid"); 4491 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4492 sizeof(wmi_mlo_tx_send_params)); 4493 bufp += WMI_TLV_HDR_SIZE; 4494 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4495 WMITLV_SET_HDR(&mlo_params->tlv_header, 4496 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4497 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4498 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4499 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4500 } 4501 4502 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4503 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4504 WMI_MGMT_TX_SEND_CMDID)) { 4505 wmi_err("Failed to send mgmt Tx"); 4506 goto unmap_tx_frame; 4507 } 4508 return QDF_STATUS_SUCCESS; 4509 4510 unmap_tx_frame: 4511 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4512 QDF_DMA_TO_DEVICE); 4513 free_buf: 4514 wmi_buf_free(buf); 4515 return QDF_STATUS_E_FAILURE; 4516 } 4517 #endif /* CONFIG_HL_SUPPORT */ 4518 4519 /** 4520 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 4521 * @wmi_handle : handle to WMI. 4522 * @param : pointer to offchan data tx cmd parameter 4523 * 4524 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4525 */ 4526 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4527 struct wmi_offchan_data_tx_params *param) 4528 { 4529 wmi_buf_t buf; 4530 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4531 int32_t cmd_len; 4532 uint64_t dma_addr; 4533 void *qdf_ctx = param->qdf_ctx; 4534 uint8_t *bufp; 4535 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4536 param->frm_len : mgmt_tx_dl_frm_len; 4537 QDF_STATUS status = QDF_STATUS_SUCCESS; 4538 4539 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4540 WMI_TLV_HDR_SIZE + 4541 roundup(bufp_len, sizeof(uint32_t)); 4542 4543 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4544 if (!buf) 4545 return QDF_STATUS_E_NOMEM; 4546 4547 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4548 bufp = (uint8_t *) cmd; 4549 WMITLV_SET_HDR(&cmd->tlv_header, 4550 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4551 WMITLV_GET_STRUCT_TLVLEN 4552 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4553 4554 cmd->vdev_id = param->vdev_id; 4555 4556 cmd->desc_id = param->desc_id; 4557 cmd->chanfreq = param->chanfreq; 4558 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4559 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4560 sizeof(uint32_t))); 4561 bufp += WMI_TLV_HDR_SIZE; 4562 qdf_mem_copy(bufp, param->pdata, bufp_len); 4563 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4564 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4565 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4566 #if defined(HTT_PADDR64) 4567 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4568 #endif 4569 cmd->frame_len = param->frm_len; 4570 cmd->buf_len = bufp_len; 4571 cmd->tx_params_valid = param->tx_params_valid; 4572 4573 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4574 bufp, cmd->vdev_id, cmd->chanfreq); 4575 4576 bufp += roundup(bufp_len, sizeof(uint32_t)); 4577 if (param->tx_params_valid) { 4578 status = populate_tx_send_params(bufp, param->tx_param); 4579 if (status != QDF_STATUS_SUCCESS) { 4580 wmi_err("Populate TX send params failed"); 4581 goto err1; 4582 } 4583 cmd_len += sizeof(wmi_tx_send_params); 4584 } 4585 4586 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4587 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4588 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4589 wmi_err("Failed to offchan data Tx"); 4590 goto err1; 4591 } 4592 4593 return QDF_STATUS_SUCCESS; 4594 4595 err1: 4596 wmi_buf_free(buf); 4597 return QDF_STATUS_E_FAILURE; 4598 } 4599 4600 /** 4601 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4602 * @wmi_handle: wmi handle 4603 * @param_value: parameter value 4604 * 4605 * Return: QDF_STATUS_SUCCESS for success or error code 4606 */ 4607 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4608 uint32_t param_value) 4609 { 4610 QDF_STATUS ret; 4611 wmi_modem_power_state_cmd_param *cmd; 4612 wmi_buf_t buf; 4613 uint16_t len = sizeof(*cmd); 4614 4615 buf = wmi_buf_alloc(wmi_handle, len); 4616 if (!buf) 4617 return QDF_STATUS_E_NOMEM; 4618 4619 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4620 WMITLV_SET_HDR(&cmd->tlv_header, 4621 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4622 WMITLV_GET_STRUCT_TLVLEN 4623 (wmi_modem_power_state_cmd_param)); 4624 cmd->modem_power_state = param_value; 4625 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4626 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4627 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4628 WMI_MODEM_POWER_STATE_CMDID); 4629 if (QDF_IS_STATUS_ERROR(ret)) { 4630 wmi_err("Failed to send notify cmd ret = %d", ret); 4631 wmi_buf_free(buf); 4632 } 4633 4634 return ret; 4635 } 4636 4637 /** 4638 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4639 * @wmi_handle: wmi handle 4640 * @vdev_id: vdev id 4641 * @val: value 4642 * 4643 * Return: QDF_STATUS_SUCCESS for success or error code. 4644 */ 4645 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4646 uint32_t vdev_id, uint8_t val) 4647 { 4648 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4649 wmi_buf_t buf; 4650 int32_t len = sizeof(*cmd); 4651 4652 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4653 4654 buf = wmi_buf_alloc(wmi_handle, len); 4655 if (!buf) 4656 return QDF_STATUS_E_NOMEM; 4657 4658 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4659 WMITLV_SET_HDR(&cmd->tlv_header, 4660 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4661 WMITLV_GET_STRUCT_TLVLEN 4662 (wmi_sta_powersave_mode_cmd_fixed_param)); 4663 cmd->vdev_id = vdev_id; 4664 if (val) 4665 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4666 else 4667 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4668 4669 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4670 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4671 WMI_STA_POWERSAVE_MODE_CMDID)) { 4672 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4673 vdev_id, val); 4674 wmi_buf_free(buf); 4675 return QDF_STATUS_E_FAILURE; 4676 } 4677 return QDF_STATUS_SUCCESS; 4678 } 4679 4680 /** 4681 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4682 * @wmi_handle: wmi handle 4683 * @vdev_id: vdev id 4684 * 4685 * Return: QDF_STATUS_SUCCESS for success or error code. 4686 */ 4687 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4688 uint8_t val) 4689 { 4690 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4691 wmi_buf_t buf; 4692 size_t len = sizeof(*cmd); 4693 4694 buf = wmi_buf_alloc(wmi_handle, len); 4695 if (!buf) 4696 return QDF_STATUS_E_NOMEM; 4697 4698 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4699 WMITLV_SET_HDR(&cmd->tlv_header, 4700 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4701 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4702 4703 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4704 WMI_IDLE_TRIGGER_MONITOR_OFF); 4705 4706 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4707 4708 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4709 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4710 wmi_buf_free(buf); 4711 return QDF_STATUS_E_FAILURE; 4712 } 4713 return QDF_STATUS_SUCCESS; 4714 } 4715 4716 /** 4717 * send_set_mimops_cmd_tlv() - set MIMO powersave 4718 * @wmi_handle: wmi handle 4719 * @vdev_id: vdev id 4720 * @value: value 4721 * 4722 * Return: QDF_STATUS_SUCCESS for success or error code. 4723 */ 4724 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4725 uint8_t vdev_id, int value) 4726 { 4727 QDF_STATUS ret; 4728 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4729 wmi_buf_t buf; 4730 uint16_t len = sizeof(*cmd); 4731 4732 buf = wmi_buf_alloc(wmi_handle, len); 4733 if (!buf) 4734 return QDF_STATUS_E_NOMEM; 4735 4736 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4737 WMITLV_SET_HDR(&cmd->tlv_header, 4738 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4739 WMITLV_GET_STRUCT_TLVLEN 4740 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4741 4742 cmd->vdev_id = vdev_id; 4743 4744 /* WMI_SMPS_FORCED_MODE values do not directly map 4745 * to SM power save values defined in the specification. 4746 * Make sure to send the right mapping. 4747 */ 4748 switch (value) { 4749 case 0: 4750 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4751 break; 4752 case 1: 4753 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4754 break; 4755 case 2: 4756 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4757 break; 4758 case 3: 4759 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4760 break; 4761 default: 4762 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4763 wmi_buf_free(buf); 4764 return QDF_STATUS_E_FAILURE; 4765 } 4766 4767 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4768 4769 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4770 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4771 WMI_STA_SMPS_FORCE_MODE_CMDID); 4772 if (QDF_IS_STATUS_ERROR(ret)) { 4773 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4774 wmi_buf_free(buf); 4775 } 4776 4777 return ret; 4778 } 4779 4780 /** 4781 * send_set_smps_params_cmd_tlv() - set smps params 4782 * @wmi_handle: wmi handle 4783 * @vdev_id: vdev id 4784 * @value: value 4785 * 4786 * Return: QDF_STATUS_SUCCESS for success or error code. 4787 */ 4788 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4789 int value) 4790 { 4791 QDF_STATUS ret; 4792 wmi_sta_smps_param_cmd_fixed_param *cmd; 4793 wmi_buf_t buf; 4794 uint16_t len = sizeof(*cmd); 4795 4796 buf = wmi_buf_alloc(wmi_handle, len); 4797 if (!buf) 4798 return QDF_STATUS_E_NOMEM; 4799 4800 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4801 WMITLV_SET_HDR(&cmd->tlv_header, 4802 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4803 WMITLV_GET_STRUCT_TLVLEN 4804 (wmi_sta_smps_param_cmd_fixed_param)); 4805 4806 cmd->vdev_id = vdev_id; 4807 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4808 cmd->param = 4809 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4810 4811 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4812 cmd->param); 4813 4814 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4815 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4816 WMI_STA_SMPS_PARAM_CMDID); 4817 if (QDF_IS_STATUS_ERROR(ret)) { 4818 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4819 wmi_buf_free(buf); 4820 } 4821 4822 return ret; 4823 } 4824 4825 /** 4826 * send_get_temperature_cmd_tlv() - get pdev temperature req 4827 * @wmi_handle: wmi handle 4828 * 4829 * Return: QDF_STATUS_SUCCESS for success or error code. 4830 */ 4831 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4832 { 4833 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4834 wmi_buf_t wmi_buf; 4835 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4836 uint8_t *buf_ptr; 4837 4838 if (!wmi_handle) { 4839 wmi_err("WMI is closed, can not issue cmd"); 4840 return QDF_STATUS_E_INVAL; 4841 } 4842 4843 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4844 if (!wmi_buf) 4845 return QDF_STATUS_E_NOMEM; 4846 4847 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4848 4849 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4850 WMITLV_SET_HDR(&cmd->tlv_header, 4851 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4852 WMITLV_GET_STRUCT_TLVLEN 4853 (wmi_pdev_get_temperature_cmd_fixed_param)); 4854 4855 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4856 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4857 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4858 wmi_err("Failed to send get temperature command"); 4859 wmi_buf_free(wmi_buf); 4860 return QDF_STATUS_E_FAILURE; 4861 } 4862 4863 return QDF_STATUS_SUCCESS; 4864 } 4865 4866 /** 4867 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4868 * @wmi_handle: wmi handle 4869 * @vdevid: vdev id 4870 * @peer_addr: peer mac address 4871 * @auto_triggerparam: auto trigger parameters 4872 * @num_ac: number of access category 4873 * 4874 * This function sets the trigger 4875 * uapsd params such as service interval, delay interval 4876 * and suspend interval which will be used by the firmware 4877 * to send trigger frames periodically when there is no 4878 * traffic on the transmit side. 4879 * 4880 * Return: QDF_STATUS_SUCCESS for success or error code. 4881 */ 4882 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4883 struct sta_uapsd_trig_params *param) 4884 { 4885 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4886 QDF_STATUS ret; 4887 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4888 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4889 uint32_t i; 4890 wmi_buf_t buf; 4891 uint8_t *buf_ptr; 4892 struct sta_uapsd_params *uapsd_param; 4893 wmi_sta_uapsd_auto_trig_param *trig_param; 4894 4895 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4896 if (!buf) 4897 return QDF_STATUS_E_NOMEM; 4898 4899 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4900 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4901 WMITLV_SET_HDR(&cmd->tlv_header, 4902 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4903 WMITLV_GET_STRUCT_TLVLEN 4904 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4905 cmd->vdev_id = param->vdevid; 4906 cmd->num_ac = param->num_ac; 4907 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4908 4909 /* TLV indicating array of structures to follow */ 4910 buf_ptr += sizeof(*cmd); 4911 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4912 4913 buf_ptr += WMI_TLV_HDR_SIZE; 4914 4915 /* 4916 * Update tag and length for uapsd auto trigger params (this will take 4917 * care of updating tag and length if it is not pre-filled by caller). 4918 */ 4919 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4920 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4921 for (i = 0; i < param->num_ac; i++) { 4922 WMITLV_SET_HDR((buf_ptr + 4923 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4924 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4925 WMITLV_GET_STRUCT_TLVLEN 4926 (wmi_sta_uapsd_auto_trig_param)); 4927 trig_param->wmm_ac = uapsd_param->wmm_ac; 4928 trig_param->user_priority = uapsd_param->user_priority; 4929 trig_param->service_interval = uapsd_param->service_interval; 4930 trig_param->suspend_interval = uapsd_param->suspend_interval; 4931 trig_param->delay_interval = uapsd_param->delay_interval; 4932 trig_param++; 4933 uapsd_param++; 4934 } 4935 4936 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4937 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4938 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4939 if (QDF_IS_STATUS_ERROR(ret)) { 4940 wmi_err("Failed to send set uapsd param ret = %d", ret); 4941 wmi_buf_free(buf); 4942 } 4943 4944 return ret; 4945 } 4946 4947 /** 4948 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4949 * @wmi_handle: Pointer to wmi handle 4950 * @thermal_info: Thermal command information 4951 * 4952 * This function sends the thermal management command 4953 * to the firmware 4954 * 4955 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4956 */ 4957 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4958 struct thermal_cmd_params *thermal_info) 4959 { 4960 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4961 wmi_buf_t buf = NULL; 4962 QDF_STATUS status; 4963 uint32_t len = 0; 4964 uint8_t action; 4965 4966 switch (thermal_info->thermal_action) { 4967 case THERMAL_MGMT_ACTION_DEFAULT: 4968 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4969 break; 4970 4971 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4972 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4973 break; 4974 4975 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4976 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4977 break; 4978 4979 case THERMAL_MGMT_ACTION_CHAINSCALING: 4980 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4981 break; 4982 4983 default: 4984 wmi_err("Invalid thermal_action code %d", 4985 thermal_info->thermal_action); 4986 return QDF_STATUS_E_FAILURE; 4987 } 4988 4989 len = sizeof(*cmd); 4990 4991 buf = wmi_buf_alloc(wmi_handle, len); 4992 if (!buf) 4993 return QDF_STATUS_E_FAILURE; 4994 4995 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4996 4997 WMITLV_SET_HDR(&cmd->tlv_header, 4998 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4999 WMITLV_GET_STRUCT_TLVLEN 5000 (wmi_thermal_mgmt_cmd_fixed_param)); 5001 5002 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5003 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5004 cmd->enable = thermal_info->thermal_enable; 5005 cmd->action = action; 5006 5007 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5008 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5009 cmd->enable, cmd->action); 5010 5011 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5012 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5013 WMI_THERMAL_MGMT_CMDID); 5014 if (QDF_IS_STATUS_ERROR(status)) { 5015 wmi_buf_free(buf); 5016 wmi_err("Failed to send thermal mgmt command"); 5017 } 5018 5019 return status; 5020 } 5021 5022 /** 5023 * send_lro_config_cmd_tlv() - process the LRO config command 5024 * @wmi_handle: Pointer to WMI handle 5025 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5026 * 5027 * This function sends down the LRO configuration parameters to 5028 * the firmware to enable LRO, sets the TCP flags and sets the 5029 * seed values for the toeplitz hash generation 5030 * 5031 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5032 */ 5033 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5034 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5035 { 5036 wmi_lro_info_cmd_fixed_param *cmd; 5037 wmi_buf_t buf; 5038 QDF_STATUS status; 5039 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5040 5041 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5042 if (!buf) 5043 return QDF_STATUS_E_FAILURE; 5044 5045 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5046 5047 WMITLV_SET_HDR(&cmd->tlv_header, 5048 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5049 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5050 5051 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5052 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5053 wmi_lro_cmd->tcp_flag); 5054 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5055 wmi_lro_cmd->tcp_flag_mask); 5056 cmd->toeplitz_hash_ipv4_0_3 = 5057 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5058 cmd->toeplitz_hash_ipv4_4_7 = 5059 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5060 cmd->toeplitz_hash_ipv4_8_11 = 5061 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5062 cmd->toeplitz_hash_ipv4_12_15 = 5063 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5064 cmd->toeplitz_hash_ipv4_16 = 5065 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5066 5067 cmd->toeplitz_hash_ipv6_0_3 = 5068 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5069 cmd->toeplitz_hash_ipv6_4_7 = 5070 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5071 cmd->toeplitz_hash_ipv6_8_11 = 5072 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5073 cmd->toeplitz_hash_ipv6_12_15 = 5074 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5075 cmd->toeplitz_hash_ipv6_16_19 = 5076 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5077 cmd->toeplitz_hash_ipv6_20_23 = 5078 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5079 cmd->toeplitz_hash_ipv6_24_27 = 5080 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5081 cmd->toeplitz_hash_ipv6_28_31 = 5082 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5083 cmd->toeplitz_hash_ipv6_32_35 = 5084 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5085 cmd->toeplitz_hash_ipv6_36_39 = 5086 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5087 cmd->toeplitz_hash_ipv6_40 = 5088 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5089 5090 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5091 wmi_handle, 5092 pdev_id); 5093 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5094 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5095 5096 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5097 status = wmi_unified_cmd_send(wmi_handle, buf, 5098 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5099 if (QDF_IS_STATUS_ERROR(status)) { 5100 wmi_buf_free(buf); 5101 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5102 } 5103 5104 return status; 5105 } 5106 5107 /** 5108 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5109 * @wmi_handle: Pointer to wmi handle 5110 * @rate_report_params: Pointer to peer rate report parameters 5111 * 5112 * 5113 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5114 */ 5115 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5116 struct wmi_peer_rate_report_params *rate_report_params) 5117 { 5118 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5119 wmi_buf_t buf = NULL; 5120 QDF_STATUS status = 0; 5121 uint32_t len = 0; 5122 uint32_t i, j; 5123 5124 len = sizeof(*cmd); 5125 5126 buf = wmi_buf_alloc(wmi_handle, len); 5127 if (!buf) 5128 return QDF_STATUS_E_FAILURE; 5129 5130 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5131 wmi_buf_data(buf); 5132 5133 WMITLV_SET_HDR( 5134 &cmd->tlv_header, 5135 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5136 WMITLV_GET_STRUCT_TLVLEN( 5137 wmi_peer_set_rate_report_condition_fixed_param)); 5138 5139 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5140 cmd->report_backoff_time = rate_report_params->backoff_time; 5141 cmd->report_timer_period = rate_report_params->timer_period; 5142 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5143 cmd->cond_per_phy[i].val_cond_flags = 5144 rate_report_params->report_per_phy[i].cond_flags; 5145 cmd->cond_per_phy[i].rate_delta.min_delta = 5146 rate_report_params->report_per_phy[i].delta.delta_min; 5147 cmd->cond_per_phy[i].rate_delta.percentage = 5148 rate_report_params->report_per_phy[i].delta.percent; 5149 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5150 cmd->cond_per_phy[i].rate_threshold[j] = 5151 rate_report_params->report_per_phy[i]. 5152 report_rate_threshold[j]; 5153 } 5154 } 5155 5156 wmi_debug("enable %d backoff_time %d period %d", 5157 cmd->enable_rate_report, 5158 cmd->report_backoff_time, cmd->report_timer_period); 5159 5160 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5161 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5162 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5163 if (QDF_IS_STATUS_ERROR(status)) { 5164 wmi_buf_free(buf); 5165 wmi_err("Failed to send peer_set_report_cond command"); 5166 } 5167 return status; 5168 } 5169 5170 /** 5171 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5172 * @wmi_handle: wmi handle 5173 * @vdev_id: vdev id. 5174 * @wmm_vparams: edca parameters 5175 * 5176 * This function updates EDCA parameters to the target 5177 * 5178 * Return: CDF Status 5179 */ 5180 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5181 uint8_t vdev_id, bool mu_edca_param, 5182 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5183 { 5184 uint8_t *buf_ptr; 5185 wmi_buf_t buf; 5186 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5187 wmi_wmm_vparams *wmm_param; 5188 struct wmi_host_wme_vparams *twmm_param; 5189 int len = sizeof(*cmd); 5190 int ac; 5191 5192 buf = wmi_buf_alloc(wmi_handle, len); 5193 5194 if (!buf) 5195 return QDF_STATUS_E_NOMEM; 5196 5197 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5198 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5199 WMITLV_SET_HDR(&cmd->tlv_header, 5200 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5201 WMITLV_GET_STRUCT_TLVLEN 5202 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5203 cmd->vdev_id = vdev_id; 5204 cmd->wmm_param_type = mu_edca_param; 5205 5206 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5207 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5208 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5209 WMITLV_SET_HDR(&wmm_param->tlv_header, 5210 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5211 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5212 wmm_param->cwmin = twmm_param->cwmin; 5213 wmm_param->cwmax = twmm_param->cwmax; 5214 wmm_param->aifs = twmm_param->aifs; 5215 if (mu_edca_param) 5216 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5217 else 5218 wmm_param->txoplimit = twmm_param->txoplimit; 5219 wmm_param->acm = twmm_param->acm; 5220 wmm_param->no_ack = twmm_param->noackpolicy; 5221 } 5222 5223 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5224 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5225 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5226 goto fail; 5227 5228 return QDF_STATUS_SUCCESS; 5229 5230 fail: 5231 wmi_buf_free(buf); 5232 wmi_err("Failed to set WMM Parameters"); 5233 return QDF_STATUS_E_FAILURE; 5234 } 5235 5236 /** 5237 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5238 * @wmi_handle: wmi handle 5239 * @vdev_id: vdev id 5240 * @probe_rsp_info: probe response info 5241 * 5242 * Return: QDF_STATUS_SUCCESS for success or error code 5243 */ 5244 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5245 uint8_t vdev_id, 5246 struct wmi_probe_resp_params *probe_rsp_info) 5247 { 5248 wmi_prb_tmpl_cmd_fixed_param *cmd; 5249 wmi_bcn_prb_info *bcn_prb_info; 5250 wmi_buf_t wmi_buf; 5251 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5252 uint8_t *buf_ptr; 5253 QDF_STATUS ret; 5254 5255 wmi_debug("Send probe response template for vdev %d", vdev_id); 5256 5257 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5258 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5259 5260 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5261 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5262 tmpl_len_aligned; 5263 5264 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5265 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5266 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5267 return QDF_STATUS_E_INVAL; 5268 } 5269 5270 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5271 if (!wmi_buf) 5272 return QDF_STATUS_E_NOMEM; 5273 5274 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5275 5276 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5277 WMITLV_SET_HDR(&cmd->tlv_header, 5278 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5279 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5280 cmd->vdev_id = vdev_id; 5281 cmd->buf_len = tmpl_len; 5282 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5283 5284 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5285 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5286 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5287 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5288 bcn_prb_info->caps = 0; 5289 bcn_prb_info->erp = 0; 5290 buf_ptr += sizeof(wmi_bcn_prb_info); 5291 5292 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5293 buf_ptr += WMI_TLV_HDR_SIZE; 5294 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5295 5296 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5297 ret = wmi_unified_cmd_send(wmi_handle, 5298 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5299 if (QDF_IS_STATUS_ERROR(ret)) { 5300 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5301 wmi_buf_free(wmi_buf); 5302 } 5303 5304 return ret; 5305 } 5306 5307 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5308 #define WPI_IV_LEN 16 5309 5310 /** 5311 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5312 * 5313 * @dest_tx: destination address of tsc key counter 5314 * @src_tx: source address of tsc key counter 5315 * @dest_rx: destination address of rsc key counter 5316 * @src_rx: source address of rsc key counter 5317 * 5318 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5319 * 5320 * Return: None 5321 * 5322 */ 5323 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5324 uint8_t *dest_rx, uint8_t *src_rx) 5325 { 5326 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5327 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5328 } 5329 #else 5330 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5331 uint8_t *dest_rx, uint8_t *src_rx) 5332 { 5333 return; 5334 } 5335 #endif 5336 5337 /** 5338 * send_setup_install_key_cmd_tlv() - set key parameters 5339 * @wmi_handle: wmi handle 5340 * @key_params: key parameters 5341 * 5342 * This function fills structure from information 5343 * passed in key_params. 5344 * 5345 * Return: QDF_STATUS_SUCCESS - success 5346 * QDF_STATUS_E_FAILURE - failure 5347 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5348 */ 5349 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5350 struct set_key_params *key_params) 5351 { 5352 wmi_vdev_install_key_cmd_fixed_param *cmd; 5353 wmi_buf_t buf; 5354 uint8_t *buf_ptr; 5355 uint32_t len; 5356 uint8_t *key_data; 5357 QDF_STATUS status; 5358 5359 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5360 WMI_TLV_HDR_SIZE; 5361 5362 buf = wmi_buf_alloc(wmi_handle, len); 5363 if (!buf) 5364 return QDF_STATUS_E_NOMEM; 5365 5366 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5367 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5368 WMITLV_SET_HDR(&cmd->tlv_header, 5369 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5370 WMITLV_GET_STRUCT_TLVLEN 5371 (wmi_vdev_install_key_cmd_fixed_param)); 5372 cmd->vdev_id = key_params->vdev_id; 5373 cmd->key_ix = key_params->key_idx; 5374 if (key_params->group_key_idx) { 5375 cmd->is_group_key_ix_valid = 1; 5376 cmd->group_key_ix = key_params->group_key_idx; 5377 } 5378 5379 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5380 cmd->key_flags |= key_params->key_flags; 5381 cmd->key_cipher = key_params->key_cipher; 5382 if ((key_params->key_txmic_len) && 5383 (key_params->key_rxmic_len)) { 5384 cmd->key_txmic_len = key_params->key_txmic_len; 5385 cmd->key_rxmic_len = key_params->key_rxmic_len; 5386 } 5387 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5388 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5389 key_params->tx_iv, 5390 cmd->wpi_key_rsc_counter, 5391 key_params->rx_iv); 5392 #endif 5393 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5394 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5395 roundup(key_params->key_len, sizeof(uint32_t))); 5396 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5397 5398 /* for big endian host, copy engine byte_swap is enabled 5399 * But key_data is in network byte order 5400 * Need to byte swap the key_data - so when copy engine 5401 * does byte_swap - target gets key_data in the correct order 5402 */ 5403 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5404 (const void *)key_params->key_data, 5405 key_params->key_len); 5406 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5407 sizeof(wmi_key_seq_counter)); 5408 cmd->key_len = key_params->key_len; 5409 5410 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5411 sizeof(wmi_key_seq_counter)); 5412 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5413 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5414 WMI_VDEV_INSTALL_KEY_CMDID); 5415 if (QDF_IS_STATUS_ERROR(status)) { 5416 qdf_mem_zero(wmi_buf_data(buf), len); 5417 wmi_buf_free(buf); 5418 } 5419 return status; 5420 } 5421 5422 /** 5423 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5424 * @wmi_handle: wmi handle 5425 * @vdev_id: vdev id 5426 * @p2p_ie: p2p IE 5427 * 5428 * Return: QDF_STATUS_SUCCESS for success or error code 5429 */ 5430 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5431 uint32_t vdev_id, uint8_t *p2p_ie) 5432 { 5433 QDF_STATUS ret; 5434 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5435 wmi_buf_t wmi_buf; 5436 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5437 uint8_t *buf_ptr; 5438 5439 ie_len = (uint32_t) (p2p_ie[1] + 2); 5440 5441 /* More than one P2P IE may be included in a single frame. 5442 If multiple P2P IEs are present, the complete P2P attribute 5443 data consists of the concatenation of the P2P Attribute 5444 fields of the P2P IEs. The P2P Attributes field of each 5445 P2P IE may be any length up to the maximum (251 octets). 5446 In this case host sends one P2P IE to firmware so the length 5447 should not exceed more than 251 bytes 5448 */ 5449 if (ie_len > 251) { 5450 wmi_err("Invalid p2p ie length %u", ie_len); 5451 return QDF_STATUS_E_INVAL; 5452 } 5453 5454 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5455 5456 wmi_buf_len = 5457 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5458 WMI_TLV_HDR_SIZE; 5459 5460 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5461 if (!wmi_buf) 5462 return QDF_STATUS_E_NOMEM; 5463 5464 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5465 5466 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5467 WMITLV_SET_HDR(&cmd->tlv_header, 5468 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5469 WMITLV_GET_STRUCT_TLVLEN 5470 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5471 cmd->vdev_id = vdev_id; 5472 cmd->ie_buf_len = ie_len; 5473 5474 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5475 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5476 buf_ptr += WMI_TLV_HDR_SIZE; 5477 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5478 5479 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5480 5481 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5482 ret = wmi_unified_cmd_send(wmi_handle, 5483 wmi_buf, wmi_buf_len, 5484 WMI_P2P_GO_SET_BEACON_IE); 5485 if (QDF_IS_STATUS_ERROR(ret)) { 5486 wmi_err("Failed to send bcn tmpl: %d", ret); 5487 wmi_buf_free(wmi_buf); 5488 } 5489 5490 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5491 return ret; 5492 } 5493 5494 /** 5495 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5496 * @wmi_handle: wmi handle 5497 * @psetoui: OUI parameters 5498 * 5499 * set scan probe OUI parameters in firmware 5500 * 5501 * Return: CDF status 5502 */ 5503 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5504 struct scan_mac_oui *psetoui) 5505 { 5506 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5507 wmi_buf_t wmi_buf; 5508 uint32_t len; 5509 uint8_t *buf_ptr; 5510 uint32_t *oui_buf; 5511 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5512 5513 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5514 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5515 5516 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5517 if (!wmi_buf) 5518 return QDF_STATUS_E_NOMEM; 5519 5520 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5521 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5522 WMITLV_SET_HDR(&cmd->tlv_header, 5523 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5524 WMITLV_GET_STRUCT_TLVLEN 5525 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5526 5527 oui_buf = &cmd->prob_req_oui; 5528 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5529 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5530 | psetoui->oui[2]; 5531 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5532 5533 cmd->vdev_id = psetoui->vdev_id; 5534 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5535 if (psetoui->enb_probe_req_sno_randomization) 5536 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5537 5538 if (ie_allowlist->allow_list) { 5539 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5540 &cmd->num_vendor_oui, 5541 ie_allowlist); 5542 cmd->flags |= 5543 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5544 } 5545 5546 buf_ptr += sizeof(*cmd); 5547 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5548 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5549 buf_ptr += WMI_TLV_HDR_SIZE; 5550 5551 if (cmd->num_vendor_oui != 0) { 5552 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5553 ie_allowlist->voui); 5554 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5555 } 5556 5557 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5558 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5559 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5560 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5561 wmi_buf_free(wmi_buf); 5562 return QDF_STATUS_E_FAILURE; 5563 } 5564 return QDF_STATUS_SUCCESS; 5565 } 5566 5567 #ifdef IPA_OFFLOAD 5568 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5569 * @wmi_handle: wmi handle 5570 * @ipa_offload: ipa offload control parameter 5571 * 5572 * Returns: 0 on success, error number otherwise 5573 */ 5574 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5575 struct ipa_uc_offload_control_params *ipa_offload) 5576 { 5577 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5578 wmi_buf_t wmi_buf; 5579 uint32_t len; 5580 u_int8_t *buf_ptr; 5581 5582 len = sizeof(*cmd); 5583 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5584 if (!wmi_buf) 5585 return QDF_STATUS_E_NOMEM; 5586 5587 wmi_debug("offload_type=%d, enable=%d", 5588 ipa_offload->offload_type, ipa_offload->enable); 5589 5590 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5591 5592 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5593 WMITLV_SET_HDR(&cmd->tlv_header, 5594 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5595 WMITLV_GET_STRUCT_TLVLEN( 5596 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5597 5598 cmd->offload_type = ipa_offload->offload_type; 5599 cmd->vdev_id = ipa_offload->vdev_id; 5600 cmd->enable = ipa_offload->enable; 5601 5602 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5603 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5604 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5605 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5606 wmi_buf_free(wmi_buf); 5607 return QDF_STATUS_E_FAILURE; 5608 } 5609 5610 return QDF_STATUS_SUCCESS; 5611 } 5612 #endif 5613 5614 /** 5615 * send_pno_stop_cmd_tlv() - PNO stop request 5616 * @wmi_handle: wmi handle 5617 * @vdev_id: vdev id 5618 * 5619 * This function request FW to stop ongoing PNO operation. 5620 * 5621 * Return: CDF status 5622 */ 5623 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5624 { 5625 wmi_nlo_config_cmd_fixed_param *cmd; 5626 int32_t len = sizeof(*cmd); 5627 wmi_buf_t buf; 5628 uint8_t *buf_ptr; 5629 int ret; 5630 5631 /* 5632 * TLV place holder for array of structures nlo_configured_parameters 5633 * TLV place holder for array of uint32_t channel_list 5634 * TLV place holder for chnl prediction cfg 5635 */ 5636 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5637 buf = wmi_buf_alloc(wmi_handle, len); 5638 if (!buf) 5639 return QDF_STATUS_E_NOMEM; 5640 5641 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5642 buf_ptr = (uint8_t *) cmd; 5643 5644 WMITLV_SET_HDR(&cmd->tlv_header, 5645 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5646 WMITLV_GET_STRUCT_TLVLEN 5647 (wmi_nlo_config_cmd_fixed_param)); 5648 5649 cmd->vdev_id = vdev_id; 5650 cmd->flags = WMI_NLO_CONFIG_STOP; 5651 buf_ptr += sizeof(*cmd); 5652 5653 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5654 buf_ptr += WMI_TLV_HDR_SIZE; 5655 5656 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5657 buf_ptr += WMI_TLV_HDR_SIZE; 5658 5659 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5660 buf_ptr += WMI_TLV_HDR_SIZE; 5661 5662 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5663 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5664 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5665 if (ret) { 5666 wmi_err("Failed to send nlo wmi cmd"); 5667 wmi_buf_free(buf); 5668 return QDF_STATUS_E_FAILURE; 5669 } 5670 5671 return QDF_STATUS_SUCCESS; 5672 } 5673 5674 /** 5675 * send_obss_disable_cmd_tlv() - disable obss scan request 5676 * @wmi_handle: wmi handle 5677 * @vdev_id: vdev id 5678 * 5679 * This function request FW to disable ongoing obss scan operation. 5680 * 5681 * Return: QDF status 5682 */ 5683 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5684 uint8_t vdev_id) 5685 { 5686 QDF_STATUS status; 5687 wmi_buf_t buf; 5688 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5689 int len = sizeof(*cmd); 5690 5691 buf = wmi_buf_alloc(wmi_handle, len); 5692 if (!buf) 5693 return QDF_STATUS_E_NOMEM; 5694 5695 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5696 5697 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5698 WMITLV_SET_HDR(&cmd->tlv_header, 5699 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5700 WMITLV_GET_STRUCT_TLVLEN( 5701 wmi_obss_scan_disable_cmd_fixed_param)); 5702 5703 cmd->vdev_id = vdev_id; 5704 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5705 WMI_OBSS_SCAN_DISABLE_CMDID); 5706 if (QDF_IS_STATUS_ERROR(status)) 5707 wmi_buf_free(buf); 5708 5709 return status; 5710 } 5711 5712 /** 5713 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5714 * @buf_ptr: Buffer passed by upper layers 5715 * @pno: Buffer to be sent to the firmware 5716 * 5717 * Copy the PNO Channel prediction configuration parameters 5718 * passed by the upper layers to a WMI format TLV and send it 5719 * down to the firmware. 5720 * 5721 * Return: None 5722 */ 5723 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5724 struct pno_scan_req_params *pno) 5725 { 5726 nlo_channel_prediction_cfg *channel_prediction_cfg = 5727 (nlo_channel_prediction_cfg *) buf_ptr; 5728 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5729 WMITLV_TAG_ARRAY_BYTE, 5730 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5731 #ifdef FEATURE_WLAN_SCAN_PNO 5732 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5733 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5734 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5735 channel_prediction_cfg->full_scan_period_ms = 5736 pno->channel_prediction_full_scan; 5737 #endif 5738 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5739 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5740 channel_prediction_cfg->enable, 5741 channel_prediction_cfg->top_k_num, 5742 channel_prediction_cfg->stationary_threshold, 5743 channel_prediction_cfg->full_scan_period_ms); 5744 } 5745 5746 /** 5747 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5748 * @wmi_handle: wmi handle 5749 * @buf_ptr: Buffer passed by upper layers 5750 * @buf_len: Length of passed buffer by upper layer 5751 * 5752 * Copy the buffer passed by the upper layers and send it 5753 * down to the firmware. 5754 * 5755 * Return: None 5756 */ 5757 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5758 void *buf_ptr, uint32_t buf_len) 5759 { 5760 wmi_buf_t buf = NULL; 5761 QDF_STATUS status; 5762 int len; 5763 uint8_t *data_ptr; 5764 5765 len = buf_len; 5766 buf = wmi_buf_alloc(wmi_handle, len); 5767 if (!buf) 5768 return QDF_STATUS_E_NOMEM; 5769 5770 data_ptr = (uint8_t *)wmi_buf_data(buf); 5771 qdf_mem_copy(data_ptr, buf_ptr, len); 5772 5773 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5774 status = wmi_unified_cmd_send(wmi_handle, buf, 5775 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5776 5777 if (QDF_IS_STATUS_ERROR(status)) { 5778 wmi_buf_free(buf); 5779 return QDF_STATUS_E_FAILURE; 5780 } 5781 return QDF_STATUS_SUCCESS; 5782 } 5783 5784 /** 5785 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 5786 * @wmi_handle: wmi handle 5787 * @buf_ptr: Buffer passed by upper layers 5788 * @buf_len: Length of passed buffer by upper layer 5789 * 5790 * Copy the buffer passed by the upper layers and send it 5791 * down to the firmware. 5792 * 5793 * Return: None 5794 */ 5795 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 5796 void *buf_ptr, uint32_t buf_len) 5797 { 5798 wmi_buf_t buf = NULL; 5799 QDF_STATUS status; 5800 int len; 5801 uint8_t *data_ptr; 5802 5803 len = buf_len; 5804 buf = wmi_buf_alloc(wmi_handle, len); 5805 if (!buf) 5806 return QDF_STATUS_E_NOMEM; 5807 5808 data_ptr = (uint8_t *)wmi_buf_data(buf); 5809 qdf_mem_copy(data_ptr, buf_ptr, len); 5810 5811 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5812 status = wmi_unified_cmd_send(wmi_handle, buf, 5813 len, 5814 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 5815 5816 if (QDF_IS_STATUS_ERROR(status)) { 5817 wmi_buf_free(buf); 5818 return QDF_STATUS_E_FAILURE; 5819 } 5820 return QDF_STATUS_SUCCESS; 5821 } 5822 5823 /** 5824 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5825 * @wmi_handle: wmi handle 5826 * @evt_buf: event buffer 5827 * @more_flag: buffer to populate more flag 5828 * 5829 * Return: status of operation 5830 */ 5831 static QDF_STATUS 5832 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5833 uint32_t *more_flag) 5834 { 5835 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5836 wmi_ctrl_path_stats_event_fixed_param *ev; 5837 5838 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5839 if (!param_buf) { 5840 wmi_err_rl("param_buf is NULL"); 5841 return QDF_STATUS_E_FAILURE; 5842 } 5843 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5844 5845 *more_flag = ev->more; 5846 return QDF_STATUS_SUCCESS; 5847 } 5848 5849 /** 5850 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 5851 * from event data 5852 * @wmi_handle: wmi handle 5853 * @evt_buf: event buffer 5854 * @end_of_event_flag: buffer to populate end_of_event flag 5855 * 5856 * Return: status of operation 5857 */ 5858 static QDF_STATUS 5859 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi, void *evt_buf, 5860 uint32_t *end_of_event_flag) 5861 { 5862 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5863 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5864 5865 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5866 if (!param_buf) { 5867 wmi_err_rl("param_buf is NULL"); 5868 return QDF_STATUS_E_FAILURE; 5869 } 5870 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5871 param_buf->fixed_param; 5872 5873 *end_of_event_flag = ev->end_of_event; 5874 return QDF_STATUS_SUCCESS; 5875 } 5876 5877 /** 5878 * extract_halphy_stats_event_count - api to extract event count flag from 5879 * event data 5880 * @wmi_handle: wmi handle 5881 * @evt_buf: event buffer 5882 * @event_count_flag: buffer to populate event_count flag 5883 * 5884 * Return: status of operation 5885 */ 5886 static QDF_STATUS 5887 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi, void *evt_buf, 5888 uint32_t *event_count_flag) 5889 { 5890 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5891 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5892 5893 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5894 if (!param_buf) { 5895 wmi_err_rl("param_buf is NULL"); 5896 return QDF_STATUS_E_FAILURE; 5897 } 5898 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5899 param_buf->fixed_param; 5900 5901 *event_count_flag = ev->event_count; 5902 return QDF_STATUS_SUCCESS; 5903 } 5904 5905 /** 5906 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 5907 * @wmi_handle: wmi handle 5908 * @params: configuration parameters 5909 * 5910 * Return: QDF_STATUS 5911 */ 5912 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 5913 struct nlo_mawc_params *params) 5914 { 5915 wmi_buf_t buf = NULL; 5916 QDF_STATUS status; 5917 int len; 5918 uint8_t *buf_ptr; 5919 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 5920 5921 len = sizeof(*wmi_nlo_mawc_params); 5922 buf = wmi_buf_alloc(wmi_handle, len); 5923 if (!buf) 5924 return QDF_STATUS_E_NOMEM; 5925 5926 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5927 wmi_nlo_mawc_params = 5928 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 5929 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 5930 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 5931 WMITLV_GET_STRUCT_TLVLEN 5932 (wmi_nlo_configure_mawc_cmd_fixed_param)); 5933 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 5934 if (params->enable) 5935 wmi_nlo_mawc_params->enable = 1; 5936 else 5937 wmi_nlo_mawc_params->enable = 0; 5938 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 5939 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 5940 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 5941 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 5942 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 5943 wmi_nlo_mawc_params->exp_backoff_ratio, 5944 wmi_nlo_mawc_params->init_scan_interval, 5945 wmi_nlo_mawc_params->max_scan_interval); 5946 5947 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 5948 status = wmi_unified_cmd_send(wmi_handle, buf, 5949 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 5950 if (QDF_IS_STATUS_ERROR(status)) { 5951 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 5952 status); 5953 wmi_buf_free(buf); 5954 return QDF_STATUS_E_FAILURE; 5955 } 5956 5957 return QDF_STATUS_SUCCESS; 5958 } 5959 5960 /** 5961 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 5962 * scan 5963 * @scan_freq_list: frequency list for pno scan 5964 * 5965 * Return: void 5966 */ 5967 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 5968 { 5969 uint32_t i; 5970 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 5971 uint32_t len = 0; 5972 struct chan_info *chan_info; 5973 int ret; 5974 5975 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 5976 for (i = 0; i < scan_freq_list->num_chan; i++) { 5977 chan_info = &scan_freq_list->chan[i]; 5978 ret = qdf_scnprintf(info + len, sizeof(info) - len, 5979 " %d[%d]", chan_info->freq, 5980 chan_info->flags); 5981 if (ret <= 0) 5982 break; 5983 len += ret; 5984 if (len >= (sizeof(info) - 20)) { 5985 wmi_nofl_debug("Freq[flag]:%s", 5986 info); 5987 len = 0; 5988 } 5989 } 5990 if (len) 5991 wmi_nofl_debug("Freq[flag]:%s", info); 5992 } 5993 5994 /** 5995 * send_pno_start_cmd_tlv() - PNO start request 5996 * @wmi_handle: wmi handle 5997 * @pno: PNO request 5998 * 5999 * This function request FW to start PNO request. 6000 * Request: CDF status 6001 */ 6002 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6003 struct pno_scan_req_params *pno) 6004 { 6005 wmi_nlo_config_cmd_fixed_param *cmd; 6006 nlo_configured_parameters *nlo_list; 6007 uint32_t *channel_list; 6008 int32_t len; 6009 qdf_freq_t freq; 6010 wmi_buf_t buf; 6011 uint8_t *buf_ptr; 6012 uint8_t i; 6013 int ret; 6014 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6015 connected_nlo_rssi_params *nlo_relative_rssi; 6016 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6017 6018 /* 6019 * TLV place holder for array nlo_configured_parameters(nlo_list) 6020 * TLV place holder for array of uint32_t channel_list 6021 * TLV place holder for chnnl prediction cfg 6022 * TLV place holder for array of wmi_vendor_oui 6023 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6024 */ 6025 len = sizeof(*cmd) + 6026 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6027 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6028 6029 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6030 len += sizeof(nlo_configured_parameters) * 6031 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6032 len += sizeof(nlo_channel_prediction_cfg); 6033 len += sizeof(enlo_candidate_score_params); 6034 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6035 len += sizeof(connected_nlo_rssi_params); 6036 len += sizeof(connected_nlo_bss_band_rssi_pref); 6037 6038 buf = wmi_buf_alloc(wmi_handle, len); 6039 if (!buf) 6040 return QDF_STATUS_E_NOMEM; 6041 6042 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6043 6044 buf_ptr = (uint8_t *) cmd; 6045 WMITLV_SET_HDR(&cmd->tlv_header, 6046 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6047 WMITLV_GET_STRUCT_TLVLEN 6048 (wmi_nlo_config_cmd_fixed_param)); 6049 cmd->vdev_id = pno->vdev_id; 6050 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6051 6052 #ifdef FEATURE_WLAN_SCAN_PNO 6053 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6054 pno->adaptive_dwell_mode); 6055 #endif 6056 /* Current FW does not support min-max range for dwell time */ 6057 cmd->active_dwell_time = pno->active_dwell_time; 6058 cmd->passive_dwell_time = pno->passive_dwell_time; 6059 6060 if (pno->do_passive_scan) 6061 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6062 /* Copy scan interval */ 6063 cmd->fast_scan_period = pno->fast_scan_period; 6064 cmd->slow_scan_period = pno->slow_scan_period; 6065 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6066 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6067 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6068 6069 /* mac randomization attributes */ 6070 if (pno->scan_random.randomize) { 6071 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6072 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6073 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6074 pno->scan_random.mac_mask, 6075 &cmd->mac_addr, 6076 &cmd->mac_mask); 6077 } 6078 6079 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6080 6081 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6082 6083 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6084 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6085 buf_ptr += WMI_TLV_HDR_SIZE; 6086 6087 nlo_list = (nlo_configured_parameters *) buf_ptr; 6088 for (i = 0; i < cmd->no_of_ssids; i++) { 6089 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6090 WMITLV_TAG_ARRAY_BYTE, 6091 WMITLV_GET_STRUCT_TLVLEN 6092 (nlo_configured_parameters)); 6093 /* Copy ssid and it's length */ 6094 nlo_list[i].ssid.valid = true; 6095 nlo_list[i].ssid.ssid.ssid_len = 6096 pno->networks_list[i].ssid.length; 6097 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6098 pno->networks_list[i].ssid.ssid, 6099 nlo_list[i].ssid.ssid.ssid_len); 6100 6101 /* Copy rssi threshold */ 6102 if (pno->networks_list[i].rssi_thresh && 6103 pno->networks_list[i].rssi_thresh > 6104 WMI_RSSI_THOLD_DEFAULT) { 6105 nlo_list[i].rssi_cond.valid = true; 6106 nlo_list[i].rssi_cond.rssi = 6107 pno->networks_list[i].rssi_thresh; 6108 } 6109 nlo_list[i].bcast_nw_type.valid = true; 6110 nlo_list[i].bcast_nw_type.bcast_nw_type = 6111 pno->networks_list[i].bc_new_type; 6112 } 6113 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6114 6115 /* Copy channel info */ 6116 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6117 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6118 (cmd->num_of_channels * sizeof(uint32_t))); 6119 buf_ptr += WMI_TLV_HDR_SIZE; 6120 6121 channel_list = (uint32_t *) buf_ptr; 6122 for (i = 0; i < cmd->num_of_channels; i++) { 6123 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6124 pno->networks_list[0].pno_chan_list.chan[i].freq); 6125 6126 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6127 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6128 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6129 wlan_chan_to_freq(freq)); 6130 } 6131 6132 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6133 pno->networks_list[0].pno_chan_list.chan[i].flags); 6134 } 6135 6136 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6137 6138 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6139 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6140 sizeof(nlo_channel_prediction_cfg)); 6141 buf_ptr += WMI_TLV_HDR_SIZE; 6142 wmi_set_pno_channel_prediction(buf_ptr, pno); 6143 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6144 /** TODO: Discrete firmware doesn't have command/option to configure 6145 * App IE which comes from wpa_supplicant as of part PNO start request. 6146 */ 6147 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6148 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6149 buf_ptr += sizeof(enlo_candidate_score_params); 6150 6151 if (ie_allowlist->allow_list) { 6152 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6153 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6154 &cmd->num_vendor_oui, 6155 ie_allowlist); 6156 } 6157 6158 /* ie allow list */ 6159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6160 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6161 buf_ptr += WMI_TLV_HDR_SIZE; 6162 if (cmd->num_vendor_oui != 0) { 6163 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6164 ie_allowlist->voui); 6165 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6166 } 6167 6168 if (pno->relative_rssi_set) 6169 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6170 6171 /* 6172 * Firmware calculation using connected PNO params: 6173 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6174 * deduction of rssi_pref for chosen band_pref and 6175 * addition of rssi_pref for remaining bands (other than chosen band). 6176 */ 6177 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6178 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6179 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6180 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6181 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6182 buf_ptr += sizeof(*nlo_relative_rssi); 6183 6184 /* 6185 * As of now Kernel and Host supports one band and rssi preference. 6186 * Firmware supports array of band and rssi preferences 6187 */ 6188 cmd->num_cnlo_band_pref = 1; 6189 WMITLV_SET_HDR(buf_ptr, 6190 WMITLV_TAG_ARRAY_STRUC, 6191 cmd->num_cnlo_band_pref * 6192 sizeof(connected_nlo_bss_band_rssi_pref)); 6193 buf_ptr += WMI_TLV_HDR_SIZE; 6194 6195 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6196 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6197 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6198 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6199 WMITLV_GET_STRUCT_TLVLEN( 6200 connected_nlo_bss_band_rssi_pref)); 6201 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6202 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6203 } 6204 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6205 6206 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6207 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6208 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6209 if (ret) { 6210 wmi_err("Failed to send nlo wmi cmd"); 6211 wmi_buf_free(buf); 6212 return QDF_STATUS_E_FAILURE; 6213 } 6214 6215 return QDF_STATUS_SUCCESS; 6216 } 6217 6218 /** 6219 * is_service_enabled_tlv() - Check if service enabled 6220 * @param wmi_handle: wmi handle 6221 * @param service_id: service identifier 6222 * 6223 * Return: 1 enabled, 0 disabled 6224 */ 6225 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6226 uint32_t service_id) 6227 { 6228 struct wmi_soc *soc = wmi_handle->soc; 6229 6230 if (!soc->wmi_service_bitmap) { 6231 wmi_err("WMI service bit map is not saved yet"); 6232 return false; 6233 } 6234 6235 /* if wmi_service_enabled was received with extended2 bitmap, 6236 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6237 */ 6238 if (soc->wmi_ext2_service_bitmap) { 6239 if (!soc->wmi_ext_service_bitmap) { 6240 wmi_err("WMI service ext bit map is not saved yet"); 6241 return false; 6242 } 6243 6244 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6245 soc->wmi_ext_service_bitmap, 6246 soc->wmi_ext2_service_bitmap, 6247 service_id); 6248 } 6249 6250 if (service_id >= WMI_MAX_EXT_SERVICE) { 6251 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6252 service_id); 6253 return false; 6254 } 6255 /* if wmi_service_enabled was received with extended bitmap, 6256 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6257 */ 6258 if (soc->wmi_ext_service_bitmap) 6259 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6260 soc->wmi_ext_service_bitmap, 6261 service_id); 6262 6263 if (service_id >= WMI_MAX_SERVICE) { 6264 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6265 service_id); 6266 return false; 6267 } 6268 6269 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6270 service_id); 6271 } 6272 6273 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6274 /** 6275 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6276 * @wmi_handle: wmi handle 6277 * @clear_req: ll stats clear request command params 6278 * 6279 * Return: QDF_STATUS_SUCCESS for success or error code 6280 */ 6281 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6282 const struct ll_stats_clear_params *clear_req) 6283 { 6284 wmi_clear_link_stats_cmd_fixed_param *cmd; 6285 int32_t len; 6286 wmi_buf_t buf; 6287 uint8_t *buf_ptr; 6288 int ret; 6289 6290 len = sizeof(*cmd); 6291 buf = wmi_buf_alloc(wmi_handle, len); 6292 6293 if (!buf) 6294 return QDF_STATUS_E_NOMEM; 6295 6296 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6297 qdf_mem_zero(buf_ptr, len); 6298 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6299 6300 WMITLV_SET_HDR(&cmd->tlv_header, 6301 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6302 WMITLV_GET_STRUCT_TLVLEN 6303 (wmi_clear_link_stats_cmd_fixed_param)); 6304 6305 cmd->stop_stats_collection_req = clear_req->stop_req; 6306 cmd->vdev_id = clear_req->vdev_id; 6307 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6308 6309 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6310 &cmd->peer_macaddr); 6311 6312 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6313 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6314 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6315 cmd->stop_stats_collection_req, 6316 cmd->vdev_id, cmd->stats_clear_req_mask, 6317 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6318 6319 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6320 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6321 WMI_CLEAR_LINK_STATS_CMDID); 6322 if (ret) { 6323 wmi_err("Failed to send clear link stats req"); 6324 wmi_buf_free(buf); 6325 return QDF_STATUS_E_FAILURE; 6326 } 6327 6328 wmi_debug("Clear Link Layer Stats request sent successfully"); 6329 return QDF_STATUS_SUCCESS; 6330 } 6331 6332 /** 6333 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6334 * @wmi_handle: wmi handle 6335 * @set_req: ll stats set request command params 6336 * 6337 * Return: QDF_STATUS_SUCCESS for success or error code 6338 */ 6339 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6340 const struct ll_stats_set_params *set_req) 6341 { 6342 wmi_start_link_stats_cmd_fixed_param *cmd; 6343 int32_t len; 6344 wmi_buf_t buf; 6345 uint8_t *buf_ptr; 6346 int ret; 6347 6348 len = sizeof(*cmd); 6349 buf = wmi_buf_alloc(wmi_handle, len); 6350 6351 if (!buf) 6352 return QDF_STATUS_E_NOMEM; 6353 6354 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6355 qdf_mem_zero(buf_ptr, len); 6356 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6357 6358 WMITLV_SET_HDR(&cmd->tlv_header, 6359 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6360 WMITLV_GET_STRUCT_TLVLEN 6361 (wmi_start_link_stats_cmd_fixed_param)); 6362 6363 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6364 cmd->aggressive_statistics_gathering = 6365 set_req->aggressive_statistics_gathering; 6366 6367 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6368 cmd->mpdu_size_threshold, 6369 cmd->aggressive_statistics_gathering); 6370 6371 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6372 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6373 WMI_START_LINK_STATS_CMDID); 6374 if (ret) { 6375 wmi_err("Failed to send set link stats request"); 6376 wmi_buf_free(buf); 6377 return QDF_STATUS_E_FAILURE; 6378 } 6379 6380 return QDF_STATUS_SUCCESS; 6381 } 6382 6383 /** 6384 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6385 * @wmi_handle: wmi handle 6386 * @get_req: ll stats get request command params 6387 * 6388 * Return: QDF_STATUS_SUCCESS for success or error code 6389 */ 6390 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6391 const struct ll_stats_get_params *get_req) 6392 { 6393 wmi_request_link_stats_cmd_fixed_param *cmd; 6394 int32_t len; 6395 wmi_buf_t buf; 6396 uint8_t *buf_ptr; 6397 int ret; 6398 6399 len = sizeof(*cmd); 6400 buf = wmi_buf_alloc(wmi_handle, len); 6401 6402 if (!buf) 6403 return QDF_STATUS_E_NOMEM; 6404 6405 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6406 qdf_mem_zero(buf_ptr, len); 6407 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6408 6409 WMITLV_SET_HDR(&cmd->tlv_header, 6410 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6411 WMITLV_GET_STRUCT_TLVLEN 6412 (wmi_request_link_stats_cmd_fixed_param)); 6413 6414 cmd->request_id = get_req->req_id; 6415 cmd->stats_type = get_req->param_id_mask; 6416 cmd->vdev_id = get_req->vdev_id; 6417 6418 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6419 &cmd->peer_macaddr); 6420 6421 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6422 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6423 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6424 6425 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6426 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6427 WMI_REQUEST_LINK_STATS_CMDID, true); 6428 if (ret) { 6429 wmi_buf_free(buf); 6430 return QDF_STATUS_E_FAILURE; 6431 } 6432 6433 return QDF_STATUS_SUCCESS; 6434 } 6435 6436 #ifdef WLAN_FEATURE_11BE_MLO 6437 static int 6438 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6439 { 6440 int32_t len = 0; 6441 6442 /* In case of MLO connection, update the length of the buffer. 6443 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6444 * hence just update the TLV header, but allocate no memory for it. 6445 */ 6446 if (!get_req->is_mlo_req) 6447 return len; 6448 6449 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6450 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6451 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6452 6453 return len; 6454 } 6455 6456 static void 6457 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6458 void *buf_ptr) 6459 { 6460 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6461 uint32_t *vdev_id_bitmap; 6462 wmi_mac_addr *mld_mac; 6463 6464 /* In case of MLO connection, update the TLV Headers */ 6465 if (!get_req->is_mlo_req) 6466 return; 6467 6468 buf_ptr += sizeof(*unified_cmd); 6469 6470 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6471 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6472 buf_ptr += WMI_TLV_HDR_SIZE; 6473 6474 /* Adding vdev_bitmap_id array TLV */ 6475 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6476 sizeof(*vdev_id_bitmap)); 6477 buf_ptr += WMI_TLV_HDR_SIZE; 6478 vdev_id_bitmap = buf_ptr; 6479 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6480 buf_ptr += sizeof(*vdev_id_bitmap); 6481 6482 /* Adding mld_macaddr array TLV */ 6483 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6484 sizeof(*mld_mac)); 6485 buf_ptr += WMI_TLV_HDR_SIZE; 6486 mld_mac = buf_ptr; 6487 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6488 6489 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6490 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6491 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6492 } 6493 #else 6494 static inline int 6495 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6496 { 6497 return 0; 6498 } 6499 6500 static inline void 6501 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6502 void *buf_ptr) 6503 { 6504 } 6505 #endif 6506 6507 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6508 /** 6509 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6510 * station request 6511 * @wmi_handle: wmi handle 6512 * @get_req: ll stats get request command params 6513 * 6514 * Return: QDF_STATUS_SUCCESS for success or error code 6515 */ 6516 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6517 wmi_unified_t wmi_handle, 6518 const struct ll_stats_get_params *get_req) 6519 { 6520 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6521 int32_t len; 6522 wmi_buf_t buf; 6523 void *buf_ptr; 6524 QDF_STATUS ret; 6525 bool is_ll_get_sta_stats_over_qmi; 6526 6527 len = sizeof(*unified_cmd); 6528 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6529 6530 buf = wmi_buf_alloc(wmi_handle, len); 6531 if (!buf) 6532 return QDF_STATUS_E_NOMEM; 6533 6534 buf_ptr = wmi_buf_data(buf); 6535 6536 unified_cmd = buf_ptr; 6537 WMITLV_SET_HDR( 6538 &unified_cmd->tlv_header, 6539 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6540 WMITLV_GET_STRUCT_TLVLEN 6541 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6542 6543 unified_cmd->link_stats_type = get_req->param_id_mask; 6544 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6545 WMI_REQUEST_PEER_STAT | 6546 WMI_REQUEST_VDEV_STAT | 6547 WMI_REQUEST_PDEV_STAT | 6548 WMI_REQUEST_PEER_EXTD2_STAT | 6549 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6550 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6551 wmi_handle, 6552 WMI_HOST_PDEV_ID_SOC); 6553 6554 unified_cmd->vdev_id = get_req->vdev_id; 6555 unified_cmd->request_id = get_req->req_id; 6556 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6557 &unified_cmd->peer_macaddr); 6558 6559 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6560 QDF_MAC_ADDR_FMT, 6561 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6562 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6563 6564 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6565 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6566 6567 /** 6568 * FW support for LL_get_sta command. True represents the unified 6569 * ll_get_sta command should be sent over QMI always irrespective of 6570 * WOW state. 6571 */ 6572 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6573 wmi_handle, 6574 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6575 6576 if (is_ll_get_sta_stats_over_qmi) { 6577 ret = wmi_unified_cmd_send_over_qmi( 6578 wmi_handle, buf, len, 6579 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6580 } else { 6581 ret = wmi_unified_cmd_send_pm_chk( 6582 wmi_handle, buf, len, 6583 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6584 true); 6585 } 6586 6587 if (QDF_IS_STATUS_ERROR(ret)) { 6588 wmi_buf_free(buf); 6589 return QDF_STATUS_E_FAILURE; 6590 } 6591 6592 return ret; 6593 } 6594 #endif 6595 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6596 6597 /** 6598 * send_congestion_cmd_tlv() - send request to fw to get CCA 6599 * @wmi_handle: wmi handle 6600 * @vdev_id: vdev id 6601 * 6602 * Return: CDF status 6603 */ 6604 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6605 uint8_t vdev_id) 6606 { 6607 wmi_buf_t buf; 6608 wmi_request_stats_cmd_fixed_param *cmd; 6609 uint8_t len; 6610 uint8_t *buf_ptr; 6611 6612 len = sizeof(*cmd); 6613 buf = wmi_buf_alloc(wmi_handle, len); 6614 if (!buf) 6615 return QDF_STATUS_E_FAILURE; 6616 6617 buf_ptr = wmi_buf_data(buf); 6618 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6619 WMITLV_SET_HDR(&cmd->tlv_header, 6620 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6621 WMITLV_GET_STRUCT_TLVLEN 6622 (wmi_request_stats_cmd_fixed_param)); 6623 6624 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6625 cmd->vdev_id = vdev_id; 6626 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6627 cmd->vdev_id, cmd->stats_id); 6628 6629 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6630 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6631 WMI_REQUEST_STATS_CMDID)) { 6632 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6633 wmi_buf_free(buf); 6634 return QDF_STATUS_E_FAILURE; 6635 } 6636 6637 return QDF_STATUS_SUCCESS; 6638 } 6639 6640 /** 6641 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6642 * @wmi_handle: wmi handle 6643 * @rssi_req: get RSSI request 6644 * 6645 * Return: CDF status 6646 */ 6647 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6648 { 6649 wmi_buf_t buf; 6650 wmi_request_stats_cmd_fixed_param *cmd; 6651 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6652 6653 buf = wmi_buf_alloc(wmi_handle, len); 6654 if (!buf) 6655 return QDF_STATUS_E_FAILURE; 6656 6657 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6658 WMITLV_SET_HDR(&cmd->tlv_header, 6659 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6660 WMITLV_GET_STRUCT_TLVLEN 6661 (wmi_request_stats_cmd_fixed_param)); 6662 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6663 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6664 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6665 WMI_REQUEST_STATS_CMDID)) { 6666 wmi_err("Failed to send host stats request to fw"); 6667 wmi_buf_free(buf); 6668 return QDF_STATUS_E_FAILURE; 6669 } 6670 6671 return QDF_STATUS_SUCCESS; 6672 } 6673 6674 /** 6675 * send_snr_cmd_tlv() - get RSSI from fw 6676 * @wmi_handle: wmi handle 6677 * @vdev_id: vdev id 6678 * 6679 * Return: CDF status 6680 */ 6681 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6682 { 6683 wmi_buf_t buf; 6684 wmi_request_stats_cmd_fixed_param *cmd; 6685 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6686 6687 buf = wmi_buf_alloc(wmi_handle, len); 6688 if (!buf) 6689 return QDF_STATUS_E_FAILURE; 6690 6691 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6692 cmd->vdev_id = vdev_id; 6693 6694 WMITLV_SET_HDR(&cmd->tlv_header, 6695 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6696 WMITLV_GET_STRUCT_TLVLEN 6697 (wmi_request_stats_cmd_fixed_param)); 6698 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6699 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6700 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6701 WMI_REQUEST_STATS_CMDID)) { 6702 wmi_err("Failed to send host stats request to fw"); 6703 wmi_buf_free(buf); 6704 return QDF_STATUS_E_FAILURE; 6705 } 6706 6707 return QDF_STATUS_SUCCESS; 6708 } 6709 6710 /** 6711 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6712 * @wmi_handle: wmi handle 6713 * @link_status: get link params 6714 * 6715 * Return: CDF status 6716 */ 6717 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6718 struct link_status_params *link_status) 6719 { 6720 wmi_buf_t buf; 6721 wmi_request_stats_cmd_fixed_param *cmd; 6722 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6723 6724 buf = wmi_buf_alloc(wmi_handle, len); 6725 if (!buf) 6726 return QDF_STATUS_E_FAILURE; 6727 6728 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6729 WMITLV_SET_HDR(&cmd->tlv_header, 6730 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6731 WMITLV_GET_STRUCT_TLVLEN 6732 (wmi_request_stats_cmd_fixed_param)); 6733 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6734 cmd->vdev_id = link_status->vdev_id; 6735 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6736 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6737 WMI_REQUEST_STATS_CMDID)) { 6738 wmi_err("Failed to send WMI link status request to fw"); 6739 wmi_buf_free(buf); 6740 return QDF_STATUS_E_FAILURE; 6741 } 6742 6743 return QDF_STATUS_SUCCESS; 6744 } 6745 6746 #ifdef WLAN_SUPPORT_GREEN_AP 6747 /** 6748 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6749 * @wmi_handle: wmi handler 6750 * @egap_params: pointer to egap_params 6751 * 6752 * Return: 0 for success, otherwise appropriate error code 6753 */ 6754 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 6755 struct wlan_green_ap_egap_params *egap_params) 6756 { 6757 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 6758 wmi_buf_t buf; 6759 int32_t err; 6760 6761 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6762 if (!buf) 6763 return QDF_STATUS_E_NOMEM; 6764 6765 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 6766 WMITLV_SET_HDR(&cmd->tlv_header, 6767 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 6768 WMITLV_GET_STRUCT_TLVLEN( 6769 wmi_ap_ps_egap_param_cmd_fixed_param)); 6770 6771 cmd->enable = egap_params->host_enable_egap; 6772 cmd->inactivity_time = egap_params->egap_inactivity_time; 6773 cmd->wait_time = egap_params->egap_wait_time; 6774 cmd->flags = egap_params->egap_feature_flags; 6775 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 6776 err = wmi_unified_cmd_send(wmi_handle, buf, 6777 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 6778 if (err) { 6779 wmi_err("Failed to send ap_ps_egap cmd"); 6780 wmi_buf_free(buf); 6781 return QDF_STATUS_E_FAILURE; 6782 } 6783 6784 return QDF_STATUS_SUCCESS; 6785 } 6786 #endif 6787 6788 /** 6789 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 6790 * @wmi_handle: wmi handle 6791 * @vdev_id: vdev id 6792 * 6793 * Return: QDF_STATUS_SUCCESS for success or error code 6794 */ 6795 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 6796 uint8_t vdev_id) 6797 { 6798 wmi_csa_offload_enable_cmd_fixed_param *cmd; 6799 wmi_buf_t buf; 6800 int32_t len = sizeof(*cmd); 6801 6802 wmi_debug("vdev_id %d", vdev_id); 6803 buf = wmi_buf_alloc(wmi_handle, len); 6804 if (!buf) 6805 return QDF_STATUS_E_NOMEM; 6806 6807 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 6808 WMITLV_SET_HDR(&cmd->tlv_header, 6809 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 6810 WMITLV_GET_STRUCT_TLVLEN 6811 (wmi_csa_offload_enable_cmd_fixed_param)); 6812 cmd->vdev_id = vdev_id; 6813 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 6814 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 6815 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6816 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 6817 wmi_err("Failed to send CSA offload enable command"); 6818 wmi_buf_free(buf); 6819 return QDF_STATUS_E_FAILURE; 6820 } 6821 6822 return 0; 6823 } 6824 6825 #ifdef WLAN_FEATURE_CIF_CFR 6826 /** 6827 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 6828 * @wmi_handle: wmi handle 6829 * @data_len: len of dma cfg req 6830 * @data: dma cfg req 6831 * 6832 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 6833 */ 6834 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 6835 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 6836 { 6837 wmi_buf_t buf; 6838 uint8_t *cmd; 6839 QDF_STATUS ret; 6840 6841 WMITLV_SET_HDR(cfg, 6842 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 6843 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 6844 6845 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 6846 if (!buf) 6847 return QDF_STATUS_E_FAILURE; 6848 6849 cmd = (uint8_t *) wmi_buf_data(buf); 6850 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 6851 wmi_debug("Sending OEM Data Request to target, data len %lu", 6852 sizeof(*cfg)); 6853 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 6854 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6855 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6856 if (QDF_IS_STATUS_ERROR(ret)) { 6857 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6858 wmi_buf_free(buf); 6859 } 6860 6861 return ret; 6862 } 6863 #endif 6864 6865 /** 6866 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6867 * @wmi_handle: wmi handle 6868 * @start_11d_scan: 11d scan start request parameters 6869 * 6870 * This function request FW to start 11d scan. 6871 * 6872 * Return: QDF status 6873 */ 6874 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6875 struct reg_start_11d_scan_req *start_11d_scan) 6876 { 6877 wmi_11d_scan_start_cmd_fixed_param *cmd; 6878 int32_t len; 6879 wmi_buf_t buf; 6880 int ret; 6881 6882 len = sizeof(*cmd); 6883 buf = wmi_buf_alloc(wmi_handle, len); 6884 if (!buf) 6885 return QDF_STATUS_E_NOMEM; 6886 6887 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6888 6889 WMITLV_SET_HDR(&cmd->tlv_header, 6890 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6891 WMITLV_GET_STRUCT_TLVLEN 6892 (wmi_11d_scan_start_cmd_fixed_param)); 6893 6894 cmd->vdev_id = start_11d_scan->vdev_id; 6895 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6896 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6897 6898 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6899 6900 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 6901 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6902 WMI_11D_SCAN_START_CMDID); 6903 if (ret) { 6904 wmi_err("Failed to send start 11d scan wmi cmd"); 6905 wmi_buf_free(buf); 6906 return QDF_STATUS_E_FAILURE; 6907 } 6908 6909 return QDF_STATUS_SUCCESS; 6910 } 6911 6912 /** 6913 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 6914 * @wmi_handle: wmi handle 6915 * @start_11d_scan: 11d scan stop request parameters 6916 * 6917 * This function request FW to stop 11d scan. 6918 * 6919 * Return: QDF status 6920 */ 6921 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6922 struct reg_stop_11d_scan_req *stop_11d_scan) 6923 { 6924 wmi_11d_scan_stop_cmd_fixed_param *cmd; 6925 int32_t len; 6926 wmi_buf_t buf; 6927 int ret; 6928 6929 len = sizeof(*cmd); 6930 buf = wmi_buf_alloc(wmi_handle, len); 6931 if (!buf) 6932 return QDF_STATUS_E_NOMEM; 6933 6934 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 6935 6936 WMITLV_SET_HDR(&cmd->tlv_header, 6937 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 6938 WMITLV_GET_STRUCT_TLVLEN 6939 (wmi_11d_scan_stop_cmd_fixed_param)); 6940 6941 cmd->vdev_id = stop_11d_scan->vdev_id; 6942 6943 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 6944 6945 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 6946 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6947 WMI_11D_SCAN_STOP_CMDID); 6948 if (ret) { 6949 wmi_err("Failed to send stop 11d scan wmi cmd"); 6950 wmi_buf_free(buf); 6951 return QDF_STATUS_E_FAILURE; 6952 } 6953 6954 return QDF_STATUS_SUCCESS; 6955 } 6956 6957 /** 6958 * send_start_oem_data_cmd_tlv() - start OEM data request to target 6959 * @wmi_handle: wmi handle 6960 * @data_len: the length of @data 6961 * @data: the pointer to data buf 6962 * 6963 * Return: CDF status 6964 */ 6965 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 6966 uint32_t data_len, 6967 uint8_t *data) 6968 { 6969 wmi_buf_t buf; 6970 uint8_t *cmd; 6971 QDF_STATUS ret; 6972 6973 buf = wmi_buf_alloc(wmi_handle, 6974 (data_len + WMI_TLV_HDR_SIZE)); 6975 if (!buf) 6976 return QDF_STATUS_E_FAILURE; 6977 6978 cmd = (uint8_t *) wmi_buf_data(buf); 6979 6980 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 6981 cmd += WMI_TLV_HDR_SIZE; 6982 qdf_mem_copy(cmd, data, 6983 data_len); 6984 6985 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 6986 6987 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 6988 ret = wmi_unified_cmd_send(wmi_handle, buf, 6989 (data_len + 6990 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 6991 6992 if (QDF_IS_STATUS_ERROR(ret)) { 6993 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 6994 wmi_buf_free(buf); 6995 } 6996 6997 return ret; 6998 } 6999 7000 #ifdef FEATURE_OEM_DATA 7001 /** 7002 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7003 * @wmi_handle: wmi handle 7004 * @oem_data: the pointer to oem data 7005 * 7006 * Return: QDF status 7007 */ 7008 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7009 struct oem_data *oem_data) 7010 { 7011 QDF_STATUS ret; 7012 wmi_oem_data_cmd_fixed_param *cmd; 7013 struct wmi_ops *ops; 7014 wmi_buf_t buf; 7015 uint16_t len = sizeof(*cmd); 7016 uint16_t oem_data_len_aligned; 7017 uint8_t *buf_ptr; 7018 uint32_t pdev_id; 7019 7020 if (!oem_data || !oem_data->data) { 7021 wmi_err_rl("oem data is not valid"); 7022 return QDF_STATUS_E_FAILURE; 7023 } 7024 7025 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7026 if (oem_data_len_aligned < oem_data->data_len) { 7027 wmi_err_rl("integer overflow while rounding up data_len"); 7028 return QDF_STATUS_E_FAILURE; 7029 } 7030 7031 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7032 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7033 return QDF_STATUS_E_FAILURE; 7034 } 7035 7036 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7037 buf = wmi_buf_alloc(wmi_handle, len); 7038 if (!buf) 7039 return QDF_STATUS_E_NOMEM; 7040 7041 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7042 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7043 WMITLV_SET_HDR(&cmd->tlv_header, 7044 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7045 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7046 7047 pdev_id = oem_data->pdev_id; 7048 if (oem_data->pdev_vdev_flag) { 7049 ops = wmi_handle->ops; 7050 if (oem_data->is_host_pdev_id) 7051 pdev_id = 7052 ops->convert_host_pdev_id_to_target(wmi_handle, 7053 pdev_id); 7054 else 7055 pdev_id = 7056 ops->convert_pdev_id_host_to_target(wmi_handle, 7057 pdev_id); 7058 } 7059 7060 cmd->vdev_id = oem_data->vdev_id; 7061 cmd->data_len = oem_data->data_len; 7062 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7063 cmd->pdev_id = pdev_id; 7064 7065 buf_ptr += sizeof(*cmd); 7066 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7067 buf_ptr += WMI_TLV_HDR_SIZE; 7068 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7069 7070 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7071 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7072 if (QDF_IS_STATUS_ERROR(ret)) { 7073 wmi_err_rl("Failed with ret = %d", ret); 7074 wmi_buf_free(buf); 7075 } 7076 7077 return ret; 7078 } 7079 #endif 7080 7081 /** 7082 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7083 * @wmi_handle: wmi handle 7084 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7085 * 7086 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7087 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7088 * to firmware based on phyerr filtering 7089 * offload status. 7090 * 7091 * Return: 1 success, 0 failure 7092 */ 7093 static QDF_STATUS 7094 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7095 bool dfs_phyerr_filter_offload) 7096 { 7097 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7098 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7099 wmi_buf_t buf; 7100 uint16_t len; 7101 QDF_STATUS ret; 7102 7103 7104 if (false == dfs_phyerr_filter_offload) { 7105 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7106 len = sizeof(*disable_phyerr_offload_cmd); 7107 buf = wmi_buf_alloc(wmi_handle, len); 7108 if (!buf) 7109 return 0; 7110 7111 disable_phyerr_offload_cmd = 7112 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7113 wmi_buf_data(buf); 7114 7115 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7116 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7117 WMITLV_GET_STRUCT_TLVLEN 7118 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7119 7120 /* 7121 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7122 * to the firmware to disable the phyerror 7123 * filtering offload. 7124 */ 7125 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7126 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7127 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7128 if (QDF_IS_STATUS_ERROR(ret)) { 7129 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7130 ret); 7131 wmi_buf_free(buf); 7132 return QDF_STATUS_E_FAILURE; 7133 } 7134 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7135 } else { 7136 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7137 7138 len = sizeof(*enable_phyerr_offload_cmd); 7139 buf = wmi_buf_alloc(wmi_handle, len); 7140 if (!buf) 7141 return QDF_STATUS_E_FAILURE; 7142 7143 enable_phyerr_offload_cmd = 7144 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7145 wmi_buf_data(buf); 7146 7147 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7148 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7149 WMITLV_GET_STRUCT_TLVLEN 7150 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7151 7152 /* 7153 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7154 * to the firmware to enable the phyerror 7155 * filtering offload. 7156 */ 7157 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7158 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7159 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7160 7161 if (QDF_IS_STATUS_ERROR(ret)) { 7162 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7163 wmi_buf_free(buf); 7164 return QDF_STATUS_E_FAILURE; 7165 } 7166 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7167 } 7168 7169 return QDF_STATUS_SUCCESS; 7170 } 7171 7172 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7173 /** 7174 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7175 * @wmi_handle: wmi handle 7176 * @pktlog_event: pktlog event 7177 * @cmd_id: pktlog cmd id 7178 * @user_triggered: user triggered input for PKTLOG enable mode 7179 * 7180 * Return: CDF status 7181 */ 7182 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7183 WMI_PKTLOG_EVENT pktlog_event, 7184 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7185 { 7186 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7187 WMI_CMD_ID CMD_ID; 7188 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7189 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7190 int len = 0; 7191 wmi_buf_t buf; 7192 int32_t idx, max_idx; 7193 7194 PKTLOG_EVENT = pktlog_event; 7195 CMD_ID = cmd_id; 7196 7197 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7198 switch (CMD_ID) { 7199 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7200 len = sizeof(*cmd); 7201 buf = wmi_buf_alloc(wmi_handle, len); 7202 if (!buf) 7203 return QDF_STATUS_E_NOMEM; 7204 7205 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7206 wmi_buf_data(buf); 7207 WMITLV_SET_HDR(&cmd->tlv_header, 7208 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7209 WMITLV_GET_STRUCT_TLVLEN 7210 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7211 cmd->evlist = 0; 7212 for (idx = 0; idx < max_idx; idx++) { 7213 if (PKTLOG_EVENT & (1 << idx)) 7214 cmd->evlist |= pktlog_event_tlv[idx]; 7215 } 7216 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7217 : WMI_PKTLOG_ENABLE_AUTO; 7218 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7219 wmi_handle, 7220 WMI_HOST_PDEV_ID_SOC); 7221 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7222 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7223 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7224 wmi_err("Failed to send pktlog enable cmdid"); 7225 goto wmi_send_failed; 7226 } 7227 break; 7228 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7229 len = sizeof(*disable_cmd); 7230 buf = wmi_buf_alloc(wmi_handle, len); 7231 if (!buf) 7232 return QDF_STATUS_E_NOMEM; 7233 7234 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7235 wmi_buf_data(buf); 7236 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7237 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7238 WMITLV_GET_STRUCT_TLVLEN 7239 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7240 disable_cmd->pdev_id = 7241 wmi_handle->ops->convert_pdev_id_host_to_target( 7242 wmi_handle, 7243 WMI_HOST_PDEV_ID_SOC); 7244 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7245 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7246 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7247 wmi_err("failed to send pktlog disable cmdid"); 7248 goto wmi_send_failed; 7249 } 7250 break; 7251 default: 7252 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7253 break; 7254 } 7255 7256 return QDF_STATUS_SUCCESS; 7257 7258 wmi_send_failed: 7259 wmi_buf_free(buf); 7260 return QDF_STATUS_E_FAILURE; 7261 } 7262 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7263 7264 /** 7265 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7266 * @wmi_handle: wmi handle 7267 * @preq: stats ext params 7268 * 7269 * Return: CDF status 7270 */ 7271 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7272 struct stats_ext_params *preq) 7273 { 7274 QDF_STATUS ret; 7275 wmi_req_stats_ext_cmd_fixed_param *cmd; 7276 wmi_buf_t buf; 7277 size_t len; 7278 uint8_t *buf_ptr; 7279 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7280 uint32_t *vdev_bitmap; 7281 7282 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7283 sizeof(*cmd))) { 7284 wmi_err("Data length=%d is greater than max wmi msg size", 7285 preq->request_data_len); 7286 return QDF_STATUS_E_FAILURE; 7287 } 7288 7289 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7290 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7291 7292 buf = wmi_buf_alloc(wmi_handle, len); 7293 if (!buf) 7294 return QDF_STATUS_E_NOMEM; 7295 7296 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7297 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7298 7299 WMITLV_SET_HDR(&cmd->tlv_header, 7300 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7301 WMITLV_GET_STRUCT_TLVLEN 7302 (wmi_req_stats_ext_cmd_fixed_param)); 7303 cmd->vdev_id = preq->vdev_id; 7304 cmd->data_len = preq->request_data_len; 7305 7306 wmi_debug("The data len value is %u and vdev id set is %u", 7307 preq->request_data_len, preq->vdev_id); 7308 7309 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7310 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7311 7312 buf_ptr += WMI_TLV_HDR_SIZE; 7313 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7314 7315 buf_ptr += cmd->data_len; 7316 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7317 7318 buf_ptr += WMI_TLV_HDR_SIZE; 7319 7320 vdev_bitmap = (A_UINT32 *)buf_ptr; 7321 7322 vdev_bitmap[0] = preq->vdev_id_bitmap; 7323 7324 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7325 7326 buf_ptr += sizeof(uint32_t); 7327 7328 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7329 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7330 WMI_REQUEST_STATS_EXT_CMDID); 7331 if (QDF_IS_STATUS_ERROR(ret)) { 7332 wmi_err("Failed to send notify cmd ret = %d", ret); 7333 wmi_buf_free(buf); 7334 } 7335 7336 return ret; 7337 } 7338 7339 /** 7340 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7341 * @wmi_handle: wmi handle 7342 * @params: DHCP server offload info 7343 * 7344 * Return: QDF_STATUS_SUCCESS for success or error code 7345 */ 7346 static QDF_STATUS 7347 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7348 struct dhcp_offload_info_params *params) 7349 { 7350 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7351 wmi_buf_t buf; 7352 QDF_STATUS status; 7353 7354 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7355 if (!buf) 7356 return QDF_STATUS_E_NOMEM; 7357 7358 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7359 7360 WMITLV_SET_HDR(&cmd->tlv_header, 7361 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7362 WMITLV_GET_STRUCT_TLVLEN 7363 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7364 cmd->vdev_id = params->vdev_id; 7365 cmd->enable = params->dhcp_offload_enabled; 7366 cmd->num_client = params->dhcp_client_num; 7367 cmd->srv_ipv4 = params->dhcp_srv_addr; 7368 cmd->start_lsb = 0; 7369 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7370 status = wmi_unified_cmd_send(wmi_handle, buf, 7371 sizeof(*cmd), 7372 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7373 if (QDF_IS_STATUS_ERROR(status)) { 7374 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7375 wmi_buf_free(buf); 7376 return QDF_STATUS_E_FAILURE; 7377 } 7378 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7379 7380 return status; 7381 } 7382 7383 /** 7384 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7385 * @wmi_handle: wmi handle 7386 * @param: pointer to pdev regdomain params 7387 * 7388 * Return: 0 for success or error code 7389 */ 7390 static QDF_STATUS 7391 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7392 struct pdev_set_regdomain_params *param) 7393 { 7394 wmi_buf_t buf; 7395 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7396 int32_t len = sizeof(*cmd); 7397 7398 buf = wmi_buf_alloc(wmi_handle, len); 7399 if (!buf) 7400 return QDF_STATUS_E_NOMEM; 7401 7402 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7403 WMITLV_SET_HDR(&cmd->tlv_header, 7404 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7405 WMITLV_GET_STRUCT_TLVLEN 7406 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7407 7408 cmd->reg_domain = param->currentRDinuse; 7409 cmd->reg_domain_2G = param->currentRD2G; 7410 cmd->reg_domain_5G = param->currentRD5G; 7411 cmd->conformance_test_limit_2G = param->ctl_2G; 7412 cmd->conformance_test_limit_5G = param->ctl_5G; 7413 cmd->dfs_domain = param->dfsDomain; 7414 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7415 wmi_handle, 7416 param->pdev_id); 7417 7418 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7419 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7420 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7421 wmi_err("Failed to send pdev set regdomain command"); 7422 wmi_buf_free(buf); 7423 return QDF_STATUS_E_FAILURE; 7424 } 7425 7426 return QDF_STATUS_SUCCESS; 7427 } 7428 7429 /** 7430 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7431 * @wmi_handle: wmi handle 7432 * @reg_dmn: reg domain 7433 * @regdmn2G: 2G reg domain 7434 * @regdmn5G: 5G reg domain 7435 * @ctl2G: 2G test limit 7436 * @ctl5G: 5G test limit 7437 * 7438 * Return: none 7439 */ 7440 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7441 uint32_t reg_dmn, uint16_t regdmn2G, 7442 uint16_t regdmn5G, uint8_t ctl2G, 7443 uint8_t ctl5G) 7444 { 7445 wmi_buf_t buf; 7446 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7447 int32_t len = sizeof(*cmd); 7448 7449 7450 buf = wmi_buf_alloc(wmi_handle, len); 7451 if (!buf) 7452 return QDF_STATUS_E_NOMEM; 7453 7454 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7455 WMITLV_SET_HDR(&cmd->tlv_header, 7456 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7457 WMITLV_GET_STRUCT_TLVLEN 7458 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7459 cmd->reg_domain = reg_dmn; 7460 cmd->reg_domain_2G = regdmn2G; 7461 cmd->reg_domain_5G = regdmn5G; 7462 cmd->conformance_test_limit_2G = ctl2G; 7463 cmd->conformance_test_limit_5G = ctl5G; 7464 7465 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7466 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7467 cmd->conformance_test_limit_2G, 7468 cmd->conformance_test_limit_5G); 7469 7470 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7471 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7472 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7473 wmi_err("Failed to send pdev set regdomain command"); 7474 wmi_buf_free(buf); 7475 return QDF_STATUS_E_FAILURE; 7476 } 7477 7478 return QDF_STATUS_SUCCESS; 7479 } 7480 7481 /** 7482 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7483 * @param: param sent from the host side 7484 * @cmd: param to be sent to the fw side 7485 */ 7486 static inline void copy_custom_aggr_bitmap( 7487 struct set_custom_aggr_size_params *param, 7488 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7489 { 7490 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7491 param->ac); 7492 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7493 param->aggr_type); 7494 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7495 param->tx_aggr_size_disable); 7496 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7497 param->rx_aggr_size_disable); 7498 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7499 param->tx_ac_enable); 7500 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7501 param->aggr_ba_enable); 7502 } 7503 7504 /** 7505 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7506 * @wmi_handle: wmi handle 7507 * @param: pointer to hold custom aggr size params 7508 * 7509 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7510 */ 7511 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7512 wmi_unified_t wmi_handle, 7513 struct set_custom_aggr_size_params *param) 7514 { 7515 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7516 wmi_buf_t buf; 7517 int32_t len = sizeof(*cmd); 7518 7519 buf = wmi_buf_alloc(wmi_handle, len); 7520 if (!buf) 7521 return QDF_STATUS_E_FAILURE; 7522 7523 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7524 wmi_buf_data(buf); 7525 WMITLV_SET_HDR(&cmd->tlv_header, 7526 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7527 WMITLV_GET_STRUCT_TLVLEN( 7528 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7529 cmd->vdev_id = param->vdev_id; 7530 cmd->tx_aggr_size = param->tx_aggr_size; 7531 cmd->rx_aggr_size = param->rx_aggr_size; 7532 copy_custom_aggr_bitmap(param, cmd); 7533 7534 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7535 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7536 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7537 "tx_ac_enable=0x%X", 7538 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7539 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7540 param->rx_aggr_size_disable, param->tx_ac_enable); 7541 7542 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7543 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7544 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7545 wmi_err("Setting custom aggregation size failed"); 7546 wmi_buf_free(buf); 7547 return QDF_STATUS_E_FAILURE; 7548 } 7549 7550 return QDF_STATUS_SUCCESS; 7551 } 7552 7553 /** 7554 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7555 * @param wmi_handle : handle to WMI. 7556 * @param param : pointer to tx antenna param 7557 * 7558 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7559 */ 7560 7561 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7562 struct set_qdepth_thresh_params *param) 7563 { 7564 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7565 wmi_msduq_qdepth_thresh_update *cmd_update; 7566 wmi_buf_t buf; 7567 int32_t len = 0; 7568 int i; 7569 uint8_t *buf_ptr; 7570 QDF_STATUS ret; 7571 7572 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7573 wmi_err("Invalid Update Count!"); 7574 return QDF_STATUS_E_INVAL; 7575 } 7576 7577 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7578 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7579 param->num_of_msduq_updates); 7580 buf = wmi_buf_alloc(wmi_handle, len); 7581 7582 if (!buf) 7583 return QDF_STATUS_E_NOMEM; 7584 7585 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7586 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7587 buf_ptr; 7588 7589 WMITLV_SET_HDR(&cmd->tlv_header, 7590 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7591 , WMITLV_GET_STRUCT_TLVLEN( 7592 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7593 7594 cmd->pdev_id = 7595 wmi_handle->ops->convert_pdev_id_host_to_target( 7596 wmi_handle, 7597 param->pdev_id); 7598 cmd->vdev_id = param->vdev_id; 7599 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7600 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7601 7602 buf_ptr += sizeof( 7603 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7604 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7605 param->num_of_msduq_updates * 7606 sizeof(wmi_msduq_qdepth_thresh_update)); 7607 buf_ptr += WMI_TLV_HDR_SIZE; 7608 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7609 7610 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7611 WMITLV_SET_HDR(&cmd_update->tlv_header, 7612 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7613 WMITLV_GET_STRUCT_TLVLEN( 7614 wmi_msduq_qdepth_thresh_update)); 7615 cmd_update->tid_num = param->update_params[i].tid_num; 7616 cmd_update->msduq_update_mask = 7617 param->update_params[i].msduq_update_mask; 7618 cmd_update->qdepth_thresh_value = 7619 param->update_params[i].qdepth_thresh_value; 7620 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7621 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7622 " update mask=0x%X thresh val=0x%X", 7623 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7624 cmd->peer_mac_address.mac_addr31to0, 7625 cmd->peer_mac_address.mac_addr47to32, 7626 cmd_update->msduq_update_mask, 7627 cmd_update->qdepth_thresh_value); 7628 cmd_update++; 7629 } 7630 7631 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7632 cmd->vdev_id, 0); 7633 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7634 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7635 7636 if (ret != 0) { 7637 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7638 wmi_buf_free(buf); 7639 } 7640 7641 return ret; 7642 } 7643 7644 /** 7645 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7646 * @wmi_handle: wmi handle 7647 * @param: pointer to hold vap dscp tid map param 7648 * 7649 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7650 */ 7651 static QDF_STATUS 7652 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7653 struct vap_dscp_tid_map_params *param) 7654 { 7655 wmi_buf_t buf; 7656 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7657 int32_t len = sizeof(*cmd); 7658 7659 buf = wmi_buf_alloc(wmi_handle, len); 7660 if (!buf) 7661 return QDF_STATUS_E_FAILURE; 7662 7663 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7664 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7665 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7666 7667 cmd->vdev_id = param->vdev_id; 7668 cmd->enable_override = 0; 7669 7670 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7671 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7672 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7673 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7674 wmi_err("Failed to set dscp cmd"); 7675 wmi_buf_free(buf); 7676 return QDF_STATUS_E_FAILURE; 7677 } 7678 7679 return QDF_STATUS_SUCCESS; 7680 } 7681 7682 /** 7683 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7684 * @wmi_handle: wmi handle 7685 * @param: pointer to hold fwtest param 7686 * 7687 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7688 */ 7689 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7690 struct set_fwtest_params *param) 7691 { 7692 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7693 wmi_buf_t buf; 7694 int32_t len = sizeof(*cmd); 7695 7696 buf = wmi_buf_alloc(wmi_handle, len); 7697 7698 if (!buf) 7699 return QDF_STATUS_E_FAILURE; 7700 7701 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7702 WMITLV_SET_HDR(&cmd->tlv_header, 7703 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7704 WMITLV_GET_STRUCT_TLVLEN( 7705 wmi_fwtest_set_param_cmd_fixed_param)); 7706 cmd->param_id = param->arg; 7707 cmd->param_value = param->value; 7708 7709 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7710 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7711 wmi_err("Setting FW test param failed"); 7712 wmi_buf_free(buf); 7713 return QDF_STATUS_E_FAILURE; 7714 } 7715 7716 return QDF_STATUS_SUCCESS; 7717 } 7718 7719 /** 7720 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7721 * 7722 * @param wmi_handle : handle to WMI. 7723 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7724 */ 7725 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7726 { 7727 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7728 wmi_buf_t buf; 7729 QDF_STATUS ret; 7730 int32_t len; 7731 7732 len = sizeof(*cmd); 7733 7734 buf = wmi_buf_alloc(wmi_handle, len); 7735 if (!buf) 7736 return QDF_STATUS_E_FAILURE; 7737 7738 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7739 WMITLV_SET_HDR(&cmd->tlv_header, 7740 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7741 WMITLV_GET_STRUCT_TLVLEN( 7742 wmi_pdev_dfs_disable_cmd_fixed_param)); 7743 /* Filling it with WMI_PDEV_ID_SOC for now */ 7744 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7745 wmi_handle, 7746 WMI_HOST_PDEV_ID_SOC); 7747 7748 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7749 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7750 WMI_PDEV_DFS_DISABLE_CMDID); 7751 7752 if (ret != 0) { 7753 wmi_err("Sending PDEV DFS disable cmd failed"); 7754 wmi_buf_free(buf); 7755 } 7756 7757 return ret; 7758 } 7759 7760 /** 7761 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 7762 * 7763 * @param wmi_handle : handle to WMI. 7764 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7765 */ 7766 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 7767 { 7768 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 7769 wmi_buf_t buf; 7770 QDF_STATUS ret; 7771 int32_t len; 7772 7773 len = sizeof(*cmd); 7774 7775 buf = wmi_buf_alloc(wmi_handle, len); 7776 if (!buf) 7777 return QDF_STATUS_E_FAILURE; 7778 7779 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 7780 WMITLV_SET_HDR(&cmd->tlv_header, 7781 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 7782 WMITLV_GET_STRUCT_TLVLEN( 7783 wmi_pdev_dfs_enable_cmd_fixed_param)); 7784 /* Reserved for future use */ 7785 cmd->reserved0 = 0; 7786 7787 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 7788 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7789 WMI_PDEV_DFS_ENABLE_CMDID); 7790 7791 if (ret != 0) { 7792 wmi_err("Sending PDEV DFS enable cmd failed"); 7793 wmi_buf_free(buf); 7794 } 7795 7796 return ret; 7797 } 7798 7799 /** 7800 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 7801 * to fw 7802 * @wmi_handle: wmi handle 7803 * @param: pointer to hold periodic chan stats param 7804 * 7805 * Return: 0 for success or error code 7806 */ 7807 static QDF_STATUS 7808 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 7809 struct periodic_chan_stats_params *param) 7810 { 7811 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 7812 wmi_buf_t buf; 7813 QDF_STATUS ret; 7814 int32_t len; 7815 7816 len = sizeof(*cmd); 7817 7818 buf = wmi_buf_alloc(wmi_handle, len); 7819 if (!buf) 7820 return QDF_STATUS_E_FAILURE; 7821 7822 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 7823 wmi_buf_data(buf); 7824 WMITLV_SET_HDR(&cmd->tlv_header, 7825 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 7826 WMITLV_GET_STRUCT_TLVLEN( 7827 wmi_set_periodic_channel_stats_config_fixed_param)); 7828 cmd->enable = param->enable; 7829 cmd->stats_period = param->stats_period; 7830 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7831 wmi_handle, 7832 param->pdev_id); 7833 7834 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 7835 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7836 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 7837 7838 if (ret != 0) { 7839 wmi_err("Sending periodic chan stats config failed"); 7840 wmi_buf_free(buf); 7841 } 7842 7843 return ret; 7844 } 7845 7846 #ifdef WLAN_IOT_SIM_SUPPORT 7847 /** 7848 * send_simulation_test_cmd_tlv() - send simulation test command to fw 7849 * 7850 * @wmi_handle: wmi handle 7851 * @param: pointer to hold simulation test parameter 7852 * 7853 * Return: 0 for success or error code 7854 */ 7855 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 7856 struct simulation_test_params 7857 *param) 7858 { 7859 wmi_simulation_test_cmd_fixed_param *cmd; 7860 u32 wmi_buf_len; 7861 wmi_buf_t buf; 7862 u8 *buf_ptr; 7863 u32 aligned_len = 0; 7864 7865 wmi_buf_len = sizeof(*cmd); 7866 if (param->buf_len) { 7867 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 7868 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 7869 } 7870 7871 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7872 if (!buf) { 7873 wmi_err("wmi_buf_alloc failed"); 7874 return QDF_STATUS_E_NOMEM; 7875 } 7876 7877 buf_ptr = wmi_buf_data(buf); 7878 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7879 WMITLV_SET_HDR(&cmd->tlv_header, 7880 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7881 WMITLV_GET_STRUCT_TLVLEN( 7882 wmi_simulation_test_cmd_fixed_param)); 7883 cmd->pdev_id = param->pdev_id; 7884 cmd->vdev_id = param->vdev_id; 7885 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7886 cmd->test_cmd_type = param->test_cmd_type; 7887 cmd->test_subcmd_type = param->test_subcmd_type; 7888 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7889 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7890 param->frame_subtype); 7891 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7892 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7893 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7894 cmd->buf_len = param->buf_len; 7895 7896 if (param->buf_len) { 7897 buf_ptr += sizeof(*cmd); 7898 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7899 buf_ptr += WMI_TLV_HDR_SIZE; 7900 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 7901 } 7902 7903 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 7904 WMI_SIMULATION_TEST_CMDID)) { 7905 wmi_err("Failed to send test simulation cmd"); 7906 wmi_buf_free(buf); 7907 return QDF_STATUS_E_FAILURE; 7908 } 7909 7910 return QDF_STATUS_SUCCESS; 7911 } 7912 #endif 7913 7914 #ifdef WLAN_FEATURE_11BE 7915 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 7916 #else 7917 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 7918 #endif 7919 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 7920 { 7921 switch (wmi_width) { 7922 case WMI_CHAN_WIDTH_20: 7923 return CH_WIDTH_20MHZ; 7924 case WMI_CHAN_WIDTH_40: 7925 return CH_WIDTH_40MHZ; 7926 case WMI_CHAN_WIDTH_80: 7927 return CH_WIDTH_80MHZ; 7928 case WMI_CHAN_WIDTH_160: 7929 return CH_WIDTH_160MHZ; 7930 case WMI_CHAN_WIDTH_80P80: 7931 return CH_WIDTH_80P80MHZ; 7932 case WMI_CHAN_WIDTH_5: 7933 return CH_WIDTH_5MHZ; 7934 case WMI_CHAN_WIDTH_10: 7935 return CH_WIDTH_10MHZ; 7936 case WMI_CHAN_WIDTH_320: 7937 return WLAN_PHY_CH_WIDTH_320MHZ; 7938 default: 7939 return CH_WIDTH_INVALID; 7940 } 7941 } 7942 7943 /** 7944 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 7945 * command to fw 7946 * @wmi_handle: wmi handle 7947 * @param: pointer to hold spectral config parameter 7948 * 7949 * Return: 0 for success or error code 7950 */ 7951 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 7952 struct vdev_spectral_configure_params *param) 7953 { 7954 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 7955 wmi_buf_t buf; 7956 QDF_STATUS ret; 7957 int32_t len; 7958 7959 len = sizeof(*cmd); 7960 buf = wmi_buf_alloc(wmi_handle, len); 7961 if (!buf) 7962 return QDF_STATUS_E_FAILURE; 7963 7964 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 7965 WMITLV_SET_HDR(&cmd->tlv_header, 7966 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 7967 WMITLV_GET_STRUCT_TLVLEN( 7968 wmi_vdev_spectral_configure_cmd_fixed_param)); 7969 7970 cmd->vdev_id = param->vdev_id; 7971 cmd->spectral_scan_count = param->count; 7972 cmd->spectral_scan_period = param->period; 7973 cmd->spectral_scan_priority = param->spectral_pri; 7974 cmd->spectral_scan_fft_size = param->fft_size; 7975 cmd->spectral_scan_gc_ena = param->gc_enable; 7976 cmd->spectral_scan_restart_ena = param->restart_enable; 7977 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 7978 cmd->spectral_scan_init_delay = param->init_delay; 7979 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 7980 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 7981 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 7982 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 7983 cmd->spectral_scan_rssi_thr = param->rssi_thr; 7984 cmd->spectral_scan_pwr_format = param->pwr_format; 7985 cmd->spectral_scan_rpt_mode = param->rpt_mode; 7986 cmd->spectral_scan_bin_scale = param->bin_scale; 7987 cmd->spectral_scan_dBm_adj = param->dbm_adj; 7988 cmd->spectral_scan_chn_mask = param->chn_mask; 7989 cmd->spectral_scan_mode = param->mode; 7990 cmd->spectral_scan_center_freq1 = param->center_freq1; 7991 cmd->spectral_scan_center_freq2 = param->center_freq2; 7992 cmd->spectral_scan_chan_width = param->chan_width; 7993 cmd->recapture_sample_on_gain_change = param->fft_recap; 7994 /* Not used, fill with zeros */ 7995 cmd->spectral_scan_chan_freq = 0; 7996 7997 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 7998 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7999 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8000 8001 if (ret != 0) { 8002 wmi_err("Sending set quiet cmd failed"); 8003 wmi_buf_free(buf); 8004 } 8005 8006 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8007 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8008 param->vdev_id, param->count); 8009 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8010 param->period, param->spectral_pri); 8011 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8012 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8013 param->fft_size, param->gc_enable); 8014 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8015 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8016 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8017 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8018 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8019 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8020 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8021 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8022 param->rssi_thr, param->pwr_format); 8023 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8024 param->rpt_mode, param->bin_scale); 8025 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8026 param->dbm_adj, param->chn_mask); 8027 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8028 param->mode, param->center_freq1); 8029 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8030 param->center_freq2, param->chan_freq); 8031 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8032 param->chan_width, ret); 8033 8034 return ret; 8035 } 8036 8037 /** 8038 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8039 * command to fw 8040 * @wmi_handle: wmi handle 8041 * @param: pointer to hold spectral enable parameter 8042 * 8043 * Return: 0 for success or error code 8044 */ 8045 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8046 struct vdev_spectral_enable_params *param) 8047 { 8048 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8049 wmi_buf_t buf; 8050 QDF_STATUS ret; 8051 int32_t len; 8052 8053 len = sizeof(*cmd); 8054 buf = wmi_buf_alloc(wmi_handle, len); 8055 if (!buf) 8056 return QDF_STATUS_E_FAILURE; 8057 8058 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8059 WMITLV_SET_HDR(&cmd->tlv_header, 8060 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8061 WMITLV_GET_STRUCT_TLVLEN( 8062 wmi_vdev_spectral_enable_cmd_fixed_param)); 8063 8064 cmd->vdev_id = param->vdev_id; 8065 8066 if (param->active_valid) { 8067 cmd->trigger_cmd = param->active ? 1 : 2; 8068 /* 1: Trigger, 2: Clear Trigger */ 8069 } else { 8070 cmd->trigger_cmd = 0; /* 0: Ignore */ 8071 } 8072 8073 if (param->enabled_valid) { 8074 cmd->enable_cmd = param->enabled ? 1 : 2; 8075 /* 1: Enable 2: Disable */ 8076 } else { 8077 cmd->enable_cmd = 0; /* 0: Ignore */ 8078 } 8079 cmd->spectral_scan_mode = param->mode; 8080 8081 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8082 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8083 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8084 8085 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8086 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8087 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8088 8089 if (ret != 0) { 8090 wmi_err("Sending scan enable CMD failed"); 8091 wmi_buf_free(buf); 8092 } 8093 8094 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8095 ret); 8096 8097 return ret; 8098 } 8099 8100 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8101 static QDF_STATUS 8102 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8103 wmi_unified_t wmi_handle, 8104 uint8_t *event, struct spectral_startscan_resp_params *param) 8105 { 8106 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8107 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8108 8109 if (!wmi_handle) { 8110 wmi_err("WMI handle is null"); 8111 return QDF_STATUS_E_INVAL; 8112 } 8113 8114 if (!event) { 8115 wmi_err("WMI event is null"); 8116 return QDF_STATUS_E_INVAL; 8117 } 8118 8119 if (!param) { 8120 wmi_err("Spectral startscan response params is null"); 8121 return QDF_STATUS_E_INVAL; 8122 } 8123 8124 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8125 if (!param_buf) 8126 return QDF_STATUS_E_INVAL; 8127 8128 ev = param_buf->fixed_param; 8129 if (!ev) 8130 return QDF_STATUS_E_INVAL; 8131 8132 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8133 wmi_handle, 8134 ev->pdev_id); 8135 param->smode = ev->spectral_scan_mode; 8136 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8137 param->num_det_info = param_buf->num_det_info; 8138 8139 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8140 ev->pdev_id, ev->spectral_scan_mode, 8141 param_buf->num_fft_bin_index, param_buf->num_det_info); 8142 8143 return QDF_STATUS_SUCCESS; 8144 } 8145 8146 static QDF_STATUS 8147 extract_pdev_sscan_fft_bin_index_tlv( 8148 wmi_unified_t wmi_handle, uint8_t *event, 8149 struct spectral_fft_bin_markers_160_165mhz *param) 8150 { 8151 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8152 wmi_pdev_sscan_fft_bin_index *ev; 8153 8154 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8155 if (!param_buf) 8156 return QDF_STATUS_E_INVAL; 8157 8158 ev = param_buf->fft_bin_index; 8159 if (!ev) 8160 return QDF_STATUS_E_INVAL; 8161 8162 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8163 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8164 param->start_pri80 + 1; 8165 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8166 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8167 param->start_sec80 + 1; 8168 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8169 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8170 param->start_5mhz + 1; 8171 param->is_valid = true; 8172 8173 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8174 param->start_pri80, param->num_pri80, 8175 param->start_sec80, param->num_sec80, 8176 param->start_5mhz, param->num_5mhz); 8177 8178 return QDF_STATUS_SUCCESS; 8179 } 8180 8181 /** 8182 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8183 * for a spectral scan session 8184 * @wmi_handle: handle to WMI. 8185 * @event: Event buffer 8186 * @chan_info: Spectral session channel information data structure to be filled 8187 * by this API 8188 * 8189 * Return: QDF_STATUS of operation 8190 */ 8191 static QDF_STATUS 8192 extract_pdev_spectral_session_chan_info_tlv( 8193 wmi_unified_t wmi_handle, void *event, 8194 struct spectral_session_chan_info *chan_info) 8195 { 8196 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8197 wmi_pdev_sscan_chan_info *chan_info_tlv; 8198 8199 if (!param_buf) { 8200 wmi_err("param_buf is NULL"); 8201 return QDF_STATUS_E_NULL_VALUE; 8202 } 8203 8204 if (!chan_info) { 8205 wmi_err("chan_info is NULL"); 8206 return QDF_STATUS_E_NULL_VALUE; 8207 } 8208 8209 chan_info_tlv = param_buf->chan_info; 8210 if (!chan_info_tlv) { 8211 wmi_err("chan_info tlv is not present in the event"); 8212 return QDF_STATUS_E_NULL_VALUE; 8213 } 8214 8215 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8216 "operating_cfreq2:%u operating_bw:%u" 8217 "operating_puncture_20mhz_bitmap:%u" 8218 "sscan_cfreq1:%u sscan_cfreq2:%u" 8219 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8220 chan_info_tlv->operating_pri20_freq, 8221 chan_info_tlv->operating_cfreq1, 8222 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8223 chan_info_tlv->operating_puncture_20mhz_bitmap, 8224 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8225 chan_info_tlv->sscan_bw, 8226 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8227 8228 chan_info->operating_pri20_freq = 8229 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8230 chan_info->operating_cfreq1 = 8231 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8232 chan_info->operating_cfreq2 = 8233 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8234 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8235 chan_info->operating_puncture_20mhz_bitmap = 8236 chan_info_tlv->operating_puncture_20mhz_bitmap; 8237 8238 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8239 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8240 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8241 chan_info->sscan_puncture_20mhz_bitmap = 8242 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8243 8244 return QDF_STATUS_SUCCESS; 8245 } 8246 8247 static QDF_STATUS 8248 extract_pdev_spectral_session_detector_info_tlv( 8249 wmi_unified_t wmi_handle, void *event, 8250 struct spectral_session_det_info *det_info, uint8_t idx) 8251 { 8252 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8253 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8254 8255 if (!param_buf) { 8256 wmi_err("param_buf is NULL"); 8257 return QDF_STATUS_E_NULL_VALUE; 8258 } 8259 8260 if (!det_info) { 8261 wmi_err("chan_info is NULL"); 8262 return QDF_STATUS_E_NULL_VALUE; 8263 } 8264 8265 if (!param_buf->det_info) { 8266 wmi_err("det_info tlv is not present in the event"); 8267 return QDF_STATUS_E_NULL_VALUE; 8268 } 8269 8270 if (idx >= param_buf->num_det_info) { 8271 wmi_err("det_info index(%u) is greater than or equal to %u", 8272 idx, param_buf->num_det_info); 8273 return QDF_STATUS_E_FAILURE; 8274 } 8275 8276 det_info_tlv = ¶m_buf->det_info[idx]; 8277 8278 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8279 idx, det_info_tlv->detector_id, 8280 det_info_tlv->start_freq, det_info_tlv->end_freq); 8281 8282 det_info->det_id = det_info_tlv->detector_id; 8283 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8284 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8285 8286 return QDF_STATUS_SUCCESS; 8287 } 8288 8289 /** 8290 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8291 * capabilities WMI event 8292 * @wmi_handle: handle to WMI. 8293 * @event: Event buffer 8294 * @param: Spectral capabilities event parameters data structure to be filled 8295 * by this API 8296 * 8297 * Return: QDF_STATUS of operation 8298 */ 8299 static QDF_STATUS 8300 extract_spectral_caps_fixed_param_tlv( 8301 wmi_unified_t wmi_handle, void *event, 8302 struct spectral_capabilities_event_params *params) 8303 { 8304 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8305 8306 if (!param_buf) { 8307 wmi_err("param_buf is NULL"); 8308 return QDF_STATUS_E_NULL_VALUE; 8309 } 8310 8311 if (!params) { 8312 wmi_err("event parameters is NULL"); 8313 return QDF_STATUS_E_NULL_VALUE; 8314 } 8315 8316 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8317 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8318 8319 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 8320 params->num_sscan_bw_caps, params->num_fft_size_caps); 8321 8322 return QDF_STATUS_SUCCESS; 8323 } 8324 8325 /** 8326 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 8327 * Spectral capabilities WMI event 8328 * @wmi_handle: handle to WMI. 8329 * @event: Event buffer 8330 * @bw_caps: Data structure to be populated by this API after extraction 8331 * 8332 * Return: QDF_STATUS of operation 8333 */ 8334 static QDF_STATUS 8335 extract_spectral_scan_bw_caps_tlv( 8336 wmi_unified_t wmi_handle, void *event, 8337 struct spectral_scan_bw_capabilities *bw_caps) 8338 { 8339 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8340 int idx; 8341 8342 if (!param_buf) { 8343 wmi_err("param_buf is NULL"); 8344 return QDF_STATUS_E_NULL_VALUE; 8345 } 8346 8347 if (!bw_caps) { 8348 wmi_err("bw_caps is null"); 8349 return QDF_STATUS_E_NULL_VALUE; 8350 } 8351 8352 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 8353 bw_caps[idx].pdev_id = 8354 wmi_handle->ops->convert_pdev_id_target_to_host( 8355 wmi_handle, 8356 param_buf->sscan_bw_caps[idx].pdev_id); 8357 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 8358 bw_caps[idx].operating_bw = wmi_map_ch_width( 8359 param_buf->sscan_bw_caps[idx].operating_bw); 8360 bw_caps[idx].supported_bws = 8361 param_buf->sscan_bw_caps[idx].supported_flags; 8362 8363 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 8364 "operating_bw:%u supported_flags:0x%x", 8365 idx, param_buf->sscan_bw_caps[idx].pdev_id, 8366 param_buf->sscan_bw_caps[idx].sscan_mode, 8367 param_buf->sscan_bw_caps[idx].operating_bw, 8368 param_buf->sscan_bw_caps[idx].supported_flags); 8369 } 8370 8371 return QDF_STATUS_SUCCESS; 8372 } 8373 8374 /** 8375 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 8376 * Spectral capabilities WMI event 8377 * @wmi_handle: handle to WMI. 8378 * @event: Event buffer 8379 * @fft_size_caps: Data structure to be populated by this API after extraction 8380 * 8381 * Return: QDF_STATUS of operation 8382 */ 8383 static QDF_STATUS 8384 extract_spectral_fft_size_caps_tlv( 8385 wmi_unified_t wmi_handle, void *event, 8386 struct spectral_fft_size_capabilities *fft_size_caps) 8387 { 8388 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8389 int idx; 8390 8391 if (!param_buf) { 8392 wmi_err("param_buf is NULL"); 8393 return QDF_STATUS_E_NULL_VALUE; 8394 } 8395 8396 if (!fft_size_caps) { 8397 wmi_err("fft size caps is NULL"); 8398 return QDF_STATUS_E_NULL_VALUE; 8399 } 8400 8401 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 8402 fft_size_caps[idx].pdev_id = 8403 wmi_handle->ops->convert_pdev_id_target_to_host( 8404 wmi_handle, 8405 param_buf->fft_size_caps[idx].pdev_id); 8406 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 8407 param_buf->fft_size_caps[idx].sscan_bw); 8408 fft_size_caps[idx].supports_fft_sizes = 8409 param_buf->fft_size_caps[idx].supported_flags; 8410 8411 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 8412 "supported_flags:0x%x", 8413 idx, param_buf->fft_size_caps[idx].pdev_id, 8414 param_buf->fft_size_caps[idx].sscan_bw, 8415 param_buf->fft_size_caps[idx].supported_flags); 8416 } 8417 8418 return QDF_STATUS_SUCCESS; 8419 } 8420 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 8421 8422 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8423 static inline void 8424 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8425 struct thermal_mitigation_params *param) 8426 { 8427 tt_conf->client_id = param->client_id; 8428 tt_conf->priority = param->priority; 8429 } 8430 #else 8431 static inline void 8432 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8433 struct thermal_mitigation_params *param) 8434 { 8435 } 8436 #endif 8437 8438 /** 8439 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8440 * @param wmi_handle : handle to WMI. 8441 * @param param : pointer to hold thermal mitigation param 8442 * 8443 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 8444 */ 8445 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8446 wmi_unified_t wmi_handle, 8447 struct thermal_mitigation_params *param) 8448 { 8449 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8450 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8451 wmi_buf_t buf = NULL; 8452 uint8_t *buf_ptr = NULL; 8453 int error; 8454 int32_t len; 8455 int i; 8456 8457 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8458 param->num_thermal_conf * 8459 sizeof(wmi_therm_throt_level_config_info); 8460 8461 buf = wmi_buf_alloc(wmi_handle, len); 8462 if (!buf) 8463 return QDF_STATUS_E_NOMEM; 8464 8465 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8466 8467 /* init fixed params */ 8468 WMITLV_SET_HDR(tt_conf, 8469 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8470 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8471 8472 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8473 wmi_handle, 8474 param->pdev_id); 8475 tt_conf->enable = param->enable; 8476 tt_conf->dc = param->dc; 8477 tt_conf->dc_per_event = param->dc_per_event; 8478 tt_conf->therm_throt_levels = param->num_thermal_conf; 8479 wmi_fill_client_id_priority(tt_conf, param); 8480 buf_ptr = (uint8_t *) ++tt_conf; 8481 /* init TLV params */ 8482 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8483 (param->num_thermal_conf * 8484 sizeof(wmi_therm_throt_level_config_info))); 8485 8486 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8487 for (i = 0; i < param->num_thermal_conf; i++) { 8488 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8489 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8490 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8491 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8492 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8493 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8494 lvl_conf->prio = param->levelconf[i].priority; 8495 lvl_conf++; 8496 } 8497 8498 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8499 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8500 WMI_THERM_THROT_SET_CONF_CMDID); 8501 if (QDF_IS_STATUS_ERROR(error)) { 8502 wmi_buf_free(buf); 8503 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8504 } 8505 8506 return error; 8507 } 8508 8509 /** 8510 * send_coex_config_cmd_tlv() - send coex config command to fw 8511 * @wmi_handle: wmi handle 8512 * @param: pointer to coex config param 8513 * 8514 * Return: 0 for success or error code 8515 */ 8516 static QDF_STATUS 8517 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8518 struct coex_config_params *param) 8519 { 8520 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8521 wmi_buf_t buf; 8522 QDF_STATUS ret; 8523 int32_t len; 8524 8525 len = sizeof(*cmd); 8526 buf = wmi_buf_alloc(wmi_handle, len); 8527 if (!buf) 8528 return QDF_STATUS_E_FAILURE; 8529 8530 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8531 WMITLV_SET_HDR(&cmd->tlv_header, 8532 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8533 WMITLV_GET_STRUCT_TLVLEN( 8534 WMI_COEX_CONFIG_CMD_fixed_param)); 8535 8536 cmd->vdev_id = param->vdev_id; 8537 cmd->config_type = param->config_type; 8538 cmd->config_arg1 = param->config_arg1; 8539 cmd->config_arg2 = param->config_arg2; 8540 cmd->config_arg3 = param->config_arg3; 8541 cmd->config_arg4 = param->config_arg4; 8542 cmd->config_arg5 = param->config_arg5; 8543 cmd->config_arg6 = param->config_arg6; 8544 8545 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8546 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8547 WMI_COEX_CONFIG_CMDID); 8548 8549 if (ret != 0) { 8550 wmi_err("Sending COEX CONFIG CMD failed"); 8551 wmi_buf_free(buf); 8552 } 8553 8554 return ret; 8555 } 8556 8557 #ifdef WLAN_FEATURE_DBAM_CONFIG 8558 8559 static enum wmi_coex_dbam_mode_type 8560 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8561 { 8562 switch (mode) { 8563 case COEX_DBAM_ENABLE: 8564 return WMI_COEX_DBAM_ENABLE; 8565 case COEX_DBAM_FORCE_ENABLE: 8566 return WMI_COEX_DBAM_FORCED; 8567 case COEX_DBAM_DISABLE: 8568 default: 8569 return WMI_COEX_DBAM_DISABLE; 8570 } 8571 } 8572 8573 /** 8574 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8575 * @wmi_handle: wmi handle 8576 * @param: pointer to coex dbam config param 8577 * 8578 * Return: 0 for success or error code 8579 */ 8580 static QDF_STATUS 8581 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8582 struct coex_dbam_config_params *param) 8583 { 8584 wmi_coex_dbam_cmd_fixed_param *cmd; 8585 wmi_buf_t buf; 8586 void *buf_ptr; 8587 QDF_STATUS ret; 8588 int32_t len; 8589 8590 len = sizeof(*cmd); 8591 buf = wmi_buf_alloc(wmi_handle, len); 8592 if (!buf) { 8593 wmi_err_rl("Failed to allocate wmi buffer"); 8594 return QDF_STATUS_E_NOMEM; 8595 } 8596 8597 buf_ptr = wmi_buf_data(buf); 8598 cmd = buf_ptr; 8599 WMITLV_SET_HDR(&cmd->tlv_header, 8600 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8601 WMITLV_GET_STRUCT_TLVLEN( 8602 wmi_coex_dbam_cmd_fixed_param)); 8603 8604 cmd->vdev_id = param->vdev_id; 8605 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8606 8607 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8608 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8609 WMI_COEX_DBAM_CMDID); 8610 8611 if (QDF_IS_STATUS_ERROR(ret)) { 8612 wmi_err("Sending DBAM CONFIG CMD failed"); 8613 wmi_buf_free(buf); 8614 return QDF_STATUS_E_FAILURE; 8615 } 8616 8617 return ret; 8618 } 8619 8620 static enum coex_dbam_comp_status 8621 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8622 { 8623 switch (status) { 8624 case WMI_COEX_DBAM_COMP_SUCCESS: 8625 case WMI_COEX_DBAM_COMP_ONGOING: 8626 case WMI_COEX_DBAM_COMP_DELAYED: 8627 return COEX_DBAM_COMP_SUCCESS; 8628 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8629 return COEX_DBAM_COMP_NOT_SUPPORT; 8630 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8631 case WMI_COEX_DBAM_COMP_FAIL: 8632 default: 8633 return COEX_DBAM_COMP_FAIL; 8634 } 8635 } 8636 8637 /** 8638 * extract_dbam_comp_status_event_tlv() - extract dbam complete status event 8639 * @wmi_handle: WMI handle 8640 * @evt_buf: event buffer 8641 * @resp: pointer to coex dbam config response 8642 * 8643 * Return: QDF_STATUS 8644 */ 8645 static QDF_STATUS 8646 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8647 struct coex_dbam_config_resp *resp) 8648 { 8649 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8650 wmi_coex_dbam_complete_event_fixed_param *event; 8651 8652 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8653 8654 event = param_buf->fixed_param; 8655 8656 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8657 8658 return QDF_STATUS_SUCCESS; 8659 } 8660 #endif 8661 8662 #ifdef WLAN_SUPPORT_TWT 8663 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8664 target_resource_config *tgt_res_cfg) 8665 { 8666 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8667 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8668 } 8669 #else 8670 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8671 target_resource_config *tgt_res_cfg) 8672 { 8673 resource_cfg->twt_ap_pdev_count = 0; 8674 resource_cfg->twt_ap_sta_count = 0; 8675 } 8676 #endif 8677 8678 #ifdef WLAN_FEATURE_NAN 8679 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8680 { 8681 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8682 resource_cfg->host_service_flags, 1); 8683 } 8684 #else 8685 static inline 8686 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8687 { 8688 } 8689 #endif 8690 8691 #if defined(CONFIG_AFC_SUPPORT) 8692 static 8693 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8694 target_resource_config *tgt_res_cfg) 8695 { 8696 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8697 resource_cfg->host_service_flags, 8698 tgt_res_cfg->afc_indoor_support); 8699 8700 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8701 resource_cfg->host_service_flags, 8702 tgt_res_cfg->afc_outdoor_support); 8703 } 8704 #else 8705 static 8706 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8707 target_resource_config *tgt_res_cfg) 8708 { 8709 } 8710 #endif 8711 8712 static 8713 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8714 target_resource_config *tgt_res_cfg) 8715 { 8716 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 8717 resource_cfg->num_peers = tgt_res_cfg->num_peers; 8718 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 8719 resource_cfg->num_offload_reorder_buffs = 8720 tgt_res_cfg->num_offload_reorder_buffs; 8721 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 8722 resource_cfg->num_tids = tgt_res_cfg->num_tids; 8723 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 8724 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 8725 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 8726 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 8727 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 8728 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 8729 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 8730 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 8731 resource_cfg->scan_max_pending_req = 8732 tgt_res_cfg->scan_max_pending_req; 8733 resource_cfg->bmiss_offload_max_vdev = 8734 tgt_res_cfg->bmiss_offload_max_vdev; 8735 resource_cfg->roam_offload_max_vdev = 8736 tgt_res_cfg->roam_offload_max_vdev; 8737 resource_cfg->roam_offload_max_ap_profiles = 8738 tgt_res_cfg->roam_offload_max_ap_profiles; 8739 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 8740 resource_cfg->num_mcast_table_elems = 8741 tgt_res_cfg->num_mcast_table_elems; 8742 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 8743 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 8744 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 8745 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 8746 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 8747 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 8748 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 8749 resource_cfg->vow_config = tgt_res_cfg->vow_config; 8750 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 8751 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 8752 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 8753 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 8754 resource_cfg->num_tdls_conn_table_entries = 8755 tgt_res_cfg->num_tdls_conn_table_entries; 8756 resource_cfg->beacon_tx_offload_max_vdev = 8757 tgt_res_cfg->beacon_tx_offload_max_vdev; 8758 resource_cfg->num_multicast_filter_entries = 8759 tgt_res_cfg->num_multicast_filter_entries; 8760 resource_cfg->num_wow_filters = 8761 tgt_res_cfg->num_wow_filters; 8762 resource_cfg->num_keep_alive_pattern = 8763 tgt_res_cfg->num_keep_alive_pattern; 8764 resource_cfg->keep_alive_pattern_size = 8765 tgt_res_cfg->keep_alive_pattern_size; 8766 resource_cfg->max_tdls_concurrent_sleep_sta = 8767 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 8768 resource_cfg->max_tdls_concurrent_buffer_sta = 8769 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 8770 resource_cfg->wmi_send_separate = 8771 tgt_res_cfg->wmi_send_separate; 8772 resource_cfg->num_ocb_vdevs = 8773 tgt_res_cfg->num_ocb_vdevs; 8774 resource_cfg->num_ocb_channels = 8775 tgt_res_cfg->num_ocb_channels; 8776 resource_cfg->num_ocb_schedules = 8777 tgt_res_cfg->num_ocb_schedules; 8778 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 8779 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 8780 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 8781 resource_cfg->max_num_dbs_scan_duty_cycle = 8782 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 8783 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 8784 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 8785 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 8786 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 8787 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 8788 /* Deferred AI: Max rnr neighbors supported in multisoc case 8789 * where in SoC can support 6ghz. During WMI init of a SoC 8790 * currently there is no way to figure if another SOC is plugged in 8791 * and it can support 6Ghz. 8792 */ 8793 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 8794 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 8795 resource_cfg->ema_max_profile_period = 8796 tgt_res_cfg->ema_max_profile_period; 8797 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 8798 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 8799 8800 if (tgt_res_cfg->max_ndp_sessions) 8801 resource_cfg->max_ndp_sessions = 8802 tgt_res_cfg->max_ndp_sessions; 8803 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 8804 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 8805 8806 if (tgt_res_cfg->atf_config) 8807 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 8808 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 8809 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 8810 resource_cfg->flag1, 1); 8811 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 8812 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 8813 resource_cfg->flag1, 1); 8814 if (tgt_res_cfg->cce_disable) 8815 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 8816 if (tgt_res_cfg->enable_pci_gen) 8817 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 8818 resource_cfg->flag1, 1); 8819 if (tgt_res_cfg->eapol_minrate_set) { 8820 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 8821 resource_cfg->flag1, 1); 8822 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 8823 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 8824 resource_cfg->flag1, 1); 8825 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 8826 resource_cfg->flag1, 8827 tgt_res_cfg->eapol_minrate_ac_set); 8828 } 8829 } 8830 if (tgt_res_cfg->new_htt_msg_format) { 8831 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 8832 resource_cfg->flag1, 1); 8833 } 8834 8835 if (tgt_res_cfg->peer_unmap_conf_support) 8836 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 8837 resource_cfg->flag1, 1); 8838 8839 if (tgt_res_cfg->tstamp64_en) 8840 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 8841 resource_cfg->flag1, 1); 8842 8843 if (tgt_res_cfg->three_way_coex_config_legacy_en) 8844 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 8845 resource_cfg->flag1, 1); 8846 if (tgt_res_cfg->pktcapture_support) 8847 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 8848 resource_cfg->flag1, 1); 8849 8850 /* 8851 * Control padding using config param/ini of iphdr_pad_config 8852 */ 8853 if (tgt_res_cfg->iphdr_pad_config) 8854 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 8855 resource_cfg->flag1, 1); 8856 8857 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 8858 tgt_res_cfg->ipa_disable); 8859 8860 if (tgt_res_cfg->time_sync_ftm) 8861 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 8862 1); 8863 8864 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 8865 resource_cfg->peer_map_unmap_versions = 8866 tgt_res_cfg->peer_map_unmap_version; 8867 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 8868 if (tgt_res_cfg->re_ul_resp) 8869 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 8870 tgt_res_cfg->re_ul_resp); 8871 8872 /* 8873 * Enable Service Aware Wifi 8874 */ 8875 if (tgt_res_cfg->sawf) 8876 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 8877 tgt_res_cfg->sawf); 8878 8879 /* 8880 * Enable ast flow override per peer 8881 */ 8882 resource_cfg->msdu_flow_override_config0 = 0; 8883 WMI_MSDU_FLOW_AST_ENABLE_SET( 8884 resource_cfg->msdu_flow_override_config0, 8885 WMI_CONFIG_MSDU_AST_INDEX_1, 8886 tgt_res_cfg->ast_1_valid_mask_enable); 8887 8888 WMI_MSDU_FLOW_AST_ENABLE_SET( 8889 resource_cfg->msdu_flow_override_config0, 8890 WMI_CONFIG_MSDU_AST_INDEX_2, 8891 tgt_res_cfg->ast_2_valid_mask_enable); 8892 8893 WMI_MSDU_FLOW_AST_ENABLE_SET( 8894 resource_cfg->msdu_flow_override_config0, 8895 WMI_CONFIG_MSDU_AST_INDEX_3, 8896 tgt_res_cfg->ast_3_valid_mask_enable); 8897 8898 /* 8899 * Enable ast flow mask and TID valid mask configurations 8900 */ 8901 resource_cfg->msdu_flow_override_config1 = 0; 8902 8903 /*Enable UDP flow for Ast index 0*/ 8904 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8905 resource_cfg->msdu_flow_override_config1, 8906 WMI_CONFIG_MSDU_AST_INDEX_0, 8907 tgt_res_cfg->ast_0_flow_mask_enable); 8908 8909 /*Enable Non UDP flow for Ast index 1*/ 8910 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8911 resource_cfg->msdu_flow_override_config1, 8912 WMI_CONFIG_MSDU_AST_INDEX_1, 8913 tgt_res_cfg->ast_1_flow_mask_enable); 8914 8915 /*Enable Hi-Priority flow for Ast index 2*/ 8916 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8917 resource_cfg->msdu_flow_override_config1, 8918 WMI_CONFIG_MSDU_AST_INDEX_2, 8919 tgt_res_cfg->ast_2_flow_mask_enable); 8920 8921 /*Enable Low-Priority flow for Ast index 3*/ 8922 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8923 resource_cfg->msdu_flow_override_config1, 8924 WMI_CONFIG_MSDU_AST_INDEX_3, 8925 tgt_res_cfg->ast_3_flow_mask_enable); 8926 8927 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 8928 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 8929 resource_cfg->msdu_flow_override_config1, 8930 tgt_res_cfg->ast_tid_high_mask_enable); 8931 8932 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 8933 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 8934 resource_cfg->msdu_flow_override_config1, 8935 tgt_res_cfg->ast_tid_low_mask_enable); 8936 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 8937 resource_cfg->host_service_flags, 8938 tgt_res_cfg->nan_separate_iface_support); 8939 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 8940 resource_cfg->host_service_flags, 1); 8941 8942 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 8943 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 8944 8945 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 8946 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 8947 resource_cfg->flags2, 1); 8948 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 8949 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 8950 resource_cfg->flags2, 1); 8951 8952 if (tgt_res_cfg->sae_eapol_offload) 8953 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 8954 resource_cfg->host_service_flags, 1); 8955 8956 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 8957 resource_cfg->host_service_flags, 8958 tgt_res_cfg->is_reg_cc_ext_event_supported); 8959 8960 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 8961 resource_cfg->host_service_flags, 8962 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 8963 8964 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 8965 resource_cfg->host_service_flags, 8966 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 8967 8968 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 8969 resource_cfg->host_service_flags, 8970 tgt_res_cfg->afc_timer_check_disable); 8971 8972 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 8973 resource_cfg->host_service_flags, 8974 tgt_res_cfg->afc_req_id_check_disable); 8975 8976 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 8977 8978 wmi_set_nan_channel_support(resource_cfg); 8979 8980 if (tgt_res_cfg->twt_ack_support_cap) 8981 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 8982 resource_cfg->host_service_flags, 1); 8983 8984 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 8985 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 8986 resource_cfg->host_service_flags, 1); 8987 8988 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 8989 tgt_res_cfg->target_cap_flags); 8990 if (tgt_res_cfg->notify_frame_support) 8991 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 8992 resource_cfg->flags2, 1); 8993 8994 } 8995 8996 #ifdef FEATURE_SET 8997 /** 8998 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 8999 * requirement2 version to target vendor1 requirement2 version 9000 * @vendor1_req2_ver: Host vendor1 requirement2 version 9001 * 9002 * Return: Target vendor1 requirement2 version 9003 */ 9004 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9005 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9006 { 9007 switch (vendor1_req2_ver) { 9008 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9009 return WMI_VENDOR1_REQ2_VERSION_3_00; 9010 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9011 return WMI_VENDOR1_REQ2_VERSION_3_01; 9012 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9013 return WMI_VENDOR1_REQ2_VERSION_3_20; 9014 default: 9015 return WMI_VENDOR1_REQ2_VERSION_3_00; 9016 } 9017 } 9018 9019 /** 9020 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9021 * requirement1 version to target vendor1 requirement1 version 9022 * @vendor1_req1_ver: Host vendor1 requirement1 version 9023 * 9024 * Return: Target vendor1 requirement1 version 9025 */ 9026 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9027 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9028 { 9029 switch (vendor1_req1_ver) { 9030 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9031 return WMI_VENDOR1_REQ1_VERSION_3_00; 9032 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9033 return WMI_VENDOR1_REQ1_VERSION_3_01; 9034 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9035 return WMI_VENDOR1_REQ1_VERSION_3_20; 9036 default: 9037 return WMI_VENDOR1_REQ1_VERSION_3_00; 9038 } 9039 } 9040 9041 /** 9042 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9043 * target wifi standard 9044 * @wifi_standard: Host wifi standard 9045 * 9046 * Return: Target wifi standard 9047 */ 9048 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9049 WMI_HOST_WIFI_STANDARD wifi_standard) 9050 { 9051 switch (wifi_standard) { 9052 case WMI_HOST_WIFI_STANDARD_4: 9053 return WMI_WIFI_STANDARD_4; 9054 case WMI_HOST_WIFI_STANDARD_5: 9055 return WMI_WIFI_STANDARD_5; 9056 case WMI_HOST_WIFI_STANDARD_6: 9057 return WMI_WIFI_STANDARD_6; 9058 case WMI_HOST_WIFI_STANDARD_6E: 9059 return WMI_WIFI_STANDARD_6E; 9060 case WMI_HOST_WIFI_STANDARD_7: 9061 return WMI_WIFI_STANDARD_7; 9062 default: 9063 return WMI_WIFI_STANDARD_4; 9064 } 9065 } 9066 9067 /** 9068 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9069 * target band concurrency 9070 * @band_concurrency: Host Band concurrency 9071 * 9072 * Return: Target band concurrency 9073 */ 9074 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9075 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9076 { 9077 switch (band_concurrency) { 9078 case WMI_HOST_BAND_CONCURRENCY_DBS: 9079 return WMI_HOST_DBS; 9080 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9081 return WMI_HOST_DBS_SBS; 9082 default: 9083 return 0; 9084 } 9085 } 9086 9087 /** 9088 * convert_host_to_target_num_antennas() -Convert host num antennas to 9089 * target num antennas 9090 * @num_antennas: Host num antennas 9091 * 9092 * Return: Target num antennas 9093 */ 9094 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9095 WMI_HOST_NUM_ANTENNAS num_antennas) 9096 { 9097 switch (num_antennas) { 9098 case WMI_HOST_SISO: 9099 return WMI_SISO; 9100 case WMI_HOST_MIMO_2X2: 9101 return WMI_MIMO_2X2; 9102 default: 9103 return WMI_SISO; 9104 } 9105 } 9106 9107 /** 9108 * copy_feature_set_info() -Copy feaure set info from host to target 9109 * @feature_set_bitmap: Target feature set pointer 9110 * @feature_set: Host feature set structure 9111 * 9112 * Return: None 9113 */ 9114 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9115 struct target_feature_set *feature_set) 9116 { 9117 WMI_NUM_ANTENNAS num_antennas; 9118 WMI_BAND_CONCURRENCY band_concurrency; 9119 WMI_WIFI_STANDARD wifi_standard; 9120 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9121 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9122 9123 num_antennas = convert_host_to_target_num_antennas( 9124 feature_set->num_antennas); 9125 band_concurrency = convert_host_to_target_band_concurrency( 9126 feature_set->concurrency_support); 9127 wifi_standard = convert_host_to_target_wifi_standard( 9128 feature_set->wifi_standard); 9129 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9130 feature_set->vendor_req_1_version); 9131 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9132 feature_set->vendor_req_2_version); 9133 9134 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9135 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9136 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9137 feature_set->pno_in_unassoc_state); 9138 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9139 feature_set->pno_in_assoc_state); 9140 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9141 feature_set->enable_twt); 9142 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9143 feature_set->enable_twt_requester); 9144 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9145 feature_set->enable_twt_broadcast); 9146 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9147 feature_set->enable_twt_flexible); 9148 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9149 feature_set->enable_wifi_optimizer); 9150 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9151 feature_set->enable_rfc835); 9152 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9153 feature_set->sap_5g_supported); 9154 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9155 feature_set->sap_6g_supported); 9156 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9157 feature_set->sap_max_num_clients); 9158 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9159 feature_set_bitmap, 9160 feature_set->set_country_code_hal_supported); 9161 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9162 feature_set_bitmap, 9163 feature_set->get_valid_channel_supported); 9164 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9165 feature_set->supported_dot11mode); 9166 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9167 feature_set->sap_wpa3_support); 9168 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9169 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9170 feature_set_bitmap, 9171 feature_set->roaming_high_cu_roam_trigger); 9172 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9173 feature_set_bitmap, 9174 feature_set->roaming_emergency_trigger); 9175 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9176 feature_set->roaming_btm_trihgger); 9177 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9178 feature_set->roaming_idle_trigger); 9179 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9180 feature_set->roaming_wtc_trigger); 9181 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9182 feature_set->roaming_btcoex_trigger); 9183 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9184 feature_set->roaming_btw_wpa_wpa2); 9185 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9186 feature_set_bitmap, 9187 feature_set->roaming_manage_chan_list_api); 9188 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9189 feature_set->roaming_adaptive_11r); 9190 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9191 feature_set->roaming_ctrl_api_get_set); 9192 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9193 feature_set->roaming_ctrl_api_reassoc); 9194 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9195 feature_set->roaming_ctrl_get_cu); 9196 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9197 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9198 feature_set_bitmap, 9199 feature_set->assurance_disconnect_reason_api); 9200 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9201 feature_set->frame_pcap_log_mgmt); 9202 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9203 feature_set->frame_pcap_log_ctrl); 9204 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9205 feature_set->frame_pcap_log_data); 9206 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9207 feature_set->security_wpa3_sae_h2e); 9208 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9209 feature_set->security_wpa3_sae_ft); 9210 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9211 feature_set_bitmap, 9212 feature_set->security_wpa3_enterp_suitb); 9213 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9214 feature_set_bitmap, 9215 feature_set->security_wpa3_enterp_suitb_192bit); 9216 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9217 feature_set->security_fills_sha_256); 9218 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9219 feature_set->security_fills_sha_384); 9220 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9221 feature_set->security_fills_sha_256_FT); 9222 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9223 feature_set->security_fills_sha_384_FT); 9224 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9225 feature_set->security_enhanced_open); 9226 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9227 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9228 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9229 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9230 feature_set->enable_tdls_offchannel); 9231 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9232 feature_set->enable_tdls_capability_enhance); 9233 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9234 feature_set->max_tdls_peers); 9235 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9236 feature_set->sta_dual_p2p_support); 9237 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9238 feature_set_bitmap, 9239 feature_set->peer_bigdata_getbssinfo_support); 9240 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9241 feature_set_bitmap, 9242 feature_set->peer_bigdata_assocreject_info_support); 9243 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9244 feature_set_bitmap, 9245 feature_set->peer_getstainfo_support); 9246 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9247 feature_set->feature_set_version); 9248 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9249 } 9250 9251 /** 9252 * feature_set_cmd_send_tlv() -Send feature set command 9253 * @wmi_handle: WMI handle 9254 * @feature_set: Feature set structure 9255 * 9256 * Return: QDF_STATUS_SUCCESS on success else reurn failure 9257 */ 9258 static QDF_STATUS feature_set_cmd_send_tlv( 9259 struct wmi_unified *wmi_handle, 9260 struct target_feature_set *feature_set) 9261 { 9262 wmi_pdev_featureset_cmd_fixed_param *cmd; 9263 wmi_buf_t buf; 9264 uint16_t len; 9265 QDF_STATUS ret; 9266 uint8_t *buf_ptr; 9267 uint32_t *feature_set_bitmap; 9268 9269 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9270 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9271 buf = wmi_buf_alloc(wmi_handle, len); 9272 9273 if (!buf) 9274 return QDF_STATUS_E_NOMEM; 9275 9276 wmi_debug("Send feature set param"); 9277 9278 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9279 9280 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9281 9282 WMITLV_SET_HDR(&cmd->tlv_header, 9283 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9284 WMITLV_GET_STRUCT_TLVLEN( 9285 wmi_pdev_featureset_cmd_fixed_param)); 9286 9287 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9288 WMI_TLV_HDR_SIZE); 9289 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9290 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9291 copy_feature_set_info(feature_set_bitmap, feature_set); 9292 9293 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9294 9295 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9296 WMI_PDEV_FEATURESET_CMDID); 9297 if (QDF_IS_STATUS_ERROR(ret)) 9298 wmi_buf_free(buf); 9299 9300 return ret; 9301 } 9302 #endif 9303 9304 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9305 * @wmi_handle: pointer to wmi handle 9306 * @buf_ptr: pointer to current position in init command buffer 9307 * @len: pointer to length. This will be updated with current length of cmd 9308 * @param: point host parameters for init command 9309 * 9310 * Return: Updated pointer of buf_ptr. 9311 */ 9312 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9313 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9314 { 9315 uint16_t idx; 9316 9317 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9318 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9319 wmi_pdev_band_to_mac *band_to_mac; 9320 9321 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9322 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9323 sizeof(wmi_resource_config) + 9324 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9325 sizeof(wlan_host_memory_chunk))); 9326 9327 WMITLV_SET_HDR(&hw_mode->tlv_header, 9328 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9329 (WMITLV_GET_STRUCT_TLVLEN 9330 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9331 9332 hw_mode->hw_mode_index = param->hw_mode_id; 9333 hw_mode->num_band_to_mac = param->num_band_to_mac; 9334 9335 buf_ptr = (uint8_t *) (hw_mode + 1); 9336 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9337 WMI_TLV_HDR_SIZE); 9338 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9339 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9340 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9341 WMITLV_GET_STRUCT_TLVLEN 9342 (wmi_pdev_band_to_mac)); 9343 band_to_mac[idx].pdev_id = 9344 wmi_handle->ops->convert_pdev_id_host_to_target( 9345 wmi_handle, 9346 param->band_to_mac[idx].pdev_id); 9347 band_to_mac[idx].start_freq = 9348 param->band_to_mac[idx].start_freq; 9349 band_to_mac[idx].end_freq = 9350 param->band_to_mac[idx].end_freq; 9351 } 9352 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9353 (param->num_band_to_mac * 9354 sizeof(wmi_pdev_band_to_mac)) + 9355 WMI_TLV_HDR_SIZE; 9356 9357 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9358 (param->num_band_to_mac * 9359 sizeof(wmi_pdev_band_to_mac))); 9360 } 9361 9362 return buf_ptr; 9363 } 9364 9365 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9366 wmi_init_cmd_fixed_param *cmd) 9367 { 9368 int num_allowlist; 9369 wmi_abi_version my_vers; 9370 9371 num_allowlist = sizeof(version_whitelist) / 9372 sizeof(wmi_whitelist_version_info); 9373 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9374 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9375 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9376 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9377 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9378 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9379 9380 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9381 &my_vers, 9382 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9383 &cmd->host_abi_vers); 9384 9385 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9386 __func__, 9387 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9388 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9389 cmd->host_abi_vers.abi_version_ns_0, 9390 cmd->host_abi_vers.abi_version_ns_1, 9391 cmd->host_abi_vers.abi_version_ns_2, 9392 cmd->host_abi_vers.abi_version_ns_3); 9393 9394 /* Save version sent from host - 9395 * Will be used to check ready event 9396 */ 9397 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9398 sizeof(wmi_abi_version)); 9399 } 9400 9401 /* 9402 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9403 * @wmi_handle: Pointer to WMi handle 9404 * @ie_data: Pointer for ie data 9405 * 9406 * This function sends action frame tb ppdu cfg to FW 9407 * 9408 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9409 * 9410 */ 9411 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9412 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9413 { 9414 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9415 wmi_buf_t buf; 9416 uint8_t *buf_ptr; 9417 uint32_t len, frm_len_aligned; 9418 QDF_STATUS ret; 9419 9420 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9421 /* Allocate memory for the WMI command */ 9422 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9423 9424 buf = wmi_buf_alloc(wmi_handle, len); 9425 if (!buf) 9426 return QDF_STATUS_E_NOMEM; 9427 9428 buf_ptr = wmi_buf_data(buf); 9429 qdf_mem_zero(buf_ptr, len); 9430 9431 /* Populate the WMI command */ 9432 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9433 9434 WMITLV_SET_HDR(&cmd->tlv_header, 9435 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9436 WMITLV_GET_STRUCT_TLVLEN( 9437 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9438 cmd->enable = cfg_msg->cfg; 9439 cmd->data_len = cfg_msg->frm_len; 9440 9441 buf_ptr += sizeof(*cmd); 9442 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9443 buf_ptr += WMI_TLV_HDR_SIZE; 9444 9445 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9446 9447 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9448 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9449 if (QDF_IS_STATUS_ERROR(ret)) { 9450 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9451 wmi_buf_free(buf); 9452 } 9453 9454 return ret; 9455 } 9456 9457 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9458 { 9459 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9460 wmi_service_ready_event_fixed_param *ev; 9461 9462 9463 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9464 9465 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9466 if (!ev) 9467 return QDF_STATUS_E_FAILURE; 9468 9469 /*Save fw version from service ready message */ 9470 /*This will be used while sending INIT message */ 9471 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9472 sizeof(wmi_handle->fw_abi_version)); 9473 9474 return QDF_STATUS_SUCCESS; 9475 } 9476 9477 /** 9478 * wmi_unified_save_fw_version_cmd() - save fw version 9479 * @wmi_handle: pointer to wmi handle 9480 * @res_cfg: resource config 9481 * @num_mem_chunks: no of mem chunck 9482 * @mem_chunk: pointer to mem chunck structure 9483 * 9484 * This function sends IE information to firmware 9485 * 9486 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9487 * 9488 */ 9489 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9490 void *evt_buf) 9491 { 9492 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9493 wmi_ready_event_fixed_param *ev = NULL; 9494 9495 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9496 ev = param_buf->fixed_param; 9497 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9498 &wmi_handle->final_abi_vers, 9499 &ev->fw_abi_vers)) { 9500 /* 9501 * Error: Our host version and the given firmware version 9502 * are incompatible. 9503 **/ 9504 wmi_debug("Error: Incompatible WMI version." 9505 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9506 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9507 abi_version_0), 9508 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9509 abi_version_0), 9510 wmi_handle->final_abi_vers.abi_version_ns_0, 9511 wmi_handle->final_abi_vers.abi_version_ns_1, 9512 wmi_handle->final_abi_vers.abi_version_ns_2, 9513 wmi_handle->final_abi_vers.abi_version_ns_3, 9514 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9515 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9516 ev->fw_abi_vers.abi_version_ns_0, 9517 ev->fw_abi_vers.abi_version_ns_1, 9518 ev->fw_abi_vers.abi_version_ns_2, 9519 ev->fw_abi_vers.abi_version_ns_3); 9520 9521 return QDF_STATUS_E_FAILURE; 9522 } 9523 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9524 sizeof(wmi_abi_version)); 9525 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9526 sizeof(wmi_abi_version)); 9527 9528 return QDF_STATUS_SUCCESS; 9529 } 9530 9531 /** 9532 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9533 * @handle: wmi handle 9534 * @event: Event received from FW 9535 * @len: Length of the event 9536 * 9537 * Enables the low frequency events and disables the high frequency 9538 * events. Bit 17 indicates if the event if low/high frequency. 9539 * 1 - high frequency, 0 - low frequency 9540 * 9541 * Return: 0 on successfully enabling/disabling the events 9542 */ 9543 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9544 uint8_t *event, 9545 uint32_t len) 9546 { 9547 uint32_t num_of_diag_events_logs; 9548 wmi_diag_event_log_config_fixed_param *cmd; 9549 wmi_buf_t buf; 9550 uint8_t *buf_ptr; 9551 uint32_t *cmd_args, *evt_args; 9552 uint32_t buf_len, i; 9553 9554 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9555 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9556 9557 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9558 9559 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9560 if (!param_buf) { 9561 wmi_err("Invalid log supported event buffer"); 9562 return QDF_STATUS_E_INVAL; 9563 } 9564 wmi_event = param_buf->fixed_param; 9565 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9566 9567 if (num_of_diag_events_logs > 9568 param_buf->num_diag_events_logs_list) { 9569 wmi_err("message number of events %d is more than tlv hdr content %d", 9570 num_of_diag_events_logs, 9571 param_buf->num_diag_events_logs_list); 9572 return QDF_STATUS_E_INVAL; 9573 } 9574 9575 evt_args = param_buf->diag_events_logs_list; 9576 if (!evt_args) { 9577 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9578 num_of_diag_events_logs); 9579 return QDF_STATUS_E_INVAL; 9580 } 9581 9582 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9583 9584 /* Free any previous allocation */ 9585 if (wmi_handle->events_logs_list) { 9586 qdf_mem_free(wmi_handle->events_logs_list); 9587 wmi_handle->events_logs_list = NULL; 9588 } 9589 9590 if (num_of_diag_events_logs > 9591 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9592 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9593 QDF_ASSERT(0); 9594 return QDF_STATUS_E_INVAL; 9595 } 9596 /* Store the event list for run time enable/disable */ 9597 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9598 sizeof(uint32_t)); 9599 if (!wmi_handle->events_logs_list) 9600 return QDF_STATUS_E_NOMEM; 9601 9602 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9603 9604 /* Prepare the send buffer */ 9605 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9606 (num_of_diag_events_logs * sizeof(uint32_t)); 9607 9608 buf = wmi_buf_alloc(wmi_handle, buf_len); 9609 if (!buf) { 9610 qdf_mem_free(wmi_handle->events_logs_list); 9611 wmi_handle->events_logs_list = NULL; 9612 return QDF_STATUS_E_NOMEM; 9613 } 9614 9615 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9616 buf_ptr = (uint8_t *) cmd; 9617 9618 WMITLV_SET_HDR(&cmd->tlv_header, 9619 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9620 WMITLV_GET_STRUCT_TLVLEN( 9621 wmi_diag_event_log_config_fixed_param)); 9622 9623 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9624 9625 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9626 9627 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9628 (num_of_diag_events_logs * sizeof(uint32_t))); 9629 9630 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9631 9632 /* Populate the events */ 9633 for (i = 0; i < num_of_diag_events_logs; i++) { 9634 /* Low freq (0) - Enable (1) the event 9635 * High freq (1) - Disable (0) the event 9636 */ 9637 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9638 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9639 /* Set the event ID */ 9640 WMI_DIAG_ID_SET(cmd_args[i], 9641 WMI_DIAG_ID_GET(evt_args[i])); 9642 /* Set the type */ 9643 WMI_DIAG_TYPE_SET(cmd_args[i], 9644 WMI_DIAG_TYPE_GET(evt_args[i])); 9645 /* Storing the event/log list in WMI */ 9646 wmi_handle->events_logs_list[i] = evt_args[i]; 9647 } 9648 9649 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9650 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9651 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9652 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9653 wmi_buf_free(buf); 9654 /* Not clearing events_logs_list, though wmi cmd failed. 9655 * Host can still have this list 9656 */ 9657 return QDF_STATUS_E_INVAL; 9658 } 9659 9660 return 0; 9661 } 9662 9663 /** 9664 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9665 * @wmi_handle: wmi handle 9666 * @start_log: Start logging related parameters 9667 * 9668 * Send the command to the FW based on which specific logging of diag 9669 * event/log id can be started/stopped 9670 * 9671 * Return: None 9672 */ 9673 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9674 struct wmi_wifi_start_log *start_log) 9675 { 9676 wmi_diag_event_log_config_fixed_param *cmd; 9677 wmi_buf_t buf; 9678 uint8_t *buf_ptr; 9679 uint32_t len, count, log_level, i; 9680 uint32_t *cmd_args; 9681 uint32_t total_len; 9682 count = 0; 9683 9684 if (!wmi_handle->events_logs_list) { 9685 wmi_debug("Not received event/log list from FW, yet"); 9686 return QDF_STATUS_E_NOMEM; 9687 } 9688 /* total_len stores the number of events where BITS 17 and 18 are set. 9689 * i.e., events of high frequency (17) and for extended debugging (18) 9690 */ 9691 total_len = 0; 9692 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9693 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 9694 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 9695 total_len++; 9696 } 9697 9698 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9699 (total_len * sizeof(uint32_t)); 9700 9701 buf = wmi_buf_alloc(wmi_handle, len); 9702 if (!buf) 9703 return QDF_STATUS_E_NOMEM; 9704 9705 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9706 buf_ptr = (uint8_t *) cmd; 9707 9708 WMITLV_SET_HDR(&cmd->tlv_header, 9709 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9710 WMITLV_GET_STRUCT_TLVLEN( 9711 wmi_diag_event_log_config_fixed_param)); 9712 9713 cmd->num_of_diag_events_logs = total_len; 9714 9715 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9716 9717 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9718 (total_len * sizeof(uint32_t))); 9719 9720 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9721 9722 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 9723 log_level = 1; 9724 else 9725 log_level = 0; 9726 9727 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 9728 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9729 uint32_t val = wmi_handle->events_logs_list[i]; 9730 if ((WMI_DIAG_FREQUENCY_GET(val)) && 9731 (WMI_DIAG_EXT_FEATURE_GET(val))) { 9732 9733 WMI_DIAG_ID_SET(cmd_args[count], 9734 WMI_DIAG_ID_GET(val)); 9735 WMI_DIAG_TYPE_SET(cmd_args[count], 9736 WMI_DIAG_TYPE_GET(val)); 9737 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 9738 log_level); 9739 wmi_debug("Idx:%d, val:%x", i, val); 9740 count++; 9741 } 9742 } 9743 9744 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9745 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9746 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9747 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9748 wmi_buf_free(buf); 9749 return QDF_STATUS_E_INVAL; 9750 } 9751 9752 return QDF_STATUS_SUCCESS; 9753 } 9754 9755 /** 9756 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 9757 * @wmi_handle: WMI handle 9758 * 9759 * This function is used to send the flush command to the FW, 9760 * that will flush the fw logs that are residue in the FW 9761 * 9762 * Return: None 9763 */ 9764 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9765 { 9766 wmi_debug_mesg_flush_fixed_param *cmd; 9767 wmi_buf_t buf; 9768 int len = sizeof(*cmd); 9769 QDF_STATUS ret; 9770 9771 buf = wmi_buf_alloc(wmi_handle, len); 9772 if (!buf) 9773 return QDF_STATUS_E_NOMEM; 9774 9775 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 9776 WMITLV_SET_HDR(&cmd->tlv_header, 9777 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 9778 WMITLV_GET_STRUCT_TLVLEN( 9779 wmi_debug_mesg_flush_fixed_param)); 9780 cmd->reserved0 = 0; 9781 9782 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 9783 ret = wmi_unified_cmd_send(wmi_handle, 9784 buf, 9785 len, 9786 WMI_DEBUG_MESG_FLUSH_CMDID); 9787 if (QDF_IS_STATUS_ERROR(ret)) { 9788 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 9789 wmi_buf_free(buf); 9790 return QDF_STATUS_E_INVAL; 9791 } 9792 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 9793 9794 return ret; 9795 } 9796 9797 #ifdef BIG_ENDIAN_HOST 9798 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9799 /** 9800 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 9801 * @param - fips extend param related parameters 9802 * 9803 * Return: QDF_STATUS - success or error status 9804 */ 9805 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9806 struct fips_extend_params *param) 9807 { 9808 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 9809 int c; 9810 u_int8_t *key_aligned = NULL; 9811 u_int8_t *nonce_iv_aligned = NULL; 9812 u_int8_t *data_aligned = NULL; 9813 int ret = QDF_STATUS_SUCCESS; 9814 9815 /* Assigning unaligned space to copy the key */ 9816 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9817 param->cmd_params.key_len + FIPS_ALIGN); 9818 /* Checking if kmalloc is successful to allocate space */ 9819 if (!key_unaligned) 9820 return QDF_STATUS_E_INVAL; 9821 9822 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 9823 FIPS_ALIGN); 9824 /* Checking if kmalloc is successful to allocate space */ 9825 if (!data_unaligned) { 9826 ret = QDF_STATUS_E_INVAL; 9827 goto fips_align_fail_data; 9828 } 9829 9830 /* Checking if space is aligned */ 9831 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9832 /* align to 4 */ 9833 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9834 FIPS_ALIGN); 9835 } else { 9836 key_aligned = (u_int8_t *)key_unaligned; 9837 } 9838 9839 /* memset and copy content from key to key aligned */ 9840 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 9841 OS_MEMCPY(key_aligned, param->cmd_params.key, 9842 param->cmd_params.key_len); 9843 9844 /* print a hexdump for host debug */ 9845 wmi_debug("Aligned and Copied Key: "); 9846 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9847 key_aligned, param->cmd_params.key_len); 9848 9849 /* Checking of space is aligned */ 9850 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9851 /* align to 4 */ 9852 data_aligned = 9853 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 9854 } else { 9855 data_aligned = (u_int8_t *)data_unaligned; 9856 } 9857 9858 /* memset and copy content from data to data aligned */ 9859 OS_MEMSET(data_aligned, 0, param->data_len); 9860 OS_MEMCPY(data_aligned, param->data, param->data_len); 9861 9862 /* print a hexdump for host debug */ 9863 wmi_debug("\t Properly Aligned and Copied Data: "); 9864 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9865 data_aligned, param->data_len); 9866 9867 /* converting to little Endian */ 9868 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 9869 *((u_int32_t *)key_aligned + c) = 9870 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 9871 } 9872 for (c = 0; c < param->data_len / 4; c++) { 9873 *((u_int32_t *)data_aligned + c) = 9874 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 9875 } 9876 9877 /* update endian data */ 9878 OS_MEMCPY(param->cmd_params.key, key_aligned, 9879 param->cmd_params.key_len); 9880 OS_MEMCPY(param->data, data_aligned, param->data_len); 9881 9882 if (param->cmd_params.nonce_iv_len) { 9883 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9884 param->cmd_params.nonce_iv_len + 9885 FIPS_ALIGN); 9886 9887 /* Checking if kmalloc is successful to allocate space */ 9888 if (!nonce_iv_unaligned) { 9889 ret = QDF_STATUS_E_INVAL; 9890 goto fips_align_fail_nonce_iv; 9891 } 9892 /* Checking if space is aligned */ 9893 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 9894 /* align to 4 */ 9895 nonce_iv_aligned = 9896 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 9897 FIPS_ALIGN); 9898 } else { 9899 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 9900 } 9901 9902 /* memset and copy content from iv to iv aligned */ 9903 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 9904 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 9905 param->cmd_params.nonce_iv_len); 9906 9907 /* print a hexdump for host debug */ 9908 wmi_debug("\t Aligned and Copied Nonce_IV: "); 9909 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9910 nonce_iv_aligned, 9911 param->cmd_params.nonce_iv_len); 9912 9913 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 9914 *((u_int32_t *)nonce_iv_aligned + c) = 9915 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 9916 } 9917 } 9918 9919 /* clean up allocated spaces */ 9920 qdf_mem_free(nonce_iv_unaligned); 9921 nonce_iv_unaligned = NULL; 9922 nonce_iv_aligned = NULL; 9923 9924 fips_align_fail_nonce_iv: 9925 qdf_mem_free(data_unaligned); 9926 data_unaligned = NULL; 9927 data_aligned = NULL; 9928 9929 fips_align_fail_data: 9930 qdf_mem_free(key_unaligned); 9931 key_unaligned = NULL; 9932 key_aligned = NULL; 9933 9934 return ret; 9935 } 9936 #endif 9937 9938 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 9939 struct fips_params *param) 9940 { 9941 unsigned char *key_unaligned, *data_unaligned; 9942 int c; 9943 u_int8_t *key_aligned = NULL; 9944 u_int8_t *data_aligned = NULL; 9945 9946 /* Assigning unaligned space to copy the key */ 9947 key_unaligned = qdf_mem_malloc( 9948 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 9949 data_unaligned = qdf_mem_malloc( 9950 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 9951 9952 /* Checking if kmalloc is successful to allocate space */ 9953 if (!key_unaligned) 9954 return QDF_STATUS_SUCCESS; 9955 /* Checking if space is aligned */ 9956 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9957 /* align to 4 */ 9958 key_aligned = 9959 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9960 FIPS_ALIGN); 9961 } else { 9962 key_aligned = (u_int8_t *)key_unaligned; 9963 } 9964 9965 /* memset and copy content from key to key aligned */ 9966 OS_MEMSET(key_aligned, 0, param->key_len); 9967 OS_MEMCPY(key_aligned, param->key, param->key_len); 9968 9969 /* print a hexdump for host debug */ 9970 print_hex_dump(KERN_DEBUG, 9971 "\t Aligned and Copied Key:@@@@ ", 9972 DUMP_PREFIX_NONE, 9973 16, 1, key_aligned, param->key_len, true); 9974 9975 /* Checking if kmalloc is successful to allocate space */ 9976 if (!data_unaligned) 9977 return QDF_STATUS_SUCCESS; 9978 /* Checking of space is aligned */ 9979 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9980 /* align to 4 */ 9981 data_aligned = 9982 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 9983 FIPS_ALIGN); 9984 } else { 9985 data_aligned = (u_int8_t *)data_unaligned; 9986 } 9987 9988 /* memset and copy content from data to data aligned */ 9989 OS_MEMSET(data_aligned, 0, param->data_len); 9990 OS_MEMCPY(data_aligned, param->data, param->data_len); 9991 9992 /* print a hexdump for host debug */ 9993 print_hex_dump(KERN_DEBUG, 9994 "\t Properly Aligned and Copied Data:@@@@ ", 9995 DUMP_PREFIX_NONE, 9996 16, 1, data_aligned, param->data_len, true); 9997 9998 /* converting to little Endian both key_aligned and 9999 * data_aligned*/ 10000 for (c = 0; c < param->key_len/4; c++) { 10001 *((u_int32_t *)key_aligned+c) = 10002 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10003 } 10004 for (c = 0; c < param->data_len/4; c++) { 10005 *((u_int32_t *)data_aligned+c) = 10006 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10007 } 10008 10009 /* update endian data to key and data vectors */ 10010 OS_MEMCPY(param->key, key_aligned, param->key_len); 10011 OS_MEMCPY(param->data, data_aligned, param->data_len); 10012 10013 /* clean up allocated spaces */ 10014 qdf_mem_free(key_unaligned); 10015 key_unaligned = NULL; 10016 key_aligned = NULL; 10017 10018 qdf_mem_free(data_unaligned); 10019 data_unaligned = NULL; 10020 data_aligned = NULL; 10021 10022 return QDF_STATUS_SUCCESS; 10023 } 10024 #else 10025 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10026 /** 10027 * fips_extend_align_data_be() - DUMMY for LE platform 10028 * 10029 * Return: QDF_STATUS - success 10030 */ 10031 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10032 struct fips_extend_params *param) 10033 { 10034 return QDF_STATUS_SUCCESS; 10035 } 10036 #endif 10037 10038 /** 10039 * fips_align_data_be() - DUMMY for LE platform 10040 * 10041 * Return: QDF_STATUS - success 10042 */ 10043 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10044 struct fips_params *param) 10045 { 10046 return QDF_STATUS_SUCCESS; 10047 } 10048 #endif 10049 10050 #ifdef WLAN_FEATURE_DISA 10051 /** 10052 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 10053 * @wmi_handle: wmi handle 10054 * @params: encrypt/decrypt params 10055 * 10056 * Return: QDF_STATUS_SUCCESS for success or error code 10057 */ 10058 static QDF_STATUS 10059 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10060 struct disa_encrypt_decrypt_req_params 10061 *encrypt_decrypt_params) 10062 { 10063 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10064 wmi_buf_t wmi_buf; 10065 uint8_t *buf_ptr; 10066 QDF_STATUS ret; 10067 uint32_t len; 10068 10069 wmi_debug("Send encrypt decrypt cmd"); 10070 10071 len = sizeof(*cmd) + 10072 encrypt_decrypt_params->data_len + 10073 WMI_TLV_HDR_SIZE; 10074 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10075 if (!wmi_buf) 10076 return QDF_STATUS_E_NOMEM; 10077 10078 buf_ptr = wmi_buf_data(wmi_buf); 10079 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10080 10081 WMITLV_SET_HDR(&cmd->tlv_header, 10082 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10083 WMITLV_GET_STRUCT_TLVLEN( 10084 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10085 10086 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10087 cmd->key_flag = encrypt_decrypt_params->key_flag; 10088 cmd->key_idx = encrypt_decrypt_params->key_idx; 10089 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10090 cmd->key_len = encrypt_decrypt_params->key_len; 10091 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10092 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10093 10094 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10095 encrypt_decrypt_params->key_len); 10096 10097 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10098 MAX_MAC_HEADER_LEN); 10099 10100 cmd->data_len = encrypt_decrypt_params->data_len; 10101 10102 if (cmd->data_len) { 10103 buf_ptr += sizeof(*cmd); 10104 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10105 roundup(encrypt_decrypt_params->data_len, 10106 sizeof(uint32_t))); 10107 buf_ptr += WMI_TLV_HDR_SIZE; 10108 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10109 encrypt_decrypt_params->data_len); 10110 } 10111 10112 /* This conversion is to facilitate data to FW in little endian */ 10113 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10114 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10115 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10116 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10117 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10118 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10119 10120 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10121 ret = wmi_unified_cmd_send(wmi_handle, 10122 wmi_buf, len, 10123 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10124 if (QDF_IS_STATUS_ERROR(ret)) { 10125 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10126 wmi_buf_free(wmi_buf); 10127 } 10128 10129 return ret; 10130 } 10131 #endif /* WLAN_FEATURE_DISA */ 10132 10133 /** 10134 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10135 * @wmi_handle: wmi handle 10136 * @param: pointer to hold pdev fips param 10137 * 10138 * Return: 0 for success or error code 10139 */ 10140 static QDF_STATUS 10141 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10142 struct fips_params *param) 10143 { 10144 wmi_pdev_fips_cmd_fixed_param *cmd; 10145 wmi_buf_t buf; 10146 uint8_t *buf_ptr; 10147 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10148 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10149 10150 /* Length TLV placeholder for array of bytes */ 10151 len += WMI_TLV_HDR_SIZE; 10152 if (param->data_len) 10153 len += (param->data_len*sizeof(uint8_t)); 10154 10155 /* 10156 * Data length must be multiples of 16 bytes - checked against 0xF - 10157 * and must be less than WMI_SVC_MSG_SIZE - static size of 10158 * wmi_pdev_fips_cmd structure 10159 */ 10160 10161 /* do sanity on the input */ 10162 if (!(((param->data_len & 0xF) == 0) && 10163 ((param->data_len > 0) && 10164 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10165 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10166 return QDF_STATUS_E_INVAL; 10167 } 10168 10169 buf = wmi_buf_alloc(wmi_handle, len); 10170 if (!buf) 10171 return QDF_STATUS_E_FAILURE; 10172 10173 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10174 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10175 WMITLV_SET_HDR(&cmd->tlv_header, 10176 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10177 WMITLV_GET_STRUCT_TLVLEN 10178 (wmi_pdev_fips_cmd_fixed_param)); 10179 10180 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10181 wmi_handle, 10182 param->pdev_id); 10183 if (param->key && param->data) { 10184 cmd->key_len = param->key_len; 10185 cmd->data_len = param->data_len; 10186 cmd->fips_cmd = !!(param->op); 10187 10188 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10189 return QDF_STATUS_E_FAILURE; 10190 10191 qdf_mem_copy(cmd->key, param->key, param->key_len); 10192 10193 if (param->mode == FIPS_ENGINE_AES_CTR || 10194 param->mode == FIPS_ENGINE_AES_MIC) { 10195 cmd->mode = param->mode; 10196 } else { 10197 cmd->mode = FIPS_ENGINE_AES_CTR; 10198 } 10199 qdf_print("Key len = %d, Data len = %d", 10200 cmd->key_len, cmd->data_len); 10201 10202 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10203 cmd->key, cmd->key_len, true); 10204 buf_ptr += sizeof(*cmd); 10205 10206 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10207 10208 buf_ptr += WMI_TLV_HDR_SIZE; 10209 if (param->data_len) 10210 qdf_mem_copy(buf_ptr, 10211 (uint8_t *) param->data, param->data_len); 10212 10213 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10214 16, 1, buf_ptr, cmd->data_len, true); 10215 10216 buf_ptr += param->data_len; 10217 10218 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10219 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10220 WMI_PDEV_FIPS_CMDID); 10221 qdf_print("%s return value %d", __func__, retval); 10222 } else { 10223 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10224 wmi_buf_free(buf); 10225 retval = -QDF_STATUS_E_BADMSG; 10226 } 10227 10228 return retval; 10229 } 10230 10231 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10232 /** 10233 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10234 * @wmi_handle: wmi handle 10235 * @param: pointer to hold pdev fips param 10236 * 10237 * Return: 0 for success or error code 10238 */ 10239 static QDF_STATUS 10240 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10241 struct fips_extend_params *param) 10242 { 10243 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10244 wmi_buf_t buf; 10245 uint8_t *buf_ptr; 10246 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10247 uint32_t data_len_aligned; 10248 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10249 10250 len += WMI_TLV_HDR_SIZE; 10251 if (param->frag_idx == 0) 10252 len += sizeof(wmi_fips_extend_cmd_init_params); 10253 10254 /* Length TLV placeholder for array of bytes */ 10255 len += WMI_TLV_HDR_SIZE; 10256 if (param->data_len) { 10257 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10258 len += (data_len_aligned * sizeof(uint8_t)); 10259 } 10260 10261 buf = wmi_buf_alloc(wmi_handle, len); 10262 if (!buf) 10263 return QDF_STATUS_E_FAILURE; 10264 10265 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10266 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10267 WMITLV_SET_HDR(&cmd->tlv_header, 10268 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10269 WMITLV_GET_STRUCT_TLVLEN 10270 (wmi_pdev_fips_extend_cmd_fixed_param)); 10271 10272 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10273 wmi_handle, 10274 param->pdev_id); 10275 10276 cmd->fips_cookie = param->cookie; 10277 cmd->frag_idx = param->frag_idx; 10278 cmd->more_bit = param->more_bit; 10279 cmd->data_len = param->data_len; 10280 10281 if (fips_extend_align_data_be(wmi_handle, param) != 10282 QDF_STATUS_SUCCESS) { 10283 wmi_buf_free(buf); 10284 return QDF_STATUS_E_FAILURE; 10285 } 10286 10287 buf_ptr = (uint8_t *)(cmd + 1); 10288 if (cmd->frag_idx == 0) { 10289 wmi_fips_extend_cmd_init_params *cmd_params; 10290 10291 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10292 sizeof(wmi_fips_extend_cmd_init_params)); 10293 buf_ptr += WMI_TLV_HDR_SIZE; 10294 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10295 WMITLV_SET_HDR(buf_ptr, 10296 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10297 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10298 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10299 cmd_params->key_cipher = param->cmd_params.key_cipher; 10300 cmd_params->key_len = param->cmd_params.key_len; 10301 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10302 cmd_params->tag_len = param->cmd_params.tag_len; 10303 cmd_params->aad_len = param->cmd_params.aad_len; 10304 cmd_params->payload_len = param->cmd_params.payload_len; 10305 10306 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10307 param->cmd_params.key_len); 10308 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10309 param->cmd_params.nonce_iv_len); 10310 10311 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10312 cmd_params->key_len, cmd_params->nonce_iv_len, 10313 cmd_params->tag_len, cmd_params->aad_len, 10314 cmd_params->payload_len); 10315 10316 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10317 } else { 10318 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10319 buf_ptr += WMI_TLV_HDR_SIZE; 10320 } 10321 10322 if (param->data_len && param->data) { 10323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10324 data_len_aligned); 10325 10326 buf_ptr += WMI_TLV_HDR_SIZE; 10327 if (param->data_len) 10328 qdf_mem_copy(buf_ptr, 10329 (uint8_t *)param->data, param->data_len); 10330 10331 wmi_debug("Data: "); 10332 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10333 buf_ptr, cmd->data_len); 10334 10335 if (param->data_len) 10336 buf_ptr += param->data_len; 10337 } else { 10338 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10339 buf_ptr += WMI_TLV_HDR_SIZE; 10340 } 10341 10342 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10343 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10344 WMI_PDEV_FIPS_EXTEND_CMDID); 10345 10346 if (retval) { 10347 wmi_err("Failed to send FIPS cmd"); 10348 wmi_buf_free(buf); 10349 } 10350 10351 return retval; 10352 } 10353 10354 /** 10355 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10356 * @wmi_handle: wmi handle 10357 * @param: pointer to hold pdev fips param 10358 * 10359 * Return: 0 for success or error code 10360 */ 10361 static QDF_STATUS 10362 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10363 struct fips_mode_set_params *param) 10364 { 10365 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10366 wmi_buf_t buf; 10367 uint8_t *buf_ptr; 10368 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10369 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10370 10371 buf = wmi_buf_alloc(wmi_handle, len); 10372 if (!buf) 10373 return QDF_STATUS_E_FAILURE; 10374 10375 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10376 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10377 WMITLV_SET_HDR(&cmd->tlv_header, 10378 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10379 WMITLV_GET_STRUCT_TLVLEN 10380 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10381 10382 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10383 wmi_handle, 10384 param->pdev_id); 10385 10386 cmd->fips_mode_set = param->mode; 10387 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10388 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10389 WMI_PDEV_FIPS_MODE_SET_CMDID); 10390 if (retval) { 10391 wmi_err("Failed to send FIPS mode enable cmd"); 10392 wmi_buf_free(buf); 10393 } 10394 return retval; 10395 } 10396 #endif 10397 10398 /** 10399 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10400 * to fw 10401 * @wmi_handle: wmi handle 10402 * @param: pointer to wlan profile param 10403 * 10404 * Return: 0 for success or error code 10405 */ 10406 static QDF_STATUS 10407 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10408 struct wlan_profile_params *param) 10409 { 10410 wmi_buf_t buf; 10411 uint16_t len; 10412 QDF_STATUS ret; 10413 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10414 10415 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10416 buf = wmi_buf_alloc(wmi_handle, len); 10417 if (!buf) { 10418 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10419 return QDF_STATUS_E_NOMEM; 10420 } 10421 10422 profile_enable_cmd = 10423 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10424 wmi_buf_data(buf); 10425 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10426 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10427 WMITLV_GET_STRUCT_TLVLEN 10428 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10429 10430 profile_enable_cmd->profile_id = param->profile_id; 10431 profile_enable_cmd->enable = param->enable; 10432 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10433 NO_SESSION, 0); 10434 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10435 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10436 if (ret) { 10437 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10438 wmi_buf_free(buf); 10439 } 10440 return ret; 10441 } 10442 10443 /** 10444 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10445 * to fw 10446 * @wmi_handle: wmi handle 10447 * @param: pointer to wlan profile param 10448 * 10449 * Return: 0 for success or error code 10450 */ 10451 static QDF_STATUS 10452 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10453 struct wlan_profile_params *param) 10454 { 10455 wmi_buf_t buf; 10456 uint16_t len; 10457 QDF_STATUS ret; 10458 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10459 10460 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10461 buf = wmi_buf_alloc(wmi_handle, len); 10462 if (!buf) { 10463 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10464 return QDF_STATUS_E_NOMEM; 10465 } 10466 10467 prof_trig_cmd = 10468 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10469 wmi_buf_data(buf); 10470 10471 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10472 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10473 WMITLV_GET_STRUCT_TLVLEN 10474 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10475 10476 prof_trig_cmd->enable = param->enable; 10477 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10478 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10479 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10480 if (ret) { 10481 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10482 wmi_buf_free(buf); 10483 } 10484 return ret; 10485 } 10486 10487 /** 10488 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10489 * to fw 10490 * @wmi_handle: wmi handle 10491 * @param: pointer to wlan profile param 10492 * 10493 * Return: 0 for success or error code 10494 */ 10495 static QDF_STATUS 10496 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10497 struct wlan_profile_params *param) 10498 { 10499 wmi_buf_t buf; 10500 int32_t len = 0; 10501 QDF_STATUS ret; 10502 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10503 10504 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10505 buf = wmi_buf_alloc(wmi_handle, len); 10506 if (!buf) { 10507 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10508 return QDF_STATUS_E_NOMEM; 10509 } 10510 10511 hist_intvl_cmd = 10512 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10513 wmi_buf_data(buf); 10514 10515 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10516 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10517 WMITLV_GET_STRUCT_TLVLEN 10518 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10519 10520 hist_intvl_cmd->profile_id = param->profile_id; 10521 hist_intvl_cmd->value = param->enable; 10522 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10523 NO_SESSION, 0); 10524 10525 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10526 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10527 if (ret) { 10528 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10529 wmi_buf_free(buf); 10530 } 10531 return ret; 10532 } 10533 10534 /** 10535 * send_fw_test_cmd_tlv() - send fw test command to fw. 10536 * @wmi_handle: wmi handle 10537 * @wmi_fwtest: fw test command 10538 * 10539 * This function sends fw test command to fw. 10540 * 10541 * Return: CDF STATUS 10542 */ 10543 static 10544 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10545 struct set_fwtest_params *wmi_fwtest) 10546 { 10547 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10548 wmi_buf_t wmi_buf; 10549 uint16_t len; 10550 10551 len = sizeof(*cmd); 10552 10553 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10554 if (!wmi_buf) 10555 return QDF_STATUS_E_NOMEM; 10556 10557 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10558 WMITLV_SET_HDR(&cmd->tlv_header, 10559 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10560 WMITLV_GET_STRUCT_TLVLEN( 10561 wmi_fwtest_set_param_cmd_fixed_param)); 10562 cmd->param_id = wmi_fwtest->arg; 10563 cmd->param_value = wmi_fwtest->value; 10564 10565 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10566 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10567 WMI_FWTEST_CMDID)) { 10568 wmi_err("Failed to send fw test command"); 10569 wmi_buf_free(wmi_buf); 10570 return QDF_STATUS_E_FAILURE; 10571 } 10572 10573 return QDF_STATUS_SUCCESS; 10574 } 10575 10576 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10577 { 10578 uint16_t len = 0; 10579 10580 if (config == WFA_CONFIG_RXNE) 10581 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10582 else 10583 len += WMI_TLV_HDR_SIZE; 10584 10585 if (config == WFA_CONFIG_CSA) 10586 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10587 else 10588 len += WMI_TLV_HDR_SIZE; 10589 10590 if (config == WFA_CONFIG_OCV) 10591 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10592 else 10593 len += WMI_TLV_HDR_SIZE; 10594 10595 if (config == WFA_CONFIG_SA_QUERY) 10596 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10597 else 10598 len += WMI_TLV_HDR_SIZE; 10599 10600 return len; 10601 } 10602 10603 /** 10604 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10605 * @host_frmtype: Host defined OCV frame type 10606 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10607 * 10608 * This function converts and fills host defined OCV frame type into WMI OCV 10609 * frame type. 10610 * 10611 * Return: CDF STATUS 10612 */ 10613 static QDF_STATUS 10614 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10615 { 10616 switch (host_frmtype) { 10617 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10618 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10619 break; 10620 10621 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10622 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10623 break; 10624 10625 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10626 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10627 break; 10628 10629 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10630 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10631 break; 10632 10633 default: 10634 wmi_err("Invalid command type cmd %d", host_frmtype); 10635 return QDF_STATUS_E_FAILURE; 10636 } 10637 10638 return QDF_STATUS_SUCCESS; 10639 } 10640 10641 /** 10642 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10643 * @wmi_handle: wmi handle 10644 * @wmi_wfatest: wfa test command 10645 * 10646 * This function sends wfa test command to fw. 10647 * 10648 * Return: CDF STATUS 10649 */ 10650 static 10651 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10652 struct set_wfatest_params *wmi_wfatest) 10653 { 10654 wmi_wfa_config_cmd_fixed_param *cmd; 10655 wmi_wfa_config_rsnxe *rxne; 10656 wmi_wfa_config_csa *csa; 10657 wmi_wfa_config_ocv *ocv; 10658 wmi_wfa_config_saquery *saquery; 10659 wmi_buf_t wmi_buf; 10660 uint16_t len = sizeof(*cmd); 10661 uint8_t *buf_ptr; 10662 10663 len += wfa_config_param_len(wmi_wfatest->cmd); 10664 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10665 if (!wmi_buf) 10666 return QDF_STATUS_E_NOMEM; 10667 10668 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10669 WMITLV_SET_HDR(&cmd->tlv_header, 10670 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10671 WMITLV_GET_STRUCT_TLVLEN( 10672 wmi_wfa_config_cmd_fixed_param)); 10673 10674 cmd->vdev_id = wmi_wfatest->vdev_id; 10675 buf_ptr = (uint8_t *)(cmd + 1); 10676 10677 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10678 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10679 sizeof(wmi_wfa_config_rsnxe)); 10680 buf_ptr += WMI_TLV_HDR_SIZE; 10681 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10682 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10683 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10684 rxne->rsnxe_param = wmi_wfatest->value; 10685 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10686 } else { 10687 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10688 buf_ptr += WMI_TLV_HDR_SIZE; 10689 } 10690 10691 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 10692 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10693 sizeof(wmi_wfa_config_csa)); 10694 buf_ptr += WMI_TLV_HDR_SIZE; 10695 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 10696 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 10697 csa = (wmi_wfa_config_csa *)buf_ptr; 10698 csa->ignore_csa = wmi_wfatest->value; 10699 buf_ptr += sizeof(wmi_wfa_config_csa); 10700 } else { 10701 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10702 buf_ptr += WMI_TLV_HDR_SIZE; 10703 } 10704 10705 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 10706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10707 sizeof(wmi_wfa_config_ocv)); 10708 buf_ptr += WMI_TLV_HDR_SIZE; 10709 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 10710 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 10711 ocv = (wmi_wfa_config_ocv *)buf_ptr; 10712 10713 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 10714 &ocv->frame_types)) 10715 goto error; 10716 10717 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 10718 buf_ptr += sizeof(wmi_wfa_config_ocv); 10719 } else { 10720 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10721 buf_ptr += WMI_TLV_HDR_SIZE; 10722 } 10723 10724 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 10725 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10726 sizeof(wmi_wfa_config_saquery)); 10727 buf_ptr += WMI_TLV_HDR_SIZE; 10728 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 10729 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 10730 10731 saquery = (wmi_wfa_config_saquery *)buf_ptr; 10732 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 10733 } else { 10734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10735 buf_ptr += WMI_TLV_HDR_SIZE; 10736 } 10737 10738 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 10739 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10740 WMI_WFA_CONFIG_CMDID)) { 10741 wmi_err("Failed to send wfa test command"); 10742 goto error; 10743 } 10744 10745 return QDF_STATUS_SUCCESS; 10746 10747 error: 10748 wmi_buf_free(wmi_buf); 10749 return QDF_STATUS_E_FAILURE; 10750 } 10751 10752 /** 10753 * send_unit_test_cmd_tlv() - send unit test command to fw. 10754 * @wmi_handle: wmi handle 10755 * @wmi_utest: unit test command 10756 * 10757 * This function send unit test command to fw. 10758 * 10759 * Return: CDF STATUS 10760 */ 10761 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 10762 struct wmi_unit_test_cmd *wmi_utest) 10763 { 10764 wmi_unit_test_cmd_fixed_param *cmd; 10765 wmi_buf_t wmi_buf; 10766 uint8_t *buf_ptr; 10767 int i; 10768 uint16_t len, args_tlv_len; 10769 uint32_t *unit_test_cmd_args; 10770 10771 args_tlv_len = 10772 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 10773 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 10774 10775 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10776 if (!wmi_buf) 10777 return QDF_STATUS_E_NOMEM; 10778 10779 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10780 buf_ptr = (uint8_t *) cmd; 10781 WMITLV_SET_HDR(&cmd->tlv_header, 10782 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 10783 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 10784 cmd->vdev_id = wmi_utest->vdev_id; 10785 cmd->module_id = wmi_utest->module_id; 10786 cmd->num_args = wmi_utest->num_args; 10787 cmd->diag_token = wmi_utest->diag_token; 10788 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 10789 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10790 (wmi_utest->num_args * sizeof(uint32_t))); 10791 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10792 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 10793 cmd->vdev_id, cmd->module_id, cmd->diag_token); 10794 wmi_debug("%d num of args = ", wmi_utest->num_args); 10795 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 10796 unit_test_cmd_args[i] = wmi_utest->args[i]; 10797 wmi_debug("%d,", wmi_utest->args[i]); 10798 } 10799 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 10800 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10801 WMI_UNIT_TEST_CMDID)) { 10802 wmi_err("Failed to send unit test command"); 10803 wmi_buf_free(wmi_buf); 10804 return QDF_STATUS_E_FAILURE; 10805 } 10806 10807 return QDF_STATUS_SUCCESS; 10808 } 10809 10810 /** 10811 * send_power_dbg_cmd_tlv() - send power debug commands 10812 * @wmi_handle: wmi handle 10813 * @param: wmi power debug parameter 10814 * 10815 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 10816 * 10817 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10818 */ 10819 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 10820 struct wmi_power_dbg_params *param) 10821 { 10822 wmi_buf_t buf = NULL; 10823 QDF_STATUS status; 10824 int len, args_tlv_len; 10825 uint8_t *buf_ptr; 10826 uint8_t i; 10827 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 10828 uint32_t *cmd_args; 10829 10830 /* Prepare and send power debug cmd parameters */ 10831 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 10832 len = sizeof(*cmd) + args_tlv_len; 10833 buf = wmi_buf_alloc(wmi_handle, len); 10834 if (!buf) 10835 return QDF_STATUS_E_NOMEM; 10836 10837 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10838 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 10839 WMITLV_SET_HDR(&cmd->tlv_header, 10840 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 10841 WMITLV_GET_STRUCT_TLVLEN 10842 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 10843 10844 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10845 wmi_handle, 10846 param->pdev_id); 10847 cmd->module_id = param->module_id; 10848 cmd->num_args = param->num_args; 10849 buf_ptr += sizeof(*cmd); 10850 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10851 (param->num_args * sizeof(uint32_t))); 10852 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10853 wmi_debug("%d num of args = ", param->num_args); 10854 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 10855 cmd_args[i] = param->args[i]; 10856 wmi_debug("%d,", param->args[i]); 10857 } 10858 10859 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 10860 status = wmi_unified_cmd_send(wmi_handle, buf, 10861 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 10862 if (QDF_IS_STATUS_ERROR(status)) { 10863 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 10864 status); 10865 goto error; 10866 } 10867 10868 return QDF_STATUS_SUCCESS; 10869 error: 10870 wmi_buf_free(buf); 10871 10872 return status; 10873 } 10874 10875 /** 10876 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 10877 * @wmi_handle: wmi handle 10878 * @pdev_id: pdev id 10879 * 10880 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 10881 * 10882 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10883 */ 10884 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 10885 uint32_t pdev_id) 10886 { 10887 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 10888 wmi_buf_t buf; 10889 uint16_t len; 10890 QDF_STATUS ret; 10891 10892 len = sizeof(*cmd); 10893 buf = wmi_buf_alloc(wmi_handle, len); 10894 10895 wmi_debug("pdev_id=%d", pdev_id); 10896 10897 if (!buf) 10898 return QDF_STATUS_E_NOMEM; 10899 10900 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 10901 wmi_buf_data(buf); 10902 10903 WMITLV_SET_HDR(&cmd->tlv_header, 10904 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 10905 WMITLV_GET_STRUCT_TLVLEN( 10906 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 10907 10908 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10909 wmi_handle, 10910 pdev_id); 10911 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 10912 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10913 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 10914 if (QDF_IS_STATUS_ERROR(ret)) { 10915 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 10916 ret, pdev_id); 10917 wmi_buf_free(buf); 10918 return QDF_STATUS_E_FAILURE; 10919 } 10920 10921 return QDF_STATUS_SUCCESS; 10922 } 10923 10924 /** 10925 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 10926 * @wmi_handle: wmi handle 10927 * @pdev_id: pdev id 10928 * 10929 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 10930 * 10931 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10932 */ 10933 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 10934 uint32_t pdev_id) 10935 { 10936 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 10937 wmi_buf_t buf; 10938 uint16_t len; 10939 QDF_STATUS ret; 10940 10941 len = sizeof(*cmd); 10942 buf = wmi_buf_alloc(wmi_handle, len); 10943 10944 wmi_debug("pdev_id=%d", pdev_id); 10945 10946 if (!buf) 10947 return QDF_STATUS_E_NOMEM; 10948 10949 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 10950 wmi_buf_data(buf); 10951 10952 WMITLV_SET_HDR(&cmd->tlv_header, 10953 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 10954 WMITLV_GET_STRUCT_TLVLEN( 10955 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 10956 10957 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10958 wmi_handle, 10959 pdev_id); 10960 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 10961 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10962 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 10963 if (QDF_IS_STATUS_ERROR(ret)) { 10964 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 10965 ret, pdev_id); 10966 wmi_buf_free(buf); 10967 return QDF_STATUS_E_FAILURE; 10968 } 10969 10970 return QDF_STATUS_SUCCESS; 10971 } 10972 10973 #ifdef QCA_SUPPORT_AGILE_DFS 10974 static 10975 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 10976 struct vdev_adfs_ch_cfg_params *param) 10977 { 10978 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 10979 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 10980 wmi_buf_t buf; 10981 QDF_STATUS ret; 10982 uint16_t len; 10983 10984 len = sizeof(*cmd); 10985 buf = wmi_buf_alloc(wmi_handle, len); 10986 10987 if (!buf) { 10988 wmi_err("wmi_buf_alloc failed"); 10989 return QDF_STATUS_E_NOMEM; 10990 } 10991 10992 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 10993 wmi_buf_data(buf); 10994 10995 WMITLV_SET_HDR(&cmd->tlv_header, 10996 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 10997 WMITLV_GET_STRUCT_TLVLEN 10998 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 10999 11000 cmd->vdev_id = param->vdev_id; 11001 cmd->ocac_mode = param->ocac_mode; 11002 cmd->center_freq1 = param->center_freq1; 11003 cmd->center_freq2 = param->center_freq2; 11004 cmd->chan_freq = param->chan_freq; 11005 cmd->chan_width = param->chan_width; 11006 cmd->min_duration_ms = param->min_duration_ms; 11007 cmd->max_duration_ms = param->max_duration_ms; 11008 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11009 cmd->vdev_id, cmd->ocac_mode, 11010 cmd->center_freq); 11011 11012 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11013 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11014 WMI_VDEV_ADFS_CH_CFG_CMDID); 11015 11016 if (QDF_IS_STATUS_ERROR(ret)) { 11017 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11018 wmi_buf_free(buf); 11019 return QDF_STATUS_E_FAILURE; 11020 } 11021 11022 return QDF_STATUS_SUCCESS; 11023 } 11024 11025 static 11026 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11027 struct vdev_adfs_abort_params *param) 11028 { 11029 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11030 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11031 wmi_buf_t buf; 11032 QDF_STATUS ret; 11033 uint16_t len; 11034 11035 len = sizeof(*cmd); 11036 buf = wmi_buf_alloc(wmi_handle, len); 11037 11038 if (!buf) { 11039 wmi_err("wmi_buf_alloc failed"); 11040 return QDF_STATUS_E_NOMEM; 11041 } 11042 11043 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11044 wmi_buf_data(buf); 11045 11046 WMITLV_SET_HDR 11047 (&cmd->tlv_header, 11048 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11049 WMITLV_GET_STRUCT_TLVLEN 11050 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11051 11052 cmd->vdev_id = param->vdev_id; 11053 11054 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11055 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11056 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11057 11058 if (QDF_IS_STATUS_ERROR(ret)) { 11059 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11060 wmi_buf_free(buf); 11061 return QDF_STATUS_E_FAILURE; 11062 } 11063 11064 return QDF_STATUS_SUCCESS; 11065 } 11066 #endif 11067 11068 /** 11069 * init_cmd_send_tlv() - send initialization cmd to fw 11070 * @wmi_handle: wmi handle 11071 * @param param: pointer to wmi init param 11072 * 11073 * Return: QDF_STATUS_SUCCESS for success or error code 11074 */ 11075 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11076 struct wmi_init_cmd_param *param) 11077 { 11078 wmi_buf_t buf; 11079 wmi_init_cmd_fixed_param *cmd; 11080 uint8_t *buf_ptr; 11081 wmi_resource_config *resource_cfg; 11082 wlan_host_memory_chunk *host_mem_chunks; 11083 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11084 uint16_t idx; 11085 int len; 11086 QDF_STATUS ret; 11087 11088 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11089 WMI_TLV_HDR_SIZE; 11090 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11091 11092 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11093 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11094 WMI_TLV_HDR_SIZE + 11095 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11096 11097 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11098 if (!buf) 11099 return QDF_STATUS_E_FAILURE; 11100 11101 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11102 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11103 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11104 11105 host_mem_chunks = (wlan_host_memory_chunk *) 11106 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11107 + WMI_TLV_HDR_SIZE); 11108 11109 WMITLV_SET_HDR(&cmd->tlv_header, 11110 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11111 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11112 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11113 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11114 WMITLV_TAG_STRUC_wmi_resource_config, 11115 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11116 11117 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11118 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11119 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11120 WMITLV_GET_STRUCT_TLVLEN 11121 (wlan_host_memory_chunk)); 11122 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11123 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11124 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11125 if (is_service_enabled_tlv(wmi_handle, 11126 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11127 host_mem_chunks[idx].ptr_high = 11128 qdf_get_upper_32_bits( 11129 param->mem_chunks[idx].paddr); 11130 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11131 "chunk %d len %d requested ,ptr 0x%x ", 11132 idx, host_mem_chunks[idx].size, 11133 host_mem_chunks[idx].ptr); 11134 } 11135 cmd->num_host_mem_chunks = param->num_mem_chunks; 11136 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11137 11138 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11139 WMITLV_TAG_ARRAY_STRUC, 11140 (sizeof(wlan_host_memory_chunk) * 11141 param->num_mem_chunks)); 11142 11143 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", 11144 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11145 resource_cfg->num_vdevs, resource_cfg->num_tids, 11146 resource_cfg->num_tdls_conn_table_entries, 11147 resource_cfg->num_tdls_vdevs); 11148 11149 /* Fill hw mode id config */ 11150 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11151 11152 /* Fill fw_abi_vers */ 11153 copy_fw_abi_version_tlv(wmi_handle, cmd); 11154 11155 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11156 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11157 if (QDF_IS_STATUS_ERROR(ret)) { 11158 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11159 ret); 11160 wmi_buf_free(buf); 11161 } 11162 11163 return ret; 11164 11165 } 11166 11167 /** 11168 * send_addba_send_cmd_tlv() - send addba send command to fw 11169 * @wmi_handle: wmi handle 11170 * @param: pointer to delba send params 11171 * @macaddr: peer mac address 11172 * 11173 * Send WMI_ADDBA_SEND_CMDID command to firmware 11174 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11175 */ 11176 static QDF_STATUS 11177 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11178 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11179 struct addba_send_params *param) 11180 { 11181 wmi_addba_send_cmd_fixed_param *cmd; 11182 wmi_buf_t buf; 11183 uint16_t len; 11184 QDF_STATUS ret; 11185 11186 len = sizeof(*cmd); 11187 11188 buf = wmi_buf_alloc(wmi_handle, len); 11189 if (!buf) 11190 return QDF_STATUS_E_NOMEM; 11191 11192 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11193 11194 WMITLV_SET_HDR(&cmd->tlv_header, 11195 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11196 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11197 11198 cmd->vdev_id = param->vdev_id; 11199 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11200 cmd->tid = param->tidno; 11201 cmd->buffersize = param->buffersize; 11202 11203 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11204 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11205 if (QDF_IS_STATUS_ERROR(ret)) { 11206 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11207 wmi_buf_free(buf); 11208 return QDF_STATUS_E_FAILURE; 11209 } 11210 11211 return QDF_STATUS_SUCCESS; 11212 } 11213 11214 /** 11215 * send_delba_send_cmd_tlv() - send delba send command to fw 11216 * @wmi_handle: wmi handle 11217 * @param: pointer to delba send params 11218 * @macaddr: peer mac address 11219 * 11220 * Send WMI_DELBA_SEND_CMDID command to firmware 11221 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11222 */ 11223 static QDF_STATUS 11224 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11225 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11226 struct delba_send_params *param) 11227 { 11228 wmi_delba_send_cmd_fixed_param *cmd; 11229 wmi_buf_t buf; 11230 uint16_t len; 11231 QDF_STATUS ret; 11232 11233 len = sizeof(*cmd); 11234 11235 buf = wmi_buf_alloc(wmi_handle, len); 11236 if (!buf) 11237 return QDF_STATUS_E_NOMEM; 11238 11239 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11240 11241 WMITLV_SET_HDR(&cmd->tlv_header, 11242 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11243 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11244 11245 cmd->vdev_id = param->vdev_id; 11246 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11247 cmd->tid = param->tidno; 11248 cmd->initiator = param->initiator; 11249 cmd->reasoncode = param->reasoncode; 11250 11251 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11252 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11253 if (QDF_IS_STATUS_ERROR(ret)) { 11254 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11255 wmi_buf_free(buf); 11256 return QDF_STATUS_E_FAILURE; 11257 } 11258 11259 return QDF_STATUS_SUCCESS; 11260 } 11261 11262 /** 11263 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11264 * to fw 11265 * @wmi_handle: wmi handle 11266 * @param: pointer to addba clearresp params 11267 * @macaddr: peer mac address 11268 * Return: 0 for success or error code 11269 */ 11270 static QDF_STATUS 11271 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11272 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11273 struct addba_clearresponse_params *param) 11274 { 11275 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11276 wmi_buf_t buf; 11277 uint16_t len; 11278 QDF_STATUS ret; 11279 11280 len = sizeof(*cmd); 11281 11282 buf = wmi_buf_alloc(wmi_handle, len); 11283 if (!buf) 11284 return QDF_STATUS_E_FAILURE; 11285 11286 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11287 11288 WMITLV_SET_HDR(&cmd->tlv_header, 11289 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11290 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11291 11292 cmd->vdev_id = param->vdev_id; 11293 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11294 11295 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11296 ret = wmi_unified_cmd_send(wmi_handle, 11297 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11298 if (QDF_IS_STATUS_ERROR(ret)) { 11299 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11300 wmi_buf_free(buf); 11301 return QDF_STATUS_E_FAILURE; 11302 } 11303 11304 return QDF_STATUS_SUCCESS; 11305 } 11306 11307 #ifdef OBSS_PD 11308 /** 11309 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11310 * def thresh to fw 11311 * @wmi_handle: wmi handle 11312 * @thresh: pointer to obss_spatial_reuse_def_thresh 11313 * 11314 * Return: QDF_STATUS_SUCCESS for success or error code 11315 */ 11316 static 11317 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11318 wmi_unified_t wmi_handle, 11319 struct wmi_host_obss_spatial_reuse_set_def_thresh 11320 *thresh) 11321 { 11322 wmi_buf_t buf; 11323 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11324 QDF_STATUS ret; 11325 uint32_t cmd_len; 11326 uint32_t tlv_len; 11327 11328 cmd_len = sizeof(*cmd); 11329 11330 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11331 if (!buf) 11332 return QDF_STATUS_E_NOMEM; 11333 11334 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11335 wmi_buf_data(buf); 11336 11337 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11338 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11339 11340 WMITLV_SET_HDR(&cmd->tlv_header, 11341 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11342 tlv_len); 11343 11344 cmd->obss_min = thresh->obss_min; 11345 cmd->obss_max = thresh->obss_max; 11346 cmd->vdev_type = thresh->vdev_type; 11347 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11348 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11349 if (QDF_IS_STATUS_ERROR(ret)) 11350 wmi_buf_free(buf); 11351 11352 return ret; 11353 } 11354 11355 /** 11356 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11357 * @wmi_handle: wmi handle 11358 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11359 * 11360 * Return: QDF_STATUS_SUCCESS for success or error code 11361 */ 11362 static 11363 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11364 struct wmi_host_obss_spatial_reuse_set_param 11365 *obss_spatial_reuse_param) 11366 { 11367 wmi_buf_t buf; 11368 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11369 QDF_STATUS ret; 11370 uint32_t len; 11371 11372 len = sizeof(*cmd); 11373 11374 buf = wmi_buf_alloc(wmi_handle, len); 11375 if (!buf) 11376 return QDF_STATUS_E_FAILURE; 11377 11378 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11379 WMITLV_SET_HDR(&cmd->tlv_header, 11380 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11381 WMITLV_GET_STRUCT_TLVLEN 11382 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11383 11384 cmd->enable = obss_spatial_reuse_param->enable; 11385 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11386 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11387 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11388 11389 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11390 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11391 11392 if (QDF_IS_STATUS_ERROR(ret)) { 11393 wmi_err( 11394 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11395 ret); 11396 wmi_buf_free(buf); 11397 } 11398 11399 return ret; 11400 } 11401 11402 /** 11403 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11404 * to be used by SRG based Spatial Reuse feature to the FW 11405 * @wmi_handle: wmi handle 11406 * @bitmap_0: lower 32 bits in BSS color bitmap 11407 * @bitmap_1: upper 32 bits in BSS color bitmap 11408 * @pdev_id: pdev ID 11409 * 11410 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11411 */ 11412 static QDF_STATUS 11413 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11414 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11415 uint32_t bitmap_1, uint8_t pdev_id) 11416 { 11417 wmi_buf_t buf; 11418 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11419 QDF_STATUS ret; 11420 uint32_t len; 11421 11422 len = sizeof(*cmd); 11423 11424 buf = wmi_buf_alloc(wmi_handle, len); 11425 if (!buf) 11426 return QDF_STATUS_E_FAILURE; 11427 11428 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11429 wmi_buf_data(buf); 11430 11431 WMITLV_SET_HDR( 11432 &cmd->tlv_header, 11433 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11434 WMITLV_GET_STRUCT_TLVLEN 11435 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11436 11437 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11438 wmi_handle, pdev_id); 11439 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11440 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11441 11442 ret = wmi_unified_cmd_send( 11443 wmi_handle, buf, len, 11444 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11445 11446 if (QDF_IS_STATUS_ERROR(ret)) { 11447 wmi_err( 11448 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11449 ret); 11450 wmi_buf_free(buf); 11451 } 11452 11453 return ret; 11454 } 11455 11456 /** 11457 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11458 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11459 * @wmi_handle: wmi handle 11460 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11461 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11462 * @pdev_id: pdev ID 11463 * 11464 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11465 */ 11466 static QDF_STATUS 11467 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11468 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11469 uint32_t bitmap_1, uint8_t pdev_id) 11470 { 11471 wmi_buf_t buf; 11472 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11473 QDF_STATUS ret; 11474 uint32_t len; 11475 11476 len = sizeof(*cmd); 11477 11478 buf = wmi_buf_alloc(wmi_handle, len); 11479 if (!buf) 11480 return QDF_STATUS_E_FAILURE; 11481 11482 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11483 wmi_buf_data(buf); 11484 11485 WMITLV_SET_HDR( 11486 &cmd->tlv_header, 11487 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11488 WMITLV_GET_STRUCT_TLVLEN 11489 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11490 11491 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11492 wmi_handle, pdev_id); 11493 11494 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11495 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11496 11497 ret = wmi_unified_cmd_send( 11498 wmi_handle, buf, len, 11499 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11500 11501 if (QDF_IS_STATUS_ERROR(ret)) { 11502 wmi_err( 11503 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11504 ret); 11505 wmi_buf_free(buf); 11506 } 11507 11508 return ret; 11509 } 11510 11511 /** 11512 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11513 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11514 * @wmi_handle: wmi handle 11515 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11516 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11517 * @pdev_id: pdev ID 11518 * 11519 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11520 */ 11521 static QDF_STATUS 11522 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11523 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11524 uint32_t bitmap_1, uint8_t pdev_id) 11525 { 11526 wmi_buf_t buf; 11527 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11528 QDF_STATUS ret; 11529 uint32_t len; 11530 11531 len = sizeof(*cmd); 11532 11533 buf = wmi_buf_alloc(wmi_handle, len); 11534 if (!buf) 11535 return QDF_STATUS_E_FAILURE; 11536 11537 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11538 wmi_buf_data(buf); 11539 11540 WMITLV_SET_HDR( 11541 &cmd->tlv_header, 11542 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11543 WMITLV_GET_STRUCT_TLVLEN 11544 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11545 11546 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11547 wmi_handle, pdev_id); 11548 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11549 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11550 11551 ret = wmi_unified_cmd_send( 11552 wmi_handle, buf, len, 11553 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11554 11555 if (QDF_IS_STATUS_ERROR(ret)) { 11556 wmi_err( 11557 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11558 ret); 11559 wmi_buf_free(buf); 11560 } 11561 11562 return ret; 11563 } 11564 11565 /** 11566 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11567 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11568 * @wmi_handle: wmi handle 11569 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11570 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11571 * @pdev_id: pdev ID 11572 * 11573 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11574 */ 11575 static QDF_STATUS 11576 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11577 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11578 uint32_t bitmap_1, uint8_t pdev_id) 11579 { 11580 wmi_buf_t buf; 11581 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11582 QDF_STATUS ret; 11583 uint32_t len; 11584 11585 len = sizeof(*cmd); 11586 11587 buf = wmi_buf_alloc(wmi_handle, len); 11588 if (!buf) 11589 return QDF_STATUS_E_FAILURE; 11590 11591 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11592 wmi_buf_data(buf); 11593 11594 WMITLV_SET_HDR( 11595 &cmd->tlv_header, 11596 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11597 WMITLV_GET_STRUCT_TLVLEN 11598 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11599 11600 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11601 wmi_handle, pdev_id); 11602 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11603 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11604 11605 ret = wmi_unified_cmd_send( 11606 wmi_handle, buf, len, 11607 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11608 11609 if (QDF_IS_STATUS_ERROR(ret)) { 11610 wmi_err( 11611 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11612 ret); 11613 wmi_buf_free(buf); 11614 } 11615 11616 return ret; 11617 } 11618 11619 /** 11620 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11621 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11622 * @wmi_handle: wmi handle 11623 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11624 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11625 * @pdev_id: pdev ID 11626 * 11627 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11628 */ 11629 static QDF_STATUS 11630 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11631 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11632 uint32_t bitmap_1, uint8_t pdev_id) 11633 { 11634 wmi_buf_t buf; 11635 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11636 QDF_STATUS ret; 11637 uint32_t len; 11638 11639 len = sizeof(*cmd); 11640 11641 buf = wmi_buf_alloc(wmi_handle, len); 11642 if (!buf) 11643 return QDF_STATUS_E_FAILURE; 11644 11645 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11646 wmi_buf_data(buf); 11647 11648 WMITLV_SET_HDR( 11649 &cmd->tlv_header, 11650 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11651 WMITLV_GET_STRUCT_TLVLEN 11652 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11653 11654 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11655 wmi_handle, pdev_id); 11656 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11657 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11658 11659 ret = wmi_unified_cmd_send( 11660 wmi_handle, buf, len, 11661 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11662 11663 if (QDF_IS_STATUS_ERROR(ret)) { 11664 wmi_err( 11665 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11666 ret); 11667 wmi_buf_free(buf); 11668 } 11669 11670 return ret; 11671 } 11672 11673 /** 11674 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11675 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11676 * @wmi_handle: wmi handle 11677 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11678 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11679 * @pdev_id: pdev ID 11680 * 11681 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11682 */ 11683 static QDF_STATUS 11684 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11685 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11686 uint32_t bitmap_1, uint8_t pdev_id) 11687 { 11688 wmi_buf_t buf; 11689 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11690 QDF_STATUS ret; 11691 uint32_t len; 11692 11693 len = sizeof(*cmd); 11694 11695 buf = wmi_buf_alloc(wmi_handle, len); 11696 if (!buf) 11697 return QDF_STATUS_E_FAILURE; 11698 11699 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11700 wmi_buf_data(buf); 11701 11702 WMITLV_SET_HDR( 11703 &cmd->tlv_header, 11704 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11705 WMITLV_GET_STRUCT_TLVLEN 11706 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11707 11708 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11709 wmi_handle, pdev_id); 11710 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 11711 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 11712 11713 ret = wmi_unified_cmd_send( 11714 wmi_handle, buf, len, 11715 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11716 11717 if (QDF_IS_STATUS_ERROR(ret)) { 11718 wmi_err( 11719 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11720 ret); 11721 wmi_buf_free(buf); 11722 } 11723 11724 return ret; 11725 } 11726 #endif 11727 11728 static 11729 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 11730 struct wmi_host_injector_frame_params *inject_config_params) 11731 { 11732 wmi_buf_t buf; 11733 wmi_frame_inject_cmd_fixed_param *cmd; 11734 QDF_STATUS ret; 11735 uint32_t len; 11736 11737 len = sizeof(*cmd); 11738 11739 buf = wmi_buf_alloc(wmi_handle, len); 11740 if (!buf) 11741 return QDF_STATUS_E_NOMEM; 11742 11743 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 11744 WMITLV_SET_HDR(&cmd->tlv_header, 11745 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 11746 WMITLV_GET_STRUCT_TLVLEN 11747 (wmi_frame_inject_cmd_fixed_param)); 11748 11749 cmd->vdev_id = inject_config_params->vdev_id; 11750 cmd->enable = inject_config_params->enable; 11751 cmd->frame_type = inject_config_params->frame_type; 11752 cmd->frame_inject_period = inject_config_params->frame_inject_period; 11753 cmd->fc_duration = inject_config_params->frame_duration; 11754 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 11755 &cmd->frame_addr1); 11756 11757 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11758 WMI_PDEV_FRAME_INJECT_CMDID); 11759 11760 if (QDF_IS_STATUS_ERROR(ret)) { 11761 wmi_err( 11762 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 11763 ret); 11764 wmi_buf_free(buf); 11765 } 11766 11767 return ret; 11768 } 11769 #ifdef QCA_SUPPORT_CP_STATS 11770 /** 11771 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 11772 * @wmi_handle: wma handle 11773 * @evt_buf: event buffer 11774 * @out_buff: buffer to populated after stats extraction 11775 * 11776 * Return: status of operation 11777 */ 11778 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 11779 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 11780 { 11781 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11782 wmi_congestion_stats *congestion_stats; 11783 11784 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11785 congestion_stats = param_buf->congestion_stats; 11786 if (!congestion_stats) 11787 return QDF_STATUS_E_INVAL; 11788 11789 out_buff->vdev_id = congestion_stats->vdev_id; 11790 out_buff->congestion = congestion_stats->congestion; 11791 11792 wmi_debug("cca stats event processed"); 11793 return QDF_STATUS_SUCCESS; 11794 } 11795 #endif /* QCA_SUPPORT_CP_STATS */ 11796 11797 /** 11798 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 11799 * event 11800 * @wmi_handle: wmi handle 11801 * @param evt_buf: pointer to event buffer 11802 * @param param: Pointer to hold peer ctl data 11803 * 11804 * Return: QDF_STATUS_SUCCESS for success or error code 11805 */ 11806 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 11807 wmi_unified_t wmi_handle, 11808 void *evt_buf, 11809 struct wmi_host_pdev_ctl_failsafe_event *param) 11810 { 11811 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 11812 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 11813 11814 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 11815 if (!param_buf) { 11816 wmi_err("Invalid ctl_failsafe event buffer"); 11817 return QDF_STATUS_E_INVAL; 11818 } 11819 11820 fix_param = param_buf->fixed_param; 11821 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 11822 11823 return QDF_STATUS_SUCCESS; 11824 } 11825 11826 /** 11827 * save_service_bitmap_tlv() - save service bitmap 11828 * @wmi_handle: wmi handle 11829 * @param evt_buf: pointer to event buffer 11830 * @param bitmap_buf: bitmap buffer, for converged legacy support 11831 * 11832 * Return: QDF_STATUS 11833 */ 11834 static 11835 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11836 void *bitmap_buf) 11837 { 11838 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11839 struct wmi_soc *soc = wmi_handle->soc; 11840 11841 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11842 11843 /* If it is already allocated, use that buffer. This can happen 11844 * during target stop/start scenarios where host allocation is skipped. 11845 */ 11846 if (!soc->wmi_service_bitmap) { 11847 soc->wmi_service_bitmap = 11848 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 11849 if (!soc->wmi_service_bitmap) 11850 return QDF_STATUS_E_NOMEM; 11851 } 11852 11853 qdf_mem_copy(soc->wmi_service_bitmap, 11854 param_buf->wmi_service_bitmap, 11855 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11856 11857 if (bitmap_buf) 11858 qdf_mem_copy(bitmap_buf, 11859 param_buf->wmi_service_bitmap, 11860 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11861 11862 return QDF_STATUS_SUCCESS; 11863 } 11864 11865 /** 11866 * save_ext_service_bitmap_tlv() - save extendend service bitmap 11867 * @wmi_handle: wmi handle 11868 * @param evt_buf: pointer to event buffer 11869 * @param bitmap_buf: bitmap buffer, for converged legacy support 11870 * 11871 * Return: QDF_STATUS 11872 */ 11873 static 11874 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11875 void *bitmap_buf) 11876 { 11877 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 11878 wmi_service_available_event_fixed_param *ev; 11879 struct wmi_soc *soc = wmi_handle->soc; 11880 uint32_t i = 0; 11881 11882 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 11883 11884 ev = param_buf->fixed_param; 11885 11886 /* If it is already allocated, use that buffer. This can happen 11887 * during target stop/start scenarios where host allocation is skipped. 11888 */ 11889 if (!soc->wmi_ext_service_bitmap) { 11890 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 11891 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 11892 if (!soc->wmi_ext_service_bitmap) 11893 return QDF_STATUS_E_NOMEM; 11894 } 11895 11896 qdf_mem_copy(soc->wmi_ext_service_bitmap, 11897 ev->wmi_service_segment_bitmap, 11898 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 11899 11900 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 11901 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 11902 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 11903 11904 if (bitmap_buf) 11905 qdf_mem_copy(bitmap_buf, 11906 soc->wmi_ext_service_bitmap, 11907 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 11908 11909 if (!param_buf->wmi_service_ext_bitmap) { 11910 wmi_debug("wmi_service_ext_bitmap not available"); 11911 return QDF_STATUS_SUCCESS; 11912 } 11913 11914 if (!soc->wmi_ext2_service_bitmap) { 11915 soc->wmi_ext2_service_bitmap = 11916 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 11917 sizeof(uint32_t)); 11918 if (!soc->wmi_ext2_service_bitmap) 11919 return QDF_STATUS_E_NOMEM; 11920 } 11921 11922 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 11923 param_buf->wmi_service_ext_bitmap, 11924 (param_buf->num_wmi_service_ext_bitmap * 11925 sizeof(uint32_t))); 11926 11927 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 11928 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 11929 i, soc->wmi_ext2_service_bitmap[i]); 11930 } 11931 11932 return QDF_STATUS_SUCCESS; 11933 } 11934 11935 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 11936 struct wlan_psoc_target_capability_info *cap) 11937 { 11938 /* except LDPC all flags are common betwen legacy and here 11939 * also IBFEER is not defined for TLV 11940 */ 11941 cap->ht_cap_info |= ev_target_cap & ( 11942 WMI_HT_CAP_ENABLED 11943 | WMI_HT_CAP_HT20_SGI 11944 | WMI_HT_CAP_DYNAMIC_SMPS 11945 | WMI_HT_CAP_TX_STBC 11946 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 11947 | WMI_HT_CAP_RX_STBC 11948 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 11949 | WMI_HT_CAP_LDPC 11950 | WMI_HT_CAP_L_SIG_TXOP_PROT 11951 | WMI_HT_CAP_MPDU_DENSITY 11952 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 11953 | WMI_HT_CAP_HT40_SGI); 11954 if (ev_target_cap & WMI_HT_CAP_LDPC) 11955 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 11956 WMI_HOST_HT_CAP_TX_LDPC; 11957 } 11958 /** 11959 * extract_service_ready_tlv() - extract service ready event 11960 * @wmi_handle: wmi handle 11961 * @param evt_buf: pointer to received event buffer 11962 * @param cap: pointer to hold target capability information extracted from even 11963 * 11964 * Return: QDF_STATUS_SUCCESS for success or error code 11965 */ 11966 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 11967 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 11968 { 11969 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11970 wmi_service_ready_event_fixed_param *ev; 11971 11972 11973 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11974 11975 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11976 if (!ev) { 11977 qdf_print("%s: wmi_buf_alloc failed", __func__); 11978 return QDF_STATUS_E_FAILURE; 11979 } 11980 11981 cap->phy_capability = ev->phy_capability; 11982 cap->max_frag_entry = ev->max_frag_entry; 11983 cap->num_rf_chains = ev->num_rf_chains; 11984 copy_ht_cap_info(ev->ht_cap_info, cap); 11985 cap->vht_cap_info = ev->vht_cap_info; 11986 cap->vht_supp_mcs = ev->vht_supp_mcs; 11987 cap->hw_min_tx_power = ev->hw_min_tx_power; 11988 cap->hw_max_tx_power = ev->hw_max_tx_power; 11989 cap->sys_cap_info = ev->sys_cap_info; 11990 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 11991 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 11992 cap->max_num_scan_channels = ev->max_num_scan_channels; 11993 cap->max_supported_macs = ev->max_supported_macs; 11994 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 11995 cap->txrx_chainmask = ev->txrx_chainmask; 11996 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 11997 cap->num_msdu_desc = ev->num_msdu_desc; 11998 cap->fw_version = ev->fw_build_vers; 11999 /* fw_version_1 is not available in TLV. */ 12000 cap->fw_version_1 = 0; 12001 12002 return QDF_STATUS_SUCCESS; 12003 } 12004 12005 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12006 * to host internal HOST_REGDMN_MODE values. 12007 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12008 * host currently. Add this in the future if required. 12009 * 11AX (Phase II) : 11ax related values are not currently 12010 * advertised separately by FW. As part of phase II regulatory bring-up, 12011 * finalize the advertisement mechanism. 12012 * @target_wireless_mode: target wireless mode received in message 12013 * 12014 * Return: returns the host internal wireless mode. 12015 */ 12016 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12017 { 12018 12019 uint32_t wireless_modes = 0; 12020 12021 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12022 12023 if (target_wireless_mode & REGDMN_MODE_11A) 12024 wireless_modes |= HOST_REGDMN_MODE_11A; 12025 12026 if (target_wireless_mode & REGDMN_MODE_TURBO) 12027 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12028 12029 if (target_wireless_mode & REGDMN_MODE_11B) 12030 wireless_modes |= HOST_REGDMN_MODE_11B; 12031 12032 if (target_wireless_mode & REGDMN_MODE_PUREG) 12033 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12034 12035 if (target_wireless_mode & REGDMN_MODE_11G) 12036 wireless_modes |= HOST_REGDMN_MODE_11G; 12037 12038 if (target_wireless_mode & REGDMN_MODE_108G) 12039 wireless_modes |= HOST_REGDMN_MODE_108G; 12040 12041 if (target_wireless_mode & REGDMN_MODE_108A) 12042 wireless_modes |= HOST_REGDMN_MODE_108A; 12043 12044 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12045 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12046 12047 if (target_wireless_mode & REGDMN_MODE_XR) 12048 wireless_modes |= HOST_REGDMN_MODE_XR; 12049 12050 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12051 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12052 12053 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12054 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12055 12056 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12057 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12058 12059 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12060 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12061 12062 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12063 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12064 12065 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12066 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12067 12068 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12069 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12070 12071 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12072 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12073 12074 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12075 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12076 12077 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12078 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12079 12080 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12081 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12082 12083 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12084 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12085 12086 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12087 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12088 12089 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12090 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12091 12092 return wireless_modes; 12093 } 12094 12095 /** 12096 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12097 * to regulatory flags. 12098 * @target_phybitmap: target phybitmap. 12099 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12100 * phybitmap. 12101 * 12102 * Return: None 12103 */ 12104 12105 #ifdef WLAN_FEATURE_11BE 12106 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12107 uint32_t *phybitmap) 12108 { 12109 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12110 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12111 } 12112 #else 12113 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12114 uint32_t *phybitmap) 12115 { 12116 } 12117 #endif 12118 12119 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12120 * target to host internal REGULATORY_PHYMODE values. 12121 * 12122 * @target_target_phybitmap: target phybitmap received in the message. 12123 * 12124 * Return: returns the host internal REGULATORY_PHYMODE. 12125 */ 12126 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12127 { 12128 uint32_t phybitmap = 0; 12129 12130 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12131 12132 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12133 phybitmap |= REGULATORY_PHYMODE_NO11A; 12134 12135 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12136 phybitmap |= REGULATORY_PHYMODE_NO11B; 12137 12138 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12139 phybitmap |= REGULATORY_PHYMODE_NO11G; 12140 12141 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12142 phybitmap |= REGULATORY_CHAN_NO11N; 12143 12144 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12145 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12146 12147 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12148 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12149 12150 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12151 12152 return phybitmap; 12153 } 12154 12155 /** 12156 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12157 * advertised by the target to wireless mode ext flags. 12158 * @target_wireless_modes_ext: Target wireless mode 12159 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12160 * 12161 * Return: None 12162 */ 12163 #ifdef WLAN_FEATURE_11BE 12164 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12165 uint64_t *wireless_modes_ext) 12166 { 12167 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12168 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12169 12170 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12171 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12172 12173 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12174 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12175 12176 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12177 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12178 12179 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12180 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12181 12182 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12183 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12184 12185 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12186 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12187 12188 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12189 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12190 12191 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12192 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12193 } 12194 #else 12195 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12196 uint64_t *wireless_modes_ext) 12197 { 12198 } 12199 #endif 12200 12201 static inline uint64_t convert_wireless_modes_ext_tlv( 12202 uint32_t target_wireless_modes_ext) 12203 { 12204 uint64_t wireless_modes_ext = 0; 12205 12206 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12207 12208 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12209 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12210 12211 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12212 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12213 12214 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12215 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12216 12217 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12218 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12219 12220 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12221 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12222 12223 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12224 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12225 12226 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12227 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12228 12229 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12230 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12231 12232 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12233 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12234 12235 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12236 &wireless_modes_ext); 12237 12238 return wireless_modes_ext; 12239 } 12240 12241 /** 12242 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12243 * @wmi_handle: wmi handle 12244 * @param evt_buf: Pointer to event buffer 12245 * @param cap: pointer to hold HAL reg capabilities 12246 * 12247 * Return: QDF_STATUS_SUCCESS for success or error code 12248 */ 12249 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12250 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12251 { 12252 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12253 12254 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12255 if (!param_buf || !param_buf->hal_reg_capabilities) { 12256 wmi_err("Invalid arguments"); 12257 return QDF_STATUS_E_FAILURE; 12258 } 12259 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12260 sizeof(uint32_t)), 12261 sizeof(struct wlan_psoc_hal_reg_capability)); 12262 12263 cap->wireless_modes = convert_wireless_modes_tlv( 12264 param_buf->hal_reg_capabilities->wireless_modes); 12265 12266 return QDF_STATUS_SUCCESS; 12267 } 12268 12269 /** 12270 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12271 * @wmi_handle: wmi handle 12272 * @param evt_buf: Pointer to event buffer 12273 * @param cap: pointer to hold HAL reg capabilities 12274 * 12275 * Return: QDF_STATUS_SUCCESS for success or error code 12276 */ 12277 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12278 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12279 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12280 { 12281 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12282 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12283 12284 if (!evt_buf) { 12285 wmi_err("null evt_buf"); 12286 return QDF_STATUS_E_INVAL; 12287 } 12288 12289 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12290 12291 if (!param_buf->num_hal_reg_caps) 12292 return QDF_STATUS_SUCCESS; 12293 12294 if (phy_idx >= param_buf->num_hal_reg_caps) 12295 return QDF_STATUS_E_INVAL; 12296 12297 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12298 12299 param->phy_id = reg_caps->phy_id; 12300 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12301 reg_caps->wireless_modes_ext); 12302 12303 return QDF_STATUS_SUCCESS; 12304 } 12305 12306 /** 12307 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12308 * @wmi_handle: wmi handle 12309 * @evt_buf: pointer to event buffer 12310 * 12311 * Return: Number of entries requested 12312 */ 12313 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12314 void *evt_buf) 12315 { 12316 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12317 wmi_service_ready_event_fixed_param *ev; 12318 12319 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12320 12321 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12322 if (!ev) { 12323 qdf_print("%s: wmi_buf_alloc failed", __func__); 12324 return 0; 12325 } 12326 12327 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12328 wmi_err("Invalid num_mem_reqs %d:%d", 12329 ev->num_mem_reqs, param_buf->num_mem_reqs); 12330 return 0; 12331 } 12332 12333 return ev->num_mem_reqs; 12334 } 12335 12336 /** 12337 * extract_host_mem_req_tlv() - Extract host memory required from 12338 * service ready event 12339 * @wmi_handle: wmi handle 12340 * @evt_buf: pointer to event buffer 12341 * @mem_reqs: pointer to host memory request structure 12342 * @num_active_peers: number of active peers for peer cache 12343 * @num_peers: number of peers 12344 * @fw_prio: FW priority 12345 * @idx: index for memory request 12346 * 12347 * Return: Host memory request parameters requested by target 12348 */ 12349 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12350 void *evt_buf, 12351 host_mem_req *mem_reqs, 12352 uint32_t num_active_peers, 12353 uint32_t num_peers, 12354 enum wmi_fw_mem_prio fw_prio, 12355 uint16_t idx) 12356 { 12357 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12358 12359 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12360 12361 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12362 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12363 mem_reqs->num_unit_info = 12364 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12365 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12366 mem_reqs->tgt_num_units = 0; 12367 12368 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12369 (mem_reqs->num_unit_info & 12370 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12371 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12372 (!(mem_reqs->num_unit_info & 12373 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12374 /* First allocate the memory that requires contiguous memory */ 12375 mem_reqs->tgt_num_units = mem_reqs->num_units; 12376 if (mem_reqs->num_unit_info) { 12377 if (mem_reqs->num_unit_info & 12378 NUM_UNITS_IS_NUM_PEERS) { 12379 /* 12380 * number of units allocated is equal to number 12381 * of peers, 1 extra for self peer on target. 12382 * this needs to be fixed, host and target can 12383 * get out of sync 12384 */ 12385 mem_reqs->tgt_num_units = num_peers + 1; 12386 } 12387 if (mem_reqs->num_unit_info & 12388 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12389 /* 12390 * Requesting allocation of memory using 12391 * num_active_peers in qcache. if qcache is 12392 * disabled in host, then it should allocate 12393 * memory for num_peers instead of 12394 * num_active_peers. 12395 */ 12396 if (num_active_peers) 12397 mem_reqs->tgt_num_units = 12398 num_active_peers + 1; 12399 else 12400 mem_reqs->tgt_num_units = 12401 num_peers + 1; 12402 } 12403 } 12404 12405 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12406 "unit size %d actual units %d", 12407 idx, mem_reqs->req_id, 12408 mem_reqs->num_units, 12409 mem_reqs->num_unit_info, 12410 mem_reqs->unit_size, 12411 mem_reqs->tgt_num_units); 12412 } 12413 12414 return QDF_STATUS_SUCCESS; 12415 } 12416 12417 /** 12418 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12419 * ready function 12420 * @wmi_handle: wmi handle 12421 * @param evt_buf: pointer to event buffer 12422 * 12423 * Return: QDF_STATUS_SUCCESS for success or error code 12424 */ 12425 static QDF_STATUS 12426 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12427 { 12428 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12429 wmi_service_ready_event_fixed_param *ev; 12430 12431 12432 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12433 12434 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12435 if (!ev) { 12436 qdf_print("%s: wmi_buf_alloc failed", __func__); 12437 return QDF_STATUS_E_FAILURE; 12438 } 12439 12440 /*Save fw version from service ready message */ 12441 /*This will be used while sending INIT message */ 12442 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12443 sizeof(wmi_handle->fw_abi_version)); 12444 12445 return QDF_STATUS_SUCCESS; 12446 } 12447 12448 /** 12449 * ready_extract_init_status_tlv() - Extract init status from ready event 12450 * @wmi_handle: wmi handle 12451 * @param evt_buf: Pointer to event buffer 12452 * 12453 * Return: ready status 12454 */ 12455 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12456 void *evt_buf) 12457 { 12458 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12459 wmi_ready_event_fixed_param *ev = NULL; 12460 12461 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12462 ev = param_buf->fixed_param; 12463 12464 qdf_print("%s:%d", __func__, ev->status); 12465 12466 return ev->status; 12467 } 12468 12469 /** 12470 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12471 * @wmi_handle: wmi handle 12472 * @param evt_buf: pointer to event buffer 12473 * @param macaddr: Pointer to hold MAC address 12474 * 12475 * Return: QDF_STATUS_SUCCESS for success or error code 12476 */ 12477 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 12478 void *evt_buf, uint8_t *macaddr) 12479 { 12480 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12481 wmi_ready_event_fixed_param *ev = NULL; 12482 12483 12484 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12485 ev = param_buf->fixed_param; 12486 12487 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12488 12489 return QDF_STATUS_SUCCESS; 12490 } 12491 12492 /** 12493 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12494 * @wmi_handle: wmi handle 12495 * @param evt_buf: pointer to event buffer 12496 * @param macaddr: Pointer to hold number of MAC addresses 12497 * 12498 * Return: Pointer to addr list 12499 */ 12500 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 12501 void *evt_buf, uint8_t *num_mac) 12502 { 12503 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12504 wmi_ready_event_fixed_param *ev = NULL; 12505 12506 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12507 ev = param_buf->fixed_param; 12508 12509 *num_mac = ev->num_extra_mac_addr; 12510 12511 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12512 } 12513 12514 /** 12515 * extract_ready_params_tlv() - Extract data from ready event apart from 12516 * status, macaddr and version. 12517 * @wmi_handle: Pointer to WMI handle. 12518 * @evt_buf: Pointer to Ready event buffer. 12519 * @ev_param: Pointer to host defined struct to copy the data from event. 12520 * 12521 * Return: QDF_STATUS_SUCCESS on success. 12522 */ 12523 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12524 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12525 { 12526 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12527 wmi_ready_event_fixed_param *ev = NULL; 12528 12529 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12530 ev = param_buf->fixed_param; 12531 12532 ev_param->status = ev->status; 12533 ev_param->num_dscp_table = ev->num_dscp_table; 12534 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12535 ev_param->num_total_peer = ev->num_total_peers; 12536 ev_param->num_extra_peer = ev->num_extra_peers; 12537 /* Agile_capability in ready event is supported in TLV target, 12538 * as per aDFS FR 12539 */ 12540 ev_param->max_ast_index = ev->max_ast_index; 12541 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12542 ev_param->agile_capability = 1; 12543 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12544 12545 return QDF_STATUS_SUCCESS; 12546 } 12547 12548 /** 12549 * extract_dbglog_data_len_tlv() - extract debuglog data length 12550 * @wmi_handle: wmi handle 12551 * @param evt_buf: pointer to event buffer 12552 * 12553 * Return: length 12554 */ 12555 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12556 void *evt_buf, uint32_t *len) 12557 { 12558 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12559 12560 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12561 12562 *len = param_buf->num_bufp; 12563 12564 return param_buf->bufp; 12565 } 12566 12567 12568 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12569 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12570 #else 12571 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12572 ((_status) & WMI_RXERR_DECRYPT) 12573 #endif 12574 12575 /** 12576 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12577 * @wmi_handle: wmi handle 12578 * @param evt_buf: pointer to event buffer 12579 * @param hdr: Pointer to hold header 12580 * @param bufp: Pointer to hold pointer to rx param buffer 12581 * 12582 * Return: QDF_STATUS_SUCCESS for success or error code 12583 */ 12584 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12585 void *evt_buf, struct mgmt_rx_event_params *hdr, 12586 uint8_t **bufp) 12587 { 12588 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12589 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12590 int i; 12591 12592 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12593 if (!param_tlvs) { 12594 wmi_err("Get NULL point message from FW"); 12595 return QDF_STATUS_E_INVAL; 12596 } 12597 12598 ev_hdr = param_tlvs->hdr; 12599 if (!hdr) { 12600 wmi_err("Rx event is NULL"); 12601 return QDF_STATUS_E_INVAL; 12602 } 12603 12604 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12605 wmi_err("RX mgmt frame decrypt error, discard it"); 12606 return QDF_STATUS_E_INVAL; 12607 } 12608 12609 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12610 wmi_err("Rx mgmt frame length mismatch, discard it"); 12611 return QDF_STATUS_E_INVAL; 12612 } 12613 12614 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12615 wmi_handle, 12616 ev_hdr->pdev_id); 12617 hdr->chan_freq = ev_hdr->chan_freq; 12618 hdr->channel = ev_hdr->channel; 12619 hdr->snr = ev_hdr->snr; 12620 hdr->rate = ev_hdr->rate; 12621 hdr->phy_mode = ev_hdr->phy_mode; 12622 hdr->buf_len = ev_hdr->buf_len; 12623 hdr->status = ev_hdr->status; 12624 hdr->flags = ev_hdr->flags; 12625 hdr->rssi = ev_hdr->rssi; 12626 hdr->tsf_delta = ev_hdr->tsf_delta; 12627 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12628 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12629 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12630 12631 *bufp = param_tlvs->bufp; 12632 12633 return QDF_STATUS_SUCCESS; 12634 } 12635 12636 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12637 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12638 { 12639 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12640 wmi_mgmt_rx_params_ext *ext_params_tlv; 12641 wmi_mgmt_rx_hdr *ev_hdr; 12642 12643 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12644 if (!param_tlvs) { 12645 wmi_err("param_tlvs is NULL"); 12646 return QDF_STATUS_E_INVAL; 12647 } 12648 12649 ev_hdr = param_tlvs->hdr; 12650 if (!ev_hdr) { 12651 wmi_err("Rx event is NULL"); 12652 return QDF_STATUS_E_INVAL; 12653 } 12654 12655 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12656 if (ext_params_tlv) { 12657 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12658 ext_params_tlv->mgmt_rx_params_ext_dword1); 12659 if (ext_params->ba_win_size > 1024) { 12660 wmi_err("ba win size from TLV is Invalid"); 12661 return QDF_STATUS_E_INVAL; 12662 } 12663 12664 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12665 ext_params_tlv->mgmt_rx_params_ext_dword1); 12666 if (ext_params->reo_win_size > 2048) { 12667 wmi_err("reo win size from TLV is Invalid"); 12668 return QDF_STATUS_E_INVAL; 12669 } 12670 } else { 12671 ext_params->ba_win_size = 0; 12672 ext_params->reo_win_size = 0; 12673 } 12674 12675 return QDF_STATUS_SUCCESS; 12676 } 12677 12678 #ifdef WLAN_MGMT_RX_REO_SUPPORT 12679 /** 12680 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 12681 * @wmi_handle: wmi handle 12682 * @evt_buf: pointer to event buffer 12683 * @params: Pointer to MGMT Rx REO parameters 12684 * 12685 * Return: QDF_STATUS_SUCCESS for success or error code 12686 */ 12687 static QDF_STATUS 12688 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 12689 void *evt_buf, 12690 struct mgmt_rx_reo_params *params) 12691 { 12692 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 12693 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 12694 12695 param_tlvs = evt_buf; 12696 if (!param_tlvs) { 12697 wmi_err("param_tlvs is NULL"); 12698 return QDF_STATUS_E_INVAL; 12699 } 12700 12701 ev_hdr = param_tlvs->hdr; 12702 if (!params) { 12703 wmi_err("Rx REO parameters is NULL"); 12704 return QDF_STATUS_E_INVAL; 12705 } 12706 12707 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12708 wmi_handle, 12709 ev_hdr->pdev_id); 12710 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 12711 ev_hdr->mgmt_pkt_ctr_info); 12712 params->global_timestamp = ev_hdr->global_timestamp; 12713 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 12714 ev_hdr->mgmt_pkt_ctr_info); 12715 params->duration_us = ev_hdr->rx_ppdu_duration_us; 12716 params->start_timestamp = params->global_timestamp; 12717 params->end_timestamp = params->start_timestamp + 12718 params->duration_us; 12719 12720 return QDF_STATUS_SUCCESS; 12721 } 12722 12723 /** 12724 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 12725 * MGMT_RX_EVENT_ID 12726 * @wmi_handle: wmi handle 12727 * @evt_buf: pointer to event buffer 12728 * @params: Pointer to MGMT Rx REO parameters 12729 * 12730 * Return: QDF_STATUS_SUCCESS for success or error code 12731 */ 12732 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 12733 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 12734 { 12735 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12736 wmi_mgmt_rx_reo_params *reo_params_tlv; 12737 wmi_mgmt_rx_hdr *ev_hdr; 12738 12739 param_tlvs = evt_buf; 12740 if (!param_tlvs) { 12741 wmi_err("param_tlvs is NULL"); 12742 return QDF_STATUS_E_INVAL; 12743 } 12744 12745 ev_hdr = param_tlvs->hdr; 12746 if (!ev_hdr) { 12747 wmi_err("Rx event is NULL"); 12748 return QDF_STATUS_E_INVAL; 12749 } 12750 12751 reo_params_tlv = param_tlvs->reo_params; 12752 if (!reo_params_tlv) { 12753 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 12754 return QDF_STATUS_E_INVAL; 12755 } 12756 12757 if (!reo_params) { 12758 wmi_err("MGMT Rx REO params is NULL"); 12759 return QDF_STATUS_E_INVAL; 12760 } 12761 12762 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12763 wmi_handle, 12764 ev_hdr->pdev_id); 12765 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 12766 reo_params_tlv->mgmt_pkt_ctr_link_info); 12767 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 12768 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 12769 reo_params_tlv->mgmt_pkt_ctr_link_info); 12770 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 12771 reo_params->start_timestamp = reo_params->global_timestamp; 12772 reo_params->end_timestamp = reo_params->start_timestamp + 12773 reo_params->duration_us; 12774 12775 return QDF_STATUS_SUCCESS; 12776 } 12777 12778 /** 12779 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 12780 * configuration command 12781 * @wmi_handle: wmi handle 12782 * @pdev_id: pdev ID of the radio 12783 * @filter: Pointer to MGMT Rx REO filter 12784 * 12785 * Return: QDF_STATUS_SUCCESS for success or error code 12786 */ 12787 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 12788 wmi_unified_t wmi_handle, 12789 uint8_t pdev_id, 12790 struct mgmt_rx_reo_filter *filter) 12791 { 12792 QDF_STATUS ret; 12793 wmi_buf_t buf; 12794 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 12795 size_t len = sizeof(*cmd); 12796 12797 if (!filter) { 12798 wmi_err("mgmt_rx_reo_filter is NULL"); 12799 return QDF_STATUS_E_INVAL; 12800 } 12801 12802 buf = wmi_buf_alloc(wmi_handle, len); 12803 if (!buf) { 12804 wmi_err("wmi_buf_alloc failed"); 12805 return QDF_STATUS_E_NOMEM; 12806 } 12807 12808 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 12809 wmi_buf_data(buf); 12810 12811 WMITLV_SET_HDR(&cmd->tlv_header, 12812 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 12813 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 12814 12815 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12816 wmi_handle, 12817 pdev_id); 12818 cmd->filter_low = filter->low; 12819 cmd->filter_high = filter->high; 12820 12821 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 12822 ret = wmi_unified_cmd_send( 12823 wmi_handle, buf, len, 12824 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 12825 12826 if (QDF_IS_STATUS_ERROR(ret)) { 12827 wmi_err("Failed to send WMI command"); 12828 wmi_buf_free(buf); 12829 } 12830 12831 return ret; 12832 } 12833 #endif 12834 12835 /** 12836 * extract_frame_pn_params_tlv() - extract PN params from event 12837 * @wmi_handle: wmi handle 12838 * @evt_buf: pointer to event buffer 12839 * @pn_params: Pointer to Frame PN params 12840 * 12841 * Return: QDF_STATUS_SUCCESS for success or error code 12842 */ 12843 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 12844 void *evt_buf, 12845 struct frame_pn_params *pn_params) 12846 { 12847 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12848 wmi_frame_pn_params *pn_params_tlv; 12849 12850 if (!is_service_enabled_tlv(wmi_handle, 12851 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 12852 return QDF_STATUS_SUCCESS; 12853 12854 param_tlvs = evt_buf; 12855 if (!param_tlvs) { 12856 wmi_err("Got NULL point message from FW"); 12857 return QDF_STATUS_E_INVAL; 12858 } 12859 12860 if (!pn_params) { 12861 wmi_err("PN Params is NULL"); 12862 return QDF_STATUS_E_INVAL; 12863 } 12864 12865 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 12866 * found by target 12867 */ 12868 pn_params_tlv = param_tlvs->pn_params; 12869 if (!pn_params_tlv) 12870 return QDF_STATUS_SUCCESS; 12871 12872 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 12873 sizeof(pn_params->curr_pn)); 12874 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 12875 sizeof(pn_params->prev_pn)); 12876 12877 return QDF_STATUS_SUCCESS; 12878 } 12879 12880 /** 12881 * extract_is_conn_ap_param_tlv() - extract is_conn_ap_frame param from event 12882 * @wmi_handle: wmi handle 12883 * @evt_buf: pointer to event buffer 12884 * @is_conn_ap: Pointer for is_conn_ap frame 12885 * 12886 * Return: QDF_STATUS_SUCCESS for success or error code 12887 */ 12888 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 12889 wmi_unified_t wmi_handle, 12890 void *evt_buf, 12891 struct frm_conn_ap *is_conn_ap) 12892 { 12893 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12894 wmi_is_my_mgmt_frame *my_frame_tlv; 12895 12896 param_tlvs = evt_buf; 12897 if (!param_tlvs) { 12898 wmi_err("Got NULL point message from FW"); 12899 return QDF_STATUS_E_INVAL; 12900 } 12901 12902 if (!is_conn_ap) { 12903 wmi_err(" is connected ap param is NULL"); 12904 return QDF_STATUS_E_INVAL; 12905 } 12906 12907 my_frame_tlv = param_tlvs->my_frame; 12908 if (!my_frame_tlv) 12909 return QDF_STATUS_SUCCESS; 12910 12911 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 12912 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 12913 12914 return QDF_STATUS_SUCCESS; 12915 } 12916 12917 /** 12918 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 12919 * @wmi_handle: wmi handle 12920 * @param evt_buf: pointer to event buffer 12921 * @param param: Pointer to hold roam param 12922 * 12923 * Return: QDF_STATUS_SUCCESS for success or error code 12924 */ 12925 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 12926 void *evt_buf, wmi_host_roam_event *param) 12927 { 12928 WMI_ROAM_EVENTID_param_tlvs *param_buf; 12929 wmi_roam_event_fixed_param *evt; 12930 12931 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 12932 if (!param_buf) { 12933 wmi_err("Invalid roam event buffer"); 12934 return QDF_STATUS_E_INVAL; 12935 } 12936 12937 evt = param_buf->fixed_param; 12938 qdf_mem_zero(param, sizeof(*param)); 12939 12940 param->vdev_id = evt->vdev_id; 12941 param->reason = evt->reason; 12942 param->rssi = evt->rssi; 12943 12944 return QDF_STATUS_SUCCESS; 12945 } 12946 12947 /** 12948 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 12949 * @wmi_handle: wmi handle 12950 * @param evt_buf: pointer to event buffer 12951 * @param param: Pointer to hold vdev scan param 12952 * 12953 * Return: QDF_STATUS_SUCCESS for success or error code 12954 */ 12955 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 12956 void *evt_buf, struct scan_event *param) 12957 { 12958 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 12959 wmi_scan_event_fixed_param *evt = NULL; 12960 12961 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 12962 evt = param_buf->fixed_param; 12963 12964 qdf_mem_zero(param, sizeof(*param)); 12965 12966 switch (evt->event) { 12967 case WMI_SCAN_EVENT_STARTED: 12968 param->type = SCAN_EVENT_TYPE_STARTED; 12969 break; 12970 case WMI_SCAN_EVENT_COMPLETED: 12971 param->type = SCAN_EVENT_TYPE_COMPLETED; 12972 break; 12973 case WMI_SCAN_EVENT_BSS_CHANNEL: 12974 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 12975 break; 12976 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 12977 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 12978 break; 12979 case WMI_SCAN_EVENT_DEQUEUED: 12980 param->type = SCAN_EVENT_TYPE_DEQUEUED; 12981 break; 12982 case WMI_SCAN_EVENT_PREEMPTED: 12983 param->type = SCAN_EVENT_TYPE_PREEMPTED; 12984 break; 12985 case WMI_SCAN_EVENT_START_FAILED: 12986 param->type = SCAN_EVENT_TYPE_START_FAILED; 12987 break; 12988 case WMI_SCAN_EVENT_RESTARTED: 12989 param->type = SCAN_EVENT_TYPE_RESTARTED; 12990 break; 12991 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 12992 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 12993 break; 12994 case WMI_SCAN_EVENT_MAX: 12995 default: 12996 param->type = SCAN_EVENT_TYPE_MAX; 12997 break; 12998 }; 12999 13000 switch (evt->reason) { 13001 case WMI_SCAN_REASON_NONE: 13002 param->reason = SCAN_REASON_NONE; 13003 break; 13004 case WMI_SCAN_REASON_COMPLETED: 13005 param->reason = SCAN_REASON_COMPLETED; 13006 break; 13007 case WMI_SCAN_REASON_CANCELLED: 13008 param->reason = SCAN_REASON_CANCELLED; 13009 break; 13010 case WMI_SCAN_REASON_PREEMPTED: 13011 param->reason = SCAN_REASON_PREEMPTED; 13012 break; 13013 case WMI_SCAN_REASON_TIMEDOUT: 13014 param->reason = SCAN_REASON_TIMEDOUT; 13015 break; 13016 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13017 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13018 break; 13019 case WMI_SCAN_REASON_SUSPENDED: 13020 param->reason = SCAN_REASON_SUSPENDED; 13021 break; 13022 case WMI_SCAN_REASON_DFS_VIOLATION: 13023 param->reason = SCAN_REASON_DFS_VIOLATION; 13024 break; 13025 case WMI_SCAN_REASON_MAX: 13026 param->reason = SCAN_REASON_MAX; 13027 break; 13028 default: 13029 param->reason = SCAN_REASON_MAX; 13030 break; 13031 }; 13032 13033 param->chan_freq = evt->channel_freq; 13034 param->requester = evt->requestor; 13035 param->scan_id = evt->scan_id; 13036 param->vdev_id = evt->vdev_id; 13037 param->timestamp = evt->tsf_timestamp; 13038 13039 return QDF_STATUS_SUCCESS; 13040 } 13041 13042 #ifdef FEATURE_WLAN_SCAN_PNO 13043 /** 13044 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13045 * @wmi_handle: pointer to WMI handle 13046 * @evt_buf: pointer to WMI event buffer 13047 * @param: pointer to scan event param for NLO match 13048 * 13049 * Return: QDF_STATUS_SUCCESS for success or error code 13050 */ 13051 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13052 void *evt_buf, 13053 struct scan_event *param) 13054 { 13055 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13056 wmi_nlo_event *evt = param_buf->fixed_param; 13057 13058 qdf_mem_zero(param, sizeof(*param)); 13059 13060 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13061 param->vdev_id = evt->vdev_id; 13062 13063 return QDF_STATUS_SUCCESS; 13064 } 13065 13066 /** 13067 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13068 * @wmi_handle: pointer to WMI handle 13069 * @evt_buf: pointer to WMI event buffer 13070 * @param: pointer to scan event param for NLO complete 13071 * 13072 * Return: QDF_STATUS_SUCCESS for success or error code 13073 */ 13074 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13075 void *evt_buf, 13076 struct scan_event *param) 13077 { 13078 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13079 wmi_nlo_event *evt = param_buf->fixed_param; 13080 13081 qdf_mem_zero(param, sizeof(*param)); 13082 13083 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13084 param->vdev_id = evt->vdev_id; 13085 13086 return QDF_STATUS_SUCCESS; 13087 } 13088 #endif 13089 13090 /** 13091 * extract_unit_test_tlv() - extract unit test data 13092 * @wmi_handle: wmi handle 13093 * @param evt_buf: pointer to event buffer 13094 * @param unit_test: pointer to hold unit test data 13095 * @param maxspace: Amount of space in evt_buf 13096 * 13097 * Return: QDF_STATUS_SUCCESS for success or error code 13098 */ 13099 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13100 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13101 { 13102 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13103 wmi_unit_test_event_fixed_param *ev_param; 13104 uint32_t num_bufp; 13105 uint32_t copy_size; 13106 uint8_t *bufp; 13107 13108 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13109 ev_param = param_buf->fixed_param; 13110 bufp = param_buf->bufp; 13111 num_bufp = param_buf->num_bufp; 13112 unit_test->vdev_id = ev_param->vdev_id; 13113 unit_test->module_id = ev_param->module_id; 13114 unit_test->diag_token = ev_param->diag_token; 13115 unit_test->flag = ev_param->flag; 13116 unit_test->payload_len = ev_param->payload_len; 13117 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13118 ev_param->vdev_id, 13119 ev_param->module_id, 13120 ev_param->diag_token, 13121 ev_param->flag); 13122 wmi_debug("Unit-test data given below %d", num_bufp); 13123 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13124 bufp, num_bufp); 13125 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13126 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13127 unit_test->buffer_len = copy_size; 13128 13129 return QDF_STATUS_SUCCESS; 13130 } 13131 13132 /** 13133 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13134 * @wmi_handle: wmi handle 13135 * @param evt_buf: pointer to event buffer 13136 * @param index: Index into extended pdev stats 13137 * @param pdev_ext_stats: Pointer to hold extended pdev stats 13138 * 13139 * Return: QDF_STATUS_SUCCESS for success or error code 13140 */ 13141 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13142 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13143 { 13144 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13145 wmi_pdev_extd_stats *ev; 13146 13147 param_buf = evt_buf; 13148 if (!param_buf) 13149 return QDF_STATUS_E_FAILURE; 13150 13151 if (!param_buf->pdev_extd_stats) 13152 return QDF_STATUS_E_FAILURE; 13153 13154 ev = param_buf->pdev_extd_stats + index; 13155 13156 pdev_ext_stats->pdev_id = 13157 wmi_handle->ops->convert_target_pdev_id_to_host( 13158 wmi_handle, 13159 ev->pdev_id); 13160 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13161 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13162 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13163 13164 return QDF_STATUS_SUCCESS; 13165 } 13166 13167 /** 13168 * extract_bcn_stats_tlv() - extract bcn stats from event 13169 * @wmi_handle: wmi handle 13170 * @param evt_buf: pointer to event buffer 13171 * @param index: Index into vdev stats 13172 * @param bcn_stats: Pointer to hold bcn stats 13173 * 13174 * Return: QDF_STATUS_SUCCESS for success or error code 13175 */ 13176 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13177 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13178 { 13179 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13180 wmi_stats_event_fixed_param *ev_param; 13181 uint8_t *data; 13182 13183 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13184 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13185 data = (uint8_t *) param_buf->data; 13186 13187 if (index < ev_param->num_bcn_stats) { 13188 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13189 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13190 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13191 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13192 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13193 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13194 (index * sizeof(wmi_bcn_stats))); 13195 13196 bcn_stats->vdev_id = ev->vdev_id; 13197 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13198 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13199 } 13200 13201 return QDF_STATUS_SUCCESS; 13202 } 13203 13204 /** 13205 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13206 * stats from event 13207 * @wmi_handle: wmi handle 13208 * @param evt_buf: pointer to event buffer 13209 * @param index: Index into vdev stats 13210 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 13211 * 13212 * Return: QDF_STATUS_SUCCESS for success or error code 13213 */ 13214 static QDF_STATUS 13215 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13216 void *evt_buf, uint32_t index, 13217 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13218 { 13219 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13220 wmi_vdev_extd_stats *ev; 13221 13222 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13223 13224 if (param_buf->vdev_extd_stats) { 13225 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13226 index); 13227 vdev_stats->vdev_id = ev->vdev_id; 13228 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13229 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13230 vdev_stats->unsolicited_prb_succ_cnt = 13231 ev->unsolicited_prb_succ_cnt; 13232 vdev_stats->unsolicited_prb_fail_cnt = 13233 ev->unsolicited_prb_fail_cnt; 13234 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13235 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13236 ev->unsolicited_prb_succ_cnt, 13237 ev->unsolicited_prb_fail_cnt); 13238 } 13239 13240 return QDF_STATUS_SUCCESS; 13241 } 13242 13243 /** 13244 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13245 * @wmi_handle: wmi handle 13246 * @param evt_buf: pointer to event buffer 13247 * @param index: Index into bcn fault stats 13248 * @param bcnflt_stats: Pointer to hold bcn fault stats 13249 * 13250 * Return: QDF_STATUS_SUCCESS for success or error code 13251 */ 13252 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13253 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 13254 { 13255 return QDF_STATUS_SUCCESS; 13256 } 13257 13258 /** 13259 * extract_chan_stats_tlv() - extract chan stats from event 13260 * @wmi_handle: wmi handle 13261 * @param evt_buf: pointer to event buffer 13262 * @param index: Index into chan stats 13263 * @param vdev_extd_stats: Pointer to hold chan stats 13264 * 13265 * Return: QDF_STATUS_SUCCESS for success or error code 13266 */ 13267 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13268 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13269 { 13270 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13271 wmi_stats_event_fixed_param *ev_param; 13272 uint8_t *data; 13273 13274 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13275 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13276 data = (uint8_t *) param_buf->data; 13277 13278 if (index < ev_param->num_chan_stats) { 13279 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13280 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13281 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13282 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13283 (index * sizeof(wmi_chan_stats))); 13284 13285 13286 /* Non-TLV doesn't have num_chan_stats */ 13287 chan_stats->chan_mhz = ev->chan_mhz; 13288 chan_stats->sampling_period_us = ev->sampling_period_us; 13289 chan_stats->rx_clear_count = ev->rx_clear_count; 13290 chan_stats->tx_duration_us = ev->tx_duration_us; 13291 chan_stats->rx_duration_us = ev->rx_duration_us; 13292 } 13293 13294 return QDF_STATUS_SUCCESS; 13295 } 13296 13297 /** 13298 * extract_profile_ctx_tlv() - extract profile context from event 13299 * @wmi_handle: wmi handle 13300 * @param evt_buf: pointer to event buffer 13301 * @idx: profile stats index to extract 13302 * @param profile_ctx: Pointer to hold profile context 13303 * 13304 * Return: QDF_STATUS_SUCCESS for success or error code 13305 */ 13306 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13307 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13308 { 13309 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13310 13311 wmi_wlan_profile_ctx_t *ev; 13312 13313 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13314 if (!param_buf) { 13315 wmi_err("Invalid profile data event buf"); 13316 return QDF_STATUS_E_INVAL; 13317 } 13318 13319 ev = param_buf->profile_ctx; 13320 13321 profile_ctx->tot = ev->tot; 13322 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13323 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13324 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13325 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13326 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13327 profile_ctx->bin_count = ev->bin_count; 13328 13329 return QDF_STATUS_SUCCESS; 13330 } 13331 13332 /** 13333 * extract_profile_data_tlv() - extract profile data from event 13334 * @wmi_handle: wmi handle 13335 * @param evt_buf: pointer to event buffer 13336 * @param profile_data: Pointer to hold profile data 13337 * 13338 * Return: QDF_STATUS_SUCCESS for success or error code 13339 */ 13340 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13341 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13342 { 13343 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13344 wmi_wlan_profile_t *ev; 13345 13346 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13347 if (!param_buf) { 13348 wmi_err("Invalid profile data event buf"); 13349 return QDF_STATUS_E_INVAL; 13350 } 13351 13352 ev = ¶m_buf->profile_data[idx]; 13353 profile_data->id = ev->id; 13354 profile_data->cnt = ev->cnt; 13355 profile_data->tot = ev->tot; 13356 profile_data->min = ev->min; 13357 profile_data->max = ev->max; 13358 profile_data->hist_intvl = ev->hist_intvl; 13359 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13360 13361 return QDF_STATUS_SUCCESS; 13362 } 13363 13364 /** 13365 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13366 * @wmi_handle: WMI handle 13367 * @param evt_buf: Pointer to event buffer 13368 * @param param: Pointer to hold data 13369 * 13370 * Return : QDF_STATUS_SUCCESS for success or error code 13371 */ 13372 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13373 uint8_t *evt_buf, 13374 struct wmi_host_pdev_utf_event *event) 13375 { 13376 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13377 struct wmi_host_utf_seg_header_info *seg_hdr; 13378 13379 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13380 event->data = param_buf->data; 13381 event->datalen = param_buf->num_data; 13382 13383 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13384 wmi_err("Invalid datalen: %d", event->datalen); 13385 return QDF_STATUS_E_INVAL; 13386 } 13387 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13388 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13389 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13390 wmi_handle, 13391 seg_hdr->pdev_id); 13392 13393 return QDF_STATUS_SUCCESS; 13394 } 13395 13396 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13397 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13398 uint8_t *event, 13399 uint32_t *num_rf_characterization_entries) 13400 { 13401 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13402 13403 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13404 if (!param_buf) 13405 return QDF_STATUS_E_INVAL; 13406 13407 *num_rf_characterization_entries = 13408 param_buf->num_wmi_chan_rf_characterization_info; 13409 13410 return QDF_STATUS_SUCCESS; 13411 } 13412 13413 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13414 uint8_t *event, 13415 uint32_t num_rf_characterization_entries, 13416 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13417 { 13418 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13419 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13420 uint8_t ix; 13421 13422 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13423 if (!param_buf) 13424 return QDF_STATUS_E_INVAL; 13425 13426 wmi_rf_characterization_entry = 13427 param_buf->wmi_chan_rf_characterization_info; 13428 if (!wmi_rf_characterization_entry) 13429 return QDF_STATUS_E_INVAL; 13430 13431 /* 13432 * Using num_wmi_chan_rf_characterization instead of param_buf value 13433 * since memory for rf_characterization_entries was allocated using 13434 * the former. 13435 */ 13436 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13437 rf_characterization_entries[ix].freq = 13438 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13439 &wmi_rf_characterization_entry[ix]); 13440 13441 rf_characterization_entries[ix].bw = 13442 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13443 &wmi_rf_characterization_entry[ix]); 13444 13445 rf_characterization_entries[ix].chan_metric = 13446 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13447 &wmi_rf_characterization_entry[ix]); 13448 13449 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13450 "bw: %u, chan_metric: %u", 13451 ix, rf_characterization_entries[ix].freq, 13452 rf_characterization_entries[ix].bw, 13453 rf_characterization_entries[ix].chan_metric); 13454 } 13455 13456 return QDF_STATUS_SUCCESS; 13457 } 13458 #endif 13459 13460 #ifdef WLAN_FEATURE_11BE 13461 static void 13462 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13463 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13464 { 13465 cap->supports_chan_width_320 = 13466 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13467 } 13468 #else 13469 static void 13470 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13471 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13472 { 13473 } 13474 #endif /* WLAN_FEATURE_11BE */ 13475 13476 /** 13477 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13478 * @wmi_handle: wmi handle 13479 * @param evt_buf: pointer to event buffer 13480 * @param param: Pointer to hold evt buf 13481 * 13482 * Return: QDF_STATUS_SUCCESS for success or error code 13483 */ 13484 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13485 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13486 { 13487 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13488 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13489 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13490 uint8_t i = 0, j = 0; 13491 uint32_t num_mac_phy_chainmask_caps = 0; 13492 13493 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13494 if (!param_buf) 13495 return QDF_STATUS_E_INVAL; 13496 13497 hw_caps = param_buf->soc_hw_mode_caps; 13498 if (!hw_caps) 13499 return QDF_STATUS_E_INVAL; 13500 13501 if ((!hw_caps->num_chainmask_tables) || 13502 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13503 (hw_caps->num_chainmask_tables > 13504 param_buf->num_mac_phy_chainmask_combo)) 13505 return QDF_STATUS_E_INVAL; 13506 13507 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13508 13509 if (!chainmask_caps) 13510 return QDF_STATUS_E_INVAL; 13511 13512 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13513 if (chainmask_table[i].num_valid_chainmasks > 13514 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13515 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13516 num_mac_phy_chainmask_caps, i, 13517 chainmask_table[i].num_valid_chainmasks); 13518 return QDF_STATUS_E_INVAL; 13519 } 13520 num_mac_phy_chainmask_caps += 13521 chainmask_table[i].num_valid_chainmasks; 13522 } 13523 13524 if (num_mac_phy_chainmask_caps > 13525 param_buf->num_mac_phy_chainmask_caps) { 13526 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13527 num_mac_phy_chainmask_caps, 13528 param_buf->num_mac_phy_chainmask_caps); 13529 return QDF_STATUS_E_INVAL; 13530 } 13531 13532 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13533 13534 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13535 i); 13536 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13537 13538 chainmask_table[i].cap_list[j].chainmask = 13539 chainmask_caps->chainmask; 13540 13541 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13542 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13543 13544 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13545 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13546 13547 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13548 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13549 13550 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13551 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13552 13553 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13554 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13555 13556 chainmask_table[i].cap_list[j].chain_mask_2G = 13557 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13558 13559 chainmask_table[i].cap_list[j].chain_mask_5G = 13560 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13561 13562 chainmask_table[i].cap_list[j].chain_mask_tx = 13563 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13564 13565 chainmask_table[i].cap_list[j].chain_mask_rx = 13566 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13567 13568 chainmask_table[i].cap_list[j].supports_aDFS = 13569 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13570 13571 chainmask_table[i].cap_list[j].supports_aSpectral = 13572 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13573 13574 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13575 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13576 13577 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13578 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13579 13580 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13581 chainmask_caps); 13582 13583 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13584 chainmask_caps->supported_flags, 13585 chainmask_caps->chainmask); 13586 chainmask_caps++; 13587 } 13588 } 13589 13590 return QDF_STATUS_SUCCESS; 13591 } 13592 13593 /** 13594 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13595 * from event 13596 * @wmi_handle: wmi handle 13597 * @param evt_buf: pointer to event buffer 13598 * @param param: Pointer to hold evt buf 13599 * 13600 * Return: QDF_STATUS_SUCCESS for success or error code 13601 */ 13602 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13603 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13604 { 13605 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13606 wmi_service_ready_ext_event_fixed_param *ev; 13607 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13608 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13609 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13610 uint8_t i = 0; 13611 13612 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13613 if (!param_buf) 13614 return QDF_STATUS_E_INVAL; 13615 13616 ev = param_buf->fixed_param; 13617 if (!ev) 13618 return QDF_STATUS_E_INVAL; 13619 13620 /* Move this to host based bitmap */ 13621 param->default_conc_scan_config_bits = 13622 ev->default_conc_scan_config_bits; 13623 param->default_fw_config_bits = ev->default_fw_config_bits; 13624 param->he_cap_info = ev->he_cap_info; 13625 param->mpdu_density = ev->mpdu_density; 13626 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13627 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13628 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13629 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13630 param->max_bssid_indicator = ev->max_bssid_indicator; 13631 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13632 13633 hw_caps = param_buf->soc_hw_mode_caps; 13634 if (hw_caps) 13635 param->num_hw_modes = hw_caps->num_hw_modes; 13636 else 13637 param->num_hw_modes = 0; 13638 13639 reg_caps = param_buf->soc_hal_reg_caps; 13640 if (reg_caps) 13641 param->num_phy = reg_caps->num_phy; 13642 else 13643 param->num_phy = 0; 13644 13645 if (hw_caps) { 13646 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13647 wmi_nofl_debug("Num chain mask tables: %d", 13648 hw_caps->num_chainmask_tables); 13649 } else 13650 param->num_chainmask_tables = 0; 13651 13652 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13653 param->num_chainmask_tables > 13654 param_buf->num_mac_phy_chainmask_combo) { 13655 wmi_err_rl("num_chainmask_tables is OOB: %u", 13656 param->num_chainmask_tables); 13657 return QDF_STATUS_E_INVAL; 13658 } 13659 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13660 13661 if (!chain_mask_combo) 13662 return QDF_STATUS_SUCCESS; 13663 13664 wmi_nofl_debug("Dumping chain mask combo data"); 13665 13666 for (i = 0; i < param->num_chainmask_tables; i++) { 13667 13668 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 13669 chain_mask_combo->chainmask_table_id, 13670 chain_mask_combo->num_valid_chainmask); 13671 13672 param->chainmask_table[i].table_id = 13673 chain_mask_combo->chainmask_table_id; 13674 param->chainmask_table[i].num_valid_chainmasks = 13675 chain_mask_combo->num_valid_chainmask; 13676 chain_mask_combo++; 13677 } 13678 wmi_nofl_debug("chain mask combo end"); 13679 13680 return QDF_STATUS_SUCCESS; 13681 } 13682 13683 #if defined(CONFIG_AFC_SUPPORT) 13684 /** 13685 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 13686 * type from event 13687 * @ev: pointer to event fixed param 13688 * @param: Pointer to hold the params 13689 * 13690 * Return: void 13691 */ 13692 static void 13693 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13694 struct wlan_psoc_host_service_ext2_param *param) 13695 { 13696 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 13697 enum reg_afc_dev_deploy_type reg_afc_dev_type; 13698 13699 tgt_afc_dev_type = ev->afc_deployment_type; 13700 switch (tgt_afc_dev_type) { 13701 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 13702 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13703 break; 13704 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 13705 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13706 break; 13707 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 13708 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 13709 break; 13710 default: 13711 wmi_err("invalid afc deloyment %d", tgt_afc_dev_type); 13712 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 13713 break; 13714 } 13715 param->afc_dev_type = reg_afc_dev_type; 13716 13717 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 13718 } 13719 #else 13720 static inline void 13721 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13722 struct wlan_psoc_host_service_ext2_param *param) 13723 { 13724 } 13725 #endif 13726 13727 /** 13728 * extract_ul_mumimo_support) - extract UL-MUMIMO capability from target cap 13729 * @param: Pointer to hold the params 13730 * 13731 * Return: Void 13732 */ 13733 static void 13734 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 13735 { 13736 uint32_t tgt_cap = param->target_cap_flags; 13737 13738 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 13739 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 13740 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 13741 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 13742 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 13743 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 13744 } 13745 13746 /** 13747 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 13748 * event 13749 * @wmi_handle: wmi handle 13750 * @event: pointer to event buffer 13751 * @param: Pointer to hold the params 13752 * 13753 * Return: QDF_STATUS_SUCCESS for success or error code 13754 */ 13755 static QDF_STATUS 13756 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 13757 struct wlan_psoc_host_service_ext2_param *param) 13758 { 13759 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13760 wmi_service_ready_ext2_event_fixed_param *ev; 13761 13762 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13763 if (!param_buf) 13764 return QDF_STATUS_E_INVAL; 13765 13766 ev = param_buf->fixed_param; 13767 if (!ev) 13768 return QDF_STATUS_E_INVAL; 13769 13770 param->reg_db_version_major = 13771 WMI_REG_DB_VERSION_MAJOR_GET( 13772 ev->reg_db_version); 13773 param->reg_db_version_minor = 13774 WMI_REG_DB_VERSION_MINOR_GET( 13775 ev->reg_db_version); 13776 param->bdf_reg_db_version_major = 13777 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 13778 ev->reg_db_version); 13779 param->bdf_reg_db_version_minor = 13780 WMI_BDF_REG_DB_VERSION_MINOR_GET( 13781 ev->reg_db_version); 13782 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 13783 13784 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13785 13786 if (param_buf->nan_cap) 13787 param->max_ndp_sessions = 13788 param_buf->nan_cap->max_ndp_sessions; 13789 else 13790 param->max_ndp_sessions = 0; 13791 13792 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 13793 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 13794 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 13795 ev->max_user_per_ppdu_ofdma); 13796 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 13797 ev->max_user_per_ppdu_ofdma); 13798 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 13799 ev->max_user_per_ppdu_mumimo); 13800 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 13801 ev->max_user_per_ppdu_mumimo); 13802 param->target_cap_flags = ev->target_cap_flags; 13803 extract_ul_mumimo_support(param); 13804 wmi_debug("htt peer data :%d", ev->target_cap_flags); 13805 13806 extract_svc_rdy_ext2_afc_tlv(ev, param); 13807 13808 return QDF_STATUS_SUCCESS; 13809 } 13810 13811 /* 13812 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 13813 * service ready ext 2 13814 * 13815 * @wmi_handle: wmi handle 13816 * @event: pointer to event buffer 13817 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 13818 * it indicates async SBS mode is supported, and 13819 * lower-band/higher band to MAC mapping is 13820 * switch-able. unit: mhz. examples 5180, 5320 13821 * 13822 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 13823 */ 13824 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 13825 wmi_unified_t wmi_handle, uint8_t *event, 13826 uint32_t *sbs_lower_band_end_freq) 13827 { 13828 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13829 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 13830 13831 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13832 if (!param_buf) 13833 return QDF_STATUS_E_INVAL; 13834 13835 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 13836 if (!dbs_or_sbs_caps) 13837 return QDF_STATUS_E_INVAL; 13838 13839 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 13840 13841 return QDF_STATUS_SUCCESS; 13842 } 13843 13844 /** 13845 * extract_sar_cap_service_ready_ext_tlv() - 13846 * extract SAR cap from service ready event 13847 * @wmi_handle: wmi handle 13848 * @event: pointer to event buffer 13849 * @ext_param: extended target info 13850 * 13851 * Return: QDF_STATUS_SUCCESS for success or error code 13852 */ 13853 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 13854 wmi_unified_t wmi_handle, 13855 uint8_t *event, 13856 struct wlan_psoc_host_service_ext_param *ext_param) 13857 { 13858 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13859 WMI_SAR_CAPABILITIES *sar_caps; 13860 13861 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 13862 13863 if (!param_buf) 13864 return QDF_STATUS_E_INVAL; 13865 13866 sar_caps = param_buf->sar_caps; 13867 if (sar_caps) 13868 ext_param->sar_version = sar_caps->active_version; 13869 else 13870 ext_param->sar_version = 0; 13871 13872 return QDF_STATUS_SUCCESS; 13873 } 13874 13875 /** 13876 * extract_hw_mode_cap_service_ready_ext_tlv() - 13877 * extract HW mode cap from service ready event 13878 * @wmi_handle: wmi handle 13879 * @param evt_buf: pointer to event buffer 13880 * @param param: Pointer to hold evt buf 13881 * @param hw_mode_idx: hw mode idx should be less than num_mode 13882 * 13883 * Return: QDF_STATUS_SUCCESS for success or error code 13884 */ 13885 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 13886 wmi_unified_t wmi_handle, 13887 uint8_t *event, uint8_t hw_mode_idx, 13888 struct wlan_psoc_host_hw_mode_caps *param) 13889 { 13890 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13891 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13892 13893 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13894 if (!param_buf) 13895 return QDF_STATUS_E_INVAL; 13896 13897 hw_caps = param_buf->soc_hw_mode_caps; 13898 if (!hw_caps) 13899 return QDF_STATUS_E_INVAL; 13900 13901 if (!hw_caps->num_hw_modes || 13902 !param_buf->hw_mode_caps || 13903 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 13904 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 13905 return QDF_STATUS_E_INVAL; 13906 13907 if (hw_mode_idx >= hw_caps->num_hw_modes) 13908 return QDF_STATUS_E_INVAL; 13909 13910 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 13911 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 13912 13913 param->hw_mode_config_type = 13914 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 13915 13916 return QDF_STATUS_SUCCESS; 13917 } 13918 13919 /** 13920 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 13921 * @param param: host mac phy capabilities 13922 * @param mac_phy_caps: mac phy capabilities 13923 * 13924 * Return: void 13925 */ 13926 #ifdef WLAN_FEATURE_11BE 13927 static void 13928 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 13929 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13930 { 13931 param->supports_11be = 13932 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 13933 13934 wmi_debug("11be support %d", param->supports_11be); 13935 } 13936 #else 13937 static void 13938 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 13939 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13940 { 13941 } 13942 #endif 13943 13944 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 13945 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 13946 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13947 { 13948 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 13949 } 13950 #else 13951 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 13952 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 13953 { 13954 } 13955 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 13956 13957 /** 13958 * extract_mac_phy_cap_service_ready_ext_tlv() - 13959 * extract MAC phy cap from service ready event 13960 * @wmi_handle: wmi handle 13961 * @param evt_buf: pointer to event buffer 13962 * @param param: Pointer to hold evt buf 13963 * @param hw_mode_idx: hw mode idx should be less than num_mode 13964 * @param phy_id: phy id within hw_mode 13965 * 13966 * Return: QDF_STATUS_SUCCESS for success or error code 13967 */ 13968 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 13969 wmi_unified_t wmi_handle, 13970 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 13971 struct wlan_psoc_host_mac_phy_caps *param) 13972 { 13973 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13974 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 13975 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13976 uint32_t phy_map; 13977 uint8_t hw_idx, phy_idx = 0, pdev_id; 13978 13979 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13980 if (!param_buf) 13981 return QDF_STATUS_E_INVAL; 13982 13983 hw_caps = param_buf->soc_hw_mode_caps; 13984 if (!hw_caps) 13985 return QDF_STATUS_E_INVAL; 13986 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 13987 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 13988 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 13989 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 13990 return QDF_STATUS_E_INVAL; 13991 } 13992 13993 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 13994 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 13995 break; 13996 13997 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 13998 while (phy_map) { 13999 phy_map >>= 1; 14000 phy_idx++; 14001 } 14002 } 14003 14004 if (hw_idx == hw_caps->num_hw_modes) 14005 return QDF_STATUS_E_INVAL; 14006 14007 phy_idx += phy_id; 14008 if (phy_idx >= param_buf->num_mac_phy_caps) 14009 return QDF_STATUS_E_INVAL; 14010 14011 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14012 14013 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14014 param->phy_idx = phy_idx; 14015 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14016 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14017 wmi_handle, 14018 pdev_id); 14019 param->tgt_pdev_id = pdev_id; 14020 extract_hw_link_id(param, mac_phy_caps); 14021 param->phy_id = mac_phy_caps->phy_id; 14022 param->supports_11b = 14023 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14024 param->supports_11g = 14025 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14026 param->supports_11a = 14027 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14028 param->supports_11n = 14029 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14030 param->supports_11ac = 14031 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14032 param->supports_11ax = 14033 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14034 14035 extract_service_ready_11be_support(param, mac_phy_caps); 14036 14037 param->supported_bands = mac_phy_caps->supported_bands; 14038 param->ampdu_density = mac_phy_caps->ampdu_density; 14039 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14040 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14041 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14042 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14043 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14044 mac_phy_caps->he_cap_info_2G; 14045 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14046 mac_phy_caps->he_cap_info_2G_ext; 14047 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14048 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14049 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14050 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14051 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14052 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14053 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14054 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14055 mac_phy_caps->he_cap_info_5G; 14056 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14057 mac_phy_caps->he_cap_info_5G_ext; 14058 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14059 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14060 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14061 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14062 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14063 &mac_phy_caps->he_cap_phy_info_2G, 14064 sizeof(param->he_cap_phy_info_2G)); 14065 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14066 &mac_phy_caps->he_cap_phy_info_5G, 14067 sizeof(param->he_cap_phy_info_5G)); 14068 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14069 sizeof(param->he_ppet2G)); 14070 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14071 sizeof(param->he_ppet5G)); 14072 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14073 param->lmac_id = mac_phy_caps->lmac_id; 14074 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14075 (mac_phy_caps->wireless_modes); 14076 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14077 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14078 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14079 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14080 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14081 mac_phy_caps->nss_ratio); 14082 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14083 14084 return QDF_STATUS_SUCCESS; 14085 } 14086 14087 #ifdef WLAN_FEATURE_11BE_MLO 14088 /** 14089 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14090 * @param: host ext2 mac phy capabilities 14091 * @mac_phy_caps: ext mac phy capabilities 14092 * 14093 * Return: void 14094 */ 14095 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14096 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14097 { 14098 if (!param || !mac_phy_caps) 14099 return; 14100 14101 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14102 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14103 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14104 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14105 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14106 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14107 } 14108 14109 /** 14110 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14111 * @param: host ext2 mac phy capabilities 14112 * @mac_phy_caps: ext mac phy capabilities 14113 * 14114 * Return: void 14115 */ 14116 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14117 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14118 { 14119 if (!param || !mac_phy_caps) 14120 return; 14121 14122 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14123 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14124 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14125 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14126 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14127 } 14128 #else 14129 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14130 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14131 { 14132 } 14133 14134 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14135 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14136 { 14137 } 14138 #endif 14139 14140 /** 14141 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14142 * @param param: host ext2 mac phy capabilities 14143 * @param mac_phy_caps: ext mac phy capabilities 14144 * 14145 * Return: void 14146 */ 14147 #ifdef WLAN_FEATURE_11BE 14148 static void extract_mac_phy_cap_ehtcaps( 14149 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14150 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14151 { 14152 uint32_t i; 14153 14154 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14155 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14156 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14157 14158 qdf_mem_copy(¶m->eht_cap_info_2G, 14159 &mac_phy_caps->eht_cap_mac_info_2G, 14160 sizeof(param->eht_cap_info_2G)); 14161 qdf_mem_copy(¶m->eht_cap_info_5G, 14162 &mac_phy_caps->eht_cap_mac_info_5G, 14163 sizeof(param->eht_cap_info_5G)); 14164 14165 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14166 &mac_phy_caps->eht_cap_phy_info_2G, 14167 sizeof(param->eht_cap_phy_info_2G)); 14168 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14169 &mac_phy_caps->eht_cap_phy_info_5G, 14170 sizeof(param->eht_cap_phy_info_5G)); 14171 14172 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14173 &mac_phy_caps->eht_supp_mcs_ext_2G, 14174 sizeof(param->eht_supp_mcs_ext_2G)); 14175 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14176 &mac_phy_caps->eht_supp_mcs_ext_5G, 14177 sizeof(param->eht_supp_mcs_ext_5G)); 14178 14179 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14180 sizeof(param->eht_ppet2G)); 14181 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14182 sizeof(param->eht_ppet5G)); 14183 14184 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", 14185 mac_phy_caps->eht_cap_mac_info_2G[0], 14186 mac_phy_caps->eht_cap_mac_info_5G[0], 14187 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14188 mac_phy_caps->eht_cap_info_internal); 14189 14190 wmi_nofl_debug("EHT phy caps: "); 14191 14192 wmi_nofl_debug("2G:"); 14193 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14194 wmi_nofl_debug("index %d value %x", 14195 i, param->eht_cap_phy_info_2G[i]); 14196 } 14197 wmi_nofl_debug("5G:"); 14198 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14199 wmi_nofl_debug("index %d value %x", 14200 i, param->eht_cap_phy_info_5G[i]); 14201 } 14202 wmi_nofl_debug("2G MCS ext Map:"); 14203 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14204 wmi_nofl_debug("index %d value %x", 14205 i, param->eht_supp_mcs_ext_2G[i]); 14206 } 14207 wmi_nofl_debug("5G MCS ext Map:"); 14208 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14209 wmi_nofl_debug("index %d value %x", 14210 i, param->eht_supp_mcs_ext_5G[i]); 14211 } 14212 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14213 param->eht_ppet2G.numss_m1, 14214 param->eht_ppet2G.ru_bit_mask); 14215 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14216 wmi_nofl_debug("index %d value %x", 14217 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14218 } 14219 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14220 param->eht_ppet5G.numss_m1, 14221 param->eht_ppet5G.ru_bit_mask); 14222 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14223 wmi_nofl_debug("index %d value %x", 14224 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14225 } 14226 } 14227 #else 14228 static void extract_mac_phy_cap_ehtcaps( 14229 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14230 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14231 { 14232 } 14233 #endif 14234 14235 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14236 wmi_unified_t wmi_handle, 14237 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14238 uint8_t phy_idx, 14239 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14240 { 14241 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14242 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14243 14244 if (!event) { 14245 wmi_err("null evt_buf"); 14246 return QDF_STATUS_E_INVAL; 14247 } 14248 14249 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14250 14251 if (!param_buf->num_mac_phy_caps) 14252 return QDF_STATUS_SUCCESS; 14253 14254 if (phy_idx >= param_buf->num_mac_phy_caps) 14255 return QDF_STATUS_E_INVAL; 14256 14257 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14258 14259 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14260 (phy_id != mac_phy_caps->phy_id)) 14261 return QDF_STATUS_E_INVAL; 14262 14263 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14264 param->phy_id = mac_phy_caps->phy_id; 14265 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14266 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14267 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14268 mac_phy_caps->wireless_modes_ext); 14269 14270 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14271 extract_mac_phy_emlcap(param, mac_phy_caps); 14272 extract_mac_phy_mldcap(param, mac_phy_caps); 14273 14274 return QDF_STATUS_SUCCESS; 14275 } 14276 14277 /** 14278 * extract_reg_cap_service_ready_ext_tlv() - 14279 * extract REG cap from service ready event 14280 * @wmi_handle: wmi handle 14281 * @param evt_buf: pointer to event buffer 14282 * @param param: Pointer to hold evt buf 14283 * @param phy_idx: phy idx should be less than num_mode 14284 * 14285 * Return: QDF_STATUS_SUCCESS for success or error code 14286 */ 14287 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14288 wmi_unified_t wmi_handle, 14289 uint8_t *event, uint8_t phy_idx, 14290 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14291 { 14292 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14293 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14294 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14295 14296 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14297 if (!param_buf) 14298 return QDF_STATUS_E_INVAL; 14299 14300 reg_caps = param_buf->soc_hal_reg_caps; 14301 if (!reg_caps) 14302 return QDF_STATUS_E_INVAL; 14303 14304 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14305 return QDF_STATUS_E_INVAL; 14306 14307 if (phy_idx >= reg_caps->num_phy) 14308 return QDF_STATUS_E_INVAL; 14309 14310 if (!param_buf->hal_reg_caps) 14311 return QDF_STATUS_E_INVAL; 14312 14313 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14314 14315 param->phy_id = ext_reg_cap->phy_id; 14316 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14317 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14318 param->regcap1 = ext_reg_cap->regcap1; 14319 param->regcap2 = ext_reg_cap->regcap2; 14320 param->wireless_modes = convert_wireless_modes_tlv( 14321 ext_reg_cap->wireless_modes); 14322 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14323 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14324 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14325 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14326 14327 return QDF_STATUS_SUCCESS; 14328 } 14329 14330 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14331 uint8_t num_dma_ring_caps) 14332 { 14333 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14334 if (!num_dma_ring_caps) { 14335 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14336 return QDF_STATUS_E_INVAL; 14337 } 14338 if (idx >= num_dma_ring_caps) { 14339 wmi_err("Index %d exceeds range", idx); 14340 return QDF_STATUS_E_INVAL; 14341 } 14342 return QDF_STATUS_SUCCESS; 14343 } 14344 14345 static void 14346 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14347 struct wlan_psoc_host_dbr_ring_caps *param, 14348 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14349 { 14350 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14351 wmi_handle, 14352 dbr_ring_caps->pdev_id); 14353 param->mod_id = dbr_ring_caps->mod_id; 14354 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14355 param->min_buf_size = dbr_ring_caps->min_buf_size; 14356 param->min_buf_align = dbr_ring_caps->min_buf_align; 14357 } 14358 14359 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14360 wmi_unified_t wmi_handle, 14361 uint8_t *event, uint8_t idx, 14362 struct wlan_psoc_host_dbr_ring_caps *param) 14363 { 14364 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14365 QDF_STATUS status; 14366 14367 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14368 if (!param_buf) 14369 return QDF_STATUS_E_INVAL; 14370 14371 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14372 if (status != QDF_STATUS_SUCCESS) 14373 return status; 14374 14375 populate_dbr_ring_cap_elems(wmi_handle, param, 14376 ¶m_buf->dma_ring_caps[idx]); 14377 return QDF_STATUS_SUCCESS; 14378 } 14379 14380 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14381 wmi_unified_t wmi_handle, 14382 uint8_t *event, uint8_t idx, 14383 struct wlan_psoc_host_dbr_ring_caps *param) 14384 { 14385 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14386 QDF_STATUS status; 14387 14388 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14389 if (!param_buf) 14390 return QDF_STATUS_E_INVAL; 14391 14392 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14393 if (status != QDF_STATUS_SUCCESS) 14394 return status; 14395 14396 populate_dbr_ring_cap_elems(wmi_handle, param, 14397 ¶m_buf->dma_ring_caps[idx]); 14398 return QDF_STATUS_SUCCESS; 14399 } 14400 14401 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14402 wmi_unified_t wmi_handle, 14403 uint8_t *event, uint8_t idx, 14404 struct wlan_psoc_host_scan_radio_caps *param) 14405 { 14406 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14407 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14408 14409 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14410 if (!param_buf) 14411 return QDF_STATUS_E_INVAL; 14412 14413 if (idx >= param_buf->num_wmi_scan_radio_caps) 14414 return QDF_STATUS_E_INVAL; 14415 14416 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14417 param->phy_id = scan_radio_caps->phy_id; 14418 param->scan_radio_supported = 14419 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14420 param->dfs_en = 14421 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14422 14423 return QDF_STATUS_SUCCESS; 14424 } 14425 14426 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14427 uint8_t *event, 14428 struct wmi_host_sw_cal_ver *cal) 14429 { 14430 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14431 wmi_sw_cal_ver_cap *fw_cap; 14432 14433 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14434 if (!param_buf) 14435 return QDF_STATUS_E_INVAL; 14436 14437 fw_cap = param_buf->sw_cal_ver_cap; 14438 if (!fw_cap) 14439 return QDF_STATUS_E_INVAL; 14440 14441 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14442 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14443 cal->status = fw_cap->status; 14444 14445 return QDF_STATUS_SUCCESS; 14446 } 14447 14448 /** 14449 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14450 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14451 * 14452 * Return: host thermal throt level 14453 */ 14454 static enum thermal_throttle_level 14455 wmi_tgt_thermal_level_to_host(uint32_t level) 14456 { 14457 switch (level) { 14458 case WMI_THERMAL_FULLPERF: 14459 return THERMAL_FULLPERF; 14460 case WMI_THERMAL_MITIGATION: 14461 return THERMAL_MITIGATION; 14462 case WMI_THERMAL_SHUTOFF: 14463 return THERMAL_SHUTOFF; 14464 case WMI_THERMAL_SHUTDOWN_TGT: 14465 return THERMAL_SHUTDOWN_TARGET; 14466 default: 14467 return THERMAL_UNKNOWN; 14468 } 14469 } 14470 14471 #ifdef THERMAL_STATS_SUPPORT 14472 static void 14473 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14474 uint32_t *therm_throt_levels, 14475 struct thermal_throt_level_stats *tt_temp_range_stats) 14476 { 14477 uint8_t lvl_idx; 14478 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14479 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14480 14481 tt_stats_event = param_buf->fixed_param; 14482 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14483 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14484 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14485 tt_stats_event->therm_throt_levels; 14486 14487 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14488 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14489 *therm_throt_levels, 14490 param_buf->num_temp_range_stats); 14491 return; 14492 } 14493 14494 wmi_tt_stats = param_buf->temp_range_stats; 14495 if (!wmi_tt_stats) { 14496 wmi_err("wmi_tt_stats Null"); 14497 return; 14498 } 14499 14500 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14501 tt_temp_range_stats[lvl_idx].start_temp_level = 14502 wmi_tt_stats[lvl_idx].start_temp_level; 14503 tt_temp_range_stats[lvl_idx].end_temp_level = 14504 wmi_tt_stats[lvl_idx].end_temp_level; 14505 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14506 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14507 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14508 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14509 tt_temp_range_stats[lvl_idx].num_entry = 14510 wmi_tt_stats[lvl_idx].num_entry; 14511 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14512 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14513 wmi_tt_stats[lvl_idx].end_temp_level, 14514 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14515 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14516 wmi_tt_stats[lvl_idx].num_entry); 14517 } 14518 } 14519 #else 14520 static void 14521 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14522 uint32_t *therm_throt_levels, 14523 struct thermal_throt_level_stats *tt_temp_range_stats) 14524 { 14525 } 14526 #endif 14527 14528 /** 14529 * extract_thermal_stats_tlv() - extract thermal stats from event 14530 * @wmi_handle: wmi handle 14531 * @param evt_buf: Pointer to event buffer 14532 * @param temp: Pointer to hold extracted temperature 14533 * @param level: Pointer to hold extracted level in host enum 14534 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 14535 * range 14536 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14537 * every level 14538 * 14539 * Return: 0 for success or error code 14540 */ 14541 static QDF_STATUS 14542 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14543 void *evt_buf, uint32_t *temp, 14544 enum thermal_throttle_level *level, 14545 uint32_t *therm_throt_levels, 14546 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14547 uint32_t *pdev_id) 14548 { 14549 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14550 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14551 14552 param_buf = 14553 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14554 if (!param_buf) 14555 return QDF_STATUS_E_INVAL; 14556 14557 tt_stats_event = param_buf->fixed_param; 14558 wmi_debug("thermal temperature %d level %d", 14559 tt_stats_event->temp, tt_stats_event->level); 14560 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14561 wmi_handle, 14562 tt_stats_event->pdev_id); 14563 *temp = tt_stats_event->temp; 14564 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14565 14566 if (tt_stats_event->therm_throt_levels) 14567 populate_thermal_stats(param_buf, therm_throt_levels, 14568 tt_temp_range_stats_event); 14569 14570 return QDF_STATUS_SUCCESS; 14571 } 14572 14573 /** 14574 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14575 * @wmi_handle: wmi handle 14576 * @param evt_buf: pointer to event buffer 14577 * @param idx: Index to level stats 14578 * @param levelcount: Pointer to hold levelcount 14579 * @param dccount: Pointer to hold dccount 14580 * 14581 * Return: 0 for success or error code 14582 */ 14583 static QDF_STATUS 14584 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14585 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14586 uint32_t *dccount) 14587 { 14588 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14589 wmi_therm_throt_level_stats_info *tt_level_info; 14590 14591 param_buf = 14592 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14593 if (!param_buf) 14594 return QDF_STATUS_E_INVAL; 14595 14596 tt_level_info = param_buf->therm_throt_level_stats_info; 14597 14598 if (idx < THERMAL_LEVELS) { 14599 *levelcount = tt_level_info[idx].level_count; 14600 *dccount = tt_level_info[idx].dc_count; 14601 return QDF_STATUS_SUCCESS; 14602 } 14603 14604 return QDF_STATUS_E_FAILURE; 14605 } 14606 #ifdef BIG_ENDIAN_HOST 14607 /** 14608 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14609 * @param data_len - data length 14610 * @param data - pointer to data 14611 * 14612 * Return: QDF_STATUS - success or error status 14613 */ 14614 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14615 { 14616 uint8_t *data_aligned = NULL; 14617 int c; 14618 unsigned char *data_unaligned; 14619 14620 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 14621 FIPS_ALIGN)); 14622 /* Assigning unaligned space to copy the data */ 14623 /* Checking if kmalloc does successful allocation */ 14624 if (!data_unaligned) 14625 return QDF_STATUS_E_FAILURE; 14626 14627 /* Checking if space is alligned */ 14628 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14629 /* align the data space */ 14630 data_aligned = 14631 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 14632 } else { 14633 data_aligned = (u_int8_t *)data_unaligned; 14634 } 14635 14636 /* memset and copy content from data to data aligned */ 14637 OS_MEMSET(data_aligned, 0, data_len); 14638 OS_MEMCPY(data_aligned, data, data_len); 14639 /* Endianness to LE */ 14640 for (c = 0; c < data_len/4; c++) { 14641 *((u_int32_t *)data_aligned + c) = 14642 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 14643 } 14644 14645 /* Copy content to event->data */ 14646 OS_MEMCPY(data, data_aligned, data_len); 14647 14648 /* clean up allocated space */ 14649 qdf_mem_free(data_unaligned); 14650 data_aligned = NULL; 14651 data_unaligned = NULL; 14652 14653 /*************************************************************/ 14654 14655 return QDF_STATUS_SUCCESS; 14656 } 14657 #else 14658 /** 14659 * fips_conv_data_be() - DUMMY for LE platform 14660 * 14661 * Return: QDF_STATUS - success 14662 */ 14663 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14664 { 14665 return QDF_STATUS_SUCCESS; 14666 } 14667 #endif 14668 14669 /** 14670 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 14671 * @wmi_handle - wmi handle 14672 * @params - PN request params for peer 14673 * 14674 * Return: QDF_STATUS - success or error status 14675 */ 14676 static QDF_STATUS 14677 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 14678 struct peer_request_pn_param *params) 14679 { 14680 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 14681 wmi_buf_t buf; 14682 uint8_t *buf_ptr; 14683 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 14684 14685 buf = wmi_buf_alloc(wmi_handle, len); 14686 if (!buf) { 14687 wmi_err("wmi_buf_alloc failed"); 14688 return QDF_STATUS_E_FAILURE; 14689 } 14690 14691 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14692 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 14693 14694 WMITLV_SET_HDR(&cmd->tlv_header, 14695 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 14696 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 14697 14698 cmd->vdev_id = params->vdev_id; 14699 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14700 cmd->key_type = params->key_type; 14701 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14702 WMI_PEER_TX_PN_REQUEST_CMDID)) { 14703 wmi_err("Failed to send WMI command"); 14704 wmi_buf_free(buf); 14705 return QDF_STATUS_E_FAILURE; 14706 } 14707 return QDF_STATUS_SUCCESS; 14708 } 14709 14710 /** 14711 * extract_get_pn_data_tlv() - extract pn resp 14712 * @wmi_handle - wmi handle 14713 * @params - PN response params for peer 14714 * 14715 * Return: QDF_STATUS - success or error status 14716 */ 14717 static QDF_STATUS 14718 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14719 struct wmi_host_get_pn_event *param) 14720 { 14721 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14722 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 14723 14724 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 14725 event = 14726 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 14727 14728 param->vdev_id = event->vdev_id; 14729 param->key_type = event->key_type; 14730 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 14731 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 14732 14733 return QDF_STATUS_SUCCESS; 14734 } 14735 14736 /** 14737 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 14738 * @wmi_handle: wmi handle 14739 * @params: Rx PN request params for peer 14740 * 14741 * Return: QDF_STATUS - success or error status 14742 */ 14743 static QDF_STATUS 14744 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 14745 struct peer_request_rxpn_param *params) 14746 { 14747 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 14748 wmi_buf_t buf; 14749 uint8_t *buf_ptr; 14750 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 14751 14752 if (!is_service_enabled_tlv(wmi_handle, 14753 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 14754 wmi_err("Rx PN Replay Check not supported by target"); 14755 return QDF_STATUS_E_NOSUPPORT; 14756 } 14757 14758 buf = wmi_buf_alloc(wmi_handle, len); 14759 if (!buf) { 14760 wmi_err("wmi_buf_alloc failed"); 14761 return QDF_STATUS_E_FAILURE; 14762 } 14763 14764 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14765 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 14766 14767 WMITLV_SET_HDR(&cmd->tlv_header, 14768 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 14769 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 14770 14771 cmd->vdev_id = params->vdev_id; 14772 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14773 cmd->key_ix = params->keyix; 14774 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14775 WMI_PEER_RX_PN_REQUEST_CMDID)) { 14776 wmi_err("Failed to send WMI command"); 14777 wmi_buf_free(buf); 14778 return QDF_STATUS_E_FAILURE; 14779 } 14780 return QDF_STATUS_SUCCESS; 14781 } 14782 14783 /** 14784 * extract_get_rxpn_data_tlv() - extract Rx PN resp 14785 * @wmi_handle: wmi handle 14786 * @params: Rx PN response params for peer 14787 * 14788 * Return: QDF_STATUS - success or error status 14789 */ 14790 static QDF_STATUS 14791 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14792 struct wmi_host_get_rxpn_event *params) 14793 { 14794 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14795 wmi_peer_rx_pn_response_event_fixed_param *event; 14796 14797 param_buf = evt_buf; 14798 event = param_buf->fixed_param; 14799 14800 params->vdev_id = event->vdev_id; 14801 params->keyix = event->key_idx; 14802 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 14803 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 14804 14805 return QDF_STATUS_SUCCESS; 14806 } 14807 14808 /** 14809 * extract_fips_event_data_tlv() - extract fips event data 14810 * @wmi_handle: wmi handle 14811 * @param evt_buf: pointer to event buffer 14812 * @param param: pointer FIPS event params 14813 * 14814 * Return: 0 for success or error code 14815 */ 14816 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 14817 void *evt_buf, struct wmi_host_fips_event_param *param) 14818 { 14819 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 14820 wmi_pdev_fips_event_fixed_param *event; 14821 14822 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 14823 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 14824 14825 if (event->data_len > param_buf->num_data) 14826 return QDF_STATUS_E_FAILURE; 14827 14828 if (fips_conv_data_be(event->data_len, param_buf->data) != 14829 QDF_STATUS_SUCCESS) 14830 return QDF_STATUS_E_FAILURE; 14831 14832 param->data = (uint32_t *)param_buf->data; 14833 param->data_len = event->data_len; 14834 param->error_status = event->error_status; 14835 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14836 wmi_handle, 14837 event->pdev_id); 14838 14839 return QDF_STATUS_SUCCESS; 14840 } 14841 14842 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 14843 /** 14844 * extract_fips_extend_event_data_tlv() - extract fips event data 14845 * @wmi_handle: wmi handle 14846 * @param evt_buf: pointer to event buffer 14847 * @param param: pointer FIPS event params 14848 * 14849 * Return: 0 for success or error code 14850 */ 14851 static QDF_STATUS 14852 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 14853 void *evt_buf, 14854 struct wmi_host_fips_extend_event_param 14855 *param) 14856 { 14857 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 14858 wmi_pdev_fips_extend_event_fixed_param *event; 14859 14860 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 14861 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 14862 14863 if (fips_conv_data_be(event->data_len, param_buf->data) != 14864 QDF_STATUS_SUCCESS) 14865 return QDF_STATUS_E_FAILURE; 14866 14867 param->data = (uint32_t *)param_buf->data; 14868 param->data_len = event->data_len; 14869 param->error_status = event->error_status; 14870 param->fips_cookie = event->fips_cookie; 14871 param->cmd_frag_idx = event->cmd_frag_idx; 14872 param->more_bit = event->more_bit; 14873 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14874 wmi_handle, 14875 event->pdev_id); 14876 14877 return QDF_STATUS_SUCCESS; 14878 } 14879 #endif 14880 14881 #ifdef WLAN_FEATURE_DISA 14882 /** 14883 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 14884 * params from event 14885 * @wmi_handle: wmi handle 14886 * @evt_buf: pointer to event buffer 14887 * @resp: Pointer to hold resp parameters 14888 * 14889 * Return: QDF_STATUS_SUCCESS for success or error code 14890 */ 14891 static QDF_STATUS 14892 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 14893 void *evt_buf, 14894 struct disa_encrypt_decrypt_resp_params 14895 *resp) 14896 { 14897 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 14898 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 14899 14900 param_buf = evt_buf; 14901 if (!param_buf) { 14902 wmi_err("encrypt decrypt resp evt_buf is NULL"); 14903 return QDF_STATUS_E_INVAL; 14904 } 14905 14906 data_event = param_buf->fixed_param; 14907 14908 resp->vdev_id = data_event->vdev_id; 14909 resp->status = data_event->status; 14910 14911 if ((data_event->data_length > param_buf->num_enc80211_frame) || 14912 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 14913 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 14914 wmi_err("FW msg data_len %d more than TLV hdr %d", 14915 data_event->data_length, 14916 param_buf->num_enc80211_frame); 14917 return QDF_STATUS_E_INVAL; 14918 } 14919 14920 resp->data_len = data_event->data_length; 14921 14922 if (resp->data_len) 14923 resp->data = (uint8_t *)param_buf->enc80211_frame; 14924 14925 return QDF_STATUS_SUCCESS; 14926 } 14927 #endif /* WLAN_FEATURE_DISA */ 14928 14929 static bool is_management_record_tlv(uint32_t cmd_id) 14930 { 14931 switch (cmd_id) { 14932 case WMI_MGMT_TX_SEND_CMDID: 14933 case WMI_MGMT_TX_COMPLETION_EVENTID: 14934 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 14935 case WMI_MGMT_RX_EVENTID: 14936 return true; 14937 default: 14938 return false; 14939 } 14940 } 14941 14942 static bool is_diag_event_tlv(uint32_t event_id) 14943 { 14944 if (WMI_DIAG_EVENTID == event_id) 14945 return true; 14946 14947 return false; 14948 } 14949 14950 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 14951 { 14952 uint16_t tag = 0; 14953 14954 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 14955 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 14956 __func__); 14957 return tag; 14958 } 14959 14960 if (wmi_handle->tag_crash_inject) 14961 tag = HTC_TX_PACKET_TAG_AUTO_PM; 14962 14963 wmi_handle->tag_crash_inject = false; 14964 return tag; 14965 } 14966 14967 /** 14968 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 14969 * @wmi_handle: WMI handle 14970 * @buf: WMI buffer 14971 * @cmd_id: WMI command Id 14972 * 14973 * Return htc_tx_tag 14974 */ 14975 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 14976 wmi_buf_t buf, 14977 uint32_t cmd_id) 14978 { 14979 uint16_t htc_tx_tag = 0; 14980 14981 switch (cmd_id) { 14982 case WMI_WOW_ENABLE_CMDID: 14983 case WMI_PDEV_SUSPEND_CMDID: 14984 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 14985 case WMI_PDEV_RESUME_CMDID: 14986 case WMI_HB_SET_ENABLE_CMDID: 14987 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 14988 #ifdef FEATURE_WLAN_D0WOW 14989 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 14990 #endif 14991 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 14992 break; 14993 case WMI_FORCE_FW_HANG_CMDID: 14994 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 14995 break; 14996 default: 14997 break; 14998 } 14999 15000 return htc_tx_tag; 15001 } 15002 15003 #ifdef CONFIG_BAND_6GHZ 15004 #ifdef CONFIG_REG_CLIENT 15005 /** 15006 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15007 * @num_fcc_rules: Number of FCC rules 15008 * @wmi_fcc_rule: WMI FCC rules TLV 15009 * 15010 * Return fcc_rule_ptr 15011 */ 15012 static struct cur_fcc_rule 15013 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15014 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15015 { 15016 struct cur_fcc_rule *fcc_rule_ptr; 15017 uint32_t count; 15018 15019 if (!wmi_fcc_rule) 15020 return NULL; 15021 15022 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15023 sizeof(*fcc_rule_ptr)); 15024 if (!fcc_rule_ptr) 15025 return NULL; 15026 15027 for (count = 0; count < num_fcc_rules; count++) { 15028 fcc_rule_ptr[count].center_freq = 15029 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15030 wmi_fcc_rule[count].freq_info); 15031 fcc_rule_ptr[count].tx_power = 15032 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15033 wmi_fcc_rule[count].freq_info); 15034 } 15035 15036 return fcc_rule_ptr; 15037 } 15038 #endif 15039 15040 static struct cur_reg_rule 15041 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15042 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15043 { 15044 struct cur_reg_rule *reg_rule_ptr; 15045 uint32_t count; 15046 15047 if (!num_reg_rules) 15048 return NULL; 15049 15050 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15051 sizeof(*reg_rule_ptr)); 15052 15053 if (!reg_rule_ptr) 15054 return NULL; 15055 15056 for (count = 0; count < num_reg_rules; count++) { 15057 reg_rule_ptr[count].start_freq = 15058 WMI_REG_RULE_START_FREQ_GET( 15059 wmi_reg_rule[count].freq_info); 15060 reg_rule_ptr[count].end_freq = 15061 WMI_REG_RULE_END_FREQ_GET( 15062 wmi_reg_rule[count].freq_info); 15063 reg_rule_ptr[count].max_bw = 15064 WMI_REG_RULE_MAX_BW_GET( 15065 wmi_reg_rule[count].bw_pwr_info); 15066 reg_rule_ptr[count].reg_power = 15067 WMI_REG_RULE_REG_POWER_GET( 15068 wmi_reg_rule[count].bw_pwr_info); 15069 reg_rule_ptr[count].ant_gain = 15070 WMI_REG_RULE_ANTENNA_GAIN_GET( 15071 wmi_reg_rule[count].bw_pwr_info); 15072 reg_rule_ptr[count].flags = 15073 WMI_REG_RULE_FLAGS_GET( 15074 wmi_reg_rule[count].flag_info); 15075 reg_rule_ptr[count].psd_flag = 15076 WMI_REG_RULE_PSD_FLAG_GET( 15077 wmi_reg_rule[count].psd_power_info); 15078 reg_rule_ptr[count].psd_eirp = 15079 WMI_REG_RULE_PSD_EIRP_GET( 15080 wmi_reg_rule[count].psd_power_info); 15081 } 15082 15083 return reg_rule_ptr; 15084 } 15085 #endif 15086 15087 static struct cur_reg_rule 15088 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15089 wmi_regulatory_rule_struct *wmi_reg_rule) 15090 { 15091 struct cur_reg_rule *reg_rule_ptr; 15092 uint32_t count; 15093 15094 if (!num_reg_rules) 15095 return NULL; 15096 15097 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15098 sizeof(*reg_rule_ptr)); 15099 15100 if (!reg_rule_ptr) 15101 return NULL; 15102 15103 for (count = 0; count < num_reg_rules; count++) { 15104 reg_rule_ptr[count].start_freq = 15105 WMI_REG_RULE_START_FREQ_GET( 15106 wmi_reg_rule[count].freq_info); 15107 reg_rule_ptr[count].end_freq = 15108 WMI_REG_RULE_END_FREQ_GET( 15109 wmi_reg_rule[count].freq_info); 15110 reg_rule_ptr[count].max_bw = 15111 WMI_REG_RULE_MAX_BW_GET( 15112 wmi_reg_rule[count].bw_pwr_info); 15113 reg_rule_ptr[count].reg_power = 15114 WMI_REG_RULE_REG_POWER_GET( 15115 wmi_reg_rule[count].bw_pwr_info); 15116 reg_rule_ptr[count].ant_gain = 15117 WMI_REG_RULE_ANTENNA_GAIN_GET( 15118 wmi_reg_rule[count].bw_pwr_info); 15119 reg_rule_ptr[count].flags = 15120 WMI_REG_RULE_FLAGS_GET( 15121 wmi_reg_rule[count].flag_info); 15122 } 15123 15124 return reg_rule_ptr; 15125 } 15126 15127 static enum cc_setting_code wmi_reg_status_to_reg_status( 15128 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15129 { 15130 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 15131 return REG_SET_CC_STATUS_PASS; 15132 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 15133 return REG_CURRENT_ALPHA2_NOT_FOUND; 15134 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 15135 return REG_INIT_ALPHA2_NOT_FOUND; 15136 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 15137 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15138 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 15139 return REG_SET_CC_STATUS_NO_MEMORY; 15140 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 15141 return REG_SET_CC_STATUS_FAIL; 15142 15143 wmi_debug("Unknown reg status code from WMI"); 15144 return REG_SET_CC_STATUS_FAIL; 15145 } 15146 15147 #ifdef CONFIG_BAND_6GHZ 15148 15149 #ifdef CONFIG_REG_CLIENT 15150 #define MAX_NUM_FCC_RULES 2 15151 15152 /** 15153 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15154 * @param_buf - Pointer to WMI params TLV 15155 * @ext_chan_list_event_hdr - Pointer to REG CHAN LIST CC EXT EVENT Fixed 15156 * Params TLV 15157 * @ext_wmi_reg_rule - Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15158 * @ext_wmi_chan_priority - Pointer to REG CHAN LIST CC EXT EVENT Chan 15159 * Priority TLV 15160 * @evt_buf - Pointer to REG CHAN LIST CC EXT EVENT event buffer 15161 * @reg_info - Pointer to Regulatory Info 15162 * @len - Length of REG CHAN LIST CC EXT EVENT buffer 15163 * 15164 * Return - QDF_STATUS 15165 */ 15166 static QDF_STATUS extract_reg_fcc_rules_tlv( 15167 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15168 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15169 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15170 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15171 uint8_t *evt_buf, 15172 struct cur_regulatory_info *reg_info, 15173 uint32_t len) 15174 { 15175 int i; 15176 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15177 15178 if (!param_buf) { 15179 wmi_err("invalid channel list event buf"); 15180 return QDF_STATUS_E_INVAL; 15181 } 15182 15183 reg_info->num_fcc_rules = 0; 15184 if (param_buf->reg_fcc_rule) { 15185 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15186 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15187 return QDF_STATUS_E_INVAL; 15188 } 15189 15190 ext_wmi_fcc_rule = 15191 (wmi_regulatory_fcc_rule_struct *) 15192 ((uint8_t *)ext_chan_list_event_hdr + 15193 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15194 WMI_TLV_HDR_SIZE + 15195 sizeof(wmi_regulatory_rule_ext_struct) * 15196 param_buf->num_reg_rule_array + 15197 WMI_TLV_HDR_SIZE + 15198 sizeof(wmi_regulatory_chan_priority_struct) * 15199 param_buf->num_reg_chan_priority + 15200 WMI_TLV_HDR_SIZE); 15201 15202 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15203 param_buf->num_reg_fcc_rule, 15204 ext_wmi_fcc_rule); 15205 15206 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15207 } 15208 15209 if (reg_info->fcc_rules_ptr) { 15210 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15211 wmi_debug("FCC rule %d center_freq %d tx_power %d", 15212 i, reg_info->fcc_rules_ptr[i].center_freq, 15213 reg_info->fcc_rules_ptr[i].tx_power); 15214 } 15215 } 15216 return QDF_STATUS_SUCCESS; 15217 } 15218 #else 15219 static QDF_STATUS extract_reg_fcc_rules_tlv( 15220 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15221 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15222 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15223 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15224 uint8_t *evt_buf, 15225 struct cur_regulatory_info *reg_info, 15226 uint32_t len) 15227 { 15228 return QDF_STATUS_SUCCESS; 15229 } 15230 #endif 15231 15232 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15233 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15234 struct cur_regulatory_info *reg_info, uint32_t len) 15235 { 15236 uint32_t i, j, k; 15237 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15238 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15239 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15240 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15241 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15242 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15243 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15244 uint32_t total_reg_rules = 0; 15245 QDF_STATUS status; 15246 15247 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15248 if (!param_buf) { 15249 wmi_err("invalid channel list event buf"); 15250 return QDF_STATUS_E_FAILURE; 15251 } 15252 15253 ext_chan_list_event_hdr = param_buf->fixed_param; 15254 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15255 15256 if (ext_wmi_chan_priority) 15257 reg_info->reg_6g_thresh_priority_freq = 15258 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15259 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15260 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15261 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15262 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15263 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15264 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15265 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15266 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15267 15268 wmi_debug("num reg rules from fw"); 15269 wmi_debug("AP SP %d, LPI %d, VLP %d", 15270 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15271 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15272 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15273 15274 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15275 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15276 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15277 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15278 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15279 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15280 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15281 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 15282 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15283 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15284 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15285 } 15286 15287 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15288 total_reg_rules += num_2g_reg_rules; 15289 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15290 total_reg_rules += num_5g_reg_rules; 15291 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15292 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15293 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15294 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15295 num_6g_reg_rules_ap[i]); 15296 return QDF_STATUS_E_FAILURE; 15297 } 15298 total_reg_rules += num_6g_reg_rules_ap[i]; 15299 num_6g_reg_rules_client[i] = 15300 reg_info->num_6g_reg_rules_client[i]; 15301 } 15302 15303 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15304 total_reg_rules += 15305 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15306 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15307 total_reg_rules += 15308 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15309 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15310 MAX_6G_REG_RULES) || 15311 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15312 MAX_6G_REG_RULES) || 15313 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15314 MAX_6G_REG_RULES)) { 15315 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", 15316 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15317 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15318 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15319 i); 15320 return QDF_STATUS_E_FAILURE; 15321 } 15322 } 15323 15324 if (total_reg_rules != param_buf->num_reg_rule_array) { 15325 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15326 total_reg_rules, param_buf->num_reg_rule_array); 15327 return QDF_STATUS_E_FAILURE; 15328 } 15329 15330 if ((num_2g_reg_rules > MAX_REG_RULES) || 15331 (num_5g_reg_rules > MAX_REG_RULES)) { 15332 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15333 num_2g_reg_rules, num_5g_reg_rules); 15334 return QDF_STATUS_E_FAILURE; 15335 } 15336 15337 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15338 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15339 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15340 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", 15341 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15342 num_6g_reg_rules_ap[REG_INDOOR_AP], 15343 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15344 return QDF_STATUS_E_FAILURE; 15345 } 15346 15347 if (param_buf->num_reg_rule_array > 15348 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15349 sizeof(*ext_wmi_reg_rule)) { 15350 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15351 param_buf->num_reg_rule_array); 15352 return QDF_STATUS_E_FAILURE; 15353 } 15354 15355 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15356 REG_ALPHA2_LEN); 15357 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15358 reg_info->phybitmap = convert_phybitmap_tlv( 15359 ext_chan_list_event_hdr->phybitmap); 15360 reg_info->offload_enabled = true; 15361 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15362 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15363 wmi_handle, ext_chan_list_event_hdr->phy_id); 15364 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15365 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15366 15367 reg_info->status_code = 15368 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15369 status_code); 15370 15371 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15372 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15373 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15374 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15375 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15376 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15377 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15378 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15379 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15380 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15381 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15382 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15383 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15384 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15385 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15386 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15387 15388 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15389 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15390 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15391 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15392 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15393 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15394 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15395 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15396 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15397 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15398 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15399 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15400 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15401 } 15402 15403 wmi_debug("num_phys = %u and phy_id = %u", 15404 reg_info->num_phy, reg_info->phy_id); 15405 15406 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 15407 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 15408 reg_info->max_bw_2g, reg_info->min_bw_5g, 15409 reg_info->max_bw_5g); 15410 15411 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", 15412 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15413 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15414 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15415 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15416 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15417 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15418 15419 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", 15420 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15421 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15422 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15423 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15424 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15425 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15426 15427 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", 15428 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15429 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15430 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15431 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15432 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15433 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15434 15435 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15436 num_2g_reg_rules, num_5g_reg_rules); 15437 15438 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15439 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15440 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15441 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15442 15443 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", 15444 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15445 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15446 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15447 15448 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", 15449 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15450 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15451 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15452 15453 ext_wmi_reg_rule = 15454 (wmi_regulatory_rule_ext_struct *) 15455 ((uint8_t *)ext_chan_list_event_hdr + 15456 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15457 WMI_TLV_HDR_SIZE); 15458 reg_info->reg_rules_2g_ptr = 15459 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15460 ext_wmi_reg_rule); 15461 ext_wmi_reg_rule += num_2g_reg_rules; 15462 for (i = 0; i < num_2g_reg_rules; i++) { 15463 if (!reg_info->reg_rules_2g_ptr) 15464 break; 15465 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 15466 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15467 reg_info->reg_rules_2g_ptr[i].end_freq, 15468 reg_info->reg_rules_2g_ptr[i].flags); 15469 } 15470 reg_info->reg_rules_5g_ptr = 15471 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15472 ext_wmi_reg_rule); 15473 ext_wmi_reg_rule += num_5g_reg_rules; 15474 for (i = 0; i < num_5g_reg_rules; i++) { 15475 if (!reg_info->reg_rules_5g_ptr) 15476 break; 15477 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 15478 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15479 reg_info->reg_rules_5g_ptr[i].end_freq, 15480 reg_info->reg_rules_5g_ptr[i].flags); 15481 } 15482 15483 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15484 reg_info->reg_rules_6g_ap_ptr[i] = 15485 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15486 ext_wmi_reg_rule); 15487 15488 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15489 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15490 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15491 break; 15492 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 15493 i, j, 15494 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15495 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15496 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 15497 } 15498 } 15499 15500 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15501 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15502 reg_info->reg_rules_6g_client_ptr[j][i] = 15503 create_ext_reg_rules_from_wmi( 15504 num_6g_reg_rules_client[j][i], 15505 ext_wmi_reg_rule); 15506 15507 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15508 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15509 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15510 break; 15511 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 15512 j, i, k, 15513 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15514 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15515 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 15516 } 15517 } 15518 } 15519 15520 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15521 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15522 reg_info->unspecified_ap_usable = 15523 ext_chan_list_event_hdr->unspecified_ap_usable; 15524 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15525 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15526 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15527 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15528 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 15529 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 15530 15531 wmi_debug("client type %d", reg_info->client_type); 15532 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 15533 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 15534 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 15535 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 15536 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 15537 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 15538 15539 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15540 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 15541 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 15542 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 15543 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 15544 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 15545 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 15546 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 15547 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 15548 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 15549 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 15550 } 15551 15552 reg_info->domain_code_6g_super_id = 15553 ext_chan_list_event_hdr->domain_code_6g_super_id; 15554 15555 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 15556 ext_wmi_reg_rule, ext_wmi_chan_priority, 15557 evt_buf, reg_info, len); 15558 if (status != QDF_STATUS_SUCCESS) 15559 return status; 15560 15561 wmi_debug("processed regulatory extended channel list"); 15562 15563 return QDF_STATUS_SUCCESS; 15564 } 15565 15566 #ifdef CONFIG_AFC_SUPPORT 15567 /** 15568 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 15569 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 15570 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 15571 * an index pointer required to store the current index of 15572 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 15573 * @chan_eirp_info: pointer to chan_eirp_info 15574 * @num_chans: Number of channels 15575 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15576 * @index: Pointer to index 15577 * 15578 * Return: void 15579 */ 15580 static void 15581 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 15582 uint8_t num_chans, 15583 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 15584 uint8_t *index) 15585 { 15586 uint8_t chan_idx; 15587 15588 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 15589 chan_eirp_info[chan_idx].cfi = 15590 chan_eirp_power_info_hdr[*index].channel_cfi; 15591 chan_eirp_info[chan_idx].eirp_power = 15592 chan_eirp_power_info_hdr[*index].eirp_pwr; 15593 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 15594 chan_idx, 15595 chan_eirp_info[chan_idx].cfi, 15596 chan_eirp_info[chan_idx].eirp_power); 15597 } 15598 } 15599 15600 /** 15601 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 15602 * to the internal buffer afc_chan_info. 15603 * @afc_chan_info: pointer to afc_chan_info 15604 * @num_chan_objs: Number of channel objects 15605 * @channel_info_hdr: Pointer to channel_info_hdr 15606 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15607 * 15608 * Return: void 15609 */ 15610 static void 15611 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 15612 uint8_t num_chan_objs, 15613 wmi_6g_afc_channel_info *channel_info_hdr, 15614 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 15615 { 15616 uint8_t count; 15617 uint8_t src_pwr_index = 0; 15618 15619 for (count = 0; count < num_chan_objs; count++) { 15620 afc_chan_info[count].global_opclass = 15621 channel_info_hdr[count].global_operating_class; 15622 afc_chan_info[count].num_chans = 15623 channel_info_hdr[count].num_channels; 15624 wmi_debug("Chan object count = %d global opclasss = %d", 15625 count, 15626 afc_chan_info[count].global_opclass); 15627 wmi_debug("Number of Channel EIRP objects = %d", 15628 afc_chan_info[count].num_chans); 15629 15630 if (afc_chan_info[count].num_chans > 0) { 15631 struct chan_eirp_obj *chan_eirp_info; 15632 15633 chan_eirp_info = 15634 qdf_mem_malloc(afc_chan_info[count].num_chans * 15635 sizeof(*chan_eirp_info)); 15636 15637 if (!chan_eirp_info) 15638 return; 15639 15640 copy_afc_chan_eirp_info(chan_eirp_info, 15641 afc_chan_info[count].num_chans, 15642 chan_eirp_power_info_hdr, 15643 &src_pwr_index); 15644 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 15645 } else { 15646 wmi_err("Number of channels is zero in object idx %d", 15647 count); 15648 } 15649 } 15650 } 15651 15652 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 15653 uint8_t num_freq_objs, 15654 wmi_6g_afc_frequency_info *freq_info_hdr) 15655 { 15656 uint8_t count; 15657 15658 for (count = 0; count < num_freq_objs; count++) { 15659 afc_freq_info[count].low_freq = 15660 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 15661 afc_freq_info[count].high_freq = 15662 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 15663 afc_freq_info[count].max_psd = 15664 freq_info_hdr[count].psd_power_info; 15665 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 15666 count, 15667 afc_freq_info[count].low_freq, 15668 afc_freq_info[count].high_freq, 15669 afc_freq_info[count].max_psd); 15670 } 15671 } 15672 15673 /** 15674 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 15675 * the power event info from the WMI AFC event buffer to the internal buffer 15676 * power_info. 15677 * @power_info: pointer to power_info 15678 * @afc_power_event_hdr: pointer to afc_power_event_hdr 15679 * 15680 * Return: void 15681 */ 15682 static void 15683 copy_afc_event_fixed_hdr_power_info( 15684 struct reg_fw_afc_power_event *power_info, 15685 wmi_afc_power_event_param *afc_power_event_hdr) 15686 { 15687 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 15688 power_info->resp_id = afc_power_event_hdr->resp_id; 15689 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 15690 power_info->afc_wfa_version = 15691 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15692 power_info->afc_wfa_version |= 15693 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15694 15695 power_info->avail_exp_time_d = 15696 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 15697 power_info->avail_exp_time_d |= 15698 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 15699 power_info->avail_exp_time_d |= 15700 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 15701 15702 power_info->avail_exp_time_t = 15703 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 15704 power_info->avail_exp_time_t |= 15705 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 15706 power_info->avail_exp_time_t |= 15707 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 15708 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 15709 power_info->fw_status_code, 15710 power_info->resp_id, 15711 power_info->serv_resp_code); 15712 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 15713 power_info->afc_wfa_version, 15714 power_info->avail_exp_time_d, 15715 power_info->avail_exp_time_t); 15716 } 15717 15718 /** 15719 * copy_power_event() - Copy the power event parameters from the AFC event 15720 * buffer to the power_info within the afc_info. 15721 * @afc_info: pointer to afc_info 15722 * @param_buf: pointer to param_buf 15723 * 15724 * Return: void 15725 */ 15726 static void copy_power_event(struct afc_regulatory_info *afc_info, 15727 WMI_AFC_EVENTID_param_tlvs *param_buf) 15728 { 15729 struct reg_fw_afc_power_event *power_info; 15730 wmi_afc_power_event_param *afc_power_event_hdr; 15731 struct afc_freq_obj *afc_freq_info; 15732 15733 power_info = qdf_mem_malloc(sizeof(*power_info)); 15734 15735 if (!power_info) 15736 return; 15737 15738 afc_power_event_hdr = param_buf->afc_power_event_param; 15739 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 15740 afc_info->power_info = power_info; 15741 15742 power_info->num_freq_objs = param_buf->num_freq_info_array; 15743 wmi_debug("Number of frequency objects = %d", 15744 power_info->num_freq_objs); 15745 if (power_info->num_freq_objs > 0) { 15746 wmi_6g_afc_frequency_info *freq_info_hdr; 15747 15748 freq_info_hdr = param_buf->freq_info_array; 15749 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 15750 sizeof(*afc_freq_info)); 15751 15752 if (!afc_freq_info) 15753 return; 15754 15755 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 15756 freq_info_hdr); 15757 power_info->afc_freq_info = afc_freq_info; 15758 } else { 15759 wmi_err("Number of frequency objects is zero"); 15760 } 15761 15762 power_info->num_chan_objs = param_buf->num_channel_info_array; 15763 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 15764 if (power_info->num_chan_objs > 0) { 15765 struct afc_chan_obj *afc_chan_info; 15766 wmi_6g_afc_channel_info *channel_info_hdr; 15767 15768 channel_info_hdr = param_buf->channel_info_array; 15769 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 15770 sizeof(*afc_chan_info)); 15771 15772 if (!afc_chan_info) 15773 return; 15774 15775 copy_afc_chan_obj_info(afc_chan_info, 15776 power_info->num_chan_objs, 15777 channel_info_hdr, 15778 param_buf->chan_eirp_power_info_array); 15779 power_info->afc_chan_info = afc_chan_info; 15780 } else { 15781 wmi_err("Number of channel objects is zero"); 15782 } 15783 } 15784 15785 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 15786 WMI_AFC_EVENTID_param_tlvs *param_buf) 15787 { 15788 struct reg_afc_expiry_event *expiry_info; 15789 15790 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 15791 15792 if (!expiry_info) 15793 return; 15794 15795 expiry_info->request_id = 15796 param_buf->expiry_event_param->request_id; 15797 expiry_info->event_subtype = 15798 param_buf->expiry_event_param->event_subtype; 15799 wmi_debug("Event subtype %d request ID %d", 15800 expiry_info->event_subtype, 15801 expiry_info->request_id); 15802 afc_info->expiry_info = expiry_info; 15803 } 15804 15805 /** 15806 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 15807 * in the AFC event. 'Common' indicates that these parameters are common for 15808 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 15809 * @wmi_handle: wmi handle 15810 * @afc_info: pointer to afc_info 15811 * @event_fixed_hdr: pointer to event_fixed_hdr 15812 * 15813 * Return: void 15814 */ 15815 static void 15816 copy_afc_event_common_info(wmi_unified_t wmi_handle, 15817 struct afc_regulatory_info *afc_info, 15818 wmi_afc_event_fixed_param *event_fixed_hdr) 15819 { 15820 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15821 wmi_handle, event_fixed_hdr->phy_id); 15822 wmi_debug("phy_id %d", afc_info->phy_id); 15823 afc_info->event_type = event_fixed_hdr->event_type; 15824 } 15825 15826 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 15827 uint8_t *evt_buf, 15828 struct afc_regulatory_info *afc_info, 15829 uint32_t len) 15830 { 15831 WMI_AFC_EVENTID_param_tlvs *param_buf; 15832 wmi_afc_event_fixed_param *event_fixed_hdr; 15833 15834 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 15835 if (!param_buf) { 15836 wmi_err("Invalid AFC event buf"); 15837 return QDF_STATUS_E_FAILURE; 15838 } 15839 15840 event_fixed_hdr = param_buf->fixed_param; 15841 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 15842 wmi_debug("AFC event type %d received", afc_info->event_type); 15843 15844 switch (afc_info->event_type) { 15845 case WMI_AFC_EVENT_POWER_INFO: 15846 copy_power_event(afc_info, param_buf); 15847 break; 15848 case WMI_AFC_EVENT_TIMER_EXPIRY: 15849 copy_expiry_event(afc_info, param_buf); 15850 return QDF_STATUS_SUCCESS; 15851 default: 15852 wmi_err("Invalid event type"); 15853 return QDF_STATUS_E_FAILURE; 15854 } 15855 15856 return QDF_STATUS_SUCCESS; 15857 } 15858 #endif 15859 #endif 15860 15861 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 15862 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15863 struct cur_regulatory_info *reg_info, uint32_t len) 15864 { 15865 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 15866 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 15867 wmi_regulatory_rule_struct *wmi_reg_rule; 15868 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15869 15870 wmi_debug("processing regulatory channel list"); 15871 15872 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 15873 if (!param_buf) { 15874 wmi_err("invalid channel list event buf"); 15875 return QDF_STATUS_E_FAILURE; 15876 } 15877 15878 chan_list_event_hdr = param_buf->fixed_param; 15879 15880 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 15881 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 15882 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15883 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15884 if ((num_2g_reg_rules > MAX_REG_RULES) || 15885 (num_5g_reg_rules > MAX_REG_RULES) || 15886 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 15887 (num_2g_reg_rules + num_5g_reg_rules != 15888 param_buf->num_reg_rule_array)) { 15889 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15890 num_2g_reg_rules, num_5g_reg_rules); 15891 return QDF_STATUS_E_FAILURE; 15892 } 15893 if (param_buf->num_reg_rule_array > 15894 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 15895 sizeof(*wmi_reg_rule)) { 15896 wmi_err_rl("Invalid num_reg_rule_array: %u", 15897 param_buf->num_reg_rule_array); 15898 return QDF_STATUS_E_FAILURE; 15899 } 15900 15901 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 15902 REG_ALPHA2_LEN); 15903 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 15904 reg_info->phybitmap = convert_phybitmap_tlv( 15905 chan_list_event_hdr->phybitmap); 15906 reg_info->offload_enabled = true; 15907 reg_info->num_phy = chan_list_event_hdr->num_phy; 15908 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15909 wmi_handle, chan_list_event_hdr->phy_id); 15910 reg_info->ctry_code = chan_list_event_hdr->country_id; 15911 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 15912 15913 reg_info->status_code = 15914 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 15915 15916 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 15917 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 15918 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 15919 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 15920 15921 wmi_debug("num_phys = %u and phy_id = %u", 15922 reg_info->num_phy, reg_info->phy_id); 15923 15924 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 15925 reg_info->alpha2, reg_info->dfs_region, 15926 reg_info->min_bw_2g, reg_info->max_bw_2g, 15927 reg_info->min_bw_5g, reg_info->max_bw_5g); 15928 15929 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15930 num_2g_reg_rules, num_5g_reg_rules); 15931 wmi_reg_rule = 15932 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 15933 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 15934 + WMI_TLV_HDR_SIZE); 15935 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 15936 wmi_reg_rule); 15937 wmi_reg_rule += num_2g_reg_rules; 15938 15939 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 15940 wmi_reg_rule); 15941 15942 wmi_debug("processed regulatory channel list"); 15943 15944 return QDF_STATUS_SUCCESS; 15945 } 15946 15947 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 15948 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15949 struct reg_11d_new_country *reg_11d_country, uint32_t len) 15950 { 15951 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 15952 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 15953 15954 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 15955 if (!param_buf) { 15956 wmi_err("invalid 11d country event buf"); 15957 return QDF_STATUS_E_FAILURE; 15958 } 15959 15960 reg_11d_country_event = param_buf->fixed_param; 15961 15962 qdf_mem_copy(reg_11d_country->alpha2, 15963 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 15964 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 15965 15966 wmi_debug("processed 11d country event, new cc %s", 15967 reg_11d_country->alpha2); 15968 15969 return QDF_STATUS_SUCCESS; 15970 } 15971 15972 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 15973 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15974 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 15975 { 15976 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 15977 wmi_avoid_freq_range_desc *afr_desc; 15978 uint32_t num_freq_ranges, freq_range_idx; 15979 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 15980 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 15981 15982 if (!param_buf) { 15983 wmi_err("Invalid channel avoid event buffer"); 15984 return QDF_STATUS_E_INVAL; 15985 } 15986 15987 afr_fixed_param = param_buf->fixed_param; 15988 if (!afr_fixed_param) { 15989 wmi_err("Invalid channel avoid event fixed param buffer"); 15990 return QDF_STATUS_E_INVAL; 15991 } 15992 15993 if (!ch_avoid_ind) { 15994 wmi_err("Invalid channel avoid indication buffer"); 15995 return QDF_STATUS_E_INVAL; 15996 } 15997 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 15998 wmi_err("no.of freq ranges exceeded the limit"); 15999 return QDF_STATUS_E_INVAL; 16000 } 16001 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16002 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16003 afr_fixed_param->num_freq_ranges; 16004 16005 wmi_debug("Channel avoid event received with %d ranges", 16006 num_freq_ranges); 16007 16008 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16009 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16010 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16011 freq_range_idx++) { 16012 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16013 afr_desc->start_freq; 16014 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16015 afr_desc->end_freq; 16016 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16017 freq_range_idx, afr_desc->tlv_header, 16018 afr_desc->start_freq, afr_desc->end_freq); 16019 afr_desc++; 16020 } 16021 16022 return QDF_STATUS_SUCCESS; 16023 } 16024 16025 #ifdef DFS_COMPONENT_ENABLE 16026 /** 16027 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16028 * @wmi_handle: wma handle 16029 * @evt_buf: event buffer 16030 * @vdev_id: vdev id 16031 * @len: length of buffer 16032 * 16033 * Return: 0 for success or error code 16034 */ 16035 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16036 uint8_t *evt_buf, 16037 uint32_t *vdev_id, 16038 uint32_t len) 16039 { 16040 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16041 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16042 16043 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16044 if (!param_tlvs) { 16045 wmi_err("invalid cac complete event buf"); 16046 return QDF_STATUS_E_FAILURE; 16047 } 16048 16049 cac_event = param_tlvs->fixed_param; 16050 *vdev_id = cac_event->vdev_id; 16051 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16052 16053 return QDF_STATUS_SUCCESS; 16054 } 16055 16056 /** 16057 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16058 * @wmi_handle: wma handle 16059 * @evt_buf: event buffer 16060 * @vdev_id: vdev id 16061 * @len: length of buffer 16062 * 16063 * Return: 0 for success or error code 16064 */ 16065 static QDF_STATUS 16066 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16067 uint8_t *evt_buf, 16068 struct vdev_adfs_complete_status *param) 16069 { 16070 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16071 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16072 16073 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16074 if (!param_tlvs) { 16075 wmi_err("invalid ocac complete event buf"); 16076 return QDF_STATUS_E_FAILURE; 16077 } 16078 16079 if (!param_tlvs->fixed_param) { 16080 wmi_err("invalid param_tlvs->fixed_param"); 16081 return QDF_STATUS_E_FAILURE; 16082 } 16083 16084 ocac_complete_status = param_tlvs->fixed_param; 16085 param->vdev_id = ocac_complete_status->vdev_id; 16086 param->chan_freq = ocac_complete_status->chan_freq; 16087 param->center_freq1 = ocac_complete_status->center_freq1; 16088 param->center_freq2 = ocac_complete_status->center_freq2; 16089 param->ocac_status = ocac_complete_status->status; 16090 param->chan_width = ocac_complete_status->chan_width; 16091 wmi_debug("processed ocac complete event vdev %d" 16092 " agile chan %d %d width %d status %d", 16093 param->vdev_id, 16094 param->center_freq1, 16095 param->center_freq2, 16096 param->chan_width, 16097 param->ocac_status); 16098 16099 return QDF_STATUS_SUCCESS; 16100 } 16101 16102 /** 16103 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16104 * @wmi_handle: wma handle 16105 * @evt_buf: event buffer 16106 * @radar_found: radar found event info 16107 * @len: length of buffer 16108 * 16109 * Return: 0 for success or error code 16110 */ 16111 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16112 wmi_unified_t wmi_handle, 16113 uint8_t *evt_buf, 16114 struct radar_found_info *radar_found, 16115 uint32_t len) 16116 { 16117 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16118 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16119 16120 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16121 if (!param_tlv) { 16122 wmi_err("invalid radar detection event buf"); 16123 return QDF_STATUS_E_FAILURE; 16124 } 16125 16126 radar_event = param_tlv->fixed_param; 16127 16128 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16129 wmi_handle, 16130 radar_event->pdev_id); 16131 16132 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16133 return QDF_STATUS_E_FAILURE; 16134 16135 radar_found->detection_mode = radar_event->detection_mode; 16136 radar_found->chan_freq = radar_event->chan_freq; 16137 radar_found->chan_width = radar_event->chan_width; 16138 radar_found->detector_id = radar_event->detector_id; 16139 radar_found->segment_id = radar_event->segment_id; 16140 radar_found->timestamp = radar_event->timestamp; 16141 radar_found->is_chirp = radar_event->is_chirp; 16142 radar_found->freq_offset = radar_event->freq_offset; 16143 radar_found->sidx = radar_event->sidx; 16144 16145 wmi_debug("processed radar found event pdev %d," 16146 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16147 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16148 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16149 "is_chirp %d,detection mode %d", 16150 radar_event->pdev_id, radar_found->pdev_id, 16151 radar_event->timestamp, radar_event->chan_freq, 16152 radar_event->chan_width, radar_event->detector_id, 16153 radar_event->freq_offset, radar_event->segment_id, 16154 radar_event->sidx, radar_event->is_chirp, 16155 radar_event->detection_mode); 16156 16157 return QDF_STATUS_SUCCESS; 16158 } 16159 16160 #ifdef MOBILE_DFS_SUPPORT 16161 /** 16162 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16163 * @wmi_handle: wma handle 16164 * @evt_buf: event buffer 16165 * @wlan_radar_event: Pointer to struct radar_event_info 16166 * @len: length of buffer 16167 * 16168 * Return: QDF_STATUS 16169 */ 16170 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16171 wmi_unified_t wmi_handle, 16172 uint8_t *evt_buf, 16173 struct radar_event_info *wlan_radar_event, 16174 uint32_t len) 16175 { 16176 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16177 wmi_dfs_radar_event_fixed_param *radar_event; 16178 16179 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16180 if (!param_tlv) { 16181 wmi_err("invalid wlan radar event buf"); 16182 return QDF_STATUS_E_FAILURE; 16183 } 16184 16185 radar_event = param_tlv->fixed_param; 16186 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16187 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16188 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16189 wlan_radar_event->rssi = radar_event->rssi; 16190 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16191 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16192 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16193 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16194 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16195 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16196 if (radar_event->pulse_flags & 16197 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16198 wlan_radar_event->is_psidx_diff_valid = true; 16199 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16200 } else { 16201 wlan_radar_event->is_psidx_diff_valid = false; 16202 } 16203 16204 wlan_radar_event->pdev_id = radar_event->pdev_id; 16205 16206 return QDF_STATUS_SUCCESS; 16207 } 16208 #else 16209 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16210 wmi_unified_t wmi_handle, 16211 uint8_t *evt_buf, 16212 struct radar_event_info *wlan_radar_event, 16213 uint32_t len) 16214 { 16215 return QDF_STATUS_SUCCESS; 16216 } 16217 #endif 16218 #endif 16219 16220 /** 16221 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16222 * @wmi_handle: wmi handle 16223 * @get_rcpi_param: rcpi params 16224 * 16225 * Return: QDF status 16226 */ 16227 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16228 struct rcpi_req *get_rcpi_param) 16229 { 16230 wmi_buf_t buf; 16231 wmi_request_rcpi_cmd_fixed_param *cmd; 16232 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16233 16234 buf = wmi_buf_alloc(wmi_handle, len); 16235 if (!buf) 16236 return QDF_STATUS_E_NOMEM; 16237 16238 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16239 WMITLV_SET_HDR(&cmd->tlv_header, 16240 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16241 WMITLV_GET_STRUCT_TLVLEN 16242 (wmi_request_rcpi_cmd_fixed_param)); 16243 16244 cmd->vdev_id = get_rcpi_param->vdev_id; 16245 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16246 &cmd->peer_macaddr); 16247 16248 switch (get_rcpi_param->measurement_type) { 16249 16250 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16251 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16252 break; 16253 16254 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16255 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16256 break; 16257 16258 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16259 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16260 break; 16261 16262 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16263 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16264 break; 16265 16266 default: 16267 /* 16268 * invalid rcpi measurement type, fall back to 16269 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16270 */ 16271 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16272 break; 16273 } 16274 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16275 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16276 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16277 WMI_REQUEST_RCPI_CMDID)) { 16278 16279 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16280 wmi_buf_free(buf); 16281 return QDF_STATUS_E_FAILURE; 16282 } 16283 16284 return QDF_STATUS_SUCCESS; 16285 } 16286 16287 /** 16288 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16289 * @wmi_handle: wmi handle 16290 * @evt_buf: pointer to event buffer 16291 * @res: pointer to hold rcpi response from firmware 16292 * 16293 * Return: QDF_STATUS_SUCCESS for successful event parse 16294 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16295 */ 16296 static QDF_STATUS 16297 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16298 void *evt_buf, struct rcpi_res *res) 16299 { 16300 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16301 wmi_update_rcpi_event_fixed_param *event; 16302 16303 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16304 if (!param_buf) { 16305 wmi_err("Invalid rcpi event"); 16306 return QDF_STATUS_E_INVAL; 16307 } 16308 16309 event = param_buf->fixed_param; 16310 res->vdev_id = event->vdev_id; 16311 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16312 16313 switch (event->measurement_type) { 16314 16315 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16316 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16317 break; 16318 16319 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16320 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16321 break; 16322 16323 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16324 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16325 break; 16326 16327 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16328 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16329 break; 16330 16331 default: 16332 wmi_err("Invalid rcpi measurement type from firmware"); 16333 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16334 return QDF_STATUS_E_FAILURE; 16335 } 16336 16337 if (event->status) 16338 return QDF_STATUS_E_FAILURE; 16339 else 16340 return QDF_STATUS_SUCCESS; 16341 } 16342 16343 /** 16344 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16345 * host to target defines. For legacy there is not conversion 16346 * required. Just return pdev_id as it is. 16347 * @param pdev_id: host pdev_id to be converted. 16348 * Return: target pdev_id after conversion. 16349 */ 16350 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16351 wmi_unified_t wmi_handle, 16352 uint32_t pdev_id) 16353 { 16354 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16355 return WMI_PDEV_ID_SOC; 16356 16357 /*No conversion required*/ 16358 return pdev_id; 16359 } 16360 16361 /** 16362 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16363 * target to host defines. For legacy there is not conversion 16364 * required. Just return pdev_id as it is. 16365 * @param pdev_id: target pdev_id to be converted. 16366 * Return: host pdev_id after conversion. 16367 */ 16368 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16369 wmi_unified_t wmi_handle, 16370 uint32_t pdev_id) 16371 { 16372 /*No conversion required*/ 16373 return pdev_id; 16374 } 16375 16376 /** 16377 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16378 * host to target defines. For legacy there is not conversion 16379 * required. Just return phy_id as it is. 16380 * @param pdev_id: host phy_id to be converted. 16381 * Return: target phy_id after conversion. 16382 */ 16383 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16384 wmi_unified_t wmi_handle, 16385 uint32_t phy_id) 16386 { 16387 /*No conversion required*/ 16388 return phy_id; 16389 } 16390 16391 /** 16392 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16393 * target to host defines. For legacy there is not conversion 16394 * required. Just return phy_id as it is. 16395 * @param pdev_id: target phy_id to be converted. 16396 * Return: host phy_id after conversion. 16397 */ 16398 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16399 wmi_unified_t wmi_handle, 16400 uint32_t phy_id) 16401 { 16402 /*No conversion required*/ 16403 return phy_id; 16404 } 16405 16406 /** 16407 * send_set_country_cmd_tlv() - WMI scan channel list function 16408 * @param wmi_handle : handle to WMI. 16409 * @param param : pointer to hold scan channel list parameter 16410 * 16411 * Return: 0 on success and -ve on failure. 16412 */ 16413 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16414 struct set_country *params) 16415 { 16416 wmi_buf_t buf; 16417 QDF_STATUS qdf_status; 16418 wmi_set_current_country_cmd_fixed_param *cmd; 16419 uint16_t len = sizeof(*cmd); 16420 uint8_t pdev_id = params->pdev_id; 16421 16422 buf = wmi_buf_alloc(wmi_handle, len); 16423 if (!buf) { 16424 qdf_status = QDF_STATUS_E_NOMEM; 16425 goto end; 16426 } 16427 16428 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16429 WMITLV_SET_HDR(&cmd->tlv_header, 16430 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16431 WMITLV_GET_STRUCT_TLVLEN 16432 (wmi_set_current_country_cmd_fixed_param)); 16433 16434 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16435 wmi_handle, 16436 pdev_id); 16437 wmi_debug("setting current country to %s and target pdev_id = %u", 16438 params->country, cmd->pdev_id); 16439 16440 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16441 16442 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16443 qdf_status = wmi_unified_cmd_send(wmi_handle, 16444 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16445 16446 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16447 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16448 wmi_buf_free(buf); 16449 } 16450 16451 end: 16452 return qdf_status; 16453 } 16454 16455 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16456 WMI_SET_BITS(alpha, 0, 8, val0); \ 16457 WMI_SET_BITS(alpha, 8, 8, val1); \ 16458 WMI_SET_BITS(alpha, 16, 8, val2); \ 16459 } while (0) 16460 16461 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16462 uint8_t pdev_id, struct cc_regdmn_s *rd) 16463 { 16464 wmi_set_init_country_cmd_fixed_param *cmd; 16465 uint16_t len; 16466 wmi_buf_t buf; 16467 int ret; 16468 16469 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16470 buf = wmi_buf_alloc(wmi_handle, len); 16471 if (!buf) 16472 return QDF_STATUS_E_NOMEM; 16473 16474 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16475 WMITLV_SET_HDR(&cmd->tlv_header, 16476 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16477 WMITLV_GET_STRUCT_TLVLEN 16478 (wmi_set_init_country_cmd_fixed_param)); 16479 16480 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16481 wmi_handle, 16482 pdev_id); 16483 16484 if (rd->flags == CC_IS_SET) { 16485 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16486 cmd->country_code.country_id = rd->cc.country_code; 16487 } else if (rd->flags == ALPHA_IS_SET) { 16488 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16489 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16490 rd->cc.alpha[0], 16491 rd->cc.alpha[1], 16492 rd->cc.alpha[2]); 16493 } else if (rd->flags == REGDMN_IS_SET) { 16494 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16495 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16496 rd->cc.regdmn.reg_2g_5g_pair_id); 16497 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16498 rd->cc.regdmn.sixg_superdmn_id); 16499 } 16500 16501 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 16502 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16503 WMI_SET_INIT_COUNTRY_CMDID); 16504 if (ret) { 16505 wmi_err("Failed to config wow wakeup event"); 16506 wmi_buf_free(buf); 16507 return QDF_STATUS_E_FAILURE; 16508 } 16509 16510 return QDF_STATUS_SUCCESS; 16511 } 16512 16513 /** 16514 * send_obss_detection_cfg_cmd_tlv() - send obss detection 16515 * configurations to firmware. 16516 * @wmi_handle: wmi handle 16517 * @obss_cfg_param: obss detection configurations 16518 * 16519 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 16520 * 16521 * Return: QDF_STATUS 16522 */ 16523 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 16524 struct wmi_obss_detection_cfg_param *obss_cfg_param) 16525 { 16526 wmi_buf_t buf; 16527 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 16528 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 16529 16530 buf = wmi_buf_alloc(wmi_handle, len); 16531 if (!buf) 16532 return QDF_STATUS_E_NOMEM; 16533 16534 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 16535 WMITLV_SET_HDR(&cmd->tlv_header, 16536 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 16537 WMITLV_GET_STRUCT_TLVLEN 16538 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 16539 16540 cmd->vdev_id = obss_cfg_param->vdev_id; 16541 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 16542 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 16543 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 16544 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 16545 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 16546 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 16547 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 16548 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 16549 16550 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 16551 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16552 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 16553 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 16554 wmi_buf_free(buf); 16555 return QDF_STATUS_E_FAILURE; 16556 } 16557 16558 return QDF_STATUS_SUCCESS; 16559 } 16560 16561 /** 16562 * extract_obss_detection_info_tlv() - Extract obss detection info 16563 * received from firmware. 16564 * @evt_buf: pointer to event buffer 16565 * @obss_detection: Pointer to hold obss detection info 16566 * 16567 * Return: QDF_STATUS 16568 */ 16569 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 16570 struct wmi_obss_detect_info 16571 *obss_detection) 16572 { 16573 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 16574 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 16575 16576 if (!obss_detection) { 16577 wmi_err("Invalid obss_detection event buffer"); 16578 return QDF_STATUS_E_INVAL; 16579 } 16580 16581 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 16582 if (!param_buf) { 16583 wmi_err("Invalid evt_buf"); 16584 return QDF_STATUS_E_INVAL; 16585 } 16586 16587 fix_param = param_buf->fixed_param; 16588 obss_detection->vdev_id = fix_param->vdev_id; 16589 obss_detection->matched_detection_masks = 16590 fix_param->matched_detection_masks; 16591 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 16592 &obss_detection->matched_bssid_addr[0]); 16593 switch (fix_param->reason) { 16594 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 16595 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 16596 break; 16597 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 16598 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 16599 break; 16600 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 16601 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 16602 break; 16603 default: 16604 wmi_err("Invalid reason: %d", fix_param->reason); 16605 return QDF_STATUS_E_INVAL; 16606 } 16607 16608 return QDF_STATUS_SUCCESS; 16609 } 16610 16611 /** 16612 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 16613 * @wmi_handle: wmi handle 16614 * @params: pointer to request structure 16615 * 16616 * Return: QDF_STATUS 16617 */ 16618 static QDF_STATUS 16619 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 16620 struct wmi_roam_scan_stats_req *params) 16621 { 16622 wmi_buf_t buf; 16623 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 16624 WMITLV_TAG_ID tag; 16625 uint32_t size; 16626 uint32_t len = sizeof(*cmd); 16627 16628 buf = wmi_buf_alloc(wmi_handle, len); 16629 if (!buf) 16630 return QDF_STATUS_E_FAILURE; 16631 16632 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 16633 16634 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 16635 size = WMITLV_GET_STRUCT_TLVLEN( 16636 wmi_request_roam_scan_stats_cmd_fixed_param); 16637 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 16638 16639 cmd->vdev_id = params->vdev_id; 16640 16641 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 16642 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16643 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 16644 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 16645 wmi_buf_free(buf); 16646 return QDF_STATUS_E_FAILURE; 16647 } 16648 16649 return QDF_STATUS_SUCCESS; 16650 } 16651 16652 /** 16653 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 16654 * channel list from firmware 16655 * @wmi_handle: wmi handler 16656 * @vdev_id: vdev id 16657 * 16658 * Return: QDF_STATUS 16659 */ 16660 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 16661 uint32_t vdev_id) 16662 { 16663 wmi_buf_t buf; 16664 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 16665 uint16_t len = sizeof(*cmd); 16666 int ret; 16667 16668 buf = wmi_buf_alloc(wmi_handle, len); 16669 if (!buf) { 16670 wmi_err("Failed to allocate wmi buffer"); 16671 return QDF_STATUS_E_NOMEM; 16672 } 16673 16674 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 16675 wmi_buf_data(buf); 16676 WMITLV_SET_HDR(&cmd->tlv_header, 16677 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 16678 WMITLV_GET_STRUCT_TLVLEN( 16679 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 16680 cmd->vdev_id = vdev_id; 16681 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 16682 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16683 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 16684 if (QDF_IS_STATUS_ERROR(ret)) { 16685 wmi_err("Failed to send get roam scan channels request = %d", 16686 ret); 16687 wmi_buf_free(buf); 16688 } 16689 return ret; 16690 } 16691 16692 /** 16693 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 16694 * @wmi_handle: wmi handle 16695 * @evt_buf: pointer to event buffer 16696 * @vdev_id: output pointer to hold vdev id 16697 * @res_param: output pointer to hold the allocated response 16698 * 16699 * Return: QDF_STATUS 16700 */ 16701 static QDF_STATUS 16702 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16703 uint32_t *vdev_id, 16704 struct wmi_roam_scan_stats_res **res_param) 16705 { 16706 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 16707 wmi_roam_scan_stats_event_fixed_param *fixed_param; 16708 uint32_t *client_id = NULL; 16709 wmi_roaming_timestamp *timestamp = NULL; 16710 uint32_t *num_channels = NULL; 16711 uint32_t *chan_info = NULL; 16712 wmi_mac_addr *old_bssid = NULL; 16713 uint32_t *is_roaming_success = NULL; 16714 wmi_mac_addr *new_bssid = NULL; 16715 uint32_t *num_roam_candidates = NULL; 16716 wmi_roam_scan_trigger_reason *roam_reason = NULL; 16717 wmi_mac_addr *bssid = NULL; 16718 uint32_t *score = NULL; 16719 uint32_t *channel = NULL; 16720 uint32_t *rssi = NULL; 16721 int chan_idx = 0, cand_idx = 0; 16722 uint32_t total_len; 16723 struct wmi_roam_scan_stats_res *res; 16724 uint32_t i, j; 16725 uint32_t num_scans, scan_param_size; 16726 16727 *res_param = NULL; 16728 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 16729 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 16730 if (!param_buf) { 16731 wmi_err("Invalid roam scan stats event"); 16732 return QDF_STATUS_E_INVAL; 16733 } 16734 16735 fixed_param = param_buf->fixed_param; 16736 16737 num_scans = fixed_param->num_roam_scans; 16738 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 16739 *vdev_id = fixed_param->vdev_id; 16740 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 16741 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 16742 num_scans, WMI_ROAM_SCAN_STATS_MAX); 16743 return QDF_STATUS_E_INVAL; 16744 } 16745 16746 total_len = sizeof(*res) + num_scans * scan_param_size; 16747 16748 res = qdf_mem_malloc(total_len); 16749 if (!res) 16750 return QDF_STATUS_E_NOMEM; 16751 16752 if (!num_scans) { 16753 *res_param = res; 16754 return QDF_STATUS_SUCCESS; 16755 } 16756 16757 if (param_buf->client_id && 16758 param_buf->num_client_id == num_scans) 16759 client_id = param_buf->client_id; 16760 16761 if (param_buf->timestamp && 16762 param_buf->num_timestamp == num_scans) 16763 timestamp = param_buf->timestamp; 16764 16765 if (param_buf->old_bssid && 16766 param_buf->num_old_bssid == num_scans) 16767 old_bssid = param_buf->old_bssid; 16768 16769 if (param_buf->new_bssid && 16770 param_buf->num_new_bssid == num_scans) 16771 new_bssid = param_buf->new_bssid; 16772 16773 if (param_buf->is_roaming_success && 16774 param_buf->num_is_roaming_success == num_scans) 16775 is_roaming_success = param_buf->is_roaming_success; 16776 16777 if (param_buf->roam_reason && 16778 param_buf->num_roam_reason == num_scans) 16779 roam_reason = param_buf->roam_reason; 16780 16781 if (param_buf->num_channels && 16782 param_buf->num_num_channels == num_scans) { 16783 uint32_t count, chan_info_sum = 0; 16784 16785 num_channels = param_buf->num_channels; 16786 for (count = 0; count < param_buf->num_num_channels; count++) { 16787 if (param_buf->num_channels[count] > 16788 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 16789 wmi_err_rl("%u exceeded max scan channels %u", 16790 param_buf->num_channels[count], 16791 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 16792 goto error; 16793 } 16794 chan_info_sum += param_buf->num_channels[count]; 16795 } 16796 16797 if (param_buf->chan_info && 16798 param_buf->num_chan_info == chan_info_sum) 16799 chan_info = param_buf->chan_info; 16800 } 16801 16802 if (param_buf->num_roam_candidates && 16803 param_buf->num_num_roam_candidates == num_scans) { 16804 uint32_t cnt, roam_cand_sum = 0; 16805 16806 num_roam_candidates = param_buf->num_roam_candidates; 16807 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 16808 if (param_buf->num_roam_candidates[cnt] > 16809 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 16810 wmi_err_rl("%u exceeded max scan cand %u", 16811 param_buf->num_roam_candidates[cnt], 16812 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 16813 goto error; 16814 } 16815 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 16816 } 16817 16818 if (param_buf->bssid && 16819 param_buf->num_bssid == roam_cand_sum) 16820 bssid = param_buf->bssid; 16821 16822 if (param_buf->score && 16823 param_buf->num_score == roam_cand_sum) 16824 score = param_buf->score; 16825 16826 if (param_buf->channel && 16827 param_buf->num_channel == roam_cand_sum) 16828 channel = param_buf->channel; 16829 16830 if (param_buf->rssi && 16831 param_buf->num_rssi == roam_cand_sum) 16832 rssi = param_buf->rssi; 16833 } 16834 16835 res->num_roam_scans = num_scans; 16836 for (i = 0; i < num_scans; i++) { 16837 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 16838 16839 if (timestamp) 16840 roam->time_stamp = timestamp[i].lower32bit | 16841 (timestamp[i].upper32bit << 31); 16842 16843 if (client_id) 16844 roam->client_id = client_id[i]; 16845 16846 if (num_channels) { 16847 roam->num_scan_chans = num_channels[i]; 16848 if (chan_info) { 16849 for (j = 0; j < num_channels[i]; j++) 16850 roam->scan_freqs[j] = 16851 chan_info[chan_idx++]; 16852 } 16853 } 16854 16855 if (is_roaming_success) 16856 roam->is_roam_successful = is_roaming_success[i]; 16857 16858 if (roam_reason) { 16859 roam->trigger_id = roam_reason[i].trigger_id; 16860 roam->trigger_value = roam_reason[i].trigger_value; 16861 } 16862 16863 if (num_roam_candidates) { 16864 roam->num_roam_candidates = num_roam_candidates[i]; 16865 16866 for (j = 0; j < num_roam_candidates[i]; j++) { 16867 if (score) 16868 roam->cand[j].score = score[cand_idx]; 16869 if (rssi) 16870 roam->cand[j].rssi = rssi[cand_idx]; 16871 if (channel) 16872 roam->cand[j].freq = 16873 channel[cand_idx]; 16874 16875 if (bssid) 16876 WMI_MAC_ADDR_TO_CHAR_ARRAY( 16877 &bssid[cand_idx], 16878 roam->cand[j].bssid); 16879 16880 cand_idx++; 16881 } 16882 } 16883 16884 if (old_bssid) 16885 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 16886 roam->old_bssid); 16887 16888 if (new_bssid) 16889 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 16890 roam->new_bssid); 16891 } 16892 16893 *res_param = res; 16894 16895 return QDF_STATUS_SUCCESS; 16896 error: 16897 qdf_mem_free(res); 16898 return QDF_STATUS_E_FAILURE; 16899 } 16900 16901 /** 16902 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 16903 * @wmi_handle: wmi handle 16904 * @evt_buf: pointer to event buffer 16905 * @vdev_id: output pointer to hold vdev id 16906 * @tx_status: output pointer to hold the tx_status 16907 * 16908 * Return: QDF_STATUS 16909 */ 16910 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 16911 void *evt_buf, 16912 uint32_t *vdev_id, 16913 uint32_t *tx_status) { 16914 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 16915 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 16916 16917 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 16918 if (!param_buf) { 16919 wmi_err("Invalid offload bcn tx status event buffer"); 16920 return QDF_STATUS_E_INVAL; 16921 } 16922 16923 bcn_tx_status_event = param_buf->fixed_param; 16924 *vdev_id = bcn_tx_status_event->vdev_id; 16925 *tx_status = bcn_tx_status_event->tx_status; 16926 16927 return QDF_STATUS_SUCCESS; 16928 } 16929 16930 #ifdef WLAN_SUPPORT_GREEN_AP 16931 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 16932 uint8_t *evt_buf, 16933 struct wlan_green_ap_egap_status_info *egap_status_info_params) 16934 { 16935 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 16936 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 16937 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 16938 16939 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 16940 if (!param_buf) { 16941 wmi_err("Invalid EGAP Info status event buffer"); 16942 return QDF_STATUS_E_INVAL; 16943 } 16944 16945 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 16946 param_buf->fixed_param; 16947 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 16948 param_buf->chainmask_list; 16949 16950 if (!egap_info_event || !chainmask_event) { 16951 wmi_err("Invalid EGAP Info event or chainmask event"); 16952 return QDF_STATUS_E_INVAL; 16953 } 16954 16955 egap_status_info_params->status = egap_info_event->status; 16956 egap_status_info_params->mac_id = chainmask_event->mac_id; 16957 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 16958 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 16959 16960 return QDF_STATUS_SUCCESS; 16961 } 16962 #endif 16963 16964 /* 16965 * extract_comb_phyerr_tlv() - extract comb phy error from event 16966 * @wmi_handle: wmi handle 16967 * @evt_buf: pointer to event buffer 16968 * @datalen: data length of event buffer 16969 * @buf_offset: Pointer to hold value of current event buffer offset 16970 * post extraction 16971 * @phyerr: Pointer to hold phyerr 16972 * 16973 * Return: QDF_STATUS 16974 */ 16975 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 16976 void *evt_buf, 16977 uint16_t datalen, 16978 uint16_t *buf_offset, 16979 wmi_host_phyerr_t *phyerr) 16980 { 16981 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 16982 wmi_comb_phyerr_rx_hdr *pe_hdr; 16983 16984 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 16985 if (!param_tlvs) { 16986 wmi_debug("Received null data from FW"); 16987 return QDF_STATUS_E_FAILURE; 16988 } 16989 16990 pe_hdr = param_tlvs->hdr; 16991 if (!pe_hdr) { 16992 wmi_debug("Received Data PE Header is NULL"); 16993 return QDF_STATUS_E_FAILURE; 16994 } 16995 16996 /* Ensure it's at least the size of the header */ 16997 if (datalen < sizeof(*pe_hdr)) { 16998 wmi_debug("Expected minimum size %zu, received %d", 16999 sizeof(*pe_hdr), datalen); 17000 return QDF_STATUS_E_FAILURE; 17001 } 17002 17003 phyerr->pdev_id = wmi_handle->ops-> 17004 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17005 phyerr->tsf64 = pe_hdr->tsf_l32; 17006 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17007 phyerr->bufp = param_tlvs->bufp; 17008 17009 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17010 wmi_debug("Invalid buf_len %d, num_bufp %d", 17011 pe_hdr->buf_len, param_tlvs->num_bufp); 17012 return QDF_STATUS_E_FAILURE; 17013 } 17014 17015 phyerr->buf_len = pe_hdr->buf_len; 17016 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17017 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17018 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17019 17020 return QDF_STATUS_SUCCESS; 17021 } 17022 17023 /** 17024 * extract_single_phyerr_tlv() - extract single phy error from event 17025 * @wmi_handle: wmi handle 17026 * @evt_buf: pointer to event buffer 17027 * @datalen: data length of event buffer 17028 * @buf_offset: Pointer to hold value of current event buffer offset 17029 * post extraction 17030 * @phyerr: Pointer to hold phyerr 17031 * 17032 * Return: QDF_STATUS 17033 */ 17034 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17035 void *evt_buf, 17036 uint16_t datalen, 17037 uint16_t *buf_offset, 17038 wmi_host_phyerr_t *phyerr) 17039 { 17040 wmi_single_phyerr_rx_event *ev; 17041 uint16_t n = *buf_offset; 17042 uint8_t *data = (uint8_t *)evt_buf; 17043 17044 if (n < datalen) { 17045 if ((datalen - n) < sizeof(ev->hdr)) { 17046 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17047 datalen, n, sizeof(ev->hdr)); 17048 return QDF_STATUS_E_FAILURE; 17049 } 17050 17051 /* 17052 * Obtain a pointer to the beginning of the current event. 17053 * data[0] is the beginning of the WMI payload. 17054 */ 17055 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17056 17057 /* 17058 * Sanity check the buffer length of the event against 17059 * what we currently have. 17060 * 17061 * Since buf_len is 32 bits, we check if it overflows 17062 * a large 32 bit value. It's not 0x7fffffff because 17063 * we increase n by (buf_len + sizeof(hdr)), which would 17064 * in itself cause n to overflow. 17065 * 17066 * If "int" is 64 bits then this becomes a moot point. 17067 */ 17068 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17069 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17070 return QDF_STATUS_E_FAILURE; 17071 } 17072 17073 if ((n + ev->hdr.buf_len) > datalen) { 17074 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17075 n, ev->hdr.buf_len, datalen); 17076 return QDF_STATUS_E_FAILURE; 17077 } 17078 17079 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17080 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17081 phyerr->bufp = &ev->bufp[0]; 17082 phyerr->buf_len = ev->hdr.buf_len; 17083 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17084 17085 /* 17086 * Advance the buffer pointer to the next PHY error. 17087 * buflen is the length of this payload, so we need to 17088 * advance past the current header _AND_ the payload. 17089 */ 17090 n += sizeof(*ev) + ev->hdr.buf_len; 17091 } 17092 *buf_offset = n; 17093 17094 return QDF_STATUS_SUCCESS; 17095 } 17096 17097 /** 17098 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17099 * @wmi_handle: wmi handle 17100 * @evt_buf: pointer to event buffer 17101 * @param: Pointer to hold esp event 17102 * 17103 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17104 */ 17105 static QDF_STATUS 17106 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17107 void *evt_buf, 17108 struct esp_estimation_event *param) 17109 { 17110 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17111 wmi_esp_estimate_event_fixed_param *esp_event; 17112 17113 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17114 if (!param_buf) { 17115 wmi_err("Invalid ESP Estimate Event buffer"); 17116 return QDF_STATUS_E_INVAL; 17117 } 17118 esp_event = param_buf->fixed_param; 17119 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17120 17121 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17122 wmi_handle, 17123 esp_event->pdev_id); 17124 17125 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17126 return QDF_STATUS_E_FAILURE; 17127 17128 return QDF_STATUS_SUCCESS; 17129 } 17130 17131 /* 17132 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17133 * updating bss color change within firmware when AP announces bss color change. 17134 * @wmi_handle: wmi handle 17135 * @vdev_id: vdev ID 17136 * @enable: enable bss color change within firmware 17137 * 17138 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17139 * 17140 * Return: QDF_STATUS 17141 */ 17142 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17143 uint32_t vdev_id, 17144 bool enable) 17145 { 17146 wmi_buf_t buf; 17147 wmi_bss_color_change_enable_fixed_param *cmd; 17148 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17149 17150 buf = wmi_buf_alloc(wmi_handle, len); 17151 if (!buf) 17152 return QDF_STATUS_E_NOMEM; 17153 17154 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17155 WMITLV_SET_HDR(&cmd->tlv_header, 17156 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17157 WMITLV_GET_STRUCT_TLVLEN 17158 (wmi_bss_color_change_enable_fixed_param)); 17159 cmd->vdev_id = vdev_id; 17160 cmd->enable = enable; 17161 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17162 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17163 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17164 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17165 wmi_buf_free(buf); 17166 return QDF_STATUS_E_FAILURE; 17167 } 17168 17169 return QDF_STATUS_SUCCESS; 17170 } 17171 17172 /** 17173 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17174 * configurations to firmware. 17175 * @wmi_handle: wmi handle 17176 * @cfg_param: obss detection configurations 17177 * 17178 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17179 * 17180 * Return: QDF_STATUS 17181 */ 17182 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17183 wmi_unified_t wmi_handle, 17184 struct wmi_obss_color_collision_cfg_param *cfg_param) 17185 { 17186 wmi_buf_t buf; 17187 wmi_obss_color_collision_det_config_fixed_param *cmd; 17188 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17189 17190 buf = wmi_buf_alloc(wmi_handle, len); 17191 if (!buf) 17192 return QDF_STATUS_E_NOMEM; 17193 17194 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17195 buf); 17196 WMITLV_SET_HDR(&cmd->tlv_header, 17197 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17198 WMITLV_GET_STRUCT_TLVLEN 17199 (wmi_obss_color_collision_det_config_fixed_param)); 17200 cmd->vdev_id = cfg_param->vdev_id; 17201 cmd->flags = cfg_param->flags; 17202 cmd->current_bss_color = cfg_param->current_bss_color; 17203 cmd->detection_period_ms = cfg_param->detection_period_ms; 17204 cmd->scan_period_ms = cfg_param->scan_period_ms; 17205 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17206 17207 switch (cfg_param->evt_type) { 17208 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17209 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17210 break; 17211 case OBSS_COLOR_COLLISION_DETECTION: 17212 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17213 break; 17214 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17215 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17216 break; 17217 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17218 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17219 break; 17220 default: 17221 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17222 wmi_buf_free(buf); 17223 return QDF_STATUS_E_FAILURE; 17224 } 17225 17226 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17227 "detection_period_ms: %d scan_period_ms: %d " 17228 "free_slot_expiry_timer_ms: %d", 17229 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17230 cmd->detection_period_ms, cmd->scan_period_ms, 17231 cmd->free_slot_expiry_time_ms); 17232 17233 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17234 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17235 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17236 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17237 cfg_param->vdev_id); 17238 wmi_buf_free(buf); 17239 return QDF_STATUS_E_FAILURE; 17240 } 17241 17242 return QDF_STATUS_SUCCESS; 17243 } 17244 17245 /** 17246 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17247 * received from firmware. 17248 * @evt_buf: pointer to event buffer 17249 * @info: Pointer to hold bss collision info 17250 * 17251 * Return: QDF_STATUS 17252 */ 17253 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17254 struct wmi_obss_color_collision_info *info) 17255 { 17256 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17257 wmi_obss_color_collision_evt_fixed_param *fix_param; 17258 17259 if (!info) { 17260 wmi_err("Invalid obss color buffer"); 17261 return QDF_STATUS_E_INVAL; 17262 } 17263 17264 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17265 evt_buf; 17266 if (!param_buf) { 17267 wmi_err("Invalid evt_buf"); 17268 return QDF_STATUS_E_INVAL; 17269 } 17270 17271 fix_param = param_buf->fixed_param; 17272 info->vdev_id = fix_param->vdev_id; 17273 info->obss_color_bitmap_bit0to31 = 17274 fix_param->bss_color_bitmap_bit0to31; 17275 info->obss_color_bitmap_bit32to63 = 17276 fix_param->bss_color_bitmap_bit32to63; 17277 17278 switch (fix_param->evt_type) { 17279 case WMI_BSS_COLOR_COLLISION_DISABLE: 17280 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17281 break; 17282 case WMI_BSS_COLOR_COLLISION_DETECTION: 17283 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17284 break; 17285 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17286 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17287 break; 17288 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17289 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17290 break; 17291 default: 17292 wmi_err("Invalid event type: %d, vdev_id: %d", 17293 fix_param->evt_type, fix_param->vdev_id); 17294 return QDF_STATUS_E_FAILURE; 17295 } 17296 17297 return QDF_STATUS_SUCCESS; 17298 } 17299 17300 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17301 { 17302 struct wmi_ops *ops = wmi_handle->ops; 17303 17304 ops->send_obss_color_collision_cfg_cmd = 17305 send_obss_color_collision_cfg_cmd_tlv; 17306 ops->extract_obss_color_collision_info = 17307 extract_obss_color_collision_info_tlv; 17308 } 17309 17310 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17311 static QDF_STATUS 17312 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17313 struct config_fils_params *param) 17314 { 17315 wmi_buf_t buf; 17316 wmi_enable_fils_cmd_fixed_param *cmd; 17317 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17318 17319 buf = wmi_buf_alloc(wmi_handle, len); 17320 if (!buf) 17321 return QDF_STATUS_E_NOMEM; 17322 17323 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17324 buf); 17325 WMITLV_SET_HDR(&cmd->tlv_header, 17326 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17327 WMITLV_GET_STRUCT_TLVLEN 17328 (wmi_enable_fils_cmd_fixed_param)); 17329 cmd->vdev_id = param->vdev_id; 17330 cmd->fd_period = param->fd_period; 17331 if (param->send_prb_rsp_frame) 17332 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17333 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17334 cmd->vdev_id, cmd->fd_period, cmd->flags); 17335 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17336 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17337 WMI_ENABLE_FILS_CMDID)) { 17338 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17339 wmi_buf_free(buf); 17340 return QDF_STATUS_E_FAILURE; 17341 } 17342 17343 return QDF_STATUS_SUCCESS; 17344 } 17345 #endif 17346 17347 #ifdef WLAN_MWS_INFO_DEBUGFS 17348 /** 17349 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17350 * 17351 * @wmi_handle: wmi handle 17352 * @vdev_id: vdev id 17353 * @cmd_id: Coex command id 17354 * 17355 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17356 * 17357 * Return: QDF_STATUS 17358 */ 17359 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17360 uint32_t vdev_id, 17361 uint32_t cmd_id) 17362 { 17363 wmi_buf_t buf; 17364 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17365 uint16_t len = sizeof(*cmd); 17366 int ret; 17367 17368 buf = wmi_buf_alloc(wmi_handle, len); 17369 if (!buf) { 17370 wmi_err("Failed to allocate wmi buffer"); 17371 return QDF_STATUS_E_NOMEM; 17372 } 17373 17374 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17375 WMITLV_SET_HDR(&cmd->tlv_header, 17376 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17377 WMITLV_GET_STRUCT_TLVLEN 17378 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17379 cmd->vdev_id = vdev_id; 17380 cmd->cmd_id = cmd_id; 17381 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17382 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17383 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17384 if (QDF_IS_STATUS_ERROR(ret)) { 17385 wmi_err("Failed to send set param command ret = %d", ret); 17386 wmi_buf_free(buf); 17387 } 17388 return ret; 17389 } 17390 #endif 17391 17392 #ifdef FEATURE_MEC_OFFLOAD 17393 static QDF_STATUS 17394 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17395 struct set_mec_timer_params *param) 17396 { 17397 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17398 wmi_buf_t buf; 17399 int32_t len = sizeof(*cmd); 17400 17401 buf = wmi_buf_alloc(wmi_handle, len); 17402 if (!buf) { 17403 wmi_err("wmi_buf_alloc failed"); 17404 return QDF_STATUS_E_FAILURE; 17405 } 17406 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17407 wmi_buf_data(buf); 17408 WMITLV_SET_HDR(&cmd->tlv_header, 17409 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17410 WMITLV_GET_STRUCT_TLVLEN( 17411 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17412 cmd->pdev_id = param->pdev_id; 17413 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17414 17415 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17416 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17417 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17418 wmi_err("Failed to set mec aging timer param"); 17419 wmi_buf_free(buf); 17420 return QDF_STATUS_E_FAILURE; 17421 } 17422 17423 return QDF_STATUS_SUCCESS; 17424 } 17425 #endif 17426 17427 #ifdef WIFI_POS_CONVERGED 17428 /** 17429 * extract_oem_response_param_tlv() - Extract oem response params 17430 * @wmi_handle: wmi handle 17431 * @resp_buf: response buffer 17432 * @oem_resp_param: pointer to hold oem response params 17433 * 17434 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17435 */ 17436 static QDF_STATUS 17437 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17438 struct wmi_oem_response_param *oem_resp_param) 17439 { 17440 uint64_t temp_addr; 17441 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17442 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17443 17444 if (!param_buf) { 17445 wmi_err("Invalid OEM response"); 17446 return QDF_STATUS_E_INVAL; 17447 } 17448 17449 if (param_buf->num_data) { 17450 oem_resp_param->num_data1 = param_buf->num_data; 17451 oem_resp_param->data_1 = param_buf->data; 17452 } 17453 17454 if (param_buf->num_data2) { 17455 oem_resp_param->num_data2 = param_buf->num_data2; 17456 oem_resp_param->data_2 = param_buf->data2; 17457 } 17458 17459 if (param_buf->indirect_data) { 17460 oem_resp_param->indirect_data.pdev_id = 17461 param_buf->indirect_data->pdev_id; 17462 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17463 oem_resp_param->indirect_data.addr = 17464 param_buf->indirect_data->addr_lo + 17465 ((uint64_t)temp_addr << 32); 17466 oem_resp_param->indirect_data.len = 17467 param_buf->indirect_data->len; 17468 } 17469 17470 return QDF_STATUS_SUCCESS; 17471 } 17472 #endif /* WIFI_POS_CONVERGED */ 17473 17474 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 17475 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 17476 17477 static QDF_STATUS 17478 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17479 struct wifi_pos_pasn_peer_data *dst) 17480 { 17481 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 17482 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 17483 wmi_rtt_pasn_peer_create_req_param *buf; 17484 uint8_t security_mode, i; 17485 17486 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 17487 if (!param_buf) { 17488 wmi_err("Invalid peer_create req buffer"); 17489 return QDF_STATUS_E_INVAL; 17490 } 17491 17492 fixed_param = param_buf->fixed_param; 17493 17494 if (param_buf->num_rtt_pasn_peer_param > 17495 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17496 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 17497 wmi_err("Invalid TLV size"); 17498 return QDF_STATUS_E_INVAL; 17499 } 17500 17501 if (!param_buf->num_rtt_pasn_peer_param || 17502 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17503 wmi_err("Invalid num TLV:%d", 17504 param_buf->num_rtt_pasn_peer_param); 17505 return QDF_STATUS_E_INVAL; 17506 } 17507 17508 dst->vdev_id = fixed_param->vdev_id; 17509 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17510 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17511 return QDF_STATUS_E_INVAL; 17512 } 17513 17514 buf = param_buf->rtt_pasn_peer_param; 17515 if (!buf) { 17516 wmi_err("NULL peer param TLV"); 17517 return QDF_STATUS_E_INVAL; 17518 } 17519 17520 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17521 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 17522 dst->peer_info[i].self_mac.bytes); 17523 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 17524 dst->peer_info[i].peer_mac.bytes); 17525 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 17526 buf->control_flag); 17527 if (security_mode) 17528 dst->peer_info[i].peer_type = 17529 WLAN_WIFI_POS_PASN_SECURE_PEER; 17530 else 17531 dst->peer_info[i].peer_type = 17532 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 17533 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 17534 dst->peer_info[i].is_ltf_keyseed_required = true; 17535 17536 dst->peer_info[i].force_self_mac_usage = 17537 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 17538 buf->control_flag); 17539 dst->num_peers++; 17540 buf++; 17541 } 17542 17543 return QDF_STATUS_SUCCESS; 17544 } 17545 17546 static QDF_STATUS 17547 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17548 struct wifi_pos_pasn_peer_data *dst) 17549 { 17550 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 17551 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 17552 wmi_rtt_pasn_peer_delete_param *buf; 17553 uint8_t i; 17554 17555 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 17556 if (!param_buf) { 17557 wmi_err("Invalid peer_delete evt buffer"); 17558 return QDF_STATUS_E_INVAL; 17559 } 17560 17561 fixed_param = param_buf->fixed_param; 17562 17563 if (param_buf->num_rtt_pasn_peer_param > 17564 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17565 sizeof(wmi_rtt_pasn_peer_delete_param))) { 17566 wmi_err("Invalid TLV size"); 17567 return QDF_STATUS_E_INVAL; 17568 } 17569 17570 if (!param_buf->num_rtt_pasn_peer_param || 17571 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17572 wmi_err("Invalid num TLV:%d", 17573 param_buf->num_rtt_pasn_peer_param); 17574 return QDF_STATUS_E_INVAL; 17575 } 17576 17577 dst->vdev_id = fixed_param->vdev_id; 17578 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17579 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17580 return QDF_STATUS_E_INVAL; 17581 } 17582 17583 buf = param_buf->rtt_pasn_peer_param; 17584 if (!buf) { 17585 wmi_err("NULL peer param TLV"); 17586 return QDF_STATUS_E_INVAL; 17587 } 17588 17589 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17590 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 17591 dst->peer_info[i].peer_mac.bytes); 17592 dst->peer_info[i].control_flags = buf->control_flag; 17593 17594 dst->num_peers++; 17595 buf++; 17596 } 17597 17598 return QDF_STATUS_SUCCESS; 17599 } 17600 17601 static QDF_STATUS 17602 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 17603 struct wlan_pasn_auth_status *data) 17604 { 17605 QDF_STATUS status; 17606 wmi_buf_t buf; 17607 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 17608 uint8_t *buf_ptr; 17609 uint8_t i; 17610 size_t len = sizeof(*fixed_param) + 17611 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 17612 WMI_TLV_HDR_SIZE; 17613 17614 buf = wmi_buf_alloc(wmi_handle, len); 17615 if (!buf) { 17616 wmi_err("wmi_buf_alloc failed"); 17617 return QDF_STATUS_E_FAILURE; 17618 } 17619 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17620 fixed_param = 17621 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 17622 WMITLV_SET_HDR(&fixed_param->tlv_header, 17623 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 17624 WMITLV_GET_STRUCT_TLVLEN( 17625 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 17626 buf_ptr += sizeof(*fixed_param); 17627 17628 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 17629 (data->num_peers * 17630 sizeof(wmi_rtt_pasn_auth_status_param))); 17631 buf_ptr += WMI_TLV_HDR_SIZE; 17632 17633 for (i = 0; i < data->num_peers; i++) { 17634 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 17635 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 17636 17637 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 17638 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 17639 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 17640 17641 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 17642 &auth_status_tlv->peer_mac_addr); 17643 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 17644 &auth_status_tlv->source_mac_addr); 17645 auth_status_tlv->status = data->auth_status[i].status; 17646 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 17647 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 17648 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 17649 auth_status_tlv->status); 17650 17651 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 17652 } 17653 17654 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 17655 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17656 WMI_RTT_PASN_AUTH_STATUS_CMD); 17657 if (QDF_IS_STATUS_ERROR(status)) { 17658 wmi_err("Failed to send Auth status command ret = %d", status); 17659 wmi_buf_free(buf); 17660 } 17661 17662 return status; 17663 } 17664 17665 static QDF_STATUS 17666 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 17667 struct qdf_mac_addr *peer_mac) 17668 { 17669 QDF_STATUS status; 17670 wmi_buf_t buf; 17671 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 17672 size_t len = sizeof(*fixed_param); 17673 17674 buf = wmi_buf_alloc(wmi_handle, len); 17675 if (!buf) { 17676 wmi_err("wmi_buf_alloc failed"); 17677 return QDF_STATUS_E_FAILURE; 17678 } 17679 fixed_param = 17680 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 17681 WMITLV_SET_HDR(&fixed_param->tlv_header, 17682 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 17683 WMITLV_GET_STRUCT_TLVLEN( 17684 wmi_rtt_pasn_deauth_cmd_fixed_param)); 17685 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 17686 &fixed_param->peer_mac_addr); 17687 17688 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 17689 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17690 WMI_RTT_PASN_DEAUTH_CMD); 17691 if (QDF_IS_STATUS_ERROR(status)) { 17692 wmi_err("Failed to send pasn deauth command ret = %d", status); 17693 wmi_buf_free(buf); 17694 } 17695 17696 return status; 17697 } 17698 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 17699 17700 static QDF_STATUS 17701 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 17702 struct wlan_crypto_ltf_keyseed_data *data) 17703 { 17704 QDF_STATUS status; 17705 wmi_buf_t buf; 17706 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 17707 uint8_t *buf_ptr; 17708 size_t len = sizeof(*fixed_param) + data->key_seed_len + 17709 WMI_TLV_HDR_SIZE; 17710 17711 buf = wmi_buf_alloc(wmi_handle, len); 17712 if (!buf) { 17713 wmi_err("wmi_buf_alloc failed"); 17714 return QDF_STATUS_E_FAILURE; 17715 } 17716 17717 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17718 fixed_param = 17719 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 17720 WMITLV_SET_HDR(&fixed_param->tlv_header, 17721 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 17722 WMITLV_GET_STRUCT_TLVLEN( 17723 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 17724 17725 fixed_param->vdev_id = data->vdev_id; 17726 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 17727 &fixed_param->peer_macaddr); 17728 fixed_param->key_seed_len = data->key_seed_len; 17729 fixed_param->rsn_authmode = data->rsn_authmode; 17730 17731 buf_ptr += sizeof(*fixed_param); 17732 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 17733 (fixed_param->key_seed_len * sizeof(A_UINT8))); 17734 buf_ptr += WMI_TLV_HDR_SIZE; 17735 17736 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 17737 17738 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 17739 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17740 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 17741 if (QDF_IS_STATUS_ERROR(status)) { 17742 wmi_err("Failed to send ltf keyseed command ret = %d", status); 17743 wmi_buf_free(buf); 17744 } 17745 17746 return status; 17747 } 17748 17749 /** 17750 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 17751 * @wmi_handle: wmi handle 17752 * @event_buf: pointer to event buffer 17753 * @cmd_status: status of HW mode change command 17754 * 17755 * Return QDF_STATUS_SUCCESS on success or proper error code. 17756 */ 17757 static QDF_STATUS 17758 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17759 uint32_t *cmd_status) 17760 { 17761 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 17762 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 17763 17764 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 17765 if (!param_buf) { 17766 wmi_err("Invalid mode change event buffer"); 17767 return QDF_STATUS_E_INVAL; 17768 } 17769 17770 fixed_param = param_buf->fixed_param; 17771 if (!fixed_param) { 17772 wmi_err("Invalid fixed param"); 17773 return QDF_STATUS_E_INVAL; 17774 } 17775 17776 *cmd_status = fixed_param->status; 17777 return QDF_STATUS_SUCCESS; 17778 } 17779 17780 #ifdef FEATURE_ANI_LEVEL_REQUEST 17781 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 17782 uint32_t *freqs, 17783 uint8_t num_freqs) 17784 { 17785 wmi_buf_t buf; 17786 wmi_get_channel_ani_cmd_fixed_param *cmd; 17787 QDF_STATUS ret; 17788 uint32_t len; 17789 A_UINT32 *chan_list; 17790 uint8_t i, *buf_ptr; 17791 17792 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 17793 WMI_TLV_HDR_SIZE + 17794 num_freqs * sizeof(A_UINT32); 17795 17796 buf = wmi_buf_alloc(wmi_handle, len); 17797 if (!buf) 17798 return QDF_STATUS_E_FAILURE; 17799 17800 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17801 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 17802 WMITLV_SET_HDR(&cmd->tlv_header, 17803 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 17804 WMITLV_GET_STRUCT_TLVLEN( 17805 wmi_get_channel_ani_cmd_fixed_param)); 17806 17807 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 17808 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 17809 (num_freqs * sizeof(A_UINT32))); 17810 17811 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 17812 for (i = 0; i < num_freqs; i++) { 17813 chan_list[i] = freqs[i]; 17814 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 17815 } 17816 17817 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17818 WMI_GET_CHANNEL_ANI_CMDID); 17819 17820 if (QDF_IS_STATUS_ERROR(ret)) { 17821 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 17822 wmi_buf_free(buf); 17823 } 17824 17825 return ret; 17826 } 17827 17828 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 17829 struct wmi_host_ani_level_event **info, 17830 uint32_t *num_freqs) 17831 { 17832 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 17833 wmi_get_channel_ani_event_fixed_param *fixed_param; 17834 wmi_channel_ani_info_tlv_param *tlv_params; 17835 uint8_t *buf_ptr, i; 17836 17837 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 17838 if (!param_buf) { 17839 wmi_err("Invalid ani level event buffer"); 17840 return QDF_STATUS_E_INVAL; 17841 } 17842 17843 fixed_param = 17844 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 17845 if (!fixed_param) { 17846 wmi_err("Invalid fixed param"); 17847 return QDF_STATUS_E_INVAL; 17848 } 17849 17850 buf_ptr = (uint8_t *)fixed_param; 17851 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 17852 buf_ptr += WMI_TLV_HDR_SIZE; 17853 17854 *num_freqs = param_buf->num_ani_info; 17855 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 17856 wmi_err("Invalid number of freqs received"); 17857 return QDF_STATUS_E_INVAL; 17858 } 17859 17860 *info = qdf_mem_malloc(*num_freqs * 17861 sizeof(struct wmi_host_ani_level_event)); 17862 if (!(*info)) 17863 return QDF_STATUS_E_NOMEM; 17864 17865 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 17866 for (i = 0; i < param_buf->num_ani_info; i++) { 17867 (*info)[i].ani_level = tlv_params->ani_level; 17868 (*info)[i].chan_freq = tlv_params->chan_freq; 17869 tlv_params++; 17870 } 17871 17872 return QDF_STATUS_SUCCESS; 17873 } 17874 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 17875 17876 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 17877 /** 17878 * convert_wtc_scan_mode() - Function to convert TLV specific 17879 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 17880 * @scan_mode: scan freq scheme coming from firmware 17881 * 17882 * Return: ROAM_TRIGGER_SCAN_MODE 17883 */ 17884 static enum roam_scan_freq_scheme 17885 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 17886 { 17887 switch (scan_mode) { 17888 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 17889 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 17890 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 17891 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 17892 case ROAM_TRIGGER_SCAN_MODE_FULL: 17893 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 17894 default: 17895 return ROAM_SCAN_FREQ_SCHEME_NONE; 17896 } 17897 } 17898 17899 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 17900 { 17901 switch (fw_trig_reason) { 17902 case WMI_ROAM_TRIGGER_REASON_NONE: 17903 return ROAM_TRIGGER_REASON_NONE; 17904 case WMI_ROAM_TRIGGER_REASON_PER: 17905 return ROAM_TRIGGER_REASON_PER; 17906 case WMI_ROAM_TRIGGER_REASON_BMISS: 17907 return ROAM_TRIGGER_REASON_BMISS; 17908 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 17909 return ROAM_TRIGGER_REASON_LOW_RSSI; 17910 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 17911 return ROAM_TRIGGER_REASON_HIGH_RSSI; 17912 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 17913 return ROAM_TRIGGER_REASON_PERIODIC; 17914 case WMI_ROAM_TRIGGER_REASON_MAWC: 17915 return ROAM_TRIGGER_REASON_MAWC; 17916 case WMI_ROAM_TRIGGER_REASON_DENSE: 17917 return ROAM_TRIGGER_REASON_DENSE; 17918 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 17919 return ROAM_TRIGGER_REASON_BACKGROUND; 17920 case WMI_ROAM_TRIGGER_REASON_FORCED: 17921 return ROAM_TRIGGER_REASON_FORCED; 17922 case WMI_ROAM_TRIGGER_REASON_BTM: 17923 return ROAM_TRIGGER_REASON_BTM; 17924 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 17925 return ROAM_TRIGGER_REASON_UNIT_TEST; 17926 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 17927 return ROAM_TRIGGER_REASON_BSS_LOAD; 17928 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 17929 return ROAM_TRIGGER_REASON_DEAUTH; 17930 case WMI_ROAM_TRIGGER_REASON_IDLE: 17931 return ROAM_TRIGGER_REASON_IDLE; 17932 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 17933 return ROAM_TRIGGER_REASON_STA_KICKOUT; 17934 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 17935 return ROAM_TRIGGER_REASON_ESS_RSSI; 17936 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 17937 return ROAM_TRIGGER_REASON_WTC_BTM; 17938 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 17939 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 17940 case WMI_ROAM_TRIGGER_REASON_BTC: 17941 return ROAM_TRIGGER_REASON_BTC; 17942 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 17943 return ROAM_TRIGGER_REASON_MAX; 17944 default: 17945 return ROAM_TRIGGER_REASON_NONE; 17946 } 17947 } 17948 17949 /** 17950 * extract_roam_11kv_candidate_info - Extract btm candidate info 17951 * @wmi_handle: wmi_handle 17952 * @evt_buf: Event buffer 17953 * @dst_info: Destination buffer 17954 * 17955 * Return: QDF_STATUS 17956 */ 17957 static QDF_STATUS 17958 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 17959 struct wmi_btm_req_candidate_info *dst_info, 17960 uint8_t btm_idx, uint16_t num_cand) 17961 { 17962 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17963 wmi_roam_btm_request_candidate_info *src_data; 17964 uint8_t i; 17965 17966 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17967 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 17968 !param_buf->num_roam_btm_request_candidate_info || 17969 (btm_idx + 17970 num_cand) > param_buf->num_roam_btm_request_candidate_info) 17971 return QDF_STATUS_SUCCESS; 17972 17973 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 17974 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 17975 num_cand = WLAN_MAX_BTM_CANDIDATE; 17976 for (i = 0; i < num_cand; i++) { 17977 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 17978 dst_info->candidate_bssid.bytes); 17979 dst_info->preference = src_data->preference; 17980 src_data++; 17981 dst_info++; 17982 } 17983 17984 return QDF_STATUS_SUCCESS; 17985 } 17986 17987 static enum roam_trigger_sub_reason 17988 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 17989 { 17990 switch (subreason) { 17991 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 17992 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 17993 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 17994 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 17995 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 17996 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 17997 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 17998 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 17999 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18000 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18001 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18002 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18003 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18004 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18005 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18006 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18007 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18008 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18009 default: 18010 break; 18011 } 18012 18013 return 0; 18014 } 18015 18016 /** 18017 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18018 * from the WMI_ROAM_STATS_EVENTID 18019 * @wmi_handle: wmi handle 18020 * @evt_buf: Pointer to the event buffer 18021 * @trig: Pointer to destination structure to fill data 18022 * @idx: TLV id 18023 */ 18024 static QDF_STATUS 18025 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18026 struct wmi_roam_trigger_info *trig, uint8_t idx, 18027 uint8_t btm_idx) 18028 { 18029 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18030 wmi_roam_trigger_reason *src_data = NULL; 18031 uint32_t trig_reason; 18032 18033 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18034 if (!param_buf || !param_buf->roam_trigger_reason) 18035 return QDF_STATUS_E_FAILURE; 18036 18037 src_data = ¶m_buf->roam_trigger_reason[idx]; 18038 18039 trig->present = true; 18040 trig_reason = src_data->trigger_reason; 18041 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 18042 trig->trigger_sub_reason = 18043 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18044 trig->current_rssi = src_data->current_rssi; 18045 trig->timestamp = src_data->timestamp; 18046 18047 switch (trig_reason) { 18048 case WMI_ROAM_TRIGGER_REASON_PER: 18049 case WMI_ROAM_TRIGGER_REASON_BMISS: 18050 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18051 case WMI_ROAM_TRIGGER_REASON_MAWC: 18052 case WMI_ROAM_TRIGGER_REASON_DENSE: 18053 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18054 case WMI_ROAM_TRIGGER_REASON_IDLE: 18055 case WMI_ROAM_TRIGGER_REASON_FORCED: 18056 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18057 case WMI_ROAM_TRIGGER_REASON_BTC: 18058 return QDF_STATUS_SUCCESS; 18059 18060 case WMI_ROAM_TRIGGER_REASON_BTM: 18061 trig->btm_trig_data.btm_request_mode = 18062 src_data->btm_request_mode; 18063 trig->btm_trig_data.disassoc_timer = 18064 src_data->disassoc_imminent_timer; 18065 trig->btm_trig_data.validity_interval = 18066 src_data->validity_internal; 18067 trig->btm_trig_data.candidate_list_count = 18068 src_data->candidate_list_count; 18069 trig->btm_trig_data.btm_resp_status = 18070 src_data->btm_response_status_code; 18071 trig->btm_trig_data.btm_bss_termination_timeout = 18072 src_data->btm_bss_termination_timeout; 18073 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18074 src_data->btm_mbo_assoc_retry_timeout; 18075 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 18076 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 18077 param_buf->num_roam_btm_request_candidate_info) 18078 extract_roam_11kv_candidate_info( 18079 wmi_handle, evt_buf, 18080 trig->btm_trig_data.btm_cand, 18081 btm_idx, 18082 src_data->candidate_list_count); 18083 18084 return QDF_STATUS_SUCCESS; 18085 18086 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18087 trig->cu_trig_data.cu_load = src_data->cu_load; 18088 return QDF_STATUS_SUCCESS; 18089 18090 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18091 trig->deauth_trig_data.type = src_data->deauth_type; 18092 trig->deauth_trig_data.reason = src_data->deauth_reason; 18093 return QDF_STATUS_SUCCESS; 18094 18095 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18096 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18097 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 18098 return QDF_STATUS_SUCCESS; 18099 18100 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18101 trig->wtc_btm_trig_data.roaming_mode = 18102 src_data->vendor_specific1[0]; 18103 trig->wtc_btm_trig_data.vsie_trigger_reason = 18104 src_data->vendor_specific1[1]; 18105 trig->wtc_btm_trig_data.sub_code = 18106 src_data->vendor_specific1[2]; 18107 trig->wtc_btm_trig_data.wtc_mode = 18108 src_data->vendor_specific1[3]; 18109 trig->wtc_btm_trig_data.wtc_scan_mode = 18110 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 18111 trig->wtc_btm_trig_data.wtc_rssi_th = 18112 src_data->vendor_specific1[5]; 18113 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 18114 src_data->vendor_specific1[6]; 18115 18116 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 18117 src_data->vendor_specific2[0]; 18118 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 18119 src_data->vendor_specific2[1]; 18120 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 18121 src_data->vendor_specific2[2]; 18122 trig->wtc_btm_trig_data.duration = 18123 src_data->vendor_specific2[3]; 18124 18125 return QDF_STATUS_SUCCESS; 18126 default: 18127 return QDF_STATUS_SUCCESS; 18128 } 18129 18130 return QDF_STATUS_SUCCESS; 18131 } 18132 18133 /** 18134 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 18135 * from the WMI_ROAM_STATS_EVENTID 18136 * @wmi_handle: wmi handle 18137 * @evt_buf: Pointer to the event buffer 18138 * @dst: Pointer to destination structure to fill data 18139 * @ap_idx: TLV index for this roam scan 18140 * @num_cand: number of candidates list in the roam scan 18141 */ 18142 static QDF_STATUS 18143 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18144 struct wmi_roam_candidate_info *dst, 18145 uint8_t ap_idx, uint16_t num_cand) 18146 { 18147 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18148 wmi_roam_ap_info *src = NULL; 18149 uint8_t i; 18150 18151 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18152 if (!param_buf) { 18153 wmi_err("Param buf is NULL"); 18154 return QDF_STATUS_E_FAILURE; 18155 } 18156 18157 if (ap_idx >= param_buf->num_roam_ap_info) { 18158 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 18159 ap_idx, param_buf->num_roam_ap_info); 18160 return QDF_STATUS_E_FAILURE; 18161 } 18162 18163 src = ¶m_buf->roam_ap_info[ap_idx]; 18164 18165 for (i = 0; i < num_cand; i++) { 18166 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 18167 dst->type = src->candidate_type; 18168 dst->freq = src->channel; 18169 dst->etp = src->etp; 18170 dst->rssi = src->rssi; 18171 dst->rssi_score = src->rssi_score; 18172 dst->cu_load = src->cu_load; 18173 dst->cu_score = src->cu_score; 18174 dst->total_score = src->total_score; 18175 dst->timestamp = src->timestamp; 18176 dst->dl_reason = src->bl_reason; 18177 dst->dl_source = src->bl_source; 18178 dst->dl_timestamp = src->bl_timestamp; 18179 dst->dl_original_timeout = src->bl_original_timeout; 18180 18181 src++; 18182 dst++; 18183 } 18184 18185 return QDF_STATUS_SUCCESS; 18186 } 18187 18188 /** 18189 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18190 * from the WMI_ROAM_STATS_EVENTID 18191 * @wmi_handle: wmi handle 18192 * @evt_buf: Pointer to the event buffer 18193 * @dst: Pointer to destination structure to fill data 18194 * @idx: TLV id 18195 * @chan_idx: Index of the channel tlv for the current roam trigger 18196 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 18197 */ 18198 static QDF_STATUS 18199 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18200 struct wmi_roam_scan_data *dst, uint8_t idx, 18201 uint8_t chan_idx, uint8_t ap_idx) 18202 { 18203 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18204 wmi_roam_scan_info *src_data = NULL; 18205 wmi_roam_scan_channel_info *src_chan = NULL; 18206 QDF_STATUS status; 18207 uint8_t i; 18208 18209 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18210 if (!param_buf || !param_buf->roam_scan_info || 18211 idx >= param_buf->num_roam_scan_info) 18212 return QDF_STATUS_E_FAILURE; 18213 18214 src_data = ¶m_buf->roam_scan_info[idx]; 18215 18216 dst->present = true; 18217 dst->type = src_data->roam_scan_type; 18218 dst->num_chan = src_data->roam_scan_channel_count; 18219 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 18220 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 18221 dst->frame_info_count = src_data->frame_info_count; 18222 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 18223 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 18224 18225 /* Read the channel data only for dst->type is 0 (partial scan) */ 18226 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 18227 chan_idx < param_buf->num_roam_scan_chan_info) { 18228 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 18229 dst->num_chan = MAX_ROAM_SCAN_CHAN; 18230 18231 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 18232 for (i = 0; i < dst->num_chan; i++) { 18233 dst->chan_freq[i] = src_chan->channel; 18234 src_chan++; 18235 } 18236 } 18237 18238 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 18239 return QDF_STATUS_SUCCESS; 18240 18241 dst->num_ap = src_data->roam_ap_count; 18242 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 18243 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 18244 18245 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 18246 ap_idx, dst->num_ap); 18247 if (QDF_IS_STATUS_ERROR(status)) { 18248 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 18249 return status; 18250 } 18251 18252 return QDF_STATUS_SUCCESS; 18253 } 18254 18255 /** 18256 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18257 * @wmi_roam_fail_reason: roam fail enum 18258 * 18259 * Return: Roaming failure reason codes 18260 */ 18261 static enum wlan_roam_failure_reason_code 18262 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18263 { 18264 switch (wmi_roam_fail_reason) { 18265 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18266 return ROAM_FAIL_REASON_NO_SCAN_START; 18267 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18268 return ROAM_FAIL_REASON_NO_AP_FOUND; 18269 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18270 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18271 case WMI_ROAM_FAIL_REASON_HOST: 18272 return ROAM_FAIL_REASON_HOST; 18273 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18274 return ROAM_FAIL_REASON_AUTH_SEND; 18275 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18276 return ROAM_FAIL_REASON_AUTH_RECV; 18277 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18278 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18279 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18280 return ROAM_FAIL_REASON_REASSOC_SEND; 18281 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18282 return ROAM_FAIL_REASON_REASSOC_RECV; 18283 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18284 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18285 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18286 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18287 case WMI_ROAM_FAIL_REASON_MLME: 18288 return ROAM_FAIL_REASON_MLME; 18289 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18290 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18291 case WMI_ROAM_FAIL_REASON_SCAN_START: 18292 return ROAM_FAIL_REASON_SCAN_START; 18293 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18294 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18295 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18296 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18297 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18298 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18299 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18300 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18301 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18302 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18303 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18304 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18305 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18306 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18307 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18308 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18309 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18310 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18311 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18312 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18313 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18314 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18315 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18316 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18317 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18318 return ROAM_FAIL_REASON_DISCONNECT; 18319 case WMI_ROAM_FAIL_REASON_SYNC: 18320 return ROAM_FAIL_REASON_SYNC; 18321 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18322 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18323 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18324 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18325 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18326 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18327 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18328 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18329 default: 18330 return ROAM_FAIL_REASON_UNKNOWN; 18331 } 18332 } 18333 18334 /** 18335 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18336 * from the WMI_ROAM_STATS_EVENTID 18337 * @wmi_handle: wmi handle 18338 * @evt_buf: Pointer to the event buffer 18339 * @dst: Pointer to destination structure to fill data 18340 * @idx: TLV id 18341 */ 18342 static QDF_STATUS 18343 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18344 struct wmi_roam_result *dst, uint8_t idx) 18345 { 18346 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18347 wmi_roam_result *src_data = NULL; 18348 18349 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18350 if (!param_buf || !param_buf->roam_result || 18351 idx >= param_buf->num_roam_result) 18352 return QDF_STATUS_E_FAILURE; 18353 18354 src_data = ¶m_buf->roam_result[idx]; 18355 18356 dst->present = true; 18357 dst->status = src_data->roam_status; 18358 dst->timestamp = src_data->timestamp; 18359 dst->fail_reason = 18360 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 18361 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 18362 18363 return QDF_STATUS_SUCCESS; 18364 } 18365 18366 /** 18367 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 18368 * from the WMI_ROAM_STATS_EVENTID 18369 * @wmi_handle: wmi handle 18370 * @evt_buf: Pointer to the event buffer 18371 * @dst: Pointer to destination structure to fill data 18372 * @idx: TLV id 18373 * @rpt_idx: Neighbor report Channel index 18374 */ 18375 static QDF_STATUS 18376 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18377 struct wmi_neighbor_report_data *dst, 18378 uint8_t idx, uint8_t rpt_idx) 18379 { 18380 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18381 wmi_roam_neighbor_report_info *src_data = NULL; 18382 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 18383 uint8_t i; 18384 18385 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18386 if (!param_buf || !param_buf->roam_neighbor_report_info || 18387 !param_buf->num_roam_neighbor_report_info || 18388 idx >= param_buf->num_roam_neighbor_report_info) { 18389 wmi_debug("Invalid 1kv param buf"); 18390 return QDF_STATUS_E_FAILURE; 18391 } 18392 18393 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 18394 18395 dst->present = true; 18396 dst->req_type = src_data->request_type; 18397 dst->num_freq = src_data->neighbor_report_channel_count; 18398 dst->req_time = src_data->neighbor_report_request_timestamp; 18399 dst->resp_time = src_data->neighbor_report_response_timestamp; 18400 dst->btm_query_token = src_data->btm_query_token; 18401 dst->btm_query_reason = src_data->btm_query_reason_code; 18402 18403 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 18404 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 18405 return QDF_STATUS_SUCCESS; 18406 18407 if (!param_buf->roam_neighbor_report_chan_info) { 18408 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 18409 dst->num_freq); 18410 dst->num_freq = 0; 18411 /* return success as its optional tlv and we can print neighbor 18412 * report received info 18413 */ 18414 return QDF_STATUS_SUCCESS; 18415 } 18416 18417 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 18418 18419 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 18420 dst->num_freq = MAX_ROAM_SCAN_CHAN; 18421 18422 for (i = 0; i < dst->num_freq; i++) { 18423 dst->freq[i] = src_freq->channel; 18424 src_freq++; 18425 } 18426 18427 return QDF_STATUS_SUCCESS; 18428 } 18429 18430 /** 18431 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 18432 * @wmi_handle : handle to WMI. 18433 * @roam_param : pointer to hold roam set parameter 18434 * 18435 * Return: 0 on success and -ve on failure. 18436 */ 18437 static QDF_STATUS 18438 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 18439 struct vdev_set_params *roam_param) 18440 { 18441 QDF_STATUS ret; 18442 wmi_roam_set_param_cmd_fixed_param *cmd; 18443 wmi_buf_t buf; 18444 uint16_t len = sizeof(*cmd); 18445 18446 buf = wmi_buf_alloc(wmi_handle, len); 18447 if (!buf) 18448 return QDF_STATUS_E_NOMEM; 18449 18450 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 18451 WMITLV_SET_HDR(&cmd->tlv_header, 18452 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 18453 WMITLV_GET_STRUCT_TLVLEN 18454 (wmi_roam_set_param_cmd_fixed_param)); 18455 cmd->vdev_id = roam_param->vdev_id; 18456 cmd->param_id = roam_param->param_id; 18457 cmd->param_value = roam_param->param_value; 18458 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 18459 cmd->vdev_id, cmd->param_id, cmd->param_value); 18460 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 18461 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18462 WMI_ROAM_SET_PARAM_CMDID); 18463 if (QDF_IS_STATUS_ERROR(ret)) { 18464 wmi_err("Failed to send roam set param command, ret = %d", ret); 18465 wmi_buf_free(buf); 18466 } 18467 18468 return ret; 18469 } 18470 #else 18471 static inline QDF_STATUS 18472 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18473 struct wmi_roam_trigger_info *trig, uint8_t idx, 18474 uint8_t btm_idx) 18475 { 18476 return QDF_STATUS_E_NOSUPPORT; 18477 } 18478 18479 static inline QDF_STATUS 18480 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18481 struct wmi_roam_result *dst, uint8_t idx) 18482 { 18483 return QDF_STATUS_E_NOSUPPORT; 18484 } 18485 18486 static QDF_STATUS 18487 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18488 struct wmi_neighbor_report_data *dst, 18489 uint8_t idx, uint8_t rpt_idx) 18490 { 18491 return QDF_STATUS_E_NOSUPPORT; 18492 } 18493 18494 static QDF_STATUS 18495 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18496 struct wmi_roam_scan_data *dst, uint8_t idx, 18497 uint8_t chan_idx, uint8_t ap_idx) 18498 { 18499 return QDF_STATUS_E_NOSUPPORT; 18500 } 18501 #endif 18502 18503 #ifdef WLAN_FEATURE_PKT_CAPTURE 18504 static QDF_STATUS 18505 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 18506 struct mgmt_offload_event_params *params) 18507 { 18508 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 18509 wmi_mgmt_hdr *hdr; 18510 18511 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 18512 if (!param_tlvs) 18513 return QDF_STATUS_E_INVAL; 18514 18515 hdr = param_tlvs->fixed_param; 18516 if (!hdr) 18517 return QDF_STATUS_E_INVAL; 18518 18519 if (hdr->buf_len > param_tlvs->num_bufp) 18520 return QDF_STATUS_E_INVAL; 18521 18522 params->tsf_l32 = hdr->tsf_l32; 18523 params->chan_freq = hdr->chan_freq; 18524 params->rate_kbps = hdr->rate_kbps; 18525 params->rssi = hdr->rssi; 18526 params->buf_len = hdr->buf_len; 18527 params->tx_status = hdr->tx_status; 18528 params->buf = param_tlvs->bufp; 18529 params->tx_retry_cnt = hdr->tx_retry_cnt; 18530 return QDF_STATUS_SUCCESS; 18531 } 18532 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 18533 18534 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 18535 static QDF_STATUS 18536 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 18537 struct smu_event_params *params) 18538 { 18539 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 18540 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 18541 18542 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 18543 if (!param_buf) { 18544 wmi_err("Invalid smart monitor event"); 18545 return QDF_STATUS_E_INVAL; 18546 } 18547 18548 smu_event = param_buf->fixed_param; 18549 if (!smu_event) { 18550 wmi_err("smart monitor event fixed param is NULL"); 18551 return QDF_STATUS_E_INVAL; 18552 } 18553 18554 params->vdev_id = smu_event->vdev_id; 18555 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 18556 return QDF_STATUS_E_INVAL; 18557 18558 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 18559 18560 return QDF_STATUS_SUCCESS; 18561 } 18562 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 18563 18564 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 18565 /** 18566 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 18567 * 18568 * @wmi: wmi handle 18569 * @vdev_id: vdev id 18570 * @burst_mode: Indicates whether relation derived using FTM is needed for 18571 * each FTM frame or only aggregated result is required. 18572 * 18573 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 18574 * 18575 * Return: QDF_STATUS 18576 */ 18577 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 18578 uint32_t vdev_id, 18579 bool burst_mode) 18580 { 18581 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 18582 wmi_buf_t buf; 18583 int32_t len = sizeof(*cmd); 18584 18585 buf = wmi_buf_alloc(wmi, len); 18586 if (!buf) { 18587 wmi_err("wmi_buf_alloc failed"); 18588 return QDF_STATUS_E_NOMEM; 18589 } 18590 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 18591 WMITLV_SET_HDR(&cmd->tlv_header, 18592 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 18593 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 18594 cmd->vdev_id = vdev_id; 18595 cmd->agg_relation = burst_mode ? false : true; 18596 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 18597 wmi_err("Failed to send audio sync trigger cmd"); 18598 wmi_buf_free(buf); 18599 return QDF_STATUS_E_FAILURE; 18600 } 18601 18602 return QDF_STATUS_SUCCESS; 18603 } 18604 18605 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 18606 uint32_t vdev_id, 18607 uint64_t lpass_ts) 18608 { 18609 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 18610 wmi_buf_t buf; 18611 int32_t len = sizeof(*cmd); 18612 18613 buf = wmi_buf_alloc(wmi, len); 18614 if (!buf) { 18615 wmi_err("wmi_buf_alloc failed"); 18616 return QDF_STATUS_E_NOMEM; 18617 } 18618 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 18619 WMITLV_SET_HDR(&cmd->tlv_header, 18620 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 18621 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 18622 cmd->vdev_id = vdev_id; 18623 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 18624 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 18625 18626 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 18627 wmi_err("Failed to send audio qtime command"); 18628 wmi_buf_free(buf); 18629 return QDF_STATUS_E_FAILURE; 18630 } 18631 18632 return QDF_STATUS_SUCCESS; 18633 } 18634 18635 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 18636 wmi_unified_t wmi, void *buf, 18637 struct ftm_time_sync_start_stop_params *param) 18638 { 18639 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 18640 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 18641 18642 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 18643 if (!param_buf) { 18644 wmi_err("Invalid audio sync start stop event buffer"); 18645 return QDF_STATUS_E_FAILURE; 18646 } 18647 18648 resp_event = param_buf->fixed_param; 18649 if (!resp_event) { 18650 wmi_err("Invalid audio sync start stop fixed param buffer"); 18651 return QDF_STATUS_E_FAILURE; 18652 } 18653 18654 param->vdev_id = resp_event->vdev_id; 18655 param->timer_interval = resp_event->periodicity; 18656 param->num_reads = resp_event->reads_needed; 18657 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 18658 resp_event->qtimer_l32; 18659 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 18660 resp_event->mac_timer_l32; 18661 18662 wmi_debug("FTM time sync time_interval %d, num_reads %d", 18663 param->timer_interval, param->num_reads); 18664 18665 return QDF_STATUS_SUCCESS; 18666 } 18667 18668 static QDF_STATUS 18669 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 18670 struct ftm_time_sync_offset *param) 18671 { 18672 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 18673 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 18674 wmi_audio_sync_q_master_slave_times *q_pair; 18675 int iter; 18676 18677 param_buf = 18678 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 18679 if (!param_buf) { 18680 wmi_err("Invalid timesync ftm offset event buffer"); 18681 return QDF_STATUS_E_FAILURE; 18682 } 18683 18684 resp_event = param_buf->fixed_param; 18685 if (!resp_event) { 18686 wmi_err("Invalid timesync ftm offset fixed param buffer"); 18687 return QDF_STATUS_E_FAILURE; 18688 } 18689 18690 param->vdev_id = resp_event->vdev_id; 18691 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 18692 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 18693 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 18694 18695 q_pair = param_buf->audio_sync_q_master_slave_times; 18696 if (!q_pair) { 18697 wmi_err("Invalid q_master_slave_times buffer"); 18698 return QDF_STATUS_E_FAILURE; 18699 } 18700 18701 for (iter = 0; iter < param->num_qtime; iter++) { 18702 param->pairs[iter].qtime_initiator = ( 18703 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 18704 q_pair[iter].qmaster_l32; 18705 param->pairs[iter].qtime_target = ( 18706 (uint64_t)q_pair[iter].qslave_u32 << 32) | 18707 q_pair[iter].qslave_l32; 18708 } 18709 return QDF_STATUS_SUCCESS; 18710 } 18711 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 18712 18713 /** 18714 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 18715 * @wmi: wmi handle 18716 * @vdev_id: vdev id 18717 * 18718 * TSF_TSTAMP_READ_VALUE is the only operation supported 18719 * Return: QDF_STATUS_SUCCESS for success or erro code 18720 */ 18721 static QDF_STATUS 18722 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 18723 { 18724 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 18725 wmi_buf_t buf; 18726 int32_t len = sizeof(*cmd); 18727 18728 buf = wmi_buf_alloc(wmi, len); 18729 if (!buf) 18730 return QDF_STATUS_E_NOMEM; 18731 18732 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 18733 WMITLV_SET_HDR(&cmd->tlv_header, 18734 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 18735 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 18736 cmd->vdev_id = vdev_id; 18737 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 18738 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 18739 if (wmi_unified_cmd_send(wmi, buf, len, 18740 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 18741 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 18742 __func__); 18743 wmi_buf_free(buf); 18744 return QDF_STATUS_E_FAILURE; 18745 } 18746 18747 return QDF_STATUS_SUCCESS; 18748 } 18749 18750 /** 18751 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 18752 * @wmi_handle: wmi handle 18753 * @param evt_buf: pointer to event buffer 18754 * @wmi_host_tsf_event param: Pointer to struct to hold event info 18755 * 18756 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 18757 */ 18758 static QDF_STATUS 18759 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18760 struct wmi_host_tsf_event *param) 18761 { 18762 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 18763 wmi_vdev_tsf_report_event_fixed_param *evt; 18764 18765 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 18766 if (!param_buf) { 18767 wmi_err("Invalid tsf report event buffer"); 18768 return QDF_STATUS_E_INVAL; 18769 } 18770 18771 evt = param_buf->fixed_param; 18772 param->vdev_id = evt->vdev_id; 18773 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 18774 param->tsf_low = evt->tsf_low; 18775 param->tsf_high = evt->tsf_high; 18776 param->qtimer_low = evt->qtimer_low; 18777 param->qtimer_high = evt->qtimer_high; 18778 param->tsf_id = evt->tsf_id; 18779 param->tsf_id_valid = evt->tsf_id_valid; 18780 param->mac_id = evt->mac_id; 18781 param->mac_id_valid = evt->mac_id_valid; 18782 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 18783 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 18784 param->tqm_timer_low = evt->tqm_timer_low; 18785 param->tqm_timer_high = evt->tqm_timer_high; 18786 param->use_tqm_timer = evt->use_tqm_timer; 18787 18788 return QDF_STATUS_SUCCESS; 18789 } 18790 18791 /** 18792 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18793 * status tlv 18794 * @wmi_handle: wmi handle 18795 * @param evt_buf: pointer to event buffer 18796 * @param param: Pointer to hold csa switch count status event param 18797 * 18798 * Return: QDF_STATUS_SUCCESS for success or error code 18799 */ 18800 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18801 wmi_unified_t wmi_handle, 18802 void *evt_buf, 18803 struct pdev_csa_switch_count_status *param) 18804 { 18805 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18806 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18807 18808 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18809 evt_buf; 18810 if (!param_buf) { 18811 wmi_err("Invalid CSA status event"); 18812 return QDF_STATUS_E_INVAL; 18813 } 18814 18815 csa_status = param_buf->fixed_param; 18816 18817 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18818 wmi_handle, 18819 csa_status->pdev_id); 18820 param->current_switch_count = csa_status->current_switch_count; 18821 param->num_vdevs = csa_status->num_vdevs; 18822 param->vdev_ids = param_buf->vdev_ids; 18823 18824 return QDF_STATUS_SUCCESS; 18825 } 18826 18827 #ifdef CONFIG_AFC_SUPPORT 18828 /** 18829 * send_afc_cmd_tlv() - Sends the AFC indication to FW 18830 * @wmi_handle: wmi handle 18831 * @pdev_id: Pdev id 18832 * @param: Pointer to hold AFC indication. 18833 * 18834 * Return: QDF_STATUS_SUCCESS for success or error code 18835 */ 18836 static 18837 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 18838 uint8_t pdev_id, 18839 struct reg_afc_resp_rx_ind_info *param) 18840 { 18841 wmi_buf_t buf; 18842 wmi_afc_cmd_fixed_param *cmd; 18843 uint32_t len; 18844 uint8_t *buf_ptr; 18845 QDF_STATUS ret; 18846 18847 len = sizeof(wmi_afc_cmd_fixed_param); 18848 buf = wmi_buf_alloc(wmi_handle, len); 18849 if (!buf) 18850 return QDF_STATUS_E_NOMEM; 18851 18852 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18853 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 18854 18855 WMITLV_SET_HDR(&cmd->tlv_header, 18856 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 18857 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 18858 18859 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 18860 wmi_handle, 18861 pdev_id); 18862 cmd->cmd_type = param->cmd_type; 18863 cmd->serv_resp_format = param->serv_resp_format; 18864 18865 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 18866 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 18867 if (QDF_IS_STATUS_ERROR(ret)) { 18868 wmi_err("Failed to send WMI_AFC_CMDID"); 18869 wmi_buf_free(buf); 18870 return QDF_STATUS_E_FAILURE; 18871 } 18872 18873 return QDF_STATUS_SUCCESS; 18874 } 18875 #endif 18876 18877 /** 18878 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 18879 * @wmi_handle: wmi handle 18880 * @param: Pointer to hold TX power info 18881 * 18882 * Return: QDF_STATUS_SUCCESS for success or error code 18883 */ 18884 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 18885 uint8_t vdev_id, 18886 struct reg_tpc_power_info *param) 18887 { 18888 wmi_buf_t buf; 18889 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 18890 wmi_vdev_ch_power_info *ch_power_info; 18891 uint8_t *buf_ptr; 18892 uint16_t idx; 18893 uint32_t len; 18894 QDF_STATUS ret; 18895 18896 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 18897 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 18898 18899 buf = wmi_buf_alloc(wmi_handle, len); 18900 if (!buf) 18901 return QDF_STATUS_E_NOMEM; 18902 18903 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18904 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 18905 18906 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 18907 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 18908 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 18909 18910 tpc_power_info_param->vdev_id = vdev_id; 18911 tpc_power_info_param->psd_power = param->is_psd_power; 18912 tpc_power_info_param->eirp_power = param->eirp_power; 18913 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 18914 wmi_debug("eirp_power = %d is_psd_power = %d power_type_6ghz = %d", 18915 tpc_power_info_param->eirp_power, 18916 tpc_power_info_param->psd_power, 18917 tpc_power_info_param->power_type_6ghz); 18918 18919 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 18920 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 18921 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 18922 18923 buf_ptr += WMI_TLV_HDR_SIZE; 18924 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 18925 18926 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 18927 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 18928 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 18929 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 18930 ch_power_info[idx].chan_cfreq = 18931 param->chan_power_info[idx].chan_cfreq; 18932 ch_power_info[idx].tx_power = 18933 param->chan_power_info[idx].tx_power; 18934 wmi_debug("chan_cfreq = %d tx_power = %d", 18935 ch_power_info[idx].chan_cfreq, 18936 ch_power_info[idx].tx_power); 18937 buf_ptr += sizeof(wmi_vdev_ch_power_info); 18938 } 18939 18940 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 18941 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18942 WMI_VDEV_SET_TPC_POWER_CMDID); 18943 if (QDF_IS_STATUS_ERROR(ret)) 18944 wmi_buf_free(buf); 18945 18946 18947 return ret; 18948 } 18949 18950 /** 18951 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 18952 * @wmi_handle: wmi handle 18953 * @evt_buf: event buffer 18954 * @param: dpd status info 18955 * 18956 * Return: QDF_STATUS_SUCCESS for success or error code 18957 */ 18958 static QDF_STATUS 18959 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 18960 void *evt_buf, 18961 struct wmi_host_pdev_get_dpd_status_event *param) 18962 { 18963 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 18964 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 18965 18966 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 18967 if (!param_buf) { 18968 wmi_err("Invalid get dpd_status event"); 18969 return QDF_STATUS_E_INVAL; 18970 } 18971 18972 dpd_status = param_buf->fixed_param; 18973 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 18974 (wmi_handle, dpd_status->pdev_id); 18975 param->dpd_status = dpd_status->dpd_status; 18976 18977 return QDF_STATUS_SUCCESS; 18978 } 18979 18980 static int 18981 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 18982 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 18983 { 18984 if (status->halphy_cal_valid_bmap && valid_bit) 18985 return (status->halphy_cal_status && valid_bit); 18986 18987 return 0; 18988 } 18989 18990 static QDF_STATUS 18991 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 18992 void *evt_buf, 18993 struct wmi_host_pdev_get_halphy_cal_status_event *param) 18994 { 18995 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 18996 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 18997 18998 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 18999 if (!param_buf) { 19000 wmi_err("Invalid get halphy cal status event"); 19001 return QDF_STATUS_E_INVAL; 19002 } 19003 19004 halphy_cal_status = param_buf->fixed_param; 19005 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19006 (wmi_handle, halphy_cal_status->pdev_id); 19007 param->halphy_cal_adc_status = 19008 convert_halphy_status(halphy_cal_status, 19009 WMI_HALPHY_CAL_ADC_BMAP); 19010 param->halphy_cal_bwfilter_status = 19011 convert_halphy_status(halphy_cal_status, 19012 WMI_HALPHY_CAL_BWFILTER_BMAP); 19013 param->halphy_cal_pdet_and_pal_status = 19014 convert_halphy_status(halphy_cal_status, 19015 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19016 param->halphy_cal_rxdco_status = 19017 convert_halphy_status(halphy_cal_status, 19018 WMI_HALPHY_CAL_RXDCO_BMAP); 19019 param->halphy_cal_comb_txiq_rxiq_status = 19020 convert_halphy_status(halphy_cal_status, 19021 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19022 param->halphy_cal_ibf_status = 19023 convert_halphy_status(halphy_cal_status, 19024 WMI_HALPHY_CAL_IBF_BMAP); 19025 param->halphy_cal_pa_droop_status = 19026 convert_halphy_status(halphy_cal_status, 19027 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19028 param->halphy_cal_dac_status = 19029 convert_halphy_status(halphy_cal_status, 19030 WMI_HALPHY_CAL_DAC_BMAP); 19031 param->halphy_cal_ani_status = 19032 convert_halphy_status(halphy_cal_status, 19033 WMI_HALPHY_CAL_ANI_BMAP); 19034 param->halphy_cal_noise_floor_status = 19035 convert_halphy_status(halphy_cal_status, 19036 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19037 19038 return QDF_STATUS_SUCCESS; 19039 } 19040 19041 /** 19042 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19043 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19044 * 19045 * Return: host_set_halphy_cal_status 19046 */ 19047 static enum wmi_host_set_halphy_cal_status 19048 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19049 { 19050 if (fw_status == 0) 19051 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19052 else if (fw_status == 1) 19053 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19054 19055 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19056 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19057 } 19058 19059 /** 19060 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19061 * @wmi_handle: wmi handle 19062 * @evt_buf: event buffer 19063 * @param: set halphy cal status info 19064 * 19065 * Return: QDF_STATUS_SUCCESS for success or error code 19066 */ 19067 static QDF_STATUS 19068 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19069 void *evt_buf, 19070 struct wmi_host_pdev_set_halphy_cal_event *param) 19071 { 19072 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19073 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19074 19075 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19076 if (!param_buf) { 19077 wmi_err("Invalid set halphy_status event"); 19078 return QDF_STATUS_E_INVAL; 19079 } 19080 19081 set_halphy_status = param_buf->fixed_param; 19082 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19083 (wmi_handle, set_halphy_status->pdev_id); 19084 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19085 19086 return QDF_STATUS_SUCCESS; 19087 } 19088 19089 /** 19090 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19091 * @wmi_handle: wmi handle 19092 * @evt_buf: pointer to event buffer 19093 * @len: length of the event buffer 19094 * @param: Pointer to hold install key complete event param 19095 * 19096 * Return: QDF_STATUS_SUCCESS for success or error code 19097 */ 19098 static QDF_STATUS 19099 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19100 void *evt_buf, uint32_t len, 19101 struct wmi_install_key_comp_event *param) 19102 { 19103 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19104 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19105 19106 if (len < sizeof(*param_buf)) { 19107 wmi_err("invalid event buf len %d", len); 19108 return QDF_STATUS_E_INVAL; 19109 } 19110 19111 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19112 if (!param_buf) { 19113 wmi_err("received null buf from target"); 19114 return QDF_STATUS_E_INVAL; 19115 } 19116 19117 key_fp = param_buf->fixed_param; 19118 if (!key_fp) { 19119 wmi_err("received null event data from target"); 19120 return QDF_STATUS_E_INVAL; 19121 } 19122 19123 param->vdev_id = key_fp->vdev_id; 19124 param->key_ix = key_fp->key_ix; 19125 param->key_flags = key_fp->key_flags; 19126 param->status = key_fp->status; 19127 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 19128 param->peer_macaddr); 19129 19130 return QDF_STATUS_SUCCESS; 19131 } 19132 19133 static QDF_STATUS 19134 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 19135 struct wmi_host_send_set_halphy_cal_info *param) 19136 { 19137 wmi_buf_t buf; 19138 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 19139 QDF_STATUS ret; 19140 uint32_t len; 19141 19142 len = sizeof(*cmd); 19143 19144 buf = wmi_buf_alloc(wmi_handle, len); 19145 if (!buf) 19146 return QDF_STATUS_E_FAILURE; 19147 19148 cmd = (void *)wmi_buf_data(buf); 19149 19150 WMITLV_SET_HDR(&cmd->tlv_header, 19151 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 19152 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 19153 19154 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 19155 param->pdev_id); 19156 cmd->online_halphy_cals_bmap = param->value; 19157 cmd->home_scan_channel = param->chan_sel; 19158 19159 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19160 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 19161 if (QDF_IS_STATUS_ERROR(ret)) { 19162 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 19163 wmi_buf_free(buf); 19164 } 19165 19166 return ret; 19167 } 19168 19169 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19170 /** 19171 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 19172 * @wmi: wmi handle 19173 * @params: set MAC address command params 19174 * 19175 * Return: QDF_STATUS_SUCCESS for success or error code 19176 */ 19177 static QDF_STATUS 19178 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 19179 struct set_mac_addr_params *params) 19180 { 19181 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 19182 wmi_buf_t buf; 19183 int32_t len = sizeof(*cmd); 19184 19185 buf = wmi_buf_alloc(wmi, len); 19186 if (!buf) 19187 return QDF_STATUS_E_NOMEM; 19188 19189 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 19190 WMITLV_SET_HDR( 19191 &cmd->tlv_header, 19192 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 19193 WMITLV_GET_STRUCT_TLVLEN 19194 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 19195 cmd->vdev_id = params->vdev_id; 19196 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 19197 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 19198 19199 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 19200 QDF_MAC_ADDR_FMT, cmd->vdev_id, 19201 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 19202 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 19203 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 19204 if (wmi_unified_cmd_send(wmi, buf, len, 19205 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 19206 wmi_buf_free(buf); 19207 return QDF_STATUS_E_FAILURE; 19208 } 19209 19210 return QDF_STATUS_SUCCESS; 19211 } 19212 19213 /** 19214 * extract_update_mac_address_event_tlv() - extract update MAC address event 19215 * @wmi_handle: WMI handle 19216 * @evt_buf: event buffer 19217 * @vdev_id: VDEV ID 19218 * @status: FW status of the set MAC address operation 19219 * 19220 * Return: QDF_STATUS 19221 */ 19222 static QDF_STATUS extract_update_mac_address_event_tlv( 19223 wmi_unified_t wmi_handle, void *evt_buf, 19224 uint8_t *vdev_id, uint8_t *status) 19225 { 19226 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 19227 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 19228 19229 param_buf = 19230 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 19231 19232 event = param_buf->fixed_param; 19233 19234 *vdev_id = event->vdev_id; 19235 *status = event->status; 19236 19237 return QDF_STATUS_SUCCESS; 19238 } 19239 #endif 19240 19241 #ifdef WLAN_FEATURE_11BE_MLO 19242 /** 19243 * extract_quiet_offload_event_tlv() - extract quiet offload event 19244 * @wmi_handle: WMI handle 19245 * @evt_buf: event buffer 19246 * @mld_mac: mld mac address 19247 * @link_mac: link mac address 19248 * @link_id: link id 19249 * @quiet_status: quiet is started or stopped 19250 * 19251 * Return: QDF_STATUS 19252 */ 19253 static QDF_STATUS extract_quiet_offload_event_tlv( 19254 wmi_unified_t wmi_handle, void *evt_buf, 19255 struct vdev_sta_quiet_event *quiet_event) 19256 { 19257 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 19258 wmi_quiet_event_fixed_param *event; 19259 19260 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 19261 19262 event = param_buf->fixed_param; 19263 19264 if (!(event->mld_mac_address_present && event->linkid_present) && 19265 !event->link_mac_address_present) { 19266 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 19267 event->mld_mac_address_present, 19268 event->linkid_present, 19269 event->link_mac_address_present); 19270 return QDF_STATUS_E_INVAL; 19271 } 19272 19273 if (event->mld_mac_address_present) 19274 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 19275 quiet_event->mld_mac.bytes); 19276 if (event->link_mac_address_present) 19277 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 19278 quiet_event->link_mac.bytes); 19279 if (event->linkid_present) 19280 quiet_event->link_id = event->linkid; 19281 quiet_event->quiet_status = (event->quiet_status == 19282 WMI_QUIET_EVENT_START); 19283 19284 return QDF_STATUS_SUCCESS; 19285 } 19286 #endif 19287 19288 /** 19289 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 19290 * @wmi_handle: wmi handle 19291 * @params: RxFilter params 19292 * 19293 * Return: QDF_STATUS_SUCCESS for success or error code 19294 */ 19295 static QDF_STATUS 19296 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 19297 struct vdev_pn_mgmt_rxfilter_params *params) 19298 { 19299 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 19300 wmi_buf_t buf; 19301 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 19302 19303 if (!is_service_enabled_tlv(wmi_handle, 19304 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 19305 wmi_err("Rx PN Replay Check not supported by target"); 19306 return QDF_STATUS_E_NOSUPPORT; 19307 } 19308 19309 buf = wmi_buf_alloc(wmi_handle, len); 19310 if (!buf) { 19311 wmi_err("wmi buf alloc failed"); 19312 return QDF_STATUS_E_NOMEM; 19313 } 19314 19315 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 19316 WMITLV_SET_HDR( 19317 &cmd->tlv_header, 19318 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 19319 WMITLV_GET_STRUCT_TLVLEN 19320 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 19321 19322 cmd->vdev_id = params->vdev_id; 19323 cmd->pn_rx_filter = params->pn_rxfilter; 19324 19325 if (wmi_unified_cmd_send(wmi_handle, buf, len, 19326 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 19327 wmi_err("Failed to send WMI command"); 19328 wmi_buf_free(buf); 19329 return QDF_STATUS_E_FAILURE; 19330 } 19331 19332 return QDF_STATUS_SUCCESS; 19333 } 19334 19335 static QDF_STATUS 19336 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19337 uint8_t *pdev_id, uint8_t *software_image, 19338 uint8_t *chip_info, 19339 uint32_t *pktlog_json_version) 19340 { 19341 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 19342 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 19343 19344 param_buf = 19345 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 19346 19347 event = param_buf->fixed_param; 19348 19349 if ((event->software_image[0] == '\0') || 19350 (event->chip_info[0] == '\0')) { 19351 *pdev_id = event->pdev_id; 19352 return QDF_STATUS_E_INVAL; 19353 } 19354 19355 qdf_mem_copy(software_image, event->software_image, 40); 19356 qdf_mem_copy(chip_info, event->chip_info, 40); 19357 *pktlog_json_version = event->pktlog_defs_json_version; 19358 *pdev_id = event->pdev_id; 19359 return QDF_STATUS_SUCCESS; 19360 } 19361 19362 #ifdef HEALTH_MON_SUPPORT 19363 /** 19364 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 19365 * fw 19366 * @wmi_handle: wmi handle 19367 * @evt_buf: pointer to event buffer 19368 * @params: health monitor params 19369 * 19370 * Return: QDF_STATUS_SUCCESS for success or error code 19371 */ 19372 static QDF_STATUS 19373 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 19374 void *evt_buf, 19375 struct wmi_health_mon_params *param) 19376 { 19377 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 19378 wmi_health_mon_init_done_fixed_param *event; 19379 19380 param_buf = 19381 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 19382 19383 event = param_buf->fixed_param; 19384 19385 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 19386 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 19387 param->initial_upload_period_ms = event->initial_upload_period_ms; 19388 param->read_index = 0; 19389 19390 return QDF_STATUS_SUCCESS; 19391 } 19392 #endif /* HEALTH_MON_SUPPORT */ 19393 19394 /** 19395 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 19396 * @wmi_handle: wmi handle 19397 * @evt_buf: pointer to event buffer 19398 * @pdev stats: Pointer to hold pdev telemetry stats 19399 * 19400 * Return: QDF_STATUS_SUCCESS for success or error code 19401 */ 19402 static QDF_STATUS 19403 extract_pdev_telemetry_stats_tlv( 19404 wmi_unified_t wmi_handle, void *evt_buf, 19405 struct wmi_host_pdev_telemetry_stats *pdev_stats) 19406 { 19407 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19408 wmi_pdev_telemetry_stats *ev; 19409 19410 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 19411 19412 if (param_buf->pdev_telemetry_stats) { 19413 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 19414 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 19415 ev->avg_chan_lat_per_ac, 19416 sizeof(ev->avg_chan_lat_per_ac)); 19417 pdev_stats->estimated_air_time_per_ac = 19418 ev->estimated_air_time_per_ac; 19419 } 19420 19421 return QDF_STATUS_SUCCESS; 19422 } 19423 19424 struct wmi_ops tlv_ops = { 19425 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 19426 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 19427 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 19428 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 19429 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 19430 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 19431 .send_peer_param_cmd = send_peer_param_cmd_tlv, 19432 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 19433 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 19434 .send_peer_create_cmd = send_peer_create_cmd_tlv, 19435 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 19436 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 19437 .send_peer_rx_reorder_queue_setup_cmd = 19438 send_peer_rx_reorder_queue_setup_cmd_tlv, 19439 .send_peer_rx_reorder_queue_remove_cmd = 19440 send_peer_rx_reorder_queue_remove_cmd_tlv, 19441 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 19442 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 19443 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 19444 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 19445 .send_suspend_cmd = send_suspend_cmd_tlv, 19446 .send_resume_cmd = send_resume_cmd_tlv, 19447 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 19448 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 19449 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 19450 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 19451 .send_dbglog_cmd = send_dbglog_cmd_tlv, 19452 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 19453 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 19454 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 19455 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 19456 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 19457 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 19458 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 19459 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 19460 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 19461 .send_scan_start_cmd = send_scan_start_cmd_tlv, 19462 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 19463 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 19464 .send_mgmt_cmd = send_mgmt_cmd_tlv, 19465 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 19466 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 19467 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 19468 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 19469 .send_set_sta_uapsd_auto_trig_cmd = 19470 send_set_sta_uapsd_auto_trig_cmd_tlv, 19471 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 19472 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 19473 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 19474 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 19475 .send_lro_config_cmd = send_lro_config_cmd_tlv, 19476 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 19477 .send_probe_rsp_tmpl_send_cmd = 19478 send_probe_rsp_tmpl_send_cmd_tlv, 19479 .send_p2p_go_set_beacon_ie_cmd = 19480 send_p2p_go_set_beacon_ie_cmd_tlv, 19481 .send_setup_install_key_cmd = 19482 send_setup_install_key_cmd_tlv, 19483 .send_scan_probe_setoui_cmd = 19484 send_scan_probe_setoui_cmd_tlv, 19485 #ifdef IPA_OFFLOAD 19486 .send_ipa_offload_control_cmd = 19487 send_ipa_offload_control_cmd_tlv, 19488 #endif 19489 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 19490 .send_pno_start_cmd = send_pno_start_cmd_tlv, 19491 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 19492 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 19493 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 19494 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 19495 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 19496 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 19497 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 19498 .send_unified_ll_stats_get_sta_cmd = 19499 send_unified_ll_stats_get_sta_cmd_tlv, 19500 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 19501 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 19502 .send_congestion_cmd = send_congestion_cmd_tlv, 19503 .send_snr_request_cmd = send_snr_request_cmd_tlv, 19504 .send_snr_cmd = send_snr_cmd_tlv, 19505 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 19506 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 19507 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 19508 #endif 19509 #ifdef WLAN_SUPPORT_GREEN_AP 19510 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 19511 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 19512 .extract_green_ap_egap_status_info = 19513 extract_green_ap_egap_status_info_tlv, 19514 #endif 19515 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 19516 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 19517 #ifdef FEATURE_OEM_DATA 19518 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 19519 #endif 19520 #ifdef WLAN_FEATURE_CIF_CFR 19521 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 19522 #endif 19523 .send_dfs_phyerr_filter_offload_en_cmd = 19524 send_dfs_phyerr_filter_offload_en_cmd_tlv, 19525 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 19526 .send_process_dhcpserver_offload_cmd = 19527 send_process_dhcpserver_offload_cmd_tlv, 19528 .send_pdev_set_regdomain_cmd = 19529 send_pdev_set_regdomain_cmd_tlv, 19530 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 19531 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 19532 .save_fw_version_cmd = save_fw_version_cmd_tlv, 19533 .check_and_update_fw_version = 19534 check_and_update_fw_version_cmd_tlv, 19535 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 19536 .send_enable_specific_fw_logs_cmd = 19537 send_enable_specific_fw_logs_cmd_tlv, 19538 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 19539 .send_unit_test_cmd = send_unit_test_cmd_tlv, 19540 #ifdef FEATURE_WLAN_APF 19541 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 19542 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 19543 .send_apf_write_work_memory_cmd = 19544 wmi_send_apf_write_work_memory_cmd_tlv, 19545 .send_apf_read_work_memory_cmd = 19546 wmi_send_apf_read_work_memory_cmd_tlv, 19547 .extract_apf_read_memory_resp_event = 19548 wmi_extract_apf_read_memory_resp_event_tlv, 19549 #endif /* FEATURE_WLAN_APF */ 19550 .init_cmd_send = init_cmd_send_tlv, 19551 .send_vdev_set_custom_aggr_size_cmd = 19552 send_vdev_set_custom_aggr_size_cmd_tlv, 19553 .send_vdev_set_qdepth_thresh_cmd = 19554 send_vdev_set_qdepth_thresh_cmd_tlv, 19555 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 19556 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 19557 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 19558 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 19559 .send_periodic_chan_stats_config_cmd = 19560 send_periodic_chan_stats_config_cmd_tlv, 19561 #ifdef WLAN_IOT_SIM_SUPPORT 19562 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 19563 #endif 19564 .send_vdev_spectral_configure_cmd = 19565 send_vdev_spectral_configure_cmd_tlv, 19566 .send_vdev_spectral_enable_cmd = 19567 send_vdev_spectral_enable_cmd_tlv, 19568 #ifdef WLAN_CONV_SPECTRAL_ENABLE 19569 .extract_pdev_sscan_fw_cmd_fixed_param = 19570 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 19571 .extract_pdev_sscan_fft_bin_index = 19572 extract_pdev_sscan_fft_bin_index_tlv, 19573 .extract_pdev_spectral_session_chan_info = 19574 extract_pdev_spectral_session_chan_info_tlv, 19575 .extract_pdev_spectral_session_detector_info = 19576 extract_pdev_spectral_session_detector_info_tlv, 19577 .extract_spectral_caps_fixed_param = 19578 extract_spectral_caps_fixed_param_tlv, 19579 .extract_spectral_scan_bw_caps = 19580 extract_spectral_scan_bw_caps_tlv, 19581 .extract_spectral_fft_size_caps = 19582 extract_spectral_fft_size_caps_tlv, 19583 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 19584 .send_thermal_mitigation_param_cmd = 19585 send_thermal_mitigation_param_cmd_tlv, 19586 .send_process_update_edca_param_cmd = 19587 send_process_update_edca_param_cmd_tlv, 19588 .send_bss_color_change_enable_cmd = 19589 send_bss_color_change_enable_cmd_tlv, 19590 .send_coex_config_cmd = send_coex_config_cmd_tlv, 19591 .send_set_country_cmd = send_set_country_cmd_tlv, 19592 .send_addba_send_cmd = send_addba_send_cmd_tlv, 19593 .send_delba_send_cmd = send_delba_send_cmd_tlv, 19594 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 19595 .get_target_cap_from_service_ready = extract_service_ready_tlv, 19596 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 19597 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 19598 .extract_host_mem_req = extract_host_mem_req_tlv, 19599 .save_service_bitmap = save_service_bitmap_tlv, 19600 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 19601 .is_service_enabled = is_service_enabled_tlv, 19602 .save_fw_version = save_fw_version_in_service_ready_tlv, 19603 .ready_extract_init_status = ready_extract_init_status_tlv, 19604 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 19605 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 19606 .extract_ready_event_params = extract_ready_event_params_tlv, 19607 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 19608 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 19609 .extract_frame_pn_params = extract_frame_pn_params_tlv, 19610 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 19611 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 19612 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 19613 #ifdef FEATURE_WLAN_SCAN_PNO 19614 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 19615 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 19616 #endif 19617 .extract_unit_test = extract_unit_test_tlv, 19618 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 19619 .extract_bcn_stats = extract_bcn_stats_tlv, 19620 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 19621 .extract_chan_stats = extract_chan_stats_tlv, 19622 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 19623 .extract_profile_ctx = extract_profile_ctx_tlv, 19624 .extract_profile_data = extract_profile_data_tlv, 19625 .send_fw_test_cmd = send_fw_test_cmd_tlv, 19626 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 19627 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 19628 .extract_service_ready_ext = extract_service_ready_ext_tlv, 19629 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 19630 .extract_dbs_or_sbs_service_ready_ext2 = 19631 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 19632 .extract_hw_mode_cap_service_ready_ext = 19633 extract_hw_mode_cap_service_ready_ext_tlv, 19634 .extract_mac_phy_cap_service_ready_ext = 19635 extract_mac_phy_cap_service_ready_ext_tlv, 19636 .extract_mac_phy_cap_service_ready_ext2 = 19637 extract_mac_phy_cap_service_ready_ext2_tlv, 19638 .extract_reg_cap_service_ready_ext = 19639 extract_reg_cap_service_ready_ext_tlv, 19640 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 19641 .extract_dbr_ring_cap_service_ready_ext = 19642 extract_dbr_ring_cap_service_ready_ext_tlv, 19643 .extract_dbr_ring_cap_service_ready_ext2 = 19644 extract_dbr_ring_cap_service_ready_ext2_tlv, 19645 .extract_scan_radio_cap_service_ready_ext2 = 19646 extract_scan_radio_cap_service_ready_ext2_tlv, 19647 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 19648 .extract_sar_cap_service_ready_ext = 19649 extract_sar_cap_service_ready_ext_tlv, 19650 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 19651 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 19652 .extract_fips_event_data = extract_fips_event_data_tlv, 19653 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19654 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 19655 #endif 19656 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 19657 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 19658 #endif 19659 #ifdef WLAN_FEATURE_DISA 19660 .extract_encrypt_decrypt_resp_event = 19661 extract_encrypt_decrypt_resp_event_tlv, 19662 #endif 19663 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 19664 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19665 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 19666 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 19667 #endif 19668 .extract_get_pn_data = extract_get_pn_data_tlv, 19669 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 19670 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 19671 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 19672 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 19673 #ifdef WLAN_FEATURE_DISA 19674 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 19675 #endif 19676 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 19677 .send_wlan_profile_hist_intvl_cmd = 19678 send_wlan_profile_hist_intvl_cmd_tlv, 19679 .is_management_record = is_management_record_tlv, 19680 .is_diag_event = is_diag_event_tlv, 19681 #ifdef WLAN_FEATURE_ACTION_OUI 19682 .send_action_oui_cmd = send_action_oui_cmd_tlv, 19683 #endif 19684 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 19685 #ifdef QCA_SUPPORT_AGILE_DFS 19686 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 19687 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 19688 #endif 19689 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 19690 .extract_reg_chan_list_update_event = 19691 extract_reg_chan_list_update_event_tlv, 19692 #ifdef CONFIG_BAND_6GHZ 19693 .extract_reg_chan_list_ext_update_event = 19694 extract_reg_chan_list_ext_update_event_tlv, 19695 #ifdef CONFIG_AFC_SUPPORT 19696 .extract_afc_event = extract_afc_event_tlv, 19697 #endif 19698 #endif 19699 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 19700 .extract_num_rf_characterization_entries = 19701 extract_num_rf_characterization_entries_tlv, 19702 .extract_rf_characterization_entries = 19703 extract_rf_characterization_entries_tlv, 19704 #endif 19705 .extract_chainmask_tables = 19706 extract_chainmask_tables_tlv, 19707 .extract_thermal_stats = extract_thermal_stats_tlv, 19708 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 19709 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 19710 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 19711 #ifdef DFS_COMPONENT_ENABLE 19712 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 19713 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 19714 .extract_dfs_radar_detection_event = 19715 extract_dfs_radar_detection_event_tlv, 19716 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 19717 #endif 19718 .convert_pdev_id_host_to_target = 19719 convert_host_pdev_id_to_target_pdev_id_legacy, 19720 .convert_pdev_id_target_to_host = 19721 convert_target_pdev_id_to_host_pdev_id_legacy, 19722 19723 .convert_host_pdev_id_to_target = 19724 convert_host_pdev_id_to_target_pdev_id, 19725 .convert_target_pdev_id_to_host = 19726 convert_target_pdev_id_to_host_pdev_id, 19727 19728 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 19729 19730 .convert_phy_id_host_to_target = 19731 convert_host_phy_id_to_target_phy_id_legacy, 19732 .convert_phy_id_target_to_host = 19733 convert_target_phy_id_to_host_phy_id_legacy, 19734 19735 .convert_host_phy_id_to_target = 19736 convert_host_phy_id_to_target_phy_id, 19737 .convert_target_phy_id_to_host = 19738 convert_target_phy_id_to_host_phy_id, 19739 19740 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 19741 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 19742 .extract_reg_11d_new_country_event = 19743 extract_reg_11d_new_country_event_tlv, 19744 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 19745 .extract_reg_ch_avoid_event = 19746 extract_reg_ch_avoid_event_tlv, 19747 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 19748 .extract_obss_detection_info = extract_obss_detection_info_tlv, 19749 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 19750 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 19751 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 19752 .wmi_check_command_params = wmitlv_check_command_tlv_params, 19753 .extract_comb_phyerr = extract_comb_phyerr_tlv, 19754 .extract_single_phyerr = extract_single_phyerr_tlv, 19755 #ifdef QCA_SUPPORT_CP_STATS 19756 .extract_cca_stats = extract_cca_stats_tlv, 19757 #endif 19758 .extract_esp_estimation_ev_param = 19759 extract_esp_estimation_ev_param_tlv, 19760 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 19761 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 19762 #ifdef OBSS_PD 19763 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 19764 .send_obss_spatial_reuse_set_def_thresh = 19765 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 19766 .send_self_srg_bss_color_bitmap_set = 19767 send_self_srg_bss_color_bitmap_set_cmd_tlv, 19768 .send_self_srg_partial_bssid_bitmap_set = 19769 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 19770 .send_self_srg_obss_color_enable_bitmap = 19771 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 19772 .send_self_srg_obss_bssid_enable_bitmap = 19773 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 19774 .send_self_non_srg_obss_color_enable_bitmap = 19775 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 19776 .send_self_non_srg_obss_bssid_enable_bitmap = 19777 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 19778 #endif 19779 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 19780 .extract_ctl_failsafe_check_ev_param = 19781 extract_ctl_failsafe_check_ev_param_tlv, 19782 #ifdef WIFI_POS_CONVERGED 19783 .extract_oem_response_param = extract_oem_response_param_tlv, 19784 #endif /* WIFI_POS_CONVERGED */ 19785 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19786 .extract_pasn_peer_create_req_event = 19787 extract_pasn_peer_create_req_event_tlv, 19788 .extract_pasn_peer_delete_req_event = 19789 extract_pasn_peer_delete_req_event_tlv, 19790 .send_rtt_pasn_auth_status_cmd = 19791 send_rtt_pasn_auth_status_cmd_tlv, 19792 .send_rtt_pasn_deauth_cmd = 19793 send_rtt_pasn_deauth_cmd_tlv, 19794 #endif 19795 #ifdef WLAN_MWS_INFO_DEBUGFS 19796 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 19797 #endif 19798 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 19799 #ifdef FEATURE_ANI_LEVEL_REQUEST 19800 .send_ani_level_cmd = send_ani_level_cmd_tlv, 19801 .extract_ani_level = extract_ani_level_tlv, 19802 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19803 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 19804 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 19805 .extract_roam_result_stats = extract_roam_result_stats_tlv, 19806 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 19807 #ifdef WLAN_FEATURE_PKT_CAPTURE 19808 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 19809 #endif 19810 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19811 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 19812 #endif 19813 19814 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19815 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 19816 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 19817 .extract_time_sync_ftm_start_stop_event = 19818 extract_time_sync_ftm_start_stop_event_tlv, 19819 .extract_time_sync_ftm_offset_event = 19820 extract_time_sync_ftm_offset_event_tlv, 19821 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 19822 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 19823 .send_injector_config_cmd = send_injector_config_cmd_tlv, 19824 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 19825 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 19826 #ifdef FEATURE_MEC_OFFLOAD 19827 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 19828 #endif 19829 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 19830 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 19831 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 19832 .extract_cp_stats_more_pending = 19833 extract_cp_stats_more_pending_tlv, 19834 .extract_halphy_stats_end_of_event = 19835 extract_halphy_stats_end_of_event_tlv, 19836 .extract_halphy_stats_event_count = 19837 extract_halphy_stats_event_count_tlv, 19838 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 19839 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 19840 .extract_pdev_csa_switch_count_status = 19841 extract_pdev_csa_switch_count_status_tlv, 19842 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 19843 #ifdef CONFIG_AFC_SUPPORT 19844 .send_afc_cmd = send_afc_cmd_tlv, 19845 #endif 19846 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 19847 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 19848 .send_vdev_set_ltf_key_seed_cmd = 19849 send_vdev_set_ltf_key_seed_cmd_tlv, 19850 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 19851 .send_set_halphy_cal = send_set_halphy_cal_tlv, 19852 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 19853 #ifdef WLAN_MGMT_RX_REO_SUPPORT 19854 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 19855 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 19856 .send_mgmt_rx_reo_filter_config_cmd = 19857 send_mgmt_rx_reo_filter_config_cmd_tlv, 19858 #endif 19859 19860 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19861 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 19862 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 19863 19864 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19865 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 19866 .extract_update_mac_address_event = 19867 extract_update_mac_address_event_tlv, 19868 #endif 19869 19870 #ifdef WLAN_FEATURE_11BE_MLO 19871 .extract_quiet_offload_event = 19872 extract_quiet_offload_event_tlv, 19873 #endif 19874 19875 #ifdef WLAN_SUPPORT_PPEDS 19876 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 19877 #endif /* WLAN_SUPPORT_PPEDS */ 19878 19879 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 19880 .extract_pktlog_decode_info_event = 19881 extract_pktlog_decode_info_event_tlv, 19882 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 19883 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 19884 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 19885 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 19886 #endif 19887 #ifdef WLAN_FEATURE_DBAM_CONFIG 19888 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 19889 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 19890 #endif 19891 #ifdef FEATURE_SET 19892 .feature_set_cmd_send = feature_set_cmd_send_tlv, 19893 #endif 19894 #ifdef HEALTH_MON_SUPPORT 19895 .extract_health_mon_init_done_info_event = 19896 extract_health_mon_init_done_info_event_tlv, 19897 #endif /* HEALTH_MON_SUPPORT */ 19898 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 19899 }; 19900 19901 #ifdef WLAN_FEATURE_11BE_MLO 19902 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 19903 { 19904 event_ids[wmi_mlo_setup_complete_event_id] = 19905 WMI_MLO_SETUP_COMPLETE_EVENTID; 19906 event_ids[wmi_mlo_teardown_complete_event_id] = 19907 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 19908 event_ids[wmi_mlo_link_set_active_resp_eventid] = 19909 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 19910 event_ids[wmi_vdev_quiet_offload_eventid] = 19911 WMI_QUIET_HANDLING_EVENTID; 19912 } 19913 #else /* WLAN_FEATURE_11BE_MLO */ 19914 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 19915 { 19916 } 19917 #endif /* WLAN_FEATURE_11BE_MLO */ 19918 19919 /** 19920 * populate_tlv_event_id() - populates wmi event ids 19921 * 19922 * @param event_ids: Pointer to hold event ids 19923 * Return: None 19924 */ 19925 static void populate_tlv_events_id(uint32_t *event_ids) 19926 { 19927 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 19928 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 19929 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 19930 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 19931 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 19932 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 19933 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 19934 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 19935 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 19936 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 19937 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 19938 event_ids[wmi_service_ready_ext_event_id] = 19939 WMI_SERVICE_READY_EXT_EVENTID; 19940 event_ids[wmi_service_ready_ext2_event_id] = 19941 WMI_SERVICE_READY_EXT2_EVENTID; 19942 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 19943 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 19944 event_ids[wmi_vdev_install_key_complete_event_id] = 19945 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 19946 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 19947 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 19948 19949 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 19950 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 19951 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 19952 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 19953 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 19954 event_ids[wmi_peer_estimated_linkspeed_event_id] = 19955 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 19956 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 19957 event_ids[wmi_peer_create_conf_event_id] = 19958 WMI_PEER_CREATE_CONF_EVENTID; 19959 event_ids[wmi_peer_delete_response_event_id] = 19960 WMI_PEER_DELETE_RESP_EVENTID; 19961 event_ids[wmi_peer_delete_all_response_event_id] = 19962 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 19963 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 19964 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 19965 event_ids[wmi_tbttoffset_update_event_id] = 19966 WMI_TBTTOFFSET_UPDATE_EVENTID; 19967 event_ids[wmi_ext_tbttoffset_update_event_id] = 19968 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 19969 event_ids[wmi_offload_bcn_tx_status_event_id] = 19970 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 19971 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 19972 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 19973 event_ids[wmi_mgmt_tx_completion_event_id] = 19974 WMI_MGMT_TX_COMPLETION_EVENTID; 19975 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 19976 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 19977 event_ids[wmi_tx_delba_complete_event_id] = 19978 WMI_TX_DELBA_COMPLETE_EVENTID; 19979 event_ids[wmi_tx_addba_complete_event_id] = 19980 WMI_TX_ADDBA_COMPLETE_EVENTID; 19981 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 19982 19983 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 19984 19985 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 19986 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 19987 19988 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 19989 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 19990 19991 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 19992 19993 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 19994 event_ids[wmi_p2p_lo_stop_event_id] = 19995 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 19996 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 19997 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 19998 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 19999 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20000 event_ids[wmi_d0_wow_disable_ack_event_id] = 20001 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20002 event_ids[wmi_wow_initial_wakeup_event_id] = 20003 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20004 20005 event_ids[wmi_rtt_meas_report_event_id] = 20006 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20007 event_ids[wmi_tsf_meas_report_event_id] = 20008 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20009 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20010 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20011 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20012 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20013 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20014 event_ids[wmi_diag_event_id_log_supported_event_id] = 20015 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20016 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20017 event_ids[wmi_nlo_scan_complete_event_id] = 20018 WMI_NLO_SCAN_COMPLETE_EVENTID; 20019 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20020 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20021 20022 event_ids[wmi_gtk_offload_status_event_id] = 20023 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20024 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20025 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20026 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20027 20028 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20029 20030 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 20031 20032 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 20033 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 20034 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 20035 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 20036 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 20037 event_ids[wmi_wlan_profile_data_event_id] = 20038 WMI_WLAN_PROFILE_DATA_EVENTID; 20039 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 20040 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 20041 event_ids[wmi_vdev_get_keepalive_event_id] = 20042 WMI_VDEV_GET_KEEPALIVE_EVENTID; 20043 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 20044 20045 event_ids[wmi_diag_container_event_id] = 20046 WMI_DIAG_DATA_CONTAINER_EVENTID; 20047 20048 event_ids[wmi_host_auto_shutdown_event_id] = 20049 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 20050 20051 event_ids[wmi_update_whal_mib_stats_event_id] = 20052 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 20053 20054 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 20055 event_ids[wmi_update_vdev_rate_stats_event_id] = 20056 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 20057 20058 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 20059 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 20060 20061 /** Set OCB Sched Response, deprecated */ 20062 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 20063 20064 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 20065 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 20066 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 20067 20068 /* GPIO Event */ 20069 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 20070 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 20071 20072 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 20073 event_ids[wmi_rfkill_state_change_event_id] = 20074 WMI_RFKILL_STATE_CHANGE_EVENTID; 20075 20076 /* TDLS Event */ 20077 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 20078 20079 event_ids[wmi_batch_scan_enabled_event_id] = 20080 WMI_BATCH_SCAN_ENABLED_EVENTID; 20081 event_ids[wmi_batch_scan_result_event_id] = 20082 WMI_BATCH_SCAN_RESULT_EVENTID; 20083 /* OEM Event */ 20084 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 20085 event_ids[wmi_oem_meas_report_event_id] = 20086 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 20087 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 20088 20089 /* NAN Event */ 20090 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 20091 20092 /* LPI Event */ 20093 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 20094 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 20095 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 20096 20097 /* ExtScan events */ 20098 event_ids[wmi_extscan_start_stop_event_id] = 20099 WMI_EXTSCAN_START_STOP_EVENTID; 20100 event_ids[wmi_extscan_operation_event_id] = 20101 WMI_EXTSCAN_OPERATION_EVENTID; 20102 event_ids[wmi_extscan_table_usage_event_id] = 20103 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 20104 event_ids[wmi_extscan_cached_results_event_id] = 20105 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 20106 event_ids[wmi_extscan_wlan_change_results_event_id] = 20107 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 20108 event_ids[wmi_extscan_hotlist_match_event_id] = 20109 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 20110 event_ids[wmi_extscan_capabilities_event_id] = 20111 WMI_EXTSCAN_CAPABILITIES_EVENTID; 20112 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 20113 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 20114 20115 /* mDNS offload events */ 20116 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 20117 20118 /* SAP Authentication offload events */ 20119 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 20120 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 20121 20122 /** Out-of-context-of-bss (OCB) events */ 20123 event_ids[wmi_ocb_set_config_resp_event_id] = 20124 WMI_OCB_SET_CONFIG_RESP_EVENTID; 20125 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 20126 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 20127 event_ids[wmi_dcc_get_stats_resp_event_id] = 20128 WMI_DCC_GET_STATS_RESP_EVENTID; 20129 event_ids[wmi_dcc_update_ndl_resp_event_id] = 20130 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 20131 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 20132 /* System-On-Chip events */ 20133 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 20134 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 20135 event_ids[wmi_soc_hw_mode_transition_event_id] = 20136 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 20137 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 20138 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 20139 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 20140 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20141 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 20142 #endif 20143 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 20144 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 20145 event_ids[wmi_vdev_ocac_complete_event_id] = 20146 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 20147 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 20148 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 20149 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 20150 #ifdef CONFIG_AFC_SUPPORT 20151 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 20152 #endif 20153 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 20154 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20155 event_ids[wmi_peer_sta_ps_statechg_event_id] = 20156 WMI_PEER_STA_PS_STATECHG_EVENTID; 20157 event_ids[wmi_pdev_channel_hopping_event_id] = 20158 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 20159 event_ids[wmi_offchan_data_tx_completion_event] = 20160 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 20161 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 20162 event_ids[wmi_dfs_radar_detection_event_id] = 20163 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 20164 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 20165 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 20166 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 20167 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 20168 event_ids[wmi_service_available_event_id] = 20169 WMI_SERVICE_AVAILABLE_EVENTID; 20170 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 20171 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 20172 /* NDP events */ 20173 event_ids[wmi_ndp_initiator_rsp_event_id] = 20174 WMI_NDP_INITIATOR_RSP_EVENTID; 20175 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 20176 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 20177 event_ids[wmi_ndp_responder_rsp_event_id] = 20178 WMI_NDP_RESPONDER_RSP_EVENTID; 20179 event_ids[wmi_ndp_end_indication_event_id] = 20180 WMI_NDP_END_INDICATION_EVENTID; 20181 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 20182 event_ids[wmi_ndl_schedule_update_event_id] = 20183 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 20184 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 20185 20186 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 20187 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 20188 event_ids[wmi_pdev_chip_power_stats_event_id] = 20189 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 20190 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 20191 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 20192 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 20193 event_ids[wmi_apf_capability_info_event_id] = 20194 WMI_BPF_CAPABILIY_INFO_EVENTID; 20195 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 20196 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 20197 event_ids[wmi_report_rx_aggr_failure_event_id] = 20198 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 20199 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 20200 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 20201 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 20202 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 20203 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 20204 event_ids[wmi_pdev_hw_mode_transition_event_id] = 20205 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 20206 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 20207 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 20208 event_ids[wmi_coex_bt_activity_event_id] = 20209 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 20210 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 20211 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 20212 event_ids[wmi_radio_tx_power_level_stats_event_id] = 20213 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 20214 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 20215 event_ids[wmi_dma_buf_release_event_id] = 20216 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 20217 event_ids[wmi_sap_obss_detection_report_event_id] = 20218 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 20219 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 20220 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 20221 event_ids[wmi_obss_color_collision_report_event_id] = 20222 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 20223 event_ids[wmi_pdev_div_rssi_antid_event_id] = 20224 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 20225 #ifdef WLAN_SUPPORT_TWT 20226 event_ids[wmi_twt_enable_complete_event_id] = 20227 WMI_TWT_ENABLE_COMPLETE_EVENTID; 20228 event_ids[wmi_twt_disable_complete_event_id] = 20229 WMI_TWT_DISABLE_COMPLETE_EVENTID; 20230 event_ids[wmi_twt_add_dialog_complete_event_id] = 20231 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 20232 event_ids[wmi_twt_del_dialog_complete_event_id] = 20233 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 20234 event_ids[wmi_twt_pause_dialog_complete_event_id] = 20235 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 20236 event_ids[wmi_twt_resume_dialog_complete_event_id] = 20237 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 20238 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 20239 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 20240 event_ids[wmi_twt_session_stats_event_id] = 20241 WMI_TWT_SESSION_STATS_EVENTID; 20242 event_ids[wmi_twt_notify_event_id] = 20243 WMI_TWT_NOTIFY_EVENTID; 20244 event_ids[wmi_twt_ack_complete_event_id] = 20245 WMI_TWT_ACK_EVENTID; 20246 #endif 20247 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 20248 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 20249 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 20250 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 20251 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 20252 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 20253 event_ids[wmi_pdev_interop_issues_ap_event_id] = 20254 WMI_PDEV_RAP_INFO_EVENTID; 20255 #endif 20256 #ifdef AST_HKV1_WORKAROUND 20257 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 20258 #endif 20259 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 20260 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 20261 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 20262 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 20263 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 20264 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 20265 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 20266 event_ids[wmi_pdev_cold_boot_cal_event_id] = 20267 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 20268 #ifdef WLAN_MWS_INFO_DEBUGFS 20269 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 20270 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 20271 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 20272 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 20273 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 20274 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 20275 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 20276 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 20277 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 20278 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 20279 #endif 20280 event_ids[wmi_coex_report_antenna_isolation_event_id] = 20281 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 20282 event_ids[wmi_peer_ratecode_list_event_id] = 20283 WMI_PEER_RATECODE_LIST_EVENTID; 20284 event_ids[wmi_chan_rf_characterization_info_event_id] = 20285 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 20286 event_ids[wmi_roam_auth_offload_event_id] = 20287 WMI_ROAM_PREAUTH_START_EVENTID; 20288 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 20289 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 20290 event_ids[wmi_motion_det_base_line_host_eventid] = 20291 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 20292 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 20293 event_ids[wmi_peer_tx_pn_response_event_id] = 20294 WMI_PEER_TX_PN_RESPONSE_EVENTID; 20295 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 20296 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 20297 event_ids[wmi_mgmt_offload_data_event_id] = 20298 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 20299 event_ids[wmi_nan_dmesg_event_id] = 20300 WMI_NAN_DMESG_EVENTID; 20301 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 20302 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 20303 event_ids[wmi_roam_pmkid_request_event_id] = 20304 WMI_ROAM_PMKID_REQUEST_EVENTID; 20305 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20306 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 20307 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 20308 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 20309 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 20310 #endif 20311 event_ids[wmi_roam_scan_chan_list_id] = 20312 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 20313 event_ids[wmi_muedca_params_config_eventid] = 20314 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 20315 event_ids[wmi_pdev_sscan_fw_param_eventid] = 20316 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 20317 event_ids[wmi_roam_cap_report_event_id] = 20318 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 20319 event_ids[wmi_vdev_bcn_latency_event_id] = 20320 WMI_VDEV_BCN_LATENCY_EVENTID; 20321 event_ids[wmi_vdev_disconnect_event_id] = 20322 WMI_VDEV_DISCONNECT_EVENTID; 20323 event_ids[wmi_peer_create_conf_event_id] = 20324 WMI_PEER_CREATE_CONF_EVENTID; 20325 event_ids[wmi_pdev_cp_fwstats_eventid] = 20326 WMI_CTRL_PATH_STATS_EVENTID; 20327 event_ids[wmi_pdev_halphy_fwstats_eventid] = 20328 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 20329 event_ids[wmi_vdev_send_big_data_p2_eventid] = 20330 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 20331 event_ids[wmi_pdev_get_dpd_status_event_id] = 20332 WMI_PDEV_GET_DPD_STATUS_EVENTID; 20333 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20334 event_ids[wmi_vdev_smart_monitor_event_id] = 20335 WMI_VDEV_SMART_MONITOR_EVENTID; 20336 #endif 20337 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 20338 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 20339 event_ids[wmi_pdev_set_halphy_cal_event_id] = 20340 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 20341 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 20342 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 20343 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20344 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 20345 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 20346 #endif 20347 populate_tlv_events_id_mlo(event_ids); 20348 event_ids[wmi_roam_frame_event_id] = 20349 WMI_ROAM_FRAME_EVENTID; 20350 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20351 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 20352 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 20353 #endif 20354 #ifdef WLAN_FEATURE_MCC_QUOTA 20355 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 20356 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 20357 #endif 20358 event_ids[wmi_peer_rx_pn_response_event_id] = 20359 WMI_PEER_RX_PN_RESPONSE_EVENTID; 20360 event_ids[wmi_extract_pktlog_decode_info_eventid] = 20361 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 20362 #ifdef QCA_RSSI_DB2DBM 20363 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 20364 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 20365 #endif 20366 #ifdef MULTI_CLIENT_LL_SUPPORT 20367 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 20368 #endif 20369 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20370 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 20371 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 20372 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 20373 WMI_RTT_PASN_PEER_DELETE_EVENTID; 20374 #endif 20375 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20376 event_ids[wmi_get_roam_vendor_control_param_event_id] = 20377 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 20378 #endif 20379 #ifdef WLAN_FEATURE_DBAM_CONFIG 20380 event_ids[wmi_coex_dbam_complete_event_id] = 20381 WMI_COEX_DBAM_COMPLETE_EVENTID; 20382 #endif 20383 event_ids[wmi_spectral_capabilities_eventid] = 20384 WMI_SPECTRAL_CAPABILITIES_EVENTID; 20385 #ifdef WLAN_FEATURE_COAP 20386 event_ids[wmi_wow_coap_buf_info_eventid] = 20387 WMI_WOW_COAP_BUF_INFO_EVENTID; 20388 #endif 20389 #ifdef HEALTH_MON_SUPPORT 20390 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 20391 WMI_HEALTH_MON_INIT_DONE_EVENTID; 20392 #endif /* HEALTH_MON_SUPPORT */ 20393 } 20394 20395 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20396 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20397 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20398 { 20399 wmi_service[wmi_service_get_station_in_ll_stats_req] = 20400 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 20401 } 20402 #else 20403 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20404 { 20405 } 20406 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20407 #else 20408 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20409 { 20410 } 20411 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 20412 20413 #ifdef WLAN_FEATURE_11BE_MLO 20414 static void populate_tlv_service_mlo(uint32_t *wmi_service) 20415 { 20416 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 20417 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 20418 } 20419 #else /* WLAN_FEATURE_11BE_MLO */ 20420 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 20421 { 20422 } 20423 #endif /* WLAN_FEATURE_11BE_MLO */ 20424 20425 /** 20426 * populate_tlv_service() - populates wmi services 20427 * 20428 * @param wmi_service: Pointer to hold wmi_service 20429 * Return: None 20430 */ 20431 static void populate_tlv_service(uint32_t *wmi_service) 20432 { 20433 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 20434 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 20435 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 20436 wmi_service[wmi_service_roam_scan_offload] = 20437 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 20438 wmi_service[wmi_service_bcn_miss_offload] = 20439 WMI_SERVICE_BCN_MISS_OFFLOAD; 20440 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 20441 wmi_service[wmi_service_sta_advanced_pwrsave] = 20442 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 20443 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 20444 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 20445 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 20446 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 20447 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 20448 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 20449 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 20450 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 20451 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 20452 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 20453 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 20454 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 20455 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 20456 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 20457 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 20458 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 20459 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 20460 wmi_service[wmi_service_packet_power_save] = 20461 WMI_SERVICE_PACKET_POWER_SAVE; 20462 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 20463 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 20464 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 20465 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 20466 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 20467 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 20468 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 20469 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 20470 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 20471 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 20472 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 20473 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 20474 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 20475 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 20476 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 20477 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 20478 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 20479 wmi_service[wmi_service_mcc_bcn_interval_change] = 20480 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 20481 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 20482 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 20483 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 20484 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 20485 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 20486 wmi_service[wmi_service_lte_ant_share_support] = 20487 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 20488 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 20489 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 20490 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 20491 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 20492 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 20493 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 20494 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 20495 wmi_service[wmi_service_bcn_txrate_override] = 20496 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 20497 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 20498 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 20499 wmi_service[wmi_service_estimate_linkspeed] = 20500 WMI_SERVICE_ESTIMATE_LINKSPEED; 20501 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 20502 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 20503 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 20504 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 20505 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 20506 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 20507 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 20508 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 20509 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 20510 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 20511 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 20512 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 20513 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 20514 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 20515 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 20516 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 20517 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 20518 wmi_service[wmi_service_sap_auth_offload] = 20519 WMI_SERVICE_SAP_AUTH_OFFLOAD; 20520 wmi_service[wmi_service_dual_band_simultaneous_support] = 20521 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 20522 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 20523 wmi_service[wmi_service_ap_arpns_offload] = 20524 WMI_SERVICE_AP_ARPNS_OFFLOAD; 20525 wmi_service[wmi_service_per_band_chainmask_support] = 20526 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 20527 wmi_service[wmi_service_packet_filter_offload] = 20528 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 20529 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 20530 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 20531 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 20532 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 20533 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 20534 wmi_service[wmi_service_multiple_vdev_restart] = 20535 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 20536 wmi_service[wmi_service_smart_antenna_sw_support] = 20537 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 20538 wmi_service[wmi_service_smart_antenna_hw_support] = 20539 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 20540 20541 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 20542 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 20543 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 20544 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 20545 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 20546 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 20547 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 20548 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 20549 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 20550 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 20551 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 20552 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 20553 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 20554 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 20555 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 20556 wmi_service[wmi_service_periodic_chan_stat_support] = 20557 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 20558 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 20559 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 20560 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 20561 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 20562 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 20563 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20564 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 20565 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 20566 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 20567 wmi_service[wmi_service_unified_wow_capability] = 20568 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 20569 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20570 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 20571 wmi_service[wmi_service_sync_delete_cmds] = 20572 WMI_SERVICE_SYNC_DELETE_CMDS; 20573 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 20574 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 20575 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 20576 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 20577 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 20578 wmi_service[wmi_service_deprecated_replace] = 20579 WMI_SERVICE_DEPRECATED_REPLACE; 20580 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 20581 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 20582 wmi_service[wmi_service_enhanced_mcast_filter] = 20583 WMI_SERVICE_ENHANCED_MCAST_FILTER; 20584 wmi_service[wmi_service_half_rate_quarter_rate_support] = 20585 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 20586 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 20587 wmi_service[wmi_service_p2p_listen_offload_support] = 20588 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 20589 wmi_service[wmi_service_mark_first_wakeup_packet] = 20590 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 20591 wmi_service[wmi_service_multiple_mcast_filter_set] = 20592 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 20593 wmi_service[wmi_service_host_managed_rx_reorder] = 20594 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 20595 wmi_service[wmi_service_flash_rdwr_support] = 20596 WMI_SERVICE_FLASH_RDWR_SUPPORT; 20597 wmi_service[wmi_service_wlan_stats_report] = 20598 WMI_SERVICE_WLAN_STATS_REPORT; 20599 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 20600 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 20601 wmi_service[wmi_service_dfs_phyerr_offload] = 20602 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 20603 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 20604 wmi_service[wmi_service_fw_mem_dump_support] = 20605 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 20606 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 20607 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 20608 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 20609 wmi_service[wmi_service_hw_data_filtering] = 20610 WMI_SERVICE_HW_DATA_FILTERING; 20611 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 20612 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 20613 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 20614 wmi_service[wmi_service_extended_nss_support] = 20615 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 20616 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 20617 wmi_service[wmi_service_bcn_offload_start_stop_support] = 20618 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 20619 wmi_service[wmi_service_offchan_data_tid_support] = 20620 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 20621 wmi_service[wmi_service_support_dma] = 20622 WMI_SERVICE_SUPPORT_DIRECT_DMA; 20623 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 20624 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 20625 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 20626 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 20627 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 20628 wmi_service[wmi_service_11k_neighbour_report_support] = 20629 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 20630 wmi_service[wmi_service_ap_obss_detection_offload] = 20631 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 20632 wmi_service[wmi_service_bss_color_offload] = 20633 WMI_SERVICE_BSS_COLOR_OFFLOAD; 20634 wmi_service[wmi_service_gmac_offload_support] = 20635 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 20636 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 20637 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 20638 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 20639 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 20640 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 20641 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 20642 wmi_service[wmi_service_listen_interval_offload_support] = 20643 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 20644 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 20645 wmi_service[wmi_service_obss_spatial_reuse] = 20646 WMI_SERVICE_OBSS_SPATIAL_REUSE; 20647 wmi_service[wmi_service_per_vdev_chain_support] = 20648 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 20649 wmi_service[wmi_service_new_htt_msg_format] = 20650 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 20651 wmi_service[wmi_service_peer_unmap_cnf_support] = 20652 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 20653 wmi_service[wmi_service_beacon_reception_stats] = 20654 WMI_SERVICE_BEACON_RECEPTION_STATS; 20655 wmi_service[wmi_service_vdev_latency_config] = 20656 WMI_SERVICE_VDEV_LATENCY_CONFIG; 20657 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 20658 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 20659 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 20660 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 20661 wmi_service[wmi_service_nan_disable_support] = 20662 WMI_SERVICE_NAN_DISABLE_SUPPORT; 20663 wmi_service[wmi_service_sta_plus_sta_support] = 20664 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 20665 wmi_service[wmi_service_hw_db2dbm_support] = 20666 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 20667 wmi_service[wmi_service_wlm_stats_support] = 20668 WMI_SERVICE_WLM_STATS_REQUEST; 20669 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 20670 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 20671 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 20672 wmi_service[wmi_service_cfr_capture_support] = 20673 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 20674 wmi_service[wmi_service_bcast_twt_support] = 20675 WMI_SERVICE_BROADCAST_TWT; 20676 wmi_service[wmi_service_wpa3_ft_sae_support] = 20677 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 20678 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 20679 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 20680 wmi_service[wmi_service_ft_fils] = 20681 WMI_SERVICE_WPA3_FT_FILS; 20682 wmi_service[wmi_service_adaptive_11r_support] = 20683 WMI_SERVICE_ADAPTIVE_11R_ROAM; 20684 wmi_service[wmi_service_tx_compl_tsf64] = 20685 WMI_SERVICE_TX_COMPL_TSF64; 20686 wmi_service[wmi_service_data_stall_recovery_support] = 20687 WMI_SERVICE_DSM_ROAM_FILTER; 20688 wmi_service[wmi_service_vdev_delete_all_peer] = 20689 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 20690 wmi_service[wmi_service_three_way_coex_config_legacy] = 20691 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 20692 wmi_service[wmi_service_rx_fse_support] = 20693 WMI_SERVICE_RX_FSE_SUPPORT; 20694 wmi_service[wmi_service_sae_roam_support] = 20695 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 20696 wmi_service[wmi_service_owe_roam_support] = 20697 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 20698 wmi_service[wmi_service_6ghz_support] = 20699 WMI_SERVICE_6GHZ_SUPPORT; 20700 wmi_service[wmi_service_bw_165mhz_support] = 20701 WMI_SERVICE_BW_165MHZ_SUPPORT; 20702 wmi_service[wmi_service_bw_restricted_80p80_support] = 20703 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 20704 wmi_service[wmi_service_packet_capture_support] = 20705 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 20706 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 20707 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 20708 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 20709 wmi_service[wmi_service_multiple_vdev_restart_ext] = 20710 WMI_SERVICE_UNAVAILABLE; 20711 wmi_service[wmi_service_time_sync_ftm] = 20712 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 20713 wmi_service[wmi_service_nss_ratio_to_host_support] = 20714 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 20715 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 20716 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 20717 wmi_service[wmi_beacon_protection_support] = 20718 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 20719 wmi_service[wmi_service_sta_nan_ndi_four_port] = 20720 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 20721 wmi_service[wmi_service_host_scan_stop_vdev_all] = 20722 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 20723 wmi_service[wmi_support_extend_address] = 20724 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 20725 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 20726 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 20727 wmi_service[wmi_service_suiteb_roam_support] = 20728 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 20729 wmi_service[wmi_service_no_interband_mcc_support] = 20730 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 20731 wmi_service[wmi_service_dual_sta_roam_support] = 20732 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 20733 wmi_service[wmi_service_peer_create_conf] = 20734 WMI_SERVICE_PEER_CREATE_CONF; 20735 wmi_service[wmi_service_configure_roam_trigger_param_support] = 20736 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 20737 wmi_service[wmi_service_5dot9_ghz_support] = 20738 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 20739 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 20740 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 20741 wmi_service[wmi_service_cfr_capture_count_support] = 20742 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 20743 wmi_service[wmi_service_ocv_support] = 20744 WMI_SERVICE_OCV_SUPPORT; 20745 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 20746 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 20747 wmi_service[wmi_service_thermal_multi_client_support] = 20748 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 20749 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 20750 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 20751 wmi_service[wmi_service_fse_cmem_alloc_support] = 20752 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 20753 wmi_service[wmi_service_scan_conf_per_ch_support] = 20754 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 20755 wmi_service[wmi_service_csa_beacon_template] = 20756 WMI_SERVICE_CSA_BEACON_TEMPLATE; 20757 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20758 wmi_service[wmi_service_rtt_11az_ntb_support] = 20759 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 20760 wmi_service[wmi_service_rtt_11az_tb_support] = 20761 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 20762 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 20763 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 20764 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 20765 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 20766 #endif 20767 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 20768 wmi_service[wmi_service_igmp_offload_support] = 20769 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 20770 #endif 20771 20772 #ifdef FEATURE_WLAN_TDLS 20773 #ifdef WLAN_FEATURE_11AX 20774 wmi_service[wmi_service_tdls_ax_support] = 20775 WMI_SERVICE_11AX_TDLS_SUPPORT; 20776 wmi_service[wmi_service_tdls_6g_support] = 20777 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 20778 #endif 20779 wmi_service[wmi_service_tdls_wideband_support] = 20780 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 20781 #endif 20782 20783 #ifdef WLAN_SUPPORT_TWT 20784 wmi_service[wmi_service_twt_bcast_req_support] = 20785 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 20786 wmi_service[wmi_service_twt_bcast_resp_support] = 20787 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 20788 wmi_service[wmi_service_twt_nudge] = 20789 WMI_SERVICE_TWT_NUDGE; 20790 wmi_service[wmi_service_all_twt] = 20791 WMI_SERVICE_TWT_ALL_DIALOG_ID; 20792 wmi_service[wmi_service_twt_statistics] = 20793 WMI_SERVICE_TWT_STATS; 20794 #endif 20795 wmi_service[wmi_service_spectral_scan_disabled] = 20796 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 20797 wmi_service[wmi_service_sae_eapol_offload_support] = 20798 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 20799 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 20800 20801 wmi_service[wmi_service_wapi_concurrency_supported] = 20802 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 20803 wmi_service[wmi_service_sap_connected_d3_wow] = 20804 WMI_SERVICE_SAP_CONNECTED_D3WOW; 20805 wmi_service[wmi_service_go_connected_d3_wow] = 20806 WMI_SERVICE_SAP_CONNECTED_D3WOW; 20807 wmi_service[wmi_service_ext_tpc_reg_support] = 20808 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 20809 wmi_service[wmi_service_ndi_txbf_support] = 20810 WMI_SERVICE_NDI_TXBF_SUPPORT; 20811 wmi_service[wmi_service_reg_cc_ext_event_support] = 20812 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 20813 wmi_service[wmi_service_bang_radar_320_support] = 20814 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 20815 #if defined(CONFIG_BAND_6GHZ) 20816 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 20817 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 20818 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 20819 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 20820 #endif 20821 wmi_service[wmi_service_dcs_awgn_int_support] = 20822 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 20823 wmi_populate_service_11be(wmi_service); 20824 20825 #ifdef WLAN_FEATURE_BIG_DATA_STATS 20826 wmi_service[wmi_service_big_data_support] = 20827 WMI_SERVICE_BIG_DATA_SUPPORT; 20828 #endif 20829 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 20830 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 20831 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 20832 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 20833 wmi_service[wmi_service_halphy_cal_status] = 20834 WMI_SERVICE_HALPHY_CAL_STATUS; 20835 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 20836 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 20837 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 20838 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 20839 wmi_service[wmi_service_ema_multiple_group_supported] = 20840 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 20841 wmi_service[wmi_service_large_beacon_supported] = 20842 WMI_SERVICE_LARGE_BEACON_SUPPORT; 20843 wmi_service[wmi_service_aoa_for_rcc_supported] = 20844 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 20845 #ifdef WLAN_FEATURE_P2P_P2P_STA 20846 wmi_service[wmi_service_p2p_p2p_cc_support] = 20847 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 20848 #endif 20849 #ifdef THERMAL_STATS_SUPPORT 20850 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 20851 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 20852 #endif 20853 wmi_service[wmi_service_hw_mode_policy_offload_support] = 20854 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 20855 wmi_service[wmi_service_mgmt_rx_reo_supported] = 20856 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 20857 wmi_service[wmi_service_phy_dma_byte_swap_support] = 20858 WMI_SERVICE_UNAVAILABLE; 20859 wmi_service[wmi_service_spectral_session_info_support] = 20860 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 20861 wmi_service[wmi_service_umac_hang_recovery_support] = 20862 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 20863 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 20864 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20865 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 20866 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 20867 #endif 20868 wmi_service[wmi_service_probe_all_bw_support] = 20869 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 20870 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 20871 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 20872 #ifdef QCA_UNDECODED_METADATA_SUPPORT 20873 wmi_service[wmi_service_fp_phy_err_filter_support] = 20874 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 20875 #endif 20876 populate_tlv_service_mlo(wmi_service); 20877 wmi_service[wmi_service_pdev_rate_config_support] = 20878 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 20879 wmi_service[wmi_service_multi_peer_group_cmd_support] = 20880 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 20881 #ifdef WLAN_FEATURE_11BE 20882 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 20883 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 20884 #endif 20885 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 20886 wmi_service[wmi_service_combined_set_param_support] = 20887 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 20888 #endif 20889 wmi_service[wmi_service_pn_replay_check_support] = 20890 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 20891 #ifdef QCA_RSSI_DB2DBM 20892 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 20893 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 20894 #endif 20895 wmi_service[wmi_service_pktlog_decode_info_support] = 20896 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 20897 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20898 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 20899 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 20900 #endif 20901 #ifdef MULTI_CLIENT_LL_SUPPORT 20902 wmi_service[wmi_service_configure_multi_client_ll_support] = 20903 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 20904 #endif 20905 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20906 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 20907 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 20908 #endif 20909 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 20910 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 20911 #ifdef FEATURE_SET 20912 wmi_service[wmi_service_feature_set_event_support] = 20913 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 20914 #endif 20915 } 20916 20917 /** 20918 * wmi_ocb_ut_attach() - Attach OCB test framework 20919 * @wmi_handle: wmi handle 20920 * 20921 * Return: None 20922 */ 20923 #ifdef WLAN_OCB_UT 20924 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 20925 #else 20926 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 20927 { 20928 return; 20929 } 20930 #endif 20931 20932 /** 20933 * wmi_tlv_attach() - Attach TLV APIs 20934 * 20935 * Return: None 20936 */ 20937 void wmi_tlv_attach(wmi_unified_t wmi_handle) 20938 { 20939 wmi_handle->ops = &tlv_ops; 20940 wmi_ocb_ut_attach(wmi_handle); 20941 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 20942 #ifdef WMI_INTERFACE_EVENT_LOGGING 20943 /* Skip saving WMI_CMD_HDR and TLV HDR */ 20944 wmi_handle->soc->buf_offset_command = 8; 20945 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 20946 wmi_handle->soc->buf_offset_event = 4; 20947 #endif 20948 populate_tlv_events_id(wmi_handle->wmi_events); 20949 populate_tlv_service(wmi_handle->services); 20950 wmi_wds_attach_tlv(wmi_handle); 20951 wmi_twt_attach_tlv(wmi_handle); 20952 wmi_extscan_attach_tlv(wmi_handle); 20953 wmi_smart_ant_attach_tlv(wmi_handle); 20954 wmi_dbr_attach_tlv(wmi_handle); 20955 wmi_atf_attach_tlv(wmi_handle); 20956 wmi_ap_attach_tlv(wmi_handle); 20957 wmi_bcn_attach_tlv(wmi_handle); 20958 wmi_ocb_attach_tlv(wmi_handle); 20959 wmi_nan_attach_tlv(wmi_handle); 20960 wmi_p2p_attach_tlv(wmi_handle); 20961 wmi_interop_issues_ap_attach_tlv(wmi_handle); 20962 wmi_dcs_attach_tlv(wmi_handle); 20963 wmi_roam_attach_tlv(wmi_handle); 20964 wmi_concurrency_attach_tlv(wmi_handle); 20965 wmi_pmo_attach_tlv(wmi_handle); 20966 wmi_sta_attach_tlv(wmi_handle); 20967 wmi_11ax_bss_color_attach_tlv(wmi_handle); 20968 wmi_fwol_attach_tlv(wmi_handle); 20969 wmi_vdev_attach_tlv(wmi_handle); 20970 wmi_cfr_attach_tlv(wmi_handle); 20971 wmi_cp_stats_attach_tlv(wmi_handle); 20972 wmi_gpio_attach_tlv(wmi_handle); 20973 wmi_11be_attach_tlv(wmi_handle); 20974 wmi_coap_attach_tlv(wmi_handle); 20975 } 20976 qdf_export_symbol(wmi_tlv_attach); 20977 20978 /** 20979 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 20980 * 20981 * Return: None 20982 */ 20983 void wmi_tlv_init(void) 20984 { 20985 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 20986 } 20987